summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml21
-rw-r--r--CHANGELOG.md2
-rw-r--r--README.md169
-rw-r--r--TRANSLATION1
-rw-r--r--assets/css/default.css16
-rw-r--r--assets/css/embed.css10
-rw-r--r--assets/css/video-js.min.css2
-rw-r--r--assets/css/videojs-vtt-thumbnails-fix.css3
-rw-r--r--assets/js/community.js2
-rw-r--r--assets/js/embed.js2
-rw-r--r--assets/js/global.js3
-rw-r--r--assets/js/handlers.js144
-rw-r--r--assets/js/notifications.js2
-rw-r--r--assets/js/player.js42
-rw-r--r--assets/js/playlist_widget.js26
-rw-r--r--assets/js/silvermine-videojs-quality-selector.min.js5
-rw-r--r--assets/js/subscribe_widget.js2
-rw-r--r--assets/js/themes.js21
-rw-r--r--assets/js/video.min.js11
-rw-r--r--assets/js/videojs-vtt-thumbnails.min.js4
-rw-r--r--assets/js/watch.js2
-rw-r--r--assets/js/watched_widget.js2
-rwxr-xr-xconfig/migrate-scripts/migrate-db-1eca969.sh19
-rw-r--r--config/sql/playlists.sql11
-rw-r--r--config/sql/privacy.sql10
-rw-r--r--config/sql/videos.sql17
-rw-r--r--docker-compose.yml27
-rw-r--r--docker/Dockerfile37
-rw-r--r--docker/Dockerfile.postgres9
-rwxr-xr-xdocker/entrypoint.postgres.sh31
-rwxr-xr-xdocker/init-invidious-db.sh16
-rw-r--r--kubernetes/.gitignore1
-rw-r--r--kubernetes/Chart.lock6
-rw-r--r--kubernetes/Chart.yaml22
-rw-r--r--kubernetes/README.md41
-rw-r--r--kubernetes/templates/_helpers.tpl16
-rw-r--r--kubernetes/templates/configmap.yaml11
-rw-r--r--kubernetes/templates/deployment.yaml61
-rw-r--r--kubernetes/templates/hpa.yaml18
-rw-r--r--kubernetes/templates/service.yaml20
-rw-r--r--kubernetes/values.yaml56
-rw-r--r--locales/ar.json2
-rw-r--r--locales/de.json22
-rw-r--r--locales/en-US.json4
-rw-r--r--locales/eo.json62
-rw-r--r--locales/es.json42
-rw-r--r--locales/eu.json78
-rw-r--r--locales/fr.json10
-rw-r--r--locales/hu-HU.json335
-rw-r--r--locales/it.json96
-rw-r--r--locales/ja.json6
-rw-r--r--locales/nb-NO.json (renamed from locales/nb_NO.json)50
-rw-r--r--locales/nl.json35
-rw-r--r--locales/pl.json84
-rw-r--r--locales/pt-BR.json336
-rw-r--r--locales/pt-PT.json387
-rw-r--r--locales/ro.json336
-rw-r--r--locales/ru.json34
-rw-r--r--locales/sr_Cyrl.json336
-rw-r--r--locales/sv-SE.json336
-rw-r--r--locales/tr.json60
-rw-r--r--locales/uk.json34
-rw-r--r--locales/zh-CN.json38
-rw-r--r--locales/zh-TW.json128
-rw-r--r--screenshots/03_subscriptions.pngbin548404 -> 0 bytes
-rw-r--r--shard.yml12
-rw-r--r--spec/helpers_spec.cr18
-rw-r--r--src/invidious.cr1331
-rw-r--r--src/invidious/channels.cr654
-rw-r--r--src/invidious/comments.cr106
-rw-r--r--src/invidious/helpers/handlers.cr32
-rw-r--r--src/invidious/helpers/helpers.cr860
-rw-r--r--src/invidious/helpers/i18n.cr2
-rw-r--r--src/invidious/helpers/jobs.cr318
-rw-r--r--src/invidious/helpers/macros.cr80
-rw-r--r--src/invidious/helpers/patch_mapping.cr166
-rw-r--r--src/invidious/helpers/signatures.cr56
-rw-r--r--src/invidious/helpers/static_file_handler.cr4
-rw-r--r--src/invidious/helpers/tokens.cr40
-rw-r--r--src/invidious/helpers/utils.cr162
-rw-r--r--src/invidious/jobs.cr13
-rw-r--r--src/invidious/jobs/base_job.cr3
-rw-r--r--src/invidious/jobs/bypass_captcha_job.cr131
-rw-r--r--src/invidious/jobs/notification_job.cr24
-rw-r--r--src/invidious/jobs/pull_popular_videos_job.cr27
-rw-r--r--src/invidious/jobs/refresh_channels_job.cr59
-rw-r--r--src/invidious/jobs/refresh_feeds_job.cr77
-rw-r--r--src/invidious/jobs/statistics_refresh_job.cr59
-rw-r--r--src/invidious/jobs/subscribe_to_feeds_job.cr52
-rw-r--r--src/invidious/jobs/update_decrypt_function_job.cr19
-rw-r--r--src/invidious/mixes.cr61
-rw-r--r--src/invidious/playlists.cr376
-rw-r--r--src/invidious/routes/base_route.cr9
-rw-r--r--src/invidious/routes/embed/index.cr27
-rw-r--r--src/invidious/routes/embed/show.cr174
-rw-r--r--src/invidious/routes/home.cr34
-rw-r--r--src/invidious/routes/licenses.cr6
-rw-r--r--src/invidious/routes/privacy.cr6
-rw-r--r--src/invidious/routes/watch.cr186
-rw-r--r--src/invidious/routing.cr8
-rw-r--r--src/invidious/search.cr204
-rw-r--r--src/invidious/trending.cr52
-rw-r--r--src/invidious/users.cr337
-rw-r--r--src/invidious/videos.cr1045
-rw-r--r--src/invidious/views/add_playlist_items.ecr12
-rw-r--r--src/invidious/views/channel.ecr6
-rw-r--r--src/invidious/views/community.ecr20
-rw-r--r--src/invidious/views/components/feed_menu.ecr28
-rw-r--r--src/invidious/views/components/item.ecr25
-rw-r--r--src/invidious/views/components/player.ecr35
-rw-r--r--src/invidious/views/components/player_sources.ecr2
-rw-r--r--src/invidious/views/components/subscribe_widget.ecr20
-rw-r--r--src/invidious/views/embed.ecr37
-rw-r--r--src/invidious/views/history.ecr14
-rw-r--r--src/invidious/views/login.ecr78
-rw-r--r--src/invidious/views/playlist.ecr18
-rw-r--r--src/invidious/views/playlists.ecr2
-rw-r--r--src/invidious/views/preferences.ecr15
-rw-r--r--src/invidious/views/subscription_manager.ecr33
-rw-r--r--src/invidious/views/subscriptions.ecr10
-rw-r--r--src/invidious/views/template.ecr19
-rw-r--r--src/invidious/views/token_manager.ecr33
-rw-r--r--src/invidious/views/top.ecr20
-rw-r--r--src/invidious/views/view_all_playlists.ecr18
-rw-r--r--src/invidious/views/watch.ecr148
125 files changed, 6574 insertions, 4621 deletions
diff --git a/.travis.yml b/.travis.yml
index 314abc73..f443e815 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,20 @@
dist: bionic
+# Work around broken Travis Crystal image
+addons:
+ apt:
+ packages:
+ - gcc
+ - pkg-config
+ - git
+ - tzdata
+ - libpcre3-dev
+ - libevent-dev
+ - libyaml-dev
+ - libgmp-dev
+ - libssl-dev
+ - libxml2-dev
+
jobs:
include:
- stage: build
@@ -9,6 +24,7 @@ jobs:
language: crystal
crystal: latest
before_install:
+ - crystal --version
- shards update
- shards install
install:
@@ -28,7 +44,4 @@ jobs:
- docker-compose build
script:
- docker-compose up -d
- - sleep 15 # Wait for cluster to become ready, TODO: do not sleep
- - HEADERS="$(curl -I -s http://localhost:3000/)"
- - STATUS="$(echo $HEADERS | head -n1)"
- - if [[ "$STATUS" != *"200 OK"* ]]; then echo "$HEADERS"; exit 1; fi
+ - while curl -Isf http://localhost:3000; do sleep 1; done
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b5bef106..314a134f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -400,7 +400,7 @@ An `/api/v1/stats` endpoint has been added with [#356](https://github.com/omarro
## For Developers
-`/api/v1/channels/:ucid` now provides an `autoGenerated` tag, which returns true for [topic channels](https://www.youtube.com/channel/UCE80FOXpJydkkMo-BYoJdEg), and larger [genre channels](https://www.youtube.com/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ) generated by YouTube. These channels don't have any videos of their own, so `latestVideos` will be empty. It is recommended instead to display a list of playlists generated by YouTube.
+`/api/v1/channels/:ucid` now provides an `autoGenerated` tag, which returns true for topic channels, and larger genre channels generated by YouTube. These channels don't have any videos of their own, so `latestVideos` will be empty. It is recommended instead to display a list of playlists generated by YouTube.
You can now pull a list of playlists from a channel with `/api/v1/channels/playlists/:ucid`. Supported options are documented in the [wiki](https://github.com/omarroth/invidious/wiki/API#get-apiv1channelsplaylistsucid-apiv1channelsucidplaylists). Pagination is handled with a `continuation` token, which is generated on each call. Of note is that auto-generated channels currently have one page of results, and subsequent calls will be empty.
diff --git a/README.md b/README.md
index f90518a2..35818536 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,18 @@
# Invidious
-[![Build Status](https://travis-ci.org/omarroth/invidious.svg?branch=master)](https://travis-ci.org/omarroth/invidious)
+[![Build Status](https://travis-ci.org/iv-org/invidious.svg?branch=master)](https://travis-ci.org/github/iv-org/invidious) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/)
## Invidious is an alternative front-end to YouTube
+## Invidious instances:
+
+[Public Invidious instances are listed here.](https://github.com/iv-org/invidious/wiki/Invidious-Instances)
+
+## Invidious features:
+
+- [Copylefted libre software](https://github.com/iv-org/invidious) (AGPLv3+ licensed)
- Audio-only mode (and no need to keep window open on mobile)
-- [Free software](https://github.com/omarroth/invidious) (AGPLv3 licensed)
-- No ads
-- No need to create a Google account to save subscriptions
-- Lightweight (homepage is ~4 KB compressed)
+- Lightweight (the homepage is ~4 KB compressed)
- Tools for managing subscriptions:
- Only show unseen videos
- Only show latest (or latest unseen) video from each channel
@@ -18,37 +22,33 @@
- Dark mode
- Embed support
- Set default player options (speed, quality, autoplay, loop)
-- Does not require JS to play videos
-- Support for Reddit comments in place of YT comments
+- Support for Reddit comments in place of YouTube comments
- Import/Export subscriptions, watch history, preferences
+- [Developer API](https://github.com/iv-org/invidious/wiki/API)
- Does not use any of the official YouTube APIs
-- Developer [API](https://github.com/omarroth/invidious/wiki/API)
-
-Liberapay: https://liberapay.com/omarroth
-BTC: 356DpZyMXu6rYd55Yqzjs29n79kGKWcYrY
-BCH: qq4ptclkzej5eza6a50et5ggc58hxsq5aylqut2npk
-
-## Invidious Instances
-
-See [Invidious Instances](https://github.com/omarroth/invidious/wiki/Invidious-Instances) for a full list of publicly available instances.
-
-### Official Instances
-
-- [invidio.us](https://invidio.us) 🇺🇸
- Issuer: Let's Encrypt, [SSLLabs Verification](https://www.ssllabs.com/ssltest/analyze.html?d=invidio.us)
-- [kgg2m7yk5aybusll.onion](http://kgg2m7yk5aybusll.onion)
-- [axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion](http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion)
+- Does not require JavaScript to play videos
+- No need to create a Google account to save subscriptions
+- No ads
+- No CoC
+- No CLA
+- [Multilingual](https://hosted.weblate.org/projects/invidious/#languages) (translated into many languages)
-## Screenshots
+## Screenshots:
| Player | Preferences | Subscriptions |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [<img src="screenshots/01_player.png?raw=true" height="140" width="280">](screenshots/01_player.png?raw=true) | [<img src="screenshots/02_preferences.png?raw=true" height="140" width="280">](screenshots/02_preferences.png?raw=true) | [<img src="screenshots/03_subscriptions.png?raw=true" height="140" width="280">](screenshots/03_subscriptions.png?raw=true) |
| [<img src="screenshots/04_description.png?raw=true" height="140" width="280">](screenshots/04_description.png?raw=true) | [<img src="screenshots/05_preferences.png?raw=true" height="140" width="280">](screenshots/05_preferences.png?raw=true) | [<img src="screenshots/06_subscriptions.png?raw=true" height="140" width="280">](screenshots/06_subscriptions.png?raw=true) |
-## Installation
+## Installation:
+
+To manually compile invidious you need at least 2GB of RAM. If you have less you can setup SWAP to have a combined amount of 2 GB or use Docker instead.
+
+After installation take a look at the [Post-install steps](#post-install-configuration).
+
+### Automated installation:
-See [Invidious-Updater](https://github.com/tmiland/Invidious-Updater) for a self-contained script that can automatically install and update Invidious.
+[Invidious-Updater](https://github.com/tmiland/Invidious-Updater) is a self-contained script that can automatically install and update Invidious.
### Docker:
@@ -58,7 +58,7 @@ See [Invidious-Updater](https://github.com/tmiland/Invidious-Updater) for a self
$ docker-compose up
```
-And visit `localhost:3000` in your browser.
+Then visit `localhost:3000` in your browser.
#### Rebuild cluster:
@@ -73,13 +73,15 @@ $ docker volume rm invidious_postgresdata
$ docker-compose build
```
+### Manual installation:
+
### Linux:
-#### Install dependencies
+#### Install the dependencies
```bash
# Arch Linux
-$ sudo pacman -S shards crystal librsvg postgresql
+$ sudo pacman -S base-devel shards crystal librsvg postgresql
# Ubuntu or Debian
# First you have to add the repository to your APT configuration. For easy setup just run in your command line:
@@ -88,23 +90,22 @@ $ curl -sSL https://dist.crystal-lang.org/apt/setup.sh | sudo bash
$ curl -sL "https://keybase.io/crystal/pgp_keys.asc" | sudo apt-key add -
$ echo "deb https://dist.crystal-lang.org/apt crystal main" | sudo tee /etc/apt/sources.list.d/crystal.list
$ sudo apt-get update
-$ sudo apt install crystal libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev
+$ sudo apt install crystal libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev zlib1g-dev
```
-#### Add invidious user and clone repository
+#### Add an Invidious user and clone the repository
```bash
$ useradd -m invidious
$ sudo -i -u invidious
-$ git clone https://github.com/omarroth/invidious
+$ git clone https://github.com/iv-org/invidious
$ exit
```
-#### Setup PostgresSQL
+#### Set up PostgresSQL
```bash
-$ sudo systemctl enable postgresql
-$ sudo systemctl start postgresql
+$ sudo systemctl enable --now postgresql
$ sudo -i -u postgres
$ psql -c "CREATE USER kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
$ createdb -O kemal invidious
@@ -115,10 +116,12 @@ $ psql invidious kemal < /home/invidious/invidious/config/sql/users.sql
$ psql invidious kemal < /home/invidious/invidious/config/sql/session_ids.sql
$ psql invidious kemal < /home/invidious/invidious/config/sql/nonces.sql
$ psql invidious kemal < /home/invidious/invidious/config/sql/annotations.sql
+$ psql invidious kemal < /home/invidious/invidious/config/sql/playlists.sql
+$ psql invidious kemal < /home/invidious/invidious/config/sql/playlist_videos.sql
$ exit
```
-#### Setup Invidious
+#### Set up Invidious
```bash
$ sudo -i -u invidious
@@ -130,23 +133,36 @@ $ ./invidious # stop with ctrl c
$ exit
```
-#### systemd service
+#### Systemd service:
```bash
$ sudo cp /home/invidious/invidious/invidious.service /etc/systemd/system/invidious.service
-$ sudo systemctl enable invidious.service
-$ sudo systemctl start invidious.service
+$ sudo systemctl enable --now invidious.service
+```
+
+#### Logrotate:
+
+```bash
+$ sudo echo "/home/invidious/invidious/invidious.log {
+rotate 4
+weekly
+notifempty
+missingok
+compress
+minsize 1048576
+}" | tee /etc/logrotate.d/invidious.logrotate
+$ sudo chmod 0644 /etc/logrotate.d/invidious.logrotate
```
-### OSX:
+### MacOS:
```bash
# Install dependencies
$ brew update
$ brew install shards crystal postgres imagemagick librsvg
-# Clone repository and setup postgres database
-$ git clone https://github.com/omarroth/invidious
+# Clone the repository and set up a PostgreSQL database
+$ git clone https://github.com/iv-org/invidious
$ cd invidious
$ brew services start postgresql
$ psql -c "CREATE ROLE kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
@@ -158,15 +174,30 @@ $ psql invidious kemal < config/sql/users.sql
$ psql invidious kemal < config/sql/session_ids.sql
$ psql invidious kemal < config/sql/nonces.sql
$ psql invidious kemal < config/sql/annotations.sql
+$ psql invidious kemal < config/sql/privacy.sql
+$ psql invidious kemal < config/sql/playlists.sql
+$ psql invidious kemal < config/sql/playlist_videos.sql
-# Setup Invidious
+# Set up Invidious
$ shards update && shards install
$ crystal build src/invidious.cr --release
```
+## Post-install configuration:
+
+Detailed configuration available in the [configuration guide](https://github.com/iv-org/invidious/wiki/Configuration).
+
+If you use a reverse proxy, you **must** configure invidious to properly serve request through it:
+
+`https_only: true` : if your are serving your instance via https, set it to true
+
+`domain: domain.ext`: if you are serving your instance via a domain name, set it here
+
+`external_port: 443`: if your are serving your instance via https, set it to 443
+
## Update Invidious
-You can see how to update Invidious [here](https://github.com/omarroth/invidious/wiki/Updating).
+Instructions are available in the [updating guide](https://github.com/iv-org/invidious/wiki/Updating).
## Usage:
@@ -197,39 +228,55 @@ $ ./sentry
## Documentation
-[Documentation](https://github.com/omarroth/invidious/wiki) can be found in the wiki.
+[Documentation](https://github.com/iv-org/invidious/wiki) can be found in the wiki.
## Extensions
-[Extensions](https://github.com/omarroth/invidious/wiki/Extensions) can be found in the wiki, as well as documentation for integrating it into other projects.
+[Extensions](https://github.com/iv-org/invidious/wiki/Extensions) can be found in the wiki, as well as documentation for integrating it into other projects.
## Made with Invidious
-- [FreeTube](https://github.com/FreeTubeApp/FreeTube): An Open Source YouTube app for privacy.
-- [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JS-rich alternate YouTube player
-- [PeerTubeify](https://gitlab.com/Ealhad/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists.
-- [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A materialistic music player that streams music from YouTube.
+- [FreeTube](https://github.com/FreeTubeApp/FreeTube): A libre software YouTube app for privacy.
+- [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JavaScript-rich alternate YouTube player
+- [PeerTubeify](https://gitlab.com/Cha_deL/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists.
+- [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A material design music player that streams music from YouTube.
+- [LapisTube](https://github.com/blubbll/lapis-tube): A fancy and advanced (experimental) YouTube front-end. Combined streams & custom YT features.
+- [HoloPlay](https://github.com/stephane-r/HoloPlay): Funny Android application connecting on Invidious API's with search, playlists and favoris.
## Contributing
-1. Fork it ( https://github.com/omarroth/invidious/fork )
+1. Fork it ( https://github.com/iv-org/invidious/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
-5. Create a new Pull Request
+5. Create a new pull request
+
+#### Translation
+
+- Log in with an account you have elsewhere, or register an account and start translating at [Hosted Weblate](https://hosted.weblate.org/engage/invidious/).
+
+## Donate:
+
+Liberapay: https://liberapay.com/iv-org/
## Contact
-Feel free to send an email to omarroth@protonmail.com or join our [Matrix Server](https://riot.im/app/#/room/#invidious:matrix.org), or #invidious on Freenode.
+Feel free to join our [Matrix room](https://matrix.to/#/#invidious:matrix.org), or #invidious on freenode. Both platforms are bridged together.
-You can also view release notes on the [releases](https://github.com/omarroth/invidious/releases) page or in the CHANGELOG.md included in the repository.
+## Liability
-## License
+We take no responsibility for the use of our tool, or external instances provided by third parties. We strongly recommend you abide by the valid official regulations in your country. Furthermore, we refuse liability for any inappropriate use of Invidious, such as illegal downloading. This tool is provided to you in the spirit of free, open software.
-[![GNU AGPLv3 Image](https://www.gnu.org/graphics/agplv3-155x51.png)](http://www.gnu.org/licenses/agpl-3.0.en.html)
+You may view the LICENSE in which this software is provided to you [here](./LICENSE).
-Invidious is Free Software: You can use, study share and improve it at your
-will. Specifically you can redistribute and/or modify it under the terms of the
-[GNU Affero General Public License](https://www.gnu.org/licenses/agpl.html) as
-published by the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+> 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.
diff --git a/TRANSLATION b/TRANSLATION
new file mode 100644
index 00000000..fa340d71
--- /dev/null
+++ b/TRANSLATION
@@ -0,0 +1 @@
+https://hosted.weblate.org/projects/invidious/
diff --git a/assets/css/default.css b/assets/css/default.css
index ea139b40..b7a77be6 100644
--- a/assets/css/default.css
+++ b/assets/css/default.css
@@ -60,6 +60,22 @@ body {
color: rgb(255, 0, 0);
}
+.feed-menu {
+ display: flex;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+.feed-menu-item {
+ text-align: center;
+}
+
+@media screen and (max-width: 640px) {
+ .feed-menu-item {
+ flex: 0 0 40%;
+ }
+}
+
.h-box {
padding-left: 1em;
padding-right: 1em;
diff --git a/assets/css/embed.css b/assets/css/embed.css
new file mode 100644
index 00000000..12fefe58
--- /dev/null
+++ b/assets/css/embed.css
@@ -0,0 +1,10 @@
+#player {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ min-width: 100%;
+ min-height: 100%;
+ width: auto;
+ height: auto;
+ z-index: -100;
+}
diff --git a/assets/css/video-js.min.css b/assets/css/video-js.min.css
index 68c82db0..b453b88c 100644
--- a/assets/css/video-js.min.css
+++ b/assets/css/video-js.min.css
@@ -1 +1 @@
-@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGJHcRdyA4RZgQRADK3CxEAAHic7dFZbsMgAEXRS0ycyZnnOeG7y+qC8pU1dHusIOXxuoxaOlwZYWQB0Aea4quIEN4E9LzKbKjzDeM6H/mua6Lmc/p8yhg0lvdYx15ZG8uOLQOGjMp3EzqmzJizYMmKNRu27Nhz4MiJMxeu3Ljz4Ekqm7T8P52G8PP3lnTOVk++Z6iN6QZzNN1F7ptuN7eGOjDUoaGODHVsuvU8MdTO9Hd5aqgzQ50b6sJQl4a6MtS1oW4MdWuoO0PdG+rBUI+GejLUs6FeDPVqqDdDvRvqw1CfhpqM9At0iFLaAAB4nJ1YDXBTVRZ+5/22TUlJ8we0pHlJm7RJf5O8F2j6EymlSPkpxaL8U2xpa3DKj0CBhc2IW4eWKSokIoLsuMqssM64f+jA4HSdWXXXscBq67IOs3FXZ1ZYWVyRFdo899yXtIBQZ90k7717zz3v3HPPOfd854YCCj9cL9dL0RQFOqCbGJnrHb5EayiKIWN8iA/hWBblo6hUWm8TtCDwE80WMJus/irwyxOdxeB0MDb14VNJHnXYoLLSl6FfCUYO9nYPTA8Epg9090LprfbBbZ2hY0UlJUXHQp3/vtWkS6EBv8+rPMq5u9692f/dNxJNiqwC1xPE9TCUgCsSdQWgE3XQD25lkG4CN2xmTcOXWBOyser6RN6KnGbKSbmQ3+d0OI1m2W8QzLLkI2sykrWAgJJEtA8vGGW/2Q+CmT3n8zS9wZwu2DCvtuZKZN3xkrLh36yCZuUomQSqGpY8t/25VfHVhw8z4ebGBtfLb0ya9PCaDc+8dGTvk2dsh6z7WzvowlXKUSWo9MJ15a3KrEP2loOr2Ojhw6iW6hf2BDdEccQvZGpaAy7YovSwq8kr7HGllxpd71rkS6G0Sf11sl9OvMK1+jwPPODxjUwkOim9CU3ix1wNjXDfmJSEn618Bs6lpWwUpU+8PCqLMY650zjq8VhCIP17NEKTx3eaLL+s5Pi6yJWaWjTHLR1jYzPSV9VF/6Ojdb/1kO3Mk3uhHC0x6gc1BjlKQ+nQFxTYdaJkZ7ySVxLBbhR1dsboNXp1tCYKW2LRaEzpYcIx2BKNxaL0ZaUnSqfFoiNhHKR/GkX6PWUSAaJelQaqZL1EpoHNsajSEyPSoJ9IjhIxTdjHLmwZvhRDOiFTY/YeQnvrVZmiTQtGncECXtFTBZLOVwwMRgoXHAkXzMzPn1nAJJ8jYSbMDaqN2waGLzNhih/bZynUBMpIWSg7VYi7DRx2m8ALkIdRCJwI6ArJx2EI8kaDWeTQKeAFk9fjl/1AvwktjQ1P7NjyMGQyfd4vjipX6M/i52D7Cq80kqlcxEcGXRr/FEcgs0u5uGgB4VWuMFfpdn2Re6Hi3PqzmxWKsz6+ae2Pn9hXXw/fqM859UiGC0oKYYILJBqJrsn1Z1E5qOs9rQCiUQRREjm8yJcbHF5cUJufX1vAHlefw0XgUoboS3ETfQlTxBC4SOtuE8VPRJTBSCQSjZCpk7Gqzu+masaZ2y7Zjehho4F3g82BNDkAHpORG4+OCS+f6JTPmtRn/PH1kch6d04sp7AQb25aQ/pqUyXeQ8vrebG8OYQdXOQ+585u0sdW9rqalzRURiJ+9F4MweRFrKUjl1GUYhH1A27WOHw5cTFSFPMo9EeUIGnQTZHIaJ7AHLaOKsOODaNF9jkBjYG2QEsQ2xjMUAx2bBEbeTBWMHwskBjngq56S/yfgkBnWBa4K9sqKtq2t1UI8S9He5XuBRbawAdatrQEAi30Aks2+LM8WeCbalVZkWNylvJ+dqJnzVb+OHlSoKW8nPCP7Rd+CcZ2DdWAGqJ2CBFOphgywFFCFBNtfAbGtNPBCwxvygHeYMZMY9ZboBqwq/pVrsbgN5tkv152ODlbMfiqwGMBgxa4Exz3QhovRIUp6acqZmQzRq0ypDXS2TPLT02YIkQETnOE445oOGxOmXAqUJNNG7XgupMjPq2ua9asrj5yY/yuKteO1Kx0YNJTufrirLe1mZnat7OL6rnUdCWenpW6I8mAnbsY8KWs1PuSovCW9A/Z25PQ24a7cNOqgmTkLmBMgh4THgc4b9k2IVv1/g/F5nGljwPLfOgHAzJzh45V/4+WenTzmMtR5Z7us2Tys909UHqrPY7KbckoxRvRHhmVc3cJGE97uml0R1S0jdULVl7EvZtDFVBF35N9cEdjpgmAiOlFZ+Dtoh93+D3zzHr8RRNZQhnCNMNbcegOvpEwZoL+06cJQ07h+th3fZ/7PVbVC6ngTAV/KoLFuO6+2KFcU651gEb5ugPSIb1D+Xp8V4+k3sEIGnw5mYe4If4k1lFYr6SCzmM2EQ8iWtmwjnBI9kTwe1TlfAmXh7H02by9fW2gsjKwtv0aaURKil4OdV7rDL1MXIFNrhdxohcZXYTnq47WisrKitaObbf5+yvkLi5J6lCNZZ+B6GC38VNBZBDidSS/+mSvh6s+srgC8pyKMvDtt+de3c9fU76ZPfuM8ud4Kv0fyP/LqfepMT/3oZxSqpZaTa1DaQYLY8TFsHYbWYsPoRhRWfL5eSSQbhUGgGC3YLbVMk6PitTFNGpAsNrC6D1VNBKgBHMejaiuRWEWGgsSDBTJjqWIl8kJLlsaLJ2tXDr6xGfT85bM2Q06a46x2HTgvdnV8z5YDy/27J4zt6x2VtkzjoYpkq36kaBr4eQSg7tyiVweWubXZugtadl58ydapfbORfKsDTuZ0OBgx4cfdjCf5tbWNITnL120fdOi1RV1C3uKGzNdwYLcMvZ3BxoPyTOCD1XvXTp7U10gWCVmTV9b3r2z0SkGWovb2hp9I89O8a2smlyaO8muMU+dRmtzp60IzAoFpjLr1n388boLyf0dRvxhsHZ0qbWqDkwqvvpkj4l0fY6EIXRi5sQSrAvsVYwXRy4qJ2EVtD1AN7a0HWth9ymvL1xc3WTUKK/TAHA/bXDVtVWfOMfuGxGZv4Ln/jVr9jc3j1yMv0tndmyt9Vq88Y9gH1wtLX3KWjot5++jWHgAoZZkQ14wGQ20Fli71UmKJAy4xKMSTGbVdybW7FDDAut9XpD5AzWrYO7zQ8qffqF8+Ynd/clrHcdyxGy3a/3+mfNnzC/cBsveTjnTvXf1o6vzOlZw7WtqtdmPK/Errz/6NNtD72zmNOZfbmYdTGHfoofqI79Oc+R2n1lrnL6pOm0Up7kwxhTW12Amm7WYkXR2qYrF2AmgmbAsxZjwy1xpg/m1Je2vrp8v/nz2xpmlBg4E9hrMU341wVpTOh/OfmGvAnra8q6uctr60ZQHV3Q+WMQJykMj8ZsWn2QBOmmHMB+m5pDIpTFonYigiaKAhGEiAHF7EliVnQkjoLVIMPtJpBKHYd3A8GYH9jJzrWwmHx5Qjp7vDAX0suGRym1vtm/9W1/HyR8vczfMs6Sk8DSv855/5dlX9oQq52hT8syyp2rx5Id17IAyAM3wIjQPMOHzytEB64q6D5zT91yNbnx3V/nqnd017S9Y0605k3izoXLpsxde2n38yoOV9s1LcjwzNjbdX6asnBVaBj/6/DwKwPkpcqbDG7BnsXoSqWnUAmottYF6jMSdVyYZh3zVXCjwTiwwHH6sGuRiEHQGzuRX6whZkp123oy1BWE2mEfJ/tvIRtM4ZM5bDXiMsPMaAKOTyc5uL57rqyyc5y5JE5pm1i2S2iUX0CcaQ6lC6Zog7JqSqZmYlosl2K6pwNA84zRnQW6SaALYZQGW5lhCtU/W34N6o+bKfZ8cf3/Cl/+iTX3wBzpOY4mRkeNf3rptycGSshQWgGbYt5jFc2e0+DglIrwl6DVWQ7BuwaJ3Xk1J4VL5urnLl/Wf+gHU/hZoZdKNym6lG+I34FaNeZKcSpJIo2IeCVvpdsDGfKvzJnAwmeD37Ow65ZWwSowpgwX5T69s/rB55dP5BcpgDKFV8p7q2sn/1uc93bVzT/w6UrCqDTWvfCq/oCD/qZXNoUj8BL5Kp6GU017frfNXkAtiiyf/SOCEeLqnd8R/Ql9GlCRfctS6k5chvIBuQ1zCCjoCHL2DHNHIXxMJ3kQeO8lbsUXONeSfA5EjcG6/E+KdhN4bP04vBhdi883+BFBzQbxFbvZzQeY9LNBZc0FNfn5NwfDn6rCTnTw6R8o+gfpf5hCom33cRuiTlss3KHmZjD+BPN+5gXuA2ziS/Q73mLxUkpbKN/eqwz5uK0X9F3h2d1V4nGNgZGBgAOJd776+iue3+crAzc4AAje5Bfcg0xz9YHEOBiYQBQA8FQlFAHicY2BkYGBnAAGOPgaG//85+hkYGVCBMgBGGwNYAAAAeJxjYGBgYB8EmKOPgQEAQ04BfgAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhAi2COh4nGNgZGBgUGYoZWBnAAEmIOYCQgaG/2A+AwAYCQG2AHicXZBNaoNAGIZfE5PQCKFQ2lUps2oXBfOzzAESyDKBQJdGR2NQR3QSSE/QE/QEPUUPUHqsvsrXjTMw83zPvPMNCuAWP3DQDAejdm1GjzwS7pMmwi75XngAD4/CQ/oX4TFe4Qt7uMMbOzjuDc0EmXCP/C7cJ38Iu+RP4QEe8CU8pP8WHmOPX2EPz87TPo202ey2OjlnQSXV/6arOjWFmvszMWtd6CqwOlKHq6ovycLaWMWVydXKFFZnmVFlZU46tP7R2nI5ncbi/dDkfDtFBA2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-mute-control:hover~.vjs-volume-control,.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel .vjs-volume-control:hover,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control,.video-js .vjs-volume-panel:hover .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-mute-control:hover~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em}.video-js .vjs-volume-panel .vjs-mute-control:hover~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-vertical{left:-3.5em}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:9em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0;background:0 0}.video-js .vjs-menu :focus:not(:focus-visible),.video-js :focus:not(:focus-visible){outline:0;background:0 0} \ No newline at end of file
+@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGJHcRdyA4RZgQRADK3CxEAAHic7dFZbsMgAEXRS0ycyZnnOeG7y+qC8pU1dHusIOXxuoxaOlwZYWQB0Aea4quIEN4E9LzKbKjzDeM6H/mua6Lmc/p8yhg0lvdYx15ZG8uOLQOGjMp3EzqmzJizYMmKNRu27Nhz4MiJMxeu3Ljz4Ekqm7T8P52G8PP3lnTOVk++Z6iN6QZzNN1F7ptuN7eGOjDUoaGODHVsuvU8MdTO9Hd5aqgzQ50b6sJQl4a6MtS1oW4MdWuoO0PdG+rBUI+GejLUs6FeDPVqqDdDvRvqw1CfhpqM9At0iFLaAAB4nJ1YDXBTVRZ+5/22TUlJ8we0pHlJm7RJf5O8F2j6EymlSPkpxaL8U2xpa3DKj0CBhc2IW4eWKSokIoLsuMqssM64f+jA4HSdWXXXscBq67IOs3FXZ1ZYWVyRFdo899yXtIBQZ90k7717zz3v3HPPOfd854YCCj9cL9dL0RQFOqCbGJnrHb5EayiKIWN8iA/hWBblo6hUWm8TtCDwE80WMJus/irwyxOdxeB0MDb14VNJHnXYoLLSl6FfCUYO9nYPTA8Epg9090LprfbBbZ2hY0UlJUXHQp3/vtWkS6EBv8+rPMq5u9692f/dNxJNiqwC1xPE9TCUgCsSdQWgE3XQD25lkG4CN2xmTcOXWBOyser6RN6KnGbKSbmQ3+d0OI1m2W8QzLLkI2sykrWAgJJEtA8vGGW/2Q+CmT3n8zS9wZwu2DCvtuZKZN3xkrLh36yCZuUomQSqGpY8t/25VfHVhw8z4ebGBtfLb0ya9PCaDc+8dGTvk2dsh6z7WzvowlXKUSWo9MJ15a3KrEP2loOr2Ojhw6iW6hf2BDdEccQvZGpaAy7YovSwq8kr7HGllxpd71rkS6G0Sf11sl9OvMK1+jwPPODxjUwkOim9CU3ix1wNjXDfmJSEn618Bs6lpWwUpU+8PCqLMY650zjq8VhCIP17NEKTx3eaLL+s5Pi6yJWaWjTHLR1jYzPSV9VF/6Ojdb/1kO3Mk3uhHC0x6gc1BjlKQ+nQFxTYdaJkZ7ySVxLBbhR1dsboNXp1tCYKW2LRaEzpYcIx2BKNxaL0ZaUnSqfFoiNhHKR/GkX6PWUSAaJelQaqZL1EpoHNsajSEyPSoJ9IjhIxTdjHLmwZvhRDOiFTY/YeQnvrVZmiTQtGncECXtFTBZLOVwwMRgoXHAkXzMzPn1nAJJ8jYSbMDaqN2waGLzNhih/bZynUBMpIWSg7VYi7DRx2m8ALkIdRCJwI6ArJx2EI8kaDWeTQKeAFk9fjl/1AvwktjQ1P7NjyMGQyfd4vjipX6M/i52D7Cq80kqlcxEcGXRr/FEcgs0u5uGgB4VWuMFfpdn2Re6Hi3PqzmxWKsz6+ae2Pn9hXXw/fqM859UiGC0oKYYILJBqJrsn1Z1E5qOs9rQCiUQRREjm8yJcbHF5cUJufX1vAHlefw0XgUoboS3ETfQlTxBC4SOtuE8VPRJTBSCQSjZCpk7Gqzu+masaZ2y7Zjehho4F3g82BNDkAHpORG4+OCS+f6JTPmtRn/PH1kch6d04sp7AQb25aQ/pqUyXeQ8vrebG8OYQdXOQ+585u0sdW9rqalzRURiJ+9F4MweRFrKUjl1GUYhH1A27WOHw5cTFSFPMo9EeUIGnQTZHIaJ7AHLaOKsOODaNF9jkBjYG2QEsQ2xjMUAx2bBEbeTBWMHwskBjngq56S/yfgkBnWBa4K9sqKtq2t1UI8S9He5XuBRbawAdatrQEAi30Aks2+LM8WeCbalVZkWNylvJ+dqJnzVb+OHlSoKW8nPCP7Rd+CcZ2DdWAGqJ2CBFOphgywFFCFBNtfAbGtNPBCwxvygHeYMZMY9ZboBqwq/pVrsbgN5tkv152ODlbMfiqwGMBgxa4Exz3QhovRIUp6acqZmQzRq0ypDXS2TPLT02YIkQETnOE445oOGxOmXAqUJNNG7XgupMjPq2ua9asrj5yY/yuKteO1Kx0YNJTufrirLe1mZnat7OL6rnUdCWenpW6I8mAnbsY8KWs1PuSovCW9A/Z25PQ24a7cNOqgmTkLmBMgh4THgc4b9k2IVv1/g/F5nGljwPLfOgHAzJzh45V/4+WenTzmMtR5Z7us2Tys909UHqrPY7KbckoxRvRHhmVc3cJGE97uml0R1S0jdULVl7EvZtDFVBF35N9cEdjpgmAiOlFZ+Dtoh93+D3zzHr8RRNZQhnCNMNbcegOvpEwZoL+06cJQ07h+th3fZ/7PVbVC6ngTAV/KoLFuO6+2KFcU651gEb5ugPSIb1D+Xp8V4+k3sEIGnw5mYe4If4k1lFYr6SCzmM2EQ8iWtmwjnBI9kTwe1TlfAmXh7H02by9fW2gsjKwtv0aaURKil4OdV7rDL1MXIFNrhdxohcZXYTnq47WisrKitaObbf5+yvkLi5J6lCNZZ+B6GC38VNBZBDidSS/+mSvh6s+srgC8pyKMvDtt+de3c9fU76ZPfuM8ud4Kv0fyP/LqfepMT/3oZxSqpZaTa1DaQYLY8TFsHYbWYsPoRhRWfL5eSSQbhUGgGC3YLbVMk6PitTFNGpAsNrC6D1VNBKgBHMejaiuRWEWGgsSDBTJjqWIl8kJLlsaLJ2tXDr6xGfT85bM2Q06a46x2HTgvdnV8z5YDy/27J4zt6x2VtkzjoYpkq36kaBr4eQSg7tyiVweWubXZugtadl58ydapfbORfKsDTuZ0OBgx4cfdjCf5tbWNITnL120fdOi1RV1C3uKGzNdwYLcMvZ3BxoPyTOCD1XvXTp7U10gWCVmTV9b3r2z0SkGWovb2hp9I89O8a2smlyaO8muMU+dRmtzp60IzAoFpjLr1n388boLyf0dRvxhsHZ0qbWqDkwqvvpkj4l0fY6EIXRi5sQSrAvsVYwXRy4qJ2EVtD1AN7a0HWth9ymvL1xc3WTUKK/TAHA/bXDVtVWfOMfuGxGZv4Ln/jVr9jc3j1yMv0tndmyt9Vq88Y9gH1wtLX3KWjot5++jWHgAoZZkQ14wGQ20Fli71UmKJAy4xKMSTGbVdybW7FDDAut9XpD5AzWrYO7zQ8qffqF8+Ynd/clrHcdyxGy3a/3+mfNnzC/cBsveTjnTvXf1o6vzOlZw7WtqtdmPK/Errz/6NNtD72zmNOZfbmYdTGHfoofqI79Oc+R2n1lrnL6pOm0Up7kwxhTW12Amm7WYkXR2qYrF2AmgmbAsxZjwy1xpg/m1Je2vrp8v/nz2xpmlBg4E9hrMU341wVpTOh/OfmGvAnra8q6uctr60ZQHV3Q+WMQJykMj8ZsWn2QBOmmHMB+m5pDIpTFonYigiaKAhGEiAHF7EliVnQkjoLVIMPtJpBKHYd3A8GYH9jJzrWwmHx5Qjp7vDAX0suGRym1vtm/9W1/HyR8vczfMs6Sk8DSv855/5dlX9oQq52hT8syyp2rx5Id17IAyAM3wIjQPMOHzytEB64q6D5zT91yNbnx3V/nqnd017S9Y0605k3izoXLpsxde2n38yoOV9s1LcjwzNjbdX6asnBVaBj/6/DwKwPkpcqbDG7BnsXoSqWnUAmottYF6jMSdVyYZh3zVXCjwTiwwHH6sGuRiEHQGzuRX6whZkp123oy1BWE2mEfJ/tvIRtM4ZM5bDXiMsPMaAKOTyc5uL57rqyyc5y5JE5pm1i2S2iUX0CcaQ6lC6Zog7JqSqZmYlosl2K6pwNA84zRnQW6SaALYZQGW5lhCtU/W34N6o+bKfZ8cf3/Cl/+iTX3wBzpOY4mRkeNf3rptycGSshQWgGbYt5jFc2e0+DglIrwl6DVWQ7BuwaJ3Xk1J4VL5urnLl/Wf+gHU/hZoZdKNym6lG+I34FaNeZKcSpJIo2IeCVvpdsDGfKvzJnAwmeD37Ow65ZWwSowpgwX5T69s/rB55dP5BcpgDKFV8p7q2sn/1uc93bVzT/w6UrCqDTWvfCq/oCD/qZXNoUj8BL5Kp6GU017frfNXkAtiiyf/SOCEeLqnd8R/Ql9GlCRfctS6k5chvIBuQ1zCCjoCHL2DHNHIXxMJ3kQeO8lbsUXONeSfA5EjcG6/E+KdhN4bP04vBhdi883+BFBzQbxFbvZzQeY9LNBZc0FNfn5NwfDn6rCTnTw6R8o+gfpf5hCom33cRuiTlss3KHmZjD+BPN+5gXuA2ziS/Q73mLxUkpbKN/eqwz5uK0X9F3h2d1V4nGNgZGBgAOJd776+iue3+crAzc4AAje5Bfcg0xz9YHEOBiYQBQA8FQlFAHicY2BkYGBnAAGOPgaG//85+hkYGVCBMgBGGwNYAAAAeJxjYGBgYB8EmKOPgQEAQ04BfgAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhAi2COh4nGNgZGBgUGYoZWBnAAEmIOYCQgaG/2A+AwAYCQG2AHicXZBNaoNAGIZfE5PQCKFQ2lUps2oXBfOzzAESyDKBQJdGR2NQR3QSSE/QE/QEPUUPUHqsvsrXjTMw83zPvPMNCuAWP3DQDAejdm1GjzwS7pMmwi75XngAD4/CQ/oX4TFe4Qt7uMMbOzjuDc0EmXCP/C7cJ38Iu+RP4QEe8CU8pP8WHmOPX2EPz87TPo202ey2OjlnQSXV/6arOjWFmvszMWtd6CqwOlKHq6ovycLaWMWVydXKFFZnmVFlZU46tP7R2nI5ncbi/dDkfDtFBA2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0;background:0 0}.video-js .vjs-menu :focus:not(:focus-visible),.video-js :focus:not(:focus-visible){outline:0;background:0 0} \ No newline at end of file
diff --git a/assets/css/videojs-vtt-thumbnails-fix.css b/assets/css/videojs-vtt-thumbnails-fix.css
new file mode 100644
index 00000000..8b62cf0c
--- /dev/null
+++ b/assets/css/videojs-vtt-thumbnails-fix.css
@@ -0,0 +1,3 @@
+.video-js .vjs-vtt-thumbnail-display {
+ max-width: 158px;
+}
diff --git a/assets/js/community.js b/assets/js/community.js
index 754ec6d3..4077f1cd 100644
--- a/assets/js/community.js
+++ b/assets/js/community.js
@@ -1,3 +1,5 @@
+var community_data = JSON.parse(document.getElementById('community_data').innerHTML);
+
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g, function (a, b) {
var r = o[b];
diff --git a/assets/js/embed.js b/assets/js/embed.js
index 534c30ff..99d2fc53 100644
--- a/assets/js/embed.js
+++ b/assets/js/embed.js
@@ -1,3 +1,5 @@
+var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
+
function get_playlist(plid, retries) {
if (retries == undefined) retries = 5;
diff --git a/assets/js/global.js b/assets/js/global.js
new file mode 100644
index 00000000..efb447fb
--- /dev/null
+++ b/assets/js/global.js
@@ -0,0 +1,3 @@
+// Disable Web Workers. Fixes Video.js CSP violation (created by `new Worker(objURL)`):
+// Refused to create a worker from 'blob:http://host/id' because it violates the following Content Security Policy directive: "worker-src 'self'".
+window.Worker = undefined;
diff --git a/assets/js/handlers.js b/assets/js/handlers.js
new file mode 100644
index 00000000..b3da8d9b
--- /dev/null
+++ b/assets/js/handlers.js
@@ -0,0 +1,144 @@
+'use strict';
+
+(function () {
+ var n2a = function (n) { return Array.prototype.slice.call(n); };
+
+ var video_player = document.getElementById('player_html5_api');
+ if (video_player) {
+ video_player.onmouseenter = function () { video_player['data-title'] = video_player['title']; video_player['title'] = ''; };
+ video_player.onmouseleave = function () { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; };
+ video_player.oncontextmenu = function () { video_player['title'] = video_player['data-title']; };
+ }
+
+ // For dynamically inserted elements
+ document.addEventListener('click', function (e) {
+ if (!e || !e.target) { return; }
+ e = e.target;
+ var handler_name = e.getAttribute('data-onclick');
+ switch (handler_name) {
+ case 'jump_to_time':
+ var time = e.getAttribute('data-jump-time');
+ player.currentTime(time);
+ break;
+ case 'get_youtube_replies':
+ var load_more = e.getAttribute('data-load-more') !== null;
+ get_youtube_replies(e, load_more);
+ break;
+ case 'toggle_parent':
+ toggle_parent(e);
+ break;
+ default:
+ break;
+ }
+ });
+
+ n2a(document.querySelectorAll('[data-mouse="switch_classes"]')).forEach(function (e) {
+ var classes = e.getAttribute('data-switch-classes').split(',');
+ var ec = classes[0];
+ var lc = classes[1];
+ var onoff = function (on, off) {
+ var cs = e.getAttribute('class');
+ cs = cs.split(off).join(on);
+ e.setAttribute('class', cs);
+ };
+ e.onmouseenter = function () { onoff(ec, lc); };
+ e.onmouseleave = function () { onoff(lc, ec); };
+ });
+
+ n2a(document.querySelectorAll('[data-onsubmit="return_false"]')).forEach(function (e) {
+ e.onsubmit = function () { return false; };
+ });
+
+ n2a(document.querySelectorAll('[data-onclick="mark_watched"]')).forEach(function (e) {
+ e.onclick = function () { mark_watched(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function (e) {
+ e.onclick = function () { mark_unwatched(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="add_playlist_video"]')).forEach(function (e) {
+ e.onclick = function () { add_playlist_video(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function (e) {
+ e.onclick = function () { add_playlist_item(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="remove_playlist_item"]')).forEach(function (e) {
+ e.onclick = function () { remove_playlist_item(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="revoke_token"]')).forEach(function (e) {
+ e.onclick = function () { revoke_token(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="remove_subscription"]')).forEach(function (e) {
+ e.onclick = function () { remove_subscription(e); };
+ });
+ n2a(document.querySelectorAll('[data-onclick="notification_requestPermission"]')).forEach(function (e) {
+ e.onclick = function () { Notification.requestPermission(); };
+ });
+
+ n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function (e) {
+ var cb = function () { update_volume_value(e); }
+ e.oninput = cb;
+ e.onchange = cb;
+ });
+
+ function update_volume_value(element) {
+ document.getElementById('volume-value').innerText = element.value;
+ }
+
+ function revoke_token(target) {
+ var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
+ row.style.display = 'none';
+ var count = document.getElementById('count');
+ count.innerText = count.innerText - 1;
+
+ var referer = window.encodeURIComponent(document.location.href);
+ var url = '/token_ajax?action_revoke_token=1&redirect=false' +
+ '&referer=' + referer +
+ '&session=' + target.getAttribute('data-session');
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 10000;
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ if (xhr.status != 200) {
+ count.innerText = parseInt(count.innerText) + 1;
+ row.style.display = '';
+ }
+ }
+ }
+
+ var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value;
+ xhr.send('csrf_token=' + csrf_token);
+ }
+
+ function remove_subscription(target) {
+ var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
+ row.style.display = 'none';
+ var count = document.getElementById('count');
+ count.innerText = count.innerText - 1;
+
+ var referer = window.encodeURIComponent(document.location.href);
+ var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
+ '&referer=' + referer +
+ '&c=' + target.getAttribute('data-ucid');
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 10000;
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ if (xhr.status != 200) {
+ count.innerText = parseInt(count.innerText) + 1;
+ row.style.display = '';
+ }
+ }
+ }
+
+ var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value;
+ xhr.send('csrf_token=' + csrf_token);
+ }
+})();
diff --git a/assets/js/notifications.js b/assets/js/notifications.js
index fcfc01e7..3d1ec1ed 100644
--- a/assets/js/notifications.js
+++ b/assets/js/notifications.js
@@ -1,3 +1,5 @@
+var notification_data = JSON.parse(document.getElementById('notification_data').innerHTML);
+
var notifications, delivered;
function get_subscriptions(callback, retries) {
diff --git a/assets/js/player.js b/assets/js/player.js
index e58af0cd..f79fbbf3 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -1,3 +1,6 @@
+var player_data = JSON.parse(document.getElementById('player_data').innerHTML);
+var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
+
var options = {
preload: 'auto',
liveui: true,
@@ -35,7 +38,7 @@ var shareOptions = {
title: player_data.title,
description: player_data.description,
image: player_data.thumbnail,
- embedCode: "<iframe id='ivplayer' type='text/html' width='640' height='360' src='" + embed_url + "' frameborder='0'></iframe>"
+ embedCode: "<iframe id='ivplayer' width='640' height='360' src='" + embed_url + "' style='border:none;'></iframe>"
}
var player = videojs('player', options);
@@ -146,7 +149,8 @@ if (!video_data.params.listen && video_data.params.quality === 'dash') {
}
player.vttThumbnails({
- src: location.origin + '/api/v1/storyboards/' + video_data.id + '?height=90'
+ src: location.origin + '/api/v1/storyboards/' + video_data.id + '?height=90',
+ showTimestamp: true
});
// Enable annotations
@@ -228,11 +232,24 @@ function set_time_percent(percent) {
player.currentTime(newTime);
}
+function play() {
+ player.play();
+}
+
+function pause() {
+ player.pause();
+}
+
+function stop() {
+ player.pause();
+ player.currentTime(0);
+}
+
function toggle_play() {
if (player.paused()) {
- player.play();
+ play();
} else {
- player.pause();
+ pause();
}
}
@@ -338,9 +355,22 @@ window.addEventListener('keydown', e => {
switch (decoratedKey) {
case ' ':
case 'k':
+ case 'MediaPlayPause':
action = toggle_play;
break;
+ case 'MediaPlay':
+ action = play;
+ break;
+
+ case 'MediaPause':
+ action = pause;
+ break;
+
+ case 'MediaStop':
+ action = stop;
+ break;
+
case 'ArrowUp':
if (isPlayerFocused) {
action = increase_volume.bind(this, 0.1);
@@ -357,9 +387,11 @@ window.addEventListener('keydown', e => {
break;
case 'ArrowRight':
+ case 'MediaFastForward':
action = skip_seconds.bind(this, 5);
break;
case 'ArrowLeft':
+ case 'MediaTrackPrevious':
action = skip_seconds.bind(this, -5);
break;
case 'l':
@@ -391,9 +423,11 @@ window.addEventListener('keydown', e => {
break;
case 'N':
+ case 'MediaTrackNext':
action = next_video;
break;
case 'P':
+ case 'MediaTrackPrevious':
// TODO: Add support to play back previous video.
break;
diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js
index 5d6ddf87..0ec27859 100644
--- a/assets/js/playlist_widget.js
+++ b/assets/js/playlist_widget.js
@@ -1,3 +1,29 @@
+var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML);
+
+function add_playlist_video(target) {
+ var select = target.parentNode.children[0].children[1];
+ var option = select.children[select.selectedIndex];
+
+ var url = '/playlist_ajax?action_add_video=1&redirect=false' +
+ '&video_id=' + target.getAttribute('data-id') +
+ '&playlist_id=' + option.getAttribute('data-plid');
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 10000;
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ option.innerText = '✓' + option.innerText;
+ }
+ }
+ }
+
+ xhr.send('csrf_token=' + playlist_data.csrf_token);
+}
+
function add_playlist_item(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none';
diff --git a/assets/js/silvermine-videojs-quality-selector.min.js b/assets/js/silvermine-videojs-quality-selector.min.js
index e4869564..88621e8d 100644
--- a/assets/js/silvermine-videojs-quality-selector.min.js
+++ b/assets/js/silvermine-videojs-quality-selector.min.js
@@ -1,3 +1,4 @@
-/*! @silvermine/videojs-quality-selector 2019-09-26 v1.2.2-4-gc134430-dirty */
+/*! @silvermine/videojs-quality-selector 2020-03-02 v1.1.2-36-g64d620a-dirty */
-!function u(o,c,a){function l(e,n){if(!c[e]){if(!o[e]){var t="function"==typeof require&&require;if(!n&&t)return t(e,!0);if(s)return s(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var i=c[e]={exports:{}};o[e][0].call(i.exports,function(n){return l(o[e][1][n]||n)},i,i.exports,u,o,c,a)}return c[e].exports}for(var s="function"==typeof require&&require,n=0;n<a.length;n++)l(a[n]);return l}({1:[function(n,e,t){!function(){var c=!1,a=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(n,e){null==e&&(e=n,n="Class");var i=this.prototype;c=!0;var t=new this;for(var r in c=!1,e)t[r]="function"==typeof e[r]&&"function"==typeof i[r]&&a.test(e[r])?function(t,r){return function(){var n=this._super;this._super=i[t];var e=r.apply(this,arguments);return this._super=n,e}}(r,e[r]):e[r];function u(){!c&&this.init&&this.init.apply(this,arguments)}u.prototype=t;var o=new Function("return function "+n+"(){ }")();return u.prototype.constructor=o,u.extend=arguments.callee,u},e.exports=Class}()},{}],2:[function(n,G,H){(function($){!function(){function t(){}var n="object"==typeof self&&self.self===self&&self||"object"==typeof $&&$.global===$&&$||this||{},e=n._,r=Array.prototype,o=Object.prototype,f="undefined"!=typeof Symbol?Symbol.prototype:null,i=r.push,a=r.slice,p=o.toString,u=o.hasOwnProperty,c=Array.isArray,l=Object.keys,s=Object.create,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};void 0===H||H.nodeType?n._=h:(void 0!==G&&!G.nodeType&&G.exports&&(H=G.exports=h),H._=h),h.VERSION="1.9.1";function v(i,u,n){if(void 0===u)return i;switch(null==n?3:n){case 1:return function(n){return i.call(u,n)};case 3:return function(n,e,t){return i.call(u,n,e,t)};case 4:return function(n,e,t,r){return i.call(u,n,e,t,r)}}return function(){return i.apply(u,arguments)}}function y(n,e,t){return h.iteratee!==d?h.iteratee(n,e):null==n?h.identity:h.isFunction(n)?v(n,e,t):h.isObject(n)&&!h.isArray(n)?h.matcher(n):h.property(n)}var d;h.iteratee=d=function(n,e){return y(n,e,1/0)};function g(i,u){return u=null==u?i.length-1:+u,function(){for(var n=Math.max(arguments.length-u,0),e=Array(n),t=0;t<n;t++)e[t]=arguments[t+u];switch(u){case 0:return i.call(this,e);case 1:return i.call(this,arguments[0],e);case 2:return i.call(this,arguments[0],arguments[1],e)}var r=Array(u+1);for(t=0;t<u;t++)r[t]=arguments[t];return r[u]=e,i.apply(this,r)}}function m(n){if(!h.isObject(n))return{};if(s)return s(n);t.prototype=n;var e=new t;return t.prototype=null,e}function S(e){return function(n){return null==n?void 0:n[e]}}function b(n,e){return null!=n&&u.call(n,e)}function _(n,e){for(var t=e.length,r=0;r<t;r++){if(null==n)return;n=n[e[r]]}return t?n:void 0}function x(n){var e=j(n);return"number"==typeof e&&0<=e&&e<=k}var k=Math.pow(2,53)-1,j=S("length");h.each=h.forEach=function(n,e,t){var r,i;if(e=v(e,t),x(n))for(r=0,i=n.length;r<i;r++)e(n[r],r,n);else{var u=h.keys(n);for(r=0,i=u.length;r<i;r++)e(n[u[r]],u[r],n)}return n},h.map=h.collect=function(n,e,t){e=y(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=Array(i),o=0;o<i;o++){var c=r?r[o]:o;u[o]=e(n[c],c,n)}return u};function w(a){return function(n,e,t,r){var i=3<=arguments.length;return function(n,e,t,r){var i=!x(n)&&h.keys(n),u=(i||n).length,o=0<a?0:u-1;for(r||(t=n[i?i[o]:o],o+=a);0<=o&&o<u;o+=a){var c=i?i[o]:o;t=e(t,n[c],c,n)}return t}(n,v(e,r,4),t,i)}}h.reduce=h.foldl=h.inject=w(1),h.reduceRight=h.foldr=w(-1),h.find=h.detect=function(n,e,t){var r=(x(n)?h.findIndex:h.findKey)(n,e,t);if(void 0!==r&&-1!==r)return n[r]},h.filter=h.select=function(n,r,e){var i=[];return r=y(r,e),h.each(n,function(n,e,t){r(n,e,t)&&i.push(n)}),i},h.reject=function(n,e,t){return h.filter(n,h.negate(y(e)),t)},h.every=h.all=function(n,e,t){e=y(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=0;u<i;u++){var o=r?r[u]:u;if(!e(n[o],o,n))return!1}return!0},h.some=h.any=function(n,e,t){e=y(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=0;u<i;u++){var o=r?r[u]:u;if(e(n[o],o,n))return!0}return!1},h.contains=h.includes=h.include=function(n,e,t,r){return x(n)||(n=h.values(n)),"number"==typeof t&&!r||(t=0),0<=h.indexOf(n,e,t)},h.invoke=g(function(n,t,r){var i,u;return h.isFunction(t)?u=t:h.isArray(t)&&(i=t.slice(0,-1),t=t[t.length-1]),h.map(n,function(n){var e=u;if(!e){if(i&&i.length&&(n=_(n,i)),null==n)return;e=n[t]}return null==e?e:e.apply(n,r)})}),h.pluck=function(n,e){return h.map(n,h.property(e))},h.where=function(n,e){return h.filter(n,h.matcher(e))},h.findWhere=function(n,e){return h.find(n,h.matcher(e))},h.max=function(n,r,e){var t,i,u=-1/0,o=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var c=0,a=(n=x(n)?n:h.values(n)).length;c<a;c++)null!=(t=n[c])&&u<t&&(u=t);else r=y(r,e),h.each(n,function(n,e,t){i=r(n,e,t),(o<i||i===-1/0&&u===-1/0)&&(u=n,o=i)});return u},h.min=function(n,r,e){var t,i,u=1/0,o=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var c=0,a=(n=x(n)?n:h.values(n)).length;c<a;c++)null!=(t=n[c])&&t<u&&(u=t);else r=y(r,e),h.each(n,function(n,e,t){((i=r(n,e,t))<o||i===1/0&&u===1/0)&&(u=n,o=i)});return u},h.shuffle=function(n){return h.sample(n,1/0)},h.sample=function(n,e,t){if(null==e||t)return x(n)||(n=h.values(n)),n[h.random(n.length-1)];var r=x(n)?h.clone(n):h.values(n),i=j(r);e=Math.max(Math.min(e,i),0);for(var u=i-1,o=0;o<e;o++){var c=h.random(o,u),a=r[o];r[o]=r[c],r[c]=a}return r.slice(0,e)},h.sortBy=function(n,r,e){var i=0;return r=y(r,e),h.pluck(h.map(n,function(n,e,t){return{value:n,index:i++,criteria:r(n,e,t)}}).sort(function(n,e){var t=n.criteria,r=e.criteria;if(t!==r){if(r<t||void 0===t)return 1;if(t<r||void 0===r)return-1}return n.index-e.index}),"value")};function A(o,e){return function(r,i,n){var u=e?[[],[]]:{};return i=y(i,n),h.each(r,function(n,e){var t=i(n,e,r);o(u,n,t)}),u}}h.groupBy=A(function(n,e,t){b(n,t)?n[t].push(e):n[t]=[e]}),h.indexBy=A(function(n,e,t){n[t]=e}),h.countBy=A(function(n,e,t){b(n,t)?n[t]++:n[t]=1});var E=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;h.toArray=function(n){return n?h.isArray(n)?a.call(n):h.isString(n)?n.match(E):x(n)?h.map(n,h.identity):h.values(n):[]},h.size=function(n){return null==n?0:x(n)?n.length:h.keys(n).length},h.partition=A(function(n,e,t){n[t?0:1].push(e)},!0),h.first=h.head=h.take=function(n,e,t){return null==n||n.length<1?null==e?void 0:[]:null==e||t?n[0]:h.initial(n,n.length-e)},h.initial=function(n,e,t){return a.call(n,0,Math.max(0,n.length-(null==e||t?1:e)))},h.last=function(n,e,t){return null==n||n.length<1?null==e?void 0:[]:null==e||t?n[n.length-1]:h.rest(n,Math.max(0,n.length-e))},h.rest=h.tail=h.drop=function(n,e,t){return a.call(n,null==e||t?1:e)},h.compact=function(n){return h.filter(n,Boolean)};var T=function(n,e,t,r){for(var i=(r=r||[]).length,u=0,o=j(n);u<o;u++){var c=n[u];if(x(c)&&(h.isArray(c)||h.isArguments(c)))if(e)for(var a=0,l=c.length;a<l;)r[i++]=c[a++];else T(c,e,t,r),i=r.length;else t||(r[i++]=c)}return r};h.flatten=function(n,e){return T(n,e,!1)},h.without=g(function(n,e){return h.difference(n,e)}),h.uniq=h.unique=function(n,e,t,r){h.isBoolean(e)||(r=t,t=e,e=!1),null!=t&&(t=y(t,r));for(var i=[],u=[],o=0,c=j(n);o<c;o++){var a=n[o],l=t?t(a,o,n):a;e&&!t?(o&&u===l||i.push(a),u=l):t?h.contains(u,l)||(u.push(l),i.push(a)):h.contains(i,a)||i.push(a)}return i},h.union=g(function(n){return h.uniq(T(n,!0,!0))}),h.intersection=function(n){for(var e=[],t=arguments.length,r=0,i=j(n);r<i;r++){var u=n[r];if(!h.contains(e,u)){var o;for(o=1;o<t&&h.contains(arguments[o],u);o++);o===t&&e.push(u)}}return e},h.difference=g(function(n,e){return e=T(e,!0,!0),h.filter(n,function(n){return!h.contains(e,n)})}),h.unzip=function(n){for(var e=n&&h.max(n,j).length||0,t=Array(e),r=0;r<e;r++)t[r]=h.pluck(n,r);return t},h.zip=g(h.unzip),h.object=function(n,e){for(var t={},r=0,i=j(n);r<i;r++)e?t[n[r]]=e[r]:t[n[r][0]]=n[r][1];return t};function O(u){return function(n,e,t){e=y(e,t);for(var r=j(n),i=0<u?0:r-1;0<=i&&i<r;i+=u)if(e(n[i],i,n))return i;return-1}}h.findIndex=O(1),h.findLastIndex=O(-1),h.sortedIndex=function(n,e,t,r){for(var i=(t=y(t,r,1))(e),u=0,o=j(n);u<o;){var c=Math.floor((u+o)/2);t(n[c])<i?u=c+1:o=c}return u};function C(u,o,c){return function(n,e,t){var r=0,i=j(n);if("number"==typeof t)0<u?r=0<=t?t:Math.max(t+i,r):i=0<=t?Math.min(t+1,i):t+i+1;else if(c&&t&&i)return n[t=c(n,e)]===e?t:-1;if(e!=e)return 0<=(t=o(a.call(n,r,i),h.isNaN))?t+r:-1;for(t=0<u?r:i-1;0<=t&&t<i;t+=u)if(n[t]===e)return t;return-1}}h.indexOf=C(1,h.findIndex,h.sortedIndex),h.lastIndexOf=C(-1,h.findLastIndex),h.range=function(n,e,t){null==e&&(e=n||0,n=0),t=t||(e<n?-1:1);for(var r=Math.max(Math.ceil((e-n)/t),0),i=Array(r),u=0;u<r;u++,n+=t)i[u]=n;return i},h.chunk=function(n,e){if(null==e||e<1)return[];for(var t=[],r=0,i=n.length;r<i;)t.push(a.call(n,r,r+=e));return t};function I(n,e,t,r,i){if(!(r instanceof e))return n.apply(t,i);var u=m(n.prototype),o=n.apply(u,i);return h.isObject(o)?o:u}h.bind=g(function(e,t,r){if(!h.isFunction(e))throw new TypeError("Bind must be called on a function");var i=g(function(n){return I(e,i,t,this,r.concat(n))});return i}),h.partial=g(function(i,u){var o=h.partial.placeholder,c=function(){for(var n=0,e=u.length,t=Array(e),r=0;r<e;r++)t[r]=u[r]===o?arguments[n++]:u[r];for(;n<arguments.length;)t.push(arguments[n++]);return I(i,c,this,this,t)};return c}),(h.partial.placeholder=h).bindAll=g(function(n,e){var t=(e=T(e,!1,!1)).length;if(t<1)throw new Error("bindAll must be passed function names");for(;t--;){var r=e[t];n[r]=h.bind(n[r],n)}}),h.memoize=function(r,i){var u=function(n){var e=u.cache,t=""+(i?i.apply(this,arguments):n);return b(e,t)||(e[t]=r.apply(this,arguments)),e[t]};return u.cache={},u},h.delay=g(function(n,e,t){return setTimeout(function(){return n.apply(null,t)},e)}),h.defer=h.partial(h.delay,h,1),h.throttle=function(t,r,i){var u,o,c,a,l=0;i=i||{};function s(){l=!1===i.leading?0:h.now(),u=null,a=t.apply(o,c),u||(o=c=null)}function n(){var n=h.now();l||!1!==i.leading||(l=n);var e=r-(n-l);return o=this,c=arguments,e<=0||r<e?(u&&(clearTimeout(u),u=null),l=n,a=t.apply(o,c),u||(o=c=null)):u||!1===i.trailing||(u=setTimeout(s,e)),a}return n.cancel=function(){clearTimeout(u),l=0,u=o=c=null},n},h.debounce=function(t,r,i){function u(n,e){o=null,e&&(c=t.apply(n,e))}var o,c,n=g(function(n){if(o&&clearTimeout(o),i){var e=!o;o=setTimeout(u,r),e&&(c=t.apply(this,n))}else o=h.delay(u,r,this,n);return c});return n.cancel=function(){clearTimeout(o),o=null},n},h.wrap=function(n,e){return h.partial(e,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var t=arguments,r=t.length-1;return function(){for(var n=r,e=t[r].apply(this,arguments);n--;)e=t[n].call(this,e);return e}},h.after=function(n,e){return function(){if(--n<1)return e.apply(this,arguments)}},h.before=function(n,e){var t;return function(){return 0<--n&&(t=e.apply(this,arguments)),n<=1&&(e=null),t}},h.once=h.partial(h.before,2),h.restArguments=g;function F(n,e){var t=M.length,r=n.constructor,i=h.isFunction(r)&&r.prototype||o,u="constructor";for(b(n,u)&&!h.contains(e,u)&&e.push(u);t--;)(u=M[t])in n&&n[u]!==i[u]&&!h.contains(e,u)&&e.push(u)}var q=!{toString:null}.propertyIsEnumerable("toString"),M=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];h.keys=function(n){if(!h.isObject(n))return[];if(l)return l(n);var e=[];for(var t in n)b(n,t)&&e.push(t);return q&&F(n,e),e},h.allKeys=function(n){if(!h.isObject(n))return[];var e=[];for(var t in n)e.push(t);return q&&F(n,e),e},h.values=function(n){for(var e=h.keys(n),t=e.length,r=Array(t),i=0;i<t;i++)r[i]=n[e[i]];return r},h.mapObject=function(n,e,t){e=y(e,t);for(var r=h.keys(n),i=r.length,u={},o=0;o<i;o++){var c=r[o];u[c]=e(n[c],c,n)}return u},h.pairs=function(n){for(var e=h.keys(n),t=e.length,r=Array(t),i=0;i<t;i++)r[i]=[e[i],n[e[i]]];return r},h.invert=function(n){for(var e={},t=h.keys(n),r=0,i=t.length;r<i;r++)e[n[t[r]]]=t[r];return e},h.functions=h.methods=function(n){var e=[];for(var t in n)h.isFunction(n[t])&&e.push(t);return e.sort()};function N(a,l){return function(n){var e=arguments.length;if(l&&(n=Object(n)),e<2||null==n)return n;for(var t=1;t<e;t++)for(var r=arguments[t],i=a(r),u=i.length,o=0;o<u;o++){var c=i[o];l&&void 0!==n[c]||(n[c]=r[c])}return n}}h.extend=N(h.allKeys),h.extendOwn=h.assign=N(h.keys),h.findKey=function(n,e,t){e=y(e,t);for(var r,i=h.keys(n),u=0,o=i.length;u<o;u++)if(e(n[r=i[u]],r,n))return r};function Q(n,e,t){return e in t}var L,R;h.pick=g(function(n,e){var t={},r=e[0];if(null==n)return t;h.isFunction(r)?(1<e.length&&(r=v(r,e[1])),e=h.allKeys(n)):(r=Q,e=T(e,!1,!1),n=Object(n));for(var i=0,u=e.length;i<u;i++){var o=e[i],c=n[o];r(c,o,n)&&(t[o]=c)}return t}),h.omit=g(function(n,t){var e,r=t[0];return h.isFunction(r)?(r=h.negate(r),1<t.length&&(e=t[1])):(t=h.map(T(t,!1,!1),String),r=function(n,e){return!h.contains(t,e)}),h.pick(n,r,e)}),h.defaults=N(h.allKeys,!0),h.create=function(n,e){var t=m(n);return e&&h.extendOwn(t,e),t},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,e){return e(n),n},h.isMatch=function(n,e){var t=h.keys(e),r=t.length;if(null==n)return!r;for(var i=Object(n),u=0;u<r;u++){var o=t[u];if(e[o]!==i[o]||!(o in i))return!1}return!0},L=function(n,e,t,r){if(n===e)return 0!==n||1/n==1/e;if(null==n||null==e)return!1;if(n!=n)return e!=e;var i=typeof n;return("function"==i||"object"==i||"object"==typeof e)&&R(n,e,t,r)},R=function(n,e,t,r){n instanceof h&&(n=n._wrapped),e instanceof h&&(e=e._wrapped);var i=p.call(n);if(i!==p.call(e))return!1;switch(i){case"[object RegExp]":case"[object String]":return""+n==""+e;case"[object Number]":return+n!=+n?+e!=+e:0==+n?1/+n==1/e:+n==+e;case"[object Date]":case"[object Boolean]":return+n==+e;case"[object Symbol]":return f.valueOf.call(n)===f.valueOf.call(e)}var u="[object Array]"===i;if(!u){if("object"!=typeof n||"object"!=typeof e)return!1;var o=n.constructor,c=e.constructor;if(o!==c&&!(h.isFunction(o)&&o instanceof o&&h.isFunction(c)&&c instanceof c)&&"constructor"in n&&"constructor"in e)return!1}r=r||[];for(var a=(t=t||[]).length;a--;)if(t[a]===n)return r[a]===e;if(t.push(n),r.push(e),u){if((a=n.length)!==e.length)return!1;for(;a--;)if(!L(n[a],e[a],t,r))return!1}else{var l,s=h.keys(n);if(a=s.length,h.keys(e).length!==a)return!1;for(;a--;)if(l=s[a],!b(e,l)||!L(n[l],e[l],t,r))return!1}return t.pop(),r.pop(),!0},h.isEqual=function(n,e){return L(n,e)},h.isEmpty=function(n){return null==n||(x(n)&&(h.isArray(n)||h.isString(n)||h.isArguments(n))?0===n.length:0===h.keys(n).length)},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=c||function(n){return"[object Array]"===p.call(n)},h.isObject=function(n){var e=typeof n;return"function"==e||"object"==e&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp","Error","Symbol","Map","WeakMap","Set","WeakSet"],function(e){h["is"+e]=function(n){return p.call(n)==="[object "+e+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return b(n,"callee")});var U=n.document&&n.document.childNodes;"function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof U&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return!h.isSymbol(n)&&isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&isNaN(n)},h.isBoolean=function(n){return!0===n||!1===n||"[object Boolean]"===p.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return void 0===n},h.has=function(n,e){if(!h.isArray(e))return b(n,e);for(var t=e.length,r=0;r<t;r++){var i=e[r];if(null==n||!u.call(n,i))return!1;n=n[i]}return!!t},h.noConflict=function(){return n._=e,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(e){return h.isArray(e)?function(n){return _(n,e)}:S(e)},h.propertyOf=function(e){return null==e?function(){}:function(n){return h.isArray(n)?_(e,n):e[n]}},h.matcher=h.matches=function(e){return e=h.extendOwn({},e),function(n){return h.isMatch(n,e)}},h.times=function(n,e,t){var r=Array(Math.max(0,n));e=v(e,t,1);for(var i=0;i<n;i++)r[i]=e(i);return r},h.random=function(n,e){return null==e&&(e=n,n=0),n+Math.floor(Math.random()*(e-n+1))},h.now=Date.now||function(){return(new Date).getTime()};function W(e){function t(n){return e[n]}var n="(?:"+h.keys(e).join("|")+")",r=RegExp(n),i=RegExp(n,"g");return function(n){return n=null==n?"":""+n,r.test(n)?n.replace(i,t):n}}var D={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},B=h.invert(D);h.escape=W(D),h.unescape=W(B),h.result=function(n,e,t){h.isArray(e)||(e=[e]);var r=e.length;if(!r)return h.isFunction(t)?t.call(n):t;for(var i=0;i<r;i++){var u=null==n?void 0:n[e[i]];void 0===u&&(u=t,i=r),n=h.isFunction(u)?u.call(n):u}return n};var P=0;h.uniqueId=function(n){var e=++P+"";return n?n+e:e},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function z(n){return"\\"+K[n]}var Y=/(.)^/,K={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},V=/\\|'|\r|\n|\u2028|\u2029/g;h.template=function(u,n,e){!n&&e&&(n=e),n=h.defaults({},n,h.templateSettings);var t,r=RegExp([(n.escape||Y).source,(n.interpolate||Y).source,(n.evaluate||Y).source].join("|")+"|$","g"),o=0,c="__p+='";u.replace(r,function(n,e,t,r,i){return c+=u.slice(o,i).replace(V,z),o=i+n.length,e?c+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":t?c+="'+\n((__t=("+t+"))==null?'':__t)+\n'":r&&(c+="';\n"+r+"\n__p+='"),n}),c+="';\n",n.variable||(c="with(obj||{}){\n"+c+"}\n"),c="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+c+"return __p;\n";try{t=new Function(n.variable||"obj","_",c)}catch(n){throw n.source=c,n}function i(n){return t.call(this,n,h)}var a=n.variable||"obj";return i.source="function("+a+"){\n"+c+"}",i},h.chain=function(n){var e=h(n);return e._chain=!0,e};function J(n,e){return n._chain?h(e).chain():e}h.mixin=function(t){return h.each(h.functions(t),function(n){var e=h[n]=t[n];h.prototype[n]=function(){var n=[this._wrapped];return i.apply(n,arguments),J(this,e.apply(h,n))}}),h},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];h.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),"shift"!==e&&"splice"!==e||0!==n.length||delete n[0],J(this,n)}}),h.each(["concat","join","slice"],function(n){var e=r[n];h.prototype[n]=function(){return J(this,e.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},h.prototype.valueOf=h.prototype.toJSON=h.prototype.value,h.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events");e.exports=function(n){var r=n.getComponent("MenuItem");return n.extend(r,{constructor:function(n,e){var t=e.source;if(!i.isObject(t))throw new Error('was not provided a "source" object, but rather: '+typeof t);e=i.extend({selectable:!0,label:t.label},e),r.call(this,n,e),this.source=t},handleClick:function(n){r.prototype.handleClick.call(this,n),this.player().trigger(u.QUALITY_REQUESTED,this.source)}})}},{"../events":5,underscore:2}],4:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events"),o=n("./QualityOption"),c="vjs-quality-changing";e.exports=function(n){var e,r=n.getComponent("MenuButton"),t=o(n);return e=n.extend(r,{constructor:function(t,n){r.call(this,t,n),t.on(u.QUALITY_REQUESTED,function(n,e){this.setSelectedSource(e),t.addClass(c),t.one("loadeddata",function(){t.removeClass(c)})}.bind(this)),t.on(u.QUALITY_SELECTED,function(n,e){this.setSelectedSource(e)}.bind(this)),t.one("ready",function(){this.selectedSrc=t.src(),this.update()}.bind(this)),this.controlText("Open quality selector menu")},setSelectedSource:function(n){var e=n?n.src:void 0;this.selectedSrc!==e&&(this.selectedSrc=e,i.each(this.items,function(n){n.selected(n.source.src===e)}))},createItems:function(){var e=this.player(),n=e.currentSources();return i.map(n,function(n){return new t(e,{source:n,selected:n.src===this.selectedSrc})}.bind(this))},buildWrapperCSSClass:function(){return"vjs-quality-selector "+r.prototype.buildWrapperCSSClass.call(this)}}),n.registerComponent("QualitySelector",e),e}},{"../events":5,"./QualityOption":3,underscore:2}],5:[function(n,e,t){"use strict";e.exports={QUALITY_REQUESTED:"qualityRequested",QUALITY_SELECTED:"qualitySelected"}},{}],6:[function(n,e,t){"use strict";var c=n("underscore"),r=n("./events"),i=n("./components/QualitySelector"),u=n("./middleware/SourceInterceptor"),a=n("./util/SafeSeek");e.exports=function(n){n=n||window.videojs,i(n),u(n),n.hook("setup",function(o){o.on(r.QUALITY_REQUESTED,function(n,e){var t=o.currentSources(),r=o.currentTime(),i=o.playbackRate(),u=o.paused();c.each(t,function(n){n.selected=!1}),c.findWhere(t,{src:e.src}).selected=!0,o._qualitySelectorSafeSeek&&o._qualitySelectorSafeSeek.onQualitySelectionChange(),o.src(t),o.ready(function(){o._qualitySelectorSafeSeek&&!o._qualitySelectorSafeSeek.hasFinished()||(o._qualitySelectorSafeSeek=new a(o,r),o.playbackRate(i)),u||o.play()})})})},e.exports.EVENTS=r},{"./components/QualitySelector":4,"./events":5,"./middleware/SourceInterceptor":7,"./util/SafeSeek":9,underscore:2}],7:[function(n,e,t){"use strict";var u=n("underscore"),o=n("../events");e.exports=function(n){n.use("*",function(i){return{setSource:function(n,e){var t,r=i.currentSources();i._qualitySelectorSafeSeek&&i._qualitySelectorSafeSeek.onPlayerSourcesChange(),t=u.find(r,function(n){return!0===n.selected||"true"===n.selected})||n,i.trigger(o.QUALITY_SELECTED,t),e(null,t)}}})}},{"../events":5,underscore:2}],8:[function(n,e,t){"use strict";n("./index")()},{"./index":6}],9:[function(n,e,t){"use strict";var r=n("class.extend");e.exports=r.extend({init:function(n,e){this._player=n,this._seekToTime=e,this._hasFinished=!1,this._keepThisInstanceWhenPlayerSourcesChange=!1,this._seekWhenSafe()},_seekWhenSafe:function(){this._player.readyState()<3?(this._seekFn=this._seek.bind(this),this._player.one("canplay",this._seekFn)):this._seek()},onPlayerSourcesChange:function(){this._keepThisInstanceWhenPlayerSourcesChange?this._keepThisInstanceWhenPlayerSourcesChange=!1:this.cancel()},onQualitySelectionChange:function(){this.hasFinished()||(this._keepThisInstanceWhenPlayerSourcesChange=!0)},_seek:function(){this._player.currentTime(this._seekToTime),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0},hasFinished:function(){return this._hasFinished},cancel:function(){this._player.off("canplay",this._seekFn),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0}})},{"class.extend":1}]},{},[8]); \ No newline at end of file
+!function u(o,c,a){function l(e,n){if(!c[e]){if(!o[e]){var t="function"==typeof require&&require;if(!n&&t)return t(e,!0);if(s)return s(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var i=c[e]={exports:{}};o[e][0].call(i.exports,function(n){return l(o[e][1][n]||n)},i,i.exports,u,o,c,a)}return c[e].exports}for(var s="function"==typeof require&&require,n=0;n<a.length;n++)l(a[n]);return l}({1:[function(n,e,t){!function(){var u=!1,o=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(n){var i=this.prototype;u=!0;var e=new this;for(var t in u=!1,n)e[t]="function"==typeof n[t]&&"function"==typeof i[t]&&o.test(n[t])?function(t,r){return function(){var n=this._super;this._super=i[t];var e=r.apply(this,arguments);return this._super=n,e}}(t,n[t]):n[t];function r(){!u&&this.init&&this.init.apply(this,arguments)}return((r.prototype=e).constructor=r).extend=arguments.callee,r},e.exports=Class}()},{}],2:[function(n,J,$){(function(V){!function(){function t(){}var n="object"==typeof self&&self.self===self&&self||"object"==typeof V&&V.global===V&&V||this||{},e=n._,r=Array.prototype,o=Object.prototype,f="undefined"!=typeof Symbol?Symbol.prototype:null,i=r.push,a=r.slice,p=o.toString,u=o.hasOwnProperty,c=Array.isArray,l=Object.keys,s=Object.create,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};void 0===$||$.nodeType?n._=h:(void 0!==J&&!J.nodeType&&J.exports&&($=J.exports=h),$._=h),h.VERSION="1.9.1";function d(i,u,n){if(void 0===u)return i;switch(null==n?3:n){case 1:return function(n){return i.call(u,n)};case 3:return function(n,e,t){return i.call(u,n,e,t)};case 4:return function(n,e,t,r){return i.call(u,n,e,t,r)}}return function(){return i.apply(u,arguments)}}function v(n,e,t){return h.iteratee!==y?h.iteratee(n,e):null==n?h.identity:h.isFunction(n)?d(n,e,t):h.isObject(n)&&!h.isArray(n)?h.matcher(n):h.property(n)}var y;h.iteratee=y=function(n,e){return v(n,e,1/0)};function g(i,u){return u=null==u?i.length-1:+u,function(){for(var n=Math.max(arguments.length-u,0),e=Array(n),t=0;t<n;t++)e[t]=arguments[t+u];switch(u){case 0:return i.call(this,e);case 1:return i.call(this,arguments[0],e);case 2:return i.call(this,arguments[0],arguments[1],e)}var r=Array(u+1);for(t=0;t<u;t++)r[t]=arguments[t];return r[u]=e,i.apply(this,r)}}function S(n){if(!h.isObject(n))return{};if(s)return s(n);t.prototype=n;var e=new t;return t.prototype=null,e}function m(e){return function(n){return null==n?void 0:n[e]}}function _(n,e){return null!=n&&u.call(n,e)}function b(n,e){for(var t=e.length,r=0;r<t;r++){if(null==n)return;n=n[e[r]]}return t?n:void 0}function x(n){var e=j(n);return"number"==typeof e&&0<=e&&e<=k}var k=Math.pow(2,53)-1,j=m("length");h.each=h.forEach=function(n,e,t){var r,i;if(e=d(e,t),x(n))for(r=0,i=n.length;r<i;r++)e(n[r],r,n);else{var u=h.keys(n);for(r=0,i=u.length;r<i;r++)e(n[u[r]],u[r],n)}return n},h.map=h.collect=function(n,e,t){e=v(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=Array(i),o=0;o<i;o++){var c=r?r[o]:o;u[o]=e(n[c],c,n)}return u};function E(a){return function(n,e,t,r){var i=3<=arguments.length;return function(n,e,t,r){var i=!x(n)&&h.keys(n),u=(i||n).length,o=0<a?0:u-1;for(r||(t=n[i?i[o]:o],o+=a);0<=o&&o<u;o+=a){var c=i?i[o]:o;t=e(t,n[c],c,n)}return t}(n,d(e,r,4),t,i)}}h.reduce=h.foldl=h.inject=E(1),h.reduceRight=h.foldr=E(-1),h.find=h.detect=function(n,e,t){var r=(x(n)?h.findIndex:h.findKey)(n,e,t);if(void 0!==r&&-1!==r)return n[r]},h.filter=h.select=function(n,r,e){var i=[];return r=v(r,e),h.each(n,function(n,e,t){r(n,e,t)&&i.push(n)}),i},h.reject=function(n,e,t){return h.filter(n,h.negate(v(e)),t)},h.every=h.all=function(n,e,t){e=v(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=0;u<i;u++){var o=r?r[u]:u;if(!e(n[o],o,n))return!1}return!0},h.some=h.any=function(n,e,t){e=v(e,t);for(var r=!x(n)&&h.keys(n),i=(r||n).length,u=0;u<i;u++){var o=r?r[u]:u;if(e(n[o],o,n))return!0}return!1},h.contains=h.includes=h.include=function(n,e,t,r){return x(n)||(n=h.values(n)),"number"==typeof t&&!r||(t=0),0<=h.indexOf(n,e,t)},h.invoke=g(function(n,t,r){var i,u;return h.isFunction(t)?u=t:h.isArray(t)&&(i=t.slice(0,-1),t=t[t.length-1]),h.map(n,function(n){var e=u;if(!e){if(i&&i.length&&(n=b(n,i)),null==n)return;e=n[t]}return null==e?e:e.apply(n,r)})}),h.pluck=function(n,e){return h.map(n,h.property(e))},h.where=function(n,e){return h.filter(n,h.matcher(e))},h.findWhere=function(n,e){return h.find(n,h.matcher(e))},h.max=function(n,r,e){var t,i,u=-1/0,o=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var c=0,a=(n=x(n)?n:h.values(n)).length;c<a;c++)null!=(t=n[c])&&u<t&&(u=t);else r=v(r,e),h.each(n,function(n,e,t){i=r(n,e,t),(o<i||i===-1/0&&u===-1/0)&&(u=n,o=i)});return u},h.min=function(n,r,e){var t,i,u=1/0,o=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var c=0,a=(n=x(n)?n:h.values(n)).length;c<a;c++)null!=(t=n[c])&&t<u&&(u=t);else r=v(r,e),h.each(n,function(n,e,t){((i=r(n,e,t))<o||i===1/0&&u===1/0)&&(u=n,o=i)});return u},h.shuffle=function(n){return h.sample(n,1/0)},h.sample=function(n,e,t){if(null==e||t)return x(n)||(n=h.values(n)),n[h.random(n.length-1)];var r=x(n)?h.clone(n):h.values(n),i=j(r);e=Math.max(Math.min(e,i),0);for(var u=i-1,o=0;o<e;o++){var c=h.random(o,u),a=r[o];r[o]=r[c],r[c]=a}return r.slice(0,e)},h.sortBy=function(n,r,e){var i=0;return r=v(r,e),h.pluck(h.map(n,function(n,e,t){return{value:n,index:i++,criteria:r(n,e,t)}}).sort(function(n,e){var t=n.criteria,r=e.criteria;if(t!==r){if(r<t||void 0===t)return 1;if(t<r||void 0===r)return-1}return n.index-e.index}),"value")};function w(o,e){return function(r,i,n){var u=e?[[],[]]:{};return i=v(i,n),h.each(r,function(n,e){var t=i(n,e,r);o(u,n,t)}),u}}h.groupBy=w(function(n,e,t){_(n,t)?n[t].push(e):n[t]=[e]}),h.indexBy=w(function(n,e,t){n[t]=e}),h.countBy=w(function(n,e,t){_(n,t)?n[t]++:n[t]=1});var A=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;h.toArray=function(n){return n?h.isArray(n)?a.call(n):h.isString(n)?n.match(A):x(n)?h.map(n,h.identity):h.values(n):[]},h.size=function(n){return null==n?0:x(n)?n.length:h.keys(n).length},h.partition=w(function(n,e,t){n[t?0:1].push(e)},!0),h.first=h.head=h.take=function(n,e,t){return null==n||n.length<1?null==e?void 0:[]:null==e||t?n[0]:h.initial(n,n.length-e)},h.initial=function(n,e,t){return a.call(n,0,Math.max(0,n.length-(null==e||t?1:e)))},h.last=function(n,e,t){return null==n||n.length<1?null==e?void 0:[]:null==e||t?n[n.length-1]:h.rest(n,Math.max(0,n.length-e))},h.rest=h.tail=h.drop=function(n,e,t){return a.call(n,null==e||t?1:e)},h.compact=function(n){return h.filter(n,Boolean)};var T=function(n,e,t,r){for(var i=(r=r||[]).length,u=0,o=j(n);u<o;u++){var c=n[u];if(x(c)&&(h.isArray(c)||h.isArguments(c)))if(e)for(var a=0,l=c.length;a<l;)r[i++]=c[a++];else T(c,e,t,r),i=r.length;else t||(r[i++]=c)}return r};h.flatten=function(n,e){return T(n,e,!1)},h.without=g(function(n,e){return h.difference(n,e)}),h.uniq=h.unique=function(n,e,t,r){h.isBoolean(e)||(r=t,t=e,e=!1),null!=t&&(t=v(t,r));for(var i=[],u=[],o=0,c=j(n);o<c;o++){var a=n[o],l=t?t(a,o,n):a;e&&!t?(o&&u===l||i.push(a),u=l):t?h.contains(u,l)||(u.push(l),i.push(a)):h.contains(i,a)||i.push(a)}return i},h.union=g(function(n){return h.uniq(T(n,!0,!0))}),h.intersection=function(n){for(var e=[],t=arguments.length,r=0,i=j(n);r<i;r++){var u=n[r];if(!h.contains(e,u)){var o;for(o=1;o<t&&h.contains(arguments[o],u);o++);o===t&&e.push(u)}}return e},h.difference=g(function(n,e){return e=T(e,!0,!0),h.filter(n,function(n){return!h.contains(e,n)})}),h.unzip=function(n){for(var e=n&&h.max(n,j).length||0,t=Array(e),r=0;r<e;r++)t[r]=h.pluck(n,r);return t},h.zip=g(h.unzip),h.object=function(n,e){for(var t={},r=0,i=j(n);r<i;r++)e?t[n[r]]=e[r]:t[n[r][0]]=n[r][1];return t};function O(u){return function(n,e,t){e=v(e,t);for(var r=j(n),i=0<u?0:r-1;0<=i&&i<r;i+=u)if(e(n[i],i,n))return i;return-1}}h.findIndex=O(1),h.findLastIndex=O(-1),h.sortedIndex=function(n,e,t,r){for(var i=(t=v(t,r,1))(e),u=0,o=j(n);u<o;){var c=Math.floor((u+o)/2);t(n[c])<i?u=c+1:o=c}return u};function C(u,o,c){return function(n,e,t){var r=0,i=j(n);if("number"==typeof t)0<u?r=0<=t?t:Math.max(t+i,r):i=0<=t?Math.min(t+1,i):t+i+1;else if(c&&t&&i)return n[t=c(n,e)]===e?t:-1;if(e!=e)return 0<=(t=o(a.call(n,r,i),h.isNaN))?t+r:-1;for(t=0<u?r:i-1;0<=t&&t<i;t+=u)if(n[t]===e)return t;return-1}}h.indexOf=C(1,h.findIndex,h.sortedIndex),h.lastIndexOf=C(-1,h.findLastIndex),h.range=function(n,e,t){null==e&&(e=n||0,n=0),t=t||(e<n?-1:1);for(var r=Math.max(Math.ceil((e-n)/t),0),i=Array(r),u=0;u<r;u++,n+=t)i[u]=n;return i},h.chunk=function(n,e){if(null==e||e<1)return[];for(var t=[],r=0,i=n.length;r<i;)t.push(a.call(n,r,r+=e));return t};function I(n,e,t,r,i){if(!(r instanceof e))return n.apply(t,i);var u=S(n.prototype),o=n.apply(u,i);return h.isObject(o)?o:u}h.bind=g(function(e,t,r){if(!h.isFunction(e))throw new TypeError("Bind must be called on a function");var i=g(function(n){return I(e,i,t,this,r.concat(n))});return i}),h.partial=g(function(i,u){var o=h.partial.placeholder,c=function(){for(var n=0,e=u.length,t=Array(e),r=0;r<e;r++)t[r]=u[r]===o?arguments[n++]:u[r];for(;n<arguments.length;)t.push(arguments[n++]);return I(i,c,this,this,t)};return c}),(h.partial.placeholder=h).bindAll=g(function(n,e){var t=(e=T(e,!1,!1)).length;if(t<1)throw new Error("bindAll must be passed function names");for(;t--;){var r=e[t];n[r]=h.bind(n[r],n)}}),h.memoize=function(r,i){var u=function(n){var e=u.cache,t=""+(i?i.apply(this,arguments):n);return _(e,t)||(e[t]=r.apply(this,arguments)),e[t]};return u.cache={},u},h.delay=g(function(n,e,t){return setTimeout(function(){return n.apply(null,t)},e)}),h.defer=h.partial(h.delay,h,1),h.throttle=function(t,r,i){var u,o,c,a,l=0;i=i||{};function s(){l=!1===i.leading?0:h.now(),u=null,a=t.apply(o,c),u||(o=c=null)}function n(){var n=h.now();l||!1!==i.leading||(l=n);var e=r-(n-l);return o=this,c=arguments,e<=0||r<e?(u&&(clearTimeout(u),u=null),l=n,a=t.apply(o,c),u||(o=c=null)):u||!1===i.trailing||(u=setTimeout(s,e)),a}return n.cancel=function(){clearTimeout(u),l=0,u=o=c=null},n},h.debounce=function(t,r,i){function u(n,e){o=null,e&&(c=t.apply(n,e))}var o,c,n=g(function(n){if(o&&clearTimeout(o),i){var e=!o;o=setTimeout(u,r),e&&(c=t.apply(this,n))}else o=h.delay(u,r,this,n);return c});return n.cancel=function(){clearTimeout(o),o=null},n},h.wrap=function(n,e){return h.partial(e,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var t=arguments,r=t.length-1;return function(){for(var n=r,e=t[r].apply(this,arguments);n--;)e=t[n].call(this,e);return e}},h.after=function(n,e){return function(){if(--n<1)return e.apply(this,arguments)}},h.before=function(n,e){var t;return function(){return 0<--n&&(t=e.apply(this,arguments)),n<=1&&(e=null),t}},h.once=h.partial(h.before,2),h.restArguments=g;function F(n,e){var t=M.length,r=n.constructor,i=h.isFunction(r)&&r.prototype||o,u="constructor";for(_(n,u)&&!h.contains(e,u)&&e.push(u);t--;)(u=M[t])in n&&n[u]!==i[u]&&!h.contains(e,u)&&e.push(u)}var q=!{toString:null}.propertyIsEnumerable("toString"),M=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];h.keys=function(n){if(!h.isObject(n))return[];if(l)return l(n);var e=[];for(var t in n)_(n,t)&&e.push(t);return q&&F(n,e),e},h.allKeys=function(n){if(!h.isObject(n))return[];var e=[];for(var t in n)e.push(t);return q&&F(n,e),e},h.values=function(n){for(var e=h.keys(n),t=e.length,r=Array(t),i=0;i<t;i++)r[i]=n[e[i]];return r},h.mapObject=function(n,e,t){e=v(e,t);for(var r=h.keys(n),i=r.length,u={},o=0;o<i;o++){var c=r[o];u[c]=e(n[c],c,n)}return u},h.pairs=function(n){for(var e=h.keys(n),t=e.length,r=Array(t),i=0;i<t;i++)r[i]=[e[i],n[e[i]]];return r},h.invert=function(n){for(var e={},t=h.keys(n),r=0,i=t.length;r<i;r++)e[n[t[r]]]=t[r];return e},h.functions=h.methods=function(n){var e=[];for(var t in n)h.isFunction(n[t])&&e.push(t);return e.sort()};function N(a,l){return function(n){var e=arguments.length;if(l&&(n=Object(n)),e<2||null==n)return n;for(var t=1;t<e;t++)for(var r=arguments[t],i=a(r),u=i.length,o=0;o<u;o++){var c=i[o];l&&void 0!==n[c]||(n[c]=r[c])}return n}}h.extend=N(h.allKeys),h.extendOwn=h.assign=N(h.keys),h.findKey=function(n,e,t){e=v(e,t);for(var r,i=h.keys(n),u=0,o=i.length;u<o;u++)if(e(n[r=i[u]],r,n))return r};function R(n,e,t){return e in t}var Q,L;h.pick=g(function(n,e){var t={},r=e[0];if(null==n)return t;h.isFunction(r)?(1<e.length&&(r=d(r,e[1])),e=h.allKeys(n)):(r=R,e=T(e,!1,!1),n=Object(n));for(var i=0,u=e.length;i<u;i++){var o=e[i],c=n[o];r(c,o,n)&&(t[o]=c)}return t}),h.omit=g(function(n,t){var e,r=t[0];return h.isFunction(r)?(r=h.negate(r),1<t.length&&(e=t[1])):(t=h.map(T(t,!1,!1),String),r=function(n,e){return!h.contains(t,e)}),h.pick(n,r,e)}),h.defaults=N(h.allKeys,!0),h.create=function(n,e){var t=S(n);return e&&h.extendOwn(t,e),t},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,e){return e(n),n},h.isMatch=function(n,e){var t=h.keys(e),r=t.length;if(null==n)return!r;for(var i=Object(n),u=0;u<r;u++){var o=t[u];if(e[o]!==i[o]||!(o in i))return!1}return!0},Q=function(n,e,t,r){if(n===e)return 0!==n||1/n==1/e;if(null==n||null==e)return!1;if(n!=n)return e!=e;var i=typeof n;return("function"==i||"object"==i||"object"==typeof e)&&L(n,e,t,r)},L=function(n,e,t,r){n instanceof h&&(n=n._wrapped),e instanceof h&&(e=e._wrapped);var i=p.call(n);if(i!==p.call(e))return!1;switch(i){case"[object RegExp]":case"[object String]":return""+n==""+e;case"[object Number]":return+n!=+n?+e!=+e:0==+n?1/+n==1/e:+n==+e;case"[object Date]":case"[object Boolean]":return+n==+e;case"[object Symbol]":return f.valueOf.call(n)===f.valueOf.call(e)}var u="[object Array]"===i;if(!u){if("object"!=typeof n||"object"!=typeof e)return!1;var o=n.constructor,c=e.constructor;if(o!==c&&!(h.isFunction(o)&&o instanceof o&&h.isFunction(c)&&c instanceof c)&&"constructor"in n&&"constructor"in e)return!1}r=r||[];for(var a=(t=t||[]).length;a--;)if(t[a]===n)return r[a]===e;if(t.push(n),r.push(e),u){if((a=n.length)!==e.length)return!1;for(;a--;)if(!Q(n[a],e[a],t,r))return!1}else{var l,s=h.keys(n);if(a=s.length,h.keys(e).length!==a)return!1;for(;a--;)if(l=s[a],!_(e,l)||!Q(n[l],e[l],t,r))return!1}return t.pop(),r.pop(),!0},h.isEqual=function(n,e){return Q(n,e)},h.isEmpty=function(n){return null==n||(x(n)&&(h.isArray(n)||h.isString(n)||h.isArguments(n))?0===n.length:0===h.keys(n).length)},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=c||function(n){return"[object Array]"===p.call(n)},h.isObject=function(n){var e=typeof n;return"function"==e||"object"==e&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp","Error","Symbol","Map","WeakMap","Set","WeakSet"],function(e){h["is"+e]=function(n){return p.call(n)==="[object "+e+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return _(n,"callee")});var U=n.document&&n.document.childNodes;"function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof U&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return!h.isSymbol(n)&&isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&isNaN(n)},h.isBoolean=function(n){return!0===n||!1===n||"[object Boolean]"===p.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return void 0===n},h.has=function(n,e){if(!h.isArray(e))return _(n,e);for(var t=e.length,r=0;r<t;r++){var i=e[r];if(null==n||!u.call(n,i))return!1;n=n[i]}return!!t},h.noConflict=function(){return n._=e,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(e){return h.isArray(e)?function(n){return b(n,e)}:m(e)},h.propertyOf=function(e){return null==e?function(){}:function(n){return h.isArray(n)?b(e,n):e[n]}},h.matcher=h.matches=function(e){return e=h.extendOwn({},e),function(n){return h.isMatch(n,e)}},h.times=function(n,e,t){var r=Array(Math.max(0,n));e=d(e,t,1);for(var i=0;i<n;i++)r[i]=e(i);return r},h.random=function(n,e){return null==e&&(e=n,n=0),n+Math.floor(Math.random()*(e-n+1))},h.now=Date.now||function(){return(new Date).getTime()};function D(e){function t(n){return e[n]}var n="(?:"+h.keys(e).join("|")+")",r=RegExp(n),i=RegExp(n,"g");return function(n){return n=null==n?"":""+n,r.test(n)?n.replace(i,t):n}}var P={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},W=h.invert(P);h.escape=D(P),h.unescape=D(W),h.result=function(n,e,t){h.isArray(e)||(e=[e]);var r=e.length;if(!r)return h.isFunction(t)?t.call(n):t;for(var i=0;i<r;i++){var u=null==n?void 0:n[e[i]];void 0===u&&(u=t,i=r),n=h.isFunction(u)?u.call(n):u}return n};var B=0;h.uniqueId=function(n){var e=++B+"";return n?n+e:e},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function Y(n){return"\\"+K[n]}var z=/(.)^/,K={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},G=/\\|'|\r|\n|\u2028|\u2029/g;h.template=function(u,n,e){!n&&e&&(n=e),n=h.defaults({},n,h.templateSettings);var t,r=RegExp([(n.escape||z).source,(n.interpolate||z).source,(n.evaluate||z).source].join("|")+"|$","g"),o=0,c="__p+='";u.replace(r,function(n,e,t,r,i){return c+=u.slice(o,i).replace(G,Y),o=i+n.length,e?c+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":t?c+="'+\n((__t=("+t+"))==null?'':__t)+\n'":r&&(c+="';\n"+r+"\n__p+='"),n}),c+="';\n",n.variable||(c="with(obj||{}){\n"+c+"}\n"),c="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+c+"return __p;\n";try{t=new Function(n.variable||"obj","_",c)}catch(n){throw n.source=c,n}function i(n){return t.call(this,n,h)}var a=n.variable||"obj";return i.source="function("+a+"){\n"+c+"}",i},h.chain=function(n){var e=h(n);return e._chain=!0,e};function H(n,e){return n._chain?h(e).chain():e}h.mixin=function(t){return h.each(h.functions(t),function(n){var e=h[n]=t[n];h.prototype[n]=function(){var n=[this._wrapped];return i.apply(n,arguments),H(this,e.apply(h,n))}}),h},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];h.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),"shift"!==e&&"splice"!==e||0!==n.length||delete n[0],H(this,n)}}),h.each(["concat","join","slice"],function(n){var e=r[n];h.prototype[n]=function(){return H(this,e.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},h.prototype.valueOf=h.prototype.toJSON=h.prototype.value,h.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events");e.exports=function(n){var r=n.getComponent("MenuItem");return n.extend(r,{constructor:function(n,e){var t=e.source;if(!i.isObject(t))throw new Error('was not provided a "source" object, but rather: '+typeof t);e=i.extend({selectable:!0,label:t.label},e),r.call(this,n,e),this.source=t},handleClick:function(n){r.prototype.handleClick.call(this,n),this.player().trigger(u.QUALITY_REQUESTED,this.source)}})}},{"../events":5,underscore:2}],4:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events"),o=n("./QualityOption"),c="vjs-quality-changing";e.exports=function(n){var e,r=n.getComponent("MenuButton"),t=o(n);return e=n.extend(r,{constructor:function(t,n){r.call(this,t,n),t.on(u.QUALITY_REQUESTED,function(n,e){this.setSelectedSource(e),t.addClass(c),t.one("loadeddata",function(){t.removeClass(c)})}.bind(this)),t.on(u.PLAYER_SOURCES_CHANGED,function(){this.update()}.bind(this)),t.on(u.QUALITY_SELECTED,function(n,e){this.setSelectedSource(e)}.bind(this)),t.one("ready",function(){this.selectedSrc=t.src(),this.update()}.bind(this)),this.controlText("Open quality selector menu")},setSelectedSource:function(n){var e=n?n.src:void 0;this.selectedSrc!==e&&(this.selectedSrc=e,i.each(this.items,function(n){n.selected(n.source.src===e)}))},createItems:function(){var e=this.player(),n=e.currentSources();return i.map(n,function(n){return new t(e,{source:n,selected:n.src===this.selectedSrc})}.bind(this))},buildWrapperCSSClass:function(){return"vjs-quality-selector "+r.prototype.buildWrapperCSSClass.call(this)}}),n.registerComponent("QualitySelector",e),e}},{"../events":5,"./QualityOption":3,underscore:2}],5:[function(n,e,t){"use strict";e.exports={QUALITY_REQUESTED:"qualityRequested",QUALITY_SELECTED:"qualitySelected",PLAYER_SOURCES_CHANGED:"playerSourcesChanged"}},{}],6:[function(n,e,t){"use strict";var c=n("underscore"),r=n("./events"),i=n("./components/QualitySelector"),u=n("./middleware/SourceInterceptor"),a=n("./util/SafeSeek");e.exports=function(n){n=n||window.videojs,i(n),u(n),n.hook("setup",function(o){o.on(r.QUALITY_REQUESTED,function(n,e){var t=o.currentSources(),r=o.currentTime(),i=o.playbackRate(),u=o.paused();c.each(t,function(n){n.selected=!1}),c.findWhere(t,{src:e.src}).selected=!0,o._qualitySelectorSafeSeek&&o._qualitySelectorSafeSeek.onQualitySelectionChange(),o.src(t),o.ready(function(){o._qualitySelectorSafeSeek&&!o._qualitySelectorSafeSeek.hasFinished()||(o._qualitySelectorSafeSeek=new a(o,r),o.playbackRate(i)),u||o.play()})})})},e.exports.EVENTS=r},{"./components/QualitySelector":4,"./events":5,"./middleware/SourceInterceptor":7,"./util/SafeSeek":9,underscore:2}],7:[function(n,e,t){"use strict";var u=n("underscore"),o=n("../events");e.exports=function(n){n.use("*",function(i){return{setSource:function(n,e){var t,r=i.currentSources();i._qualitySelectorSafeSeek&&i._qualitySelectorSafeSeek.onPlayerSourcesChange(),u.isEqual(r,i._qualitySelectorPreviousSources)||(i.trigger(o.PLAYER_SOURCES_CHANGED,r),i._qualitySelectorPreviousSources=r),t=u.find(r,function(n){return!0===n.selected||"true"===n.selected||"selected"===n.selected})||n,i.trigger(o.QUALITY_SELECTED,t),e(null,t)}}})}},{"../events":5,underscore:2}],8:[function(n,e,t){"use strict";n("./index")()},{"./index":6}],9:[function(n,e,t){"use strict";var r=n("class.extend");e.exports=r.extend({init:function(n,e){this._player=n,this._seekToTime=e,this._hasFinished=!1,this._keepThisInstanceWhenPlayerSourcesChange=!1,this._seekWhenSafe()},_seekWhenSafe:function(){this._player.readyState()<3?(this._seekFn=this._seek.bind(this),this._player.one("canplay",this._seekFn)):this._seek()},onPlayerSourcesChange:function(){this._keepThisInstanceWhenPlayerSourcesChange?this._keepThisInstanceWhenPlayerSourcesChange=!1:this.cancel()},onQualitySelectionChange:function(){this.hasFinished()||(this._keepThisInstanceWhenPlayerSourcesChange=!0)},_seek:function(){this._player.currentTime(this._seekToTime),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0},hasFinished:function(){return this._hasFinished},cancel:function(){this._player.off("canplay",this._seekFn),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0}})},{"class.extend":1}]},{},[8]);
+//# sourceMappingURL=silvermine-videojs-quality-selector.min.js.map \ No newline at end of file
diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js
index 6c21bffb..216c36fe 100644
--- a/assets/js/subscribe_widget.js
+++ b/assets/js/subscribe_widget.js
@@ -1,3 +1,5 @@
+var subscribe_data = JSON.parse(document.getElementById('subscribe_data').innerHTML);
+
var subscribe_button = document.getElementById('subscribe');
subscribe_button.parentNode['action'] = 'javascript:void(0)';
diff --git a/assets/js/themes.js b/assets/js/themes.js
index 90a05c36..c600073d 100644
--- a/assets/js/themes.js
+++ b/assets/js/themes.js
@@ -28,6 +28,27 @@ window.addEventListener('load', function () {
update_mode(window.localStorage.dark_mode);
});
+
+var darkScheme = window.matchMedia('(prefers-color-scheme: dark)');
+var lightScheme = window.matchMedia('(prefers-color-scheme: light)');
+
+darkScheme.addListener(scheme_switch);
+lightScheme.addListener(scheme_switch);
+
+function scheme_switch (e) {
+ // ignore this method if we have a preference set
+ if (localStorage.getItem('dark_mode')) {
+ return;
+ }
+ if (e.matches) {
+ if (e.media.includes("dark")) {
+ set_mode(true);
+ } else if (e.media.includes("light")) {
+ set_mode(false);
+ }
+ }
+}
+
function set_mode (bool) {
document.getElementById('dark_theme').media = !bool ? 'none' : '';
document.getElementById('light_theme').media = bool ? 'none' : '';
diff --git a/assets/js/video.min.js b/assets/js/video.min.js
index 10743dd4..ed10c74e 100644
--- a/assets/js/video.min.js
+++ b/assets/js/video.min.js
@@ -1,6 +1,6 @@
/**
* @license
- * Video.js 7.6.0 <http://videojs.com/>
+ * Video.js 7.6.6 <http://videojs.com/>
* Copyright Brightcove, Inc. <https://www.brightcove.com/>
* Available under Apache License Version 2.0
* <https://github.com/videojs/video.js/blob/master/LICENSE>
@@ -9,12 +9,13 @@
* Available under Apache License Version 2.0
* <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
*/
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("global/window"),require("global/document")):"function"==typeof define&&define.amd?define(["global/window","global/document"],t):(e=e||self).videojs=t(e.window,e.document)}(this,function(v,h){v=v&&v.hasOwnProperty("default")?v.default:v,h=h&&h.hasOwnProperty("default")?h.default:h;var d="7.6.0";function p(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}function a(e,t){return(a=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function s(e,t,i){return(s=function(){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(e){return!1}}()?Reflect.construct:function(e,t,i){var n=[null];n.push.apply(n,t);var r=new(Function.bind.apply(e,n));return i&&a(r,i.prototype),r}).apply(null,arguments)}function f(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function t(e,t){return t=t||e.slice(0),e.raw=t,e}var u=[],e=function(s,o){return function(e,t,i){var n=o.levels[t],r=new RegExp("^("+n+")$");if("log"!==e&&i.unshift(e.toUpperCase()+":"),i.unshift(s+":"),u&&u.push([].concat(i)),v.console){var a=v.console[e];a||"debug"!==e||(a=v.console.info||v.console.log),a&&n&&r.test(e)&&a[Array.isArray(i)?"apply":"call"](v.console,i)}}};var m=function t(i){function n(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];r("log",a,t)}var r,a="info";return r=e(i,n),n.createLogger=function(e){return t(i+": "+e)},n.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:a},n.level=function(e){if("string"==typeof e){if(!n.levels.hasOwnProperty(e))throw new Error('"'+e+'" in not a valid log level');a=e}return a},(n.history=function(){return u?[].concat(u):[]}).filter=function(t){return(u||[]).filter(function(e){return new RegExp(".*"+t+".*").test(e[0])})},n.history.clear=function(){u&&(u.length=0)},n.history.disable=function(){null!==u&&(u.length=0,u=null)},n.history.enable=function(){null===u&&(u=[])},n.error=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("error",a,t)},n.warn=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("warn",a,t)},n.debug=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("debug",a,t)},n}("VIDEOJS"),g=m.createLogger;var y=function(e){for(var t="",i=0;i<arguments.length;i++)t+=e[i].replace(/\n\r?\s*/g,"")+(arguments[i+1]||"");return t},i=Object.prototype.toString,o=function(e){return b(e)?Object.keys(e):[]};function r(t,i){o(t).forEach(function(e){return i(t[e],e)})}function _(i){for(var e=arguments.length,t=new Array(1<e?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];return Object.assign?Object.assign.apply(Object,[i].concat(t)):(t.forEach(function(e){e&&r(e,function(e,t){i[t]=e})}),i)}function b(e){return!!e&&"object"==typeof e}function l(e){return b(e)&&"[object Object]"===i.call(e)&&e.constructor===Object}function n(e,t){if(!e||!t)return"";if("function"!=typeof v.getComputedStyle)return"";var i=v.getComputedStyle(e);return i?i[t]:""}function c(){var e=t(["Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set "," to ","."]);return c=function(){return e},e}function T(e){return"string"==typeof e&&/\S/.test(e)}function S(e){if(/\s/.test(e))throw new Error("class has illegal whitespace characters")}function k(){return h===v.document}function w(e){return b(e)&&1===e.nodeType}function C(){try{return v.parent!==v.self}catch(e){return!0}}function E(n){return function(e,t){if(!T(e))return h[n](null);T(t)&&(t=h.querySelector(t));var i=w(t)?t:h;return i[n]&&i[n](e)}}function A(e,i,t,n){void 0===e&&(e="div"),void 0===i&&(i={}),void 0===t&&(t={});var r=h.createElement(e);return Object.getOwnPropertyNames(i).forEach(function(e){var t=i[e];-1!==e.indexOf("aria-")||"role"===e||"type"===e?(m.warn(y(c(),e,t)),r.setAttribute(e,t)):"textContent"===e?P(r,t):r[e]=t}),Object.getOwnPropertyNames(t).forEach(function(e){r.setAttribute(e,t[e])}),n&&$(r,n),r}function P(e,t){return"undefined"==typeof e.textContent?e.innerText=t:e.textContent=t,e}function L(e,t){t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e)}function I(e,t){return S(t),e.classList?e.classList.contains(t):function(e){return new RegExp("(^|\\s)"+e+"($|\\s)")}(t).test(e.className)}function O(e,t){return e.classList?e.classList.add(t):I(e,t)||(e.className=(e.className+" "+t).trim()),e}function x(e,t){return e.classList?e.classList.remove(t):(S(t),e.className=e.className.split(/\s+/).filter(function(e){return e!==t}).join(" ")),e}function U(e,t,i){var n=I(e,t);if("function"==typeof i&&(i=i(e,t)),"boolean"!=typeof i&&(i=!n),i!==n)return i?O(e,t):x(e,t),e}function D(i,n){Object.getOwnPropertyNames(n).forEach(function(e){var t=n[e];null===t||"undefined"==typeof t||!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})}function R(e){var t={},i=",autoplay,controls,playsinline,loop,muted,default,defaultMuted,";if(e&&e.attributes&&0<e.attributes.length)for(var n=e.attributes,r=n.length-1;0<=r;r--){var a=n[r].name,s=n[r].value;"boolean"!=typeof e[a]&&-1===i.indexOf(","+a+",")||(s=null!==s),t[a]=s}return t}function M(e,t){return e.getAttribute(t)}function B(e,t,i){e.setAttribute(t,i)}function N(e,t){e.removeAttribute(t)}function j(){h.body.focus(),h.onselectstart=function(){return!1}}function F(){h.onselectstart=function(){return!0}}function V(e){if(e&&e.getBoundingClientRect&&e.parentNode){var t=e.getBoundingClientRect(),i={};return["bottom","height","left","right","top","width"].forEach(function(e){void 0!==t[e]&&(i[e]=t[e])}),i.height||(i.height=parseFloat(n(e,"height"))),i.width||(i.width=parseFloat(n(e,"width"))),i}}function H(e){var t;if(e.getBoundingClientRect&&e.parentNode&&(t=e.getBoundingClientRect()),!t)return{left:0,top:0};var i=h.documentElement,n=h.body,r=i.clientLeft||n.clientLeft||0,a=v.pageXOffset||n.scrollLeft,s=t.left+a-r,o=i.clientTop||n.clientTop||0,u=v.pageYOffset||n.scrollTop,l=t.top+u-o;return{left:Math.round(s),top:Math.round(l)}}function q(e,t){var i={},n=H(e),r=e.offsetWidth,a=e.offsetHeight,s=n.top,o=n.left,u=t.pageY,l=t.pageX;return t.changedTouches&&(l=t.changedTouches[0].pageX,u=t.changedTouches[0].pageY),i.y=Math.max(0,Math.min(1,(s-u+a)/a)),i.x=Math.max(0,Math.min(1,(l-o)/r)),i}function z(e){return b(e)&&3===e.nodeType}function W(e){for(;e.firstChild;)e.removeChild(e.firstChild);return e}function G(e){return"function"==typeof e&&(e=e()),(Array.isArray(e)?e:[e]).map(function(e){return"function"==typeof e&&(e=e()),w(e)||z(e)?e:"string"==typeof e&&/\S/.test(e)?h.createTextNode(e):void 0}).filter(function(e){return e})}function $(t,e){return G(e).forEach(function(e){return t.appendChild(e)}),t}function X(e,t){return $(W(e),t)}function K(e){return void 0===e.button&&void 0===e.buttons||(0===e.button&&void 0===e.buttons||(0===e.button&&0===e.buttons||0===e.button&&1===e.buttons))}var Y=E("querySelector"),Q=E("querySelectorAll"),J=Object.freeze({isReal:k,isEl:w,isInFrame:C,createEl:A,textContent:P,prependTo:L,hasClass:I,addClass:O,removeClass:x,toggleClass:U,setAttributes:D,getAttributes:R,getAttribute:M,setAttribute:B,removeAttribute:N,blockTextSelection:j,unblockTextSelection:F,getBoundingClientRect:V,findPosition:H,getPointerPosition:q,isTextNode:z,emptyEl:W,normalizeContent:G,appendContent:$,insertContent:X,isSingleLeftClick:K,$:Y,$$:Q}),Z=1;function ee(){return Z++}var te={},ie="vdata"+Math.floor(v.performance&&v.performance.now()||Date.now());function ne(e){var t=e[ie];return t=t||(e[ie]=ee()),te[t]||(te[t]={}),te[t]}function re(e){var t=e[ie];return!!t&&!!Object.getOwnPropertyNames(te[t]).length}function ae(t){var e=t[ie];if(e){delete te[e];try{delete t[ie]}catch(e){t.removeAttribute?t.removeAttribute(ie):t[ie]=null}}}function se(e,t){var i=ne(e);0===i.handlers[t].length&&(delete i.handlers[t],e.removeEventListener?e.removeEventListener(t,i.dispatcher,!1):e.detachEvent&&e.detachEvent("on"+t,i.dispatcher)),Object.getOwnPropertyNames(i.handlers).length<=0&&(delete i.handlers,delete i.dispatcher,delete i.disabled),0===Object.getOwnPropertyNames(i).length&&ae(e)}function oe(t,i,e,n){e.forEach(function(e){t(i,e,n)})}function ue(e){function t(){return!0}function i(){return!1}if(!e||!e.isPropagationStopped){var n=e||v.event;for(var r in e={},n)"layerX"!==r&&"layerY"!==r&&"keyLocation"!==r&&"webkitMovementX"!==r&&"webkitMovementY"!==r&&("returnValue"===r&&n.preventDefault||(e[r]=n[r]));if(e.target||(e.target=e.srcElement||h),e.relatedTarget||(e.relatedTarget=e.fromElement===e.target?e.toElement:e.fromElement),e.preventDefault=function(){n.preventDefault&&n.preventDefault(),e.returnValue=!1,n.returnValue=!1,e.defaultPrevented=!0},e.defaultPrevented=!1,e.stopPropagation=function(){n.stopPropagation&&n.stopPropagation(),e.cancelBubble=!0,n.cancelBubble=!0,e.isPropagationStopped=t},e.isPropagationStopped=i,e.stopImmediatePropagation=function(){n.stopImmediatePropagation&&n.stopImmediatePropagation(),e.isImmediatePropagationStopped=t,e.stopPropagation()},e.isImmediatePropagationStopped=i,null!==e.clientX&&void 0!==e.clientX){var a=h.documentElement,s=h.body;e.pageX=e.clientX+(a&&a.scrollLeft||s&&s.scrollLeft||0)-(a&&a.clientLeft||s&&s.clientLeft||0),e.pageY=e.clientY+(a&&a.scrollTop||s&&s.scrollTop||0)-(a&&a.clientTop||s&&s.clientTop||0)}e.which=e.charCode||e.keyCode,null!==e.button&&void 0!==e.button&&(e.button=1&e.button?0:4&e.button?1:2&e.button?2:0)}return e}var le=!1;!function(){try{var e=Object.defineProperty({},"passive",{get:function(){le=!0}});v.addEventListener("test",null,e),v.removeEventListener("test",null,e)}catch(e){}}();var ce=["touchstart","touchmove"];function he(s,e,t){if(Array.isArray(e))return oe(he,s,e,t);var o=ne(s);if(o.handlers||(o.handlers={}),o.handlers[e]||(o.handlers[e]=[]),t.guid||(t.guid=ee()),o.handlers[e].push(t),o.dispatcher||(o.disabled=!1,o.dispatcher=function(e,t){if(!o.disabled){e=ue(e);var i=o.handlers[e.type];if(i)for(var n=i.slice(0),r=0,a=n.length;r<a&&!e.isImmediatePropagationStopped();r++)try{n[r].call(s,e,t)}catch(e){m.error(e)}}}),1===o.handlers[e].length)if(s.addEventListener){var i=!1;le&&-1<ce.indexOf(e)&&(i={passive:!0}),s.addEventListener(e,o.dispatcher,i)}else s.attachEvent&&s.attachEvent("on"+e,o.dispatcher)}function de(e,t,i){if(re(e)){var n=ne(e);if(n.handlers){if(Array.isArray(t))return oe(de,e,t,i);function r(e,t){n.handlers[t]=[],se(e,t)}if(void 0!==t){var a=n.handlers[t];if(a)if(i){if(i.guid)for(var s=0;s<a.length;s++)a[s].guid===i.guid&&a.splice(s--,1);se(e,t)}else r(e,t)}else for(var o in n.handlers)Object.prototype.hasOwnProperty.call(n.handlers||{},o)&&r(e,o)}}}function pe(e,t,i){var n=re(e)?ne(e):{},r=e.parentNode||e.ownerDocument;if("string"==typeof t?t={type:t,target:e}:t.target||(t.target=e),t=ue(t),n.dispatcher&&n.dispatcher.call(e,t,i),r&&!t.isPropagationStopped()&&!0===t.bubbles)pe.call(null,r,t,i);else if(!r&&!t.defaultPrevented&&t.target&&t.target[t.type]){var a=ne(t.target);t.target[t.type]&&(a.disabled=!0,"function"==typeof t.target[t.type]&&t.target[t.type](),a.disabled=!1)}return!t.defaultPrevented}function fe(e,t,i){if(Array.isArray(t))return oe(fe,e,t,i);function n(){de(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||ee(),he(e,t,n)}function me(e,t,i){function n(){de(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||ee(),he(e,t,n)}var ge,ye=Object.freeze({fixEvent:ue,on:he,off:de,trigger:pe,one:fe,any:me}),ve=!1,_e=function(){if(k()&&!1!==ge.options.autoSetup){var e=Array.prototype.slice.call(h.getElementsByTagName("video")),t=Array.prototype.slice.call(h.getElementsByTagName("audio")),i=Array.prototype.slice.call(h.getElementsByTagName("video-js")),n=e.concat(t,i);if(n&&0<n.length)for(var r=0,a=n.length;r<a;r++){var s=n[r];if(!s||!s.getAttribute){be(1);break}void 0===s.player&&null!==s.getAttribute("data-setup")&&ge(s)}else ve||be(1)}};function be(e,t){t&&(ge=t),v.setTimeout(_e,e)}k()&&"complete"===h.readyState?ve=!0:fe(v,"load",function(){ve=!0});function Te(e){var t=h.createElement("style");return t.className=e,t}function Se(e,t){e.styleSheet?e.styleSheet.cssText=t:e.textContent=t}function ke(e,t,i){function n(){return t.apply(e,arguments)}return t.guid||(t.guid=ee()),n.guid=i?i+"_"+t.guid:t.guid,n}function we(t,i){var n=v.performance.now();return function(){var e=v.performance.now();i<=e-n&&(t.apply(void 0,arguments),n=e)}}function Ce(){}var Ee;Ce.prototype.allowedEvents_={},Ce.prototype.addEventListener=Ce.prototype.on=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},he(this,e,t),this.addEventListener=i},Ce.prototype.removeEventListener=Ce.prototype.off=function(e,t){de(this,e,t)},Ce.prototype.one=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},fe(this,e,t),this.addEventListener=i},Ce.prototype.any=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},me(this,e,t),this.addEventListener=i},Ce.prototype.dispatchEvent=Ce.prototype.trigger=function(e){var t=e.type||e;"string"==typeof e&&(e={type:t}),e=ue(e),this.allowedEvents_[t]&&this["on"+t]&&this["on"+t](e),pe(this,e)},Ce.prototype.queueTrigger=function(e){var t=this;Ee=Ee||new Map;var i=e.type||e,n=Ee.get(this);n||(n=new Map,Ee.set(this,n));var r=n.get(i);n.delete(i),v.clearTimeout(r);var a=v.setTimeout(function(){0===n.size&&(n=null,Ee.delete(t)),t.trigger(e)},0);n.set(i,a)};function Ae(e){return"string"==typeof e&&/\S/.test(e)||Array.isArray(e)&&!!e.length}function Pe(e){if(!e.nodeName&&!Ue(e))throw new Error("Invalid target; must be a DOM node or evented object.")}function Le(e){if(!Ae(e))throw new Error("Invalid event type; must be a non-empty string or array.")}function Ie(e){if("function"!=typeof e)throw new Error("Invalid listener; must be a function.")}function Oe(e,t){var i,n,r,a=t.length<3||t[0]===e||t[0]===e.eventBusEl_;return r=a?(i=e.eventBusEl_,3<=t.length&&t.shift(),n=t[0],t[1]):(i=t[0],n=t[1],t[2]),Pe(i),Le(n),Ie(r),{isTargetingSelf:a,target:i,type:n,listener:r=ke(e,r)}}function xe(e,t,i,n){Pe(e),e.nodeName?ye[t](e,i,n):e[t](i,n)}var Ue=function(t){return t instanceof Ce||!!t.eventBusEl_&&["on","one","off","trigger"].every(function(e){return"function"==typeof t[e]})},De={on:function(){for(var e=this,t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];var r=Oe(this,i),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(xe(s,"on",o,u),!a){function l(){return e.off(s,o,u)}l.guid=u.guid;function c(){return e.off("dispose",l)}c.guid=u.guid,xe(this,"on","dispose",l),xe(s,"on","dispose",c)}},one:function(){for(var n=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var r=Oe(this,t),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(a)xe(s,"one",o,u);else{function l(){n.off(s,o,l);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];u.apply(null,t)}l.guid=u.guid,xe(s,"one",o,l)}},any:function(){for(var n=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var r=Oe(this,t),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(a)xe(s,"any",o,u);else{function l(){n.off(s,o,l);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];u.apply(null,t)}l.guid=u.guid,xe(s,"any",o,l)}},off:function(e,t,i){if(!e||Ae(e))de(this.eventBusEl_,e,t);else{var n=e,r=t;Pe(n),Le(r),Ie(i),i=ke(this,i),this.off("dispose",i),n.nodeName?(de(n,r,i),de(n,"dispose",i)):Ue(n)&&(n.off(r,i),n.off("dispose",i))}},trigger:function(e,t){return pe(this.eventBusEl_,e,t)}};function Re(e,t){void 0===t&&(t={});var i=t.eventBusKey;if(i){if(!e[i].nodeName)throw new Error('The eventBusKey "'+i+'" does not refer to an element.');e.eventBusEl_=e[i]}else e.eventBusEl_=A("span",{className:"vjs-event-bus"});return _(e,De),e.eventedCallbacks&&e.eventedCallbacks.forEach(function(e){e()}),e.on("dispose",function(){e.off(),v.setTimeout(function(){e.eventBusEl_=null},0)}),e}var Me={state:{},setState:function(e){var i,n=this;return"function"==typeof e&&(e=e()),r(e,function(e,t){n.state[t]!==e&&((i=i||{})[t]={from:n.state[t],to:e}),n.state[t]=e}),i&&Ue(this)&&this.trigger({changes:i,type:"statechanged"}),i}};function Be(e,t){return _(e,Me),e.state=_({},e.state,t),"function"==typeof e.handleStateChanged&&Ue(e)&&e.on("statechanged",e.handleStateChanged),e}function Ne(e){return"string"!=typeof e?e:e.charAt(0).toUpperCase()+e.slice(1)}function je(){for(var i={},e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.forEach(function(e){e&&r(e,function(e,t){l(e)?(l(i[t])||(i[t]={}),i[t]=je(i[t],e)):i[t]=e})}),i}var Fe=function(){function l(e,t,i){if(!e&&this.play?this.player_=e=this:this.player_=e,this.parentComponent_=null,this.options_=je({},this.options_),t=this.options_=je(this.options_,t),this.id_=t.id||t.el&&t.el.id,!this.id_){var n=e&&e.id&&e.id()||"no_player";this.id_=n+"_component_"+ee()}this.name_=t.name||null,t.el?this.el_=t.el:!1!==t.createEl&&(this.el_=this.createEl()),!1!==t.evented&&Re(this,{eventBusKey:this.el_?"el_":null}),Be(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},!(this.childNameIndex_={})!==t.initChildren&&this.initChildren(),this.ready(i),!1!==t.reportTouchActivity&&this.enableTouchActivity()}var e=l.prototype;return e.dispose=function(){if(this.trigger({type:"dispose",bubbles:!1}),this.children_)for(var e=this.children_.length-1;0<=e;e--)this.children_[e].dispose&&this.children_[e].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),ae(this.el_),this.el_=null),this.player_=null},e.player=function(){return this.player_},e.options=function(e){return e&&(this.options_=je(this.options_,e)),this.options_},e.el=function(){return this.el_},e.createEl=function(e,t,i){return A(e,t,i)},e.localize=function(e,r,t){void 0===t&&(t=e);var i=this.player_.language&&this.player_.language(),n=this.player_.languages&&this.player_.languages(),a=n&&n[i],s=i&&i.split("-")[0],o=n&&n[s],u=t;return a&&a[e]?u=a[e]:o&&o[e]&&(u=o[e]),r&&(u=u.replace(/\{(\d+)\}/g,function(e,t){var i=r[t-1],n=i;return"undefined"==typeof i&&(n=e),n})),u},e.contentEl=function(){return this.contentEl_||this.el_},e.id=function(){return this.id_},e.name=function(){return this.name_},e.children=function(){return this.children_},e.getChildById=function(e){return this.childIndex_[e]},e.getChild=function(e){if(e)return e=Ne(e),this.childNameIndex_[e]},e.addChild=function(e,t,i){var n,r;if(void 0===t&&(t={}),void 0===i&&(i=this.children_.length),"string"==typeof e){r=Ne(e);var a=t.componentClass||r;t.name=r;var s=l.getComponent(a);if(!s)throw new Error("Component "+a+" does not exist");if("function"!=typeof s)return null;n=new s(this.player_||this,t)}else n=e;if(n.parentComponent_&&n.parentComponent_.removeChild(n),this.children_.splice(i,0,n),n.parentComponent_=this,"function"==typeof n.id&&(this.childIndex_[n.id()]=n),(r=r||n.name&&Ne(n.name()))&&(this.childNameIndex_[r]=n),"function"==typeof n.el&&n.el()){var o=this.contentEl().children[i]||null;this.contentEl().insertBefore(n.el(),o)}return n},e.removeChild=function(e){if("string"==typeof e&&(e=this.getChild(e)),e&&this.children_){for(var t=!1,i=this.children_.length-1;0<=i;i--)if(this.children_[i]===e){t=!0,this.children_.splice(i,1);break}if(t){e.parentComponent_=null,this.childIndex_[e.id()]=null,this.childNameIndex_[e.name()]=null;var n=e.el();n&&n.parentNode===this.contentEl()&&this.contentEl().removeChild(e.el())}}},e.initChildren=function(){var r=this,n=this.options_.children;if(n){var e,a=this.options_,i=l.getComponent("Tech");(e=Array.isArray(n)?n:Object.keys(n)).concat(Object.keys(this.options_).filter(function(t){return!e.some(function(e){return"string"==typeof e?t===e:t===e.name})})).map(function(e){var t,i;return i="string"==typeof e?n[t=e]||r.options_[t]||{}:(t=e.name,e),{name:t,opts:i}}).filter(function(e){var t=l.getComponent(e.opts.componentClass||Ne(e.name));return t&&!i.isTech(t)}).forEach(function(e){var t=e.name,i=e.opts;if(void 0!==a[t]&&(i=a[t]),!1!==i){!0===i&&(i={}),i.playerOptions=r.options_.playerOptions;var n=r.addChild(t,i);n&&(r[t]=n)}})}},e.buildCSSClass=function(){return""},e.ready=function(e,t){if(void 0===t&&(t=!1),e)return this.isReady_?void(t?e.call(this):this.setTimeout(e,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(e))},e.triggerReady=function(){this.isReady_=!0,this.setTimeout(function(){var e=this.readyQueue_;this.readyQueue_=[],e&&0<e.length&&e.forEach(function(e){e.call(this)},this),this.trigger("ready")},1)},e.$=function(e,t){return Y(e,t||this.contentEl())},e.$$=function(e,t){return Q(e,t||this.contentEl())},e.hasClass=function(e){return I(this.el_,e)},e.addClass=function(e){O(this.el_,e)},e.removeClass=function(e){x(this.el_,e)},e.toggleClass=function(e,t){U(this.el_,e,t)},e.show=function(){this.removeClass("vjs-hidden")},e.hide=function(){this.addClass("vjs-hidden")},e.lockShowing=function(){this.addClass("vjs-lock-showing")},e.unlockShowing=function(){this.removeClass("vjs-lock-showing")},e.getAttribute=function(e){return M(this.el_,e)},e.setAttribute=function(e,t){B(this.el_,e,t)},e.removeAttribute=function(e){N(this.el_,e)},e.width=function(e,t){return this.dimension("width",e,t)},e.height=function(e,t){return this.dimension("height",e,t)},e.dimensions=function(e,t){this.width(e,!0),this.height(t)},e.dimension=function(e,t,i){if(void 0!==t)return null!==t&&t==t||(t=0),-1!==(""+t).indexOf("%")||-1!==(""+t).indexOf("px")?this.el_.style[e]=t:this.el_.style[e]="auto"===t?"":t+"px",void(i||this.trigger("componentresize"));if(!this.el_)return 0;var n=this.el_.style[e],r=n.indexOf("px");return-1!==r?parseInt(n.slice(0,r),10):parseInt(this.el_["offset"+Ne(e)],10)},e.currentDimension=function(e){var t=0;if("width"!==e&&"height"!==e)throw new Error("currentDimension only accepts width or height value");if("function"==typeof v.getComputedStyle){var i=v.getComputedStyle(this.el_);t=i.getPropertyValue(e)||i[e]}if(0===(t=parseFloat(t))){var n="offset"+Ne(e);t=this.el_[n]}return t},e.currentDimensions=function(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}},e.currentWidth=function(){return this.currentDimension("width")},e.currentHeight=function(){return this.currentDimension("height")},e.focus=function(){this.el_.focus()},e.blur=function(){this.el_.blur()},e.handleKeyDown=function(e){this.player_&&(e.stopPropagation(),this.player_.handleKeyDown(e))},e.handleKeyPress=function(e){this.handleKeyDown(e)},e.emitTapEvents=function(){var n,t=0,r=null;this.on("touchstart",function(e){1===e.touches.length&&(r={pageX:e.touches[0].pageX,pageY:e.touches[0].pageY},t=v.performance.now(),n=!0)}),this.on("touchmove",function(e){if(1<e.touches.length)n=!1;else if(r){var t=e.touches[0].pageX-r.pageX,i=e.touches[0].pageY-r.pageY;10<Math.sqrt(t*t+i*i)&&(n=!1)}});function e(){n=!1}this.on("touchleave",e),this.on("touchcancel",e),this.on("touchend",function(e){!(r=null)===n&&v.performance.now()-t<200&&(e.preventDefault(),this.trigger("tap"))})},e.enableTouchActivity=function(){if(this.player()&&this.player().reportUserActivity){var t,i=ke(this.player(),this.player().reportUserActivity);this.on("touchstart",function(){i(),this.clearInterval(t),t=this.setInterval(i,250)});function e(e){i(),this.clearInterval(t)}this.on("touchmove",i),this.on("touchend",e),this.on("touchcancel",e)}},e.setTimeout=function(e,t){var i,n,r=this;return e=ke(this,e),i=v.setTimeout(function(){r.off("dispose",n),e()},t),(n=function(){return r.clearTimeout(i)}).guid="vjs-timeout-"+i,this.on("dispose",n),i},e.clearTimeout=function(e){v.clearTimeout(e);function t(){}return t.guid="vjs-timeout-"+e,this.off("dispose",t),e},e.setInterval=function(e,t){var i=this;e=ke(this,e);function n(){return i.clearInterval(r)}var r=v.setInterval(e,t);return n.guid="vjs-interval-"+r,this.on("dispose",n),r},e.clearInterval=function(e){v.clearInterval(e);function t(){}return t.guid="vjs-interval-"+e,this.off("dispose",t),e},e.requestAnimationFrame=function(e){var t,i,n=this;return this.supportsRaf_?(e=ke(this,e),t=v.requestAnimationFrame(function(){n.off("dispose",i),e()}),(i=function(){return n.cancelAnimationFrame(t)}).guid="vjs-raf-"+t,this.on("dispose",i),t):this.setTimeout(e,1e3/60)},e.cancelAnimationFrame=function(e){if(this.supportsRaf_){v.cancelAnimationFrame(e);function t(){}return t.guid="vjs-raf-"+e,this.off("dispose",t),e}return this.clearTimeout(e)},l.registerComponent=function(e,t){if("string"!=typeof e||!e)throw new Error('Illegal component name, "'+e+'"; must be a non-empty string.');var i,n=l.getComponent("Tech"),r=n&&n.isTech(t),a=l===t||l.prototype.isPrototypeOf(t.prototype);if(r||!a)throw i=r?"techs must be registered using Tech.registerTech()":"must be a Component subclass",new Error('Illegal component, "'+e+'"; '+i+".");e=Ne(e),l.components_||(l.components_={});var s=l.getComponent("Player");if("Player"===e&&s&&s.players){var o=s.players,u=Object.keys(o);if(o&&0<u.length&&u.map(function(e){return o[e]}).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return l.components_[e]=t},l.getComponent=function(e){if(e)return e=Ne(e),l.components_&&l.components_[e]?l.components_[e]:void 0},l}();Fe.prototype.supportsRaf_="function"==typeof v.requestAnimationFrame&&"function"==typeof v.cancelAnimationFrame,Fe.registerComponent("Component",Fe);var Ve,He,qe,ze,We=v.navigator&&v.navigator.userAgent||"",Ge=/AppleWebKit\/([\d.]+)/i.exec(We),$e=Ge?parseFloat(Ge.pop()):null,Xe=/iPad/i.test(We),Ke=/iPhone/i.test(We)&&!Xe,Ye=/iPod/i.test(We),Qe=Ke||Xe||Ye,Je=(Ve=We.match(/OS (\d+)_/i))&&Ve[1]?Ve[1]:null,Ze=/Android/i.test(We),et=function(){var e=We.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!e)return null;var t=e[1]&&parseFloat(e[1]),i=e[2]&&parseFloat(e[2]);return t&&i?parseFloat(e[1]+"."+e[2]):t||null}(),tt=Ze&&et<5&&$e<537,it=/Firefox/i.test(We),nt=/Edge/i.test(We),rt=!nt&&(/Chrome/i.test(We)||/CriOS/i.test(We)),at=(He=We.match(/(Chrome|CriOS)\/(\d+)/))&&He[2]?parseFloat(He[2]):null,st=(qe=/MSIE\s(\d+)\.\d/.exec(We),!(ze=qe&&parseFloat(qe[1]))&&/Trident\/7.0/i.test(We)&&/rv:11.0/.test(We)&&(ze=11),ze),ot=/Safari/i.test(We)&&!rt&&!Ze&&!nt,ut=(ot||Qe)&&!rt,lt=/Windows/i.test(We),ct=k()&&("ontouchstart"in v||v.navigator.maxTouchPoints||v.DocumentTouch&&v.document instanceof v.DocumentTouch),ht=Object.freeze({IS_IPAD:Xe,IS_IPHONE:Ke,IS_IPOD:Ye,IS_IOS:Qe,IOS_VERSION:Je,IS_ANDROID:Ze,ANDROID_VERSION:et,IS_NATIVE_ANDROID:tt,IS_FIREFOX:it,IS_EDGE:nt,IS_CHROME:rt,CHROME_VERSION:at,IE_VERSION:st,IS_SAFARI:ot,IS_ANY_SAFARI:ut,IS_WINDOWS:lt,TOUCH_ENABLED:ct});function dt(e,t,i,n){return function(e,t,i){if("number"!=typeof t||t<0||i<t)throw new Error("Failed to execute '"+e+"' on 'TimeRanges': The index provided ("+t+") is non-numeric or out of bounds (0-"+i+").")}(e,n,i.length-1),i[n][t]}function pt(e){return void 0===e||0===e.length?{length:0,start:function(){throw new Error("This TimeRanges object is empty")},end:function(){throw new Error("This TimeRanges object is empty")}}:{length:e.length,start:dt.bind(null,"start",0,e),end:dt.bind(null,"end",1,e)}}function ft(e,t){return Array.isArray(e)?pt(e):void 0===e||void 0===t?pt():pt([[e,t]])}function mt(e,t){var i,n,r=0;if(!t)return 0;e&&e.length||(e=ft(0,0));for(var a=0;a<e.length;a++)i=e.start(a),t<(n=e.end(a))&&(n=t),r+=n-i;return r/t}for(var gt,yt={prefixed:!0},vt=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror","fullscreen"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror","-webkit-full-screen"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror","-moz-full-screen"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError","-ms-fullscreen"]],_t=vt[0],bt=0;bt<vt.length;bt++)if(vt[bt][1]in h){gt=vt[bt];break}if(gt){for(var Tt=0;Tt<gt.length;Tt++)yt[_t[Tt]]=gt[Tt];yt.prefixed=gt[0]!==_t[0]}function St(e){if(e instanceof St)return e;"number"==typeof e?this.code=e:"string"==typeof e?this.message=e:b(e)&&("number"==typeof e.code&&(this.code=e.code),_(this,e)),this.message||(this.message=St.defaultMessages[this.code]||"")}St.prototype.code=0,St.prototype.message="",St.prototype.status=null,St.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],St.defaultMessages={1:"You aborted the media playback",2:"A network error caused the media download to fail part-way.",3:"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",4:"The media could not be loaded, either because the server or network failed or because the format is not supported.",5:"The media is encrypted and we do not have the keys to decrypt it."};for(var kt=0;kt<St.errorTypes.length;kt++)St[St.errorTypes[kt]]=kt,St.prototype[St.errorTypes[kt]]=kt;var wt=function(e,t){var i,n=null;try{i=JSON.parse(e,t)}catch(e){n=e}return[n,i]};function Ct(e){return null!=e&&"function"==typeof e.then}function Et(e){Ct(e)&&e.then(null,function(e){})}function At(n){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(function(e,t,i){return n[t]&&(e[t]=n[t]),e},{cues:n.cues&&Array.prototype.map.call(n.cues,function(e){return{startTime:e.startTime,endTime:e.endTime,text:e.text,id:e.id}})})}var Pt=function(e){var t=e.$$("track"),i=Array.prototype.map.call(t,function(e){return e.track});return Array.prototype.map.call(t,function(e){var t=At(e.track);return e.src&&(t.src=e.src),t}).concat(Array.prototype.filter.call(e.textTracks(),function(e){return-1===i.indexOf(e)}).map(At))},Lt=function(e,i){return e.forEach(function(e){var t=i.addRemoteTextTrack(e).track;!e.src&&e.cues&&e.cues.forEach(function(e){return t.addCue(e)})}),i.textTracks()};function It(e,t){return e(t={exports:{}},t.exports),t.exports}var Ot=It(function(e,t){function i(e){if(e&&"object"==typeof e){var t=e.which||e.keyCode||e.charCode;t&&(e=t)}if("number"==typeof e)return s[e];var i,n=String(e);return(i=r[n.toLowerCase()])?i:(i=a[n.toLowerCase()])||(1===n.length?n.charCodeAt(0):void 0)}i.isEventKey=function(e,t){if(e&&"object"==typeof e){var i=e.which||e.keyCode||e.charCode;if(null==i)return!1;if("string"==typeof t){var n;if(n=r[t.toLowerCase()])return n===i;if(n=a[t.toLowerCase()])return n===i}else if("number"==typeof t)return t===i;return!1}};var r=(t=e.exports=i).code=t.codes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,esc:27,space:32,"page up":33,"page down":34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46,command:91,"left command":91,"right command":93,"numpad *":106,"numpad +":107,"numpad -":109,"numpad .":110,"numpad /":111,"num lock":144,"scroll lock":145,"my computer":182,"my calculator":183,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},a=t.aliases={windows:91,"⇧":16,"⌥":18,"⌃":17,"⌘":91,ctl:17,control:17,option:18,pause:19,break:19,caps:20,return:13,escape:27,spc:32,spacebar:32,pgup:33,pgdn:34,ins:45,del:46,cmd:91};for(n=97;n<123;n++)r[String.fromCharCode(n)]=n-32;for(var n=48;n<58;n++)r[n-48]=n;for(n=1;n<13;n++)r["f"+n]=n+111;for(n=0;n<10;n++)r["numpad "+n]=n+96;var s=t.names=t.title={};for(n in r)s[r[n]]=n;for(var o in a)r[o]=a[o]}),xt=(Ot.code,Ot.codes,Ot.aliases,Ot.names,Ot.title,"vjs-modal-dialog"),Ut=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).opened_=i.hasBeenOpened_=i.hasBeenFilled_=!1,i.closeable(!i.options_.uncloseable),i.content(i.options_.content),i.contentEl_=A("div",{className:xt+"-content"},{role:"document"}),i.descEl_=A("p",{className:xt+"-description vjs-control-text",id:i.el().getAttribute("aria-describedby")}),P(i.descEl_,i.description()),i.el_.appendChild(i.descEl_),i.el_.appendChild(i.contentEl_),i}p(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":this.id()+"_description","aria-hidden":"true","aria-label":this.label(),role:"dialog"})},t.dispose=function(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return xt+" vjs-hidden "+n.prototype.buildCSSClass.call(this)},t.label=function(){return this.localize(this.options_.label||"Modal Window")},t.description=function(){var e=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(e+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),e},t.open=function(){if(!this.opened_){var e=this.player();this.trigger("beforemodalopen"),this.opened_=!0,!this.options_.fillAlways&&(this.hasBeenOpened_||this.hasBeenFilled_)||this.fill(),this.wasPlaying_=!e.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&e.pause(),this.on("keydown",this.handleKeyDown),this.hadControls_=e.controls(),e.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0}},t.opened=function(e){return"boolean"==typeof e&&this[e?"open":"close"](),this.opened_},t.close=function(){if(this.opened_){var e=this.player();this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&e.play(),this.off("keydown",this.handleKeyDown),this.hadControls_&&e.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose()}},t.closeable=function(e){if("boolean"==typeof e){var t=this.closeable_=!!e,i=this.getChild("closeButton");if(t&&!i){var n=this.contentEl_;this.contentEl_=this.el_,i=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=n,this.on(i,"close",this.close)}!t&&i&&(this.off(i,"close",this.close),this.removeChild(i),i.dispose())}return this.closeable_},t.fill=function(){this.fillWith(this.content())},t.fillWith=function(e){var t=this.contentEl(),i=t.parentNode,n=t.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,i.removeChild(t),this.empty(),X(t,e),this.trigger("modalfill"),n?i.insertBefore(t,n):i.appendChild(t);var r=this.getChild("closeButton");r&&i.appendChild(r.el_)},t.empty=function(){this.trigger("beforemodalempty"),W(this.contentEl()),this.trigger("modalempty")},t.content=function(e){return"undefined"!=typeof e&&(this.content_=e),this.content_},t.conditionalFocus_=function(){var e=h.activeElement,t=this.player_.el_;this.previouslyActiveEl_=null,!t.contains(e)&&t!==e||(this.previouslyActiveEl_=e,this.focus())},t.conditionalBlur_=function(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)},t.handleKeyDown=function(e){if(e.stopPropagation(),Ot.isEventKey(e,"Escape")&&this.closeable())return e.preventDefault(),void this.close();if(Ot.isEventKey(e,"Tab")){for(var t,i=this.focusableEls_(),n=this.el_.querySelector(":focus"),r=0;r<i.length;r++)if(n===i[r]){t=r;break}h.activeElement===this.el_&&(t=0),e.shiftKey&&0===t?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||t!==i.length-1||(i[0].focus(),e.preventDefault())}},t.focusableEls_=function(){var e=this.el_.querySelectorAll("*");return Array.prototype.filter.call(e,function(e){return(e instanceof v.HTMLAnchorElement||e instanceof v.HTMLAreaElement)&&e.hasAttribute("href")||(e instanceof v.HTMLInputElement||e instanceof v.HTMLSelectElement||e instanceof v.HTMLTextAreaElement||e instanceof v.HTMLButtonElement)&&!e.hasAttribute("disabled")||e instanceof v.HTMLIFrameElement||e instanceof v.HTMLObjectElement||e instanceof v.HTMLEmbedElement||e.hasAttribute("tabindex")&&-1!==e.getAttribute("tabindex")||e.hasAttribute("contenteditable")})},e}(Fe);Ut.prototype.options_={pauseOnOpen:!0,temporary:!0},Fe.registerComponent("ModalDialog",Ut);var Dt=function(n){function e(e){var t;void 0===e&&(e=[]),(t=n.call(this)||this).tracks_=[],Object.defineProperty(f(t),"length",{get:function(){return this.tracks_.length}});for(var i=0;i<e.length;i++)t.addTrack(e[i]);return t}p(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this.tracks_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.tracks_[t]}}),-1===this.tracks_.indexOf(e)&&(this.tracks_.push(e),this.trigger({track:e,type:"addtrack",target:this}))},t.removeTrack=function(e){for(var t,i=0,n=this.length;i<n;i++)if(this[i]===e){(t=this[i]).off&&t.off(),this.tracks_.splice(i,1);break}t&&this.trigger({track:t,type:"removetrack",target:this})},t.getTrackById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},e}(Ce);for(var Rt in Dt.prototype.allowedEvents_={change:"change",addtrack:"addtrack",removetrack:"removetrack"},Dt.prototype.allowedEvents_)Dt.prototype["on"+Rt]=null;function Mt(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].enabled=!1)}function Bt(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].selected=!1)}function Nt(e){var t=["protocol","hostname","port","pathname","search","hash","host"],i=h.createElement("a");i.href=e;var n,r=""===i.host&&"file:"!==i.protocol;r&&((n=h.createElement("div")).innerHTML='<a href="'+e+'"></a>',i=n.firstChild,n.setAttribute("style","display:none; position:absolute;"),h.body.appendChild(n));for(var a={},s=0;s<t.length;s++)a[t[s]]=i[t[s]];return"http:"===a.protocol&&(a.host=a.host.replace(/:80$/,"")),"https:"===a.protocol&&(a.host=a.host.replace(/:443$/,"")),a.protocol||(a.protocol=v.location.protocol),r&&h.body.removeChild(n),a}function jt(e){if(!e.match(/^https?:\/\//)){var t=h.createElement("div");t.innerHTML='<a href="'+e+'">x</a>',e=t.firstChild.href}return e}function Ft(e){if("string"==typeof e){var t=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i.exec(e);if(t)return t.pop().toLowerCase()}return""}function Vt(e){var t=v.location,i=Nt(e);return(":"===i.protocol?t.protocol:i.protocol)+i.host!==t.protocol+t.host}var Ht=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].enabled){Mt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,t}p(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.enabled&&Mt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.enabledChange_=function(){t.changing_||(t.changing_=!0,Mt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("enabledchange",e.enabledChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.enabledChange_&&(e.removeEventListener("enabledchange",e.enabledChange_),e.enabledChange_=null)},e}(Dt),qt=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].selected){Bt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,Object.defineProperty(f(t),"selectedIndex",{get:function(){for(var e=0;e<this.length;e++)if(this[e].selected)return e;return-1},set:function(){}}),t}p(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.selected&&Bt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.selectedChange_=function(){t.changing_||(t.changing_=!0,Bt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("selectedchange",e.selectedChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.selectedChange_&&(e.removeEventListener("selectedchange",e.selectedChange_),e.selectedChange_=null)},e}(Dt),zt=function(i){function e(){return i.apply(this,arguments)||this}p(e,i);var t=e.prototype;return t.addTrack=function(e){var t=this;i.prototype.addTrack.call(this,e),this.queueChange_||(this.queueChange_=function(){return t.queueTrigger("change")}),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=function(){return t.trigger("selectedlanguagechange")}),e.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(e.kind)&&e.addEventListener("modechange",this.triggerSelectedlanguagechange_)},t.removeTrack=function(e){i.prototype.removeTrack.call(this,e),e.removeEventListener&&(this.queueChange_&&e.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&e.removeEventListener("modechange",this.triggerSelectedlanguagechange_))},e}(Dt),Wt=function(){function e(e){void 0===e&&(e=[]),this.trackElements_=[],Object.defineProperty(this,"length",{get:function(){return this.trackElements_.length}});for(var t=0,i=e.length;t<i;t++)this.addTrackElement_(e[t])}var t=e.prototype;return t.addTrackElement_=function(e){var t=this.trackElements_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.trackElements_[t]}}),-1===this.trackElements_.indexOf(e)&&this.trackElements_.push(e)},t.getTrackElementByTrack_=function(e){for(var t,i=0,n=this.trackElements_.length;i<n;i++)if(e===this.trackElements_[i].track){t=this.trackElements_[i];break}return t},t.removeTrackElement_=function(e){for(var t=0,i=this.trackElements_.length;t<i;t++)if(e===this.trackElements_[t]){this.trackElements_[t].track&&"function"==typeof this.trackElements_[t].track.off&&this.trackElements_[t].track.off(),"function"==typeof this.trackElements_[t].off&&this.trackElements_[t].off(),this.trackElements_.splice(t,1);break}},e}(),Gt=function(){function t(e){t.prototype.setCues_.call(this,e),Object.defineProperty(this,"length",{get:function(){return this.length_}})}var e=t.prototype;return e.setCues_=function(e){var t=this.length||0,i=0,n=e.length;this.cues_=e,this.length_=e.length;function r(e){""+e in this||Object.defineProperty(this,""+e,{get:function(){return this.cues_[e]}})}if(t<n)for(i=t;i<n;i++)r.call(this,i)},e.getCueById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},t}(),$t={alternative:"alternative",captions:"captions",main:"main",sign:"sign",subtitles:"subtitles",commentary:"commentary"},Xt={alternative:"alternative",descriptions:"descriptions",main:"main","main-desc":"main-desc",translation:"translation",commentary:"commentary"},Kt={subtitles:"subtitles",captions:"captions",descriptions:"descriptions",chapters:"chapters",metadata:"metadata"},Yt={disabled:"disabled",hidden:"hidden",showing:"showing"},Qt=function(a){function e(e){var t;void 0===e&&(e={}),t=a.call(this)||this;function i(e){Object.defineProperty(f(t),e,{get:function(){return n[e]},set:function(){}})}var n={id:e.id||"vjs_track_"+ee(),kind:e.kind||"",label:e.label||"",language:e.language||""};for(var r in n)i(r);return t}return p(e,a),e}(Ce),Jt=Object.freeze({parseUrl:Nt,getAbsoluteURL:jt,getFileExtension:Ft,isCrossOrigin:Vt}),Zt=function(e){var t=ei.call(e);return"[object Function]"===t||"function"==typeof e&&"[object RegExp]"!==t||"undefined"!=typeof window&&(e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt)},ei=Object.prototype.toString;function ti(e){var t=si.call(e),i="[object Arguments]"===t;return i=i||"[object Array]"!==t&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&0<=e.length&&"[object Function]"===si.call(e.callee)}var ii,ni=Array.prototype.slice,ri=Object.prototype.toString,ai=Function.prototype.bind||function(t){var i=this;if("function"!=typeof i||"[object Function]"!==ri.call(i))throw new TypeError("Function.prototype.bind called on incompatible "+i);for(var n,r=ni.call(arguments,1),e=Math.max(0,i.length-r.length),a=[],s=0;s<e;s++)a.push("$"+s);if(n=Function("binder","return function ("+a.join(",")+"){ return binder.apply(this,arguments); }")(function(){if(this instanceof n){var e=i.apply(this,r.concat(ni.call(arguments)));return Object(e)===e?e:this}return i.apply(t,r.concat(ni.call(arguments)))}),i.prototype){function o(){}o.prototype=i.prototype,n.prototype=new o,o.prototype=null}return n},si=Object.prototype.toString;if(!Object.keys){function oi(e){var t=e.constructor;return t&&t.prototype===e}var ui=Object.prototype.hasOwnProperty,li=Object.prototype.toString,ci=ti,hi=Object.prototype.propertyIsEnumerable,di=!hi.call({toString:null},"toString"),pi=hi.call(function(){},"prototype"),fi=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],mi={$applicationCache:!0,$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$onmozfullscreenchange:!0,$onmozfullscreenerror:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},gi=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!mi["$"+e]&&ui.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{oi(window[e])}catch(e){return!0}}catch(e){return!0}return!1}();ii=function(e){var t=null!==e&&"object"==typeof e,i="[object Function]"===li.call(e),n=ci(e),r=t&&"[object String]"===li.call(e),a=[];if(!t&&!i&&!n)throw new TypeError("Object.keys called on a non-object");var s=pi&&i;if(r&&0<e.length&&!ui.call(e,0))for(var o=0;o<e.length;++o)a.push(String(o));if(n&&0<e.length)for(var u=0;u<e.length;++u)a.push(String(u));else for(var l in e)s&&"prototype"===l||!ui.call(e,l)||a.push(String(l));if(di)for(var c=function(e){if("undefined"==typeof window||!gi)return oi(e);try{return oi(e)}catch(e){return!1}}(e),h=0;h<fi.length;++h)c&&"constructor"===fi[h]||!ui.call(e,fi[h])||a.push(fi[h]);return a}}var yi=ii,vi=Array.prototype.slice,_i=Object.keys,bi=_i?function(e){return _i(e)}:yi,Ti=Object.keys;bi.shim=function(){Object.keys?function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2)||(Object.keys=function(e){return ti(e)?Ti(vi.call(e)):Ti(e)}):Object.keys=bi;return Object.keys||bi};function Si(e,t,i,n){t in e&&(!function(e){return"function"==typeof e&&"[object Function]"===Ei.call(e)}(n)||!n())||(Li?Pi(e,t,{configurable:!0,enumerable:!1,value:i,writable:!0}):e[t]=i)}function ki(e,t,i){var n=2<arguments.length?i:{},r=wi(t);Ci&&(r=Ai.call(r,Object.getOwnPropertySymbols(t)));for(var a=0;a<r.length;a+=1)Si(e,r[a],t[r[a]],n[r[a]])}var wi=bi,Ci="function"==typeof Symbol&&"symbol"==typeof Symbol("foo"),Ei=Object.prototype.toString,Ai=Array.prototype.concat,Pi=Object.defineProperty,Li=Pi&&function(){var e={};try{for(var t in Pi(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}();ki.supportsDescriptors=!!Li;function Ii(e,t){if(1<arguments.length&&"boolean"!=typeof t)throw new TypeError('"allowMissing" argument must be a boolean');var i="$ "+e;if(!(i in zi))throw new SyntaxError("intrinsic "+e+" does not exist!");if("undefined"==typeof zi[i]&&!t)throw new TypeError("intrinsic "+e+" exists, but is not available. Please file an issue!");return zi[i]}function Oi(e,t,i,n){var r=Xi[t];if("function"!=typeof r)throw new $i("unknown record type: "+t);if(!r(e,n))throw new Gi(i+" must be a "+t)}function xi(e){return 0<=e?1:-1}function Ui(e){try{var t=Ji.call(e);return Zi.test(t)}catch(e){return!1}}function Di(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if("function"==typeof e&&!e.prototype)return!0;if(tn)return function(e){try{return!Ui(e)&&(Ji.call(e),!0)}catch(e){return!1}}(e);if(Ui(e))return!1;var t=en.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}function Ri(e){return null===e||"function"!=typeof e&&"object"!=typeof e}function Mi(){var e=un.ToString(un.CheckObjectCoercible(this));return ln(ln(e,cn,""),hn,"")}function Bi(){return String.prototype.trim&&"​"==="​".trim()?String.prototype.trim:Mi}var Ni,ji=ki,Fi=Object.getOwnPropertyDescriptor?function(){return Object.getOwnPropertyDescriptor(arguments,"callee").get}():function(){throw new TypeError},Vi="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator,Hi=Object.getPrototypeOf||function(e){return e.__proto__},qi="undefined"==typeof Uint8Array?Ni:Hi(Uint8Array),zi={"$ %Array%":Array,"$ %ArrayBuffer%":"undefined"==typeof ArrayBuffer?Ni:ArrayBuffer,"$ %ArrayBufferPrototype%":"undefined"==typeof ArrayBuffer?Ni:ArrayBuffer.prototype,"$ %ArrayIteratorPrototype%":Vi?Hi([][Symbol.iterator]()):Ni,"$ %ArrayPrototype%":Array.prototype,"$ %ArrayProto_entries%":Array.prototype.entries,"$ %ArrayProto_forEach%":Array.prototype.forEach,"$ %ArrayProto_keys%":Array.prototype.keys,"$ %ArrayProto_values%":Array.prototype.values,"$ %AsyncFromSyncIteratorPrototype%":Ni,"$ %AsyncFunction%":void 0,"$ %AsyncFunctionPrototype%":Ni,"$ %AsyncGenerator%":Ni,"$ %AsyncGeneratorFunction%":void 0,"$ %AsyncGeneratorPrototype%":Ni,"$ %AsyncIteratorPrototype%":Ni,"$ %Atomics%":"undefined"==typeof Atomics?Ni:Atomics,"$ %Boolean%":Boolean,"$ %BooleanPrototype%":Boolean.prototype,"$ %DataView%":"undefined"==typeof DataView?Ni:DataView,"$ %DataViewPrototype%":"undefined"==typeof DataView?Ni:DataView.prototype,"$ %Date%":Date,"$ %DatePrototype%":Date.prototype,"$ %decodeURI%":decodeURI,"$ %decodeURIComponent%":decodeURIComponent,"$ %encodeURI%":encodeURI,"$ %encodeURIComponent%":encodeURIComponent,"$ %Error%":Error,"$ %ErrorPrototype%":Error.prototype,"$ %eval%":eval,"$ %EvalError%":EvalError,"$ %EvalErrorPrototype%":EvalError.prototype,"$ %Float32Array%":"undefined"==typeof Float32Array?Ni:Float32Array,"$ %Float32ArrayPrototype%":"undefined"==typeof Float32Array?Ni:Float32Array.prototype,"$ %Float64Array%":"undefined"==typeof Float64Array?Ni:Float64Array,"$ %Float64ArrayPrototype%":"undefined"==typeof Float64Array?Ni:Float64Array.prototype,"$ %Function%":Function,"$ %FunctionPrototype%":Function.prototype,"$ %Generator%":Ni,"$ %GeneratorFunction%":void 0,"$ %GeneratorPrototype%":Ni,"$ %Int8Array%":"undefined"==typeof Int8Array?Ni:Int8Array,"$ %Int8ArrayPrototype%":"undefined"==typeof Int8Array?Ni:Int8Array.prototype,"$ %Int16Array%":"undefined"==typeof Int16Array?Ni:Int16Array,"$ %Int16ArrayPrototype%":"undefined"==typeof Int16Array?Ni:Int8Array.prototype,"$ %Int32Array%":"undefined"==typeof Int32Array?Ni:Int32Array,"$ %Int32ArrayPrototype%":"undefined"==typeof Int32Array?Ni:Int32Array.prototype,"$ %isFinite%":isFinite,"$ %isNaN%":isNaN,"$ %IteratorPrototype%":Vi?Hi(Hi([][Symbol.iterator]())):Ni,"$ %JSON%":JSON,"$ %JSONParse%":JSON.parse,"$ %Map%":"undefined"==typeof Map?Ni:Map,"$ %MapIteratorPrototype%":"undefined"!=typeof Map&&Vi?Hi((new Map)[Symbol.iterator]()):Ni,"$ %MapPrototype%":"undefined"==typeof Map?Ni:Map.prototype,"$ %Math%":Math,"$ %Number%":Number,"$ %NumberPrototype%":Number.prototype,"$ %Object%":Object,"$ %ObjectPrototype%":Object.prototype,"$ %ObjProto_toString%":Object.prototype.toString,"$ %ObjProto_valueOf%":Object.prototype.valueOf,"$ %parseFloat%":parseFloat,"$ %parseInt%":parseInt,"$ %Promise%":"undefined"==typeof Promise?Ni:Promise,"$ %PromisePrototype%":"undefined"==typeof Promise?Ni:Promise.prototype,"$ %PromiseProto_then%":"undefined"==typeof Promise?Ni:Promise.prototype.then,"$ %Promise_all%":"undefined"==typeof Promise?Ni:Promise.all,"$ %Promise_reject%":"undefined"==typeof Promise?Ni:Promise.reject,"$ %Promise_resolve%":"undefined"==typeof Promise?Ni:Promise.resolve,"$ %Proxy%":"undefined"==typeof Proxy?Ni:Proxy,"$ %RangeError%":RangeError,"$ %RangeErrorPrototype%":RangeError.prototype,"$ %ReferenceError%":ReferenceError,"$ %ReferenceErrorPrototype%":ReferenceError.prototype,"$ %Reflect%":"undefined"==typeof Reflect?Ni:Reflect,"$ %RegExp%":RegExp,"$ %RegExpPrototype%":RegExp.prototype,"$ %Set%":"undefined"==typeof Set?Ni:Set,"$ %SetIteratorPrototype%":"undefined"!=typeof Set&&Vi?Hi((new Set)[Symbol.iterator]()):Ni,"$ %SetPrototype%":"undefined"==typeof Set?Ni:Set.prototype,"$ %SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?Ni:SharedArrayBuffer,"$ %SharedArrayBufferPrototype%":"undefined"==typeof SharedArrayBuffer?Ni:SharedArrayBuffer.prototype,"$ %String%":String,"$ %StringIteratorPrototype%":Vi?Hi(""[Symbol.iterator]()):Ni,"$ %StringPrototype%":String.prototype,"$ %Symbol%":Vi?Symbol:Ni,"$ %SymbolPrototype%":Vi?Symbol.prototype:Ni,"$ %SyntaxError%":SyntaxError,"$ %SyntaxErrorPrototype%":SyntaxError.prototype,"$ %ThrowTypeError%":Fi,"$ %TypedArray%":qi,"$ %TypedArrayPrototype%":qi?qi.prototype:Ni,"$ %TypeError%":TypeError,"$ %TypeErrorPrototype%":TypeError.prototype,"$ %Uint8Array%":"undefined"==typeof Uint8Array?Ni:Uint8Array,"$ %Uint8ArrayPrototype%":"undefined"==typeof Uint8Array?Ni:Uint8Array.prototype,"$ %Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?Ni:Uint8ClampedArray,"$ %Uint8ClampedArrayPrototype%":"undefined"==typeof Uint8ClampedArray?Ni:Uint8ClampedArray.prototype,"$ %Uint16Array%":"undefined"==typeof Uint16Array?Ni:Uint16Array,"$ %Uint16ArrayPrototype%":"undefined"==typeof Uint16Array?Ni:Uint16Array.prototype,"$ %Uint32Array%":"undefined"==typeof Uint32Array?Ni:Uint32Array,"$ %Uint32ArrayPrototype%":"undefined"==typeof Uint32Array?Ni:Uint32Array.prototype,"$ %URIError%":URIError,"$ %URIErrorPrototype%":URIError.prototype,"$ %WeakMap%":"undefined"==typeof WeakMap?Ni:WeakMap,"$ %WeakMapPrototype%":"undefined"==typeof WeakMap?Ni:WeakMap.prototype,"$ %WeakSet%":"undefined"==typeof WeakSet?Ni:WeakSet,"$ %WeakSetPrototype%":"undefined"==typeof WeakSet?Ni:WeakSet.prototype},Wi=ai.call(Function.call,Object.prototype.hasOwnProperty),Gi=Ii("%TypeError%"),$i=Ii("%SyntaxError%"),Xi={"Property Descriptor":function(e,t){if("Object"!==e.Type(t))return!1;var i={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var n in t)if(Wi(t,n)&&!i[n])return!1;var r=Wi(t,"[[Value]]"),a=Wi(t,"[[Get]]")||Wi(t,"[[Set]]");if(r&&a)throw new Gi("Property Descriptors may not be both accessor and data descriptors");return!0}},Ki=Number.isNaN||function(e){return e!=e},Yi=Number.isNaN||function(e){return e!=e},Qi=Number.isFinite||function(e){return"number"==typeof e&&!Yi(e)&&e!==1/0&&e!==-1/0},Ji=Function.prototype.toString,Zi=/^\s*class\b/,en=Object.prototype.toString,tn="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,nn=Object.prototype.toString,rn=function(e,t){var i;if((i=1<arguments.length?t:"[object Date]"===nn.call(e)?String:Number)!==String&&i!==Number)throw new TypeError("invalid [[DefaultValue]] hint supplied");var n,r,a=i===String?["toString","valueOf"]:["valueOf","toString"];for(r=0;r<a.length;++r)if(Di(e[a[r]])&&(n=e[a[r]](),Ri(n)))return n;throw new TypeError("No default value")},an=Ii("%Object%"),sn=Ii("%TypeError%"),on=Ii("%String%"),un={ToPrimitive:function(e,t){return Ri(e)?e:1<arguments.length?rn(e,t):rn(e)},ToBoolean:function(e){return!!e},ToNumber:function(e){return+e},ToInteger:function(e){var t=this.ToNumber(e);return Ki(t)?0:0!==t&&Qi(t)?xi(t)*Math.floor(Math.abs(t)):t},ToInt32:function(e){return this.ToNumber(e)>>0},ToUint32:function(e){return this.ToNumber(e)>>>0},ToUint16:function(e){var t=this.ToNumber(e);return Ki(t)||0===t||!Qi(t)?0:function(e,t){var i=e%t;return Math.floor(0<=i?i:i+t)}(xi(t)*Math.floor(Math.abs(t)),65536)},ToString:function(e){return on(e)},ToObject:function(e){return this.CheckObjectCoercible(e),an(e)},CheckObjectCoercible:function(e,t){if(null==e)throw new sn(t||"Cannot call method on "+e);return e},IsCallable:Di,SameValue:function(e,t){return e===t?0!==e||1/e==1/t:Ki(e)&&Ki(t)},Type:function(e){return null===e?"Null":"undefined"==typeof e?"Undefined":"function"==typeof e||"object"==typeof e?"Object":"number"==typeof e?"Number":"boolean"==typeof e?"Boolean":"string"==typeof e?"String":void 0},IsPropertyDescriptor:function(e){if("Object"!==this.Type(e))return!1;var t={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var i in e)if(Wi(e,i)&&!t[i])return!1;var n=Wi(e,"[[Value]]"),r=Wi(e,"[[Get]]")||Wi(e,"[[Set]]");if(n&&r)throw new sn("Property Descriptors may not be both accessor and data descriptors");return!0},IsAccessorDescriptor:function(e){return"undefined"!=typeof e&&(Oi(this,"Property Descriptor","Desc",e),!(!Wi(e,"[[Get]]")&&!Wi(e,"[[Set]]")))},IsDataDescriptor:function(e){return"undefined"!=typeof e&&(Oi(this,"Property Descriptor","Desc",e),!(!Wi(e,"[[Value]]")&&!Wi(e,"[[Writable]]")))},IsGenericDescriptor:function(e){return"undefined"!=typeof e&&(Oi(this,"Property Descriptor","Desc",e),!this.IsAccessorDescriptor(e)&&!this.IsDataDescriptor(e))},FromPropertyDescriptor:function(e){if("undefined"==typeof e)return e;if(Oi(this,"Property Descriptor","Desc",e),this.IsDataDescriptor(e))return{value:e["[[Value]]"],writable:!!e["[[Writable]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};if(this.IsAccessorDescriptor(e))return{get:e["[[Get]]"],set:e["[[Set]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};throw new sn("FromPropertyDescriptor must be called with a fully populated Property Descriptor")},ToPropertyDescriptor:function(e){if("Object"!==this.Type(e))throw new sn("ToPropertyDescriptor requires an object");var t={};if(Wi(e,"enumerable")&&(t["[[Enumerable]]"]=this.ToBoolean(e.enumerable)),Wi(e,"configurable")&&(t["[[Configurable]]"]=this.ToBoolean(e.configurable)),Wi(e,"value")&&(t["[[Value]]"]=e.value),Wi(e,"writable")&&(t["[[Writable]]"]=this.ToBoolean(e.writable)),Wi(e,"get")){var i=e.get;if("undefined"!=typeof i&&!this.IsCallable(i))throw new TypeError("getter must be a function");t["[[Get]]"]=i}if(Wi(e,"set")){var n=e.set;if("undefined"!=typeof n&&!this.IsCallable(n))throw new sn("setter must be a function");t["[[Set]]"]=n}if((Wi(t,"[[Get]]")||Wi(t,"[[Set]]"))&&(Wi(t,"[[Value]]")||Wi(t,"[[Writable]]")))throw new sn("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");return t}},ln=ai.call(Function.call,String.prototype.replace),cn=/^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/,hn=/[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/,dn=ai.call(Function.call,Bi());ji(dn,{getPolyfill:Bi,implementation:Mi,shim:function(){var e=Bi();return ji(String.prototype,{trim:e},{trim:function(){return String.prototype.trim!==e}}),e}});var pn=dn,fn=Object.prototype.toString,mn=Object.prototype.hasOwnProperty,gn=function(e,t,i){if(!Di(t))throw new TypeError("iterator must be a function");var n;3<=arguments.length&&(n=i),"[object Array]"===fn.call(e)?function(e,t,i){for(var n=0,r=e.length;n<r;n++)mn.call(e,n)&&(null==i?t(e[n],n,e):t.call(i,e[n],n,e))}(e,t,n):"string"==typeof e?function(e,t,i){for(var n=0,r=e.length;n<r;n++)null==i?t(e.charAt(n),n,e):t.call(i,e.charAt(n),n,e)}(e,t,n):function(e,t,i){for(var n in e)mn.call(e,n)&&(null==i?t(e[n],n,e):t.call(i,e[n],n,e))}(e,t,n)},yn=function(e){if(!e)return{};var r={};return gn(pn(e).split("\n"),function(e){var t=e.indexOf(":"),i=pn(e.slice(0,t)).toLowerCase(),n=pn(e.slice(t+1));"undefined"==typeof r[i]?r[i]=n:!function(e){return"[object Array]"===Object.prototype.toString.call(e)}(r[i])?r[i]=[r[i],n]:r[i].push(n)}),r},vn=function(){for(var e={},t=0;t<arguments.length;t++){var i=arguments[t];for(var n in i)_n.call(i,n)&&(e[n]=i[n])}return e},_n=Object.prototype.hasOwnProperty;var bn=Sn;function Tn(e,t,i){var n=e;return Zt(t)?(i=t,"string"==typeof e&&(n={uri:e})):n=vn(t,{uri:e}),n.callback=i,n}function Sn(e,t,i){return kn(t=Tn(e,t,i))}function kn(n){if("undefined"==typeof n.callback)throw new Error("callback argument missing");var r=!1,a=function(e,t,i){r||(r=!0,n.callback(e,t,i))};function t(e){return clearTimeout(o),e instanceof Error||(e=new Error(""+(e||"Unknown XMLHttpRequest Error"))),e.statusCode=0,a(e,m)}function e(){if(!s){var e;clearTimeout(o),e=n.useXDR&&void 0===u.status?200:1223===u.status?204:u.status;var t=m,i=null;return 0!==e?(t={body:function(){var e=void 0;if(e=u.response?u.response:u.responseText||function(e){if("document"===e.responseType)return e.responseXML;var t=e.responseXML&&"parsererror"===e.responseXML.documentElement.nodeName;return""!==e.responseType||t?null:e.responseXML}(u),f)try{e=JSON.parse(e)}catch(e){}return e}(),statusCode:e,method:c,headers:{},url:l,rawRequest:u},u.getAllResponseHeaders&&(t.headers=yn(u.getAllResponseHeaders()))):i=new Error("Internal XMLHttpRequest Error"),a(i,t,t.body)}}var i,s,o,u=n.xhr||null,l=(u=u||(n.cors||n.useXDR?new Sn.XDomainRequest:new Sn.XMLHttpRequest)).url=n.uri||n.url,c=u.method=n.method||"GET",h=n.body||n.data,d=u.headers=n.headers||{},p=!!n.sync,f=!1,m={body:void 0,headers:{},statusCode:0,method:c,url:l,rawRequest:u};if("json"in n&&!1!==n.json&&(f=!0,d.accept||d.Accept||(d.Accept="application/json"),"GET"!==c&&"HEAD"!==c&&(d["content-type"]||d["Content-Type"]||(d["Content-Type"]="application/json"),h=JSON.stringify(!0===n.json?h:n.json))),u.onreadystatechange=function(){4===u.readyState&&setTimeout(e,0)},u.onload=e,u.onerror=t,u.onprogress=function(){},u.onabort=function(){s=!0},u.ontimeout=t,u.open(c,l,!p,n.username,n.password),p||(u.withCredentials=!!n.withCredentials),!p&&0<n.timeout&&(o=setTimeout(function(){if(!s){s=!0,u.abort("timeout");var e=new Error("XMLHttpRequest timeout");e.code="ETIMEDOUT",t(e)}},n.timeout)),u.setRequestHeader)for(i in d)d.hasOwnProperty(i)&&u.setRequestHeader(i,d[i]);else if(n.headers&&!function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}(n.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in n&&(u.responseType=n.responseType),"beforeSend"in n&&"function"==typeof n.beforeSend&&n.beforeSend(u),u.send(h||null),u}Sn.XMLHttpRequest=v.XMLHttpRequest||function(){},Sn.XDomainRequest="withCredentials"in new Sn.XMLHttpRequest?Sn.XMLHttpRequest:v.XDomainRequest,function(e,t){for(var i=0;i<e.length;i++)t(e[i])}(["get","put","post","patch","head","delete"],function(n){Sn["delete"===n?"del":n]=function(e,t,i){return(t=Tn(e,t,i)).method=n.toUpperCase(),kn(t)}});function wn(e,t){var i=new v.WebVTT.Parser(v,v.vttjs,v.WebVTT.StringDecoder()),n=[];i.oncue=function(e){t.addCue(e)},i.onparsingerror=function(e){n.push(e)},i.onflush=function(){t.trigger({type:"loadeddata",target:t})},i.parse(e),0<n.length&&(v.console&&v.console.groupCollapsed&&v.console.groupCollapsed("Text Track parsing errors for "+t.src),n.forEach(function(e){return m.error(e)}),v.console&&v.console.groupEnd&&v.console.groupEnd()),i.flush()}var Cn=function(l){function e(e){var t;if(void 0===e&&(e={}),!e.tech)throw new Error("A tech was not provided.");var i=je(e,{kind:Kt[e.kind]||"subtitles",language:e.language||e.srclang||""}),n=Yt[i.mode]||"disabled",r=i.default;"metadata"!==i.kind&&"chapters"!==i.kind||(n="hidden"),(t=l.call(this,i)||this).tech_=i.tech,t.cues_=[],t.activeCues_=[];var a=new Gt(t.cues_),s=new Gt(t.activeCues_),o=!1,u=ke(f(t),function(){this.activeCues=this.activeCues,o&&(this.trigger("cuechange"),o=!1)});return"disabled"!==n&&t.tech_.ready(function(){t.tech_.on("timeupdate",u)},!0),Object.defineProperties(f(t),{default:{get:function(){return r},set:function(){}},mode:{get:function(){return n},set:function(e){var t=this;Yt[e]&&("disabled"!==(n=e)?this.tech_.ready(function(){t.tech_.on("timeupdate",u)},!0):this.tech_.off("timeupdate",u),this.trigger("modechange"))}},cues:{get:function(){return this.loaded_?a:null},set:function(){}},activeCues:{get:function(){if(!this.loaded_)return null;if(0===this.cues.length)return s;for(var e=this.tech_.currentTime(),t=[],i=0,n=this.cues.length;i<n;i++){var r=this.cues[i];r.startTime<=e&&r.endTime>=e?t.push(r):r.startTime===r.endTime&&r.startTime<=e&&r.startTime+.5>=e&&t.push(r)}if(o=!1,t.length!==this.activeCues_.length)o=!0;else for(var a=0;a<t.length;a++)-1===this.activeCues_.indexOf(t[a])&&(o=!0);return this.activeCues_=t,s.setCues_(this.activeCues_),s},set:function(){}}}),i.src?(t.src=i.src,function(e,a){var t={uri:e},i=Vt(e);i&&(t.cors=i),bn(t,ke(this,function(e,t,i){if(e)return m.error(e,t);if(a.loaded_=!0,"function"!=typeof v.WebVTT){if(a.tech_){function n(){m.error("vttjs failed to load, stopping trying to process "+a.src),a.tech_.off("vttjsloaded",r)}var r;r=function(){return a.tech_.off("vttjserror",n),wn(i,a)},a.tech_.one("vttjsloaded",r),a.tech_.one("vttjserror",n)}}else wn(i,a)}))}(i.src,f(t))):t.loaded_=!0,t}p(e,l);var t=e.prototype;return t.addCue=function(e){var t=e;if(v.vttjs&&!(e instanceof v.vttjs.VTTCue)){for(var i in t=new v.vttjs.VTTCue(e.startTime,e.endTime,e.text),e)i in t||(t[i]=e[i]);t.id=e.id,t.originalCue_=e}for(var n=this.tech_.textTracks(),r=0;r<n.length;r++)n[r]!==this&&n[r].removeCue(t);this.cues_.push(t),this.cues.setCues_(this.cues_)},t.removeCue=function(e){for(var t=this.cues_.length;t--;){var i=this.cues_[t];if(i===e||i.originalCue_&&i.originalCue_===e){this.cues_.splice(t,1),this.cues.setCues_(this.cues_);break}}},e}(Qt);Cn.prototype.allowedEvents_={cuechange:"cuechange"};var En=function(r){function e(e){var t;void 0===e&&(e={});var i=je(e,{kind:Xt[e.kind]||""});t=r.call(this,i)||this;var n=!1;return Object.defineProperty(f(t),"enabled",{get:function(){return n},set:function(e){"boolean"==typeof e&&e!==n&&(n=e,this.trigger("enabledchange"))}}),i.enabled&&(t.enabled=i.enabled),t.loaded_=!0,t}return p(e,r),e}(Qt),An=function(r){function e(e){var t;void 0===e&&(e={});var i=je(e,{kind:$t[e.kind]||""});t=r.call(this,i)||this;var n=!1;return Object.defineProperty(f(t),"selected",{get:function(){return n},set:function(e){"boolean"==typeof e&&e!==n&&(n=e,this.trigger("selectedchange"))}}),i.selected&&(t.selected=i.selected),t}return p(e,r),e}(Qt),Pn=function(r){function e(e){var t,i;void 0===e&&(e={}),t=r.call(this)||this;var n=new Cn(e);return t.kind=n.kind,t.src=n.src,t.srclang=n.language,t.label=n.label,t.default=n.default,Object.defineProperties(f(t),{readyState:{get:function(){return i}},track:{get:function(){return n}}}),i=0,n.addEventListener("loadeddata",function(){i=2,t.trigger({type:"load",target:f(t)})}),t}return p(e,r),e}(Ce);Pn.prototype.allowedEvents_={load:"load"},Pn.NONE=0,Pn.LOADING=1,Pn.LOADED=2,Pn.ERROR=3;var Ln={audio:{ListClass:Ht,TrackClass:En,capitalName:"Audio"},video:{ListClass:qt,TrackClass:An,capitalName:"Video"},text:{ListClass:zt,TrackClass:Cn,capitalName:"Text"}};Object.keys(Ln).forEach(function(e){Ln[e].getterName=e+"Tracks",Ln[e].privateName=e+"Tracks_"});var In={remoteText:{ListClass:zt,TrackClass:Cn,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:Wt,TrackClass:Pn,capitalName:"RemoteTextTrackEls",getterName:"remoteTextTrackEls",privateName:"remoteTextTrackEls_"}},On=je(Ln,In);In.names=Object.keys(In),Ln.names=Object.keys(Ln),On.names=[].concat(In.names).concat(Ln.names);var xn=Object.create||function(e){if(1!==arguments.length)throw new Error("Object.create shim only accepts one parameter.");return Un.prototype=e,new Un};function Un(){}function Dn(e,t){this.name="ParsingError",this.code=e.code,this.message=t||e.message}function Rn(e){function t(e,t,i,n){return 3600*(0|e)+60*(0|t)+(0|i)+(0|n)/1e3}var i=e.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);return i?i[3]?t(i[1],i[2],i[3].replace(":",""),i[4]):59<i[1]?t(i[1],i[2],0,i[4]):t(0,i[1],i[2],i[4]):null}function Mn(){this.values=xn(null)}function Bn(e,t,i,n){var r=n?e.split(n):[e];for(var a in r)if("string"==typeof r[a]){var s=r[a].split(i);if(2===s.length)t(s[0],s[1])}}function Nn(t,e,a){var i,n,s,r=t;function o(){var e=Rn(t);if(null===e)throw new Dn(Dn.Errors.BadTimeStamp,"Malformed timestamp: "+r);return t=t.replace(/^[^\sa-zA-Z-]+/,""),e}function u(){t=t.replace(/^\s+/,"")}if(u(),e.startTime=o(),u(),"--\x3e"!==t.substr(0,3))throw new Dn(Dn.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+r);t=t.substr(3),u(),e.endTime=o(),u(),i=t,n=e,s=new Mn,Bn(i,function(e,t){switch(e){case"region":for(var i=a.length-1;0<=i;i--)if(a[i].id===t){s.set(e,a[i].region);break}break;case"vertical":s.alt(e,t,["rl","lr"]);break;case"line":var n=t.split(","),r=n[0];s.integer(e,r),s.percent(e,r)&&s.set("snapToLines",!1),s.alt(e,r,["auto"]),2===n.length&&s.alt("lineAlign",n[1],["start","middle","end"]);break;case"position":n=t.split(","),s.percent(e,n[0]),2===n.length&&s.alt("positionAlign",n[1],["start","middle","end"]);break;case"size":s.percent(e,t);break;case"align":s.alt(e,t,["start","middle","end","left","right"])}},/:/,/\s/),n.region=s.get("region",null),n.vertical=s.get("vertical",""),n.line=s.get("line","auto"),n.lineAlign=s.get("lineAlign","start"),n.snapToLines=s.get("snapToLines",!0),n.size=s.get("size",100),n.align=s.get("align","middle"),n.position=s.get("position",{start:0,left:0,middle:50,end:100,right:100},n.align),n.positionAlign=s.get("positionAlign",{start:"start",left:"start",middle:"middle",end:"end",right:"end"},n.align)}((Dn.prototype=xn(Error.prototype)).constructor=Dn).Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},Mn.prototype={set:function(e,t){this.get(e)||""===t||(this.values[e]=t)},get:function(e,t,i){return i?this.has(e)?this.values[e]:t[i]:this.has(e)?this.values[e]:t},has:function(e){return e in this.values},alt:function(e,t,i){for(var n=0;n<i.length;++n)if(t===i[n]){this.set(e,t);break}},integer:function(e,t){/^-?\d+$/.test(t)&&this.set(e,parseInt(t,10))},percent:function(e,t){return!!(t.match(/^([\d]{1,3})(\.[\d]*)?%$/)&&0<=(t=parseFloat(t))&&t<=100)&&(this.set(e,t),!0)}};var jn={"&amp;":"&","&lt;":"<","&gt;":">","&lrm;":"‎","&rlm;":"‏","&nbsp;":" "},Fn={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},Vn={v:"title",lang:"lang"},Hn={rt:"ruby"};function qn(a,i){function e(){if(!i)return null;var e,t=i.match(/^([^<]*)(<[^>]*>?)?/);return e=t[1]?t[1]:t[2],i=i.substr(e.length),e}function t(e){return jn[e]}function n(e){for(;f=e.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)e=e.replace(f[0],t);return e}function r(e,t){var i=Fn[e];if(!i)return null;var n=a.document.createElement(i);n.localName=i;var r=Vn[e];return r&&t&&(n[r]=t.trim()),n}for(var s,o,u,l=a.document.createElement("div"),c=l,h=[];null!==(s=e());)if("<"!==s[0])c.appendChild(a.document.createTextNode(n(s)));else{if("/"===s[1]){h.length&&h[h.length-1]===s.substr(2).replace(">","")&&(h.pop(),c=c.parentNode);continue}var d,p=Rn(s.substr(1,s.length-2));if(p){d=a.document.createProcessingInstruction("timestamp",p),c.appendChild(d);continue}var f=s.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!f)continue;if(!(d=r(f[1],f[3])))continue;if(o=c,Hn[(u=d).localName]&&Hn[u.localName]!==o.localName)continue;f[2]&&(d.className=f[2].substr(1).replace("."," ")),h.push(f[1]),c.appendChild(d),c=d}return l}var zn=[[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]];function Wn(e){for(var t=0;t<zn.length;t++){var i=zn[t];if(e>=i[0]&&e<=i[1])return!0}return!1}function Gn(){}function $n(e,t,i){Gn.call(this),this.cue=t,this.cueDiv=qn(e,t.text);var n={color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 0.8)",position:"relative",left:0,right:0,top:0,bottom:0,display:"inline",writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext"};this.applyStyles(n,this.cueDiv),this.div=e.document.createElement("div"),n={direction:function(e){var t=[],i="";if(!e||!e.childNodes)return"ltr";function r(e,t){for(var i=t.childNodes.length-1;0<=i;i--)e.push(t.childNodes[i])}function a(e){if(!e||!e.length)return null;var t=e.pop(),i=t.textContent||t.innerText;if(i){var n=i.match(/^.*(\n|\r)/);return n?n[e.length=0]:i}return"ruby"===t.tagName?a(e):t.childNodes?(r(e,t),a(e)):void 0}for(r(t,e);i=a(t);)for(var n=0;n<i.length;n++)if(Wn(i.charCodeAt(n)))return"rtl";return"ltr"}(this.cueDiv),writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext",textAlign:"middle"===t.align?"center":t.align,font:i.font,whiteSpace:"pre-line",position:"absolute"},this.applyStyles(n),this.div.appendChild(this.cueDiv);var r=0;switch(t.positionAlign){case"start":r=t.position;break;case"middle":r=t.position-t.size/2;break;case"end":r=t.position-t.size}""===t.vertical?this.applyStyles({left:this.formatStyle(r,"%"),width:this.formatStyle(t.size,"%")}):this.applyStyles({top:this.formatStyle(r,"%"),height:this.formatStyle(t.size,"%")}),this.move=function(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")})}}function Xn(e){var t,i,n,r;if(e.div){i=e.div.offsetHeight,n=e.div.offsetWidth,r=e.div.offsetTop;var a=(a=e.div.childNodes)&&(a=a[0])&&a.getClientRects&&a.getClientRects();e=e.div.getBoundingClientRect(),t=a?Math.max(a[0]&&a[0].height||0,e.height/a.length):0}this.left=e.left,this.right=e.right,this.top=e.top||r,this.height=e.height||i,this.bottom=e.bottom||r+(e.height||i),this.width=e.width||n,this.lineHeight=void 0!==t?t:e.lineHeight}function Kn(e,t,o,u){var i=new Xn(t),n=t.cue,r=function(e){if("number"==typeof e.line&&(e.snapToLines||0<=e.line&&e.line<=100))return e.line;if(!e.track||!e.track.textTrackList||!e.track.textTrackList.mediaElement)return-1;for(var t=e.track,i=t.textTrackList,n=0,r=0;r<i.length&&i[r]!==t;r++)"showing"===i[r].mode&&n++;return-1*++n}(n),a=[];if(n.snapToLines){var s;switch(n.vertical){case"":a=["+y","-y"],s="height";break;case"rl":a=["+x","-x"],s="width";break;case"lr":a=["-x","+x"],s="width"}var l=i.lineHeight,c=l*Math.round(r),h=o[s]+l,d=a[0];Math.abs(c)>h&&(c=c<0?-1:1,c*=Math.ceil(h/l)*l),r<0&&(c+=""===n.vertical?o.height:o.width,a=a.reverse()),i.move(d,c)}else{var p=i.lineHeight/o.height*100;switch(n.lineAlign){case"middle":r-=p/2;break;case"end":r-=p}switch(n.vertical){case"":t.applyStyles({top:t.formatStyle(r,"%")});break;case"rl":t.applyStyles({left:t.formatStyle(r,"%")});break;case"lr":t.applyStyles({right:t.formatStyle(r,"%")})}a=["+y","-x","+x","-y"],i=new Xn(t)}var f=function(e,t){for(var i,n=new Xn(e),r=1,a=0;a<t.length;a++){for(;e.overlapsOppositeAxis(o,t[a])||e.within(o)&&e.overlapsAny(u);)e.move(t[a]);if(e.within(o))return e;var s=e.intersectPercentage(o);s<r&&(i=new Xn(e),r=s),e=new Xn(n)}return i||n}(i,a);t.move(f.toCSSCompatValues(o))}function Yn(){}Gn.prototype.applyStyles=function(e,t){for(var i in t=t||this.div,e)e.hasOwnProperty(i)&&(t.style[i]=e[i])},Gn.prototype.formatStyle=function(e,t){return 0===e?0:e+t},($n.prototype=xn(Gn.prototype)).constructor=$n,Xn.prototype.move=function(e,t){switch(t=void 0!==t?t:this.lineHeight,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}},Xn.prototype.overlaps=function(e){return this.left<e.right&&this.right>e.left&&this.top<e.bottom&&this.bottom>e.top},Xn.prototype.overlapsAny=function(e){for(var t=0;t<e.length;t++)if(this.overlaps(e[t]))return!0;return!1},Xn.prototype.within=function(e){return this.top>=e.top&&this.bottom<=e.bottom&&this.left>=e.left&&this.right<=e.right},Xn.prototype.overlapsOppositeAxis=function(e,t){switch(t){case"+x":return this.left<e.left;case"-x":return this.right>e.right;case"+y":return this.top<e.top;case"-y":return this.bottom>e.bottom}},Xn.prototype.intersectPercentage=function(e){return Math.max(0,Math.min(this.right,e.right)-Math.max(this.left,e.left))*Math.max(0,Math.min(this.bottom,e.bottom)-Math.max(this.top,e.top))/(this.height*this.width)},Xn.prototype.toCSSCompatValues=function(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}},Xn.getSimpleBoxPosition=function(e){var t=e.div?e.div.offsetHeight:e.tagName?e.offsetHeight:0,i=e.div?e.div.offsetWidth:e.tagName?e.offsetWidth:0,n=e.div?e.div.offsetTop:e.tagName?e.offsetTop:0;return{left:(e=e.div?e.div.getBoundingClientRect():e.tagName?e.getBoundingClientRect():e).left,right:e.right,top:e.top||n,height:e.height||t,bottom:e.bottom||n+(e.height||t),width:e.width||i}},Yn.StringDecoder=function(){return{decode:function(e){if(!e)return"";if("string"!=typeof e)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(e))}}},Yn.convertCueToDOMTree=function(e,t){return e&&t?qn(e,t):null};Yn.processCues=function(n,r,e){if(!n||!r||!e)return null;for(;e.firstChild;)e.removeChild(e.firstChild);var a=n.document.createElement("div");if(a.style.position="absolute",a.style.left="0",a.style.right="0",a.style.top="0",a.style.bottom="0",a.style.margin="1.5%",e.appendChild(a),function(e){for(var t=0;t<e.length;t++)if(e[t].hasBeenReset||!e[t].displayState)return!0;return!1}(r)){var s=[],o=Xn.getSimpleBoxPosition(a),u={font:Math.round(.05*o.height*100)/100+"px sans-serif"};!function(){for(var e,t,i=0;i<r.length;i++)t=r[i],e=new $n(n,t,u),a.appendChild(e.div),Kn(0,e,o,s),t.displayState=e.div,s.push(Xn.getSimpleBoxPosition(e))}()}else for(var t=0;t<r.length;t++)a.appendChild(r[t].displayState)},(Yn.Parser=function(e,t,i){i||(i=t,t={}),t=t||{},this.window=e,this.vttjs=t,this.state="INITIAL",this.buffer="",this.decoder=i||new TextDecoder("utf8"),this.regionList=[]}).prototype={reportOrThrowError:function(e){if(!(e instanceof Dn))throw e;this.onparsingerror&&this.onparsingerror(e)},parse:function(e){var n=this;function t(){for(var e=n.buffer,t=0;t<e.length&&"\r"!==e[t]&&"\n"!==e[t];)++t;var i=e.substr(0,t);return"\r"===e[t]&&++t,"\n"===e[t]&&++t,n.buffer=e.substr(t),i}function i(e){e.match(/X-TIMESTAMP-MAP/)?Bn(e,function(e,t){switch(e){case"X-TIMESTAMP-MAP":!function(e){var i=new Mn;Bn(e,function(e,t){switch(e){case"MPEGT":i.integer(e+"S",t);break;case"LOCA":i.set(e+"L",Rn(t))}},/[^\d]:/,/,/),n.ontimestampmap&&n.ontimestampmap({MPEGTS:i.get("MPEGTS"),LOCAL:i.get("LOCAL")})}(t)}},/=/):Bn(e,function(e,t){switch(e){case"Region":!function(e){var r=new Mn;if(Bn(e,function(e,t){switch(e){case"id":r.set(e,t);break;case"width":r.percent(e,t);break;case"lines":r.integer(e,t);break;case"regionanchor":case"viewportanchor":var i=t.split(",");if(2!==i.length)break;var n=new Mn;if(n.percent("x",i[0]),n.percent("y",i[1]),!n.has("x")||!n.has("y"))break;r.set(e+"X",n.get("x")),r.set(e+"Y",n.get("y"));break;case"scroll":r.alt(e,t,["up"])}},/=/,/\s/),r.has("id")){var t=new(n.vttjs.VTTRegion||n.window.VTTRegion);t.width=r.get("width",100),t.lines=r.get("lines",3),t.regionAnchorX=r.get("regionanchorX",0),t.regionAnchorY=r.get("regionanchorY",100),t.viewportAnchorX=r.get("viewportanchorX",0),t.viewportAnchorY=r.get("viewportanchorY",100),t.scroll=r.get("scroll",""),n.onregion&&n.onregion(t),n.regionList.push({id:r.get("id"),region:t})}}(t)}},/:/)}e&&(n.buffer+=n.decoder.decode(e,{stream:!0}));try{var r;if("INITIAL"===n.state){if(!/\r\n|\n/.test(n.buffer))return this;var a=(r=t()).match(/^WEBVTT([ \t].*)?$/);if(!a||!a[0])throw new Dn(Dn.Errors.BadSignature);n.state="HEADER"}for(var s=!1;n.buffer;){if(!/\r\n|\n/.test(n.buffer))return this;switch(s?s=!1:r=t(),n.state){case"HEADER":/:/.test(r)?i(r):r||(n.state="ID");continue;case"NOTE":r||(n.state="ID");continue;case"ID":if(/^NOTE($|[ \t])/.test(r)){n.state="NOTE";break}if(!r)continue;if(n.cue=new(n.vttjs.VTTCue||n.window.VTTCue)(0,0,""),n.state="CUE",-1===r.indexOf("--\x3e")){n.cue.id=r;continue}case"CUE":try{Nn(r,n.cue,n.regionList)}catch(e){n.reportOrThrowError(e),n.cue=null,n.state="BADCUE";continue}n.state="CUETEXT";continue;case"CUETEXT":var o=-1!==r.indexOf("--\x3e");if(!r||o&&(s=!0)){n.oncue&&n.oncue(n.cue),n.cue=null,n.state="ID";continue}n.cue.text&&(n.cue.text+="\n"),n.cue.text+=r;continue;case"BADCUE":r||(n.state="ID");continue}}}catch(e){n.reportOrThrowError(e),"CUETEXT"===n.state&&n.cue&&n.oncue&&n.oncue(n.cue),n.cue=null,n.state="INITIAL"===n.state?"BADWEBVTT":"BADCUE"}return this},flush:function(){var t=this;try{if(t.buffer+=t.decoder.decode(),!t.cue&&"HEADER"!==t.state||(t.buffer+="\n\n",t.parse()),"INITIAL"===t.state)throw new Dn(Dn.Errors.BadSignature)}catch(e){t.reportOrThrowError(e)}return t.onflush&&t.onflush(),this}};var Qn=Yn,Jn={"":1,lr:1,rl:1},Zn={start:1,middle:1,end:1,left:1,right:1};function er(e){return"string"==typeof e&&(!!Zn[e.toLowerCase()]&&e.toLowerCase())}function tr(e,t,i){this.hasBeenReset=!1;var n="",r=!1,a=e,s=t,o=i,u=null,l="",c=!0,h="auto",d="start",p=50,f="middle",m=50,g="middle";Object.defineProperties(this,{id:{enumerable:!0,get:function(){return n},set:function(e){n=""+e}},pauseOnExit:{enumerable:!0,get:function(){return r},set:function(e){r=!!e}},startTime:{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e)throw new TypeError("Start time must be set to a number.");a=e,this.hasBeenReset=!0}},endTime:{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e)throw new TypeError("End time must be set to a number.");s=e,this.hasBeenReset=!0}},text:{enumerable:!0,get:function(){return o},set:function(e){o=""+e,this.hasBeenReset=!0}},region:{enumerable:!0,get:function(){return u},set:function(e){u=e,this.hasBeenReset=!0}},vertical:{enumerable:!0,get:function(){return l},set:function(e){var t=function(e){return"string"==typeof e&&(!!Jn[e.toLowerCase()]&&e.toLowerCase())}(e);if(!1===t)throw new SyntaxError("An invalid or illegal string was specified.");l=t,this.hasBeenReset=!0}},snapToLines:{enumerable:!0,get:function(){return c},set:function(e){c=!!e,this.hasBeenReset=!0}},line:{enumerable:!0,get:function(){return h},set:function(e){if("number"!=typeof e&&"auto"!==e)throw new SyntaxError("An invalid number or illegal string was specified.");h=e,this.hasBeenReset=!0}},lineAlign:{enumerable:!0,get:function(){return d},set:function(e){var t=er(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");d=t,this.hasBeenReset=!0}},position:{enumerable:!0,get:function(){return p},set:function(e){if(e<0||100<e)throw new Error("Position must be between 0 and 100.");p=e,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return f},set:function(e){var t=er(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");f=t,this.hasBeenReset=!0}},size:{enumerable:!0,get:function(){return m},set:function(e){if(e<0||100<e)throw new Error("Size must be between 0 and 100.");m=e,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return g},set:function(e){var t=er(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");g=t,this.hasBeenReset=!0}}}),this.displayState=void 0}tr.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var ir=tr,nr={"":!0,up:!0};function rr(e){return"number"==typeof e&&0<=e&&e<=100}function ar(){var t=100,i=3,n=0,r=100,a=0,s=100,o="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return t},set:function(e){if(!rr(e))throw new Error("Width must be between 0 and 100.");t=e}},lines:{enumerable:!0,get:function(){return i},set:function(e){if("number"!=typeof e)throw new TypeError("Lines must be set to a number.");i=e}},regionAnchorY:{enumerable:!0,get:function(){return r},set:function(e){if(!rr(e))throw new Error("RegionAnchorX must be between 0 and 100.");r=e}},regionAnchorX:{enumerable:!0,get:function(){return n},set:function(e){if(!rr(e))throw new Error("RegionAnchorY must be between 0 and 100.");n=e}},viewportAnchorY:{enumerable:!0,get:function(){return s},set:function(e){if(!rr(e))throw new Error("ViewportAnchorY must be between 0 and 100.");s=e}},viewportAnchorX:{enumerable:!0,get:function(){return a},set:function(e){if(!rr(e))throw new Error("ViewportAnchorX must be between 0 and 100.");a=e}},scroll:{enumerable:!0,get:function(){return o},set:function(e){var t=function(e){return"string"==typeof e&&(!!nr[e.toLowerCase()]&&e.toLowerCase())}(e);if(!1===t)throw new SyntaxError("An invalid or illegal string was specified.");o=t}}})}var sr=It(function(e){var t=e.exports={WebVTT:Qn,VTTCue:ir,VTTRegion:ar};v.vttjs=t,v.WebVTT=t.WebVTT;var i=t.VTTCue,n=t.VTTRegion,r=v.VTTCue,a=v.VTTRegion;t.shim=function(){v.VTTCue=i,v.VTTRegion=n},t.restore=function(){v.VTTCue=r,v.VTTRegion=a},v.VTTCue||t.shim()});sr.WebVTT,sr.VTTCue,sr.VTTRegion;var or=function(t){function i(i,e){var n;return void 0===i&&(i={}),void 0===e&&(e=function(){}),i.reportTouchActivity=!1,(n=t.call(this,null,i,e)||this).hasStarted_=!1,n.on("playing",function(){this.hasStarted_=!0}),n.on("loadstart",function(){this.hasStarted_=!1}),On.names.forEach(function(e){var t=On[e];i&&i[t.getterName]&&(n[t.privateName]=i[t.getterName])}),n.featuresProgressEvents||n.manualProgressOn(),n.featuresTimeupdateEvents||n.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach(function(e){!1===i["native"+e+"Tracks"]&&(n["featuresNative"+e+"Tracks"]=!1)}),!1===i.nativeCaptions||!1===i.nativeTextTracks?n.featuresNativeTextTracks=!1:!0!==i.nativeCaptions&&!0!==i.nativeTextTracks||(n.featuresNativeTextTracks=!0),n.featuresNativeTextTracks||n.emulateTextTracks(),n.autoRemoteTextTracks_=new On.text.ListClass,n.initTrackListeners(),i.nativeControlsForTouch||n.emitTapEvents(),n.constructor&&(n.name_=n.constructor.name||"Unknown Tech"),n}p(i,t);var e=i.prototype;return e.triggerSourceset=function(e){var t=this;this.isReady_||this.one("ready",function(){return t.setTimeout(function(){return t.triggerSourceset(e)},1)}),this.trigger({src:e,type:"sourceset"})},e.manualProgressOn=function(){this.on("durationchange",this.onDurationChange),this.manualProgress=!0,this.one("ready",this.trackProgress)},e.manualProgressOff=function(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange)},e.trackProgress=function(e){this.stopTrackingProgress(),this.progressInterval=this.setInterval(ke(this,function(){var e=this.bufferedPercent();this.bufferedPercent_!==e&&this.trigger("progress"),1===(this.bufferedPercent_=e)&&this.stopTrackingProgress()}),500)},e.onDurationChange=function(e){this.duration_=this.duration()},e.buffered=function(){return ft(0,0)},e.bufferedPercent=function(){return mt(this.buffered(),this.duration_)},e.stopTrackingProgress=function(){this.clearInterval(this.progressInterval)},e.manualTimeUpdatesOn=function(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime),this.on("pause",this.stopTrackingCurrentTime)},e.manualTimeUpdatesOff=function(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime),this.off("pause",this.stopTrackingCurrentTime)},e.trackCurrentTime=function(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval(function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},250)},e.stopTrackingCurrentTime=function(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.dispose=function(){this.clearTracks(Ln.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),t.prototype.dispose.call(this)},e.clearTracks=function(e){var r=this;(e=[].concat(e)).forEach(function(e){for(var t=r[e+"Tracks"]()||[],i=t.length;i--;){var n=t[i];"text"===e&&r.removeRemoteTextTrack(n),t.removeTrack(n)}})},e.cleanupAutoTextTracks=function(){for(var e=this.autoRemoteTextTracks_||[],t=e.length;t--;){var i=e[t];this.removeRemoteTextTrack(i)}},e.reset=function(){},e.error=function(e){return void 0!==e&&(this.error_=new St(e),this.trigger("error")),this.error_},e.played=function(){return this.hasStarted_?ft(0,0):ft()},e.setCurrentTime=function(){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.initTrackListeners=function(){var r=this;Ln.names.forEach(function(e){function t(){r.trigger(e+"trackchange")}var i=Ln[e],n=r[i.getterName]();n.addEventListener("removetrack",t),n.addEventListener("addtrack",t),r.on("dispose",function(){n.removeEventListener("removetrack",t),n.removeEventListener("addtrack",t)})})},e.addWebVttScript_=function(){var e=this;if(!v.WebVTT)if(h.body.contains(this.el())){if(!this.options_["vtt.js"]&&l(sr)&&0<Object.keys(sr).length)return void this.trigger("vttjsloaded");var t=h.createElement("script");t.src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",t.onload=function(){e.trigger("vttjsloaded")},t.onerror=function(){e.trigger("vttjserror")},this.on("dispose",function(){t.onload=null,t.onerror=null}),v.WebVTT=!0,this.el().parentNode.appendChild(t)}else this.ready(this.addWebVttScript_)},e.emulateTextTracks=function(){function t(e){return n.addTrack(e.track)}function i(e){return n.removeTrack(e.track)}var e=this,n=this.textTracks(),r=this.remoteTextTracks();r.on("addtrack",t),r.on("removetrack",i),this.addWebVttScript_();function a(){return e.trigger("texttrackchange")}function s(){a();for(var e=0;e<n.length;e++){var t=n[e];t.removeEventListener("cuechange",a),"showing"===t.mode&&t.addEventListener("cuechange",a)}}s(),n.addEventListener("change",s),n.addEventListener("addtrack",s),n.addEventListener("removetrack",s),this.on("dispose",function(){r.off("addtrack",t),r.off("removetrack",i),n.removeEventListener("change",s),n.removeEventListener("addtrack",s),n.removeEventListener("removetrack",s);for(var e=0;e<n.length;e++){n[e].removeEventListener("cuechange",a)}})},e.addTextTrack=function(e,t,i){if(!e)throw new Error("TextTrack kind is required but was not provided");return function(e,t,i,n,r){void 0===r&&(r={});var a=e.textTracks();r.kind=t,i&&(r.label=i),n&&(r.language=n),r.tech=e;var s=new On.text.TrackClass(r);return a.addTrack(s),s}(this,e,t,i)},e.createRemoteTextTrack=function(e){var t=je(e,{tech:this});return new In.remoteTextEl.TrackClass(t)},e.addRemoteTextTrack=function(e,t){var i=this;void 0===e&&(e={});var n=this.createRemoteTextTrack(e);return!0!==t&&!1!==t&&(m.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'),t=!0),this.remoteTextTrackEls().addTrackElement_(n),this.remoteTextTracks().addTrack(n.track),!0!==t&&this.ready(function(){return i.autoRemoteTextTracks_.addTrack(n.track)}),n},e.removeRemoteTextTrack=function(e){var t=this.remoteTextTrackEls().getTrackElementByTrack_(e);this.remoteTextTrackEls().removeTrackElement_(t),this.remoteTextTracks().removeTrack(e),this.autoRemoteTextTracks_.removeTrack(e)},e.getVideoPlaybackQuality=function(){return{}},e.requestPictureInPicture=function(){var e=this.options_.Promise||v.Promise;if(e)return e.reject()},e.setPoster=function(){},e.playsinline=function(){},e.setPlaysinline=function(){},e.overrideNativeAudioTracks=function(){},e.overrideNativeVideoTracks=function(){},e.canPlayType=function(){return""},i.canPlayType=function(){return""},i.canPlaySource=function(e,t){return i.canPlayType(e.type)},i.isTech=function(e){return e.prototype instanceof i||e instanceof i||e===i},i.registerTech=function(e,t){if(i.techs_||(i.techs_={}),!i.isTech(t))throw new Error("Tech "+e+" must be a Tech");if(!i.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!i.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return e=Ne(e),i.techs_[e]=t,"Tech"!==e&&i.defaultTechOrder_.push(e),t},i.getTech=function(e){if(e)return e=Ne(e),i.techs_&&i.techs_[e]?i.techs_[e]:v&&v.videojs&&v.videojs[e]?(m.warn("The "+e+" tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)"),v.videojs[e]):void 0},i}(Fe);On.names.forEach(function(e){var t=On[e];or.prototype[t.getterName]=function(){return this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName]}}),or.prototype.featuresVolumeControl=!0,or.prototype.featuresMuteControl=!0,or.prototype.featuresFullscreenResize=!1,or.prototype.featuresPlaybackRate=!1,or.prototype.featuresProgressEvents=!1,or.prototype.featuresSourceset=!1,or.prototype.featuresTimeupdateEvents=!1,or.prototype.featuresNativeTextTracks=!1,or.withSourceHandlers=function(r){r.registerSourceHandler=function(e,t){var i=r.sourceHandlers;i=i||(r.sourceHandlers=[]),void 0===t&&(t=i.length),i.splice(t,0,e)},r.canPlayType=function(e){for(var t,i=r.sourceHandlers||[],n=0;n<i.length;n++)if(t=i[n].canPlayType(e))return t;return""},r.selectSourceHandler=function(e,t){for(var i=r.sourceHandlers||[],n=0;n<i.length;n++)if(i[n].canHandleSource(e,t))return i[n];return null},r.canPlaySource=function(e,t){var i=r.selectSourceHandler(e,t);return i?i.canHandleSource(e,t):""};["seekable","seeking","duration"].forEach(function(e){var t=this[e];"function"==typeof t&&(this[e]=function(){return this.sourceHandler_&&this.sourceHandler_[e]?this.sourceHandler_[e].apply(this.sourceHandler_,arguments):t.apply(this,arguments)})},r.prototype),r.prototype.setSource=function(e){var t=r.selectSourceHandler(e,this.options_);t||(r.nativeSourceHandler?t=r.nativeSourceHandler:m.error("No source handler found for the current source.")),this.disposeSourceHandler(),this.off("dispose",this.disposeSourceHandler),t!==r.nativeSourceHandler&&(this.currentSource_=e),this.sourceHandler_=t.handleSource(e,this,this.options_),this.one("dispose",this.disposeSourceHandler)},r.prototype.disposeSourceHandler=function(){this.currentSource_&&(this.clearTracks(["audio","video"]),this.currentSource_=null),this.cleanupAutoTextTracks(),this.sourceHandler_&&(this.sourceHandler_.dispose&&this.sourceHandler_.dispose(),this.sourceHandler_=null)}},Fe.registerComponent("Tech",or),or.registerTech("Tech",or),or.defaultTechOrder_=[];var ur={},lr={},cr={};function hr(e,t,i){e.setTimeout(function(){return function i(n,e,r,a,s,o){void 0===n&&(n={});void 0===e&&(e=[]);void 0===s&&(s=[]);void 0===o&&(o=!1);var t=e,u=t[0],l=t.slice(1);if("string"==typeof u)i(n,ur[u],r,a,s,o);else if(u){var c=yr(a,u);if(!c.setSource)return s.push(c),i(n,l,r,a,s,o);c.setSource(_({},n),function(e,t){if(e)return i(n,l,r,a,s,o);s.push(c),i(t,n.type===t.type?l:ur[t.type],r,a,s,o)})}else l.length?i(n,l,r,a,s,o):o?r(n,s):i(n,ur["*"],r,a,s,!0)}(t,ur[t.type],i,e)},1)}function dr(e,t,i,n){void 0===n&&(n=null);var r="call"+Ne(i),a=e.reduce(gr(r),n),s=a===cr,o=s?null:t[i](a);return function(e,t,i,n){for(var r=e.length-1;0<=r;r--){var a=e[r];a[t]&&a[t](n,i)}}(e,i,o,s),o}var pr={buffered:1,currentTime:1,duration:1,seekable:1,played:1,paused:1,volume:1},fr={setCurrentTime:1,setVolume:1},mr={play:1,pause:1};function gr(i){return function(e,t){return e===cr?cr:t[i]?t[i](e):e}}function yr(e,t){var i=lr[e.id()],n=null;if(null==i)return n=t(e),lr[e.id()]=[[t,n]],n;for(var r=0;r<i.length;r++){var a=i[r],s=a[0],o=a[1];s===t&&(n=o)}return null===n&&(n=t(e),i.push([t,n])),n}function vr(e){void 0===e&&(e="");var t=Ft(e);return _r[t.toLowerCase()]||""}var _r={opus:"video/ogg",ogv:"video/ogg",mp4:"video/mp4",mov:"video/mp4",m4v:"video/mp4",mkv:"video/x-matroska",m4a:"audio/mp4",mp3:"audio/mpeg",aac:"audio/aac",oga:"audio/ogg",m3u8:"application/x-mpegURL",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"};function br(e){var t=vr(e.src);return!e.type&&t&&(e.type=t),e}var Tr=function(l){function e(e,t,i){var n,r=je({createEl:!1},t);if(n=l.call(this,e,r,i)||this,t.playerOptions.sources&&0!==t.playerOptions.sources.length)e.src(t.playerOptions.sources);else for(var a=0,s=t.playerOptions.techOrder;a<s.length;a++){var o=Ne(s[a]),u=or.getTech(o);if(o||(u=Fe.getComponent(o)),u&&u.isSupported()){e.loadTech_(o);break}}return n}return p(e,l),e}(Fe);Fe.registerComponent("MediaLoader",Tr);var Sr=function(r){function e(e,t){var i;return(i=r.call(this,e,t)||this).emitTapEvents(),i.enable(),i}p(e,r);var t=e.prototype;return t.createEl=function(e,t,i){void 0===e&&(e="div"),void 0===t&&(t={}),void 0===i&&(i={}),t=_({innerHTML:'<span aria-hidden="true" class="vjs-icon-placeholder"></span>',className:this.buildCSSClass(),tabIndex:0},t),"button"===e&&m.error("Creating a ClickableComponent with an HTML element of "+e+" is not supported; use a Button instead."),i=_({role:"button"},i),this.tabIndex_=t.tabIndex;var n=r.prototype.createEl.call(this,e,t,i);return this.createControlTextEl(n),n},t.dispose=function(){this.controlTextEl_=null,r.prototype.dispose.call(this)},t.createControlTextEl=function(e){return this.controlTextEl_=A("span",{className:"vjs-control-text"},{"aria-live":"polite"}),e&&e.appendChild(this.controlTextEl_),this.controlText(this.controlText_,e),this.controlTextEl_},t.controlText=function(e,t){if(void 0===t&&(t=this.el()),void 0===e)return this.controlText_||"Need Text";var i=this.localize(e);this.controlText_=e,P(this.controlTextEl_,i),this.nonIconControl||t.setAttribute("title",i)},t.buildCSSClass=function(){return"vjs-control vjs-button "+r.prototype.buildCSSClass.call(this)},t.enable=function(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),"undefined"!=typeof this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick),this.on("keydown",this.handleKeyDown))},t.disable=function(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),"undefined"!=typeof this.tabIndex_&&this.el_.removeAttribute("tabIndex"),this.off(["tap","click"],this.handleClick),this.off("keydown",this.handleKeyDown)},t.handleClick=function(e){},t.handleKeyDown=function(e){Ot.isEventKey(e,"Space")||Ot.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):r.prototype.handleKeyDown.call(this,e)},e}(Fe);Fe.registerComponent("ClickableComponent",Sr);var kr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update(),e.on("posterchange",ke(f(i),i.update)),i}p(e,n);var t=e.prototype;return t.dispose=function(){this.player().off("posterchange",this.update),n.prototype.dispose.call(this)},t.createEl=function(){return A("div",{className:"vjs-poster",tabIndex:-1})},t.update=function(e){var t=this.player().poster();this.setSrc(t),t?this.show():this.hide()},t.setSrc=function(e){var t="";e&&(t='url("'+e+'")'),this.el_.style.backgroundImage=t},t.handleClick=function(e){this.player_.controls()&&(this.player_.tech(!0)&&this.player_.tech(!0).focus(),this.player_.paused()?Et(this.player_.play()):this.player_.pause())},e}(Sr);Fe.registerComponent("PosterImage",kr);var wr="#222",Cr={monospace:"monospace",sansSerif:"sans-serif",serif:"serif",monospaceSansSerif:'"Andale Mono", "Lucida Console", monospace',monospaceSerif:'"Courier New", monospace',proportionalSansSerif:"sans-serif",proportionalSerif:"serif",casual:'"Comic Sans MS", Impact, fantasy',script:'"Monotype Corsiva", cursive',smallcaps:'"Andale Mono", "Lucida Console", monospace, sans-serif'};function Er(e,t){var i;if(4===e.length)i=e[1]+e[1]+e[2]+e[2]+e[3]+e[3];else{if(7!==e.length)throw new Error("Invalid color code provided, "+e+"; must be formatted as e.g. #f0e or #f604e2.");i=e.slice(1)}return"rgba("+parseInt(i.slice(0,2),16)+","+parseInt(i.slice(2,4),16)+","+parseInt(i.slice(4,6),16)+","+t+")"}function Ar(e,t,i){try{e.style[t]=i}catch(e){return}}var Pr=function(a){function e(i,e,t){var n;n=a.call(this,i,e,t)||this;var r=ke(f(n),n.updateDisplay);return i.on("loadstart",ke(f(n),n.toggleDisplay)),i.on("texttrackchange",r),i.on("loadedmetadata",ke(f(n),n.preselectTrack)),i.ready(ke(f(n),function(){if(i.tech_&&i.tech_.featuresNativeTextTracks)this.hide();else{i.on("fullscreenchange",r),i.on("playerresize",r),v.addEventListener("orientationchange",r),i.on("dispose",function(){return v.removeEventListener("orientationchange",r)});for(var e=this.options_.playerOptions.tracks||[],t=0;t<e.length;t++)this.player_.addRemoteTextTrack(e[t],!0);this.preselectTrack()}})),n}p(e,a);var t=e.prototype;return t.preselectTrack=function(){for(var e,t,i,n={captions:1,subtitles:1},r=this.player_.textTracks(),a=this.player_.cache_.selectedLanguage,s=0;s<r.length;s++){var o=r[s];a&&a.enabled&&a.language&&a.language===o.language&&o.kind in n?i=o.kind===a.kind?o:i||o:a&&!a.enabled?t=e=i=null:o.default&&("descriptions"!==o.kind||e?o.kind in n&&!t&&(t=o):e=o)}i?i.mode="showing":t?t.mode="showing":e&&(e.mode="showing")},t.toggleDisplay=function(){this.player_.tech_&&this.player_.tech_.featuresNativeTextTracks?this.hide():this.show()},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-text-track-display"},{"aria-live":"off","aria-atomic":"true"})},t.clearDisplay=function(){"function"==typeof v.WebVTT&&v.WebVTT.processCues(v,[],this.el_)},t.updateDisplay=function(){var e=this.player_.textTracks(),t=this.options_.allowMultipleShowingTracks;if(this.clearDisplay(),t){for(var i=[],n=0;n<e.length;++n){var r=e[n];"showing"===r.mode&&i.push(r)}this.updateForTrack(i)}else{for(var a=null,s=null,o=e.length;o--;){var u=e[o];"showing"===u.mode&&("descriptions"===u.kind?a=u:s=u)}s?("off"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","off"),this.updateForTrack(s)):a&&("assertive"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","assertive"),this.updateForTrack(a))}},t.updateDisplayState=function(e){for(var t=this.player_.textTrackSettings.getValues(),i=e.activeCues,n=i.length;n--;){var r=i[n];if(r){var a=r.displayState;if(t.color&&(a.firstChild.style.color=t.color),t.textOpacity&&Ar(a.firstChild,"color",Er(t.color||"#fff",t.textOpacity)),t.backgroundColor&&(a.firstChild.style.backgroundColor=t.backgroundColor),t.backgroundOpacity&&Ar(a.firstChild,"backgroundColor",Er(t.backgroundColor||"#000",t.backgroundOpacity)),t.windowColor&&(t.windowOpacity?Ar(a,"backgroundColor",Er(t.windowColor,t.windowOpacity)):a.style.backgroundColor=t.windowColor),t.edgeStyle&&("dropshadow"===t.edgeStyle?a.firstChild.style.textShadow="2px 2px 3px #222, 2px 2px 4px #222, 2px 2px 5px "+wr:"raised"===t.edgeStyle?a.firstChild.style.textShadow="1px 1px #222, 2px 2px #222, 3px 3px "+wr:"depressed"===t.edgeStyle?a.firstChild.style.textShadow="1px 1px #ccc, 0 1px #ccc, -1px -1px #222, 0 -1px "+wr:"uniform"===t.edgeStyle&&(a.firstChild.style.textShadow="0 0 4px #222, 0 0 4px #222, 0 0 4px #222, 0 0 4px "+wr)),t.fontPercent&&1!==t.fontPercent){var s=v.parseFloat(a.style.fontSize);a.style.fontSize=s*t.fontPercent+"px",a.style.height="auto",a.style.top="auto",a.style.bottom="2px"}t.fontFamily&&"default"!==t.fontFamily&&("small-caps"===t.fontFamily?a.firstChild.style.fontVariant="small-caps":a.firstChild.style.fontFamily=Cr[t.fontFamily])}}},t.updateForTrack=function(e){if(Array.isArray(e)||(e=[e]),"function"==typeof v.WebVTT&&!e.every(function(e){return!e.activeCues})){for(var t=[],i=0;i<e.length;++i)for(var n=e[i],r=0;r<n.activeCues.length;++r)t.push(n.activeCues[r]);v.WebVTT.processCues(v,t,this.el_);for(var a=0;a<e.length;++a){for(var s=e[a],o=0;o<s.activeCues.length;++o){var u=s.activeCues[o].displayState;O(u,"vjs-text-track-cue"),O(u,"vjs-text-track-cue-"+(s.language?s.language:a))}this.player_.textTrackSettings&&this.updateDisplayState(s)}}},e}(Fe);Fe.registerComponent("TextTrackDisplay",Pr);var Lr=function(r){function e(){return r.apply(this,arguments)||this}return p(e,r),e.prototype.createEl=function(){var e=this.player_.isAudio(),t=this.localize(e?"Audio Player":"Video Player"),i=A("span",{className:"vjs-control-text",innerHTML:this.localize("{1} is loading.",[t])}),n=r.prototype.createEl.call(this,"div",{className:"vjs-loading-spinner",dir:"ltr"});return n.appendChild(i),n},e}(Fe);Fe.registerComponent("LoadingSpinner",Lr);var Ir=function(t){function e(){return t.apply(this,arguments)||this}p(e,t);var i=e.prototype;return i.createEl=function(e,t,i){void 0===t&&(t={}),void 0===i&&(i={}),t=_({innerHTML:'<span aria-hidden="true" class="vjs-icon-placeholder"></span>',className:this.buildCSSClass()},t),i=_({type:"button"},i);var n=Fe.prototype.createEl.call(this,"button",t,i);return this.createControlTextEl(n),n},i.addChild=function(e,t){void 0===t&&(t={});var i=this.constructor.name;return m.warn("Adding an actionable (user controllable) child to a Button ("+i+") is not supported; use a ClickableComponent instead."),Fe.prototype.addChild.call(this,e,t)},i.enable=function(){t.prototype.enable.call(this),this.el_.removeAttribute("disabled")},i.disable=function(){t.prototype.disable.call(this),this.el_.setAttribute("disabled","disabled")},i.handleKeyDown=function(e){Ot.isEventKey(e,"Space")||Ot.isEventKey(e,"Enter")?e.stopPropagation():t.prototype.handleKeyDown.call(this,e)},e}(Sr);Fe.registerComponent("Button",Ir);var Or=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).mouseused_=!1,i.on("mousedown",i.handleMouseDown),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-big-play-button"},t.handleClick=function(e){var t=this.player_.play();if(this.mouseused_&&e.clientX&&e.clientY)return Et(t),void(this.player_.tech(!0)&&this.player_.tech(!0).focus());var i=this.player_.getChild("controlBar"),n=i&&i.getChild("playToggle");if(n){function r(){return n.focus()}Ct(t)?t.then(r,function(){}):this.setTimeout(r,1)}else this.player_.tech(!0).focus()},t.handleKeyDown=function(e){this.mouseused_=!1,n.prototype.handleKeyDown.call(this,e)},t.handleMouseDown=function(e){this.mouseused_=!0},e}(Ir);Or.prototype.controlText_="Play Video",Fe.registerComponent("BigPlayButton",Or);var xr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).controlText(t&&t.controlText||i.localize("Close")),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-close-button "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.trigger({type:"close",bubbles:!1})},t.handleKeyDown=function(e){Ot.isEventKey(e,"Esc")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):n.prototype.handleKeyDown.call(this,e)},e}(Ir);Fe.registerComponent("CloseButton",xr);var Ur=function(n){function e(e,t){var i;return void 0===t&&(t={}),i=n.call(this,e,t)||this,t.replay=void 0===t.replay||t.replay,i.on(e,"play",i.handlePlay),i.on(e,"pause",i.handlePause),t.replay&&i.on(e,"ended",i.handleEnded),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-play-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.player_.paused()?this.player_.play():this.player_.pause(),e.stopPropagation()},t.handleSeeked=function(e){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(e):this.handlePlay(e)},t.handlePlay=function(e){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")},t.handlePause=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")},t.handleEnded=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.controlText("Replay"),this.one(this.player_,"seeked",this.handleSeeked)},e}(Ir);Ur.prototype.controlText_="Play",Fe.registerComponent("PlayToggle",Ur);function Dr(e,t){e=e<0?0:e;var i=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),a=Math.floor(t/60%60),s=Math.floor(t/3600);return!isNaN(e)&&e!==1/0||(r=n=i="-"),(r=0<r||0<s?r+":":"")+(n=((r||10<=a)&&n<10?"0"+n:n)+":")+(i=i<10?"0"+i:i)}var Rr=Dr;function Mr(e,t){return void 0===t&&(t=e),Rr(e,t)}var Br=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).throttledUpdateContent=we(ke(f(i),i.updateContent),25),i.on(e,"timeupdate",i.throttledUpdateContent),i}p(e,n);var t=e.prototype;return t.createEl=function(){var e=this.buildCSSClass(),t=n.prototype.createEl.call(this,"div",{className:e+" vjs-time-control vjs-control",innerHTML:'<span class="vjs-control-text" role="presentation">'+this.localize(this.labelText_)+" </span>"});return this.contentEl_=A("span",{className:e+"-display"},{"aria-live":"off",role:"presentation"}),this.updateTextNode_(),t.appendChild(this.contentEl_),t},t.dispose=function(){this.contentEl_=null,this.textNode_=null,n.prototype.dispose.call(this)},t.updateTextNode_=function(){if(this.contentEl_){for(;this.contentEl_.firstChild;)this.contentEl_.removeChild(this.contentEl_.firstChild);this.textNode_=h.createTextNode(this.formattedTime_||this.formatTime_(0)),this.contentEl_.appendChild(this.textNode_)}},t.formatTime_=function(e){return Mr(e)},t.updateFormattedTime_=function(e){var t=this.formatTime_(e);t!==this.formattedTime_&&(this.formattedTime_=t,this.requestAnimationFrame(this.updateTextNode_))},t.updateContent=function(e){},e}(Fe);Br.prototype.labelText_="Time",Br.prototype.controlText_="Time",Fe.registerComponent("TimeDisplay",Br);var Nr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"ended",i.handleEnded),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-current-time"},t.updateContent=function(e){var t=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();this.updateFormattedTime_(t)},t.handleEnded=function(e){this.player_.duration()&&this.updateFormattedTime_(this.player_.duration())},e}(Br);Nr.prototype.labelText_="Current Time",Nr.prototype.controlText_="Current Time",Fe.registerComponent("CurrentTimeDisplay",Nr);var jr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"durationchange",i.updateContent),i.on(e,"loadstart",i.updateContent),i.on(e,"loadedmetadata",i.throttledUpdateContent),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-duration"},t.updateContent=function(e){var t=this.player_.duration();this.duration_!==t&&(this.duration_=t,this.updateFormattedTime_(t))},e}(Br);jr.prototype.labelText_="Duration",jr.prototype.controlText_="Duration",Fe.registerComponent("DurationDisplay",jr);var Fr=function(e){function t(){return e.apply(this,arguments)||this}return p(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-time-control vjs-time-divider",innerHTML:"<div><span>/</span></div>"},{"aria-hidden":!0})},t}(Fe);Fe.registerComponent("TimeDivider",Fr);var Vr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"durationchange",i.throttledUpdateContent),i.on(e,"ended",i.handleEnded),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-remaining-time"},t.createEl=function(){var e=n.prototype.createEl.call(this);return e.insertBefore(A("span",{},{"aria-hidden":!0},"-"),this.contentEl_),e},t.updateContent=function(e){"number"==typeof this.player_.duration()&&(this.player_.remainingTimeDisplay?this.updateFormattedTime_(this.player_.remainingTimeDisplay()):this.updateFormattedTime_(this.player_.remainingTime()))},t.handleEnded=function(e){this.player_.duration()&&this.updateFormattedTime_(0)},e}(Br);Vr.prototype.labelText_="Remaining Time",Vr.prototype.controlText_="Remaining Time",Fe.registerComponent("RemainingTimeDisplay",Vr);var Hr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateShowing(),i.on(i.player(),"durationchange",i.updateShowing),i}p(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-live-control vjs-control"});return this.contentEl_=A("div",{className:"vjs-live-display",innerHTML:'<span class="vjs-control-text">'+this.localize("Stream Type")+" </span>"+this.localize("LIVE")},{"aria-live":"off"}),e.appendChild(this.contentEl_),e},t.dispose=function(){this.contentEl_=null,n.prototype.dispose.call(this)},t.updateShowing=function(e){this.player().duration()===1/0?this.show():this.hide()},e}(Fe);Fe.registerComponent("LiveDisplay",Hr);var qr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateLiveEdgeStatus(),i.player_.liveTracker&&i.on(i.player_.liveTracker,"liveedgechange",i.updateLiveEdgeStatus),i}p(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"button",{className:"vjs-seek-to-live-control vjs-control"});return this.textEl_=A("span",{className:"vjs-seek-to-live-text",innerHTML:this.localize("LIVE")},{"aria-hidden":"true"}),e.appendChild(this.textEl_),e},t.updateLiveEdgeStatus=function(e){!this.player_.liveTracker||this.player_.liveTracker.atLiveEdge()?(this.setAttribute("aria-disabled",!0),this.addClass("vjs-at-live-edge"),this.controlText("Seek to live, currently playing live")):(this.setAttribute("aria-disabled",!1),this.removeClass("vjs-at-live-edge"),this.controlText("Seek to live, currently behind live"))},t.handleClick=function(){this.player_.liveTracker.seekToLiveEdge()},t.dispose=function(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatus),this.textEl_=null,n.prototype.dispose.call(this)},e}(Ir);qr.prototype.controlText_="Seek to live, currently playing live",Fe.registerComponent("SeekToLive",qr);var zr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).bar=i.getChild(i.options_.barName),i.vertical(!!i.options_.vertical),i.enable(),i}p(e,n);var t=e.prototype;return t.enabled=function(){return this.enabled_},t.enable=function(){this.enabled()||(this.on("mousedown",this.handleMouseDown),this.on("touchstart",this.handleMouseDown),this.on("keydown",this.handleKeyDown),this.on("click",this.handleClick),this.on(this.player_,"controlsvisible",this.update),this.playerEvent&&this.on(this.player_,this.playerEvent,this.update),this.removeClass("disabled"),this.setAttribute("tabindex",0),this.enabled_=!0)},t.disable=function(){if(this.enabled()){var e=this.bar.el_.ownerDocument;this.off("mousedown",this.handleMouseDown),this.off("touchstart",this.handleMouseDown),this.off("keydown",this.handleKeyDown),this.off("click",this.handleClick),this.off(this.player_,"controlsvisible",this.update),this.off(e,"mousemove",this.handleMouseMove),this.off(e,"mouseup",this.handleMouseUp),this.off(e,"touchmove",this.handleMouseMove),this.off(e,"touchend",this.handleMouseUp),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1}},t.createEl=function(e,t,i){return void 0===t&&(t={}),void 0===i&&(i={}),t.className=t.className+" vjs-slider",t=_({tabIndex:0},t),i=_({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},i),n.prototype.createEl.call(this,e,t,i)},t.handleMouseDown=function(e){var t=this.bar.el_.ownerDocument;"mousedown"===e.type&&e.preventDefault(),"touchstart"!==e.type||rt||e.preventDefault(),j(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(t,"mousemove",this.handleMouseMove),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchmove",this.handleMouseMove),this.on(t,"touchend",this.handleMouseUp),this.handleMouseMove(e)},t.handleMouseMove=function(e){},t.handleMouseUp=function(){var e=this.bar.el_.ownerDocument;F(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(e,"mousemove",this.handleMouseMove),this.off(e,"mouseup",this.handleMouseUp),this.off(e,"touchmove",this.handleMouseMove),this.off(e,"touchend",this.handleMouseUp),this.update()},t.update=function(){if(this.el_){var e=this.getPercent(),t=this.bar;if(t){("number"!=typeof e||e!=e||e<0||e===1/0)&&(e=0);var i=(100*e).toFixed(2)+"%",n=t.el().style;return this.vertical()?n.height=i:n.width=i,e}}},t.calculateDistance=function(e){var t=q(this.el_,e);return this.vertical()?t.y:t.x},t.handleKeyDown=function(e){Ot.isEventKey(e,"Left")||Ot.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepBack()):Ot.isEventKey(e,"Right")||Ot.isEventKey(e,"Up")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):n.prototype.handleKeyDown.call(this,e)},t.handleClick=function(e){e.stopPropagation(),e.preventDefault()},t.vertical=function(e){if(void 0===e)return this.vertical_||!1;this.vertical_=!!e,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")},e}(Fe);Fe.registerComponent("Slider",zr);var Wr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).partEls_=[],i.on(e,"progress",i.update),i}p(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text"><span>'+this.localize("Loaded")+'</span>: <span class="vjs-control-text-loaded-percentage">0%</span></span>'})},t.dispose=function(){this.partEls_=null,n.prototype.dispose.call(this)},t.update=function(e){function t(e,t,i){var n=e/t||0;return n=100*(1<=n?1:n),i&&(n=n.toFixed(2)),n+"%"}var i=this.player_.liveTracker,n=this.player_.buffered(),r=i&&i.isLive()?i.seekableEnd():this.player_.duration(),a=this.player_.bufferedEnd(),s=this.partEls_,o=this.$(".vjs-control-text-loaded-percentage");this.el_.style.width=t(a,r),P(o,t(a,r,!0));for(var u=0;u<n.length;u++){var l=n.start(u),c=n.end(u),h=s[u];h||(h=this.el_.appendChild(A()),s[u]=h),h.style.left=t(l,a),h.style.width=t(c-l,a)}for(var d=s.length;d>n.length;d--)this.el_.removeChild(s[d-1]);s.length=n.length},e}(Fe);Fe.registerComponent("LoadProgressBar",Wr);var Gr=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var i=t.prototype;return i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})},i.update=function(e,t,i){var n=V(this.el_),r=V(this.player_.el()),a=e.width*t;if(r&&n){var s=e.left-r.left+a,o=e.width-a+(r.right-e.right),u=n.width/2;s<u?u+=u-s:o<u&&(u=o),u<0?u=0:u>n.width&&(u=n.width),this.el_.style.right="-"+u+"px",this.write(i)}},i.write=function(e){P(this.el_,e)},i.updateTime=function(r,a,s,o){var u=this;this.rafId_&&this.cancelAnimationFrame(this.rafId_),this.rafId_=this.requestAnimationFrame(function(){var e,t=u.player_.duration();if(u.player_.liveTracker&&u.player_.liveTracker.isLive()){var i=u.player_.liveTracker.liveWindow(),n=i-a*i;e=(n<1?"":"-")+Mr(n,i)}else e=Mr(s,t);u.update(r,a,e),o&&o()})},t}(Fe);Fe.registerComponent("TimeTooltip",Gr);var $r=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var i=t.prototype;return i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})},i.update=function(e,t){var i=this.getChild("timeTooltip");if(i){var n=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();i.updateTime(e,t,n)}},t}(Fe);$r.prototype.options_={children:[]},Qe||Ze||$r.prototype.options_.children.push("timeTooltip"),Fe.registerComponent("PlayProgressBar",$r);var Xr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update=we(ke(f(i),i.update),25),i}p(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t){var i=this,n=t*this.player_.duration();this.getChild("timeTooltip").updateTime(e,t,n,function(){i.el_.style.left=e.width*t+"px"})},e}(Fe);Xr.prototype.options_={children:["timeTooltip"]},Fe.registerComponent("MouseTimeDisplay",Xr);var Kr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).setEventHandlers_(),i}p(e,n);var t=e.prototype;return t.setEventHandlers_=function(){this.update=we(ke(this,this.update),30),this.on(this.player_,"timeupdate",this.update),this.on(this.player_,"ended",this.handleEnded),this.on(this.player_,"durationchange",this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.on(this.player_,["playing"],this.enableInterval_),this.on(this.player_,["ended","pause","waiting"],this.disableInterval_),"hidden"in h&&"visibilityState"in h&&this.on(h,"visibilitychange",this.toggleVisibility_)},t.toggleVisibility_=function(e){h.hidden?this.disableInterval_(e):(this.enableInterval_(),this.requestAnimationFrame(this.update))},t.enableInterval_=function(){var e=this;this.clearInterval(this.updateInterval),this.updateInterval=this.setInterval(function(){e.requestAnimationFrame(e.update)},30)},t.disableInterval_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&"ended"!==e.type||this.clearInterval(this.updateInterval)},t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})},t.update_=function(e,t){var i=this.player_.liveTracker,n=this.player_.duration();i&&i.isLive()&&(n=this.player_.liveTracker.liveCurrentTime()),this.el_.setAttribute("aria-valuenow",(100*t).toFixed(2)),this.el_.setAttribute("aria-valuetext",this.localize("progress bar timing: currentTime={1} duration={2}",[Mr(e,n),Mr(n,n)],"{1} of {2}")),this.bar&&this.bar.update(V(this.el_),t)},t.update=function(e){if(null!==this.el().offsetParent){var t=n.prototype.update.call(this);return this.update_(this.getCurrentTime_(),t),t}},t.getCurrentTime_=function(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()},t.handleEnded=function(e){this.update_(this.player_.duration(),1)},t.getPercent=function(){var e,t=this.getCurrentTime_(),i=this.player_.liveTracker;return i&&i.isLive()?(e=(t-i.seekableStart())/i.liveWindow(),i.atLiveEdge()&&(e=1)):e=t/this.player_.duration(),1<=e?1:e||0},t.handleMouseDown=function(e){K(e)&&(e.stopPropagation(),this.player_.scrubbing(!0),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),n.prototype.handleMouseDown.call(this,e))},t.handleMouseMove=function(e){if(K(e)){var t,i=this.calculateDistance(e),n=this.player_.liveTracker;if(n&&n.isLive()){var r=n.seekableStart(),a=n.liveCurrentTime();if(a<=(t=r+i*n.liveWindow())&&(t=a),t<=r&&(t=r+.1),t===1/0)return}else(t=i*this.player_.duration())===this.player_.duration()&&(t-=.1);this.player_.currentTime(t)}},t.enable=function(){n.prototype.enable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.show()},t.disable=function(){n.prototype.disable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.hide()},t.handleMouseUp=function(e){n.prototype.handleMouseUp.call(this,e),e&&e.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying&&Et(this.player_.play())},t.stepForward=function(){this.player_.currentTime(this.player_.currentTime()+5)},t.stepBack=function(){this.player_.currentTime(this.player_.currentTime()-5)},t.handleAction=function(e){this.player_.paused()?this.player_.play():this.player_.pause()},t.handleKeyDown=function(e){if(Ot.isEventKey(e,"Space")||Ot.isEventKey(e,"Enter"))e.preventDefault(),e.stopPropagation(),this.handleAction(e);else if(Ot.isEventKey(e,"Home"))e.preventDefault(),e.stopPropagation(),this.player_.currentTime(0);else if(Ot.isEventKey(e,"End"))e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.duration());else if(/^[0-9]$/.test(Ot(e))){e.preventDefault(),e.stopPropagation();var t=10*(Ot.codes[Ot(e)]-Ot.codes[0])/100;this.player_.currentTime(this.player_.duration()*t)}else Ot.isEventKey(e,"PgDn")?(e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.currentTime()-60)):Ot.isEventKey(e,"PgUp")?(e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.currentTime()+60)):n.prototype.handleKeyDown.call(this,e)},e}(zr);Kr.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},Qe||Ze||Kr.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),Fe.registerComponent("SeekBar",Kr);var Yr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).handleMouseMove=we(ke(f(i),i.handleMouseMove),25),i.throttledHandleMouseSeek=we(ke(f(i),i.handleMouseSeek),25),i.enable(),i}p(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-control vjs-control"})},t.handleMouseMove=function(e){var t=this.getChild("seekBar");if(t){var i=t.getChild("mouseTimeDisplay"),n=t.el(),r=V(n),a=q(n,e).x;1<a?a=1:a<0&&(a=0),i&&i.update(r,a)}},t.handleMouseSeek=function(e){var t=this.getChild("seekBar");t&&t.handleMouseMove(e)},t.enabled=function(){return this.enabled_},t.disable=function(){this.children().forEach(function(e){return e.disable&&e.disable()}),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDown),this.off(this.el_,"mousemove",this.handleMouseMove),this.handleMouseUp(),this.addClass("disabled"),this.enabled_=!1)},t.enable=function(){this.children().forEach(function(e){return e.enable&&e.enable()}),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDown),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)},t.handleMouseDown=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseDown(e),this.on(t,"mousemove",this.throttledHandleMouseSeek),this.on(t,"touchmove",this.throttledHandleMouseSeek),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchend",this.handleMouseUp)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseUp(e),this.off(t,"mousemove",this.throttledHandleMouseSeek),this.off(t,"touchmove",this.throttledHandleMouseSeek),this.off(t,"mouseup",this.handleMouseUp),this.off(t,"touchend",this.handleMouseUp)},e}(Fe);Yr.prototype.options_={children:["seekBar"]},Fe.registerComponent("ProgressControl",Yr);var Qr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,["enterpictureinpicture","leavepictureinpicture"],i.handlePictureInPictureChange),h.pictureInPictureEnabled||i.disable(),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-picture-in-picture-control "+n.prototype.buildCSSClass.call(this)},t.handlePictureInPictureChange=function(e){this.player_.isInPictureInPicture()?this.controlText("Exit Picture-in-Picture"):this.controlText("Picture-in-Picture")},t.handleClick=function(e){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()},e}(Ir);Qr.prototype.controlText_="Picture-in-Picture",Fe.registerComponent("PictureInPictureToggle",Qr);var Jr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"fullscreenchange",i.handleFullscreenChange),!1===h[e.fsApi_.fullscreenEnabled]&&i.disable(),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-fullscreen-control "+n.prototype.buildCSSClass.call(this)},t.handleFullscreenChange=function(e){this.player_.isFullscreen()?this.controlText("Non-Fullscreen"):this.controlText("Fullscreen")},t.handleClick=function(e){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()},e}(Ir);Jr.prototype.controlText_="Fullscreen",Fe.registerComponent("FullscreenToggle",Jr);var Zr=function(e){function t(){return e.apply(this,arguments)||this}return p(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})},t}(Fe);Fe.registerComponent("VolumeLevel",Zr);var ea=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on("slideractive",i.updateLastVolume_),i.on(e,"volumechange",i.updateARIAAttributes),e.ready(function(){return i.updateARIAAttributes()}),i}p(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})},t.handleMouseDown=function(e){K(e)&&n.prototype.handleMouseDown.call(this,e)},t.handleMouseMove=function(e){K(e)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(e)))},t.checkMuted=function(){this.player_.muted()&&this.player_.muted(!1)},t.getPercent=function(){return this.player_.muted()?0:this.player_.volume()},t.stepForward=function(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)},t.stepBack=function(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)},t.updateARIAAttributes=function(e){var t=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",t),this.el_.setAttribute("aria-valuetext",t+"%")},t.volumeAsPercentage_=function(){return Math.round(100*this.player_.volume())},t.updateLastVolume_=function(){var e=this,t=this.player_.volume();this.one("sliderinactive",function(){0===e.player_.volume()&&e.player_.lastVolume_(t)})},e}(zr);ea.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},ea.prototype.playerEvent="volumechange",Fe.registerComponent("VolumeBar",ea);var ta=function(n){function e(e,t){var i;return void 0===t&&(t={}),t.vertical=t.vertical||!1,"undefined"!=typeof t.volumeBar&&!l(t.volumeBar)||(t.volumeBar=t.volumeBar||{},t.volumeBar.vertical=t.vertical),function(e,t){t.tech_&&!t.tech_.featuresVolumeControl&&e.addClass("vjs-hidden"),e.on(t,"loadstart",function(){t.tech_.featuresVolumeControl?e.removeClass("vjs-hidden"):e.addClass("vjs-hidden")})}(f(i=n.call(this,e,t)||this),e),i.throttledHandleMouseMove=we(ke(f(i),i.handleMouseMove),25),i.on("mousedown",i.handleMouseDown),i.on("touchstart",i.handleMouseDown),i.on(i.volumeBar,["focus","slideractive"],function(){i.volumeBar.addClass("vjs-slider-active"),i.addClass("vjs-slider-active"),i.trigger("slideractive")}),i.on(i.volumeBar,["blur","sliderinactive"],function(){i.volumeBar.removeClass("vjs-slider-active"),i.removeClass("vjs-slider-active"),i.trigger("sliderinactive")}),i}p(e,n);var t=e.prototype;return t.createEl=function(){var e="vjs-volume-horizontal";return this.options_.vertical&&(e="vjs-volume-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-control vjs-control "+e})},t.handleMouseDown=function(e){var t=this.el_.ownerDocument;this.on(t,"mousemove",this.throttledHandleMouseMove),this.on(t,"touchmove",this.throttledHandleMouseMove),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchend",this.handleMouseUp)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument;this.off(t,"mousemove",this.throttledHandleMouseMove),this.off(t,"touchmove",this.throttledHandleMouseMove),this.off(t,"mouseup",this.handleMouseUp),this.off(t,"touchend",this.handleMouseUp)},t.handleMouseMove=function(e){this.volumeBar.handleMouseMove(e)},e}(Fe);ta.prototype.options_={children:["volumeBar"]},Fe.registerComponent("VolumeControl",ta);var ia=function(n){function e(e,t){var i;return function(e,t){t.tech_&&!t.tech_.featuresMuteControl&&e.addClass("vjs-hidden"),e.on(t,"loadstart",function(){t.tech_.featuresMuteControl?e.removeClass("vjs-hidden"):e.addClass("vjs-hidden")})}(f(i=n.call(this,e,t)||this),e),i.on(e,["loadstart","volumechange"],i.update),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-mute-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){var t=this.player_.volume(),i=this.player_.lastVolume_();if(0===t){var n=i<.1?.1:i;this.player_.volume(n),this.player_.muted(!1)}else this.player_.muted(!this.player_.muted())},t.update=function(e){this.updateIcon_(),this.updateControlText_()},t.updateIcon_=function(){var e=this.player_.volume(),t=3;Qe&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===e||this.player_.muted()?t=0:e<.33?t=1:e<.67&&(t=2);for(var i=0;i<4;i++)x(this.el_,"vjs-vol-"+i);O(this.el_,"vjs-vol-"+t)},t.updateControlText_=function(){var e=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==e&&this.controlText(e)},e}(Ir);ia.prototype.controlText_="Mute",Fe.registerComponent("MuteToggle",ia);var na=function(n){function e(e,t){var i;return void 0===t&&(t={}),"undefined"!=typeof t.inline?t.inline=t.inline:t.inline=!0,"undefined"!=typeof t.volumeControl&&!l(t.volumeControl)||(t.volumeControl=t.volumeControl||{},t.volumeControl.vertical=!t.inline),(i=n.call(this,e,t)||this).on(e,["loadstart"],i.volumePanelState_),i.on(i.volumeControl,["slideractive"],i.sliderActive_),i.on(i.volumeControl,["sliderinactive"],i.sliderInactive_),i}p(e,n);var t=e.prototype;return t.sliderActive_=function(){this.addClass("vjs-slider-active")},t.sliderInactive_=function(){this.removeClass("vjs-slider-active")},t.volumePanelState_=function(){this.volumeControl.hasClass("vjs-hidden")&&this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-hidden"),this.volumeControl.hasClass("vjs-hidden")&&!this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-mute-toggle-only")},t.createEl=function(){var e="vjs-volume-panel-horizontal";return this.options_.inline||(e="vjs-volume-panel-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-panel vjs-control "+e})},e}(Fe);na.prototype.options_={children:["muteToggle","volumeControl"]},Fe.registerComponent("VolumePanel",na);var ra=function(n){function e(e,t){var i;return i=n.call(this,e,t)||this,t&&(i.menuButton_=t.menuButton),i.focusedChild_=-1,i.on("keydown",i.handleKeyDown),i.boundHandleBlur_=ke(f(i),i.handleBlur),i.boundHandleTapClick_=ke(f(i),i.handleTapClick),i}p(e,n);var t=e.prototype;return t.addEventListenerForItem=function(e){e instanceof Fe&&(this.on(e,"blur",this.boundHandleBlur_),this.on(e,["tap","click"],this.boundHandleTapClick_))},t.removeEventListenerForItem=function(e){e instanceof Fe&&(this.off(e,"blur",this.boundHandleBlur_),this.off(e,["tap","click"],this.boundHandleTapClick_))},t.removeChild=function(e){"string"==typeof e&&(e=this.getChild(e)),this.removeEventListenerForItem(e),n.prototype.removeChild.call(this,e)},t.addItem=function(e){var t=this.addChild(e);t&&this.addEventListenerForItem(t)},t.createEl=function(){var e=this.options_.contentElType||"ul";this.contentEl_=A(e,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");var t=n.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return t.appendChild(this.contentEl_),he(t,"click",function(e){e.preventDefault(),e.stopImmediatePropagation()}),t},t.dispose=function(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,n.prototype.dispose.call(this)},t.handleBlur=function(e){var t=e.relatedTarget||h.activeElement;if(!this.children().some(function(e){return e.el()===t})){var i=this.menuButton_;i&&i.buttonPressed_&&t!==i.el().firstChild&&i.unpressButton()}},t.handleTapClick=function(t){if(this.menuButton_){this.menuButton_.unpressButton();var e=this.children();if(!Array.isArray(e))return;var i=e.filter(function(e){return e.el()===t.target})[0];if(!i)return;"CaptionSettingsMenuItem"!==i.name()&&this.menuButton_.focus()}},t.handleKeyDown=function(e){Ot.isEventKey(e,"Left")||Ot.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):(Ot.isEventKey(e,"Right")||Ot.isEventKey(e,"Up"))&&(e.preventDefault(),e.stopPropagation(),this.stepBack())},t.stepForward=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_+1),this.focus(e)},t.stepBack=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_-1),this.focus(e)},t.focus=function(e){void 0===e&&(e=0);var t=this.children().slice();t.length&&t[0].className&&/vjs-menu-title/.test(t[0].className)&&t.shift(),0<t.length&&(e<0?e=0:e>=t.length&&(e=t.length-1),t[this.focusedChild_=e].el_.focus())},e}(Fe);Fe.registerComponent("Menu",ra);var aa=function(r){function e(e,t){var i;void 0===t&&(t={}),(i=r.call(this,e,t)||this).menuButton_=new Ir(e,t),i.menuButton_.controlText(i.controlText_),i.menuButton_.el_.setAttribute("aria-haspopup","true");var n=Ir.prototype.buildCSSClass();return i.menuButton_.el_.className=i.buildCSSClass()+" "+n,i.menuButton_.removeClass("vjs-control"),i.addChild(i.menuButton_),i.update(),i.enabled_=!0,i.on(i.menuButton_,"tap",i.handleClick),i.on(i.menuButton_,"click",i.handleClick),i.on(i.menuButton_,"keydown",i.handleKeyDown),i.on(i.menuButton_,"mouseenter",function(){i.menu.show()}),i.on("keydown",i.handleSubmenuKeyDown),i}p(e,r);var t=e.prototype;return t.update=function(){var e=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=e,this.addChild(e),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?this.hide():this.show()},t.createMenu=function(){var e=new ra(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title){var t=A("li",{className:"vjs-menu-title",innerHTML:Ne(this.options_.title),tabIndex:-1});this.hideThreshold_+=1;var i=new Fe(this.player_,{el:t});e.addItem(i)}if(this.items=this.createItems(),this.items)for(var n=0;n<this.items.length;n++)e.addItem(this.items[n]);return e},t.createItems=function(){},t.createEl=function(){return r.prototype.createEl.call(this,"div",{className:this.buildWrapperCSSClass()},{})},t.buildWrapperCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+Ir.prototype.buildCSSClass()+" "+r.prototype.buildCSSClass.call(this)},t.buildCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+r.prototype.buildCSSClass.call(this)},t.controlText=function(e,t){return void 0===t&&(t=this.menuButton_.el()),this.menuButton_.controlText(e,t)},t.handleClick=function(e){this.buttonPressed_?this.unpressButton():this.pressButton()},t.focus=function(){this.menuButton_.focus()},t.blur=function(){this.menuButton_.blur()},t.handleKeyDown=function(e){Ot.isEventKey(e,"Esc")||Ot.isEventKey(e,"Tab")?(this.buttonPressed_&&this.unpressButton(),Ot.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus())):(Ot.isEventKey(e,"Up")||Ot.isEventKey(e,"Down"))&&(this.buttonPressed_||(e.preventDefault(),this.pressButton()))},t.handleSubmenuKeyPress=function(e){this.handleSubmenuKeyDown(e)},t.handleSubmenuKeyDown=function(e){(Ot.isEventKey(e,"Esc")||Ot.isEventKey(e,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),Ot.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus()))},t.pressButton=function(){if(this.enabled_){if(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),Qe&&C())return;this.menu.focus()}},t.unpressButton=function(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))},t.disable=function(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()},t.enable=function(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()},e}(Fe);Fe.registerComponent("MenuButton",aa);var sa=function(a){function e(e,t){var i,n=t.tracks;if((i=a.call(this,e,t)||this).items.length<=1&&i.hide(),!n)return f(i);var r=ke(f(i),i.update);return n.addEventListener("removetrack",r),n.addEventListener("addtrack",r),i.player_.on("ready",r),i.player_.on("dispose",function(){n.removeEventListener("removetrack",r),n.removeEventListener("addtrack",r)}),i}return p(e,a),e}(aa);Fe.registerComponent("TrackButton",sa);var oa=["Tab","Esc","Up","Down","Right","Left"],ua=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).selectable=t.selectable,i.isSelected_=t.selected||!1,i.multiSelectable=t.multiSelectable,i.selected(i.isSelected_),i.selectable?i.multiSelectable?i.el_.setAttribute("role","menuitemcheckbox"):i.el_.setAttribute("role","menuitemradio"):i.el_.setAttribute("role","menuitem"),i}p(e,n);var t=e.prototype;return t.createEl=function(e,t,i){return this.nonIconControl=!0,n.prototype.createEl.call(this,"li",_({className:"vjs-menu-item",innerHTML:'<span class="vjs-menu-item-text">'+this.localize(this.options_.label)+"</span>",tabIndex:-1},t),i)},t.handleKeyDown=function(t){oa.some(function(e){return Ot.isEventKey(t,e)})||n.prototype.handleKeyDown.call(this,t)},t.handleClick=function(e){this.selected(!0)},t.selected=function(e){this.selectable&&(e?(this.addClass("vjs-selected"),this.el_.setAttribute("aria-checked","true"),this.controlText(", selected"),this.isSelected_=!0):(this.removeClass("vjs-selected"),this.el_.setAttribute("aria-checked","false"),this.controlText(""),this.isSelected_=!1))},e}(Sr);Fe.registerComponent("MenuItem",ua);var la=function(u){function e(e,t){var n,i=t.track,r=e.textTracks();t.label=i.label||i.language||"Unknown",t.selected="showing"===i.mode,(n=u.call(this,e,t)||this).track=i,n.kinds=(t.kinds||[t.kind||n.track.kind]).filter(Boolean);function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(f(n),t)}function s(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleSelectedLanguageChange.apply(f(n),t)}var o;e.on(["loadstart","texttrackchange"],a),r.addEventListener("change",a),r.addEventListener("selectedlanguagechange",s),n.on("dispose",function(){e.off(["loadstart","texttrackchange"],a),r.removeEventListener("change",a),r.removeEventListener("selectedlanguagechange",s)}),void 0===r.onchange&&n.on(["tap","click"],function(){if("object"!=typeof v.Event)try{o=new v.Event("change")}catch(e){}o||(o=h.createEvent("Event")).initEvent("change",!0,!0),r.dispatchEvent(o)});return n.handleTracksChange(),n}p(e,u);var t=e.prototype;return t.handleClick=function(e){var t=this.track,i=this.player_.textTracks();if(u.prototype.handleClick.call(this,e),i)for(var n=0;n<i.length;n++){var r=i[n];-1!==this.kinds.indexOf(r.kind)&&(r===t?"showing"!==r.mode&&(r.mode="showing"):"disabled"!==r.mode&&(r.mode="disabled"))}},t.handleTracksChange=function(e){var t="showing"===this.track.mode;t!==this.isSelected_&&this.selected(t)},t.handleSelectedLanguageChange=function(e){if("showing"===this.track.mode){var t=this.player_.cache_.selectedLanguage;if(t&&t.enabled&&t.language===this.track.language&&t.kind!==this.track.kind)return;this.player_.cache_.selectedLanguage={enabled:!0,language:this.track.language,kind:this.track.kind}}},t.dispose=function(){this.track=null,u.prototype.dispose.call(this)},e}(ua);Fe.registerComponent("TextTrackMenuItem",la);var ca=function(i){function e(e,t){return t.track={player:e,kind:t.kind,kinds:t.kinds,default:!1,mode:"disabled"},t.kinds||(t.kinds=[t.kind]),t.label?t.track.label=t.label:t.track.label=t.kinds.join(" and ")+" off",t.selectable=!0,t.multiSelectable=!1,i.call(this,e,t)||this}p(e,i);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<this.options_.kinds.indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i!==this.isSelected_&&this.selected(i)},t.handleSelectedLanguageChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<["captions","descriptions","subtitles"].indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i&&(this.player_.cache_.selectedLanguage={enabled:!1})},e}(la);Fe.registerComponent("OffTextTrackMenuItem",ca);var ha=function(i){function e(e,t){return void 0===t&&(t={}),t.tracks=e.textTracks(),i.call(this,e,t)||this}return p(e,i),e.prototype.createItems=function(e,t){var i;void 0===e&&(e=[]),void 0===t&&(t=la),this.label_&&(i=this.label_+" off"),e.push(new ca(this.player_,{kinds:this.kinds_,kind:this.kind_,label:i})),this.hideThreshold_+=1;var n=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(var r=0;r<n.length;r++){var a=n[r];if(-1<this.kinds_.indexOf(a.kind)){var s=new t(this.player_,{track:a,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1});s.addClass("vjs-"+a.kind+"-menu-item"),e.push(s)}}return e},e}(sa);Fe.registerComponent("TextTrackButton",ha);var da=function(s){function e(e,t){var i,n=t.track,r=t.cue,a=e.currentTime();return t.selectable=!0,t.multiSelectable=!1,t.label=r.text,t.selected=r.startTime<=a&&a<r.endTime,(i=s.call(this,e,t)||this).track=n,i.cue=r,n.addEventListener("cuechange",ke(f(i),i.update)),i}p(e,s);var t=e.prototype;return t.handleClick=function(e){s.prototype.handleClick.call(this),this.player_.currentTime(this.cue.startTime),this.update(this.cue.startTime)},t.update=function(e){var t=this.cue,i=this.player_.currentTime();this.selected(t.startTime<=i&&i<t.endTime)},e}(ua);Fe.registerComponent("ChaptersTrackMenuItem",da);var pa=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildWrapperCSSClass.call(this)},t.update=function(e){this.track_&&(!e||"addtrack"!==e.type&&"removetrack"!==e.type)||this.setTrack(this.findChaptersTrack()),n.prototype.update.call(this)},t.setTrack=function(e){if(this.track_!==e){if(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_){var t=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);t&&t.removeEventListener("load",this.updateHandler_),this.track_=null}if(this.track_=e,this.track_){this.track_.mode="hidden";var i=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);i&&i.addEventListener("load",this.updateHandler_)}}},t.findChaptersTrack=function(){for(var e=this.player_.textTracks()||[],t=e.length-1;0<=t;t--){var i=e[t];if(i.kind===this.kind_)return i}},t.getMenuCaption=function(){return this.track_&&this.track_.label?this.track_.label:this.localize(Ne(this.kind_))},t.createMenu=function(){return this.options_.title=this.getMenuCaption(),n.prototype.createMenu.call(this)},t.createItems=function(){var e=[];if(!this.track_)return e;var t=this.track_.cues;if(!t)return e;for(var i=0,n=t.length;i<n;i++){var r=t[i],a=new da(this.player_,{track:this.track_,cue:r});e.push(a)}return e},e}(ha);pa.prototype.kind_="chapters",pa.prototype.controlText_="Chapters",Fe.registerComponent("ChaptersButton",pa);var fa=function(s){function e(e,t,i){var n;n=s.call(this,e,t,i)||this;var r=e.textTracks(),a=ke(f(n),n.handleTracksChange);return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}p(e,s);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!1,n=0,r=t.length;n<r;n++){var a=t[n];if(a.kind!==this.kind_&&"showing"===a.mode){i=!0;break}}i?this.disable():this.enable()},t.buildCSSClass=function(){return"vjs-descriptions-button "+s.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-descriptions-button "+s.prototype.buildWrapperCSSClass.call(this)},e}(ha);fa.prototype.kind_="descriptions",fa.prototype.controlText_="Descriptions",Fe.registerComponent("DescriptionsButton",fa);var ma=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildWrapperCSSClass.call(this)},e}(ha);ma.prototype.kind_="subtitles",ma.prototype.controlText_="Subtitles",Fe.registerComponent("SubtitlesButton",ma);var ga=function(n){function e(e,t){var i;return t.track={player:e,kind:t.kind,label:t.kind+" settings",selectable:!1,default:!1,mode:"disabled"},t.selectable=!1,t.name="CaptionSettingsMenuItem",(i=n.call(this,e,t)||this).addClass("vjs-texttrack-settings"),i.controlText(", opens "+t.kind+" settings dialog"),i}return p(e,n),e.prototype.handleClick=function(e){this.player().getChild("textTrackSettings").open()},e}(la);Fe.registerComponent("CaptionSettingsMenuItem",ga);var ya=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-captions-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-captions-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new ga(this.player_,{kind:this.kind_})),this.hideThreshold_+=1),n.prototype.createItems.call(this,e)},e}(ha);ya.prototype.kind_="captions",ya.prototype.controlText_="Captions",Fe.registerComponent("CaptionsButton",ya);var va=function(r){function e(){return r.apply(this,arguments)||this}return p(e,r),e.prototype.createEl=function(e,t,i){var n='<span class="vjs-menu-item-text">'+this.localize(this.options_.label);return"captions"===this.options_.track.kind&&(n+='\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> '+this.localize("Captions")+"</span>\n "),n+="</span>",r.prototype.createEl.call(this,e,_({innerHTML:n},t),i)},e}(la);Fe.registerComponent("SubsCapsMenuItem",va);var _a=function(n){function e(e,t){var i;return void 0===t&&(t={}),(i=n.call(this,e,t)||this).label_="subtitles",-1<["en","en-us","en-ca","fr-ca"].indexOf(i.player_.language_)&&(i.label_="captions"),i.menuButton_.controlText(Ne(i.label_)),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subs-caps-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subs-caps-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new ga(this.player_,{kind:this.label_})),this.hideThreshold_+=1),e=n.prototype.createItems.call(this,e,va)},e}(ha);_a.prototype.kinds_=["captions","subtitles"],_a.prototype.controlText_="Subtitles",Fe.registerComponent("SubsCapsButton",_a);var ba=function(s){function e(e,t){var n,i=t.track,r=e.audioTracks();t.label=i.label||i.language||"Unknown",t.selected=i.enabled,(n=s.call(this,e,t)||this).track=i,n.addClass("vjs-"+i.kind+"-menu-item");function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(f(n),t)}return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}p(e,s);var t=e.prototype;return t.createEl=function(e,t,i){var n='<span class="vjs-menu-item-text">'+this.localize(this.options_.label);return"main-desc"===this.options_.track.kind&&(n+='\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> '+this.localize("Descriptions")+"</span>\n "),n+="</span>",s.prototype.createEl.call(this,e,_({innerHTML:n},t),i)},t.handleClick=function(e){var t=this.player_.audioTracks();s.prototype.handleClick.call(this,e);for(var i=0;i<t.length;i++){var n=t[i];n.enabled=n===this.track}},t.handleTracksChange=function(e){this.selected(this.track.enabled)},e}(ua);Fe.registerComponent("AudioTrackMenuItem",ba);var Ta=function(i){function e(e,t){return void 0===t&&(t={}),t.tracks=e.audioTracks(),i.call(this,e,t)||this}p(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-audio-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-audio-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(e){void 0===e&&(e=[]),this.hideThreshold_=1;for(var t=this.player_.audioTracks(),i=0;i<t.length;i++){var n=t[i];e.push(new ba(this.player_,{track:n,selectable:!0,multiSelectable:!1}))}return e},e}(sa);Ta.prototype.controlText_="Audio Track",Fe.registerComponent("AudioTrackButton",Ta);var Sa=function(a){function e(e,t){var i,n=t.rate,r=parseFloat(n,10);return t.label=n,t.selected=1===r,t.selectable=!0,t.multiSelectable=!1,(i=a.call(this,e,t)||this).label=n,i.rate=r,i.on(e,"ratechange",i.update),i}p(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player().playbackRate(this.rate)},t.update=function(e){this.selected(this.player().playbackRate()===this.rate)},e}(ua);Sa.prototype.contentElType="button",Fe.registerComponent("PlaybackRateMenuItem",Sa);var ka=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateVisibility(),i.updateLabel(),i.on(e,"loadstart",i.updateVisibility),i.on(e,"ratechange",i.updateLabel),i}p(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this);return this.labelEl_=A("div",{className:"vjs-playback-rate-value",innerHTML:"1x"}),e.appendChild(this.labelEl_),e},t.dispose=function(){this.labelEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildWrapperCSSClass.call(this)},t.createMenu=function(){var e=new ra(this.player()),t=this.playbackRates();if(t)for(var i=t.length-1;0<=i;i--)e.addChild(new Sa(this.player(),{rate:t[i]+"x"}));return e},t.updateARIAAttributes=function(){this.el().setAttribute("aria-valuenow",this.player().playbackRate())},t.handleClick=function(e){for(var t=this.player().playbackRate(),i=this.playbackRates(),n=i[0],r=0;r<i.length;r++)if(i[r]>t){n=i[r];break}this.player().playbackRate(n)},t.playbackRates=function(){return this.options_.playbackRates||this.options_.playerOptions&&this.options_.playerOptions.playbackRates},t.playbackRateSupported=function(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&0<this.playbackRates().length},t.updateVisibility=function(e){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")},t.updateLabel=function(e){this.playbackRateSupported()&&(this.labelEl_.innerHTML=this.player().playbackRate()+"x")},e}(aa);ka.prototype.controlText_="Playback Rate",Fe.registerComponent("PlaybackRateMenuButton",ka);var wa=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-spacer "+e.prototype.buildCSSClass.call(this)},i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:this.buildCSSClass()})},t}(Fe);Fe.registerComponent("Spacer",wa);var Ca=function(t){function e(){return t.apply(this,arguments)||this}p(e,t);var i=e.prototype;return i.buildCSSClass=function(){return"vjs-custom-control-spacer "+t.prototype.buildCSSClass.call(this)},i.createEl=function(){var e=t.prototype.createEl.call(this,{className:this.buildCSSClass()});return e.innerHTML=" ",e},e}(wa);Fe.registerComponent("CustomControlSpacer",Ca);var Ea=function(e){function t(){return e.apply(this,arguments)||this}return p(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-control-bar",dir:"ltr"})},t}(Fe);Ea.prototype.options_={children:["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","pictureInPictureToggle","fullscreenToggle"]},Fe.registerComponent("ControlBar",Ea);var Aa=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"error",i.open),i}p(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-error-display "+n.prototype.buildCSSClass.call(this)},t.content=function(){var e=this.player().error();return e?this.localize(e.message):""},e}(Ut);Aa.prototype.options_=je(Ut.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),Fe.registerComponent("ErrorDisplay",Aa);var Pa="vjs-text-track-settings",La=["#000","Black"],Ia=["#00F","Blue"],Oa=["#0FF","Cyan"],xa=["#0F0","Green"],Ua=["#F0F","Magenta"],Da=["#F00","Red"],Ra=["#FFF","White"],Ma=["#FF0","Yellow"],Ba=["1","Opaque"],Na=["0.5","Semi-Transparent"],ja=["0","Transparent"],Fa={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[La,Ra,Da,xa,Ia,Ma,Ua,Oa]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Transparency",options:[Ba,Na,ja]},color:{selector:".vjs-fg-color > select",id:"captions-foreground-color-%s",label:"Color",options:[Ra,La,Da,xa,Ia,Ma,Ua,Oa]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Dropshadow"]]},fontFamily:{selector:".vjs-font-family > select",id:"captions-font-family-%s",label:"Font Family",options:[["proportionalSansSerif","Proportional Sans-Serif"],["monospaceSansSerif","Monospace Sans-Serif"],["proportionalSerif","Proportional Serif"],["monospaceSerif","Monospace Serif"],["casual","Casual"],["script","Script"],["small-caps","Small Caps"]]},fontPercent:{selector:".vjs-font-percent > select",id:"captions-font-size-%s",label:"Font Size",options:[["0.50","50%"],["0.75","75%"],["1.00","100%"],["1.25","125%"],["1.50","150%"],["1.75","175%"],["2.00","200%"],["3.00","300%"],["4.00","400%"]],default:2,parser:function(e){return"1.00"===e?null:Number(e)}},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Transparency",options:[Ba,Na]},windowColor:{selector:".vjs-window-color > select",id:"captions-window-color-%s",label:"Color"},windowOpacity:{selector:".vjs-window-opacity > select",id:"captions-window-opacity-%s",label:"Transparency",options:[ja,Na,Ba]}};function Va(e,t){if(t&&(e=t(e)),e&&"none"!==e)return e}Fa.windowColor.options=Fa.backgroundColor.options;var Ha=function(n){function e(e,t){var i;return t.temporary=!1,(i=n.call(this,e,t)||this).updateDisplay=ke(f(i),i.updateDisplay),i.fill(),i.hasBeenOpened_=i.hasBeenFilled_=!0,i.endDialog=A("p",{className:"vjs-control-text",textContent:i.localize("End of dialog window.")}),i.el().appendChild(i.endDialog),i.setDefaults(),void 0===t.persistTextTrackSettings&&(i.options_.persistTextTrackSettings=i.options_.playerOptions.persistTextTrackSettings),i.on(i.$(".vjs-done-button"),"click",function(){i.saveSettings(),i.close()}),i.on(i.$(".vjs-default-button"),"click",function(){i.setDefaults(),i.updateDisplay()}),r(Fa,function(e){i.on(i.$(e.selector),"change",i.updateDisplay)}),i.options_.persistTextTrackSettings&&i.restoreSettings(),i}p(e,n);var t=e.prototype;return t.dispose=function(){this.endDialog=null,n.prototype.dispose.call(this)},t.createElSelect_=function(e,t,i){var n=this;void 0===t&&(t=""),void 0===i&&(i="label");var r=Fa[e],a=r.id.replace("%s",this.id_),s=[t,a].join(" ").trim();return["<"+i+' id="'+a+'" class="'+("label"===i?"vjs-label":"")+'">',this.localize(r.label),"</"+i+">",'<select aria-labelledby="'+s+'">'].concat(r.options.map(function(e){var t=a+"-"+e[1].replace(/\W+/g,"");return['<option id="'+t+'" value="'+e[0]+'" ','aria-labelledby="'+s+" "+t+'">',n.localize(e[1]),"</option>"].join("")})).concat("</select>").join("")},t.createElFgColor_=function(){var e="captions-text-legend-"+this.id_;return['<fieldset class="vjs-fg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Text"),"</legend>",this.createElSelect_("color",e),'<span class="vjs-text-opacity vjs-opacity">',this.createElSelect_("textOpacity",e),"</span>","</fieldset>"].join("")},t.createElBgColor_=function(){var e="captions-background-"+this.id_;return['<fieldset class="vjs-bg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Background"),"</legend>",this.createElSelect_("backgroundColor",e),'<span class="vjs-bg-opacity vjs-opacity">',this.createElSelect_("backgroundOpacity",e),"</span>","</fieldset>"].join("")},t.createElWinColor_=function(){var e="captions-window-"+this.id_;return['<fieldset class="vjs-window-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Window"),"</legend>",this.createElSelect_("windowColor",e),'<span class="vjs-window-opacity vjs-opacity">',this.createElSelect_("windowOpacity",e),"</span>","</fieldset>"].join("")},t.createElColors_=function(){return A("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})},t.createElFont_=function(){return A("div",{className:"vjs-track-settings-font",innerHTML:['<fieldset class="vjs-font-percent vjs-track-setting">',this.createElSelect_("fontPercent","","legend"),"</fieldset>",'<fieldset class="vjs-edge-style vjs-track-setting">',this.createElSelect_("edgeStyle","","legend"),"</fieldset>",'<fieldset class="vjs-font-family vjs-track-setting">',this.createElSelect_("fontFamily","","legend"),"</fieldset>"].join("")})},t.createElControls_=function(){var e=this.localize("restore all settings to the default values");return A("div",{className:"vjs-track-settings-controls",innerHTML:['<button type="button" class="vjs-default-button" title="'+e+'">',this.localize("Reset"),'<span class="vjs-control-text"> '+e+"</span>","</button>",'<button type="button" class="vjs-done-button">'+this.localize("Done")+"</button>"].join("")})},t.content=function(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]},t.label=function(){return this.localize("Caption Settings Dialog")},t.description=function(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")},t.buildCSSClass=function(){return n.prototype.buildCSSClass.call(this)+" vjs-text-track-settings"},t.getValues=function(){var r=this;return function(i,n,e){return void 0===e&&(e=0),o(i).reduce(function(e,t){return n(e,i[t],t)},e)}(Fa,function(e,t,i){var n=function(e,t){return Va(e.options[e.options.selectedIndex].value,t)}(r.$(t.selector),t.parser);return void 0!==n&&(e[i]=n),e},{})},t.setValues=function(i){var n=this;r(Fa,function(e,t){!function(e,t,i){if(t)for(var n=0;n<e.options.length;n++)if(Va(e.options[n].value,i)===t){e.selectedIndex=n;break}}(n.$(e.selector),i[t],e.parser)})},t.setDefaults=function(){var i=this;r(Fa,function(e){var t=e.hasOwnProperty("default")?e.default:0;i.$(e.selector).selectedIndex=t})},t.restoreSettings=function(){var e;try{e=JSON.parse(v.localStorage.getItem(Pa))}catch(e){m.warn(e)}e&&this.setValues(e)},t.saveSettings=function(){if(this.options_.persistTextTrackSettings){var e=this.getValues();try{Object.keys(e).length?v.localStorage.setItem(Pa,JSON.stringify(e)):v.localStorage.removeItem(Pa)}catch(e){m.warn(e)}}},t.updateDisplay=function(){var e=this.player_.getChild("textTrackDisplay");e&&e.updateDisplay()},t.conditionalBlur_=function(){this.previouslyActiveEl_=null;var e=this.player_.controlBar,t=e&&e.subsCapsButton,i=e&&e.captionsButton;t?t.focus():i&&i.focus()},e}(Ut);Fe.registerComponent("TextTrackSettings",Ha);var qa=function(a){function e(e,t){var i,n=t.ResizeObserver||v.ResizeObserver;null===t.ResizeObserver&&(n=!1);var r=je({createEl:!n,reportTouchActivity:!1},t);return(i=a.call(this,e,r)||this).ResizeObserver=t.ResizeObserver||v.ResizeObserver,i.loadListener_=null,i.resizeObserver_=null,i.debouncedHandler_=function(n,r,a,s){var o;void 0===s&&(s=v);function e(){var e=this,t=arguments,i=function(){i=o=null,a||n.apply(e,t)};!o&&a&&n.apply(e,t),s.clearTimeout(o),o=s.setTimeout(i,r)}return e.cancel=function(){s.clearTimeout(o),o=null},e}(function(){i.resizeHandler()},100,!1,f(i)),n?(i.resizeObserver_=new i.ResizeObserver(i.debouncedHandler_),i.resizeObserver_.observe(e.el())):(i.loadListener_=function(){if(i.el_&&i.el_.contentWindow){var e=i.debouncedHandler_,t=i.unloadListener_=function(){de(this,"resize",e),de(this,"unload",t),t=null};he(i.el_.contentWindow,"unload",t),he(i.el_.contentWindow,"resize",e)}},i.one("load",i.loadListener_)),i}p(e,a);var t=e.prototype;return t.createEl=function(){return a.prototype.createEl.call(this,"iframe",{className:"vjs-resize-manager",tabIndex:-1},{"aria-hidden":"true"})},t.resizeHandler=function(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")},t.dispose=function(){this.debouncedHandler_&&this.debouncedHandler_.cancel(),this.resizeObserver_&&(this.player_.el()&&this.resizeObserver_.unobserve(this.player_.el()),this.resizeObserver_.disconnect()),this.loadListener_&&this.off("load",this.loadListener_),this.el_&&this.el_.contentWindow&&this.unloadListener_&&this.unloadListener_.call(this.el_.contentWindow),this.ResizeObserver=null,this.resizeObserver=null,this.debouncedHandler_=null,this.loadListener_=null,a.prototype.dispose.call(this)},e}(Fe);Fe.registerComponent("ResizeManager",qa);var za=function(r){function e(e,t){var i,n=je({createEl:!1},t);return(i=r.call(this,e,n)||this).reset_(),i.on(i.player_,"durationchange",i.handleDurationchange),st&&"hidden"in h&&"visibilityState"in h&&i.on(h,"visibilitychange",i.handleVisibilityChange),i}p(e,r);var t=e.prototype;return t.handleVisibilityChange=function(){this.player_.duration()===1/0&&(h.hidden?this.stopTracking():this.startTracking())},t.isBehind_=function(){if(!this.timeupdateSeen_)return!1;var e=this.liveCurrentTime(),t=this.player_.currentTime(),i=this.seekableIncrement_;return e!==1/0&&t<=e-(2*i+.07)},t.trackLive_=function(){this.pastSeekEnd_=this.pastSeekEnd_;var e=this.player_.seekable();if(e&&e.length){var t=this.seekableEnd();t!==this.lastSeekEnd_&&(this.lastSeekEnd_&&(this.seekableIncrement_=Math.abs(t-this.lastSeekEnd_)),this.pastSeekEnd_=0,this.lastSeekEnd_=t,this.trigger("seekableendchange")),this.pastSeekEnd_=this.pastSeekEnd()+.03,this.isBehind_()!==this.behindLiveEdge()&&(this.behindLiveEdge_=this.isBehind_(),this.trigger("liveedgechange"))}},t.handleDurationchange=function(){this.player_.duration()===1/0?this.startTracking():this.stopTracking()},t.startTracking=function(){var e=this;this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLive_,30),this.trackLive_(),this.on(this.player_,"play",this.trackLive_),this.on(this.player_,"pause",this.trackLive_),this.timeupdateSeen_||(this.one(this.player_,"play",this.handlePlay),this.handleTimeupdate=function(){e.timeupdateSeen_=!0,e.handleTimeupdate=null},this.one(this.player_,"timeupdate",this.handleTimeupdate)))},t.handlePlay=function(){this.one(this.player_,"timeupdate",this.seekToLiveEdge)},t.reset_=function(){this.pastSeekEnd_=0,this.lastSeekEnd_=null,this.behindLiveEdge_=null,this.timeupdateSeen_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.seekableIncrement_=12,this.off(this.player_,"play",this.trackLive_),this.off(this.player_,"pause",this.trackLive_),this.off(this.player_,"play",this.handlePlay),this.off(this.player_,"timeupdate",this.seekToLiveEdge),this.handleTimeupdate&&(this.off(this.player_,"timeupdate",this.handleTimeupdate),this.handleTimeupdate=null)},t.stopTracking=function(){this.isTracking()&&this.reset_()},t.seekableEnd=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.end(i));return t.length?t.sort()[t.length-1]:1/0},t.seekableStart=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.start(i));return t.length?t.sort()[0]:0},t.liveWindow=function(){var e=this.liveCurrentTime();return e===1/0?1/0:e-this.seekableStart()},t.isLive=function(){return this.isTracking()},t.atLiveEdge=function(){return!this.behindLiveEdge()},t.liveCurrentTime=function(){return this.pastSeekEnd()+this.seekableEnd()},t.pastSeekEnd=function(){return this.pastSeekEnd_},t.behindLiveEdge=function(){return this.behindLiveEdge_},t.isTracking=function(){return"number"==typeof this.trackingInterval_},t.seekToLiveEdge=function(){this.atLiveEdge()||(this.player_.currentTime(this.liveCurrentTime()),this.player_.paused()&&this.player_.play())},t.dispose=function(){this.stopTracking(),r.prototype.dispose.call(this)},e}(Fe);Fe.registerComponent("LiveTracker",za);function Wa(e){var t=e.el();if(t.hasAttribute("src"))return e.triggerSourceset(t.src),!0;var i=e.$$("source"),n=[],r="";if(!i.length)return!1;for(var a=0;a<i.length;a++){var s=i[a].src;s&&-1===n.indexOf(s)&&n.push(s)}return!!n.length&&(1===n.length&&(r=n[0]),e.triggerSourceset(r),!0)}function Ga(e,t){for(var i={},n=0;n<e.length&&!((i=Object.getOwnPropertyDescriptor(e[n],t))&&i.set&&i.get);n++);return i.enumerable=!0,i.configurable=!0,i}function $a(a){var s=a.el();if(!s.resetSourceWatch_){function t(r){return function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=r.apply(s,t);return Wa(a),n}}var i={},e=function(e){return Ga([e.el(),v.HTMLMediaElement.prototype,v.Element.prototype,Ka],"innerHTML")}(a);["append","appendChild","insertAdjacentHTML"].forEach(function(e){s[e]&&(i[e]=s[e],s[e]=t(i[e]))}),Object.defineProperty(s,"innerHTML",je(e,{set:t(e.set)})),s.resetSourceWatch_=function(){s.resetSourceWatch_=null,Object.keys(i).forEach(function(e){s[e]=i[e]}),Object.defineProperty(s,"innerHTML",e)},a.one("sourceset",s.resetSourceWatch_)}}function Xa(n){if(n.featuresSourceset){var r=n.el();if(!r.resetSourceset_){var i=function(e){return Ga([e.el(),v.HTMLMediaElement.prototype,Ya],"src")}(n),a=r.setAttribute,t=r.load;Object.defineProperty(r,"src",je(i,{set:function(e){var t=i.set.call(r,e);return n.triggerSourceset(r.src),t}})),r.setAttribute=function(e,t){var i=a.call(r,e,t);return/src/i.test(e)&&n.triggerSourceset(r.src),i},r.load=function(){var e=t.call(r);return Wa(n)||(n.triggerSourceset(""),$a(n)),e},r.currentSrc?n.triggerSourceset(r.currentSrc):Wa(n)||$a(n),r.resetSourceset_=function(){r.resetSourceset_=null,r.load=t,r.setAttribute=a,Object.defineProperty(r,"src",i),r.resetSourceWatch_&&r.resetSourceWatch_()}}}}var Ka=Object.defineProperty({},"innerHTML",{get:function(){return this.cloneNode(!0).innerHTML},set:function(e){var t=h.createElement(this.nodeName.toLowerCase());t.innerHTML=e;for(var i=h.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return this.innerText="",v.Element.prototype.appendChild.call(this,i),this.innerHTML}}),Ya=Object.defineProperty({},"src",{get:function(){return this.hasAttribute("src")?jt(v.Element.prototype.getAttribute.call(this,"src")):""},set:function(e){return v.Element.prototype.setAttribute.call(this,"src",e),e}});function Qa(){var e=t(["Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\n This may prevent text tracks from loading."]);return Qa=function(){return e},e}var Ja=function(c){function o(e,t){var i;i=c.call(this,e,t)||this;var n=e.source,r=!1;if(n&&(i.el_.currentSrc!==n.src||e.tag&&3===e.tag.initNetworkState_)?i.setSource(n):i.handleLateInit_(i.el_),e.enableSourceset&&i.setupSourcesetHandling_(),i.el_.hasChildNodes()){for(var a=i.el_.childNodes,s=a.length,o=[];s--;){var u=a[s];"track"===u.nodeName.toLowerCase()&&(i.featuresNativeTextTracks?(i.remoteTextTrackEls().addTrackElement_(u),i.remoteTextTracks().addTrack(u.track),i.textTracks().addTrack(u.track),r||i.el_.hasAttribute("crossorigin")||!Vt(u.src)||(r=!0)):o.push(u))}for(var l=0;l<o.length;l++)i.el_.removeChild(o[l])}return i.proxyNativeTracks_(),i.featuresNativeTextTracks&&r&&m.warn(y(Qa())),i.restoreMetadataTracksInIOSNativePlayer_(),(ct||Ke||tt)&&!0===e.nativeControlsForTouch&&i.setControls(!0),i.proxyWebkitFullscreen_(),i.triggerReady(),i}p(o,c);var e=o.prototype;return e.dispose=function(){this.el_&&this.el_.resetSourceset_&&this.el_.resetSourceset_(),o.disposeMediaElement(this.el_),this.options_=null,c.prototype.dispose.call(this)},e.setupSourcesetHandling_=function(){Xa(this)},e.restoreMetadataTracksInIOSNativePlayer_=function(){function e(){i=[];for(var e=0;e<n.length;e++){var t=n[e];"metadata"===t.kind&&i.push({track:t,storedMode:t.mode})}}var i,n=this.textTracks();e(),n.addEventListener("change",e),this.on("dispose",function(){return n.removeEventListener("change",e)});function r(){for(var e=0;e<i.length;e++){var t=i[e];"disabled"===t.track.mode&&t.track.mode!==t.storedMode&&(t.track.mode=t.storedMode)}n.removeEventListener("change",r)}this.on("webkitbeginfullscreen",function(){n.removeEventListener("change",e),n.removeEventListener("change",r),n.addEventListener("change",r)}),this.on("webkitendfullscreen",function(){n.removeEventListener("change",e),n.addEventListener("change",e),n.removeEventListener("change",r)})},e.overrideNative_=function(e,t){var i=this;if(t===this["featuresNative"+e+"Tracks"]){var n=e.toLowerCase();this[n+"TracksListeners_"]&&Object.keys(this[n+"TracksListeners_"]).forEach(function(e){i.el()[n+"Tracks"].removeEventListener(e,i[n+"TracksListeners_"][e])}),this["featuresNative"+e+"Tracks"]=!t,this[n+"TracksListeners_"]=null,this.proxyNativeTracksForType_(n)}},e.overrideNativeAudioTracks=function(e){this.overrideNative_("Audio",e)},e.overrideNativeVideoTracks=function(e){this.overrideNative_("Video",e)},e.proxyNativeTracksForType_=function(e){var n=this,t=Ln[e],r=this.el()[t.getterName],a=this[t.getterName]();if(this["featuresNative"+t.capitalName+"Tracks"]&&r&&r.addEventListener){function i(){for(var e=[],t=0;t<a.length;t++){for(var i=!1,n=0;n<r.length;n++)if(r[n]===a[t]){i=!0;break}i||e.push(a[t])}for(;e.length;)a.removeTrack(e.shift())}var s={change:function(e){a.trigger({type:"change",target:a,currentTarget:a,srcElement:a})},addtrack:function(e){a.addTrack(e.track)},removetrack:function(e){a.removeTrack(e.track)}};this[t.getterName+"Listeners_"]=s,Object.keys(s).forEach(function(t){var i=s[t];r.addEventListener(t,i),n.on("dispose",function(e){return r.removeEventListener(t,i)})}),this.on("loadstart",i),this.on("dispose",function(e){return n.off("loadstart",i)})}},e.proxyNativeTracks_=function(){var t=this;Ln.names.forEach(function(e){t.proxyNativeTracksForType_(e)})},e.createEl=function(){var e=this.options_.tag;if(!e||!this.options_.playerElIngest&&!this.movingMediaElementInDOM){if(e){var t=e.cloneNode(!0);e.parentNode&&e.parentNode.insertBefore(t,e),o.disposeMediaElement(e),e=t}else{e=h.createElement("video");var i=je({},this.options_.tag&&R(this.options_.tag));ct&&!0===this.options_.nativeControlsForTouch||delete i.controls,D(e,_(i,{id:this.options_.techId,class:"vjs-tech"}))}e.playerId=this.options_.playerId}"undefined"!=typeof this.options_.preload&&B(e,"preload",this.options_.preload);for(var n=["loop","muted","playsinline","autoplay"],r=0;r<n.length;r++){var a=n[r],s=this.options_[a];"undefined"!=typeof s&&(s?B(e,a,a):N(e,a),e[a]=s)}return e},e.handleLateInit_=function(e){if(0!==e.networkState&&3!==e.networkState){if(0===e.readyState){function t(){i=!0}var i=!1;this.on("loadstart",t);function n(){i||this.trigger("loadstart")}return this.on("loadedmetadata",n),void this.ready(function(){this.off("loadstart",t),this.off("loadedmetadata",n),i||this.trigger("loadstart")})}var r=["loadstart"];r.push("loadedmetadata"),2<=e.readyState&&r.push("loadeddata"),3<=e.readyState&&r.push("canplay"),4<=e.readyState&&r.push("canplaythrough"),this.ready(function(){r.forEach(function(e){this.trigger(e)},this)})}},e.setCurrentTime=function(e){try{this.el_.currentTime=e}catch(e){m(e,"Video is not ready. (Video.js)")}},e.duration=function(){var t=this;if(this.el_.duration===1/0&&Ze&&rt&&0===this.el_.currentTime){return this.on("timeupdate",function e(){0<t.el_.currentTime&&(t.el_.duration===1/0&&t.trigger("durationchange"),t.off("timeupdate",e))}),NaN}return this.el_.duration||NaN},e.width=function(){return this.el_.offsetWidth},e.height=function(){return this.el_.offsetHeight},e.proxyWebkitFullscreen_=function(){var e=this;if("webkitDisplayingFullscreen"in this.el_){function t(){this.trigger("fullscreenchange",{isFullscreen:!1})}function i(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",t),this.trigger("fullscreenchange",{isFullscreen:!0}))}this.on("webkitbeginfullscreen",i),this.on("dispose",function(){e.off("webkitbeginfullscreen",i),e.off("webkitendfullscreen",t)})}},e.supportsFullScreen=function(){if("function"==typeof this.el_.webkitEnterFullScreen){var e=v.navigator&&v.navigator.userAgent||"";if(/Android/.test(e)||!/Chrome|Mac OS X 10.5/.test(e))return!0}return!1},e.enterFullScreen=function(){var e=this.el_;e.paused&&e.networkState<=e.HAVE_METADATA?(this.el_.play(),this.setTimeout(function(){e.pause(),e.webkitEnterFullScreen()},0)):e.webkitEnterFullScreen()},e.exitFullScreen=function(){this.el_.webkitExitFullScreen()},e.requestPictureInPicture=function(){return this.el_.requestPictureInPicture()},e.src=function(e){if(void 0===e)return this.el_.src;this.setSrc(e)},e.reset=function(){o.resetMediaElement(this.el_)},e.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc},e.setControls=function(e){this.el_.controls=!!e},e.addTextTrack=function(e,t,i){return this.featuresNativeTextTracks?this.el_.addTextTrack(e,t,i):c.prototype.addTextTrack.call(this,e,t,i)},e.createRemoteTextTrack=function(e){if(!this.featuresNativeTextTracks)return c.prototype.createRemoteTextTrack.call(this,e);var t=h.createElement("track");return e.kind&&(t.kind=e.kind),e.label&&(t.label=e.label),(e.language||e.srclang)&&(t.srclang=e.language||e.srclang),e.default&&(t.default=e.default),e.id&&(t.id=e.id),e.src&&(t.src=e.src),t},e.addRemoteTextTrack=function(e,t){var i=c.prototype.addRemoteTextTrack.call(this,e,t);return this.featuresNativeTextTracks&&this.el().appendChild(i),i},e.removeRemoteTextTrack=function(e){if(c.prototype.removeRemoteTextTrack.call(this,e),this.featuresNativeTextTracks)for(var t=this.$$("track"),i=t.length;i--;)e!==t[i]&&e!==t[i].track||this.el().removeChild(t[i])},e.getVideoPlaybackQuality=function(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();var e={};return"undefined"!=typeof this.el().webkitDroppedFrameCount&&"undefined"!=typeof this.el().webkitDecodedFrameCount&&(e.droppedVideoFrames=this.el().webkitDroppedFrameCount,e.totalVideoFrames=this.el().webkitDecodedFrameCount),v.performance&&"function"==typeof v.performance.now?e.creationTime=v.performance.now():v.performance&&v.performance.timing&&"number"==typeof v.performance.timing.navigationStart&&(e.creationTime=v.Date.now()-v.performance.timing.navigationStart),e},o}(or);if(k()){Ja.TEST_VID=h.createElement("video");var Za=h.createElement("track");Za.kind="captions",Za.srclang="en",Za.label="English",Ja.TEST_VID.appendChild(Za)}Ja.isSupported=function(){try{Ja.TEST_VID.volume=.5}catch(e){return!1}return!(!Ja.TEST_VID||!Ja.TEST_VID.canPlayType)},Ja.canPlayType=function(e){return Ja.TEST_VID.canPlayType(e)},Ja.canPlaySource=function(e,t){return Ja.canPlayType(e.type)},Ja.canControlVolume=function(){try{var e=Ja.TEST_VID.volume;return Ja.TEST_VID.volume=e/2+.1,e!==Ja.TEST_VID.volume}catch(e){return!1}},Ja.canMuteVolume=function(){try{var e=Ja.TEST_VID.muted;return Ja.TEST_VID.muted=!e,Ja.TEST_VID.muted?B(Ja.TEST_VID,"muted","muted"):N(Ja.TEST_VID,"muted"),e!==Ja.TEST_VID.muted}catch(e){return!1}},Ja.canControlPlaybackRate=function(){if(Ze&&rt&&at<58)return!1;try{var e=Ja.TEST_VID.playbackRate;return Ja.TEST_VID.playbackRate=e/2+.1,e!==Ja.TEST_VID.playbackRate}catch(e){return!1}},Ja.canOverrideAttributes=function(){try{function e(){}Object.defineProperty(h.createElement("video"),"src",{get:e,set:e}),Object.defineProperty(h.createElement("audio"),"src",{get:e,set:e}),Object.defineProperty(h.createElement("video"),"innerHTML",{get:e,set:e}),Object.defineProperty(h.createElement("audio"),"innerHTML",{get:e,set:e})}catch(e){return!1}return!0},Ja.supportsNativeTextTracks=function(){return ut||Qe&&rt},Ja.supportsNativeVideoTracks=function(){return!(!Ja.TEST_VID||!Ja.TEST_VID.videoTracks)},Ja.supportsNativeAudioTracks=function(){return!(!Ja.TEST_VID||!Ja.TEST_VID.audioTracks)},Ja.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],Ja.prototype.featuresVolumeControl=Ja.canControlVolume(),Ja.prototype.featuresMuteControl=Ja.canMuteVolume(),Ja.prototype.featuresPlaybackRate=Ja.canControlPlaybackRate(),Ja.prototype.featuresSourceset=Ja.canOverrideAttributes(),Ja.prototype.movingMediaElementInDOM=!Qe,Ja.prototype.featuresFullscreenResize=!0,Ja.prototype.featuresProgressEvents=!0,Ja.prototype.featuresTimeupdateEvents=!0,Ja.prototype.featuresNativeTextTracks=Ja.supportsNativeTextTracks(),Ja.prototype.featuresNativeVideoTracks=Ja.supportsNativeVideoTracks(),Ja.prototype.featuresNativeAudioTracks=Ja.supportsNativeAudioTracks();var es=Ja.TEST_VID&&Ja.TEST_VID.constructor.prototype.canPlayType,ts=/^application\/(?:x-|vnd\.apple\.)mpegurl/i;function is(){var e=t(["\n Using the tech directly can be dangerous. I hope you know what you're doing.\n See https://github.com/videojs/video.js/issues/2617 for more info.\n "]);return is=function(){return e},e}Ja.patchCanPlayType=function(){4<=et&&!it&&!rt&&(Ja.TEST_VID.constructor.prototype.canPlayType=function(e){return e&&ts.test(e)?"maybe":es.call(this,e)})},Ja.unpatchCanPlayType=function(){var e=Ja.TEST_VID.constructor.prototype.canPlayType;return Ja.TEST_VID.constructor.prototype.canPlayType=es,e},Ja.patchCanPlayType(),Ja.disposeMediaElement=function(e){if(e){for(e.parentNode&&e.parentNode.removeChild(e);e.hasChildNodes();)e.removeChild(e.firstChild);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},Ja.resetMediaElement=function(e){if(e){for(var t=e.querySelectorAll("source"),i=t.length;i--;)e.removeChild(t[i]);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach(function(e){Ja.prototype[e]=function(){return this.el_[e]||this.el_.hasAttribute(e)}}),["muted","defaultMuted","autoplay","loop","playsinline"].forEach(function(t){Ja.prototype["set"+Ne(t)]=function(e){(this.el_[t]=e)?this.el_.setAttribute(t,t):this.el_.removeAttribute(t)}}),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","played","networkState","readyState","videoWidth","videoHeight"].forEach(function(e){Ja.prototype[e]=function(){return this.el_[e]}}),["volume","src","poster","preload","playbackRate","defaultPlaybackRate"].forEach(function(t){Ja.prototype["set"+Ne(t)]=function(e){this.el_[t]=e}}),["pause","load","play"].forEach(function(e){Ja.prototype[e]=function(){return this.el_[e]()}}),or.withSourceHandlers(Ja),Ja.nativeSourceHandler={},Ja.nativeSourceHandler.canPlayType=function(e){try{return Ja.TEST_VID.canPlayType(e)}catch(e){return""}},Ja.nativeSourceHandler.canHandleSource=function(e,t){if(e.type)return Ja.nativeSourceHandler.canPlayType(e.type);if(e.src){var i=Ft(e.src);return Ja.nativeSourceHandler.canPlayType("video/"+i)}return""},Ja.nativeSourceHandler.handleSource=function(e,t,i){t.setSrc(e.src)},Ja.nativeSourceHandler.dispose=function(){},Ja.registerSourceHandler(Ja.nativeSourceHandler),or.registerTech("Html5",Ja);var ns=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],rs={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},as=["tiny","xsmall","small","medium","large","xlarge","huge"],ss={};as.forEach(function(e){var t="x"===e.charAt(0)?"x-"+e.substring(1):e;ss[e]="vjs-layout-"+t});var os={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0},us=function(c){function l(e,t,i){var n;if(e.id=e.id||t.id||"vjs_video_"+ee(),(t=_(l.getTagSettings(e),t)).initChildren=!1,t.createEl=!1,t.evented=!1,t.reportTouchActivity=!1,!t.language)if("function"==typeof e.closest){var r=e.closest("[lang]");r&&r.getAttribute&&(t.language=r.getAttribute("lang"))}else for(var a=e;a&&1===a.nodeType;){if(R(a).hasOwnProperty("lang")){t.language=a.getAttribute("lang");break}a=a.parentNode}if((n=c.call(this,null,t,i)||this).boundDocumentFullscreenChange_=ke(f(n),n.documentFullscreenChange_),n.boundFullWindowOnEscKey_=ke(f(n),n.fullWindowOnEscKey),n.log=g(n.id_),n.fsApi_=yt,n.isPosterFromTech_=!1,n.queuedCallbacks_=[],n.isReady_=!1,n.hasStarted_=!1,n.userActive_=!1,!n.options_||!n.options_.techOrder||!n.options_.techOrder.length)throw new Error("No techOrder specified. Did you overwrite videojs.options instead of just changing the properties you want to override?");if(n.tag=e,n.tagAttributes=e&&R(e),n.language(n.options_.language),t.languages){var s={};Object.getOwnPropertyNames(t.languages).forEach(function(e){s[e.toLowerCase()]=t.languages[e]}),n.languages_=s}else n.languages_=l.prototype.options_.languages;n.resetCache_(),n.poster_=t.poster||"",n.controls_=!!t.controls,e.controls=!1,e.removeAttribute("controls"),n.changingSrc_=!1,n.playCallbacks_=[],n.playTerminatedQueue_=[],e.hasAttribute("autoplay")?n.autoplay(!0):n.autoplay(n.options_.autoplay),t.plugins&&Object.keys(t.plugins).forEach(function(e){if("function"!=typeof n[e])throw new Error('plugin "'+e+'" does not exist')}),n.scrubbing_=!1,n.el_=n.createEl(),Re(f(n),{eventBusKey:"el_"}),n.fluid_&&n.on("playerreset",n.updateStyleEl_);var o=je(n.options_);t.plugins&&Object.keys(t.plugins).forEach(function(e){n[e](t.plugins[e])}),n.options_.playerOptions=o,n.middleware_=[],n.initChildren(),n.isAudio("audio"===e.nodeName.toLowerCase()),n.controls()?n.addClass("vjs-controls-enabled"):n.addClass("vjs-controls-disabled"),n.el_.setAttribute("role","region"),n.isAudio()?n.el_.setAttribute("aria-label",n.localize("Audio Player")):n.el_.setAttribute("aria-label",n.localize("Video Player")),n.isAudio()&&n.addClass("vjs-audio"),n.flexNotSupported_()&&n.addClass("vjs-no-flex"),ct&&n.addClass("vjs-touch-enabled"),Qe||n.addClass("vjs-workinghover"),l.players[n.id_]=f(n);var u=d.split(".")[0];return n.addClass("vjs-v"+u),n.userActive(!0),n.reportUserActivity(),n.one("play",n.listenForUserActivity_),n.on("stageclick",n.handleStageClick_),n.on("keydown",n.handleKeyDown),n.breakpoints(n.options_.breakpoints),n.responsive(n.options_.responsive),n}p(l,c);var e=l.prototype;return e.dispose=function(){var n=this;this.trigger("dispose"),this.off("dispose"),de(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),de(h,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),l.players[this.id_]=null,this.tag&&this.tag.player&&(this.tag.player=null),this.el_&&this.el_.player&&(this.el_.player=null),this.tech_&&(this.tech_.dispose(),this.isPosterFromTech_=!1,this.poster_=""),this.playerElIngest_&&(this.playerElIngest_=null),this.tag&&(this.tag=null),function(e){lr[e.id()]=null}(this),On.names.forEach(function(e){var t=On[e],i=n[t.getterName]();i&&i.off&&i.off()}),c.prototype.dispose.call(this)},e.createEl=function(){var t,i=this.tag,e=this.playerElIngest_=i.parentNode&&i.parentNode.hasAttribute&&i.parentNode.hasAttribute("data-vjs-player"),n="video-js"===this.tag.tagName.toLowerCase();e?t=this.el_=i.parentNode:n||(t=this.el_=c.prototype.createEl.call(this,"div"));var r=R(i);if(n){for(t=this.el_=i,i=this.tag=h.createElement("video");t.children.length;)i.appendChild(t.firstChild);I(t,"video-js")||O(t,"video-js"),t.appendChild(i),e=this.playerElIngest_=t,Object.keys(t).forEach(function(e){i[e]=t[e]})}if(i.setAttribute("tabindex","-1"),r.tabindex="-1",(st||rt&&lt)&&(i.setAttribute("role","application"),r.role="application"),i.removeAttribute("width"),i.removeAttribute("height"),"width"in r&&delete r.width,"height"in r&&delete r.height,Object.getOwnPropertyNames(r).forEach(function(e){n&&"class"===e||t.setAttribute(e,r[e]),n&&i.setAttribute(e,r[e])}),i.playerId=i.id,i.id+="_html5_api",i.className="vjs-tech",i.player=t.player=this,this.addClass("vjs-paused"),!0!==v.VIDEOJS_NO_DYNAMIC_STYLE){this.styleEl_=Te("vjs-styles-dimensions");var a=Y(".vjs-styles-defaults"),s=Y("head");s.insertBefore(this.styleEl_,a?a.nextSibling:s.firstChild)}this.fill_=!1,this.fluid_=!1,this.width(this.options_.width),this.height(this.options_.height),this.fill(this.options_.fill),this.fluid(this.options_.fluid),this.aspectRatio(this.options_.aspectRatio);for(var o=i.getElementsByTagName("a"),u=0;u<o.length;u++){var l=o.item(u);O(l,"vjs-hidden"),l.setAttribute("hidden","hidden")}return i.initNetworkState_=i.networkState,i.parentNode&&!e&&i.parentNode.insertBefore(t,i),L(i,t),this.children_.unshift(i),this.el_.setAttribute("lang",this.language_),this.el_=t},e.width=function(e){return this.dimension("width",e)},e.height=function(e){return this.dimension("height",e)},e.dimension=function(e,t){var i=e+"_";if(void 0===t)return this[i]||0;if(""===t)return this[i]=void 0,void this.updateStyleEl_();var n=parseFloat(t);isNaN(n)?m.error('Improper value "'+t+'" supplied for for '+e):(this[i]=n,this.updateStyleEl_())},e.fluid=function(e){if(void 0===e)return!!this.fluid_;this.fluid_=!!e,Ue(this)&&this.off("playerreset",this.updateStyleEl_),e?(this.addClass("vjs-fluid"),this.fill(!1),function(e,t){Ue(e)?t():(e.eventedCallbacks||(e.eventedCallbacks=[]),e.eventedCallbacks.push(t))}(function(){this.on("playerreset",this.updateStyleEl_)})):this.removeClass("vjs-fluid"),this.updateStyleEl_()},e.fill=function(e){if(void 0===e)return!!this.fill_;this.fill_=!!e,e?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")},e.aspectRatio=function(e){if(void 0===e)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(e))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=e,this.fluid(!0),this.updateStyleEl_()},e.updateStyleEl_=function(){if(!0!==v.VIDEOJS_NO_DYNAMIC_STYLE){var e,t,i,n=(void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:0<this.videoWidth()?this.videoWidth()+":"+this.videoHeight():"16:9").split(":"),r=n[1]/n[0];e=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/r:this.videoWidth()||300,t=void 0!==this.height_?this.height_:e*r,i=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(i),Se(this.styleEl_,"\n ."+i+" {\n width: "+e+"px;\n height: "+t+"px;\n }\n\n ."+i+".vjs-fluid {\n padding-top: "+100*r+"%;\n }\n ")}else{var a="number"==typeof this.width_?this.width_:this.options_.width,s="number"==typeof this.height_?this.height_:this.options_.height,o=this.tech_&&this.tech_.el();o&&(0<=a&&(o.width=a),0<=s&&(o.height=s))}},e.loadTech_=function(e,t){var i=this;this.tech_&&this.unloadTech_();var n=Ne(e),r=e.charAt(0).toLowerCase()+e.slice(1);"Html5"!==n&&this.tag&&(or.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=n,this.isReady_=!1;var a={source:t,autoplay:"string"!=typeof this.autoplay()&&this.autoplay(),nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:this.id()+"_"+r+"_api",playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,muted:this.options_.muted,poster:this.poster(),language:this.language(),playerElIngest:this.playerElIngest_||!1,"vtt.js":this.options_["vtt.js"],canOverridePoster:!!this.options_.techCanOverridePoster,enableSourceset:this.options_.enableSourceset,Promise:this.options_.Promise};On.names.forEach(function(e){var t=On[e];a[t.getterName]=i[t.privateName]}),_(a,this.options_[n]),_(a,this.options_[r]),_(a,this.options_[e.toLowerCase()]),this.tag&&(a.tag=this.tag),t&&t.src===this.cache_.src&&0<this.cache_.currentTime&&(a.startTime=this.cache_.currentTime);var s=or.getTech(e);if(!s)throw new Error("No Tech named '"+n+"' exists! '"+n+"' should be registered using videojs.registerTech()'");this.tech_=new s(a),this.tech_.ready(ke(this,this.handleTechReady_),!0),Lt(this.textTracksJson_||[],this.tech_),ns.forEach(function(e){i.on(i.tech_,e,i["handleTech"+Ne(e)+"_"])}),Object.keys(rs).forEach(function(t){i.on(i.tech_,t,function(e){0===i.tech_.playbackRate()&&i.tech_.seeking()?i.queuedCallbacks_.push({callback:i["handleTech"+rs[t]+"_"].bind(i),event:e}):i["handleTech"+rs[t]+"_"](e)})}),this.on(this.tech_,"loadstart",this.handleTechLoadStart_),this.on(this.tech_,"sourceset",this.handleTechSourceset_),this.on(this.tech_,"waiting",this.handleTechWaiting_),this.on(this.tech_,"ended",this.handleTechEnded_),this.on(this.tech_,"seeking",this.handleTechSeeking_),this.on(this.tech_,"play",this.handleTechPlay_),this.on(this.tech_,"firstplay",this.handleTechFirstPlay_),this.on(this.tech_,"pause",this.handleTechPause_),this.on(this.tech_,"durationchange",this.handleTechDurationChange_),this.on(this.tech_,"fullscreenchange",this.handleTechFullscreenChange_),this.on(this.tech_,"enterpictureinpicture",this.handleTechEnterPictureInPicture_),this.on(this.tech_,"leavepictureinpicture",this.handleTechLeavePictureInPicture_),this.on(this.tech_,"error",this.handleTechError_),this.on(this.tech_,"loadedmetadata",this.updateStyleEl_),this.on(this.tech_,"posterchange",this.handleTechPosterChange_),this.on(this.tech_,"textdata",this.handleTechTextData_),this.on(this.tech_,"ratechange",this.handleTechRateChange_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===n&&this.tag||L(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)},e.unloadTech_=function(){var i=this;On.names.forEach(function(e){var t=On[e];i[t.privateName]=i[t.getterName]()}),this.textTracksJson_=Pt(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1},e.tech=function(e){return void 0===e&&m.warn(y(is())),this.tech_},e.addTechControlsListeners_=function(){this.removeTechControlsListeners_(),this.on(this.tech_,"mouseup",this.handleTechClick_),this.on(this.tech_,"dblclick",this.handleTechDoubleClick_),this.on(this.tech_,"touchstart",this.handleTechTouchStart_),this.on(this.tech_,"touchmove",this.handleTechTouchMove_),this.on(this.tech_,"touchend",this.handleTechTouchEnd_),this.on(this.tech_,"tap",this.handleTechTap_)},e.removeTechControlsListeners_=function(){this.off(this.tech_,"tap",this.handleTechTap_),this.off(this.tech_,"touchstart",this.handleTechTouchStart_),this.off(this.tech_,"touchmove",this.handleTechTouchMove_),this.off(this.tech_,"touchend",this.handleTechTouchEnd_),this.off(this.tech_,"mouseup",this.handleTechClick_),this.off(this.tech_,"dblclick",this.handleTechDoubleClick_)},e.handleTechReady_=function(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()},e.handleTechLoadStart_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):(this.trigger("loadstart"),this.trigger("firstplay")),this.manualAutoplay_(this.autoplay())},e.manualAutoplay_=function(t){var n=this;if(this.tech_&&"string"==typeof t){function e(){var e=n.muted();n.muted(!0);function t(){n.muted(e)}n.playTerminatedQueue_.push(t);var i=n.play();if(Ct(i))return i.catch(t)}var i;if("any"===t&&!0!==this.muted()?Ct(i=this.play())&&(i=i.catch(e)):i="muted"===t&&!0!==this.muted()?e():this.play(),Ct(i))return i.then(function(){n.trigger({type:"autoplay-success",autoplay:t})}).catch(function(e){n.trigger({type:"autoplay-failure",autoplay:t})})}},e.updateSourceCaches_=function(e){void 0===e&&(e="");var t=e,i="";"string"!=typeof t&&(t=e.src,i=e.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],t&&!i&&(i=function(e,t){if(!t)return"";if(e.cache_.source.src===t&&e.cache_.source.type)return e.cache_.source.type;var i=e.cache_.sources.filter(function(e){return e.src===t});if(i.length)return i[0].type;for(var n=e.$$("source"),r=0;r<n.length;r++){var a=n[r];if(a.type&&a.src&&a.src===t)return a.type}return vr(t)}(this,t)),this.cache_.source=je({},e,{src:t,type:i});for(var n=this.cache_.sources.filter(function(e){return e.src&&e.src===t}),r=[],a=this.$$("source"),s=[],o=0;o<a.length;o++){var u=R(a[o]);r.push(u),u.src&&u.src===t&&s.push(u.src)}s.length&&!n.length?this.cache_.sources=r:n.length||(this.cache_.sources=[this.cache_.source]),this.cache_.src=t},e.handleTechSourceset_=function(e){var n=this;if(!this.changingSrc_){var t=function(e){return n.updateSourceCaches_(e)},i=this.currentSource().src,r=e.src;if(i&&!/^blob:/.test(i)&&/^blob:/.test(r)&&(this.lastSource_&&(this.lastSource_.tech===r||this.lastSource_.player===i)||(t=function(){})),t(r),!e.src){this.tech_.one(["sourceset","loadstart"],function e(t){if("sourceset"!==t.type){var i=n.techGet("currentSrc");n.lastSource_.tech=i,n.updateSourceCaches_(i)}n.tech_.off(["sourceset","loadstart"],e)})}}this.lastSource_={player:this.currentSource().src,tech:e.src},this.trigger({src:e.src,type:"sourceset"})},e.hasStarted=function(e){if(void 0===e)return this.hasStarted_;e!==this.hasStarted_&&(this.hasStarted_=e,this.hasStarted_?(this.addClass("vjs-has-started"),this.trigger("firstplay")):this.removeClass("vjs-has-started"))},e.handleTechPlay_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")},e.handleTechRateChange_=function(){0<this.tech_.playbackRate()&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach(function(e){return e.callback(e.event)}),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")},e.handleTechWaiting_=function(){var t=this;this.addClass("vjs-waiting"),this.trigger("waiting");var i=this.currentTime();this.on("timeupdate",function e(){i!==t.currentTime()&&(t.removeClass("vjs-waiting"),t.off("timeupdate",e))})},e.handleTechCanPlay_=function(){this.removeClass("vjs-waiting"),this.trigger("canplay")},e.handleTechCanPlayThrough_=function(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")},e.handleTechPlaying_=function(){this.removeClass("vjs-waiting"),this.trigger("playing")},e.handleTechSeeking_=function(){this.addClass("vjs-seeking"),this.trigger("seeking")},e.handleTechSeeked_=function(){this.removeClass("vjs-seeking"),this.removeClass("vjs-ended"),this.trigger("seeked")},e.handleTechFirstPlay_=function(){this.options_.starttime&&(m.warn("Passing the `starttime` option to the player will be deprecated in 6.0"),this.currentTime(this.options_.starttime)),this.addClass("vjs-has-started"),this.trigger("firstplay")},e.handleTechPause_=function(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")},e.handleTechEnded_=function(){this.addClass("vjs-ended"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")},e.handleTechDurationChange_=function(){this.duration(this.techGet_("duration"))},e.handleTechClick_=function(e){K(e)&&this.controls_&&(this.paused()?Et(this.play()):this.pause())},e.handleTechDoubleClick_=function(t){this.controls_&&(Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),function(e){return e.contains(t.target)})||void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.doubleClick&&!1===this.options_.userActions.doubleClick||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.doubleClick?this.options_.userActions.doubleClick.call(this,t):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen()))},e.handleTechTap_=function(){this.userActive(!this.userActive())},e.handleTechTouchStart_=function(){this.userWasActive=this.userActive()},e.handleTechTouchMove_=function(){this.userWasActive&&this.reportUserActivity()},e.handleTechTouchEnd_=function(e){e.preventDefault()},e.handleStageClick_=function(){this.reportUserActivity()},e.toggleFullscreenClass_=function(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")},e.documentFullscreenChange_=function(e){var t=this.el(),i=h[this.fsApi_.fullscreenElement]===t;!i&&t.matches?i=t.matches(":"+this.fsApi_.fullscreen):!i&&t.msMatchesSelector&&(i=t.msMatchesSelector(":"+this.fsApi_.fullscreen)),this.isFullscreen(i),!1===this.isFullscreen()&&de(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.fsApi_.prefixed&&this.trigger("fullscreenchange")},e.handleTechFullscreenChange_=function(e,t){t&&this.isFullscreen(t.isFullscreen),this.trigger("fullscreenchange")},e.togglePictureInPictureClass_=function(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")},e.handleTechEnterPictureInPicture_=function(e){this.isInPictureInPicture(!0)},e.handleTechLeavePictureInPicture_=function(e){this.isInPictureInPicture(!1)},e.handleTechError_=function(){var e=this.tech_.error();this.error(e)},e.handleTechTextData_=function(e,t){var i=null;1<arguments.length&&(i=t),this.trigger("textdata",i)},e.getCache=function(){return this.cache_},e.resetCache_=function(){this.cache_={currentTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],volume:1}},e.techCall_=function(e,t){this.ready(function(){if(e in fr)return function(e,t,i,n){return t[i](e.reduce(gr(i),n))}(this.middleware_,this.tech_,e,t);if(e in mr)return dr(this.middleware_,this.tech_,e,t);try{this.tech_&&this.tech_[e](t)}catch(e){throw m(e),e}},!0)},e.techGet_=function(t){if(this.tech_&&this.tech_.isReady_){if(t in pr)return function(e,t,i){return e.reduceRight(gr(i),t[i]())}(this.middleware_,this.tech_,t);if(t in mr)return dr(this.middleware_,this.tech_,t);try{return this.tech_[t]()}catch(e){if(void 0===this.tech_[t])throw m("Video.js: "+t+" method not defined for "+this.techName_+" playback technology.",e),e;if("TypeError"===e.name)throw m("Video.js: "+t+" unavailable on "+this.techName_+" playback technology element.",e),this.tech_.isReady_=!1,e;throw m(e),e}}},e.play=function(){var t=this,e=this.options_.Promise||v.Promise;return e?new e(function(e){t.play_(e)}):this.play_()},e.play_=function(e){var t=this;void 0===e&&(e=Et),this.playCallbacks_.push(e);var i=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc()));if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!i)return this.waitToPlay_=function(e){t.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(i||!ut&&!Qe||this.load());var n=this.techGet_("play");null===n?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(n)},e.runPlayTerminatedQueue_=function(){var e=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],e.forEach(function(e){e()})},e.runPlayCallbacks_=function(t){var e=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],e.forEach(function(e){e(t)})},e.pause=function(){this.techCall_("pause")},e.paused=function(){return!1!==this.techGet_("paused")},e.played=function(){return this.techGet_("played")||ft(0,0)},e.scrubbing=function(e){if("undefined"==typeof e)return this.scrubbing_;this.scrubbing_=!!e,e?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")},e.currentTime=function(e){return"undefined"!=typeof e?(e<0&&(e=0),void this.techCall_("setCurrentTime",e)):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)},e.duration=function(e){if(void 0===e)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(e=parseFloat(e))<0&&(e=1/0),e!==this.cache_.duration&&((this.cache_.duration=e)===1/0?(this.addClass("vjs-live"),this.options_.liveui&&this.player_.liveTracker&&this.addClass("vjs-liveui")):(this.removeClass("vjs-live"),this.removeClass("vjs-liveui")),isNaN(e)||this.trigger("durationchange"))},e.remainingTime=function(){return this.duration()-this.currentTime()},e.remainingTimeDisplay=function(){return Math.floor(this.duration())-Math.floor(this.currentTime())},e.buffered=function(){var e=this.techGet_("buffered");return e&&e.length||(e=ft(0,0)),e},e.bufferedPercent=function(){return mt(this.buffered(),this.duration())},e.bufferedEnd=function(){var e=this.buffered(),t=this.duration(),i=e.end(e.length-1);return t<i&&(i=t),i},e.volume=function(e){var t;return void 0!==e?(t=Math.max(0,Math.min(1,parseFloat(e))),this.cache_.volume=t,this.techCall_("setVolume",t),void(0<t&&this.lastVolume_(t))):(t=parseFloat(this.techGet_("volume")),isNaN(t)?1:t)},e.muted=function(e){if(void 0===e)return this.techGet_("muted")||!1;this.techCall_("setMuted",e)},e.defaultMuted=function(e){return void 0!==e?this.techCall_("setDefaultMuted",e):this.techGet_("defaultMuted")||!1},e.lastVolume_=function(e){if(void 0===e||0===e)return this.cache_.lastVolume;this.cache_.lastVolume=e},e.supportsFullScreen=function(){return this.techGet_("supportsFullScreen")||!1},e.isFullscreen=function(e){return void 0!==e?(this.isFullscreen_=!!e,void this.toggleFullscreenClass_()):!!this.isFullscreen_},e.requestFullscreen=function(e){var t;this.isFullscreen(!0),this.fsApi_.requestFullscreen?(he(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.fsApi_.prefixed||(t=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==e&&(t=e)),Et(this.el_[this.fsApi_.requestFullscreen](t))):this.tech_.supportsFullScreen()?this.techCall_("enterFullScreen"):(this.enterFullWindow(),this.trigger("fullscreenchange"))},e.exitFullscreen=function(){this.isFullscreen(!1),this.fsApi_.requestFullscreen?Et(h[this.fsApi_.exitFullscreen]()):this.tech_.supportsFullScreen()?this.techCall_("exitFullScreen"):(this.exitFullWindow(),this.trigger("fullscreenchange"))},e.enterFullWindow=function(){this.isFullWindow=!0,this.docOrigOverflow=h.documentElement.style.overflow,he(h,"keydown",this.boundFullWindowOnEscKey_),h.documentElement.style.overflow="hidden",O(h.body,"vjs-full-window"),this.trigger("enterFullWindow")},e.fullWindowOnEscKey=function(e){Ot.isEventKey(e,"Esc")&&(!0===this.isFullscreen()?this.exitFullscreen():this.exitFullWindow())},e.exitFullWindow=function(){this.isFullWindow=!1,de(h,"keydown",this.boundFullWindowOnEscKey_),h.documentElement.style.overflow=this.docOrigOverflow,x(h.body,"vjs-full-window"),this.trigger("exitFullWindow")},e.isInPictureInPicture=function(e){return void 0!==e?(this.isInPictureInPicture_=!!e,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_},e.requestPictureInPicture=function(){if("pictureInPictureEnabled"in h)return this.techGet_("requestPictureInPicture")},e.exitPictureInPicture=function(){if("pictureInPictureEnabled"in h)return h.exitPictureInPicture()},e.handleKeyDown=function(e){var t=this.options_.userActions;if(t&&t.hotkeys){var i,n;if(i=this.el_.ownerDocument.activeElement,"input"===(n=i.tagName.toLowerCase())?-1!==["button","checkbox","hidden","radio","reset","submit"].indexOf(i.type):-1===["textarea"].indexOf(n))"function"==typeof t.hotkeys?t.hotkeys.call(this,e):this.handleHotkeys(e)}},e.handleHotkeys=function(e){var t=this.options_.userActions?this.options_.userActions.hotkeys:{},i=t.fullscreenKey,n=void 0===i?function(e){return Ot.isEventKey(e,"f")}:i,r=t.muteKey,a=void 0===r?function(e){return Ot.isEventKey(e,"m")}:r,s=t.playPauseKey,o=void 0===s?function(e){return Ot.isEventKey(e,"k")||Ot.isEventKey(e,"Space")}:s;if(n.call(this,e)){e.preventDefault(),e.stopPropagation();var u=Fe.getComponent("FullscreenToggle");!1!==h[this.fsApi_.fullscreenEnabled]&&u.prototype.handleClick.call(this,e)}else if(a.call(this,e)){e.preventDefault(),e.stopPropagation(),Fe.getComponent("MuteToggle").prototype.handleClick.call(this,e)}else if(o.call(this,e)){e.preventDefault(),e.stopPropagation(),Fe.getComponent("PlayToggle").prototype.handleClick.call(this,e)}},e.canPlayType=function(e){for(var t,i=0,n=this.options_.techOrder;i<n.length;i++){var r=n[i],a=or.getTech(r);if(a=a||Fe.getComponent(r)){if(a.isSupported()&&(t=a.canPlayType(e)))return t}else m.error('The "'+r+'" tech is undefined. Skipped browser support check for that tech.')}return""},e.selectSource=function(e){function t(e,i,n){var r;return e.some(function(t){return i.some(function(e){if(r=n(t,e))return!0})}),r}function i(e,t){var i=e[0];if(e[1].canPlaySource(t,r.options_[i.toLowerCase()]))return{source:t,tech:i}}var n,r=this,a=this.options_.techOrder.map(function(e){return[e,or.getTech(e)]}).filter(function(e){var t=e[0],i=e[1];return i?i.isSupported():(m.error('The "'+t+'" tech is undefined. Skipped browser support check for that tech.'),!1)});return(this.options_.sourceOrder?t(e,a,(n=i,function(e,t){return n(t,e)})):t(a,e,i))||!1},e.src=function(e){var i=this;if("undefined"==typeof e)return this.cache_.src||"";var n=function t(e){if(Array.isArray(e)){var i=[];e.forEach(function(e){e=t(e),Array.isArray(e)?i=i.concat(e):b(e)&&i.push(e)}),e=i}else e="string"==typeof e&&e.trim()?[br({src:e})]:b(e)&&"string"==typeof e.src&&e.src&&e.src.trim()?[br(e)]:[];return e}(e);n.length?(this.changingSrc_=!0,this.cache_.sources=n,this.updateSourceCaches_(n[0]),hr(this,n[0],function(e,t){if(i.middleware_=t,i.cache_.sources=n,i.updateSourceCaches_(e),i.src_(e))return 1<n.length?i.src(n.slice(1)):(i.changingSrc_=!1,i.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0),void i.triggerReady());!function(e,t){e.forEach(function(e){return e.setTech&&e.setTech(t)})}(t,i.tech_)})):this.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0)},e.src_=function(e){var t=this,i=this.selectSource([e]);return!i||(function(e,t){return Ne(e)===Ne(t)}(i.tech,this.techName_)?this.ready(function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",e):this.techCall_("src",e.src),this.changingSrc_=!1},!0):(this.changingSrc_=!0,this.loadTech_(i.tech,i.source),this.tech_.ready(function(){t.changingSrc_=!1})),!1)},e.load=function(){this.techCall_("load")},e.reset=function(){var e=this,t=this.options_.Promise||v.Promise;this.paused()||!t?this.doReset_():Et(this.play().then(function(){return e.doReset_()}))},e.doReset_=function(){this.tech_&&this.tech_.clearTracks("text"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),Ue(this)&&this.trigger("playerreset")},e.resetControlBarUI_=function(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()},e.resetProgressBar_=function(){this.currentTime(0);var e=this.controlBar,t=e.durationDisplay,i=e.remainingTimeDisplay;t&&t.updateContent(),i&&i.updateContent()},e.resetPlaybackRate_=function(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()},e.resetVolumeBar_=function(){this.volume(1),this.trigger("volumechange")},e.currentSources=function(){var e=this.currentSource(),t=[];return 0!==Object.keys(e).length&&t.push(e),this.cache_.sources||t},e.currentSource=function(){return this.cache_.source||{}},e.currentSrc=function(){return this.currentSource()&&this.currentSource().src||""},e.currentType=function(){return this.currentSource()&&this.currentSource().type||""},e.preload=function(e){return void 0!==e?(this.techCall_("setPreload",e),void(this.options_.preload=e)):this.techGet_("preload")},e.autoplay=function(e){if(void 0===e)return this.options_.autoplay||!1;var t;"string"==typeof e&&/(any|play|muted)/.test(e)?(this.options_.autoplay=e,this.manualAutoplay_(e),t=!1):this.options_.autoplay=!!e,t="undefined"==typeof t?this.options_.autoplay:t,this.tech_&&this.techCall_("setAutoplay",t)},e.playsinline=function(e){return void 0!==e?(this.techCall_("setPlaysinline",e),this.options_.playsinline=e,this):this.techGet_("playsinline")},e.loop=function(e){return void 0!==e?(this.techCall_("setLoop",e),void(this.options_.loop=e)):this.techGet_("loop")},e.poster=function(e){if(void 0===e)return this.poster_;(e=e||"")!==this.poster_&&(this.poster_=e,this.techCall_("setPoster",e),this.isPosterFromTech_=!1,this.trigger("posterchange"))},e.handleTechPosterChange_=function(){if((!this.poster_||this.options_.techCanOverridePoster)&&this.tech_&&this.tech_.poster){var e=this.tech_.poster()||"";e!==this.poster_&&(this.poster_=e,this.isPosterFromTech_=!0,this.trigger("posterchange"))}},e.controls=function(e){if(void 0===e)return!!this.controls_;e=!!e,this.controls_!==e&&(this.controls_=e,this.usingNativeControls()&&this.techCall_("setControls",e),this.controls_?(this.removeClass("vjs-controls-disabled"),this.addClass("vjs-controls-enabled"),this.trigger("controlsenabled"),this.usingNativeControls()||this.addTechControlsListeners_()):(this.removeClass("vjs-controls-enabled"),this.addClass("vjs-controls-disabled"),this.trigger("controlsdisabled"),this.usingNativeControls()||this.removeTechControlsListeners_()))},e.usingNativeControls=function(e){if(void 0===e)return!!this.usingNativeControls_;e=!!e,this.usingNativeControls_!==e&&(this.usingNativeControls_=e,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))},e.error=function(e){if(void 0===e)return this.error_||null;if(this.options_.suppressNotSupportedError&&e&&e.message&&e.message===this.localize(this.options_.notSupportedMessage)){function t(){this.error(e)}return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],t),void this.one("loadstart",function(){this.off(["click","touchstart"],t)})}if(null===e)return this.error_=e,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new St(e),this.addClass("vjs-error"),m.error("(CODE:"+this.error_.code+" "+St.errorTypes[this.error_.code]+")",this.error_.message,this.error_),this.trigger("error")},e.reportUserActivity=function(e){this.userActivity_=!0},e.userActive=function(e){if(void 0===e)return this.userActive_;if((e=!!e)!==this.userActive_){if(this.userActive_=e,this.userActive_)return this.userActivity_=!0,this.removeClass("vjs-user-inactive"),this.addClass("vjs-user-active"),void this.trigger("useractive");this.tech_&&this.tech_.one("mousemove",function(e){e.stopPropagation(),e.preventDefault()}),this.userActivity_=!1,this.removeClass("vjs-user-active"),this.addClass("vjs-user-inactive"),this.trigger("userinactive")}},e.listenForUserActivity_=function(){var t,i,n,r=ke(this,this.reportUserActivity);this.on("mousedown",function(){r(),this.clearInterval(t),t=this.setInterval(r,250)}),this.on("mousemove",function(e){e.screenX===i&&e.screenY===n||(i=e.screenX,n=e.screenY,r())}),this.on("mouseup",function(e){r(),this.clearInterval(t)});var a,e=this.getChild("controlBar");!e||Qe||Ze||(e.on("mouseenter",function(e){this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout,this.player().options_.inactivityTimeout=0}),e.on("mouseleave",function(e){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout})),this.on("keydown",r),this.on("keyup",r),this.setInterval(function(){if(this.userActivity_){this.userActivity_=!1,this.userActive(!0),this.clearTimeout(a);var e=this.options_.inactivityTimeout;e<=0||(a=this.setTimeout(function(){this.userActivity_||this.userActive(!1)},e))}},250)},e.playbackRate=function(e){if(void 0===e)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",e)},e.defaultPlaybackRate=function(e){return void 0!==e?this.techCall_("setDefaultPlaybackRate",e):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1},e.isAudio=function(e){if(void 0===e)return!!this.isAudio_;this.isAudio_=!!e},e.addTextTrack=function(e,t,i){if(this.tech_)return this.tech_.addTextTrack(e,t,i)},e.addRemoteTextTrack=function(e,t){if(this.tech_)return this.tech_.addRemoteTextTrack(e,t)},e.removeRemoteTextTrack=function(e){void 0===e&&(e={});var t=e.track;if(t=t||e,this.tech_)return this.tech_.removeRemoteTextTrack(t)},e.getVideoPlaybackQuality=function(){return this.techGet_("getVideoPlaybackQuality")},e.videoWidth=function(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0},e.videoHeight=function(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0},e.language=function(e){if(void 0===e)return this.language_;this.language_=String(e).toLowerCase()},e.languages=function(){return je(l.prototype.options_.languages,this.languages_)},e.toJSON=function(){var e=je(this.options_),t=e.tracks;e.tracks=[];for(var i=0;i<t.length;i++){var n=t[i];(n=je(n)).player=void 0,e.tracks[i]=n}return e},e.createModal=function(e,t){var i=this;(t=t||{}).content=e||"";var n=new Ut(this,t);return this.addChild(n),n.on("dispose",function(){i.removeChild(n)}),n.open(),n},e.updateCurrentBreakpoint_=function(){if(this.responsive())for(var e=this.currentBreakpoint(),t=this.currentWidth(),i=0;i<as.length;i++){var n=as[i];if(t<=this.breakpoints_[n]){if(e===n)return;e&&this.removeClass(ss[e]),this.addClass(ss[n]),this.breakpoint_=n;break}}},e.removeCurrentBreakpoint_=function(){var e=this.currentBreakpointClass();this.breakpoint_="",e&&this.removeClass(e)},e.breakpoints=function(e){return void 0===e||(this.breakpoint_="",this.breakpoints_=_({},os,e),this.updateCurrentBreakpoint_()),_(this.breakpoints_)},e.responsive=function(e){return void 0===e?this.responsive_:(e=Boolean(e))!==this.responsive_?((this.responsive_=e)?(this.on("playerresize",this.updateCurrentBreakpoint_),this.updateCurrentBreakpoint_()):(this.off("playerresize",this.updateCurrentBreakpoint_),this.removeCurrentBreakpoint_()),e):void 0},e.currentBreakpoint=function(){return this.breakpoint_},e.currentBreakpointClass=function(){return ss[this.breakpoint_]||""},e.loadMedia=function(e,t){var i=this;if(e&&"object"==typeof e){this.reset(),this.cache_.media=je(e);var n=this.cache_.media,r=n.artwork,a=n.poster,s=n.src,o=n.textTracks;!r&&a&&(this.cache_.media.artwork=[{src:a,type:vr(a)}]),s&&this.src(s),a&&this.poster(a),Array.isArray(o)&&o.forEach(function(e){return i.addRemoteTextTrack(e,!1)}),this.ready(t)}},e.getMedia=function(){if(this.cache_.media)return je(this.cache_.media);var e=this.poster(),t={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),function(e){return{kind:e.kind,label:e.label,language:e.language,src:e.src}})};return e&&(t.poster=e,t.artwork=[{src:t.poster,type:vr(t.poster)}]),t},l.getTagSettings=function(e){var t={sources:[],tracks:[]},i=R(e),n=i["data-setup"];if(I(e,"vjs-fill")&&(i.fill=!0),I(e,"vjs-fluid")&&(i.fluid=!0),null!==n){var r=wt(n||"{}"),a=r[0],s=r[1];a&&m.error(a),_(i,s)}if(_(t,i),e.hasChildNodes())for(var o=e.childNodes,u=0,l=o.length;u<l;u++){var c=o[u],h=c.nodeName.toLowerCase();"source"===h?t.sources.push(R(c)):"track"===h&&t.tracks.push(R(c))}return t},e.flexNotSupported_=function(){var e=h.createElement("i");return!("flexBasis"in e.style||"webkitFlexBasis"in e.style||"mozFlexBasis"in e.style||"msFlexBasis"in e.style||"msFlexOrder"in e.style)},l}(Fe);On.names.forEach(function(e){var t=On[e];us.prototype[t.getterName]=function(){return this.tech_?this.tech_[t.getterName]():(this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName])}}),us.players={};var ls=v.navigator;us.prototype.options_={techOrder:or.defaultTechOrder_,html5:{},flash:{},inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:ls&&(ls.languages&&ls.languages[0]||ls.userLanguage||ls.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1},["ended","seeking","seekable","networkState","readyState"].forEach(function(e){us.prototype[e]=function(){return this.techGet_(e)}}),ns.forEach(function(e){us.prototype["handleTech"+Ne(e)+"_"]=function(){return this.trigger(e)}}),Fe.registerComponent("Player",us);function cs(e){return ys.hasOwnProperty(e)}function hs(e){return cs(e)?ys[e]:void 0}function ds(e,t){e[gs]=e[gs]||{},e[gs][t]=!0}function ps(e,t,i){var n=(i?"before":"")+"pluginsetup";e.trigger(n,t),e.trigger(n+":"+t.name,t)}function fs(r,a){return a.prototype.name=r,function(){ps(this,{name:r,plugin:a,instance:null},!0);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=s(a,[this].concat(t));return this[r]=function(){return n},ps(this,n.getEventHash()),n}}var ms="plugin",gs="activePlugins_",ys={},vs=function(){function i(e){if(this.constructor===i)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=e,Re(this),delete this.trigger,Be(this,this.constructor.defaultState),ds(e,this.name),this.dispose=ke(this,this.dispose),e.on("dispose",this.dispose)}var e=i.prototype;return e.version=function(){return this.constructor.VERSION},e.getEventHash=function(e){return void 0===e&&(e={}),e.name=this.name,e.plugin=this.constructor,e.instance=this,e},e.trigger=function(e,t){return void 0===t&&(t={}),pe(this.eventBusEl_,e,this.getEventHash(t))},e.handleStateChanged=function(e){},e.dispose=function(){var e=this.name,t=this.player;this.trigger("dispose"),this.off(),t.off("dispose",this.dispose),t[gs][e]=!1,this.player=this.state=null,t[e]=fs(e,ys[e])},i.isBasic=function(e){var t="string"==typeof e?hs(e):e;return"function"==typeof t&&!i.prototype.isPrototypeOf(t.prototype)},i.registerPlugin=function(e,t){if("string"!=typeof e)throw new Error('Illegal plugin name, "'+e+'", must be a string, was '+typeof e+".");if(cs(e))m.warn('A plugin named "'+e+'" already exists. You may want to avoid re-registering plugins!');else if(us.prototype.hasOwnProperty(e))throw new Error('Illegal plugin name, "'+e+'", cannot share a name with an existing player method!');if("function"!=typeof t)throw new Error('Illegal plugin for "'+e+'", must be a function, was '+typeof t+".");return ys[e]=t,e!==ms&&(i.isBasic(t)?us.prototype[e]=function(t,i){function n(){ps(this,{name:t,plugin:i,instance:null},!0);var e=i.apply(this,arguments);return ds(this,t),ps(this,{name:t,plugin:i,instance:e}),e}return Object.keys(i).forEach(function(e){n[e]=i[e]}),n}(e,t):us.prototype[e]=fs(e,t)),t},i.deregisterPlugin=function(e){if(e===ms)throw new Error("Cannot de-register base plugin.");cs(e)&&(delete ys[e],delete us.prototype[e])},i.getPlugins=function(e){var i;return void 0===e&&(e=Object.keys(ys)),e.forEach(function(e){var t=hs(e);t&&((i=i||{})[e]=t)}),i},i.getPluginVersion=function(e){var t=hs(e);return t&&t.VERSION||""},i}();vs.getPlugin=hs,vs.BASE_PLUGIN_NAME=ms,vs.registerPlugin(ms,vs),us.prototype.usingPlugin=function(e){return!!this[gs]&&!0===this[gs][e]},us.prototype.hasPlugin=function(e){return!!cs(e)};var _s=function(e){return 0===e.indexOf("#")?e.slice(1):e};function bs(e,i,t){var n=bs.getPlayer(e);if(n)return i&&m.warn('Player "'+e+'" is already initialised. Options will not be applied.'),t&&n.ready(t),n;var r="string"==typeof e?Y("#"+_s(e)):e;if(!w(r))throw new TypeError("The element or ID supplied is not valid. (videojs)");r.ownerDocument.defaultView&&r.ownerDocument.body.contains(r)||m.warn("The element supplied is not included in the DOM"),i=i||{},bs.hooks("beforesetup").forEach(function(e){var t=e(r,je(i));b(t)&&!Array.isArray(t)?i=je(i,t):m.error("please return an object in beforesetup hooks")});var a=Fe.getComponent("Player");return n=new a(r,i,t),bs.hooks("setup").forEach(function(e){return e(n)}),n}if(bs.hooks_={},bs.hooks=function(e,t){return bs.hooks_[e]=bs.hooks_[e]||[],t&&(bs.hooks_[e]=bs.hooks_[e].concat(t)),bs.hooks_[e]},bs.hook=function(e,t){bs.hooks(e,t)},bs.hookOnce=function(i,e){bs.hooks(i,[].concat(e).map(function(t){return function e(){return bs.removeHook(i,e),t.apply(void 0,arguments)}}))},bs.removeHook=function(e,t){var i=bs.hooks(e).indexOf(t);return!(i<=-1)&&(bs.hooks_[e]=bs.hooks_[e].slice(),bs.hooks_[e].splice(i,1),!0)},!0!==v.VIDEOJS_NO_DYNAMIC_STYLE&&k()){var Ts=Y(".vjs-styles-defaults");if(!Ts){Ts=Te("vjs-styles-defaults");var Ss=Y("head");Ss&&Ss.insertBefore(Ts,Ss.firstChild),Se(Ts,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ")}}be(1,bs),bs.VERSION=d,bs.options=us.prototype.options_,bs.getPlayers=function(){return us.players},bs.getPlayer=function(e){var t,i=us.players;if("string"==typeof e){var n=_s(e),r=i[n];if(r)return r;t=Y("#"+n)}else t=e;if(w(t)){var a=t,s=a.player,o=a.playerId;if(s||i[o])return s||i[o]}},bs.getAllPlayers=function(){return Object.keys(us.players).map(function(e){return us.players[e]}).filter(Boolean)},bs.players=us.players,bs.getComponent=Fe.getComponent,bs.registerComponent=function(e,t){or.isTech(t)&&m.warn("The "+e+" tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)"),Fe.registerComponent.call(Fe,e,t)},bs.getTech=or.getTech,bs.registerTech=or.registerTech,bs.use=function(e,t){ur[e]=ur[e]||[],ur[e].push(t)},Object.defineProperty(bs,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(bs.middleware,"TERMINATOR",{value:cr,writeable:!1,enumerable:!0}),bs.browser=ht,bs.TOUCH_ENABLED=ct,bs.extend=function(e,t){void 0===t&&(t={});var i=function(){e.apply(this,arguments)},n={};for(var r in"object"==typeof t?(t.constructor!==Object.prototype.constructor&&(i=t.constructor),n=t):"function"==typeof t&&(i=t),function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.super_=t)}(i,e),n)n.hasOwnProperty(r)&&(i.prototype[r]=n[r]);return i},bs.mergeOptions=je,bs.bind=ke,bs.registerPlugin=vs.registerPlugin,bs.deregisterPlugin=vs.deregisterPlugin,bs.plugin=function(e,t){return m.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),vs.registerPlugin(e,t)},bs.getPlugins=vs.getPlugins,bs.getPlugin=vs.getPlugin,bs.getPluginVersion=vs.getPluginVersion,bs.addLanguage=function(e,t){var i;return e=(""+e).toLowerCase(),bs.options.languages=je(bs.options.languages,((i={})[e]=t,i)),bs.options.languages[e]},bs.log=m,bs.createLogger=g,bs.createTimeRange=bs.createTimeRanges=ft,bs.formatTime=Mr,bs.setFormatTime=function(e){Rr=e},bs.resetFormatTime=function(){Rr=Dr},bs.parseUrl=Nt,bs.isCrossOrigin=Vt,bs.EventTarget=Ce,bs.on=he,bs.one=fe,bs.off=de,bs.trigger=pe,bs.xhr=bn,bs.TextTrack=Cn,bs.AudioTrack=En,bs.VideoTrack=An,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach(function(e){bs[e]=function(){return m.warn("videojs."+e+"() is deprecated; use videojs.dom."+e+"() instead"),J[e].apply(null,arguments)}}),bs.computedStyle=n,bs.dom=J,bs.url=Jt;var ks=It(function(e,t){var i,c,n,r,h;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/\?#]*\/)*.*?)??(;.*?)?(\?.*?)?(#.*?)?$/,c=/^([^\/?#]*)(.*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g,h={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=h.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=h.normalizePath(n.path),h.buildURLFromParts(n)}var r=h.parseURL(t);if(!r)throw new Error("Error trying to parse relative URL.");if(r.scheme)return i.alwaysNormalize?(r.path=h.normalizePath(r.path),h.buildURLFromParts(r)):t;var a=h.parseURL(e);if(!a)throw new Error("Error trying to parse base URL.");if(!a.netLoc&&a.path&&"/"!==a.path[0]){var s=c.exec(a.path);a.netLoc=s[1],a.path=s[2]}a.netLoc&&!a.path&&(a.path="/");var o={scheme:a.scheme,netLoc:r.netLoc,path:null,params:r.params,query:r.query,fragment:r.fragment};if(!r.netLoc&&(o.netLoc=a.netLoc,"/"!==r.path[0]))if(r.path){var u=a.path,l=u.substring(0,u.lastIndexOf("/")+1)+r.path;o.path=h.normalizePath(l)}else o.path=a.path,r.params||(o.params=a.params,r.query||(o.query=a.query));return null===o.path&&(o.path=i.alwaysNormalize?h.normalizePath(r.path):r.path),h.buildURLFromParts(o)},parseURL:function(e){var t=i.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=h});
-/*! @name m3u8-parser @version 4.3.0 @license Apache-2.0 */function ws(){return(ws=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i=arguments[t];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e}).apply(this,arguments)}function Cs(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}function Es(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function As(e){for(var t,i=e.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),n={},r=i.length;r--;)""!==i[r]&&((t=/([^=]*)=(.*)/.exec(i[r]).slice(1))[0]=t[0].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^['"](.*)['"]$/g,"$1"),n[t[0]]=t[1]);return n}function Ps(e){return!!e&&"object"==typeof e}function Ls(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return t.reduce(function(t,i){return Object.keys(i).forEach(function(e){Array.isArray(t[e])&&Array.isArray(i[e])?t[e]=t[e].concat(i[e]):Ps(t[e])&&Ps(i[e])?t[e]=Ls(t[e],i[e]):t[e]=i[e]}),t},{})}function Is(e){return e.reduce(function(e,t){return e.concat(t)},[])}function Os(e){if(!e.length)return[];for(var t=[],i=0;i<e.length;i++)t.push(e[i]);return t}var xs=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},t.trigger=function(e,t){var i,n,r,a=this.listeners[e];if(a)if(2===arguments.length)for(n=a.length,i=0;i<n;++i)a[i].call(this,t);else for(r=Array.prototype.slice.call(arguments,1),n=a.length,i=0;i<n;++i)a[i].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}(),Us=function(t){function e(){var e;return(e=t.call(this)||this).buffer="",e}return Cs(e,t),e.prototype.push=function(e){var t;for(this.buffer+=e,t=this.buffer.indexOf("\n");-1<t;t=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,t)),this.buffer=this.buffer.substring(t+1)},e}(xs),Ds=function(t){function e(){var e;return(e=t.call(this)||this).customParsers=[],e.tagMappers=[],e}Cs(e,t);var i=e.prototype;return i.push=function(n){var u,l,c=this;0!==(n=n.trim()).length&&("#"===n[0]?this.tagMappers.reduce(function(e,t){var i=t(n);return i===n?e:e.concat([i])},[n]).forEach(function(e){for(var t=0;t<c.customParsers.length;t++)if(c.customParsers[t].call(c,e))return;if(0===e.indexOf("#EXT"))if(e=e.replace("\r",""),u=/^#EXTM3U/.exec(e))c.trigger("data",{type:"tag",tagType:"m3u"});else{if(u=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(e))return l={type:"tag",tagType:"inf"},u[1]&&(l.duration=parseFloat(u[1])),u[2]&&(l.title=u[2]),void c.trigger("data",l);if(u=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"targetduration"},u[1]&&(l.duration=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#ZEN-TOTAL-DURATION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"totalduration"},u[1]&&(l.duration=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"version"},u[1]&&(l.version=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return l={type:"tag",tagType:"media-sequence"},u[1]&&(l.number=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return l={type:"tag",tagType:"discontinuity-sequence"},u[1]&&(l.number=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(e))return l={type:"tag",tagType:"playlist-type"},u[1]&&(l.playlistType=u[1]),void c.trigger("data",l);if(u=/^#EXT-X-BYTERANGE:?([0-9.]*)?@?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"byterange"},u[1]&&(l.length=parseInt(u[1],10)),u[2]&&(l.offset=parseInt(u[2],10)),void c.trigger("data",l);if(u=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(e))return l={type:"tag",tagType:"allow-cache"},u[1]&&(l.allowed=!/NO/.test(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-MAP:?(.*)$/.exec(e)){if(l={type:"tag",tagType:"map"},u[1]){var i=As(u[1]);if(i.URI&&(l.uri=i.URI),i.BYTERANGE){var n=i.BYTERANGE.split("@"),r=n[0],a=n[1];l.byterange={},r&&(l.byterange.length=parseInt(r,10)),a&&(l.byterange.offset=parseInt(a,10))}}c.trigger("data",l)}else if(u=/^#EXT-X-STREAM-INF:?(.*)$/.exec(e)){if(l={type:"tag",tagType:"stream-inf"},u[1]){if(l.attributes=As(u[1]),l.attributes.RESOLUTION){var s=l.attributes.RESOLUTION.split("x"),o={};s[0]&&(o.width=parseInt(s[0],10)),s[1]&&(o.height=parseInt(s[1],10)),l.attributes.RESOLUTION=o}l.attributes.BANDWIDTH&&(l.attributes.BANDWIDTH=parseInt(l.attributes.BANDWIDTH,10)),l.attributes["PROGRAM-ID"]&&(l.attributes["PROGRAM-ID"]=parseInt(l.attributes["PROGRAM-ID"],10))}c.trigger("data",l)}else{if(u=/^#EXT-X-MEDIA:?(.*)$/.exec(e))return l={type:"tag",tagType:"media"},u[1]&&(l.attributes=As(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-ENDLIST/.exec(e))c.trigger("data",{type:"tag",tagType:"endlist"});else if(u=/^#EXT-X-DISCONTINUITY/.exec(e))c.trigger("data",{type:"tag",tagType:"discontinuity"});else{if(u=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(e))return l={type:"tag",tagType:"program-date-time"},u[1]&&(l.dateTimeString=u[1],l.dateTimeObject=new Date(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-KEY:?(.*)$/.exec(e))return l={type:"tag",tagType:"key"},u[1]&&(l.attributes=As(u[1]),l.attributes.IV&&("0x"===l.attributes.IV.substring(0,2).toLowerCase()&&(l.attributes.IV=l.attributes.IV.substring(2)),l.attributes.IV=l.attributes.IV.match(/.{8}/g),l.attributes.IV[0]=parseInt(l.attributes.IV[0],16),l.attributes.IV[1]=parseInt(l.attributes.IV[1],16),l.attributes.IV[2]=parseInt(l.attributes.IV[2],16),l.attributes.IV[3]=parseInt(l.attributes.IV[3],16),l.attributes.IV=new Uint32Array(l.attributes.IV))),void c.trigger("data",l);if(u=/^#EXT-X-START:?(.*)$/.exec(e))return l={type:"tag",tagType:"start"},u[1]&&(l.attributes=As(u[1]),l.attributes["TIME-OFFSET"]=parseFloat(l.attributes["TIME-OFFSET"]),l.attributes.PRECISE=/YES/.test(l.attributes.PRECISE)),void c.trigger("data",l);if(u=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-out-cont"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);if(u=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-out"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);if(u=/^#EXT-X-CUE-IN:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-in"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);c.trigger("data",{type:"tag",data:e.slice(4)})}}}else c.trigger("data",{type:"comment",text:e.slice(1)})}):this.trigger("data",{type:"uri",uri:n}))},i.addParser=function(e){var t=this,i=e.expression,n=e.customType,r=e.dataParser,a=e.segment;"function"!=typeof r&&(r=function(e){return e}),this.customParsers.push(function(e){if(i.exec(e))return t.trigger("data",{type:"custom",data:r(e),customType:n,segment:a}),!0})},i.addTagMapper=function(e){var t=e.expression,i=e.map;this.tagMappers.push(function(e){return t.test(e)?i(e):e})},e}(xs),Rs=function(t){function e(){var e;(e=t.call(this)||this).lineStream=new Us,e.parseStream=new Ds,e.lineStream.pipe(e.parseStream);var r,a,s=Es(Es(e)),o=[],u={},l={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},c=0;return e.manifest={allowCache:!0,discontinuityStarts:[],segments:[]},e.parseStream.on("data",function(t){var i,n;({tag:function(){({"allow-cache":function(){this.manifest.allowCache=t.allowed,"allowed"in t||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange:function(){var e={};"length"in t&&((u.byterange=e).length=t.length,"offset"in t||(this.trigger("info",{message:"defaulting offset to zero"}),t.offset=0)),"offset"in t&&((u.byterange=e).offset=t.offset)},endlist:function(){this.manifest.endList=!0},inf:function(){"mediaSequence"in this.manifest||(this.manifest.mediaSequence=0,this.trigger("info",{message:"defaulting media sequence to zero"})),"discontinuitySequence"in this.manifest||(this.manifest.discontinuitySequence=0,this.trigger("info",{message:"defaulting discontinuity sequence to zero"})),0<t.duration&&(u.duration=t.duration),0===t.duration&&(u.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=o},key:function(){t.attributes?"NONE"!==t.attributes.METHOD?t.attributes.URI?(t.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),a={method:t.attributes.METHOD||"AES-128",uri:t.attributes.URI},"undefined"!=typeof t.attributes.IV&&(a.iv=t.attributes.IV)):this.trigger("warn",{message:"ignoring key declaration without URI"}):a=null:this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence":function(){isFinite(t.number)?this.manifest.mediaSequence=t.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+t.number})},"discontinuity-sequence":function(){isFinite(t.number)?(this.manifest.discontinuitySequence=t.number,c=t.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+t.number})},"playlist-type":function(){/VOD|EVENT/.test(t.playlistType)?this.manifest.playlistType=t.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+t.playlist})},map:function(){r={},t.uri&&(r.uri=t.uri),t.byterange&&(r.byterange=t.byterange)},"stream-inf":function(){this.manifest.playlists=o,this.manifest.mediaGroups=this.manifest.mediaGroups||l,t.attributes?(u.attributes||(u.attributes={}),ws(u.attributes,t.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media:function(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||l,t.attributes&&t.attributes.TYPE&&t.attributes["GROUP-ID"]&&t.attributes.NAME){var e=this.manifest.mediaGroups[t.attributes.TYPE];e[t.attributes["GROUP-ID"]]=e[t.attributes["GROUP-ID"]]||{},i=e[t.attributes["GROUP-ID"]],(n={default:/yes/i.test(t.attributes.DEFAULT)}).default?n.autoselect=!0:n.autoselect=/yes/i.test(t.attributes.AUTOSELECT),t.attributes.LANGUAGE&&(n.language=t.attributes.LANGUAGE),t.attributes.URI&&(n.uri=t.attributes.URI),t.attributes["INSTREAM-ID"]&&(n.instreamId=t.attributes["INSTREAM-ID"]),t.attributes.CHARACTERISTICS&&(n.characteristics=t.attributes.CHARACTERISTICS),t.attributes.FORCED&&(n.forced=/yes/i.test(t.attributes.FORCED)),i[t.attributes.NAME]=n}else this.trigger("warn",{message:"ignoring incomplete or missing media group"})},discontinuity:function(){c+=1,u.discontinuity=!0,this.manifest.discontinuityStarts.push(o.length)},"program-date-time":function(){"undefined"==typeof this.manifest.dateTimeString&&(this.manifest.dateTimeString=t.dateTimeString,this.manifest.dateTimeObject=t.dateTimeObject),u.dateTimeString=t.dateTimeString,u.dateTimeObject=t.dateTimeObject},targetduration:function(){!isFinite(t.duration)||t.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+t.duration}):this.manifest.targetDuration=t.duration},totalduration:function(){!isFinite(t.duration)||t.duration<0?this.trigger("warn",{message:"ignoring invalid total duration: "+t.duration}):this.manifest.totalDuration=t.duration},start:function(){t.attributes&&!isNaN(t.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:t.attributes["TIME-OFFSET"],precise:t.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out":function(){u.cueOut=t.data},"cue-out-cont":function(){u.cueOutCont=t.data},"cue-in":function(){u.cueIn=t.data}}[t.tagType]||function(){}).call(s)},uri:function(){u.uri=t.uri,o.push(u),!this.manifest.targetDuration||"duration"in u||(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),u.duration=this.manifest.targetDuration),a&&(u.key=a),u.timeline=c,r&&(u.map=r),u={}},comment:function(){},custom:function(){t.segment?(u.custom=u.custom||{},u.custom[t.customType]=t.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[t.customType]=t.data)}})[t.type].call(s)}),e}Cs(e,t);var i=e.prototype;return i.push=function(e){this.lineStream.push(e)},i.end=function(){this.lineStream.push("\n")},i.addParser=function(e){this.parseStream.addParser(e)},i.addTagMapper=function(e){this.parseStream.addTagMapper(e)},e}(xs),Ms="INVALID_NUMBER_OF_PERIOD",Bs="DASH_EMPTY_MANIFEST",Ns="DASH_INVALID_XML",js="NO_BASE_URL",Fs="SEGMENT_TIME_UNSPECIFIED",Vs="UNSUPPORTED_UTC_TIMING_SCHEME";function Hs(e,t){return/^[a-z]+:/i.test(t)?t:(/\/\//i.test(e)||(e=oo.buildAbsoluteURL(v.location.href,e)),oo.buildAbsoluteURL(e,t))}function qs(e){var t=e.baseUrl,i=void 0===t?"":t,n=e.source,r=void 0===n?"":n,a=e.range,s=void 0===a?"":a,o=e.indexRange,u=void 0===o?"":o,l={uri:r,resolvedUri:Hs(i||"",r)};if(s||u){var c=(s||u).split("-"),h=parseInt(c[0],10),d=parseInt(c[1],10);l.byterange={length:d-h+1,offset:h}}return l}function zs(e){var t=e.type,i=void 0===t?"static":t,n=e.duration,r=e.timescale,a=void 0===r?1:r,s=e.sourceDuration,o=uo[i](e),u=function(e,t){for(var i=[],n=e;n<t;n++)i.push(n);return i}(o.start,o.end).map(function(o){return function(e,t){var i=o.duration,n=o.timescale,r=void 0===n?1:n,a=o.periodIndex,s=o.startNumber;return{number:(void 0===s?1:s)+e,duration:i/r,timeline:a,time:t*i}}}(e));if("static"===i){var l=u.length-1;u[l].duration=s-n/a*l}return u}function Ws(e){var t=e.baseUrl,i=e.initialization,n=void 0===i?{}:i,r=e.sourceDuration,a=e.timescale,s=void 0===a?1:a,o=e.indexRange,u=void 0===o?"":o,l=e.duration;if(!t)throw new Error(js);var c=qs({baseUrl:t,source:n.sourceURL,range:n.range}),h=qs({baseUrl:t,source:t,indexRange:u});if(h.map=c,l){var d=zs(e);d.length&&(h.duration=d[0].duration,h.timeline=d[0].timeline)}else r&&(h.duration=r/s,h.timeline=0);return h.number=0,[h]}function Gs(e,t,i){for(var n=e.sidx.map?e.sidx.map:null,r=e.sidx.duration,a=e.timeline||0,s=e.sidx.byterange,o=s.offset+s.length,u=t.timescale,l=t.references.filter(function(e){return 1!==e.referenceType}),c=[],h=o+t.firstOffset,d=0;d<l.length;d++){var p=t.references[d],f=p.referencedSize,m=p.subsegmentDuration,g=Ws({baseUrl:i,timescale:u,timeline:a,periodIndex:a,duration:m,sourceDuration:r,indexRange:h+"-"+(h+f-1)})[0];n&&(g.map=n),c.push(g),h+=f}return e.segments=c,e}function $s(e){return function(t){return Object.keys(t).map(function(e){return t[e]})}(e.reduce(function(e,t){var i,n=t.attributes.id+(t.attributes.lang||"");e[n]?(t.segments[0]&&(t.segments[0].discontinuity=!0),(i=e[n].segments).push.apply(i,t.segments),t.attributes.contentProtection&&(e[n].attributes.contentProtection=t.attributes.contentProtection)):e[n]=t;return e},{})).map(function(e){return e.discontinuityStarts=function(e,n){return e.reduce(function(e,t,i){return t[n]&&e.push(i),e},[])}(e.segments,"discontinuity"),e})}function Xs(e,t){if(void 0===t&&(t={}),!Object.keys(t).length)return e;for(var i in e){var n=e[i];if(n.sidx){var r=n.sidx.uri+"-"+(s=n.sidx.byterange,void 0,o=s.offset+s.length-1,s.offset+"-"+o),a=t[r]&&t[r].sidx;n.sidx&&a&&Gs(n,a,n.sidx.resolvedUri)}}var s,o;return e}function Ks(e){var t,i=e.attributes,n=e.segments,r=e.sidx,a={attributes:(t={NAME:i.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:i.width,height:i.height},CODECS:i.codecs,BANDWIDTH:i.bandwidth},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1};return i.contentProtection&&(a.contentProtection=i.contentProtection),r&&(a.sidx=r),a}function Ys(e,t){var i;if(void 0===t&&(t={}),!e.length)return{};var n=e[0].attributes,r=n.sourceDuration,a=n.minimumUpdatePeriod,s=void 0===a?0:a,o=$s(e.filter(function(e){var t=e.attributes;return"video/mp4"===t.mimeType||"video"===t.contentType})).map(Ks),u=$s(e.filter(function(e){var t=e.attributes;return"audio/mp4"===t.mimeType||"audio"===t.contentType})),l=e.filter(function(e){var t=e.attributes;return"text/vtt"===t.mimeType||"text"===t.contentType}),c={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:(i={AUDIO:{},VIDEO:{}},i["CLOSED-CAPTIONS"]={},i.SUBTITLES={},i),uri:"",duration:r,playlists:Xs(o,t),minimumUpdatePeriod:1e3*s};return u.length&&(c.mediaGroups.AUDIO.audio=function(e,s){var o;void 0===s&&(s={});var t=e.reduce(function(e,t){var i=t.attributes.role&&t.attributes.role.value||"",n=t.attributes.lang||"",r="main";if(n){var a=i?" ("+i+")":"";r=t.attributes.lang+a}return e[r]&&e[r].playlists[0].attributes.BANDWIDTH>t.attributes.bandwidth||(e[r]={language:n,autoselect:!0,default:"main"===i,playlists:Xs([function(e){var t,i=e.attributes,n=e.segments,r=e.sidx,a={attributes:(t={NAME:i.id,BANDWIDTH:i.bandwidth,CODECS:i.codecs},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1};return i.contentProtection&&(a.contentProtection=i.contentProtection),r&&(a.sidx=r),a}(t)],s),uri:""},"undefined"==typeof o&&"main"===i&&((o=t).default=!0)),e},{});o||(t[Object.keys(t)[0]].default=!0);return t}(u,t)),l.length&&(c.mediaGroups.SUBTITLES.subs=function(e,n){return void 0===n&&(n={}),e.reduce(function(e,t){var i=t.attributes.lang||"text";return e[i]||(e[i]={language:i,default:!1,autoselect:!1,playlists:Xs([function(e){var t,i=e.attributes,n=e.segments;return"undefined"==typeof n&&(n=[{uri:i.baseUrl,timeline:i.periodIndex,resolvedUri:i.baseUrl||"",duration:i.sourceDuration,number:0}],i.duration=i.sourceDuration),{attributes:(t={NAME:i.id,BANDWIDTH:i.bandwidth},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:i.baseUrl||"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1}}(t)],n),uri:""}),e},{})}(l,t)),c}function Qs(e,t){for(var i,n,r,a,s,o,u,l,c,h,d,p,f=e.type,m=void 0===f?"static":f,g=e.minimumUpdatePeriod,y=void 0===g?0:g,v=e.media,_=void 0===v?"":v,b=e.sourceDuration,T=e.timescale,S=void 0===T?1:T,k=e.startNumber,w=void 0===k?1:k,C=e.periodIndex,E=[],A=-1,P=0;P<t.length;P++){var L=t[P],I=L.d,O=L.r||0,x=L.t||0;A<0&&(A=x),x&&A<x&&(A=x);var U=void 0;if(O<0){var D=P+1;U=D===t.length?"dynamic"===m&&0<y&&0<_.indexOf("$Number$")?(n=A,r=I,void 0,a=(i=e).NOW,s=i.clientOffset,o=i.availabilityStartTime,u=i.timescale,l=void 0===u?1:u,c=i.start,h=void 0===c?0:c,d=i.minimumUpdatePeriod,p=(a+s)/1e3+(void 0===d?0:d)-(o+h),Math.ceil((p*l-n)/r)):(b*S-A)/I:(t[D].t-A)/I}else U=O+1;for(var R=w+E.length+U,M=w+E.length;M<R;)E.push({number:M,duration:I/S,time:A,timeline:C}),A+=I,M++}return E}function Js(e,t){return e.replace(lo,function(a){return function(e,t,i,n){if("$$"===e)return"$";if("undefined"==typeof a[t])return e;var r=""+a[t];return"RepresentationID"===t?r:(n=i?parseInt(n,10):1)<=r.length?r:new Array(n-r.length+1).join("0")+r}}(t))}function Zs(i,e){var n={RepresentationID:i.id,Bandwidth:i.bandwidth||0},t=i.initialization,r=void 0===t?{sourceURL:"",range:""}:t,a=qs({baseUrl:i.baseUrl,source:Js(r.sourceURL,n),range:r.range});return function(e,t){return e.duration||t?e.duration?zs(e):Qs(e,t):[{number:e.startNumber||1,duration:e.sourceDuration,time:0,timeline:e.periodIndex}]}(i,e).map(function(e){n.Number=e.number,n.Time=e.time;var t=Js(i.media||"",n);return{uri:t,timeline:e.timeline,duration:e.duration,resolvedUri:Hs(i.baseUrl||"",t),map:a,number:e.number}})}function eo(t,e){var i=t.duration,n=t.segmentUrls,r=void 0===n?[]:n;if(!i&&!e||i&&e)throw new Error(Fs);var a,s=r.map(function(e){return function(e,t){var i=e.baseUrl,n=e.initialization,r=void 0===n?{}:n,a=qs({baseUrl:i,source:r.sourceURL,range:r.range}),s=qs({baseUrl:i,source:t.media,range:t.mediaRange});return s.map=a,s}(t,e)});return i&&(a=zs(t)),e&&(a=Qs(t,e)),a.map(function(e,t){if(s[t]){var i=s[t];return i.timeline=e.timeline,i.duration=e.duration,i.number=e.number,i}}).filter(function(e){return e})}function to(e){var t,i,n=e.attributes,r=e.segmentInfo;r.template?(i=Zs,t=Ls(n,r.template)):r.base?(i=Ws,t=Ls(n,r.base)):r.list&&(i=eo,t=Ls(n,r.list));var a={attributes:n};if(!i)return a;var s=i(t,r.timeline);if(t.duration){var o=t,u=o.duration,l=o.timescale,c=void 0===l?1:l;t.duration=u/c}else s.length?t.duration=s.reduce(function(e,t){return Math.max(e,Math.ceil(t.duration))},0):t.duration=0;return a.attributes=t,a.segments=s,r.base&&t.indexRange&&(a.sidx=s[0],a.segments=[]),a}function io(e,t){return Os(e.childNodes).filter(function(e){return e.tagName===t})}function no(e){return e.textContent.trim()}function ro(e){var t=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(e);if(!t)return 0;var i=t.slice(1),n=i[0],r=i[1],a=i[2],s=i[3],o=i[4],u=i[5];return 31536e3*parseFloat(n||0)+2592e3*parseFloat(r||0)+86400*parseFloat(a||0)+3600*parseFloat(s||0)+60*parseFloat(o||0)+parseFloat(u||0)}function ao(e){return e&&e.attributes?Os(e.attributes).reduce(function(e,t){var i=co[t.name]||co.DEFAULT;return e[t.name]=i(t.value),e},{}):{}}var so,oo=(function(e,t){var i,c,n,r,h;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/\?#]*\/)*.*?)??(;.*?)?(\?.*?)?(#.*?)?$/,c=/^([^\/?#]*)(.*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g,h={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=h.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=h.normalizePath(n.path),h.buildURLFromParts(n)}var r=h.parseURL(t);if(!r)throw new Error("Error trying to parse relative URL.");if(r.scheme)return i.alwaysNormalize?(r.path=h.normalizePath(r.path),h.buildURLFromParts(r)):t;var a=h.parseURL(e);if(!a)throw new Error("Error trying to parse base URL.");if(!a.netLoc&&a.path&&"/"!==a.path[0]){var s=c.exec(a.path);a.netLoc=s[1],a.path=s[2]}a.netLoc&&!a.path&&(a.path="/");var o={scheme:a.scheme,netLoc:r.netLoc,path:null,params:r.params,query:r.query,fragment:r.fragment};if(!r.netLoc&&(o.netLoc=a.netLoc,"/"!==r.path[0]))if(r.path){var u=a.path,l=u.substring(0,u.lastIndexOf("/")+1)+r.path;o.path=h.normalizePath(l)}else o.path=a.path,r.params||(o.params=a.params,r.query||(o.query=a.query));return null===o.path&&(o.path=i.alwaysNormalize?h.normalizePath(r.path):r.path),h.buildURLFromParts(o)},parseURL:function(e){var t=i.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=h}(so={exports:{}},so.exports),so.exports),uo={static:function(e){var t=e.duration,i=e.timescale,n=void 0===i?1:i,r=e.sourceDuration;return{start:0,end:Math.ceil(r/(t/n))}},dynamic:function(e){var t=e.NOW,i=e.clientOffset,n=e.availabilityStartTime,r=e.timescale,a=void 0===r?1:r,s=e.duration,o=e.start,u=void 0===o?0:o,l=e.minimumUpdatePeriod,c=void 0===l?0:l,h=e.timeShiftBufferDepth,d=void 0===h?1/0:h,p=(t+i)/1e3,f=n+u,m=p+c-f,g=Math.ceil(m*a/s),y=Math.floor((p-f-d)*a/s),v=Math.floor((p-f)*a/s);return{start:Math.max(0,y),end:Math.min(g,v)}}},lo=/\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g,co={mediaPresentationDuration:function(e){return ro(e)},availabilityStartTime:function(e){return function(e){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(e)&&(e+="Z"),Date.parse(e)}(e)/1e3},minimumUpdatePeriod:function(e){return ro(e)},timeShiftBufferDepth:function(e){return ro(e)},start:function(e){return ro(e)},width:function(e){return parseInt(e,10)},height:function(e){return parseInt(e,10)},bandwidth:function(e){return parseInt(e,10)},startNumber:function(e){return parseInt(e,10)},timescale:function(e){return parseInt(e,10)},duration:function(e){var t=parseInt(e,10);return isNaN(t)?ro(e):t},d:function(e){return parseInt(e,10)},t:function(e){return parseInt(e,10)},r:function(e){return parseInt(e,10)},DEFAULT:function(e){return e}};function ho(e,i){return i.length?Is(e.map(function(t){return i.map(function(e){return Hs(t,no(e))})})):e}function po(e){var t=io(e,"SegmentTemplate")[0],i=io(e,"SegmentList")[0],n=i&&io(i,"SegmentURL").map(function(e){return Ls({tag:"SegmentURL"},ao(e))}),r=io(e,"SegmentBase")[0],a=i||t,s=a&&io(a,"SegmentTimeline")[0],o=i||r||t,u=o&&io(o,"Initialization")[0],l=t&&ao(t);l&&u?l.initialization=u&&ao(u):l&&l.initialization&&(l.initialization={sourceURL:l.initialization});var c={template:l,timeline:s&&io(s,"S").map(function(e){return ao(e)}),list:i&&Ls(ao(i),{segmentUrls:n,initialization:ao(u)}),base:r&&Ls(ao(r),{initialization:ao(u)})};return Object.keys(c).forEach(function(e){c[e]||delete c[e]}),c}function fo(e){return e.reduce(function(e,t){var i=ao(t),n=Co[i.schemeIdUri];if(n){e[n]={attributes:i};var r=io(t,"cenc:pssh")[0];if(r){var a=no(r),s=a&&function(e){for(var t=v.atob(e),i=new Uint8Array(t.length),n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i}(a);e[n].pssh=s}}return e},{})}function mo(c,h,d){return function(e){var t=ao(e),i=ho(h,io(e,"BaseURL")),n=io(e,"Role")[0],r={role:ao(n)},a=Ls(c,t,r),s=fo(io(e,"ContentProtection"));Object.keys(s).length&&(a=Ls(a,{contentProtection:s}));var o=po(e),u=io(e,"Representation"),l=Ls(d,o);return Is(u.map(function(a,s,o){return function(e){var t=io(e,"BaseURL"),i=ho(s,t),n=Ls(a,ao(e)),r=po(e);return i.map(function(e){return{segmentInfo:Ls(o,r),attributes:Ls(n,{baseUrl:e})}})}}(a,i,l)))}}function go(e,t){void 0===t&&(t={});var i=t,n=i.manifestUri,r=void 0===n?"":n,a=i.NOW,s=void 0===a?Date.now():a,o=i.clientOffset,u=void 0===o?0:o,l=io(e,"Period");if(!l.length)throw new Error(Ms);var c=ao(e),h=ho([r],io(e,"BaseURL"));return c.sourceDuration=c.mediaPresentationDuration||0,c.NOW=s,c.clientOffset=u,Is(l.map(function(l,c){return function(e,t){var i=ho(c,io(e,"BaseURL")),n=ao(e),r=parseInt(n.id,10),a=v.isNaN(r)?t:r,s=Ls(l,{periodIndex:a}),o=io(e,"AdaptationSet"),u=po(e);return Is(o.map(mo(s,i,u)))}}(c,h)))}function yo(e){if(""===e)throw new Error(Bs);var t=(new v.DOMParser).parseFromString(e,"application/xml"),i=t&&"MPD"===t.documentElement.tagName?t.documentElement:null;if(!i||i&&0<i.getElementsByTagName("parsererror").length)throw new Error(Ns);return i}function vo(e,t){return void 0===t&&(t={}),Ys(function(e){return e.map(to)}(go(yo(e),t)),t.sidxMapping)}function _o(e){return function(e){var t=io(e,"UTCTiming")[0];if(!t)return null;var i=ao(t);switch(i.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":i.method="HEAD";break;case"urn:mpeg:dash:utc:http-xsdate:2014":case"urn:mpeg:dash:utc:http-iso:2014":case"urn:mpeg:dash:utc:http-xsdate:2012":case"urn:mpeg:dash:utc:http-iso:2012":i.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":i.method="DIRECT",i.value=Date.parse(i.value);break;case"urn:mpeg:dash:utc:http-ntp:2014":case"urn:mpeg:dash:utc:ntp:2014":case"urn:mpeg:dash:utc:sntp:2014":default:throw new Error(Vs)}return i}(yo(e))}var bo,To,So,ko,wo,Co={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"},Eo=function(e){return e>>>0};So=function(e){return bo(e,["moov","trak"]).reduce(function(e,t){var i,n,r,a,s;return(i=bo(t,["tkhd"])[0])?(n=i[0],a=Eo(i[r=0===n?12:20]<<24|i[r+1]<<16|i[r+2]<<8|i[r+3]),(s=bo(t,["mdia","mdhd"])[0])?(r=0===(n=s[0])?12:20,e[a]=Eo(s[r]<<24|s[r+1]<<16|s[r+2]<<8|s[r+3]),e):null):null},{})},ko=function(r,e){var t,i,n;return t=bo(e,["moof","traf"]),i=[].concat.apply([],t.map(function(n){return bo(n,["tfhd"]).map(function(e){var t,i;return t=Eo(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),i=r[t]||9e4,(bo(n,["tfdt"]).map(function(e){var t,i;return t=e[0],i=Eo(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),1===t&&(i*=Math.pow(2,32),i+=Eo(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),i})[0]||1/0)/i})})),n=Math.min.apply(null,i),isFinite(n)?n:0},wo=function(e){var t=bo(e,["moov","trak"]),o=[];return t.forEach(function(e){var t=bo(e,["mdia","hdlr"]),s=bo(e,["tkhd"]);t.forEach(function(e,t){var i,n,r=To(e.subarray(8,12)),a=s[t];"vide"===r&&(n=0===(i=new DataView(a.buffer,a.byteOffset,a.byteLength)).getUint8(0)?i.getUint32(12):i.getUint32(20),o.push(n))})}),o};function Ao(e){return new Date(1e3*e-20828448e5)}function Po(e){return{isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}}var Lo,Io,Oo,xo,Uo,Do,Ro,Mo,Bo,No,jo,Fo,Vo,Ho,qo,zo,Wo,Go,$o,Xo,Ko,Yo,Qo,Jo,Zo,eu,tu,iu,nu,ru,au,su,ou,uu,lu,cu,hu,du,pu,fu,mu,gu,yu={findBox:bo=function(e,t){var i,n,r,a,s,o=[];if(!t.length)return null;for(i=0;i<e.byteLength;)n=Eo(e[i]<<24|e[i+1]<<16|e[i+2]<<8|e[i+3]),r=To(e.subarray(i+4,i+8)),a=1<n?i+n:e.byteLength,r===t[0]&&(1===t.length?o.push(e.subarray(i+8,a)):(s=bo(e.subarray(i+8,a),t.slice(1))).length&&(o=o.concat(s))),i=a;return o},parseType:To=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),t+=String.fromCharCode(e[2]),t+=String.fromCharCode(e[3])},timescale:So,startTime:ko,videoTrackIds:wo},vu=yu.parseType,_u={avc1:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{dataReferenceIndex:t.getUint16(6),width:t.getUint16(24),height:t.getUint16(26),horizresolution:t.getUint16(28)+t.getUint16(30)/16,vertresolution:t.getUint16(32)+t.getUint16(34)/16,frameCount:t.getUint16(40),depth:t.getUint16(74),config:Lo(e.subarray(78,e.byteLength))}},avcC:function(e){var t,i,n,r,a=new DataView(e.buffer,e.byteOffset,e.byteLength),s={configurationVersion:e[0],avcProfileIndication:e[1],profileCompatibility:e[2],avcLevelIndication:e[3],lengthSizeMinusOne:3&e[4],sps:[],pps:[]},o=31&e[5];for(n=6,r=0;r<o;r++)i=a.getUint16(n),n+=2,s.sps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;for(t=e[n],n++,r=0;r<t;r++)i=a.getUint16(n),n+=2,s.pps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;return s},btrt:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{bufferSizeDB:t.getUint32(0),maxBitrate:t.getUint32(4),avgBitrate:t.getUint32(8)}},esds:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),esId:e[6]<<8|e[7],streamPriority:31&e[8],decoderConfig:{objectProfileIndication:e[11],streamType:e[12]>>>2&63,bufferSize:e[13]<<16|e[14]<<8|e[15],maxBitrate:e[16]<<24|e[17]<<16|e[18]<<8|e[19],avgBitrate:e[20]<<24|e[21]<<16|e[22]<<8|e[23],decoderConfigDescriptor:{tag:e[24],length:e[25],audioObjectType:e[26]>>>3&31,samplingFrequencyIndex:(7&e[26])<<1|e[27]>>>7&1,channelConfiguration:e[27]>>>3&15}}}},ftyp:function(e){for(var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={majorBrand:vu(e.subarray(0,4)),minorVersion:t.getUint32(4),compatibleBrands:[]},n=8;n<e.byteLength;)i.compatibleBrands.push(vu(e.subarray(n,n+4))),n+=4;return i},dinf:function(e){return{boxes:Lo(e)}},dref:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),dataReferences:Lo(e.subarray(8))}},hdlr:function(e){var t={version:new DataView(e.buffer,e.byteOffset,e.byteLength).getUint8(0),flags:new Uint8Array(e.subarray(1,4)),handlerType:vu(e.subarray(8,12)),name:""},i=8;for(i=24;i<e.byteLength;i++){if(0===e[i]){i++;break}t.name+=String.fromCharCode(e[i])}return t.name=decodeURIComponent(escape(t.name)),t},mdat:function(e){return{byteLength:e.byteLength,nals:function(e){var t,i,n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=[];for(t=0;t+4<e.length;t+=i)if(i=n.getUint32(t),t+=4,i<=0)r.push("<span style='color:red;'>MALFORMED DATA</span>");else switch(31&e[t]){case 1:r.push("slice_layer_without_partitioning_rbsp");break;case 5:r.push("slice_layer_without_partitioning_rbsp_idr");break;case 6:r.push("sei_rbsp");break;case 7:r.push("seq_parameter_set_rbsp");break;case 8:r.push("pic_parameter_set_rbsp");break;case 9:r.push("access_unit_delimiter_rbsp");break;default:r.push("UNKNOWN NAL - "+e[t]&31)}return r}(e)}},mdhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=4,r={version:i.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),language:""};return 1===r.version?(n+=4,r.creationTime=Ao(i.getUint32(n)),n+=8,r.modificationTime=Ao(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=8):(r.creationTime=Ao(i.getUint32(n)),n+=4,r.modificationTime=Ao(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=4),r.duration=i.getUint32(n),n+=4,t=i.getUint16(n),r.language+=String.fromCharCode(96+(t>>10)),r.language+=String.fromCharCode(96+((992&t)>>5)),r.language+=String.fromCharCode(96+(31&t)),r},mdia:function(e){return{boxes:Lo(e)}},mfhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sequenceNumber:e[4]<<24|e[5]<<16|e[6]<<8|e[7]}},minf:function(e){return{boxes:Lo(e)}},mp4a:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={dataReferenceIndex:t.getUint16(6),channelcount:t.getUint16(16),samplesize:t.getUint16(18),samplerate:t.getUint16(24)+t.getUint16(26)/65536};return 28<e.byteLength&&(i.streamDescriptor=Lo(e.subarray(28))[0]),i},moof:function(e){return{boxes:Lo(e)}},moov:function(e){return{boxes:Lo(e)}},mvex:function(e){return{boxes:Lo(e)}},mvhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=Ao(t.getUint32(i)),i+=8,n.modificationTime=Ao(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=8):(n.creationTime=Ao(t.getUint32(i)),i+=4,n.modificationTime=Ao(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=4),n.duration=t.getUint32(i),i+=4,n.rate=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,i+=8,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,i+=24,n.nextTrackId=t.getUint32(i),n},pdin:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),rate:t.getUint32(4),initialDelay:t.getUint32(8)}},sdtp:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]};for(t=4;t<e.byteLength;t++)i.samples.push({dependsOn:(48&e[t])>>4,isDependedOn:(12&e[t])>>2,hasRedundancy:3&e[t]});return i},sidx:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),references:[],referenceId:i.getUint32(4),timescale:i.getUint32(8),earliestPresentationTime:i.getUint32(12),firstOffset:i.getUint32(16)},r=i.getUint16(22);for(t=24;r;t+=12,r--)n.references.push({referenceType:(128&e[t])>>>7,referencedSize:2147483647&i.getUint32(t),subsegmentDuration:i.getUint32(t+4),startsWithSap:!!(128&e[t+8]),sapType:(112&e[t+8])>>>4,sapDeltaTime:268435455&i.getUint32(t+8)});return n},smhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),balance:e[4]+e[5]/256}},stbl:function(e){return{boxes:Lo(e)}},stco:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),chunkOffsets:[]},r=i.getUint32(4);for(t=8;r;t+=4,r--)n.chunkOffsets.push(i.getUint32(t));return n},stsc:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=i.getUint32(4),r={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleToChunks:[]};for(t=8;n;t+=12,n--)r.sampleToChunks.push({firstChunk:i.getUint32(t),samplesPerChunk:i.getUint32(t+4),sampleDescriptionIndex:i.getUint32(t+8)});return r},stsd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleDescriptions:Lo(e.subarray(8))}},stsz:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleSize:i.getUint32(4),entries:[]};for(t=12;t<e.byteLength;t+=4)n.entries.push(i.getUint32(t));return n},stts:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),timeToSamples:[]},r=i.getUint32(4);for(t=8;r;t+=8,r--)n.timeToSamples.push({sampleCount:i.getUint32(t),sampleDelta:i.getUint32(t+4)});return n},styp:function(e){return _u.ftyp(e)},tfdt:function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4)),baseMediaDecodeTime:e[4]<<24|e[5]<<16|e[6]<<8|e[7]};return 1===t.version&&(t.baseMediaDecodeTime*=Math.pow(2,32),t.baseMediaDecodeTime+=e[8]<<24|e[9]<<16|e[10]<<8|e[11]),t},tfhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:i.getUint32(4)},r=1&n.flags[2],a=2&n.flags[2],s=8&n.flags[2],o=16&n.flags[2],u=32&n.flags[2],l=65536&n.flags[0],c=131072&n.flags[0];return t=8,r&&(t+=4,n.baseDataOffset=i.getUint32(12),t+=4),a&&(n.sampleDescriptionIndex=i.getUint32(t),t+=4),s&&(n.defaultSampleDuration=i.getUint32(t),t+=4),o&&(n.defaultSampleSize=i.getUint32(t),t+=4),u&&(n.defaultSampleFlags=i.getUint32(t)),l&&(n.durationIsEmpty=!0),!r&&c&&(n.baseDataOffsetIsMoof=!0),n},tkhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=Ao(t.getUint32(i)),i+=8,n.modificationTime=Ao(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=8):(n.creationTime=Ao(t.getUint32(i)),i+=4,n.modificationTime=Ao(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=4),n.duration=t.getUint32(i),i+=4,i+=8,n.layer=t.getUint16(i),i+=2,n.alternateGroup=t.getUint16(i),i+=2,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,n.width=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.height=t.getUint16(i)+t.getUint16(i+2)/16,n},traf:function(e){return{boxes:Lo(e)}},trak:function(e){return{boxes:Lo(e)}},trex:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:t.getUint32(4),defaultSampleDescriptionIndex:t.getUint32(8),defaultSampleDuration:t.getUint32(12),defaultSampleSize:t.getUint32(16),sampleDependsOn:3&e[20],sampleIsDependedOn:(192&e[21])>>6,sampleHasRedundancy:(48&e[21])>>4,samplePaddingValue:(14&e[21])>>1,sampleIsDifferenceSample:!!(1&e[21]),sampleDegradationPriority:t.getUint16(22)}},trun:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]},n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=1&i.flags[2],a=4&i.flags[2],s=1&i.flags[1],o=2&i.flags[1],u=4&i.flags[1],l=8&i.flags[1],c=n.getUint32(4),h=8;for(r&&(i.dataOffset=n.getInt32(h),h+=4),a&&c&&(t={flags:Po(e.subarray(h,h+4))},h+=4,s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t),c--);c--;)t={},s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),u&&(t.flags=Po(e.subarray(h,h+4)),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t);return i},"url ":function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4))}},vmhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),graphicsmode:t.getUint16(4),opcolor:new Uint16Array([t.getUint16(6),t.getUint16(8),t.getUint16(10)])}}},bu={inspect:Lo=function(e){for(var t,i,n,r,a,s=0,o=[],u=new ArrayBuffer(e.length),l=new Uint8Array(u),c=0;c<e.length;++c)l[c]=e[c];for(t=new DataView(u);s<e.byteLength;)i=t.getUint32(s),n=vu(e.subarray(s+4,s+8)),r=1<i?s+i:e.byteLength,(a=(_u[n]||function(e){return{data:e}})(e.subarray(s+8,r))).size=i,a.type=n,o.push(a),s=r;return o},textify:Io=function(e,t){var a;return t=t||0,a=new Array(2*t+1).join(" "),e.map(function(r,e){return a+r.type+"\n"+Object.keys(r).filter(function(e){return"type"!==e&&"boxes"!==e}).map(function(e){var t=a+" "+e+": ",i=r[e];if(i instanceof Uint8Array||i instanceof Uint32Array){var n=Array.prototype.slice.call(new Uint8Array(i.buffer,i.byteOffset,i.byteLength)).map(function(e){return" "+("00"+e.toString(16)).slice(-2)}).join("").match(/.{1,24}/g);return n?1===n.length?t+"<"+n.join("").slice(1)+">":t+"<\n"+n.map(function(e){return a+" "+e}).join("\n")+"\n"+a+" >":t+"<>"}return t+JSON.stringify(i,null,2).split("\n").map(function(e,t){return 0===t?e:a+" "+e}).join("\n")}).join("\n")+(r.boxes?"\n"+Io(r.boxes,t+1):"")}).join("\n")},parseTfdt:_u.tfdt,parseHdlr:_u.hdlr,parseTfhd:_u.tfhd,parseTrun:_u.trun,parseSidx:_u.sidx},Tu=Math.pow(2,32)-1;!function(){var e;if(Jo={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],smhd:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],styp:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[]},"undefined"!=typeof Uint8Array){for(e in Jo)Jo.hasOwnProperty(e)&&(Jo[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);Zo=new Uint8Array(["i".charCodeAt(0),"s".charCodeAt(0),"o".charCodeAt(0),"m".charCodeAt(0)]),tu=new Uint8Array(["a".charCodeAt(0),"v".charCodeAt(0),"c".charCodeAt(0),"1".charCodeAt(0)]),eu=new Uint8Array([0,0,0,1]),iu=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]),nu=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]),ru={video:iu,audio:nu},ou=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),su=new Uint8Array([0,0,0,0,0,0,0,0]),uu=new Uint8Array([0,0,0,0,0,0,0,0]),lu=uu,cu=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),hu=uu,au=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}}(),Oo=function(e){var t,i,n=[],r=0;for(t=1;t<arguments.length;t++)n.push(arguments[t]);for(t=n.length;t--;)r+=n[t].byteLength;for(i=new Uint8Array(r+8),new DataView(i.buffer,i.byteOffset,i.byteLength).setUint32(0,i.byteLength),i.set(e,4),t=0,r=8;t<n.length;t++)i.set(n[t],r),r+=n[t].byteLength;return i},xo=function(){return Oo(Jo.dinf,Oo(Jo.dref,ou))},Uo=function(e){return Oo(Jo.esds,new Uint8Array([0,0,0,0,3,25,0,0,0,4,17,64,21,0,6,0,0,0,218,192,0,0,218,192,5,2,e.audioobjecttype<<3|e.samplingfrequencyindex>>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},Wo=function(e){return Oo(Jo.hdlr,ru[e])},zo=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(t[12]=e.samplerate>>>24&255,t[13]=e.samplerate>>>16&255,t[14]=e.samplerate>>>8&255,t[15]=255&e.samplerate),Oo(Jo.mdhd,t)},qo=function(e){return Oo(Jo.mdia,zo(e),Wo(e.type),Mo(e))},Ro=function(e){return Oo(Jo.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},Mo=function(e){return Oo(Jo.minf,"video"===e.type?Oo(Jo.vmhd,au):Oo(Jo.smhd,su),xo(),$o(e))},Bo=function(e,t){for(var i=[],n=t.length;n--;)i[n]=Ko(t[n]);return Oo.apply(null,[Jo.moof,Ro(e)].concat(i))},No=function(e){for(var t=e.length,i=[];t--;)i[t]=Vo(e[t]);return Oo.apply(null,[Jo.moov,Fo(4294967295)].concat(i).concat(jo(e)))},jo=function(e){for(var t=e.length,i=[];t--;)i[t]=Yo(e[t]);return Oo.apply(null,[Jo.mvex].concat(i))},Fo=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,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 Oo(Jo.mvhd,t)},Go=function(e){var t,i,n=e.samples||[],r=new Uint8Array(4+n.length);for(i=0;i<n.length;i++)t=n[i].flags,r[i+4]=t.dependsOn<<4|t.isDependedOn<<2|t.hasRedundancy;return Oo(Jo.sdtp,r)},$o=function(e){return Oo(Jo.stbl,Xo(e),Oo(Jo.stts,hu),Oo(Jo.stsc,lu),Oo(Jo.stsz,cu),Oo(Jo.stco,uu))},Xo=function(e){return Oo(Jo.stsd,new Uint8Array([0,0,0,0,0,0,0,1]),"video"===e.type?du(e):pu(e))},du=function(e){var t,i=e.sps||[],n=e.pps||[],r=[],a=[];for(t=0;t<i.length;t++)r.push((65280&i[t].byteLength)>>>8),r.push(255&i[t].byteLength),r=r.concat(Array.prototype.slice.call(i[t]));for(t=0;t<n.length;t++)a.push((65280&n[t].byteLength)>>>8),a.push(255&n[t].byteLength),a=a.concat(Array.prototype.slice.call(n[t]));return Oo(Jo.avc1,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,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),Oo(Jo.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([i.length]).concat(r).concat([n.length]).concat(a))),Oo(Jo.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))},pu=function(e){return Oo(Jo.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),Uo(e))},Ho=function(e){var t=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,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,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return Oo(Jo.tkhd,t)},Ko=function(e){var t,i,n,r,a,s;return t=Oo(Jo.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),a=Math.floor(e.baseMediaDecodeTime/(1+Tu)),s=Math.floor(e.baseMediaDecodeTime%(1+Tu)),i=Oo(Jo.tfdt,new Uint8Array([1,0,0,0,a>>>24&255,a>>>16&255,a>>>8&255,255&a,s>>>24&255,s>>>16&255,s>>>8&255,255&s])),92,"audio"===e.type?(n=Qo(e,92),Oo(Jo.traf,t,i,n)):(r=Go(e),n=Qo(e,r.length+92),Oo(Jo.traf,t,i,n,r))},Vo=function(e){return e.duration=e.duration||4294967295,Oo(Jo.trak,Ho(e),qo(e))},Yo=function(e){var t=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==e.type&&(t[t.length-1]=0),Oo(Jo.trex,t)},gu=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},mu=function(e,t){var i,n,r,a;for(t+=20+16*(n=e.samples||[]).length,i=gu(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size,r.flags.isLeading<<2|r.flags.dependsOn,r.flags.isDependedOn<<6|r.flags.hasRedundancy<<4|r.flags.paddingValue<<1|r.flags.isNonSyncSample,61440&r.flags.degradationPriority,15&r.flags.degradationPriority,(4278190080&r.compositionTimeOffset)>>>24,(16711680&r.compositionTimeOffset)>>>16,(65280&r.compositionTimeOffset)>>>8,255&r.compositionTimeOffset]);return Oo(Jo.trun,new Uint8Array(i))},fu=function(e,t){var i,n,r,a;for(t+=20+8*(n=e.samples||[]).length,i=gu(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size]);return Oo(Jo.trun,new Uint8Array(i))},Qo=function(e,t){return"audio"===e.type?fu(e,t):mu(e,t)};function Su(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){var i;return!!a[e]&&(i=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(i,1),-1<i)},this.trigger=function(e){var t,i,n,r;if(t=a[e])if(2===arguments.length)for(n=t.length,i=0;i<n;++i)t[i].call(this,arguments[1]);else{for(r=[],i=arguments.length,i=1;i<arguments.length;++i)r.push(arguments[i]);for(n=t.length,i=0;i<n;++i)t[i].apply(this,r)}},this.dispose=function(){a={}}}}var ku={ftyp:Do=function(){return Oo(Jo.ftyp,Zo,eu,Zo,tu)},mdat:function(e){return Oo(Jo.mdat,e)},moof:Bo,moov:No,initSegment:function(e){var t,i=Do(),n=No(e);return(t=new Uint8Array(i.byteLength+n.byteLength)).set(i),t.set(n,i.byteLength),t}};Su.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),t},Su.prototype.push=function(e){this.trigger("data",e)},Su.prototype.flush=function(e){this.trigger("done",e)};function wu(e){for(var t=[];e--;)t.push(0);return t}function Cu(){Cu.prototype.init.call(this),this.captionPackets_=[],this.ccStreams_=[new al(0,0),new al(0,1),new al(1,0),new al(1,1)],this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("done",this.trigger.bind(this,"done"))},this)}var Eu,Au,Pu,Lu,Iu,Ou=Su,xu=function(e){var t,i,n=[],r=[];for(t=n.byteLength=0;t<e.length;t++)"access_unit_delimiter_rbsp"===(i=e[t]).nalUnitType?(n.length&&(n.duration=i.dts-n.dts,r.push(n)),(n=[i]).byteLength=i.data.byteLength,n.pts=i.pts,n.dts=i.dts):("slice_layer_without_partitioning_rbsp_idr"===i.nalUnitType&&(n.keyFrame=!0),n.duration=i.dts-n.dts,n.byteLength+=i.data.byteLength,n.push(i));return r.length&&(!n.duration||n.duration<=0)&&(n.duration=r[r.length-1].duration),r.push(n),r},Uu=function(e){var t,i,n=[],r=[];for(n.byteLength=0,n.nalCount=0,n.duration=0,n.pts=e[0].pts,n.dts=e[0].dts,r.byteLength=0,r.nalCount=0,r.duration=0,r.pts=e[0].pts,r.dts=e[0].dts,t=0;t<e.length;t++)(i=e[t]).keyFrame?(n.length&&(r.push(n),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration),(n=[i]).nalCount=i.length,n.byteLength=i.byteLength,n.pts=i.pts,n.dts=i.dts,n.duration=i.duration):(n.duration+=i.duration,n.nalCount+=i.length,n.byteLength+=i.byteLength,n.push(i));return r.length&&n.duration<=0&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration,r.push(n),r},Du=function(e){var t;return!e[0][0].keyFrame&&1<e.length&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e},Ru=function(e,t){var i,n,r,a,s,o,u,l=t||0,c=[];for(i=0;i<e.length;i++)for(a=e[i],n=0;n<a.length;n++)s=a[n],o=s,u=void 0,(u={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}}).dataOffset=l,u.compositionTimeOffset=o.pts-o.dts,u.duration=o.duration,u.size=4*o.length,u.size+=o.byteLength,o.keyFrame&&(u.flags.dependsOn=2,u.flags.isNonSyncSample=0),l+=(r=u).size,c.push(r);return c},Mu=function(e){var t,i,n,r,a,s,o=0,u=e.byteLength,l=e.nalCount,c=new Uint8Array(u+4*l),h=new DataView(c.buffer);for(t=0;t<e.length;t++)for(r=e[t],i=0;i<r.length;i++)for(a=r[i],n=0;n<a.length;n++)s=a[n],h.setUint32(o,s.data.byteLength),o+=4,c.set(s.data,o),o+=s.data.byteLength;return c},Bu=[33,16,5,32,164,27],Nu=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],ju={96e3:[Bu,[227,64],wu(154),[56]],88200:[Bu,[231],wu(170),[56]],64e3:[Bu,[248,192],wu(240),[56]],48e3:[Bu,[255,192],wu(268),[55,148,128],wu(54),[112]],44100:[Bu,[255,192],wu(268),[55,163,128],wu(84),[112]],32e3:[Bu,[255,192],wu(268),[55,234],wu(226),[112]],24e3:[Bu,[255,192],wu(268),[55,255,128],wu(268),[111,112],wu(126),[224]],16e3:[Bu,[255,192],wu(268),[55,255,128],wu(268),[111,255],wu(269),[223,108],wu(195),[1,192]],12e3:[Nu,wu(268),[3,127,248],wu(268),[6,255,240],wu(268),[13,255,224],wu(268),[27,253,128],wu(259),[56]],11025:[Nu,wu(268),[3,127,248],wu(268),[6,255,240],wu(268),[13,255,224],wu(268),[27,255,192],wu(268),[55,175,128],wu(108),[112]],8e3:[Nu,wu(268),[3,121,16],wu(47),[7]]},Fu=(Eu=ju,Object.keys(Eu).reduce(function(e,t){return e[t]=new Uint8Array(Eu[t].reduce(function(e,t){return e.concat(t)},[])),e},{})),Vu=(Au=function(e){return 9e4*e},Pu=function(e,t){return e*t},Lu=function(e){return e/9e4},Iu=function(e,t){return e/t},function(e,t){return Au(Iu(e,t))}),Hu=function(e,t){return Pu(Lu(e),t)},qu=function(e,t,i,n){var r,a,s,o,u=0,l=0,c=0;if(t.length&&(r=Vu(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(9e4/(e.samplerate/1024)),i&&n&&(u=r-Math.max(i,n),c=(l=Math.floor(u/a))*a),!(l<1||45e3<c))){for(s=(s=Fu[e.samplerate])||t[0].data,o=0;o<l;o++)t.splice(o,0,{data:s});e.baseMediaDecodeTime-=Math.floor(Hu(c,e.samplerate))}},zu=function(e,t,i){return t.minSegmentDts>=i?e:(t.minSegmentDts=1/0,e.filter(function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)}))},Wu=function(e){var t,i,n=[];for(t=0;t<e.length;t++)i=e[t],n.push({size:i.data.byteLength,duration:1024});return n},Gu=function(e){var t,i,n=0,r=new Uint8Array(function(e){var t,i=0;for(t=0;t<e.length;t++)i+=e[t].data.byteLength;return i}(e));for(t=0;t<e.length;t++)i=e[t],r.set(i.data,n),n+=i.data.byteLength;return r},$u=function(e){delete e.minSegmentDts,delete e.maxSegmentDts,delete e.minSegmentPts,delete e.maxSegmentPts},Xu=function(e,t){var i,n=e.minSegmentDts;return t||(n-=e.timelineStartInfo.dts),i=e.timelineStartInfo.baseMediaDecodeTime,i+=n,i=Math.max(0,i),"audio"===e.type&&(i*=e.samplerate/9e4,i=Math.floor(i)),i},Ku=function(e,t){"number"==typeof t.pts&&(void 0===e.timelineStartInfo.pts&&(e.timelineStartInfo.pts=t.pts),void 0===e.minSegmentPts?e.minSegmentPts=t.pts:e.minSegmentPts=Math.min(e.minSegmentPts,t.pts),void 0===e.maxSegmentPts?e.maxSegmentPts=t.pts:e.maxSegmentPts=Math.max(e.maxSegmentPts,t.pts)),"number"==typeof t.dts&&(void 0===e.timelineStartInfo.dts&&(e.timelineStartInfo.dts=t.dts),void 0===e.minSegmentDts?e.minSegmentDts=t.dts:e.minSegmentDts=Math.min(e.minSegmentDts,t.dts),void 0===e.maxSegmentDts?e.maxSegmentDts=t.dts:e.maxSegmentDts=Math.max(e.maxSegmentDts,t.dts))},Yu=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}t+=r,r=n=0}return i},Qu=function(e){return 181!==e.payload[0]?null:49!=(e.payload[1]<<8|e.payload[2])?null:"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])?null:3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},Ju=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},Zu=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},el=4;(Cu.prototype=new Ou).push=function(e){var t,i,n;if("sei_rbsp"===e.nalUnitType&&(t=Yu(e.escapedRBSP)).payloadType===el&&(i=Qu(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));n=Ju(e.pts,i),this.captionPackets_=this.captionPackets_.concat(n),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},Cu.prototype.flush=function(){this.captionPackets_.length?(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2&&this.dispatchCea608Packet(e)},this),this.captionPackets_.length=0,this.ccStreams_.forEach(function(e){e.flush()},this)):this.ccStreams_.forEach(function(e){e.flush()},this)},Cu.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},Cu.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},Cu.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},Cu.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},Cu.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)};function tl(e){return null===e?"":(e=nl[e]||e,String.fromCharCode(e))}function il(){for(var e=[],t=15;t--;)e.push("");return e}var nl={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},rl=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],al=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a;if((t=32639&e.ccData)!==this.lastControlCode_){if(4096==(61440&t)?this.lastControlCode_=t:t!==this.PADDING_&&(this.lastControlCode_=null),n=t>>>8,r=255&t,t!==this.PADDING_)if(t===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(t===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),i=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=i,this.startPts_=e.pts;else if(t===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(e.pts);else if(t===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(e.pts);else if(t===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(e.pts);else if(t===this.CARRIAGE_RETURN_)this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts;else if(t===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1);else if(t===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(e.pts),this.displayed_=il();else if(t===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=il();else if(t===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=il()),this.mode_="paintOn",this.startPts_=e.pts;else if(this.isSpecialCharacter(n,r))a=tl((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isExtCharacter(n,r))"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),a=tl((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isMidRowCode(n,r))this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&r)&&this.addFormatting(e.pts,["i"]),1==(1&r)&&this.addFormatting(e.pts,["u"]);else if(this.isOffsetControlCode(n,r))this.column_+=3&r;else if(this.isPAC(n,r)){var s=rl.indexOf(7968&t);"rollUp"===this.mode_&&(s-this.rollUpRows_+1<0&&(s=this.rollUpRows_-1),this.setRollUp(e.pts,s)),s!==this.row_&&(this.clearFormatting(e.pts),this.row_=s),1&r&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&t)&&(this.column_=4*((14&t)>>1)),this.isColorPAC(r)&&14==(14&r)&&this.addFormatting(e.pts,["i"])}else this.isNormalChar(n)&&(0===r&&(r=null),a=tl(n),a+=tl(r),this[this.mode_](e.pts,a),this.column_+=a.length)}else this.lastControlCode_=null}};al.prototype=new Ou,al.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e){try{return e.trim()}catch(e){return""}}).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_})},al.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=il(),this.nonDisplayed_=il(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},al.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},al.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},al.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},al.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},al.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},al.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},al.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},al.prototype.isNormalChar=function(e){return 32<=e&&e<=127},al.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=il(),this.displayed_=il()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},al.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);var i=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,i)},al.prototype.clearFormatting=function(e){if(this.formatting_.length){var t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},"");this.formatting_=[],this[this.mode_](e,t)}},al.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];i+=t,this.nonDisplayed_[this.row_]=i},al.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i},al.prototype.shiftRowsUp_=function(){var e;for(e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},al.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i};function sl(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}function ol(e){var t,i;ol.prototype.init.call(this),this.type_=e,this.push=function(e){e.type===this.type_&&(void 0===i&&(i=e.dts),e.dts=sl(e.dts,i),e.pts=sl(e.pts,i),t=e.dts,this.trigger("data",e))},this.flush=function(){i=t,this.trigger("done")},this.discontinuity=function(){t=i=void 0}}var ul={CaptionStream:Cu,Cea608Stream:al},ll={H264_STREAM_TYPE:27,ADTS_STREAM_TYPE:15,METADATA_STREAM_TYPE:21};ol.prototype=new Ou;function cl(e,t,i){var n,r="";for(n=t;n<i;n++)r+="%"+("00"+e[n].toString(16)).slice(-2);return r}function hl(e,t,i){return decodeURIComponent(cl(e,t,i))}function dl(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var pl,fl=ol,ml=sl,gl={TXXX:function(e){var t;if(3===e.data[0]){for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=hl(e.data,1,t),e.value=hl(e.data,t+1,e.data.length).replace(/\0*$/,"");break}e.data=e.value}},WXXX:function(e){var t;if(3===e.data[0])for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=hl(e.data,1,t),e.url=hl(e.data,t+1,e.data.length);break}},PRIV:function(e){var t,i;for(t=0;t<e.data.length;t++)if(0===e.data[t]){e.owner=(i=e.data,unescape(cl(i,0,t)));break}e.privateData=e.data.subarray(t+1),e.data=e.privateData}};(pl=function(e){var t,u={debug:!(!e||!e.debug),descriptor:e&&e.descriptor},l=0,c=[],h=0;if(pl.prototype.init.call(this),this.dispatchType=ll.METADATA_STREAM_TYPE.toString(16),u.descriptor)for(t=0;t<u.descriptor.length;t++)this.dispatchType+=("00"+u.descriptor[t].toString(16)).slice(-2);this.push=function(e){var t,i,n,r,a;if("timed-metadata"===e.type)if(e.dataAlignmentIndicator&&(h=0,c.length=0),0===c.length&&(e.data.length<10||e.data[0]!=="I".charCodeAt(0)||e.data[1]!=="D".charCodeAt(0)||e.data[2]!=="3".charCodeAt(0)))u.debug;else if(c.push(e),h+=e.data.byteLength,1===c.length&&(l=dl(e.data.subarray(6,10)),l+=10),!(h<l)){for(t={data:new Uint8Array(l),frames:[],pts:c[0].pts,dts:c[0].dts},a=0;a<l;)t.data.set(c[0].data.subarray(0,l-a),a),a+=c[0].data.byteLength,h-=c[0].data.byteLength,c.shift();i=10,64&t.data[5]&&(i+=4,i+=dl(t.data.subarray(10,14)),l-=dl(t.data.subarray(16,20)));do{if((n=dl(t.data.subarray(i+4,i+8)))<1)return;if((r={id:String.fromCharCode(t.data[i],t.data[i+1],t.data[i+2],t.data[i+3]),data:t.data.subarray(i+10,i+n+10)}).key=r.id,gl[r.id]&&(gl[r.id](r),"com.apple.streaming.transportStreamTimestamp"===r.owner)){var s=r.data,o=(1&s[3])<<30|s[4]<<22|s[5]<<14|s[6]<<6|s[7]>>>2;o*=4,o+=3&s[7],r.timeStamp=o,void 0===t.pts&&void 0===t.dts&&(t.pts=r.timeStamp,t.dts=r.timeStamp),this.trigger("timestamp",r)}t.frames.push(r),i+=10,i+=n}while(i<l);this.trigger("data",t)}}}).prototype=new Ou;var yl,vl,_l,bl=pl,Tl=fl;(yl=function(){var r=new Uint8Array(188),a=0;yl.prototype.init.call(this),this.push=function(e){var t,i=0,n=188;for(a?((t=new Uint8Array(e.byteLength+a)).set(r.subarray(0,a)),t.set(e,a),a=0):t=e;n<t.byteLength;)71!==t[i]||71!==t[n]?(i++,n++):(this.trigger("data",t.subarray(i,n)),i+=188,n+=188);i<t.byteLength&&(r.set(t.subarray(i),0),a=t.byteLength-i)},this.flush=function(){188===a&&71===r[0]&&(this.trigger("data",r),a=0),this.trigger("done")}}).prototype=new Ou,(vl=function(){var n,r,a,s;vl.prototype.init.call(this),(s=this).packetsWaitingForPmt=[],this.programMapTable=void 0,n=function(e,t){var i=0;t.payloadUnitStartIndicator&&(i+=e[i]+1),"pat"===t.type?r(e.subarray(i),t):a(e.subarray(i),t)},r=function(e,t){t.section_number=e[7],t.last_section_number=e[8],s.pmtPid=(31&e[10])<<8|e[11],t.pmtPid=s.pmtPid},a=function(e,t){var i,n;if(1&e[5]){for(s.programMapTable={video:null,audio:null,"timed-metadata":{}},i=3+((15&e[1])<<8|e[2])-4,n=12+((15&e[10])<<8|e[11]);n<i;){var r=e[n],a=(31&e[n+1])<<8|e[n+2];r===ll.H264_STREAM_TYPE&&null===s.programMapTable.video?s.programMapTable.video=a:r===ll.ADTS_STREAM_TYPE&&null===s.programMapTable.audio?s.programMapTable.audio=a:r===ll.METADATA_STREAM_TYPE&&(s.programMapTable["timed-metadata"][a]=r),n+=5+((15&e[n+3])<<8|e[n+4])}t.programMapTable=s.programMapTable}},this.push=function(e){var t={},i=4;if(t.payloadUnitStartIndicator=!!(64&e[1]),t.pid=31&e[1],t.pid<<=8,t.pid|=e[2],1<(48&e[3])>>>4&&(i+=e[i]+1),0===t.pid)t.type="pat",n(e.subarray(i),t),this.trigger("data",t);else if(t.pid===this.pmtPid)for(t.type="pmt",n(e.subarray(i),t),this.trigger("data",t);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([e,i,t]):this.processPes_(e,i,t)},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=ll.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=ll.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i)}}).prototype=new Ou,vl.STREAM_TYPES={h264:27,adts:15},(_l=function(){function n(e,t,i){var n,r,a=new Uint8Array(e.size),s={type:t},o=0,u=0;if(e.data.length&&!(e.size<9)){for(s.trackId=e.data[0].pid,o=0;o<e.data.length;o++)r=e.data[o],a.set(r.data,u),u+=r.data.byteLength;!function(e,t){var i;t.packetLength=6+(e[4]<<8|e[5]),t.dataAlignmentIndicator=0!=(4&e[6]),192&(i=e[7])&&(t.pts=(14&e[9])<<27|(255&e[10])<<20|(254&e[11])<<12|(255&e[12])<<5|(254&e[13])>>>3,t.pts*=4,t.pts+=(6&e[13])>>>1,t.dts=t.pts,64&i&&(t.dts=(14&e[14])<<27|(255&e[15])<<20|(254&e[16])<<12|(255&e[17])<<5|(254&e[18])>>>3,t.dts*=4,t.dts+=(6&e[18])>>>1)),t.data=e.subarray(9+e[8])}(a,s),n="video"===t||s.packetLength<=e.size,(i||n)&&(e.size=0,e.data.length=0),n&&l.trigger("data",s)}}var l=this,r={data:[],size:0},a={data:[],size:0},s={data:[],size:0};_l.prototype.init.call(this),this.push=function(i){({pat:function(){},pes:function(){var e,t;switch(i.streamType){case ll.H264_STREAM_TYPE:case ll.H264_STREAM_TYPE:e=r,t="video";break;case ll.ADTS_STREAM_TYPE:e=a,t="audio";break;case ll.METADATA_STREAM_TYPE:e=s,t="timed-metadata";break;default:return}i.payloadUnitStartIndicator&&n(e,t,!0),e.data.push(i),e.size+=i.data.byteLength},pmt:function(){var e={type:"metadata",tracks:[]},t=i.programMapTable;null!==t.video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),l.trigger("data",e)}})[i.type]()},this.flush=function(){n(r,"video"),n(a,"audio"),n(s,"timed-metadata"),this.trigger("done")}}).prototype=new Ou;var Sl={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:yl,TransportParseStream:vl,ElementaryStream:_l,TimestampRolloverStream:Tl,CaptionStream:ul.CaptionStream,Cea608Stream:ul.Cea608Stream,MetadataStream:bl};for(var kl in ll)ll.hasOwnProperty(kl)&&(Sl[kl]=ll[kl]);var wl,Cl=Sl,El=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(wl=function(){var l;wl.prototype.init.call(this),this.push=function(e){var t,i,n,r,a,s,o=0,u=0;if("audio"===e.type)for(l?(r=l,(l=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),l.set(e.data,r.byteLength)):l=e.data;o+5<l.length;)if(255===l[o]&&240==(246&l[o+1])){if(i=2*(1&~l[o+1]),t=(3&l[o+3])<<11|l[o+4]<<3|(224&l[o+5])>>5,s=9e4*(a=1024*(1+(3&l[o+6])))/El[(60&l[o+2])>>>2],n=o+t,l.byteLength<n)return;if(this.trigger("data",{pts:e.pts+u*s,dts:e.dts+u*s,sampleCount:a,audioobjecttype:1+(l[o+2]>>>6&3),channelcount:(1&l[o+2])<<2|(192&l[o+3])>>>6,samplerate:El[(60&l[o+2])>>>2],samplingfrequencyindex:(60&l[o+2])>>>2,samplesize:16,data:l.subarray(o+7+i,n)}),l.byteLength===n)return void(l=void 0);u++,l=l.subarray(n)}else o++},this.flush=function(){this.trigger("done")}}).prototype=new Ou;var Al,Pl,Ll,Il=wl,Ol=function(n){var r=n.byteLength,a=0,s=0;this.length=function(){return 8*r},this.bitsAvailable=function(){return 8*r+s},this.loadWord=function(){var e=n.byteLength-r,t=new Uint8Array(4),i=Math.min(4,r);if(0===i)throw new Error("no bytes available");t.set(n.subarray(e,e+i)),a=new DataView(t.buffer).getUint32(0),s=8*i,r-=i},this.skipBits=function(e){var t;e<s||(e-=s,e-=8*(t=Math.floor(e/8)),r-=t,this.loadWord()),a<<=e,s-=e},this.readBits=function(e){var t=Math.min(s,e),i=a>>>32-t;return 0<(s-=t)?a<<=t:0<r&&this.loadWord(),0<(t=e-t)?i<<t|this.readBits(t):i},this.skipLeadingZeros=function(){var e;for(e=0;e<s;++e)if(0!=(a&2147483648>>>e))return a<<=e,s-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()};(Pl=function(){var i,n,r=0;Pl.prototype.init.call(this),this.push=function(e){var t;for(n=n?((t=new Uint8Array(n.byteLength+e.data.byteLength)).set(n),t.set(e.data,n.byteLength),t):e.data;r<n.byteLength-3;r++)if(1===n[r+2]){i=r+5;break}for(;i<n.byteLength;)switch(n[i]){case 0:if(0!==n[i-1]){i+=2;break}if(0!==n[i-2]){i++;break}for(r+3!==i-2&&this.trigger("data",n.subarray(r+3,i-2));1!==n[++i]&&i<n.length;);r=i-2,i+=3;break;case 1:if(0!==n[i-1]||0!==n[i-2]){i+=3;break}this.trigger("data",n.subarray(r+3,i-2)),r=i-2,i+=3;break;default:i+=3}n=n.subarray(r),i-=r,r=0},this.flush=function(){n&&3<n.byteLength&&this.trigger("data",n.subarray(r+3)),n=null,r=0,this.trigger("done")}}).prototype=new Ou,Ll={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(Al=function(){var i,n,r,a,s,o,_,t=new Pl;Al.prototype.init.call(this),(i=this).push=function(e){"video"===e.type&&(n=e.trackId,r=e.pts,a=e.dts,t.push(e))},t.on("data",function(e){var t={trackId:n,pts:r,dts:a,data:e};switch(31&e[0]){case 5:t.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:t.nalUnitType="sei_rbsp",t.escapedRBSP=s(e.subarray(1));break;case 7:t.nalUnitType="seq_parameter_set_rbsp",t.escapedRBSP=s(e.subarray(1)),t.config=o(t.escapedRBSP);break;case 8:t.nalUnitType="pic_parameter_set_rbsp";break;case 9:t.nalUnitType="access_unit_delimiter_rbsp"}i.trigger("data",t)}),t.on("done",function(){i.trigger("done")}),this.flush=function(){t.flush()},_=function(e,t){var i,n=8,r=8;for(i=0;i<e;i++)0!==r&&(r=(n+t.readExpGolomb()+256)%256),n=0===r?n:r},s=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},o=function(e){var t,i,n,r,a,s,o,u,l,c,h,d,p,f=0,m=0,g=0,y=0,v=1;if(i=(t=new Ol(e)).readUnsignedByte(),r=t.readUnsignedByte(),n=t.readUnsignedByte(),t.skipUnsignedExpGolomb(),Ll[i]&&(3===(a=t.readUnsignedExpGolomb())&&t.skipBits(1),t.skipUnsignedExpGolomb(),t.skipUnsignedExpGolomb(),t.skipBits(1),t.readBoolean()))for(h=3!==a?8:12,p=0;p<h;p++)t.readBoolean()&&_(p<6?16:64,t);if(t.skipUnsignedExpGolomb(),0===(s=t.readUnsignedExpGolomb()))t.readUnsignedExpGolomb();else if(1===s)for(t.skipBits(1),t.skipExpGolomb(),t.skipExpGolomb(),o=t.readUnsignedExpGolomb(),p=0;p<o;p++)t.skipExpGolomb();if(t.skipUnsignedExpGolomb(),t.skipBits(1),u=t.readUnsignedExpGolomb(),l=t.readUnsignedExpGolomb(),0===(c=t.readBits(1))&&t.skipBits(1),t.skipBits(1),t.readBoolean()&&(f=t.readUnsignedExpGolomb(),m=t.readUnsignedExpGolomb(),g=t.readUnsignedExpGolomb(),y=t.readUnsignedExpGolomb()),t.readBoolean()&&t.readBoolean()){switch(t.readUnsignedByte()){case 1:d=[1,1];break;case 2:d=[12,11];break;case 3:d=[10,11];break;case 4:d=[16,11];break;case 5:d=[40,33];break;case 6:d=[24,11];break;case 7:d=[20,11];break;case 8:d=[32,11];break;case 9:d=[80,33];break;case 10:d=[18,11];break;case 11:d=[15,11];break;case 12:d=[64,33];break;case 13:d=[160,99];break;case 14:d=[4,3];break;case 15:d=[3,2];break;case 16:d=[2,1];break;case 255:d=[t.readUnsignedByte()<<8|t.readUnsignedByte(),t.readUnsignedByte()<<8|t.readUnsignedByte()]}d&&(v=d[0]/d[1])}return{profileIdc:i,levelIdc:n,profileCompatibility:r,width:Math.ceil((16*(u+1)-2*f-2*m)*v),height:(2-c)*(l+1)*16-2*g-2*y}}}).prototype=new Ou;function xl(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var Ul,Dl={H264Stream:Al,NalByteStream:Pl},Rl=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],Ml={isLikelyAacData:function(e){return e[0]==="I".charCodeAt(0)&&e[1]==="D".charCodeAt(0)&&e[2]==="3".charCodeAt(0)},parseId3TagSize:function(e,t){var i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&e[t+5])>>4?20+i:10+i},parseAdtsSize:function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i},parseType:function(e,t){return e[t]==="I".charCodeAt(0)&&e[t+1]==="D".charCodeAt(0)&&e[t+2]==="3".charCodeAt(0)?"timed-metadata":!0&e[t]&&240==(240&e[t+1])?"audio":null},parseSampleRate:function(e){for(var t=0;t+5<e.length;){if(255===e[t]&&240==(246&e[t+1]))return Rl[(60&e[t+2])>>>2];t++}return null},parseAacTimestamp:function(e){var t,i,n;t=10,64&e[5]&&(t+=4,t+=xl(e.subarray(10,14)));do{if((i=xl(e.subarray(t+4,t+8)))<1)return null;if("PRIV"===String.fromCharCode(e[t],e[t+1],e[t+2],e[t+3])){n=e.subarray(t+10,t+i+10);for(var r=0;r<n.byteLength;r++)if(0===n[r]){if("com.apple.streaming.transportStreamTimestamp"!==unescape(function(e,t,i){var n,r="";for(n=t;n<i;n++)r+="%"+("00"+e[n].toString(16)).slice(-2);return r}(n,0,r)))break;var a=n.subarray(r+1),s=(1&a[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2;return s*=4,s+=3&a[7]}}t+=10,t+=i}while(t<e.byteLength);return null}};(Ul=function(){var o=new Uint8Array,u=0;Ul.prototype.init.call(this),this.setTimestamp=function(e){u=e},this.push=function(e){var t,i,n,r,a=0,s=0;for(o.length?(r=o.length,(o=new Uint8Array(e.byteLength+r)).set(o.subarray(0,r)),o.set(e,r)):o=e;3<=o.length-s;)if(o[s]!=="I".charCodeAt(0)||o[s+1]!=="D".charCodeAt(0)||o[s+2]!=="3".charCodeAt(0))if(255!=(255&o[s])||240!=(240&o[s+1]))s++;else{if(o.length-s<7)break;if(s+(a=Ml.parseAdtsSize(o,s))>o.length)break;n={type:"audio",data:o.subarray(s,s+a),pts:u,dts:u},this.trigger("data",n),s+=a}else{if(o.length-s<10)break;if(s+(a=Ml.parseId3TagSize(o,s))>o.length)break;i={type:"timed-metadata",data:o.subarray(s,s+a)},this.trigger("data",i),s+=a}t=o.length-s,o=0<t?o.subarray(s):new Uint8Array}}).prototype=new Ou;function Bl(e,t){var i;if(e.length!==t.length)return!1;for(i=0;i<e.length;i++)if(e[i]!==t[i])return!1;return!0}function Nl(e,t,i,n,r,a){return{start:{dts:e,pts:e+(i-t)},end:{dts:e+(n-t),pts:e+(r-i)},prependedContentDuration:a,baseMediaDecodeTime:e}}var jl,Fl,Vl,Hl,ql=Ul,zl=Dl.H264Stream,Wl=Ml.isLikelyAacData,Gl=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],$l=["width","height","profileIdc","levelIdc","profileCompatibility"];(Fl=function(r,a){var s=[],o=0,u=0,l=0,c=1/0;a=a||{},Fl.prototype.init.call(this),this.push=function(t){Ku(r,t),r&&Gl.forEach(function(e){r[e]=t[e]}),s.push(t)},this.setEarliestDts=function(e){u=e-r.timelineStartInfo.baseMediaDecodeTime},this.setVideoBaseMediaDecodeTime=function(e){c=e},this.setAudioAppendStart=function(e){l=e},this.flush=function(){var e,t,i,n;0!==s.length&&(e=zu(s,r,u),r.baseMediaDecodeTime=Xu(r,a.keepOriginalTimestamps),qu(r,e,l,c),r.samples=Wu(e),i=ku.mdat(Gu(e)),s=[],t=ku.moof(o,[r]),n=new Uint8Array(t.byteLength+i.byteLength),o++,n.set(t),n.set(i,t.byteLength),$u(r),this.trigger("data",{track:r,boxes:n})),this.trigger("done","AudioSegmentStream")}}).prototype=new Ou,(jl=function(c,h){var t,i,d=0,p=[],f=[];h=h||{},jl.prototype.init.call(this),delete c.minPTS,this.gopCache_=[],this.push=function(e){Ku(c,e),"seq_parameter_set_rbsp"!==e.nalUnitType||t||(t=e.config,c.sps=[e.data],$l.forEach(function(e){c[e]=t[e]},this)),"pic_parameter_set_rbsp"!==e.nalUnitType||i||(i=e.data,c.pps=[e.data]),p.push(e)},this.flush=function(){for(var e,t,i,n,r,a,s,o,u=0;p.length&&"access_unit_delimiter_rbsp"!==p[0].nalUnitType;)p.shift();if(0===p.length)return this.resetStream_(),void this.trigger("done","VideoSegmentStream");if(e=xu(p),(i=Uu(e))[0][0].keyFrame||((t=this.getGopForFusion_(p[0],c))?(u=t.duration,i.unshift(t),i.byteLength+=t.byteLength,i.nalCount+=t.nalCount,i.pts=t.pts,i.dts=t.dts,i.duration+=t.duration):i=Du(i)),f.length){var l;if(!(l=h.alignGopsAtEnd?this.alignGopsAtEnd_(i):this.alignGopsAtStart_(i)))return this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");$u(c),i=l}Ku(c,i),c.samples=Ru(i),r=ku.mdat(Mu(i)),c.baseMediaDecodeTime=Xu(c,h.keepOriginalTimestamps),this.trigger("processedGopsInfo",i.map(function(e){return{pts:e.pts,dts:e.dts,byteLength:e.byteLength}})),s=i[0],o=i[i.length-1],this.trigger("segmentTimingInfo",Nl(c.baseMediaDecodeTime,s.dts,s.pts,o.dts+o.duration,o.pts+o.duration,u)),this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.trigger("baseMediaDecodeTime",c.baseMediaDecodeTime),this.trigger("timelineStartInfo",c.timelineStartInfo),n=ku.moof(d,[c]),a=new Uint8Array(n.byteLength+r.byteLength),d++,a.set(n),a.set(r,n.byteLength),this.trigger("data",{track:c,boxes:a}),this.resetStream_(),this.trigger("done","VideoSegmentStream")},this.resetStream_=function(){$u(c),i=t=void 0},this.getGopForFusion_=function(e){var t,i,n,r,a,s=1/0;for(a=0;a<this.gopCache_.length;a++)n=(r=this.gopCache_[a]).gop,c.pps&&Bl(c.pps[0],r.pps[0])&&c.sps&&Bl(c.sps[0],r.sps[0])&&(n.dts<c.timelineStartInfo.dts||-1e4<=(t=e.dts-n.dts-n.duration)&&t<=45e3&&(!i||t<s)&&(i=r,s=t));return i?i.gop:null},this.alignGopsAtStart_=function(e){var t,i,n,r,a,s,o,u;for(a=e.byteLength,s=e.nalCount,o=e.duration,t=i=0;t<f.length&&i<e.length&&(n=f[t],r=e[i],n.pts!==r.pts);)r.pts>n.pts?t++:(i++,a-=r.byteLength,s-=r.nalCount,o-=r.duration);return 0===i?e:i===e.length?null:((u=e.slice(i)).byteLength=a,u.duration=o,u.nalCount=s,u.pts=u[0].pts,u.dts=u[0].dts,u)},this.alignGopsAtEnd_=function(e){var t,i,n,r,a,s,o;for(t=f.length-1,i=e.length-1,a=null,s=!1;0<=t&&0<=i;){if(n=f[t],r=e[i],n.pts===r.pts){s=!0;break}n.pts>r.pts?t--:(t===f.length-1&&(a=i),i--)}if(!s&&null===a)return null;if(0===(o=s?i:a))return e;var u=e.slice(o),l=u.reduce(function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e},{byteLength:0,duration:0,nalCount:0});return u.byteLength=l.byteLength,u.duration=l.duration,u.nalCount=l.nalCount,u.pts=u[0].pts,u.dts=u[0].dts,u},this.alignGopsWith=function(e){f=e}}).prototype=new Ou,(Hl=function(e,t){this.numberOfTracks=0,this.metadataStream=t,"undefined"!=typeof(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps&&(this.keepOriginalTimestamps=e.keepOriginalTimestamps),this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,Hl.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBoxes.push(e.boxes),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track),void("audio"===e.track.type&&(this.audioTrack=e.track)))}}).prototype=new Ou,Hl.prototype.flush=function(e){var t,i,n,r,a=0,s={captions:[],captionStreams:{},metadata:[],info:{}},o=0;if(this.pendingTracks.length<this.numberOfTracks){if("VideoSegmentStream"!==e&&"AudioSegmentStream"!==e)return;if(this.remuxTracks)return;if(0===this.pendingTracks.length)return this.emittedTracks++,void(this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}for(this.videoTrack?(o=this.videoTrack.timelineStartInfo.pts,$l.forEach(function(e){s.info[e]=this.videoTrack[e]},this)):this.audioTrack&&(o=this.audioTrack.timelineStartInfo.pts,Gl.forEach(function(e){s.info[e]=this.audioTrack[e]},this)),1===this.pendingTracks.length?s.type=this.pendingTracks[0].type:s.type="combined",this.emittedTracks+=this.pendingTracks.length,n=ku.initSegment(this.pendingTracks),s.initSegment=new Uint8Array(n.byteLength),s.initSegment.set(n),s.data=new Uint8Array(this.pendingBytes),r=0;r<this.pendingBoxes.length;r++)s.data.set(this.pendingBoxes[r],a),a+=this.pendingBoxes[r].byteLength;for(r=0;r<this.pendingCaptions.length;r++)(t=this.pendingCaptions[r]).startTime=t.startPts,this.keepOriginalTimestamps||(t.startTime-=o),t.startTime/=9e4,t.endTime=t.endPts,this.keepOriginalTimestamps||(t.endTime-=o),t.endTime/=9e4,s.captionStreams[t.stream]=!0,s.captions.push(t);for(r=0;r<this.pendingMetadata.length;r++)(i=this.pendingMetadata[r]).cueTime=i.pts,this.keepOriginalTimestamps||(i.cueTime-=o),i.cueTime/=9e4,s.metadata.push(i);s.metadata.dispatchType=this.metadataStream.dispatchType,this.pendingTracks.length=0,this.videoTrack=null,this.pendingBoxes.length=0,this.pendingCaptions.length=0,this.pendingBytes=0,this.pendingMetadata.length=0,this.trigger("data",s),this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},(Vl=function(n){var r,a,s=this,i=!0;Vl.prototype.init.call(this),n=n||{},this.baseMediaDecodeTime=n.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var t={};(this.transmuxPipeline_=t).type="aac",t.metadataStream=new Cl.MetadataStream,t.aacStream=new ql,t.audioTimestampRolloverStream=new Cl.TimestampRolloverStream("audio"),t.timedMetadataTimestampRolloverStream=new Cl.TimestampRolloverStream("timed-metadata"),t.adtsStream=new Il,t.coalesceStream=new Hl(n,t.metadataStream),t.headOfPipeline=t.aacStream,t.aacStream.pipe(t.audioTimestampRolloverStream).pipe(t.adtsStream),t.aacStream.pipe(t.timedMetadataTimestampRolloverStream).pipe(t.metadataStream).pipe(t.coalesceStream),t.metadataStream.on("timestamp",function(e){t.aacStream.setTimestamp(e.timeStamp)}),t.aacStream.on("data",function(e){"timed-metadata"!==e.type||t.audioSegmentStream||(a=a||{timelineStartInfo:{baseMediaDecodeTime:s.baseMediaDecodeTime},codec:"adts",type:"audio"},t.coalesceStream.numberOfTracks++,t.audioSegmentStream=new Fl(a,n),t.adtsStream.pipe(t.audioSegmentStream).pipe(t.coalesceStream))}),t.coalesceStream.on("data",this.trigger.bind(this,"data")),t.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setupTsPipeline=function(){var i={};(this.transmuxPipeline_=i).type="ts",i.metadataStream=new Cl.MetadataStream,i.packetStream=new Cl.TransportPacketStream,i.parseStream=new Cl.TransportParseStream,i.elementaryStream=new Cl.ElementaryStream,i.videoTimestampRolloverStream=new Cl.TimestampRolloverStream("video"),i.audioTimestampRolloverStream=new Cl.TimestampRolloverStream("audio"),i.timedMetadataTimestampRolloverStream=new Cl.TimestampRolloverStream("timed-metadata"),i.adtsStream=new Il,i.h264Stream=new zl,i.captionStream=new Cl.CaptionStream,i.coalesceStream=new Hl(n,i.metadataStream),i.headOfPipeline=i.packetStream,i.packetStream.pipe(i.parseStream).pipe(i.elementaryStream),i.elementaryStream.pipe(i.videoTimestampRolloverStream).pipe(i.h264Stream),i.elementaryStream.pipe(i.audioTimestampRolloverStream).pipe(i.adtsStream),i.elementaryStream.pipe(i.timedMetadataTimestampRolloverStream).pipe(i.metadataStream).pipe(i.coalesceStream),i.h264Stream.pipe(i.captionStream).pipe(i.coalesceStream),i.elementaryStream.on("data",function(e){var t;if("metadata"===e.type){for(t=e.tracks.length;t--;)r||"video"!==e.tracks[t].type?a||"audio"!==e.tracks[t].type||((a=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime):(r=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime;r&&!i.videoSegmentStream&&(i.coalesceStream.numberOfTracks++,i.videoSegmentStream=new jl(r,n),i.videoSegmentStream.on("timelineStartInfo",function(e){a&&(a.timelineStartInfo=e,i.audioSegmentStream.setEarliestDts(e.dts))}),i.videoSegmentStream.on("processedGopsInfo",s.trigger.bind(s,"gopInfo")),i.videoSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"videoSegmentTimingInfo")),i.videoSegmentStream.on("baseMediaDecodeTime",function(e){a&&i.audioSegmentStream.setVideoBaseMediaDecodeTime(e)}),i.h264Stream.pipe(i.videoSegmentStream).pipe(i.coalesceStream)),a&&!i.audioSegmentStream&&(i.coalesceStream.numberOfTracks++,i.audioSegmentStream=new Fl(a,n),i.adtsStream.pipe(i.audioSegmentStream).pipe(i.coalesceStream))}}),i.coalesceStream.on("data",this.trigger.bind(this,"data")),i.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setBaseMediaDecodeTime=function(e){var t=this.transmuxPipeline_;n.keepOriginalTimestamps||(this.baseMediaDecodeTime=e),a&&(a.timelineStartInfo.dts=void 0,a.timelineStartInfo.pts=void 0,$u(a),n.keepOriginalTimestamps||(a.timelineStartInfo.baseMediaDecodeTime=e),t.audioTimestampRolloverStream&&t.audioTimestampRolloverStream.discontinuity()),r&&(t.videoSegmentStream&&(t.videoSegmentStream.gopCache_=[],t.videoTimestampRolloverStream.discontinuity()),r.timelineStartInfo.dts=void 0,r.timelineStartInfo.pts=void 0,$u(r),t.captionStream.reset(),n.keepOriginalTimestamps||(r.timelineStartInfo.baseMediaDecodeTime=e)),t.timedMetadataTimestampRolloverStream&&t.timedMetadataTimestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(e){a&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e)},this.alignGopsWith=function(e){r&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e)},this.push=function(e){if(i){var t=Wl(e);t&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),i=!1}this.transmuxPipeline_.headOfPipeline.push(e)},this.flush=function(){i=!0,this.transmuxPipeline_.headOfPipeline.flush()},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset()}}).prototype=new Ou;function Xl(e,t){for(var i=e,n=0;n<t.length;n++){var r=t[n];if(i<r.size)return r;i-=r.size}return null}function Kl(e,c){var n=yu.findBox(e,["moof","traf"]),t=yu.findBox(e,["mdat"]),h={},r=[];return t.forEach(function(e,t){var i=n[t];r.push({mdat:e,traf:i})}),r.forEach(function(e){var t,i=e.mdat,n=e.traf,r=yu.findBox(n,["tfhd"]),a=bu.parseTfhd(r[0]),s=a.trackId,o=yu.findBox(n,["tfdt"]),u=0<o.length?bu.parseTfdt(o[0]).baseMediaDecodeTime:0,l=yu.findBox(n,["trun"]);c===s&&0<l.length&&(t=function(e,t,i){var n,r,a,s,o=new DataView(e.buffer,e.byteOffset,e.byteLength),u=[];for(r=0;r+4<e.length;r+=a)if(a=o.getUint32(r),r+=4,!(a<=0))switch(31&e[r]){case 6:var l=e.subarray(r+1,r+1+a),c=Xl(r,t);n={nalUnitType:"sei_rbsp",size:a,data:l,escapedRBSP:tc(l),trackId:i},c?(n.pts=c.pts,n.dts=c.dts,s=c):(n.pts=s.pts,n.dts=s.dts),u.push(n)}return u}(i,function(e,t,i){var n=t,r=i.defaultSampleDuration||0,a=i.defaultSampleSize||0,s=i.trackId,o=[];return e.forEach(function(e){var t=bu.parseTrun(e).samples;t.forEach(function(e){void 0===e.duration&&(e.duration=r),void 0===e.size&&(e.size=a),e.trackId=s,e.dts=n,void 0===e.compositionTimeOffset&&(e.compositionTimeOffset=0),e.pts=n+e.compositionTimeOffset,n+=e.duration}),o=o.concat(t)}),o}(l,u,a),s),h[s]||(h[s]=[]),h[s]=h[s].concat(t))}),h}function Yl(e){var t=31&e[1];return t<<=8,t|=e[2]}function Ql(e){return!!(64&e[1])}function Jl(e){var t=0;return 1<(48&e[3])>>>4&&(t+=e[4]+1),t}function Zl(e){switch(e){case 5:return"slice_layer_without_partitioning_rbsp_idr";case 6:return"sei_rbsp";case 7:return"seq_parameter_set_rbsp";case 8:return"pic_parameter_set_rbsp";case 9:return"access_unit_delimiter_rbsp";default:return null}}var ec={Transmuxer:Vl,VideoSegmentStream:jl,AudioSegmentStream:Fl,AUDIO_PROPERTIES:Gl,VIDEO_PROPERTIES:$l,generateVideoSegmentTimingInfo:Nl},tc=Zu,ic=ul.CaptionStream,nc={generator:ku,probe:yu,Transmuxer:ec.Transmuxer,AudioSegmentStream:ec.AudioSegmentStream,VideoSegmentStream:ec.VideoSegmentStream,CaptionParser:function(){var t,a,s,o,u,e=!1;this.isInitialized=function(){return e},this.init=function(){t=new ic,e=!0,t.on("data",function(e){e.startTime=e.startPts/o,e.endTime=e.endPts/o,u.captions.push(e),u.captionStreams[e.stream]=!0})},this.isNewInit=function(e,t){return!(e&&0===e.length||t&&"object"==typeof t&&0===Object.keys(t).length)&&(s!==e[0]||o!==t[s])},this.parse=function(e,t,i){var n;if(!this.isInitialized())return null;if(!t||!i)return null;if(this.isNewInit(t,i))s=t[0],o=i[s];else if(!s||!o)return a.push(e),null;for(;0<a.length;){var r=a.shift();this.parse(r,t,i)}return null!==(n=function(e,t,i){return t?{seiNals:Kl(e,t)[t],timescale:i}:null}(e,s,o))&&n.seiNals?(this.pushNals(n.seiNals),this.flushStream(),u):null},this.pushNals=function(e){if(!this.isInitialized()||!e||0===e.length)return null;e.forEach(function(e){t.push(e)})},this.flushStream=function(){if(!this.isInitialized())return null;t.flush()},this.clearParsedCaptions=function(){u.captions=[],u.captionStreams={}},this.resetCaptionStream=function(){if(!this.isInitialized())return null;t.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){a=[],o=s=null,u?this.clearParsedCaptions():u={captions:[],captionStreams:{}},this.resetCaptionStream()},this.reset()}}.CaptionParser,rc={parseType:function(e,t){var i=Yl(e);return 0===i?"pat":i===t?"pmt":t?"pes":null},parsePat:function(e){var t=Ql(e),i=4+Jl(e);return t&&(i+=e[i]+1),(31&e[i+10])<<8|e[i+11]},parsePmt:function(e){var t={},i=Ql(e),n=4+Jl(e);if(i&&(n+=e[n]+1),1&e[n+5]){var r;r=3+((15&e[n+1])<<8|e[n+2])-4;for(var a=12+((15&e[n+10])<<8|e[n+11]);a<r;){var s=n+a;t[(31&e[s+1])<<8|e[s+2]]=e[s],a+=5+((15&e[s+3])<<8|e[s+4])}return t}},parsePayloadUnitStartIndicator:Ql,parsePesType:function(e,t){switch(t[Yl(e)]){case ll.H264_STREAM_TYPE:return"video";case ll.ADTS_STREAM_TYPE:return"audio";case ll.METADATA_STREAM_TYPE:return"timed-metadata";default:return null}},parsePesTime:function(e){if(!Ql(e))return null;var t=4+Jl(e);if(t>=e.byteLength)return null;var i,n=null;return 192&(i=e[t+7])&&((n={}).pts=(14&e[t+9])<<27|(255&e[t+10])<<20|(254&e[t+11])<<12|(255&e[t+12])<<5|(254&e[t+13])>>>3,n.pts*=4,n.pts+=(6&e[t+13])>>>1,n.dts=n.pts,64&i&&(n.dts=(14&e[t+14])<<27|(255&e[t+15])<<20|(254&e[t+16])<<12|(255&e[t+17])<<5|(254&e[t+18])>>>3,n.dts*=4,n.dts+=(6&e[t+18])>>>1)),n},videoPacketContainsKeyFrame:function(e){for(var t=4+Jl(e),i=e.subarray(t),n=0,r=0,a=!1;r<i.byteLength-3;r++)if(1===i[r+2]){n=r+5;break}for(;n<i.byteLength;)switch(i[n]){case 0:if(0!==i[n-1]){n+=2;break}if(0!==i[n-2]){n++;break}for(r+3!==n-2&&"slice_layer_without_partitioning_rbsp_idr"===Zl(31&i[r+3])&&(a=!0);1!==i[++n]&&n<i.length;);r=n-2,n+=3;break;case 1:if(0!==i[n-1]||0!==i[n-2]){n+=3;break}"slice_layer_without_partitioning_rbsp_idr"===Zl(31&i[r+3])&&(a=!0),r=n-2,n+=3;break;default:n+=3}return i=i.subarray(r),n-=r,r=0,i&&3<i.byteLength&&"slice_layer_without_partitioning_rbsp_idr"===Zl(31&i[r+3])&&(a=!0),a}},ac=ml,sc={};sc.ts=rc,sc.aac=Ml;function oc(e,t,i){for(var n,r,a,s,o=0,u=cc,l=!1;u<=e.byteLength;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o++,u++;else{switch(n=e.subarray(o,u),sc.ts.parseType(n,t.pid)){case"pes":r=sc.ts.parsePesType(n,t.table),a=sc.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=sc.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)}if(l)break;o+=cc,u+=cc}for(o=(u=e.byteLength)-cc,l=!1;0<=o;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o--,u--;else{switch(n=e.subarray(o,u),sc.ts.parseType(n,t.pid)){case"pes":r=sc.ts.parsePesType(n,t.table),a=sc.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=sc.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)}if(l)break;o-=cc,u-=cc}}function uc(e,t,i){for(var n,r,a,s,o,u,l,c=0,h=cc,d=!1,p={data:[],size:0};h<e.byteLength;)if(71!==e[c]||71!==e[h])c++,h++;else{switch(n=e.subarray(c,h),sc.ts.parseType(n,t.pid)){case"pes":if(r=sc.ts.parsePesType(n,t.table),a=sc.ts.parsePayloadUnitStartIndicator(n),"video"===r&&(a&&!d&&(s=sc.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),d=!0),!i.firstKeyFrame)){if(a&&0!==p.size){for(o=new Uint8Array(p.size),u=0;p.data.length;)l=p.data.shift(),o.set(l,u),u+=l.byteLength;if(sc.ts.videoPacketContainsKeyFrame(o)){var f=sc.ts.parsePesTime(o);f&&(i.firstKeyFrame=f,i.firstKeyFrame.type="video")}p.size=0}p.data.push(n),p.size+=n.byteLength}}if(d&&i.firstKeyFrame)break;c+=cc,h+=cc}for(c=(h=e.byteLength)-cc,d=!1;0<=c;)if(71!==e[c]||71!==e[h])c--,h--;else{switch(n=e.subarray(c,h),sc.ts.parseType(n,t.pid)){case"pes":r=sc.ts.parsePesType(n,t.table),a=sc.ts.parsePayloadUnitStartIndicator(n),"video"===r&&a&&(s=sc.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),d=!0)}if(d)break;c-=cc,h-=cc}}function lc(e){var t={pid:null,table:null},i={};for(var n in function(e,t){for(var i,n=0,r=cc;r<e.byteLength;)if(71!==e[n]||71!==e[r])n++,r++;else{switch(i=e.subarray(n,r),sc.ts.parseType(i,t.pid)){case"pat":t.pid||(t.pid=sc.ts.parsePat(i));break;case"pmt":t.table||(t.table=sc.ts.parsePmt(i))}if(t.pid&&t.table)return;n+=cc,r+=cc}}(e,t),t.table){if(t.table.hasOwnProperty(n))switch(t.table[n]){case ll.H264_STREAM_TYPE:i.video=[],uc(e,t,i),0===i.video.length&&delete i.video;break;case ll.ADTS_STREAM_TYPE:i.audio=[],oc(e,t,i),0===i.audio.length&&delete i.audio}}return i}var cc=188,hc=function(e,t){var i;return(i=sc.aac.isLikelyAacData(e)?function(e){for(var t,i=!1,n=0,r=null,a=null,s=0,o=0;3<=e.length-o;){switch(sc.aac.parseType(e,o)){case"timed-metadata":if(e.length-o<10){i=!0;break}if((s=sc.aac.parseId3TagSize(e,o))>e.length){i=!0;break}null===a&&(t=e.subarray(o,o+s),a=sc.aac.parseAacTimestamp(t)),o+=s;break;case"audio":if(e.length-o<7){i=!0;break}if((s=sc.aac.parseAdtsSize(e,o))>e.length){i=!0;break}null===r&&(t=e.subarray(o,o+s),r=sc.aac.parseSampleRate(t)),n++,o+=s;break;default:o++}if(i)return null}if(null===r||null===a)return null;var u=9e4/r;return{audio:[{type:"audio",dts:a,pts:a},{type:"audio",dts:a+1024*n*u,pts:a+1024*n*u}]}}(e):lc(e))&&(i.audio||i.video)?(function(e,t){if(e.audio&&e.audio.length){var i=t;"undefined"==typeof i&&(i=e.audio[0].dts),e.audio.forEach(function(e){e.dts=ac(e.dts,i),e.pts=ac(e.pts,i),e.dtsTime=e.dts/9e4,e.ptsTime=e.pts/9e4})}if(e.video&&e.video.length){var n=t;if("undefined"==typeof n&&(n=e.video[0].dts),e.video.forEach(function(e){e.dts=ac(e.dts,n),e.pts=ac(e.pts,n),e.dtsTime=e.dts/9e4,e.ptsTime=e.pts/9e4}),e.firstKeyFrame){var r=e.firstKeyFrame;r.dts=ac(r.dts,n),r.pts=ac(r.pts,n),r.dtsTime=r.dts/9e4,r.ptsTime=r.dts/9e4}}}(i,t),i):null};function dc(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var pc=function(e,t,i){return t&&fc(e.prototype,t),i&&fc(e,i),e};function fc(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}var mc=null,gc=(yc.prototype.decrypt=function(e,t,i,n,r,a){var s=this._key[1],o=e^s[0],u=n^s[1],l=i^s[2],c=t^s[3],h=void 0,d=void 0,p=void 0,f=s.length/4-2,m=void 0,g=4,y=this._tables[1],v=y[0],_=y[1],b=y[2],T=y[3],S=y[4];for(m=0;m<f;m++)h=v[o>>>24]^_[u>>16&255]^b[l>>8&255]^T[255&c]^s[g],d=v[u>>>24]^_[l>>16&255]^b[c>>8&255]^T[255&o]^s[g+1],p=v[l>>>24]^_[c>>16&255]^b[o>>8&255]^T[255&u]^s[g+2],c=v[c>>>24]^_[o>>16&255]^b[u>>8&255]^T[255&l]^s[g+3],g+=4,o=h,u=d,l=p;for(m=0;m<4;m++)r[(3&-m)+a]=S[o>>>24]<<24^S[u>>16&255]<<16^S[l>>8&255]<<8^S[255&c]^s[g++],h=o,o=u,u=l,l=c,c=h},yc);function yc(e){dc(this,yc),mc=mc||function(){var e=[[[],[],[],[],[]],[[],[],[],[],[]]],t=e[0],i=e[1],n=t[4],r=i[4],a=void 0,s=void 0,o=void 0,u=[],l=[],c=void 0,h=void 0,d=void 0,p=void 0,f=void 0;for(a=0;a<256;a++)l[(u[a]=a<<1^283*(a>>7))^a]=a;for(s=o=0;!n[s];s^=c||1,o=l[o]||1)for(d=(d=o^o<<1^o<<2^o<<3^o<<4)>>8^255&d^99,f=16843009*u[h=u[c=u[r[n[s]=d]=s]]]^65537*h^257*c^16843008*s,p=257*u[d]^16843008*d,a=0;a<4;a++)t[a][s]=p=p<<24^p>>>8,i[a][d]=f=f<<24^f>>>8;for(a=0;a<5;a++)t[a]=t[a].slice(0),i[a]=i[a].slice(0);return e}(),this._tables=[[mc[0][0].slice(),mc[0][1].slice(),mc[0][2].slice(),mc[0][3].slice(),mc[0][4].slice()],[mc[1][0].slice(),mc[1][1].slice(),mc[1][2].slice(),mc[1][3].slice(),mc[1][4].slice()]];var t=void 0,i=void 0,n=void 0,r=void 0,a=void 0,s=this._tables[0][4],o=this._tables[1],u=e.length,l=1;if(4!==u&&6!==u&&8!==u)throw new Error("Invalid aes key size");for(r=e.slice(0),a=[],this._key=[r,a],t=u;t<4*u+28;t++)n=r[t-1],(t%u==0||8===u&&t%u==4)&&(n=s[n>>>24]<<24^s[n>>16&255]<<16^s[n>>8&255]<<8^s[255&n],t%u==0&&(n=n<<8^n>>>24^l<<24,l=l<<1^283*(l>>7))),r[t]=r[t-u]^n;for(i=0;t;i++,t--)n=r[3&i?t:t-4],a[i]=t<=4||i<4?n:o[0][s[n>>>24]]^o[1][s[n>>16&255]]^o[2][s[n>>8&255]]^o[3][s[255&n]]}var vc=(_c.prototype.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},_c.prototype.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},_c.prototype.trigger=function(e,t){var i=this.listeners[e];if(i)if(2===arguments.length)for(var n=i.length,r=0;r<n;++r)i[r].call(this,t);else for(var a=Array.prototype.slice.call(arguments,1),s=i.length,o=0;o<s;++o)i[o].apply(this,a)},_c.prototype.dispose=function(){this.listeners={}},_c.prototype.pipe=function(t){this.on("data",function(e){t.push(e)})},_c);function _c(){dc(this,_c),this.listeners={}}var bc,Tc=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(Sc,bc=vc),Sc.prototype.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},Sc.prototype.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},Sc);function Sc(){dc(this,Sc);var e=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,bc.call(this,vc));return e.jobs=[],e.delay=1,e.timeout_=null,e}function kc(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24}function wc(e,t,i){var n=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),r=new gc(Array.prototype.slice.call(t)),a=new Uint8Array(e.byteLength),s=new Int32Array(a.buffer),o=void 0,u=void 0,l=void 0,c=void 0,h=void 0,d=void 0,p=void 0,f=void 0,m=void 0;for(o=i[0],u=i[1],l=i[2],c=i[3],m=0;m<n.length;m+=4)h=kc(n[m]),d=kc(n[m+1]),p=kc(n[m+2]),f=kc(n[m+3]),r.decrypt(h,d,p,f,s,m),s[m]=kc(s[m]^o),s[m+1]=kc(s[m+1]^u),s[m+2]=kc(s[m+2]^l),s[m+3]=kc(s[m+3]^c),o=h,u=d,l=p,c=f;return a}var Cc=(Ec.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=wc(t,i,n);r.set(e,t.byteOffset)}},pc(Ec,null,[{key:"STEP",get:function(){return 32e3}}]),Ec);function Ec(e,t,i,n){dc(this,Ec);var r=Ec.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new Tc,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([kc(a[o-4]),kc(a[o-3]),kc(a[o-2]),kc(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){n(null,function(e){return e.subarray(0,e.byteLength-e[e.byteLength-1])}(s))})}function Ac(e,t){return/^[a-z]+:/i.test(t)?t:(/\/\//i.test(e)||(e=ks.buildAbsoluteURL(v.location.href,e)),ks.buildAbsoluteURL(e,t))}function Pc(e,t,i){return e&&i.responseURL&&t!==i.responseURL?i.responseURL:t}function Lc(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("global/window"),require("global/document")):"function"==typeof define&&define.amd?define(["global/window","global/document"],t):(e=e||self).videojs=t(e.window,e.document)}(this,function(v,h){v=v&&v.hasOwnProperty("default")?v.default:v,h=h&&h.hasOwnProperty("default")?h.default:h;var d="7.6.6",u=[],e=function(s,o){return function(e,t,i){var n=o.levels[t],r=new RegExp("^("+n+")$");if("log"!==e&&i.unshift(e.toUpperCase()+":"),i.unshift(s+":"),u&&u.push([].concat(i)),v.console){var a=v.console[e];a||"debug"!==e||(a=v.console.info||v.console.log),a&&n&&r.test(e)&&a[Array.isArray(i)?"apply":"call"](v.console,i)}}};var p=function t(i){function n(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];r("log",a,t)}var r,a="info";return r=e(i,n),n.createLogger=function(e){return t(i+": "+e)},n.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:a},n.level=function(e){if("string"==typeof e){if(!n.levels.hasOwnProperty(e))throw new Error('"'+e+'" in not a valid log level');a=e}return a},(n.history=function(){return u?[].concat(u):[]}).filter=function(t){return(u||[]).filter(function(e){return new RegExp(".*"+t+".*").test(e[0])})},n.history.clear=function(){u&&(u.length=0)},n.history.disable=function(){null!==u&&(u.length=0,u=null)},n.history.enable=function(){null===u&&(u=[])},n.error=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("error",a,t)},n.warn=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("warn",a,t)},n.debug=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return r("debug",a,t)},n}("VIDEOJS"),f=p.createLogger,t=Object.prototype.toString,a=function(e){return s(e)?Object.keys(e):[]};function r(t,i){a(t).forEach(function(e){return i(t[e],e)})}function m(i){for(var e=arguments.length,t=new Array(1<e?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];return Object.assign?Object.assign.apply(Object,[i].concat(t)):(t.forEach(function(e){e&&r(e,function(e,t){i[t]=e})}),i)}function s(e){return!!e&&"object"==typeof e}function o(e){return s(e)&&"[object Object]"===t.call(e)&&e.constructor===Object}function n(e,t){if(!e||!t)return"";if("function"!=typeof v.getComputedStyle)return"";var i=v.getComputedStyle(e);return i?i.getPropertyValue(t)||i[t]:""}function l(e){return"string"==typeof e&&/\S/.test(e)}function i(e){if(/\s/.test(e))throw new Error("class has illegal whitespace characters")}function c(){return h===v.document}function g(e){return s(e)&&1===e.nodeType}function y(){try{return v.parent!==v.self}catch(e){return!0}}function _(n){return function(e,t){if(!l(e))return h[n](null);l(t)&&(t=h.querySelector(t));var i=g(t)?t:h;return i[n]&&i[n](e)}}function b(e,i,t,n){void 0===e&&(e="div"),void 0===i&&(i={}),void 0===t&&(t={});var r=h.createElement(e);return Object.getOwnPropertyNames(i).forEach(function(e){var t=i[e];-1!==e.indexOf("aria-")||"role"===e||"type"===e?(p.warn("Setting attributes in the second argument of createEl()\nhas been deprecated. Use the third argument instead.\ncreateEl(type, properties, attributes). Attempting to set "+e+" to "+t+"."),r.setAttribute(e,t)):"textContent"===e?T(r,t):r[e]=t}),Object.getOwnPropertyNames(t).forEach(function(e){r.setAttribute(e,t[e])}),n&&F(r,n),r}function T(e,t){return"undefined"==typeof e.textContent?e.innerText=t:e.textContent=t,e}function S(e,t){t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e)}function k(e,t){return i(t),e.classList?e.classList.contains(t):function(e){return new RegExp("(^|\\s)"+e+"($|\\s)")}(t).test(e.className)}function C(e,t){return e.classList?e.classList.add(t):k(e,t)||(e.className=(e.className+" "+t).trim()),e}function E(e,t){return e.classList?e.classList.remove(t):(i(t),e.className=e.className.split(/\s+/).filter(function(e){return e!==t}).join(" ")),e}function w(e,t,i){var n=k(e,t);if("function"==typeof i&&(i=i(e,t)),"boolean"!=typeof i&&(i=!n),i!==n)return i?C(e,t):E(e,t),e}function A(i,n){Object.getOwnPropertyNames(n).forEach(function(e){var t=n[e];null===t||"undefined"==typeof t||!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})}function P(e){var t={},i=",autoplay,controls,playsinline,loop,muted,default,defaultMuted,";if(e&&e.attributes&&0<e.attributes.length)for(var n=e.attributes,r=n.length-1;0<=r;r--){var a=n[r].name,s=n[r].value;"boolean"!=typeof e[a]&&-1===i.indexOf(","+a+",")||(s=null!==s),t[a]=s}return t}function I(e,t){return e.getAttribute(t)}function L(e,t,i){e.setAttribute(t,i)}function O(e,t){e.removeAttribute(t)}function x(){h.body.focus(),h.onselectstart=function(){return!1}}function D(){h.onselectstart=function(){return!0}}function U(e){if(e&&e.getBoundingClientRect&&e.parentNode){var t=e.getBoundingClientRect(),i={};return["bottom","height","left","right","top","width"].forEach(function(e){void 0!==t[e]&&(i[e]=t[e])}),i.height||(i.height=parseFloat(n(e,"height"))),i.width||(i.width=parseFloat(n(e,"width"))),i}}function R(e){var t;if(e.getBoundingClientRect&&e.parentNode&&(t=e.getBoundingClientRect()),!t)return{left:0,top:0};var i=h.documentElement,n=h.body,r=i.clientLeft||n.clientLeft||0,a=v.pageXOffset||n.scrollLeft,s=t.left+a-r,o=i.clientTop||n.clientTop||0,u=v.pageYOffset||n.scrollTop,l=t.top+u-o;return{left:Math.round(s),top:Math.round(l)}}function M(e,t){var i={},n=R(e),r=e.offsetWidth,a=e.offsetHeight,s=n.top,o=n.left,u=t.pageY,l=t.pageX;return t.changedTouches&&(l=t.changedTouches[0].pageX,u=t.changedTouches[0].pageY),i.y=Math.max(0,Math.min(1,(s-u+a)/a)),i.x=Math.max(0,Math.min(1,(l-o)/r)),i}function N(e){return s(e)&&3===e.nodeType}function B(e){for(;e.firstChild;)e.removeChild(e.firstChild);return e}function j(e){return"function"==typeof e&&(e=e()),(Array.isArray(e)?e:[e]).map(function(e){return"function"==typeof e&&(e=e()),g(e)||N(e)?e:"string"==typeof e&&/\S/.test(e)?h.createTextNode(e):void 0}).filter(function(e){return e})}function F(t,e){return j(e).forEach(function(e){return t.appendChild(e)}),t}function H(e,t){return F(B(e),t)}function V(e){return void 0===e.button&&void 0===e.buttons||(0===e.button&&void 0===e.buttons||("mouseup"===e.type&&0===e.button&&0===e.buttons||0===e.button&&1===e.buttons))}var q,W=_("querySelector"),z=_("querySelectorAll"),$=Object.freeze({isReal:c,isEl:g,isInFrame:y,createEl:b,textContent:T,prependTo:S,hasClass:k,addClass:C,removeClass:E,toggleClass:w,setAttributes:A,getAttributes:P,getAttribute:I,setAttribute:L,removeAttribute:O,blockTextSelection:x,unblockTextSelection:D,getBoundingClientRect:U,findPosition:R,getPointerPosition:M,isTextNode:N,emptyEl:B,normalizeContent:j,appendContent:F,insertContent:H,isSingleLeftClick:V,$:W,$$:z}),G=!1,X=function(){if(c()&&!1!==q.options.autoSetup){var e=Array.prototype.slice.call(h.getElementsByTagName("video")),t=Array.prototype.slice.call(h.getElementsByTagName("audio")),i=Array.prototype.slice.call(h.getElementsByTagName("video-js")),n=e.concat(t,i);if(n&&0<n.length)for(var r=0,a=n.length;r<a;r++){var s=n[r];if(!s||!s.getAttribute){K(1);break}void 0===s.player&&null!==s.getAttribute("data-setup")&&q(s)}else G||K(1)}};function K(e,t){t&&(q=t),v.setTimeout(X,e)}function Y(){G=!0,v.removeEventListener("load",Y)}c()&&("complete"===h.readyState?Y():v.addEventListener("load",Y));function Q(e){var t=h.createElement("style");return t.className=e,t}function J(e,t){e.styleSheet?e.styleSheet.cssText=t:e.textContent=t}var Z,ee=3;function te(){return ee++}v.WeakMap||(Z=function(){function e(){this.vdata="vdata"+Math.floor(v.performance&&v.performance.now()||Date.now()),this.data={}}var t=e.prototype;return t.set=function(e,t){var i=e[this.vdata]||te();return e[this.vdata]||(e[this.vdata]=i),this.data[i]=t,this},t.get=function(e){var t=e[this.vdata];if(t)return this.data[t];p("We have no data for this element",e)},t.has=function(e){return e[this.vdata]in this.data},t.delete=function(e){var t=e[this.vdata];t&&(delete this.data[t],delete e[this.vdata])},e}());var ie=v.WeakMap?new WeakMap:new Z;function ne(e,t){if(ie.has(e)){var i=ie.get(e);0===i.handlers[t].length&&(delete i.handlers[t],e.removeEventListener?e.removeEventListener(t,i.dispatcher,!1):e.detachEvent&&e.detachEvent("on"+t,i.dispatcher)),Object.getOwnPropertyNames(i.handlers).length<=0&&(delete i.handlers,delete i.dispatcher,delete i.disabled),0===Object.getOwnPropertyNames(i).length&&ie.delete(e)}}function re(t,i,e,n){e.forEach(function(e){t(i,e,n)})}function ae(e){function t(){return!0}function i(){return!1}if(!e||!e.isPropagationStopped){var n=e||v.event;for(var r in e={},n)"layerX"!==r&&"layerY"!==r&&"keyLocation"!==r&&"webkitMovementX"!==r&&"webkitMovementY"!==r&&("returnValue"===r&&n.preventDefault||(e[r]=n[r]));if(e.target||(e.target=e.srcElement||h),e.relatedTarget||(e.relatedTarget=e.fromElement===e.target?e.toElement:e.fromElement),e.preventDefault=function(){n.preventDefault&&n.preventDefault(),e.returnValue=!1,n.returnValue=!1,e.defaultPrevented=!0},e.defaultPrevented=!1,e.stopPropagation=function(){n.stopPropagation&&n.stopPropagation(),e.cancelBubble=!0,n.cancelBubble=!0,e.isPropagationStopped=t},e.isPropagationStopped=i,e.stopImmediatePropagation=function(){n.stopImmediatePropagation&&n.stopImmediatePropagation(),e.isImmediatePropagationStopped=t,e.stopPropagation()},e.isImmediatePropagationStopped=i,null!==e.clientX&&void 0!==e.clientX){var a=h.documentElement,s=h.body;e.pageX=e.clientX+(a&&a.scrollLeft||s&&s.scrollLeft||0)-(a&&a.clientLeft||s&&s.clientLeft||0),e.pageY=e.clientY+(a&&a.scrollTop||s&&s.scrollTop||0)-(a&&a.clientTop||s&&s.clientTop||0)}e.which=e.charCode||e.keyCode,null!==e.button&&void 0!==e.button&&(e.button=1&e.button?0:4&e.button?1:2&e.button?2:0)}return e}var se=!1;!function(){try{var e=Object.defineProperty({},"passive",{get:function(){se=!0}});v.addEventListener("test",null,e),v.removeEventListener("test",null,e)}catch(e){}}();var oe=["touchstart","touchmove"];function ue(s,e,t){if(Array.isArray(e))return re(ue,s,e,t);ie.has(s)||ie.set(s,{});var o=ie.get(s);if(o.handlers||(o.handlers={}),o.handlers[e]||(o.handlers[e]=[]),t.guid||(t.guid=te()),o.handlers[e].push(t),o.dispatcher||(o.disabled=!1,o.dispatcher=function(e,t){if(!o.disabled){e=ae(e);var i=o.handlers[e.type];if(i)for(var n=i.slice(0),r=0,a=n.length;r<a&&!e.isImmediatePropagationStopped();r++)try{n[r].call(s,e,t)}catch(e){p.error(e)}}}),1===o.handlers[e].length)if(s.addEventListener){var i=!1;se&&-1<oe.indexOf(e)&&(i={passive:!0}),s.addEventListener(e,o.dispatcher,i)}else s.attachEvent&&s.attachEvent("on"+e,o.dispatcher)}function le(e,t,i){if(ie.has(e)){var n=ie.get(e);if(n.handlers){if(Array.isArray(t))return re(le,e,t,i);function r(e,t){n.handlers[t]=[],ne(e,t)}if(void 0!==t){var a=n.handlers[t];if(a)if(i){if(i.guid)for(var s=0;s<a.length;s++)a[s].guid===i.guid&&a.splice(s--,1);ne(e,t)}else r(e,t)}else for(var o in n.handlers)Object.prototype.hasOwnProperty.call(n.handlers||{},o)&&r(e,o)}}}function ce(e,t,i){var n=ie.has(e)?ie.get(e):{},r=e.parentNode||e.ownerDocument;if("string"==typeof t?t={type:t,target:e}:t.target||(t.target=e),t=ae(t),n.dispatcher&&n.dispatcher.call(e,t,i),r&&!t.isPropagationStopped()&&!0===t.bubbles)ce.call(null,r,t,i);else if(!r&&!t.defaultPrevented&&t.target&&t.target[t.type]){ie.has(t.target)||ie.set(t.target,{});var a=ie.get(t.target);t.target[t.type]&&(a.disabled=!0,"function"==typeof t.target[t.type]&&t.target[t.type](),a.disabled=!1)}return!t.defaultPrevented}function he(e,t,i){if(Array.isArray(t))return re(he,e,t,i);function n(){le(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||te(),ue(e,t,n)}function de(e,t,i){function n(){le(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||te(),ue(e,t,n)}function pe(e,t,i){t.guid||(t.guid=te());var n=t.bind(e);return n.guid=i?i+"_"+t.guid:t.guid,n}function fe(t,i){var n=v.performance.now();return function(){var e=v.performance.now();i<=e-n&&(t.apply(void 0,arguments),n=e)}}function me(){}var ge,ye=Object.freeze({fixEvent:ae,on:ue,off:le,trigger:ce,one:he,any:de});me.prototype.allowedEvents_={},me.prototype.addEventListener=me.prototype.on=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},ue(this,e,t),this.addEventListener=i},me.prototype.removeEventListener=me.prototype.off=function(e,t){le(this,e,t)},me.prototype.one=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},he(this,e,t),this.addEventListener=i},me.prototype.any=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},de(this,e,t),this.addEventListener=i},me.prototype.dispatchEvent=me.prototype.trigger=function(e){var t=e.type||e;"string"==typeof e&&(e={type:t}),e=ae(e),this.allowedEvents_[t]&&this["on"+t]&&this["on"+t](e),ce(this,e)},me.prototype.queueTrigger=function(e){var t=this;ge=ge||new Map;var i=e.type||e,n=ge.get(this);n||(n=new Map,ge.set(this,n));var r=n.get(i);n.delete(i),v.clearTimeout(r);var a=v.setTimeout(function(){0===n.size&&(n=null,ge.delete(t)),t.trigger(e)},0);n.set(i,a)};function ve(e){return"string"==typeof e&&/\S/.test(e)||Array.isArray(e)&&!!e.length}function _e(e){if(!e.nodeName&&!Ce(e))throw new Error("Invalid target; must be a DOM node or evented object.")}function be(e){if(!ve(e))throw new Error("Invalid event type; must be a non-empty string or array.")}function Te(e){if("function"!=typeof e)throw new Error("Invalid listener; must be a function.")}function Se(e,t){var i,n,r,a=t.length<3||t[0]===e||t[0]===e.eventBusEl_;return r=a?(i=e.eventBusEl_,3<=t.length&&t.shift(),n=t[0],t[1]):(i=t[0],n=t[1],t[2]),_e(i),be(n),Te(r),{isTargetingSelf:a,target:i,type:n,listener:r=pe(e,r)}}function ke(e,t,i,n){_e(e),e.nodeName?ye[t](e,i,n):e[t](i,n)}var Ce=function(t){return t instanceof me||!!t.eventBusEl_&&["on","one","off","trigger"].every(function(e){return"function"==typeof t[e]})},Ee={on:function(){for(var e=this,t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];var r=Se(this,i),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(ke(s,"on",o,u),!a){function l(){return e.off(s,o,u)}l.guid=u.guid;function c(){return e.off("dispose",l)}c.guid=u.guid,ke(this,"on","dispose",l),ke(s,"on","dispose",c)}},one:function(){for(var n=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var r=Se(this,t),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(a)ke(s,"one",o,u);else{function l(){n.off(s,o,l);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];u.apply(null,t)}l.guid=u.guid,ke(s,"one",o,l)}},any:function(){for(var n=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var r=Se(this,t),a=r.isTargetingSelf,s=r.target,o=r.type,u=r.listener;if(a)ke(s,"any",o,u);else{function l(){n.off(s,o,l);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];u.apply(null,t)}l.guid=u.guid,ke(s,"any",o,l)}},off:function(e,t,i){if(!e||ve(e))le(this.eventBusEl_,e,t);else{var n=e,r=t;_e(n),be(r),Te(i),i=pe(this,i),this.off("dispose",i),n.nodeName?(le(n,r,i),le(n,"dispose",i)):Ce(n)&&(n.off(r,i),n.off("dispose",i))}},trigger:function(e,t){return ce(this.eventBusEl_,e,t)}};function we(e,t){void 0===t&&(t={});var i=t.eventBusKey;if(i){if(!e[i].nodeName)throw new Error('The eventBusKey "'+i+'" does not refer to an element.');e.eventBusEl_=e[i]}else e.eventBusEl_=b("span",{className:"vjs-event-bus"});return m(e,Ee),e.eventedCallbacks&&e.eventedCallbacks.forEach(function(e){e()}),e.on("dispose",function(){e.off(),v.setTimeout(function(){e.eventBusEl_=null},0)}),e}var Ae={state:{},setState:function(e){var i,n=this;return"function"==typeof e&&(e=e()),r(e,function(e,t){n.state[t]!==e&&((i=i||{})[t]={from:n.state[t],to:e}),n.state[t]=e}),i&&Ce(this)&&this.trigger({changes:i,type:"statechanged"}),i}};function Pe(e,t){return m(e,Ae),e.state=m({},e.state,t),"function"==typeof e.handleStateChanged&&Ce(e)&&e.on("statechanged",e.handleStateChanged),e}function Ie(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toLowerCase()})}function Le(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toUpperCase()})}function Oe(){for(var i={},e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.forEach(function(e){e&&r(e,function(e,t){o(e)?(o(i[t])||(i[t]={}),i[t]=Oe(i[t],e)):i[t]=e})}),i}var xe=function(){function l(e,t,i){if(!e&&this.play?this.player_=e=this:this.player_=e,this.parentComponent_=null,this.options_=Oe({},this.options_),t=this.options_=Oe(this.options_,t),this.id_=t.id||t.el&&t.el.id,!this.id_){var n=e&&e.id&&e.id()||"no_player";this.id_=n+"_component_"+te()}var r;this.name_=t.name||null,t.el?this.el_=t.el:!1!==t.createEl&&(this.el_=this.createEl()),!1!==t.evented&&we(this,{eventBusKey:this.el_?"el_":null}),Pe(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},this.childNameIndex_={},v.Set||(r=function(){function e(){this.set_={}}var t=e.prototype;return t.has=function(e){return e in this.set_},t.delete=function(e){var t=this.has(e);return delete this.set_[e],t},t.add=function(e){return this.set_[e]=1,this},t.forEach=function(e,t){for(var i in this.set_)e.call(t,i,i,this)},e}()),this.setTimeoutIds_=v.Set?new Set:new r,this.setIntervalIds_=v.Set?new Set:new r,this.rafIds_=v.Set?new Set:new r,(this.clearingTimersOnDispose_=!1)!==t.initChildren&&this.initChildren(),this.ready(i),!1!==t.reportTouchActivity&&this.enableTouchActivity()}var e=l.prototype;return e.dispose=function(){if(this.trigger({type:"dispose",bubbles:!1}),this.children_)for(var e=this.children_.length-1;0<=e;e--)this.children_[e].dispose&&this.children_[e].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),ie.has(this.el_)&&ie.delete(this.el_),this.el_=null),this.player_=null},e.player=function(){return this.player_},e.options=function(e){return e&&(this.options_=Oe(this.options_,e)),this.options_},e.el=function(){return this.el_},e.createEl=function(e,t,i){return b(e,t,i)},e.localize=function(e,r,t){void 0===t&&(t=e);var i=this.player_.language&&this.player_.language(),n=this.player_.languages&&this.player_.languages(),a=n&&n[i],s=i&&i.split("-")[0],o=n&&n[s],u=t;return a&&a[e]?u=a[e]:o&&o[e]&&(u=o[e]),r&&(u=u.replace(/\{(\d+)\}/g,function(e,t){var i=r[t-1],n=i;return"undefined"==typeof i&&(n=e),n})),u},e.contentEl=function(){return this.contentEl_||this.el_},e.id=function(){return this.id_},e.name=function(){return this.name_},e.children=function(){return this.children_},e.getChildById=function(e){return this.childIndex_[e]},e.getChild=function(e){if(e)return this.childNameIndex_[e]},e.addChild=function(e,t,i){var n,r;if(void 0===t&&(t={}),void 0===i&&(i=this.children_.length),"string"==typeof e){r=Le(e);var a=t.componentClass||r;t.name=r;var s=l.getComponent(a);if(!s)throw new Error("Component "+a+" does not exist");if("function"!=typeof s)return null;n=new s(this.player_||this,t)}else n=e;if(n.parentComponent_&&n.parentComponent_.removeChild(n),this.children_.splice(i,0,n),n.parentComponent_=this,"function"==typeof n.id&&(this.childIndex_[n.id()]=n),(r=r||n.name&&Le(n.name()))&&(this.childNameIndex_[r]=n,this.childNameIndex_[Ie(r)]=n),"function"==typeof n.el&&n.el()){var o=this.contentEl().children[i]||null;this.contentEl().insertBefore(n.el(),o)}return n},e.removeChild=function(e){if("string"==typeof e&&(e=this.getChild(e)),e&&this.children_){for(var t=!1,i=this.children_.length-1;0<=i;i--)if(this.children_[i]===e){t=!0,this.children_.splice(i,1);break}if(t){e.parentComponent_=null,this.childIndex_[e.id()]=null,this.childNameIndex_[Le(e.name())]=null,this.childNameIndex_[Ie(e.name())]=null;var n=e.el();n&&n.parentNode===this.contentEl()&&this.contentEl().removeChild(e.el())}}},e.initChildren=function(){var r=this,n=this.options_.children;if(n){var e,a=this.options_,i=l.getComponent("Tech");(e=Array.isArray(n)?n:Object.keys(n)).concat(Object.keys(this.options_).filter(function(t){return!e.some(function(e){return"string"==typeof e?t===e:t===e.name})})).map(function(e){var t,i;return i="string"==typeof e?n[t=e]||r.options_[t]||{}:(t=e.name,e),{name:t,opts:i}}).filter(function(e){var t=l.getComponent(e.opts.componentClass||Le(e.name));return t&&!i.isTech(t)}).forEach(function(e){var t=e.name,i=e.opts;if(void 0!==a[t]&&(i=a[t]),!1!==i){!0===i&&(i={}),i.playerOptions=r.options_.playerOptions;var n=r.addChild(t,i);n&&(r[t]=n)}})}},e.buildCSSClass=function(){return""},e.ready=function(e,t){if(void 0===t&&(t=!1),e)return this.isReady_?void(t?e.call(this):this.setTimeout(e,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(e))},e.triggerReady=function(){this.isReady_=!0,this.setTimeout(function(){var e=this.readyQueue_;this.readyQueue_=[],e&&0<e.length&&e.forEach(function(e){e.call(this)},this),this.trigger("ready")},1)},e.$=function(e,t){return W(e,t||this.contentEl())},e.$$=function(e,t){return z(e,t||this.contentEl())},e.hasClass=function(e){return k(this.el_,e)},e.addClass=function(e){C(this.el_,e)},e.removeClass=function(e){E(this.el_,e)},e.toggleClass=function(e,t){w(this.el_,e,t)},e.show=function(){this.removeClass("vjs-hidden")},e.hide=function(){this.addClass("vjs-hidden")},e.lockShowing=function(){this.addClass("vjs-lock-showing")},e.unlockShowing=function(){this.removeClass("vjs-lock-showing")},e.getAttribute=function(e){return I(this.el_,e)},e.setAttribute=function(e,t){L(this.el_,e,t)},e.removeAttribute=function(e){O(this.el_,e)},e.width=function(e,t){return this.dimension("width",e,t)},e.height=function(e,t){return this.dimension("height",e,t)},e.dimensions=function(e,t){this.width(e,!0),this.height(t)},e.dimension=function(e,t,i){if(void 0!==t)return null!==t&&t==t||(t=0),-1!==(""+t).indexOf("%")||-1!==(""+t).indexOf("px")?this.el_.style[e]=t:this.el_.style[e]="auto"===t?"":t+"px",void(i||this.trigger("componentresize"));if(!this.el_)return 0;var n=this.el_.style[e],r=n.indexOf("px");return-1!==r?parseInt(n.slice(0,r),10):parseInt(this.el_["offset"+Le(e)],10)},e.currentDimension=function(e){var t=0;if("width"!==e&&"height"!==e)throw new Error("currentDimension only accepts width or height value");if(t=n(this.el_,e),0===(t=parseFloat(t))||isNaN(t)){var i="offset"+Le(e);t=this.el_[i]}return t},e.currentDimensions=function(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}},e.currentWidth=function(){return this.currentDimension("width")},e.currentHeight=function(){return this.currentDimension("height")},e.focus=function(){this.el_.focus()},e.blur=function(){this.el_.blur()},e.handleKeyDown=function(e){this.player_&&(e.stopPropagation(),this.player_.handleKeyDown(e))},e.handleKeyPress=function(e){this.handleKeyDown(e)},e.emitTapEvents=function(){var n,t=0,r=null;this.on("touchstart",function(e){1===e.touches.length&&(r={pageX:e.touches[0].pageX,pageY:e.touches[0].pageY},t=v.performance.now(),n=!0)}),this.on("touchmove",function(e){if(1<e.touches.length)n=!1;else if(r){var t=e.touches[0].pageX-r.pageX,i=e.touches[0].pageY-r.pageY;10<Math.sqrt(t*t+i*i)&&(n=!1)}});function e(){n=!1}this.on("touchleave",e),this.on("touchcancel",e),this.on("touchend",function(e){!(r=null)===n&&v.performance.now()-t<200&&(e.preventDefault(),this.trigger("tap"))})},e.enableTouchActivity=function(){if(this.player()&&this.player().reportUserActivity){var t,i=pe(this.player(),this.player().reportUserActivity);this.on("touchstart",function(){i(),this.clearInterval(t),t=this.setInterval(i,250)});function e(e){i(),this.clearInterval(t)}this.on("touchmove",i),this.on("touchend",e),this.on("touchcancel",e)}},e.setTimeout=function(e,t){var i,n=this;return e=pe(this,e),this.clearTimersOnDispose_(),i=v.setTimeout(function(){n.setTimeoutIds_.has(i)&&n.setTimeoutIds_.delete(i),e()},t),this.setTimeoutIds_.add(i),i},e.clearTimeout=function(e){return this.setTimeoutIds_.has(e)&&(this.setTimeoutIds_.delete(e),v.clearTimeout(e)),e},e.setInterval=function(e,t){e=pe(this,e),this.clearTimersOnDispose_();var i=v.setInterval(e,t);return this.setIntervalIds_.add(i),i},e.clearInterval=function(e){return this.setIntervalIds_.has(e)&&(this.setIntervalIds_.delete(e),v.clearInterval(e)),e},e.requestAnimationFrame=function(e){var t,i=this;return this.supportsRaf_?(this.clearTimersOnDispose_(),e=pe(this,e),t=v.requestAnimationFrame(function(){i.rafIds_.has(t)&&i.rafIds_.delete(t),e()}),this.rafIds_.add(t),t):this.setTimeout(e,1e3/60)},e.cancelAnimationFrame=function(e){return this.supportsRaf_?(this.rafIds_.has(e)&&(this.rafIds_.delete(e),v.cancelAnimationFrame(e)),e):this.clearTimeout(e)},e.clearTimersOnDispose_=function(){var n=this;this.clearingTimersOnDispose_||(this.clearingTimersOnDispose_=!0,this.one("dispose",function(){[["rafIds_","cancelAnimationFrame"],["setTimeoutIds_","clearTimeout"],["setIntervalIds_","clearInterval"]].forEach(function(e){var t=e[0],i=e[1];n[t].forEach(n[i],n)}),n.clearingTimersOnDispose_=!1}))},l.registerComponent=function(e,t){if("string"!=typeof e||!e)throw new Error('Illegal component name, "'+e+'"; must be a non-empty string.');var i,n=l.getComponent("Tech"),r=n&&n.isTech(t),a=l===t||l.prototype.isPrototypeOf(t.prototype);if(r||!a)throw i=r?"techs must be registered using Tech.registerTech()":"must be a Component subclass",new Error('Illegal component, "'+e+'"; '+i+".");e=Le(e),l.components_||(l.components_={});var s=l.getComponent("Player");if("Player"===e&&s&&s.players){var o=s.players,u=Object.keys(o);if(o&&0<u.length&&u.map(function(e){return o[e]}).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return l.components_[e]=t,l.components_[Ie(e)]=t},l.getComponent=function(e){if(e&&l.components_)return l.components_[e]},l}();function De(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}function Ue(e,t){return(Ue=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function Re(e,t,i){return(Re=function(){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(e){return!1}}()?Reflect.construct:function(e,t,i){var n=[null];n.push.apply(n,t);var r=new(Function.bind.apply(e,n));return i&&Ue(r,i.prototype),r}).apply(null,arguments)}function Me(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}xe.prototype.supportsRaf_="function"==typeof v.requestAnimationFrame&&"function"==typeof v.cancelAnimationFrame,xe.registerComponent("Component",xe);var Ne,Be,je,Fe,He=v.navigator&&v.navigator.userAgent||"",Ve=/AppleWebKit\/([\d.]+)/i.exec(He),qe=Ve?parseFloat(Ve.pop()):null,We=/iPad/i.test(He),ze=/iPhone/i.test(He)&&!We,$e=/iPod/i.test(He),Ge=ze||We||$e,Xe=(Ne=He.match(/OS (\d+)_/i))&&Ne[1]?Ne[1]:null,Ke=/Android/i.test(He),Ye=function(){var e=He.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!e)return null;var t=e[1]&&parseFloat(e[1]),i=e[2]&&parseFloat(e[2]);return t&&i?parseFloat(e[1]+"."+e[2]):t||null}(),Qe=Ke&&Ye<5&&qe<537,Je=/Firefox/i.test(He),Ze=/Edge/i.test(He),et=!Ze&&(/Chrome/i.test(He)||/CriOS/i.test(He)),tt=(Be=He.match(/(Chrome|CriOS)\/(\d+)/))&&Be[2]?parseFloat(Be[2]):null,it=(je=/MSIE\s(\d+)\.\d/.exec(He),!(Fe=je&&parseFloat(je[1]))&&/Trident\/7.0/i.test(He)&&/rv:11.0/.test(He)&&(Fe=11),Fe),nt=/Safari/i.test(He)&&!et&&!Ke&&!Ze,rt=(nt||Ge)&&!et,at=/Windows/i.test(He),st=c()&&("ontouchstart"in v||v.navigator.maxTouchPoints||v.DocumentTouch&&v.document instanceof v.DocumentTouch),ot=Object.freeze({IS_IPAD:We,IS_IPHONE:ze,IS_IPOD:$e,IS_IOS:Ge,IOS_VERSION:Xe,IS_ANDROID:Ke,ANDROID_VERSION:Ye,IS_NATIVE_ANDROID:Qe,IS_FIREFOX:Je,IS_EDGE:Ze,IS_CHROME:et,CHROME_VERSION:tt,IE_VERSION:it,IS_SAFARI:nt,IS_ANY_SAFARI:rt,IS_WINDOWS:at,TOUCH_ENABLED:st});function ut(e,t,i,n){return function(e,t,i){if("number"!=typeof t||t<0||i<t)throw new Error("Failed to execute '"+e+"' on 'TimeRanges': The index provided ("+t+") is non-numeric or out of bounds (0-"+i+").")}(e,n,i.length-1),i[n][t]}function lt(e){return void 0===e||0===e.length?{length:0,start:function(){throw new Error("This TimeRanges object is empty")},end:function(){throw new Error("This TimeRanges object is empty")}}:{length:e.length,start:ut.bind(null,"start",0,e),end:ut.bind(null,"end",1,e)}}function ct(e,t){return Array.isArray(e)?lt(e):void 0===e||void 0===t?lt():lt([[e,t]])}function ht(e,t){var i,n,r=0;if(!t)return 0;e&&e.length||(e=ct(0,0));for(var a=0;a<e.length;a++)i=e.start(a),t<(n=e.end(a))&&(n=t),r+=n-i;return r/t}for(var dt,pt={prefixed:!0},ft=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror","fullscreen"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror","-webkit-full-screen"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror","-moz-full-screen"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError","-ms-fullscreen"]],mt=ft[0],gt=0;gt<ft.length;gt++)if(ft[gt][1]in h){dt=ft[gt];break}if(dt){for(var yt=0;yt<dt.length;yt++)pt[mt[yt]]=dt[yt];pt.prefixed=dt[0]!==mt[0]}function vt(e){if(e instanceof vt)return e;"number"==typeof e?this.code=e:"string"==typeof e?this.message=e:s(e)&&("number"==typeof e.code&&(this.code=e.code),m(this,e)),this.message||(this.message=vt.defaultMessages[this.code]||"")}vt.prototype.code=0,vt.prototype.message="",vt.prototype.status=null,vt.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],vt.defaultMessages={1:"You aborted the media playback",2:"A network error caused the media download to fail part-way.",3:"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",4:"The media could not be loaded, either because the server or network failed or because the format is not supported.",5:"The media is encrypted and we do not have the keys to decrypt it."};for(var _t=0;_t<vt.errorTypes.length;_t++)vt[vt.errorTypes[_t]]=_t,vt.prototype[vt.errorTypes[_t]]=_t;var bt=function(e,t){var i,n=null;try{i=JSON.parse(e,t)}catch(e){n=e}return[n,i]};function Tt(e){return null!=e&&"function"==typeof e.then}function St(e){Tt(e)&&e.then(null,function(e){})}function kt(n){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(function(e,t,i){return n[t]&&(e[t]=n[t]),e},{cues:n.cues&&Array.prototype.map.call(n.cues,function(e){return{startTime:e.startTime,endTime:e.endTime,text:e.text,id:e.id}})})}var Ct=function(e){var t=e.$$("track"),i=Array.prototype.map.call(t,function(e){return e.track});return Array.prototype.map.call(t,function(e){var t=kt(e.track);return e.src&&(t.src=e.src),t}).concat(Array.prototype.filter.call(e.textTracks(),function(e){return-1===i.indexOf(e)}).map(kt))},Et=function(e,i){return e.forEach(function(e){var t=i.addRemoteTextTrack(e).track;!e.src&&e.cues&&e.cues.forEach(function(e){return t.addCue(e)})}),i.textTracks()};function wt(e,t){return e(t={exports:{}},t.exports),t.exports}var At=wt(function(e,t){function i(e){if(e&&"object"==typeof e){var t=e.which||e.keyCode||e.charCode;t&&(e=t)}if("number"==typeof e)return s[e];var i,n=String(e);return(i=r[n.toLowerCase()])?i:(i=a[n.toLowerCase()])||(1===n.length?n.charCodeAt(0):void 0)}i.isEventKey=function(e,t){if(e&&"object"==typeof e){var i=e.which||e.keyCode||e.charCode;if(null==i)return!1;if("string"==typeof t){var n;if(n=r[t.toLowerCase()])return n===i;if(n=a[t.toLowerCase()])return n===i}else if("number"==typeof t)return t===i;return!1}};var r=(t=e.exports=i).code=t.codes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,esc:27,space:32,"page up":33,"page down":34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46,command:91,"left command":91,"right command":93,"numpad *":106,"numpad +":107,"numpad -":109,"numpad .":110,"numpad /":111,"num lock":144,"scroll lock":145,"my computer":182,"my calculator":183,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},a=t.aliases={windows:91,"⇧":16,"⌥":18,"⌃":17,"⌘":91,ctl:17,control:17,option:18,pause:19,break:19,caps:20,return:13,escape:27,spc:32,spacebar:32,pgup:33,pgdn:34,ins:45,del:46,cmd:91};for(n=97;n<123;n++)r[String.fromCharCode(n)]=n-32;for(var n=48;n<58;n++)r[n-48]=n;for(n=1;n<13;n++)r["f"+n]=n+111;for(n=0;n<10;n++)r["numpad "+n]=n+96;var s=t.names=t.title={};for(n in r)s[r[n]]=n;for(var o in a)r[o]=a[o]}),Pt=(At.code,At.codes,At.aliases,At.names,At.title,"vjs-modal-dialog"),It=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).opened_=i.hasBeenOpened_=i.hasBeenFilled_=!1,i.closeable(!i.options_.uncloseable),i.content(i.options_.content),i.contentEl_=b("div",{className:Pt+"-content"},{role:"document"}),i.descEl_=b("p",{className:Pt+"-description vjs-control-text",id:i.el().getAttribute("aria-describedby")}),T(i.descEl_,i.description()),i.el_.appendChild(i.descEl_),i.el_.appendChild(i.contentEl_),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":this.id()+"_description","aria-hidden":"true","aria-label":this.label(),role:"dialog"})},t.dispose=function(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return Pt+" vjs-hidden "+n.prototype.buildCSSClass.call(this)},t.label=function(){return this.localize(this.options_.label||"Modal Window")},t.description=function(){var e=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(e+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),e},t.open=function(){if(!this.opened_){var e=this.player();this.trigger("beforemodalopen"),this.opened_=!0,!this.options_.fillAlways&&(this.hasBeenOpened_||this.hasBeenFilled_)||this.fill(),this.wasPlaying_=!e.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&e.pause(),this.on("keydown",this.handleKeyDown),this.hadControls_=e.controls(),e.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0}},t.opened=function(e){return"boolean"==typeof e&&this[e?"open":"close"](),this.opened_},t.close=function(){if(this.opened_){var e=this.player();this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&e.play(),this.off("keydown",this.handleKeyDown),this.hadControls_&&e.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose()}},t.closeable=function(e){if("boolean"==typeof e){var t=this.closeable_=!!e,i=this.getChild("closeButton");if(t&&!i){var n=this.contentEl_;this.contentEl_=this.el_,i=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=n,this.on(i,"close",this.close)}!t&&i&&(this.off(i,"close",this.close),this.removeChild(i),i.dispose())}return this.closeable_},t.fill=function(){this.fillWith(this.content())},t.fillWith=function(e){var t=this.contentEl(),i=t.parentNode,n=t.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,i.removeChild(t),this.empty(),H(t,e),this.trigger("modalfill"),n?i.insertBefore(t,n):i.appendChild(t);var r=this.getChild("closeButton");r&&i.appendChild(r.el_)},t.empty=function(){this.trigger("beforemodalempty"),B(this.contentEl()),this.trigger("modalempty")},t.content=function(e){return"undefined"!=typeof e&&(this.content_=e),this.content_},t.conditionalFocus_=function(){var e=h.activeElement,t=this.player_.el_;this.previouslyActiveEl_=null,!t.contains(e)&&t!==e||(this.previouslyActiveEl_=e,this.focus())},t.conditionalBlur_=function(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)},t.handleKeyDown=function(e){if(e.stopPropagation(),At.isEventKey(e,"Escape")&&this.closeable())return e.preventDefault(),void this.close();if(At.isEventKey(e,"Tab")){for(var t,i=this.focusableEls_(),n=this.el_.querySelector(":focus"),r=0;r<i.length;r++)if(n===i[r]){t=r;break}h.activeElement===this.el_&&(t=0),e.shiftKey&&0===t?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||t!==i.length-1||(i[0].focus(),e.preventDefault())}},t.focusableEls_=function(){var e=this.el_.querySelectorAll("*");return Array.prototype.filter.call(e,function(e){return(e instanceof v.HTMLAnchorElement||e instanceof v.HTMLAreaElement)&&e.hasAttribute("href")||(e instanceof v.HTMLInputElement||e instanceof v.HTMLSelectElement||e instanceof v.HTMLTextAreaElement||e instanceof v.HTMLButtonElement)&&!e.hasAttribute("disabled")||e instanceof v.HTMLIFrameElement||e instanceof v.HTMLObjectElement||e instanceof v.HTMLEmbedElement||e.hasAttribute("tabindex")&&-1!==e.getAttribute("tabindex")||e.hasAttribute("contenteditable")})},e}(xe);It.prototype.options_={pauseOnOpen:!0,temporary:!0},xe.registerComponent("ModalDialog",It);var Lt=function(n){function e(e){var t;void 0===e&&(e=[]),(t=n.call(this)||this).tracks_=[],Object.defineProperty(Me(t),"length",{get:function(){return this.tracks_.length}});for(var i=0;i<e.length;i++)t.addTrack(e[i]);return t}De(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this.tracks_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.tracks_[t]}}),-1===this.tracks_.indexOf(e)&&(this.tracks_.push(e),this.trigger({track:e,type:"addtrack",target:this}))},t.removeTrack=function(e){for(var t,i=0,n=this.length;i<n;i++)if(this[i]===e){(t=this[i]).off&&t.off(),this.tracks_.splice(i,1);break}t&&this.trigger({track:t,type:"removetrack",target:this})},t.getTrackById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},e}(me);for(var Ot in Lt.prototype.allowedEvents_={change:"change",addtrack:"addtrack",removetrack:"removetrack"},Lt.prototype.allowedEvents_)Lt.prototype["on"+Ot]=null;function xt(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].enabled=!1)}function Dt(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].selected=!1)}function Ut(e){var t=["protocol","hostname","port","pathname","search","hash","host"],i=h.createElement("a");i.href=e;var n,r=""===i.host&&"file:"!==i.protocol;r&&((n=h.createElement("div")).innerHTML='<a href="'+e+'"></a>',i=n.firstChild,n.setAttribute("style","display:none; position:absolute;"),h.body.appendChild(n));for(var a={},s=0;s<t.length;s++)a[t[s]]=i[t[s]];return"http:"===a.protocol&&(a.host=a.host.replace(/:80$/,"")),"https:"===a.protocol&&(a.host=a.host.replace(/:443$/,"")),a.protocol||(a.protocol=v.location.protocol),r&&h.body.removeChild(n),a}function Rt(e){if(!e.match(/^https?:\/\//)){var t=h.createElement("div");t.innerHTML='<a href="'+e+'">x</a>',e=t.firstChild.href}return e}function Mt(e){if("string"==typeof e){var t=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/.exec(e);if(t)return t.pop().toLowerCase()}return""}function Nt(e){var t=v.location,i=Ut(e);return(":"===i.protocol?t.protocol:i.protocol)+i.host!==t.protocol+t.host}var Bt=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].enabled){xt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,t}De(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.enabled&&xt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.enabledChange_=function(){t.changing_||(t.changing_=!0,xt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("enabledchange",e.enabledChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.enabledChange_&&(e.removeEventListener("enabledchange",e.enabledChange_),e.enabledChange_=null)},e}(Lt),jt=function(n){function e(e){var t;void 0===e&&(e=[]);for(var i=e.length-1;0<=i;i--)if(e[i].selected){Dt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,Object.defineProperty(Me(t),"selectedIndex",{get:function(){for(var e=0;e<this.length;e++)if(this[e].selected)return e;return-1},set:function(){}}),t}De(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.selected&&Dt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.selectedChange_=function(){t.changing_||(t.changing_=!0,Dt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("selectedchange",e.selectedChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.selectedChange_&&(e.removeEventListener("selectedchange",e.selectedChange_),e.selectedChange_=null)},e}(Lt),Ft=function(i){function e(){return i.apply(this,arguments)||this}De(e,i);var t=e.prototype;return t.addTrack=function(e){var t=this;i.prototype.addTrack.call(this,e),this.queueChange_||(this.queueChange_=function(){return t.queueTrigger("change")}),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=function(){return t.trigger("selectedlanguagechange")}),e.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(e.kind)&&e.addEventListener("modechange",this.triggerSelectedlanguagechange_)},t.removeTrack=function(e){i.prototype.removeTrack.call(this,e),e.removeEventListener&&(this.queueChange_&&e.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&e.removeEventListener("modechange",this.triggerSelectedlanguagechange_))},e}(Lt),Ht=function(){function e(e){void 0===e&&(e=[]),this.trackElements_=[],Object.defineProperty(this,"length",{get:function(){return this.trackElements_.length}});for(var t=0,i=e.length;t<i;t++)this.addTrackElement_(e[t])}var t=e.prototype;return t.addTrackElement_=function(e){var t=this.trackElements_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.trackElements_[t]}}),-1===this.trackElements_.indexOf(e)&&this.trackElements_.push(e)},t.getTrackElementByTrack_=function(e){for(var t,i=0,n=this.trackElements_.length;i<n;i++)if(e===this.trackElements_[i].track){t=this.trackElements_[i];break}return t},t.removeTrackElement_=function(e){for(var t=0,i=this.trackElements_.length;t<i;t++)if(e===this.trackElements_[t]){this.trackElements_[t].track&&"function"==typeof this.trackElements_[t].track.off&&this.trackElements_[t].track.off(),"function"==typeof this.trackElements_[t].off&&this.trackElements_[t].off(),this.trackElements_.splice(t,1);break}},e}(),Vt=function(){function t(e){t.prototype.setCues_.call(this,e),Object.defineProperty(this,"length",{get:function(){return this.length_}})}var e=t.prototype;return e.setCues_=function(e){var t=this.length||0,i=0,n=e.length;this.cues_=e,this.length_=e.length;function r(e){""+e in this||Object.defineProperty(this,""+e,{get:function(){return this.cues_[e]}})}if(t<n)for(i=t;i<n;i++)r.call(this,i)},e.getCueById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},t}(),qt={alternative:"alternative",captions:"captions",main:"main",sign:"sign",subtitles:"subtitles",commentary:"commentary"},Wt={alternative:"alternative",descriptions:"descriptions",main:"main","main-desc":"main-desc",translation:"translation",commentary:"commentary"},zt={subtitles:"subtitles",captions:"captions",descriptions:"descriptions",chapters:"chapters",metadata:"metadata"},$t={disabled:"disabled",hidden:"hidden",showing:"showing"},Gt=function(a){function e(e){var t;void 0===e&&(e={}),t=a.call(this)||this;function i(e){Object.defineProperty(Me(t),e,{get:function(){return n[e]},set:function(){}})}var n={id:e.id||"vjs_track_"+te(),kind:e.kind||"",label:e.label||"",language:e.language||""};for(var r in n)i(r);return t}return De(e,a),e}(me),Xt=Object.freeze({parseUrl:Ut,getAbsoluteURL:Rt,getFileExtension:Mt,isCrossOrigin:Nt}),Kt=function(e){var t=Yt.call(e);return"[object Function]"===t||"function"==typeof e&&"[object RegExp]"!==t||"undefined"!=typeof window&&(e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt)},Yt=Object.prototype.toString;function Qt(e){var t=ii.call(e),i="[object Arguments]"===t;return i=i||"[object Array]"!==t&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&0<=e.length&&"[object Function]"===ii.call(e.callee)}var Jt,Zt=Array.prototype.slice,ei=Object.prototype.toString,ti=Function.prototype.bind||function(t){var i=this;if("function"!=typeof i||"[object Function]"!==ei.call(i))throw new TypeError("Function.prototype.bind called on incompatible "+i);for(var n,r=Zt.call(arguments,1),e=Math.max(0,i.length-r.length),a=[],s=0;s<e;s++)a.push("$"+s);if(n=Function("binder","return function ("+a.join(",")+"){ return binder.apply(this,arguments); }")(function(){if(this instanceof n){var e=i.apply(this,r.concat(Zt.call(arguments)));return Object(e)===e?e:this}return i.apply(t,r.concat(Zt.call(arguments)))}),i.prototype){function o(){}o.prototype=i.prototype,n.prototype=new o,o.prototype=null}return n},ii=Object.prototype.toString;if(!Object.keys){function ni(e){var t=e.constructor;return t&&t.prototype===e}var ri=Object.prototype.hasOwnProperty,ai=Object.prototype.toString,si=Qt,oi=Object.prototype.propertyIsEnumerable,ui=!oi.call({toString:null},"toString"),li=oi.call(function(){},"prototype"),ci=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],hi={$applicationCache:!0,$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$onmozfullscreenchange:!0,$onmozfullscreenerror:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},di=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!hi["$"+e]&&ri.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{ni(window[e])}catch(e){return!0}}catch(e){return!0}return!1}();Jt=function(e){var t=null!==e&&"object"==typeof e,i="[object Function]"===ai.call(e),n=si(e),r=t&&"[object String]"===ai.call(e),a=[];if(!t&&!i&&!n)throw new TypeError("Object.keys called on a non-object");var s=li&&i;if(r&&0<e.length&&!ri.call(e,0))for(var o=0;o<e.length;++o)a.push(String(o));if(n&&0<e.length)for(var u=0;u<e.length;++u)a.push(String(u));else for(var l in e)s&&"prototype"===l||!ri.call(e,l)||a.push(String(l));if(ui)for(var c=function(e){if("undefined"==typeof window||!di)return ni(e);try{return ni(e)}catch(e){return!1}}(e),h=0;h<ci.length;++h)c&&"constructor"===ci[h]||!ri.call(e,ci[h])||a.push(ci[h]);return a}}var pi=Jt,fi=Array.prototype.slice,mi=Object.keys,gi=mi?function(e){return mi(e)}:pi,yi=Object.keys;gi.shim=function(){Object.keys?function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2)||(Object.keys=function(e){return Qt(e)?yi(fi.call(e)):yi(e)}):Object.keys=gi;return Object.keys||gi};function vi(e,t,i,n){t in e&&(!function(e){return"function"==typeof e&&"[object Function]"===Si.call(e)}(n)||!n())||(Ei?Ci(e,t,{configurable:!0,enumerable:!1,value:i,writable:!0}):e[t]=i)}function _i(e,t,i){var n=2<arguments.length?i:{},r=bi(t);Ti&&(r=ki.call(r,Object.getOwnPropertySymbols(t)));for(var a=0;a<r.length;a+=1)vi(e,r[a],t[r[a]],n[r[a]])}var bi=gi,Ti="function"==typeof Symbol&&"symbol"==typeof Symbol("foo"),Si=Object.prototype.toString,ki=Array.prototype.concat,Ci=Object.defineProperty,Ei=Ci&&function(){var e={};try{for(var t in Ci(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}();_i.supportsDescriptors=!!Ei;function wi(e,t){if(1<arguments.length&&"boolean"!=typeof t)throw new TypeError('"allowMissing" argument must be a boolean');var i="$ "+e;if(!(i in Fi))throw new SyntaxError("intrinsic "+e+" does not exist!");if("undefined"==typeof Fi[i]&&!t)throw new TypeError("intrinsic "+e+" exists, but is not available. Please file an issue!");return Fi[i]}function Ai(e,t,i,n){var r=Wi[t];if("function"!=typeof r)throw new qi("unknown record type: "+t);if(!r(e,n))throw new Vi(i+" must be a "+t)}function Pi(e){return 0<=e?1:-1}function Ii(e){try{var t=Xi.call(e);return Ki.test(t)}catch(e){return!1}}function Li(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if("function"==typeof e&&!e.prototype)return!0;if(Qi)return function(e){try{return!Ii(e)&&(Xi.call(e),!0)}catch(e){return!1}}(e);if(Ii(e))return!1;var t=Yi.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}function Oi(e){return null===e||"function"!=typeof e&&"object"!=typeof e}function xi(){var e=rn.ToString(rn.CheckObjectCoercible(this));return an(an(e,sn,""),on,"")}function Di(){return String.prototype.trim&&"​"==="​".trim()?String.prototype.trim:xi}var Ui,Ri=_i,Mi=Object.getOwnPropertyDescriptor?function(){return Object.getOwnPropertyDescriptor(arguments,"callee").get}():function(){throw new TypeError},Ni="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator,Bi=Object.getPrototypeOf||function(e){return e.__proto__},ji="undefined"==typeof Uint8Array?Ui:Bi(Uint8Array),Fi={"$ %Array%":Array,"$ %ArrayBuffer%":"undefined"==typeof ArrayBuffer?Ui:ArrayBuffer,"$ %ArrayBufferPrototype%":"undefined"==typeof ArrayBuffer?Ui:ArrayBuffer.prototype,"$ %ArrayIteratorPrototype%":Ni?Bi([][Symbol.iterator]()):Ui,"$ %ArrayPrototype%":Array.prototype,"$ %ArrayProto_entries%":Array.prototype.entries,"$ %ArrayProto_forEach%":Array.prototype.forEach,"$ %ArrayProto_keys%":Array.prototype.keys,"$ %ArrayProto_values%":Array.prototype.values,"$ %AsyncFromSyncIteratorPrototype%":Ui,"$ %AsyncFunction%":void 0,"$ %AsyncFunctionPrototype%":Ui,"$ %AsyncGenerator%":Ui,"$ %AsyncGeneratorFunction%":void 0,"$ %AsyncGeneratorPrototype%":Ui,"$ %AsyncIteratorPrototype%":Ui,"$ %Atomics%":"undefined"==typeof Atomics?Ui:Atomics,"$ %Boolean%":Boolean,"$ %BooleanPrototype%":Boolean.prototype,"$ %DataView%":"undefined"==typeof DataView?Ui:DataView,"$ %DataViewPrototype%":"undefined"==typeof DataView?Ui:DataView.prototype,"$ %Date%":Date,"$ %DatePrototype%":Date.prototype,"$ %decodeURI%":decodeURI,"$ %decodeURIComponent%":decodeURIComponent,"$ %encodeURI%":encodeURI,"$ %encodeURIComponent%":encodeURIComponent,"$ %Error%":Error,"$ %ErrorPrototype%":Error.prototype,"$ %eval%":eval,"$ %EvalError%":EvalError,"$ %EvalErrorPrototype%":EvalError.prototype,"$ %Float32Array%":"undefined"==typeof Float32Array?Ui:Float32Array,"$ %Float32ArrayPrototype%":"undefined"==typeof Float32Array?Ui:Float32Array.prototype,"$ %Float64Array%":"undefined"==typeof Float64Array?Ui:Float64Array,"$ %Float64ArrayPrototype%":"undefined"==typeof Float64Array?Ui:Float64Array.prototype,"$ %Function%":Function,"$ %FunctionPrototype%":Function.prototype,"$ %Generator%":Ui,"$ %GeneratorFunction%":void 0,"$ %GeneratorPrototype%":Ui,"$ %Int8Array%":"undefined"==typeof Int8Array?Ui:Int8Array,"$ %Int8ArrayPrototype%":"undefined"==typeof Int8Array?Ui:Int8Array.prototype,"$ %Int16Array%":"undefined"==typeof Int16Array?Ui:Int16Array,"$ %Int16ArrayPrototype%":"undefined"==typeof Int16Array?Ui:Int8Array.prototype,"$ %Int32Array%":"undefined"==typeof Int32Array?Ui:Int32Array,"$ %Int32ArrayPrototype%":"undefined"==typeof Int32Array?Ui:Int32Array.prototype,"$ %isFinite%":isFinite,"$ %isNaN%":isNaN,"$ %IteratorPrototype%":Ni?Bi(Bi([][Symbol.iterator]())):Ui,"$ %JSON%":JSON,"$ %JSONParse%":JSON.parse,"$ %Map%":"undefined"==typeof Map?Ui:Map,"$ %MapIteratorPrototype%":"undefined"!=typeof Map&&Ni?Bi((new Map)[Symbol.iterator]()):Ui,"$ %MapPrototype%":"undefined"==typeof Map?Ui:Map.prototype,"$ %Math%":Math,"$ %Number%":Number,"$ %NumberPrototype%":Number.prototype,"$ %Object%":Object,"$ %ObjectPrototype%":Object.prototype,"$ %ObjProto_toString%":Object.prototype.toString,"$ %ObjProto_valueOf%":Object.prototype.valueOf,"$ %parseFloat%":parseFloat,"$ %parseInt%":parseInt,"$ %Promise%":"undefined"==typeof Promise?Ui:Promise,"$ %PromisePrototype%":"undefined"==typeof Promise?Ui:Promise.prototype,"$ %PromiseProto_then%":"undefined"==typeof Promise?Ui:Promise.prototype.then,"$ %Promise_all%":"undefined"==typeof Promise?Ui:Promise.all,"$ %Promise_reject%":"undefined"==typeof Promise?Ui:Promise.reject,"$ %Promise_resolve%":"undefined"==typeof Promise?Ui:Promise.resolve,"$ %Proxy%":"undefined"==typeof Proxy?Ui:Proxy,"$ %RangeError%":RangeError,"$ %RangeErrorPrototype%":RangeError.prototype,"$ %ReferenceError%":ReferenceError,"$ %ReferenceErrorPrototype%":ReferenceError.prototype,"$ %Reflect%":"undefined"==typeof Reflect?Ui:Reflect,"$ %RegExp%":RegExp,"$ %RegExpPrototype%":RegExp.prototype,"$ %Set%":"undefined"==typeof Set?Ui:Set,"$ %SetIteratorPrototype%":"undefined"!=typeof Set&&Ni?Bi((new Set)[Symbol.iterator]()):Ui,"$ %SetPrototype%":"undefined"==typeof Set?Ui:Set.prototype,"$ %SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?Ui:SharedArrayBuffer,"$ %SharedArrayBufferPrototype%":"undefined"==typeof SharedArrayBuffer?Ui:SharedArrayBuffer.prototype,"$ %String%":String,"$ %StringIteratorPrototype%":Ni?Bi(""[Symbol.iterator]()):Ui,"$ %StringPrototype%":String.prototype,"$ %Symbol%":Ni?Symbol:Ui,"$ %SymbolPrototype%":Ni?Symbol.prototype:Ui,"$ %SyntaxError%":SyntaxError,"$ %SyntaxErrorPrototype%":SyntaxError.prototype,"$ %ThrowTypeError%":Mi,"$ %TypedArray%":ji,"$ %TypedArrayPrototype%":ji?ji.prototype:Ui,"$ %TypeError%":TypeError,"$ %TypeErrorPrototype%":TypeError.prototype,"$ %Uint8Array%":"undefined"==typeof Uint8Array?Ui:Uint8Array,"$ %Uint8ArrayPrototype%":"undefined"==typeof Uint8Array?Ui:Uint8Array.prototype,"$ %Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?Ui:Uint8ClampedArray,"$ %Uint8ClampedArrayPrototype%":"undefined"==typeof Uint8ClampedArray?Ui:Uint8ClampedArray.prototype,"$ %Uint16Array%":"undefined"==typeof Uint16Array?Ui:Uint16Array,"$ %Uint16ArrayPrototype%":"undefined"==typeof Uint16Array?Ui:Uint16Array.prototype,"$ %Uint32Array%":"undefined"==typeof Uint32Array?Ui:Uint32Array,"$ %Uint32ArrayPrototype%":"undefined"==typeof Uint32Array?Ui:Uint32Array.prototype,"$ %URIError%":URIError,"$ %URIErrorPrototype%":URIError.prototype,"$ %WeakMap%":"undefined"==typeof WeakMap?Ui:WeakMap,"$ %WeakMapPrototype%":"undefined"==typeof WeakMap?Ui:WeakMap.prototype,"$ %WeakSet%":"undefined"==typeof WeakSet?Ui:WeakSet,"$ %WeakSetPrototype%":"undefined"==typeof WeakSet?Ui:WeakSet.prototype},Hi=ti.call(Function.call,Object.prototype.hasOwnProperty),Vi=wi("%TypeError%"),qi=wi("%SyntaxError%"),Wi={"Property Descriptor":function(e,t){if("Object"!==e.Type(t))return!1;var i={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var n in t)if(Hi(t,n)&&!i[n])return!1;var r=Hi(t,"[[Value]]"),a=Hi(t,"[[Get]]")||Hi(t,"[[Set]]");if(r&&a)throw new Vi("Property Descriptors may not be both accessor and data descriptors");return!0}},zi=Number.isNaN||function(e){return e!=e},$i=Number.isNaN||function(e){return e!=e},Gi=Number.isFinite||function(e){return"number"==typeof e&&!$i(e)&&e!==1/0&&e!==-1/0},Xi=Function.prototype.toString,Ki=/^\s*class\b/,Yi=Object.prototype.toString,Qi="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,Ji=Object.prototype.toString,Zi=function(e,t){var i;if((i=1<arguments.length?t:"[object Date]"===Ji.call(e)?String:Number)!==String&&i!==Number)throw new TypeError("invalid [[DefaultValue]] hint supplied");var n,r,a=i===String?["toString","valueOf"]:["valueOf","toString"];for(r=0;r<a.length;++r)if(Li(e[a[r]])&&(n=e[a[r]](),Oi(n)))return n;throw new TypeError("No default value")},en=wi("%Object%"),tn=wi("%TypeError%"),nn=wi("%String%"),rn={ToPrimitive:function(e,t){return Oi(e)?e:1<arguments.length?Zi(e,t):Zi(e)},ToBoolean:function(e){return!!e},ToNumber:function(e){return+e},ToInteger:function(e){var t=this.ToNumber(e);return zi(t)?0:0!==t&&Gi(t)?Pi(t)*Math.floor(Math.abs(t)):t},ToInt32:function(e){return this.ToNumber(e)>>0},ToUint32:function(e){return this.ToNumber(e)>>>0},ToUint16:function(e){var t=this.ToNumber(e);return zi(t)||0===t||!Gi(t)?0:function(e,t){var i=e%t;return Math.floor(0<=i?i:i+t)}(Pi(t)*Math.floor(Math.abs(t)),65536)},ToString:function(e){return nn(e)},ToObject:function(e){return this.CheckObjectCoercible(e),en(e)},CheckObjectCoercible:function(e,t){if(null==e)throw new tn(t||"Cannot call method on "+e);return e},IsCallable:Li,SameValue:function(e,t){return e===t?0!==e||1/e==1/t:zi(e)&&zi(t)},Type:function(e){return null===e?"Null":"undefined"==typeof e?"Undefined":"function"==typeof e||"object"==typeof e?"Object":"number"==typeof e?"Number":"boolean"==typeof e?"Boolean":"string"==typeof e?"String":void 0},IsPropertyDescriptor:function(e){if("Object"!==this.Type(e))return!1;var t={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var i in e)if(Hi(e,i)&&!t[i])return!1;var n=Hi(e,"[[Value]]"),r=Hi(e,"[[Get]]")||Hi(e,"[[Set]]");if(n&&r)throw new tn("Property Descriptors may not be both accessor and data descriptors");return!0},IsAccessorDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!(!Hi(e,"[[Get]]")&&!Hi(e,"[[Set]]")))},IsDataDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!(!Hi(e,"[[Value]]")&&!Hi(e,"[[Writable]]")))},IsGenericDescriptor:function(e){return"undefined"!=typeof e&&(Ai(this,"Property Descriptor","Desc",e),!this.IsAccessorDescriptor(e)&&!this.IsDataDescriptor(e))},FromPropertyDescriptor:function(e){if("undefined"==typeof e)return e;if(Ai(this,"Property Descriptor","Desc",e),this.IsDataDescriptor(e))return{value:e["[[Value]]"],writable:!!e["[[Writable]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};if(this.IsAccessorDescriptor(e))return{get:e["[[Get]]"],set:e["[[Set]]"],enumerable:!!e["[[Enumerable]]"],configurable:!!e["[[Configurable]]"]};throw new tn("FromPropertyDescriptor must be called with a fully populated Property Descriptor")},ToPropertyDescriptor:function(e){if("Object"!==this.Type(e))throw new tn("ToPropertyDescriptor requires an object");var t={};if(Hi(e,"enumerable")&&(t["[[Enumerable]]"]=this.ToBoolean(e.enumerable)),Hi(e,"configurable")&&(t["[[Configurable]]"]=this.ToBoolean(e.configurable)),Hi(e,"value")&&(t["[[Value]]"]=e.value),Hi(e,"writable")&&(t["[[Writable]]"]=this.ToBoolean(e.writable)),Hi(e,"get")){var i=e.get;if("undefined"!=typeof i&&!this.IsCallable(i))throw new TypeError("getter must be a function");t["[[Get]]"]=i}if(Hi(e,"set")){var n=e.set;if("undefined"!=typeof n&&!this.IsCallable(n))throw new tn("setter must be a function");t["[[Set]]"]=n}if((Hi(t,"[[Get]]")||Hi(t,"[[Set]]"))&&(Hi(t,"[[Value]]")||Hi(t,"[[Writable]]")))throw new tn("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");return t}},an=ti.call(Function.call,String.prototype.replace),sn=/^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/,on=/[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/,un=ti.call(Function.call,Di());Ri(un,{getPolyfill:Di,implementation:xi,shim:function(){var e=Di();return Ri(String.prototype,{trim:e},{trim:function(){return String.prototype.trim!==e}}),e}});var ln=un,cn=Object.prototype.toString,hn=Object.prototype.hasOwnProperty,dn=function(e,t,i){if(!Li(t))throw new TypeError("iterator must be a function");var n;3<=arguments.length&&(n=i),"[object Array]"===cn.call(e)?function(e,t,i){for(var n=0,r=e.length;n<r;n++)hn.call(e,n)&&(null==i?t(e[n],n,e):t.call(i,e[n],n,e))}(e,t,n):"string"==typeof e?function(e,t,i){for(var n=0,r=e.length;n<r;n++)null==i?t(e.charAt(n),n,e):t.call(i,e.charAt(n),n,e)}(e,t,n):function(e,t,i){for(var n in e)hn.call(e,n)&&(null==i?t(e[n],n,e):t.call(i,e[n],n,e))}(e,t,n)},pn=function(e){if(!e)return{};var r={};return dn(ln(e).split("\n"),function(e){var t=e.indexOf(":"),i=ln(e.slice(0,t)).toLowerCase(),n=ln(e.slice(t+1));"undefined"==typeof r[i]?r[i]=n:!function(e){return"[object Array]"===Object.prototype.toString.call(e)}(r[i])?r[i]=[r[i],n]:r[i].push(n)}),r},fn=function(){for(var e={},t=0;t<arguments.length;t++){var i=arguments[t];for(var n in i)mn.call(i,n)&&(e[n]=i[n])}return e},mn=Object.prototype.hasOwnProperty;var gn=vn;function yn(e,t,i){var n=e;return Kt(t)?(i=t,"string"==typeof e&&(n={uri:e})):n=fn(t,{uri:e}),n.callback=i,n}function vn(e,t,i){return _n(t=yn(e,t,i))}function _n(n){if("undefined"==typeof n.callback)throw new Error("callback argument missing");var r=!1,a=function(e,t,i){r||(r=!0,n.callback(e,t,i))};function t(e){return clearTimeout(o),e instanceof Error||(e=new Error(""+(e||"Unknown XMLHttpRequest Error"))),e.statusCode=0,a(e,m)}function e(){if(!s){var e;clearTimeout(o),e=n.useXDR&&void 0===u.status?200:1223===u.status?204:u.status;var t=m,i=null;return 0!==e?(t={body:function(){var e=void 0;if(e=u.response?u.response:u.responseText||function(e){if("document"===e.responseType)return e.responseXML;var t=e.responseXML&&"parsererror"===e.responseXML.documentElement.nodeName;return""!==e.responseType||t?null:e.responseXML}(u),f)try{e=JSON.parse(e)}catch(e){}return e}(),statusCode:e,method:c,headers:{},url:l,rawRequest:u},u.getAllResponseHeaders&&(t.headers=pn(u.getAllResponseHeaders()))):i=new Error("Internal XMLHttpRequest Error"),a(i,t,t.body)}}var i,s,o,u=n.xhr||null,l=(u=u||(n.cors||n.useXDR?new vn.XDomainRequest:new vn.XMLHttpRequest)).url=n.uri||n.url,c=u.method=n.method||"GET",h=n.body||n.data,d=u.headers=n.headers||{},p=!!n.sync,f=!1,m={body:void 0,headers:{},statusCode:0,method:c,url:l,rawRequest:u};if("json"in n&&!1!==n.json&&(f=!0,d.accept||d.Accept||(d.Accept="application/json"),"GET"!==c&&"HEAD"!==c&&(d["content-type"]||d["Content-Type"]||(d["Content-Type"]="application/json"),h=JSON.stringify(!0===n.json?h:n.json))),u.onreadystatechange=function(){4===u.readyState&&setTimeout(e,0)},u.onload=e,u.onerror=t,u.onprogress=function(){},u.onabort=function(){s=!0},u.ontimeout=t,u.open(c,l,!p,n.username,n.password),p||(u.withCredentials=!!n.withCredentials),!p&&0<n.timeout&&(o=setTimeout(function(){if(!s){s=!0,u.abort("timeout");var e=new Error("XMLHttpRequest timeout");e.code="ETIMEDOUT",t(e)}},n.timeout)),u.setRequestHeader)for(i in d)d.hasOwnProperty(i)&&u.setRequestHeader(i,d[i]);else if(n.headers&&!function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}(n.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in n&&(u.responseType=n.responseType),"beforeSend"in n&&"function"==typeof n.beforeSend&&n.beforeSend(u),u.send(h||null),u}vn.XMLHttpRequest=v.XMLHttpRequest||function(){},vn.XDomainRequest="withCredentials"in new vn.XMLHttpRequest?vn.XMLHttpRequest:v.XDomainRequest,function(e,t){for(var i=0;i<e.length;i++)t(e[i])}(["get","put","post","patch","head","delete"],function(n){vn["delete"===n?"del":n]=function(e,t,i){return(t=yn(e,t,i)).method=n.toUpperCase(),_n(t)}});function bn(e,t){var i=new v.WebVTT.Parser(v,v.vttjs,v.WebVTT.StringDecoder()),n=[];i.oncue=function(e){t.addCue(e)},i.onparsingerror=function(e){n.push(e)},i.onflush=function(){t.trigger({type:"loadeddata",target:t})},i.parse(e),0<n.length&&(v.console&&v.console.groupCollapsed&&v.console.groupCollapsed("Text Track parsing errors for "+t.src),n.forEach(function(e){return p.error(e)}),v.console&&v.console.groupEnd&&v.console.groupEnd()),i.flush()}var Tn=function(l){function e(e){var t;if(void 0===e&&(e={}),!e.tech)throw new Error("A tech was not provided.");var i=Oe(e,{kind:zt[e.kind]||"subtitles",language:e.language||e.srclang||""}),n=$t[i.mode]||"disabled",r=i.default;"metadata"!==i.kind&&"chapters"!==i.kind||(n="hidden"),(t=l.call(this,i)||this).tech_=i.tech,t.cues_=[],t.activeCues_=[];var a=new Vt(t.cues_),s=new Vt(t.activeCues_),o=!1,u=pe(Me(t),function(){this.activeCues=this.activeCues,o&&(this.trigger("cuechange"),o=!1)});return"disabled"!==n&&t.tech_.ready(function(){t.tech_.on("timeupdate",u)},!0),Object.defineProperties(Me(t),{default:{get:function(){return r},set:function(){}},mode:{get:function(){return n},set:function(e){var t=this;$t[e]&&("disabled"!==(n=e)?this.tech_.ready(function(){t.tech_.on("timeupdate",u)},!0):this.tech_.off("timeupdate",u),this.trigger("modechange"))}},cues:{get:function(){return this.loaded_?a:null},set:function(){}},activeCues:{get:function(){if(!this.loaded_)return null;if(0===this.cues.length)return s;for(var e=this.tech_.currentTime(),t=[],i=0,n=this.cues.length;i<n;i++){var r=this.cues[i];r.startTime<=e&&r.endTime>=e?t.push(r):r.startTime===r.endTime&&r.startTime<=e&&r.startTime+.5>=e&&t.push(r)}if(o=!1,t.length!==this.activeCues_.length)o=!0;else for(var a=0;a<t.length;a++)-1===this.activeCues_.indexOf(t[a])&&(o=!0);return this.activeCues_=t,s.setCues_(this.activeCues_),s},set:function(){}}}),i.src?(t.src=i.src,function(e,n){var t={uri:e},i=Nt(e);i&&(t.cors=i),gn(t,pe(this,function(e,t,i){if(e)return p.error(e,t);n.loaded_=!0,"function"!=typeof v.WebVTT?n.tech_&&n.tech_.any(["vttjsloaded","vttjserror"],function(e){if("vttjserror"!==e.type)return bn(i,n);p.error("vttjs failed to load, stopping trying to process "+n.src)}):bn(i,n)}))}(i.src,Me(t))):t.loaded_=!0,t}De(e,l);var t=e.prototype;return t.addCue=function(e){var t=e;if(v.vttjs&&!(e instanceof v.vttjs.VTTCue)){for(var i in t=new v.vttjs.VTTCue(e.startTime,e.endTime,e.text),e)i in t||(t[i]=e[i]);t.id=e.id,t.originalCue_=e}for(var n=this.tech_.textTracks(),r=0;r<n.length;r++)n[r]!==this&&n[r].removeCue(t);this.cues_.push(t),this.cues.setCues_(this.cues_)},t.removeCue=function(e){for(var t=this.cues_.length;t--;){var i=this.cues_[t];if(i===e||i.originalCue_&&i.originalCue_===e){this.cues_.splice(t,1),this.cues.setCues_(this.cues_);break}}},e}(Gt);Tn.prototype.allowedEvents_={cuechange:"cuechange"};var Sn=function(r){function e(e){var t;void 0===e&&(e={});var i=Oe(e,{kind:Wt[e.kind]||""});t=r.call(this,i)||this;var n=!1;return Object.defineProperty(Me(t),"enabled",{get:function(){return n},set:function(e){"boolean"==typeof e&&e!==n&&(n=e,this.trigger("enabledchange"))}}),i.enabled&&(t.enabled=i.enabled),t.loaded_=!0,t}return De(e,r),e}(Gt),kn=function(r){function e(e){var t;void 0===e&&(e={});var i=Oe(e,{kind:qt[e.kind]||""});t=r.call(this,i)||this;var n=!1;return Object.defineProperty(Me(t),"selected",{get:function(){return n},set:function(e){"boolean"==typeof e&&e!==n&&(n=e,this.trigger("selectedchange"))}}),i.selected&&(t.selected=i.selected),t}return De(e,r),e}(Gt),Cn=function(r){function e(e){var t,i;void 0===e&&(e={}),t=r.call(this)||this;var n=new Tn(e);return t.kind=n.kind,t.src=n.src,t.srclang=n.language,t.label=n.label,t.default=n.default,Object.defineProperties(Me(t),{readyState:{get:function(){return i}},track:{get:function(){return n}}}),i=0,n.addEventListener("loadeddata",function(){i=2,t.trigger({type:"load",target:Me(t)})}),t}return De(e,r),e}(me);Cn.prototype.allowedEvents_={load:"load"},Cn.NONE=0,Cn.LOADING=1,Cn.LOADED=2,Cn.ERROR=3;var En={audio:{ListClass:Bt,TrackClass:Sn,capitalName:"Audio"},video:{ListClass:jt,TrackClass:kn,capitalName:"Video"},text:{ListClass:Ft,TrackClass:Tn,capitalName:"Text"}};Object.keys(En).forEach(function(e){En[e].getterName=e+"Tracks",En[e].privateName=e+"Tracks_"});var wn={remoteText:{ListClass:Ft,TrackClass:Tn,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:Ht,TrackClass:Cn,capitalName:"RemoteTextTrackEls",getterName:"remoteTextTrackEls",privateName:"remoteTextTrackEls_"}},An=Oe(En,wn);wn.names=Object.keys(wn),En.names=Object.keys(En),An.names=[].concat(wn.names).concat(En.names);var Pn=Object.create||function(e){if(1!==arguments.length)throw new Error("Object.create shim only accepts one parameter.");return In.prototype=e,new In};function In(){}function Ln(e,t){this.name="ParsingError",this.code=e.code,this.message=t||e.message}function On(e){function t(e,t,i,n){return 3600*(0|e)+60*(0|t)+(0|i)+(0|n)/1e3}var i=e.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);return i?i[3]?t(i[1],i[2],i[3].replace(":",""),i[4]):59<i[1]?t(i[1],i[2],0,i[4]):t(0,i[1],i[2],i[4]):null}function xn(){this.values=Pn(null)}function Dn(e,t,i,n){var r=n?e.split(n):[e];for(var a in r)if("string"==typeof r[a]){var s=r[a].split(i);if(2===s.length)t(s[0],s[1])}}function Un(t,e,a){var i,n,s,r=t;function o(){var e=On(t);if(null===e)throw new Ln(Ln.Errors.BadTimeStamp,"Malformed timestamp: "+r);return t=t.replace(/^[^\sa-zA-Z-]+/,""),e}function u(){t=t.replace(/^\s+/,"")}if(u(),e.startTime=o(),u(),"--\x3e"!==t.substr(0,3))throw new Ln(Ln.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+r);t=t.substr(3),u(),e.endTime=o(),u(),i=t,n=e,s=new xn,Dn(i,function(e,t){switch(e){case"region":for(var i=a.length-1;0<=i;i--)if(a[i].id===t){s.set(e,a[i].region);break}break;case"vertical":s.alt(e,t,["rl","lr"]);break;case"line":var n=t.split(","),r=n[0];s.integer(e,r),s.percent(e,r)&&s.set("snapToLines",!1),s.alt(e,r,["auto"]),2===n.length&&s.alt("lineAlign",n[1],["start","middle","end"]);break;case"position":n=t.split(","),s.percent(e,n[0]),2===n.length&&s.alt("positionAlign",n[1],["start","middle","end"]);break;case"size":s.percent(e,t);break;case"align":s.alt(e,t,["start","middle","end","left","right"])}},/:/,/\s/),n.region=s.get("region",null),n.vertical=s.get("vertical",""),n.line=s.get("line","auto"),n.lineAlign=s.get("lineAlign","start"),n.snapToLines=s.get("snapToLines",!0),n.size=s.get("size",100),n.align=s.get("align","middle"),n.position=s.get("position",{start:0,left:0,middle:50,end:100,right:100},n.align),n.positionAlign=s.get("positionAlign",{start:"start",left:"start",middle:"middle",end:"end",right:"end"},n.align)}((Ln.prototype=Pn(Error.prototype)).constructor=Ln).Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},xn.prototype={set:function(e,t){this.get(e)||""===t||(this.values[e]=t)},get:function(e,t,i){return i?this.has(e)?this.values[e]:t[i]:this.has(e)?this.values[e]:t},has:function(e){return e in this.values},alt:function(e,t,i){for(var n=0;n<i.length;++n)if(t===i[n]){this.set(e,t);break}},integer:function(e,t){/^-?\d+$/.test(t)&&this.set(e,parseInt(t,10))},percent:function(e,t){return!!(t.match(/^([\d]{1,3})(\.[\d]*)?%$/)&&0<=(t=parseFloat(t))&&t<=100)&&(this.set(e,t),!0)}};var Rn={"&amp;":"&","&lt;":"<","&gt;":">","&lrm;":"‎","&rlm;":"‏","&nbsp;":" "},Mn={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},Nn={v:"title",lang:"lang"},Bn={rt:"ruby"};function jn(a,i){function e(){if(!i)return null;var e,t=i.match(/^([^<]*)(<[^>]*>?)?/);return e=t[1]?t[1]:t[2],i=i.substr(e.length),e}function t(e){return Rn[e]}function n(e){for(;f=e.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)e=e.replace(f[0],t);return e}function r(e,t){var i=Mn[e];if(!i)return null;var n=a.document.createElement(i);n.localName=i;var r=Nn[e];return r&&t&&(n[r]=t.trim()),n}for(var s,o,u,l=a.document.createElement("div"),c=l,h=[];null!==(s=e());)if("<"!==s[0])c.appendChild(a.document.createTextNode(n(s)));else{if("/"===s[1]){h.length&&h[h.length-1]===s.substr(2).replace(">","")&&(h.pop(),c=c.parentNode);continue}var d,p=On(s.substr(1,s.length-2));if(p){d=a.document.createProcessingInstruction("timestamp",p),c.appendChild(d);continue}var f=s.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!f)continue;if(!(d=r(f[1],f[3])))continue;if(o=c,Bn[(u=d).localName]&&Bn[u.localName]!==o.localName)continue;f[2]&&(d.className=f[2].substr(1).replace("."," ")),h.push(f[1]),c.appendChild(d),c=d}return l}var Fn=[[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]];function Hn(e){for(var t=0;t<Fn.length;t++){var i=Fn[t];if(e>=i[0]&&e<=i[1])return!0}return!1}function Vn(){}function qn(e,t,i){Vn.call(this),this.cue=t,this.cueDiv=jn(e,t.text);var n={color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 0.8)",position:"relative",left:0,right:0,top:0,bottom:0,display:"inline",writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext"};this.applyStyles(n,this.cueDiv),this.div=e.document.createElement("div"),n={direction:function(e){var t=[],i="";if(!e||!e.childNodes)return"ltr";function r(e,t){for(var i=t.childNodes.length-1;0<=i;i--)e.push(t.childNodes[i])}function a(e){if(!e||!e.length)return null;var t=e.pop(),i=t.textContent||t.innerText;if(i){var n=i.match(/^.*(\n|\r)/);return n?n[e.length=0]:i}return"ruby"===t.tagName?a(e):t.childNodes?(r(e,t),a(e)):void 0}for(r(t,e);i=a(t);)for(var n=0;n<i.length;n++)if(Hn(i.charCodeAt(n)))return"rtl";return"ltr"}(this.cueDiv),writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext",textAlign:"middle"===t.align?"center":t.align,font:i.font,whiteSpace:"pre-line",position:"absolute"},this.applyStyles(n),this.div.appendChild(this.cueDiv);var r=0;switch(t.positionAlign){case"start":r=t.position;break;case"middle":r=t.position-t.size/2;break;case"end":r=t.position-t.size}""===t.vertical?this.applyStyles({left:this.formatStyle(r,"%"),width:this.formatStyle(t.size,"%")}):this.applyStyles({top:this.formatStyle(r,"%"),height:this.formatStyle(t.size,"%")}),this.move=function(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")})}}function Wn(e){var t,i,n,r;if(e.div){i=e.div.offsetHeight,n=e.div.offsetWidth,r=e.div.offsetTop;var a=(a=e.div.childNodes)&&(a=a[0])&&a.getClientRects&&a.getClientRects();e=e.div.getBoundingClientRect(),t=a?Math.max(a[0]&&a[0].height||0,e.height/a.length):0}this.left=e.left,this.right=e.right,this.top=e.top||r,this.height=e.height||i,this.bottom=e.bottom||r+(e.height||i),this.width=e.width||n,this.lineHeight=void 0!==t?t:e.lineHeight}function zn(e,t,o,u){var i=new Wn(t),n=t.cue,r=function(e){if("number"==typeof e.line&&(e.snapToLines||0<=e.line&&e.line<=100))return e.line;if(!e.track||!e.track.textTrackList||!e.track.textTrackList.mediaElement)return-1;for(var t=e.track,i=t.textTrackList,n=0,r=0;r<i.length&&i[r]!==t;r++)"showing"===i[r].mode&&n++;return-1*++n}(n),a=[];if(n.snapToLines){var s;switch(n.vertical){case"":a=["+y","-y"],s="height";break;case"rl":a=["+x","-x"],s="width";break;case"lr":a=["-x","+x"],s="width"}var l=i.lineHeight,c=l*Math.round(r),h=o[s]+l,d=a[0];Math.abs(c)>h&&(c=c<0?-1:1,c*=Math.ceil(h/l)*l),r<0&&(c+=""===n.vertical?o.height:o.width,a=a.reverse()),i.move(d,c)}else{var p=i.lineHeight/o.height*100;switch(n.lineAlign){case"middle":r-=p/2;break;case"end":r-=p}switch(n.vertical){case"":t.applyStyles({top:t.formatStyle(r,"%")});break;case"rl":t.applyStyles({left:t.formatStyle(r,"%")});break;case"lr":t.applyStyles({right:t.formatStyle(r,"%")})}a=["+y","-x","+x","-y"],i=new Wn(t)}var f=function(e,t){for(var i,n=new Wn(e),r=1,a=0;a<t.length;a++){for(;e.overlapsOppositeAxis(o,t[a])||e.within(o)&&e.overlapsAny(u);)e.move(t[a]);if(e.within(o))return e;var s=e.intersectPercentage(o);s<r&&(i=new Wn(e),r=s),e=new Wn(n)}return i||n}(i,a);t.move(f.toCSSCompatValues(o))}function $n(){}Vn.prototype.applyStyles=function(e,t){for(var i in t=t||this.div,e)e.hasOwnProperty(i)&&(t.style[i]=e[i])},Vn.prototype.formatStyle=function(e,t){return 0===e?0:e+t},(qn.prototype=Pn(Vn.prototype)).constructor=qn,Wn.prototype.move=function(e,t){switch(t=void 0!==t?t:this.lineHeight,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}},Wn.prototype.overlaps=function(e){return this.left<e.right&&this.right>e.left&&this.top<e.bottom&&this.bottom>e.top},Wn.prototype.overlapsAny=function(e){for(var t=0;t<e.length;t++)if(this.overlaps(e[t]))return!0;return!1},Wn.prototype.within=function(e){return this.top>=e.top&&this.bottom<=e.bottom&&this.left>=e.left&&this.right<=e.right},Wn.prototype.overlapsOppositeAxis=function(e,t){switch(t){case"+x":return this.left<e.left;case"-x":return this.right>e.right;case"+y":return this.top<e.top;case"-y":return this.bottom>e.bottom}},Wn.prototype.intersectPercentage=function(e){return Math.max(0,Math.min(this.right,e.right)-Math.max(this.left,e.left))*Math.max(0,Math.min(this.bottom,e.bottom)-Math.max(this.top,e.top))/(this.height*this.width)},Wn.prototype.toCSSCompatValues=function(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}},Wn.getSimpleBoxPosition=function(e){var t=e.div?e.div.offsetHeight:e.tagName?e.offsetHeight:0,i=e.div?e.div.offsetWidth:e.tagName?e.offsetWidth:0,n=e.div?e.div.offsetTop:e.tagName?e.offsetTop:0;return{left:(e=e.div?e.div.getBoundingClientRect():e.tagName?e.getBoundingClientRect():e).left,right:e.right,top:e.top||n,height:e.height||t,bottom:e.bottom||n+(e.height||t),width:e.width||i}},$n.StringDecoder=function(){return{decode:function(e){if(!e)return"";if("string"!=typeof e)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(e))}}},$n.convertCueToDOMTree=function(e,t){return e&&t?jn(e,t):null};$n.processCues=function(n,r,e){if(!n||!r||!e)return null;for(;e.firstChild;)e.removeChild(e.firstChild);var a=n.document.createElement("div");if(a.style.position="absolute",a.style.left="0",a.style.right="0",a.style.top="0",a.style.bottom="0",a.style.margin="1.5%",e.appendChild(a),function(e){for(var t=0;t<e.length;t++)if(e[t].hasBeenReset||!e[t].displayState)return!0;return!1}(r)){var s=[],o=Wn.getSimpleBoxPosition(a),u={font:Math.round(.05*o.height*100)/100+"px sans-serif"};!function(){for(var e,t,i=0;i<r.length;i++)t=r[i],e=new qn(n,t,u),a.appendChild(e.div),zn(0,e,o,s),t.displayState=e.div,s.push(Wn.getSimpleBoxPosition(e))}()}else for(var t=0;t<r.length;t++)a.appendChild(r[t].displayState)},($n.Parser=function(e,t,i){i||(i=t,t={}),t=t||{},this.window=e,this.vttjs=t,this.state="INITIAL",this.buffer="",this.decoder=i||new TextDecoder("utf8"),this.regionList=[]}).prototype={reportOrThrowError:function(e){if(!(e instanceof Ln))throw e;this.onparsingerror&&this.onparsingerror(e)},parse:function(e){var n=this;function t(){for(var e=n.buffer,t=0;t<e.length&&"\r"!==e[t]&&"\n"!==e[t];)++t;var i=e.substr(0,t);return"\r"===e[t]&&++t,"\n"===e[t]&&++t,n.buffer=e.substr(t),i}function i(e){e.match(/X-TIMESTAMP-MAP/)?Dn(e,function(e,t){switch(e){case"X-TIMESTAMP-MAP":!function(e){var i=new xn;Dn(e,function(e,t){switch(e){case"MPEGT":i.integer(e+"S",t);break;case"LOCA":i.set(e+"L",On(t))}},/[^\d]:/,/,/),n.ontimestampmap&&n.ontimestampmap({MPEGTS:i.get("MPEGTS"),LOCAL:i.get("LOCAL")})}(t)}},/=/):Dn(e,function(e,t){switch(e){case"Region":!function(e){var r=new xn;if(Dn(e,function(e,t){switch(e){case"id":r.set(e,t);break;case"width":r.percent(e,t);break;case"lines":r.integer(e,t);break;case"regionanchor":case"viewportanchor":var i=t.split(",");if(2!==i.length)break;var n=new xn;if(n.percent("x",i[0]),n.percent("y",i[1]),!n.has("x")||!n.has("y"))break;r.set(e+"X",n.get("x")),r.set(e+"Y",n.get("y"));break;case"scroll":r.alt(e,t,["up"])}},/=/,/\s/),r.has("id")){var t=new(n.vttjs.VTTRegion||n.window.VTTRegion);t.width=r.get("width",100),t.lines=r.get("lines",3),t.regionAnchorX=r.get("regionanchorX",0),t.regionAnchorY=r.get("regionanchorY",100),t.viewportAnchorX=r.get("viewportanchorX",0),t.viewportAnchorY=r.get("viewportanchorY",100),t.scroll=r.get("scroll",""),n.onregion&&n.onregion(t),n.regionList.push({id:r.get("id"),region:t})}}(t)}},/:/)}e&&(n.buffer+=n.decoder.decode(e,{stream:!0}));try{var r;if("INITIAL"===n.state){if(!/\r\n|\n/.test(n.buffer))return this;var a=(r=t()).match(/^WEBVTT([ \t].*)?$/);if(!a||!a[0])throw new Ln(Ln.Errors.BadSignature);n.state="HEADER"}for(var s=!1;n.buffer;){if(!/\r\n|\n/.test(n.buffer))return this;switch(s?s=!1:r=t(),n.state){case"HEADER":/:/.test(r)?i(r):r||(n.state="ID");continue;case"NOTE":r||(n.state="ID");continue;case"ID":if(/^NOTE($|[ \t])/.test(r)){n.state="NOTE";break}if(!r)continue;if(n.cue=new(n.vttjs.VTTCue||n.window.VTTCue)(0,0,""),n.state="CUE",-1===r.indexOf("--\x3e")){n.cue.id=r;continue}case"CUE":try{Un(r,n.cue,n.regionList)}catch(e){n.reportOrThrowError(e),n.cue=null,n.state="BADCUE";continue}n.state="CUETEXT";continue;case"CUETEXT":var o=-1!==r.indexOf("--\x3e");if(!r||o&&(s=!0)){n.oncue&&n.oncue(n.cue),n.cue=null,n.state="ID";continue}n.cue.text&&(n.cue.text+="\n"),n.cue.text+=r;continue;case"BADCUE":r||(n.state="ID");continue}}}catch(e){n.reportOrThrowError(e),"CUETEXT"===n.state&&n.cue&&n.oncue&&n.oncue(n.cue),n.cue=null,n.state="INITIAL"===n.state?"BADWEBVTT":"BADCUE"}return this},flush:function(){var t=this;try{if(t.buffer+=t.decoder.decode(),!t.cue&&"HEADER"!==t.state||(t.buffer+="\n\n",t.parse()),"INITIAL"===t.state)throw new Ln(Ln.Errors.BadSignature)}catch(e){t.reportOrThrowError(e)}return t.onflush&&t.onflush(),this}};var Gn=$n,Xn={"":1,lr:1,rl:1},Kn={start:1,middle:1,end:1,left:1,right:1};function Yn(e){return"string"==typeof e&&(!!Kn[e.toLowerCase()]&&e.toLowerCase())}function Qn(e,t,i){this.hasBeenReset=!1;var n="",r=!1,a=e,s=t,o=i,u=null,l="",c=!0,h="auto",d="start",p=50,f="middle",m=50,g="middle";Object.defineProperties(this,{id:{enumerable:!0,get:function(){return n},set:function(e){n=""+e}},pauseOnExit:{enumerable:!0,get:function(){return r},set:function(e){r=!!e}},startTime:{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e)throw new TypeError("Start time must be set to a number.");a=e,this.hasBeenReset=!0}},endTime:{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e)throw new TypeError("End time must be set to a number.");s=e,this.hasBeenReset=!0}},text:{enumerable:!0,get:function(){return o},set:function(e){o=""+e,this.hasBeenReset=!0}},region:{enumerable:!0,get:function(){return u},set:function(e){u=e,this.hasBeenReset=!0}},vertical:{enumerable:!0,get:function(){return l},set:function(e){var t=function(e){return"string"==typeof e&&(!!Xn[e.toLowerCase()]&&e.toLowerCase())}(e);if(!1===t)throw new SyntaxError("An invalid or illegal string was specified.");l=t,this.hasBeenReset=!0}},snapToLines:{enumerable:!0,get:function(){return c},set:function(e){c=!!e,this.hasBeenReset=!0}},line:{enumerable:!0,get:function(){return h},set:function(e){if("number"!=typeof e&&"auto"!==e)throw new SyntaxError("An invalid number or illegal string was specified.");h=e,this.hasBeenReset=!0}},lineAlign:{enumerable:!0,get:function(){return d},set:function(e){var t=Yn(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");d=t,this.hasBeenReset=!0}},position:{enumerable:!0,get:function(){return p},set:function(e){if(e<0||100<e)throw new Error("Position must be between 0 and 100.");p=e,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return f},set:function(e){var t=Yn(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");f=t,this.hasBeenReset=!0}},size:{enumerable:!0,get:function(){return m},set:function(e){if(e<0||100<e)throw new Error("Size must be between 0 and 100.");m=e,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return g},set:function(e){var t=Yn(e);if(!t)throw new SyntaxError("An invalid or illegal string was specified.");g=t,this.hasBeenReset=!0}}}),this.displayState=void 0}Qn.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var Jn=Qn,Zn={"":!0,up:!0};function er(e){return"number"==typeof e&&0<=e&&e<=100}function tr(){var t=100,i=3,n=0,r=100,a=0,s=100,o="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return t},set:function(e){if(!er(e))throw new Error("Width must be between 0 and 100.");t=e}},lines:{enumerable:!0,get:function(){return i},set:function(e){if("number"!=typeof e)throw new TypeError("Lines must be set to a number.");i=e}},regionAnchorY:{enumerable:!0,get:function(){return r},set:function(e){if(!er(e))throw new Error("RegionAnchorX must be between 0 and 100.");r=e}},regionAnchorX:{enumerable:!0,get:function(){return n},set:function(e){if(!er(e))throw new Error("RegionAnchorY must be between 0 and 100.");n=e}},viewportAnchorY:{enumerable:!0,get:function(){return s},set:function(e){if(!er(e))throw new Error("ViewportAnchorY must be between 0 and 100.");s=e}},viewportAnchorX:{enumerable:!0,get:function(){return a},set:function(e){if(!er(e))throw new Error("ViewportAnchorX must be between 0 and 100.");a=e}},scroll:{enumerable:!0,get:function(){return o},set:function(e){var t=function(e){return"string"==typeof e&&(!!Zn[e.toLowerCase()]&&e.toLowerCase())}(e);if(!1===t)throw new SyntaxError("An invalid or illegal string was specified.");o=t}}})}var ir=wt(function(e){var t=e.exports={WebVTT:Gn,VTTCue:Jn,VTTRegion:tr};v.vttjs=t,v.WebVTT=t.WebVTT;var i=t.VTTCue,n=t.VTTRegion,r=v.VTTCue,a=v.VTTRegion;t.shim=function(){v.VTTCue=i,v.VTTRegion=n},t.restore=function(){v.VTTCue=r,v.VTTRegion=a},v.VTTCue||t.shim()});ir.WebVTT,ir.VTTCue,ir.VTTRegion;var nr=function(t){function i(i,e){var n;return void 0===i&&(i={}),void 0===e&&(e=function(){}),i.reportTouchActivity=!1,(n=t.call(this,null,i,e)||this).hasStarted_=!1,n.on("playing",function(){this.hasStarted_=!0}),n.on("loadstart",function(){this.hasStarted_=!1}),An.names.forEach(function(e){var t=An[e];i&&i[t.getterName]&&(n[t.privateName]=i[t.getterName])}),n.featuresProgressEvents||n.manualProgressOn(),n.featuresTimeupdateEvents||n.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach(function(e){!1===i["native"+e+"Tracks"]&&(n["featuresNative"+e+"Tracks"]=!1)}),!1===i.nativeCaptions||!1===i.nativeTextTracks?n.featuresNativeTextTracks=!1:!0!==i.nativeCaptions&&!0!==i.nativeTextTracks||(n.featuresNativeTextTracks=!0),n.featuresNativeTextTracks||n.emulateTextTracks(),n.autoRemoteTextTracks_=new An.text.ListClass,n.initTrackListeners(),i.nativeControlsForTouch||n.emitTapEvents(),n.constructor&&(n.name_=n.constructor.name||"Unknown Tech"),n}De(i,t);var e=i.prototype;return e.triggerSourceset=function(e){var t=this;this.isReady_||this.one("ready",function(){return t.setTimeout(function(){return t.triggerSourceset(e)},1)}),this.trigger({src:e,type:"sourceset"})},e.manualProgressOn=function(){this.on("durationchange",this.onDurationChange),this.manualProgress=!0,this.one("ready",this.trackProgress)},e.manualProgressOff=function(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange)},e.trackProgress=function(e){this.stopTrackingProgress(),this.progressInterval=this.setInterval(pe(this,function(){var e=this.bufferedPercent();this.bufferedPercent_!==e&&this.trigger("progress"),1===(this.bufferedPercent_=e)&&this.stopTrackingProgress()}),500)},e.onDurationChange=function(e){this.duration_=this.duration()},e.buffered=function(){return ct(0,0)},e.bufferedPercent=function(){return ht(this.buffered(),this.duration_)},e.stopTrackingProgress=function(){this.clearInterval(this.progressInterval)},e.manualTimeUpdatesOn=function(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime),this.on("pause",this.stopTrackingCurrentTime)},e.manualTimeUpdatesOff=function(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime),this.off("pause",this.stopTrackingCurrentTime)},e.trackCurrentTime=function(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval(function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},250)},e.stopTrackingCurrentTime=function(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.dispose=function(){this.clearTracks(En.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),t.prototype.dispose.call(this)},e.clearTracks=function(e){var r=this;(e=[].concat(e)).forEach(function(e){for(var t=r[e+"Tracks"]()||[],i=t.length;i--;){var n=t[i];"text"===e&&r.removeRemoteTextTrack(n),t.removeTrack(n)}})},e.cleanupAutoTextTracks=function(){for(var e=this.autoRemoteTextTracks_||[],t=e.length;t--;){var i=e[t];this.removeRemoteTextTrack(i)}},e.reset=function(){},e.error=function(e){return void 0!==e&&(this.error_=new vt(e),this.trigger("error")),this.error_},e.played=function(){return this.hasStarted_?ct(0,0):ct()},e.setCurrentTime=function(){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.initTrackListeners=function(){var r=this;En.names.forEach(function(e){function t(){r.trigger(e+"trackchange")}var i=En[e],n=r[i.getterName]();n.addEventListener("removetrack",t),n.addEventListener("addtrack",t),r.on("dispose",function(){n.removeEventListener("removetrack",t),n.removeEventListener("addtrack",t)})})},e.addWebVttScript_=function(){var e=this;if(!v.WebVTT)if(h.body.contains(this.el())){if(!this.options_["vtt.js"]&&o(ir)&&0<Object.keys(ir).length)return void this.trigger("vttjsloaded");var t=h.createElement("script");t.src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",t.onload=function(){e.trigger("vttjsloaded")},t.onerror=function(){e.trigger("vttjserror")},this.on("dispose",function(){t.onload=null,t.onerror=null}),v.WebVTT=!0,this.el().parentNode.appendChild(t)}else this.ready(this.addWebVttScript_)},e.emulateTextTracks=function(){function t(e){return n.addTrack(e.track)}function i(e){return n.removeTrack(e.track)}var e=this,n=this.textTracks(),r=this.remoteTextTracks();r.on("addtrack",t),r.on("removetrack",i),this.addWebVttScript_();function a(){return e.trigger("texttrackchange")}function s(){a();for(var e=0;e<n.length;e++){var t=n[e];t.removeEventListener("cuechange",a),"showing"===t.mode&&t.addEventListener("cuechange",a)}}s(),n.addEventListener("change",s),n.addEventListener("addtrack",s),n.addEventListener("removetrack",s),this.on("dispose",function(){r.off("addtrack",t),r.off("removetrack",i),n.removeEventListener("change",s),n.removeEventListener("addtrack",s),n.removeEventListener("removetrack",s);for(var e=0;e<n.length;e++){n[e].removeEventListener("cuechange",a)}})},e.addTextTrack=function(e,t,i){if(!e)throw new Error("TextTrack kind is required but was not provided");return function(e,t,i,n,r){void 0===r&&(r={});var a=e.textTracks();r.kind=t,i&&(r.label=i),n&&(r.language=n),r.tech=e;var s=new An.text.TrackClass(r);return a.addTrack(s),s}(this,e,t,i)},e.createRemoteTextTrack=function(e){var t=Oe(e,{tech:this});return new wn.remoteTextEl.TrackClass(t)},e.addRemoteTextTrack=function(e,t){var i=this;void 0===e&&(e={});var n=this.createRemoteTextTrack(e);return!0!==t&&!1!==t&&(p.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'),t=!0),this.remoteTextTrackEls().addTrackElement_(n),this.remoteTextTracks().addTrack(n.track),!0!==t&&this.ready(function(){return i.autoRemoteTextTracks_.addTrack(n.track)}),n},e.removeRemoteTextTrack=function(e){var t=this.remoteTextTrackEls().getTrackElementByTrack_(e);this.remoteTextTrackEls().removeTrackElement_(t),this.remoteTextTracks().removeTrack(e),this.autoRemoteTextTracks_.removeTrack(e)},e.getVideoPlaybackQuality=function(){return{}},e.requestPictureInPicture=function(){var e=this.options_.Promise||v.Promise;if(e)return e.reject()},e.setPoster=function(){},e.playsinline=function(){},e.setPlaysinline=function(){},e.overrideNativeAudioTracks=function(){},e.overrideNativeVideoTracks=function(){},e.canPlayType=function(){return""},i.canPlayType=function(){return""},i.canPlaySource=function(e,t){return i.canPlayType(e.type)},i.isTech=function(e){return e.prototype instanceof i||e instanceof i||e===i},i.registerTech=function(e,t){if(i.techs_||(i.techs_={}),!i.isTech(t))throw new Error("Tech "+e+" must be a Tech");if(!i.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!i.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return e=Le(e),i.techs_[e]=t,i.techs_[Ie(e)]=t,"Tech"!==e&&i.defaultTechOrder_.push(e),t},i.getTech=function(e){if(e)return i.techs_&&i.techs_[e]?i.techs_[e]:(e=Le(e),v&&v.videojs&&v.videojs[e]?(p.warn("The "+e+" tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)"),v.videojs[e]):void 0)},i}(xe);An.names.forEach(function(e){var t=An[e];nr.prototype[t.getterName]=function(){return this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName]}}),nr.prototype.featuresVolumeControl=!0,nr.prototype.featuresMuteControl=!0,nr.prototype.featuresFullscreenResize=!1,nr.prototype.featuresPlaybackRate=!1,nr.prototype.featuresProgressEvents=!1,nr.prototype.featuresSourceset=!1,nr.prototype.featuresTimeupdateEvents=!1,nr.prototype.featuresNativeTextTracks=!1,nr.withSourceHandlers=function(r){r.registerSourceHandler=function(e,t){var i=r.sourceHandlers;i=i||(r.sourceHandlers=[]),void 0===t&&(t=i.length),i.splice(t,0,e)},r.canPlayType=function(e){for(var t,i=r.sourceHandlers||[],n=0;n<i.length;n++)if(t=i[n].canPlayType(e))return t;return""},r.selectSourceHandler=function(e,t){for(var i=r.sourceHandlers||[],n=0;n<i.length;n++)if(i[n].canHandleSource(e,t))return i[n];return null},r.canPlaySource=function(e,t){var i=r.selectSourceHandler(e,t);return i?i.canHandleSource(e,t):""};["seekable","seeking","duration"].forEach(function(e){var t=this[e];"function"==typeof t&&(this[e]=function(){return this.sourceHandler_&&this.sourceHandler_[e]?this.sourceHandler_[e].apply(this.sourceHandler_,arguments):t.apply(this,arguments)})},r.prototype),r.prototype.setSource=function(e){var t=r.selectSourceHandler(e,this.options_);t||(r.nativeSourceHandler?t=r.nativeSourceHandler:p.error("No source handler found for the current source.")),this.disposeSourceHandler(),this.off("dispose",this.disposeSourceHandler),t!==r.nativeSourceHandler&&(this.currentSource_=e),this.sourceHandler_=t.handleSource(e,this,this.options_),this.one("dispose",this.disposeSourceHandler)},r.prototype.disposeSourceHandler=function(){this.currentSource_&&(this.clearTracks(["audio","video"]),this.currentSource_=null),this.cleanupAutoTextTracks(),this.sourceHandler_&&(this.sourceHandler_.dispose&&this.sourceHandler_.dispose(),this.sourceHandler_=null)}},xe.registerComponent("Tech",nr),nr.registerTech("Tech",nr),nr.defaultTechOrder_=[];var rr={},ar={},sr={};function or(e,t,i){e.setTimeout(function(){return function i(n,e,r,a,s,o){void 0===n&&(n={});void 0===e&&(e=[]);void 0===s&&(s=[]);void 0===o&&(o=!1);var t=e,u=t[0],l=t.slice(1);if("string"==typeof u)i(n,rr[u],r,a,s,o);else if(u){var c=pr(a,u);if(!c.setSource)return s.push(c),i(n,l,r,a,s,o);c.setSource(m({},n),function(e,t){if(e)return i(n,l,r,a,s,o);s.push(c),i(t,n.type===t.type?l:rr[t.type],r,a,s,o)})}else l.length?i(n,l,r,a,s,o):o?r(n,s):i(n,rr["*"],r,a,s,!0)}(t,rr[t.type],i,e)},1)}function ur(e,t,i,n){void 0===n&&(n=null);var r="call"+Le(i),a=e.reduce(dr(r),n),s=a===sr,o=s?null:t[i](a);return function(e,t,i,n){for(var r=e.length-1;0<=r;r--){var a=e[r];a[t]&&a[t](n,i)}}(e,i,o,s),o}var lr={buffered:1,currentTime:1,duration:1,seekable:1,played:1,paused:1,volume:1},cr={setCurrentTime:1,setVolume:1},hr={play:1,pause:1};function dr(i){return function(e,t){return e===sr?sr:t[i]?t[i](e):e}}function pr(e,t){var i=ar[e.id()],n=null;if(null==i)return n=t(e),ar[e.id()]=[[t,n]],n;for(var r=0;r<i.length;r++){var a=i[r],s=a[0],o=a[1];s===t&&(n=o)}return null===n&&(n=t(e),i.push([t,n])),n}function fr(e){void 0===e&&(e="");var t=Mt(e);return mr[t.toLowerCase()]||""}var mr={opus:"video/ogg",ogv:"video/ogg",mp4:"video/mp4",mov:"video/mp4",m4v:"video/mp4",mkv:"video/x-matroska",m4a:"audio/mp4",mp3:"audio/mpeg",aac:"audio/aac",oga:"audio/ogg",m3u8:"application/x-mpegURL",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"};function gr(e){if(!e.type){var t=fr(e.src);t&&(e.type=t)}return e}var yr=function(l){function e(e,t,i){var n,r=Oe({createEl:!1},t);if(n=l.call(this,e,r,i)||this,t.playerOptions.sources&&0!==t.playerOptions.sources.length)e.src(t.playerOptions.sources);else for(var a=0,s=t.playerOptions.techOrder;a<s.length;a++){var o=Le(s[a]),u=nr.getTech(o);if(o||(u=xe.getComponent(o)),u&&u.isSupported()){e.loadTech_(o);break}}return n}return De(e,l),e}(xe);xe.registerComponent("MediaLoader",yr);var vr=function(r){function e(e,t){var i;return(i=r.call(this,e,t)||this).emitTapEvents(),i.enable(),i}De(e,r);var t=e.prototype;return t.createEl=function(e,t,i){void 0===e&&(e="div"),void 0===t&&(t={}),void 0===i&&(i={}),t=m({innerHTML:'<span aria-hidden="true" class="vjs-icon-placeholder"></span>',className:this.buildCSSClass(),tabIndex:0},t),"button"===e&&p.error("Creating a ClickableComponent with an HTML element of "+e+" is not supported; use a Button instead."),i=m({role:"button"},i),this.tabIndex_=t.tabIndex;var n=r.prototype.createEl.call(this,e,t,i);return this.createControlTextEl(n),n},t.dispose=function(){this.controlTextEl_=null,r.prototype.dispose.call(this)},t.createControlTextEl=function(e){return this.controlTextEl_=b("span",{className:"vjs-control-text"},{"aria-live":"polite"}),e&&e.appendChild(this.controlTextEl_),this.controlText(this.controlText_,e),this.controlTextEl_},t.controlText=function(e,t){if(void 0===t&&(t=this.el()),void 0===e)return this.controlText_||"Need Text";var i=this.localize(e);this.controlText_=e,T(this.controlTextEl_,i),this.nonIconControl||t.setAttribute("title",i)},t.buildCSSClass=function(){return"vjs-control vjs-button "+r.prototype.buildCSSClass.call(this)},t.enable=function(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),"undefined"!=typeof this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick),this.on("keydown",this.handleKeyDown))},t.disable=function(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),"undefined"!=typeof this.tabIndex_&&this.el_.removeAttribute("tabIndex"),this.off("mouseover",this.handleMouseOver),this.off("mouseout",this.handleMouseOut),this.off(["tap","click"],this.handleClick),this.off("keydown",this.handleKeyDown)},t.handleClick=function(e){},t.handleKeyDown=function(e){At.isEventKey(e,"Space")||At.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):r.prototype.handleKeyDown.call(this,e)},e}(xe);xe.registerComponent("ClickableComponent",vr);var _r=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update(),e.on("posterchange",pe(Me(i),i.update)),i}De(e,n);var t=e.prototype;return t.dispose=function(){this.player().off("posterchange",this.update),n.prototype.dispose.call(this)},t.createEl=function(){return b("div",{className:"vjs-poster",tabIndex:-1})},t.update=function(e){var t=this.player().poster();this.setSrc(t),t?this.show():this.hide()},t.setSrc=function(e){var t="";e&&(t='url("'+e+'")'),this.el_.style.backgroundImage=t},t.handleClick=function(e){this.player_.controls()&&(this.player_.tech(!0)&&this.player_.tech(!0).focus(),this.player_.paused()?St(this.player_.play()):this.player_.pause())},e}(vr);xe.registerComponent("PosterImage",_r);var br="#222",Tr={monospace:"monospace",sansSerif:"sans-serif",serif:"serif",monospaceSansSerif:'"Andale Mono", "Lucida Console", monospace',monospaceSerif:'"Courier New", monospace',proportionalSansSerif:"sans-serif",proportionalSerif:"serif",casual:'"Comic Sans MS", Impact, fantasy',script:'"Monotype Corsiva", cursive',smallcaps:'"Andale Mono", "Lucida Console", monospace, sans-serif'};function Sr(e,t){var i;if(4===e.length)i=e[1]+e[1]+e[2]+e[2]+e[3]+e[3];else{if(7!==e.length)throw new Error("Invalid color code provided, "+e+"; must be formatted as e.g. #f0e or #f604e2.");i=e.slice(1)}return"rgba("+parseInt(i.slice(0,2),16)+","+parseInt(i.slice(2,4),16)+","+parseInt(i.slice(4,6),16)+","+t+")"}function kr(e,t,i){try{e.style[t]=i}catch(e){return}}var Cr=function(a){function e(i,e,t){var n;n=a.call(this,i,e,t)||this;var r=pe(Me(n),n.updateDisplay);return i.on("loadstart",pe(Me(n),n.toggleDisplay)),i.on("texttrackchange",r),i.on("loadedmetadata",pe(Me(n),n.preselectTrack)),i.ready(pe(Me(n),function(){if(i.tech_&&i.tech_.featuresNativeTextTracks)this.hide();else{i.on("fullscreenchange",r),i.on("playerresize",r),v.addEventListener("orientationchange",r),i.on("dispose",function(){return v.removeEventListener("orientationchange",r)});for(var e=this.options_.playerOptions.tracks||[],t=0;t<e.length;t++)this.player_.addRemoteTextTrack(e[t],!0);this.preselectTrack()}})),n}De(e,a);var t=e.prototype;return t.preselectTrack=function(){for(var e,t,i,n={captions:1,subtitles:1},r=this.player_.textTracks(),a=this.player_.cache_.selectedLanguage,s=0;s<r.length;s++){var o=r[s];a&&a.enabled&&a.language&&a.language===o.language&&o.kind in n?i=o.kind===a.kind?o:i||o:a&&!a.enabled?t=e=i=null:o.default&&("descriptions"!==o.kind||e?o.kind in n&&!t&&(t=o):e=o)}i?i.mode="showing":t?t.mode="showing":e&&(e.mode="showing")},t.toggleDisplay=function(){this.player_.tech_&&this.player_.tech_.featuresNativeTextTracks?this.hide():this.show()},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-text-track-display"},{"aria-live":"off","aria-atomic":"true"})},t.clearDisplay=function(){"function"==typeof v.WebVTT&&v.WebVTT.processCues(v,[],this.el_)},t.updateDisplay=function(){var e=this.player_.textTracks(),t=this.options_.allowMultipleShowingTracks;if(this.clearDisplay(),t){for(var i=[],n=0;n<e.length;++n){var r=e[n];"showing"===r.mode&&i.push(r)}this.updateForTrack(i)}else{for(var a=null,s=null,o=e.length;o--;){var u=e[o];"showing"===u.mode&&("descriptions"===u.kind?a=u:s=u)}s?("off"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","off"),this.updateForTrack(s)):a&&("assertive"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","assertive"),this.updateForTrack(a))}},t.updateDisplayState=function(e){for(var t=this.player_.textTrackSettings.getValues(),i=e.activeCues,n=i.length;n--;){var r=i[n];if(r){var a=r.displayState;if(t.color&&(a.firstChild.style.color=t.color),t.textOpacity&&kr(a.firstChild,"color",Sr(t.color||"#fff",t.textOpacity)),t.backgroundColor&&(a.firstChild.style.backgroundColor=t.backgroundColor),t.backgroundOpacity&&kr(a.firstChild,"backgroundColor",Sr(t.backgroundColor||"#000",t.backgroundOpacity)),t.windowColor&&(t.windowOpacity?kr(a,"backgroundColor",Sr(t.windowColor,t.windowOpacity)):a.style.backgroundColor=t.windowColor),t.edgeStyle&&("dropshadow"===t.edgeStyle?a.firstChild.style.textShadow="2px 2px 3px #222, 2px 2px 4px #222, 2px 2px 5px "+br:"raised"===t.edgeStyle?a.firstChild.style.textShadow="1px 1px #222, 2px 2px #222, 3px 3px "+br:"depressed"===t.edgeStyle?a.firstChild.style.textShadow="1px 1px #ccc, 0 1px #ccc, -1px -1px #222, 0 -1px "+br:"uniform"===t.edgeStyle&&(a.firstChild.style.textShadow="0 0 4px #222, 0 0 4px #222, 0 0 4px #222, 0 0 4px "+br)),t.fontPercent&&1!==t.fontPercent){var s=v.parseFloat(a.style.fontSize);a.style.fontSize=s*t.fontPercent+"px",a.style.height="auto",a.style.top="auto",a.style.bottom="2px"}t.fontFamily&&"default"!==t.fontFamily&&("small-caps"===t.fontFamily?a.firstChild.style.fontVariant="small-caps":a.firstChild.style.fontFamily=Tr[t.fontFamily])}}},t.updateForTrack=function(e){if(Array.isArray(e)||(e=[e]),"function"==typeof v.WebVTT&&!e.every(function(e){return!e.activeCues})){for(var t=[],i=0;i<e.length;++i)for(var n=e[i],r=0;r<n.activeCues.length;++r)t.push(n.activeCues[r]);v.WebVTT.processCues(v,t,this.el_);for(var a=0;a<e.length;++a){for(var s=e[a],o=0;o<s.activeCues.length;++o){var u=s.activeCues[o].displayState;C(u,"vjs-text-track-cue"),C(u,"vjs-text-track-cue-"+(s.language?s.language:a))}this.player_.textTrackSettings&&this.updateDisplayState(s)}}},e}(xe);xe.registerComponent("TextTrackDisplay",Cr);var Er=function(r){function e(){return r.apply(this,arguments)||this}return De(e,r),e.prototype.createEl=function(){var e=this.player_.isAudio(),t=this.localize(e?"Audio Player":"Video Player"),i=b("span",{className:"vjs-control-text",innerHTML:this.localize("{1} is loading.",[t])}),n=r.prototype.createEl.call(this,"div",{className:"vjs-loading-spinner",dir:"ltr"});return n.appendChild(i),n},e}(xe);xe.registerComponent("LoadingSpinner",Er);var wr=function(t){function e(){return t.apply(this,arguments)||this}De(e,t);var i=e.prototype;return i.createEl=function(e,t,i){void 0===t&&(t={}),void 0===i&&(i={}),t=m({innerHTML:'<span aria-hidden="true" class="vjs-icon-placeholder"></span>',className:this.buildCSSClass()},t),i=m({type:"button"},i);var n=xe.prototype.createEl.call(this,"button",t,i);return this.createControlTextEl(n),n},i.addChild=function(e,t){void 0===t&&(t={});var i=this.constructor.name;return p.warn("Adding an actionable (user controllable) child to a Button ("+i+") is not supported; use a ClickableComponent instead."),xe.prototype.addChild.call(this,e,t)},i.enable=function(){t.prototype.enable.call(this),this.el_.removeAttribute("disabled")},i.disable=function(){t.prototype.disable.call(this),this.el_.setAttribute("disabled","disabled")},i.handleKeyDown=function(e){At.isEventKey(e,"Space")||At.isEventKey(e,"Enter")?e.stopPropagation():t.prototype.handleKeyDown.call(this,e)},e}(vr);xe.registerComponent("Button",wr);var Ar=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).mouseused_=!1,i.on("mousedown",i.handleMouseDown),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-big-play-button"},t.handleClick=function(e){var t=this.player_.play();if(this.mouseused_&&e.clientX&&e.clientY)return St(t),void(this.player_.tech(!0)&&this.player_.tech(!0).focus());var i=this.player_.getChild("controlBar"),n=i&&i.getChild("playToggle");if(n){function r(){return n.focus()}Tt(t)?t.then(r,function(){}):this.setTimeout(r,1)}else this.player_.tech(!0).focus()},t.handleKeyDown=function(e){this.mouseused_=!1,n.prototype.handleKeyDown.call(this,e)},t.handleMouseDown=function(e){this.mouseused_=!0},e}(wr);Ar.prototype.controlText_="Play Video",xe.registerComponent("BigPlayButton",Ar);var Pr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).controlText(t&&t.controlText||i.localize("Close")),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-close-button "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.trigger({type:"close",bubbles:!1})},t.handleKeyDown=function(e){At.isEventKey(e,"Esc")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):n.prototype.handleKeyDown.call(this,e)},e}(wr);xe.registerComponent("CloseButton",Pr);var Ir=function(n){function e(e,t){var i;return void 0===t&&(t={}),i=n.call(this,e,t)||this,t.replay=void 0===t.replay||t.replay,i.on(e,"play",i.handlePlay),i.on(e,"pause",i.handlePause),t.replay&&i.on(e,"ended",i.handleEnded),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-play-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.player_.paused()?this.player_.play():this.player_.pause()},t.handleSeeked=function(e){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(e):this.handlePlay(e)},t.handlePlay=function(e){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")},t.handlePause=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")},t.handleEnded=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.controlText("Replay"),this.one(this.player_,"seeked",this.handleSeeked)},e}(wr);Ir.prototype.controlText_="Play",xe.registerComponent("PlayToggle",Ir);function Lr(e,t){e=e<0?0:e;var i=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),a=Math.floor(t/60%60),s=Math.floor(t/3600);return!isNaN(e)&&e!==1/0||(r=n=i="-"),(r=0<r||0<s?r+":":"")+(n=((r||10<=a)&&n<10?"0"+n:n)+":")+(i=i<10?"0"+i:i)}var Or=Lr;function xr(e,t){return void 0===t&&(t=e),Or(e,t)}var Dr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).throttledUpdateContent=fe(pe(Me(i),i.updateContent),30),i.on(e,"timeupdate",i.throttledUpdateContent),i}De(e,n);var t=e.prototype;return t.createEl=function(){var e=this.buildCSSClass(),t=n.prototype.createEl.call(this,"div",{className:e+" vjs-time-control vjs-control",innerHTML:'<span class="vjs-control-text" role="presentation">'+this.localize(this.labelText_)+" </span>"});return this.contentEl_=b("span",{className:e+"-display"},{"aria-live":"off",role:"presentation"}),this.updateTextNode_(),t.appendChild(this.contentEl_),t},t.dispose=function(){this.contentEl_=null,this.textNode_=null,n.prototype.dispose.call(this)},t.updateTextNode_=function(){if(this.contentEl_){for(;this.contentEl_.firstChild;)this.contentEl_.removeChild(this.contentEl_.firstChild);this.textNode_=h.createTextNode(this.formattedTime_||this.formatTime_(0)),this.contentEl_.appendChild(this.textNode_)}},t.formatTime_=function(e){return xr(e)},t.updateFormattedTime_=function(e){var t=this.formatTime_(e);t!==this.formattedTime_&&(this.formattedTime_=t,this.requestAnimationFrame(this.updateTextNode_))},t.updateContent=function(e){},e}(xe);Dr.prototype.labelText_="Time",Dr.prototype.controlText_="Time",xe.registerComponent("TimeDisplay",Dr);var Ur=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"ended",i.handleEnded),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-current-time"},t.updateContent=function(e){var t=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();this.updateFormattedTime_(t)},t.handleEnded=function(e){this.player_.duration()&&this.updateFormattedTime_(this.player_.duration())},e}(Dr);Ur.prototype.labelText_="Current Time",Ur.prototype.controlText_="Current Time",xe.registerComponent("CurrentTimeDisplay",Ur);var Rr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"durationchange",i.updateContent),i.on(e,"loadstart",i.updateContent),i.on(e,"loadedmetadata",i.throttledUpdateContent),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-duration"},t.updateContent=function(e){var t=this.player_.duration();this.duration_!==t&&(this.duration_=t,this.updateFormattedTime_(t))},e}(Dr);Rr.prototype.labelText_="Duration",Rr.prototype.controlText_="Duration",xe.registerComponent("DurationDisplay",Rr);var Mr=function(e){function t(){return e.apply(this,arguments)||this}return De(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-time-control vjs-time-divider",innerHTML:"<div><span>/</span></div>"},{"aria-hidden":!0})},t}(xe);xe.registerComponent("TimeDivider",Mr);var Nr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"durationchange",i.throttledUpdateContent),i.on(e,"ended",i.handleEnded),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-remaining-time"},t.createEl=function(){var e=n.prototype.createEl.call(this);return e.insertBefore(b("span",{},{"aria-hidden":!0},"-"),this.contentEl_),e},t.updateContent=function(e){"number"==typeof this.player_.duration()&&(this.player_.remainingTimeDisplay?this.updateFormattedTime_(this.player_.remainingTimeDisplay()):this.updateFormattedTime_(this.player_.remainingTime()))},t.handleEnded=function(e){this.player_.duration()&&this.updateFormattedTime_(0)},e}(Dr);Nr.prototype.labelText_="Remaining Time",Nr.prototype.controlText_="Remaining Time",xe.registerComponent("RemainingTimeDisplay",Nr);var Br=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateShowing(),i.on(i.player(),"durationchange",i.updateShowing),i}De(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-live-control vjs-control"});return this.contentEl_=b("div",{className:"vjs-live-display",innerHTML:'<span class="vjs-control-text">'+this.localize("Stream Type")+" </span>"+this.localize("LIVE")},{"aria-live":"off"}),e.appendChild(this.contentEl_),e},t.dispose=function(){this.contentEl_=null,n.prototype.dispose.call(this)},t.updateShowing=function(e){this.player().duration()===1/0?this.show():this.hide()},e}(xe);xe.registerComponent("LiveDisplay",Br);var jr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateLiveEdgeStatus(),i.player_.liveTracker&&i.on(i.player_.liveTracker,"liveedgechange",i.updateLiveEdgeStatus),i}De(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"button",{className:"vjs-seek-to-live-control vjs-control"});return this.textEl_=b("span",{className:"vjs-seek-to-live-text",innerHTML:this.localize("LIVE")},{"aria-hidden":"true"}),e.appendChild(this.textEl_),e},t.updateLiveEdgeStatus=function(e){!this.player_.liveTracker||this.player_.liveTracker.atLiveEdge()?(this.setAttribute("aria-disabled",!0),this.addClass("vjs-at-live-edge"),this.controlText("Seek to live, currently playing live")):(this.setAttribute("aria-disabled",!1),this.removeClass("vjs-at-live-edge"),this.controlText("Seek to live, currently behind live"))},t.handleClick=function(){this.player_.liveTracker.seekToLiveEdge()},t.dispose=function(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatus),this.textEl_=null,n.prototype.dispose.call(this)},e}(wr);jr.prototype.controlText_="Seek to live, currently playing live",xe.registerComponent("SeekToLive",jr);var Fr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).bar=i.getChild(i.options_.barName),i.vertical(!!i.options_.vertical),i.enable(),i}De(e,n);var t=e.prototype;return t.enabled=function(){return this.enabled_},t.enable=function(){this.enabled()||(this.on("mousedown",this.handleMouseDown),this.on("touchstart",this.handleMouseDown),this.on("keydown",this.handleKeyDown),this.on("click",this.handleClick),this.on(this.player_,"controlsvisible",this.update),this.playerEvent&&this.on(this.player_,this.playerEvent,this.update),this.removeClass("disabled"),this.setAttribute("tabindex",0),this.enabled_=!0)},t.disable=function(){if(this.enabled()){var e=this.bar.el_.ownerDocument;this.off("mousedown",this.handleMouseDown),this.off("touchstart",this.handleMouseDown),this.off("keydown",this.handleKeyDown),this.off("click",this.handleClick),this.off(this.player_,"controlsvisible",this.update),this.off(e,"mousemove",this.handleMouseMove),this.off(e,"mouseup",this.handleMouseUp),this.off(e,"touchmove",this.handleMouseMove),this.off(e,"touchend",this.handleMouseUp),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1}},t.createEl=function(e,t,i){return void 0===t&&(t={}),void 0===i&&(i={}),t.className=t.className+" vjs-slider",t=m({tabIndex:0},t),i=m({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},i),n.prototype.createEl.call(this,e,t,i)},t.handleMouseDown=function(e){var t=this.bar.el_.ownerDocument;"mousedown"===e.type&&e.preventDefault(),"touchstart"!==e.type||et||e.preventDefault(),x(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(t,"mousemove",this.handleMouseMove),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchmove",this.handleMouseMove),this.on(t,"touchend",this.handleMouseUp),this.handleMouseMove(e)},t.handleMouseMove=function(e){},t.handleMouseUp=function(){var e=this.bar.el_.ownerDocument;D(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(e,"mousemove",this.handleMouseMove),this.off(e,"mouseup",this.handleMouseUp),this.off(e,"touchmove",this.handleMouseMove),this.off(e,"touchend",this.handleMouseUp),this.update()},t.update=function(){if(this.el_){var e=this.getPercent(),t=this.bar;if(t){("number"!=typeof e||e!=e||e<0||e===1/0)&&(e=0);var i=(100*e).toFixed(2)+"%",n=t.el().style,r=this.vertical()?"height":"width";return n[r]!==i&&(n[r]=i),e}}},t.calculateDistance=function(e){var t=M(this.el_,e);return this.vertical()?t.y:t.x},t.handleKeyDown=function(e){At.isEventKey(e,"Left")||At.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepBack()):At.isEventKey(e,"Right")||At.isEventKey(e,"Up")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):n.prototype.handleKeyDown.call(this,e)},t.handleClick=function(e){e.stopPropagation(),e.preventDefault()},t.vertical=function(e){if(void 0===e)return this.vertical_||!1;this.vertical_=!!e,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")},e}(xe);xe.registerComponent("Slider",Fr);var Hr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).partEls_=[],i.on(e,"progress",i.update),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text"><span>'+this.localize("Loaded")+'</span>: <span class="vjs-control-text-loaded-percentage">0%</span></span>'})},t.dispose=function(){this.partEls_=null,n.prototype.dispose.call(this)},t.update=function(e){function t(e,t,i){var n=e/t||0;return n=100*(1<=n?1:n),i&&(n=n.toFixed(2)),n+"%"}var i=this.player_.liveTracker,n=this.player_.buffered(),r=i&&i.isLive()?i.seekableEnd():this.player_.duration(),a=this.player_.bufferedEnd(),s=this.partEls_,o=this.$(".vjs-control-text-loaded-percentage");this.el_.style.width=t(a,r),T(o,t(a,r,!0));for(var u=0;u<n.length;u++){var l=n.start(u),c=n.end(u),h=s[u];h||(h=this.el_.appendChild(b()),s[u]=h),h.style.left=t(l,a),h.style.width=t(c-l,a)}for(var d=s.length;d>n.length;d--)this.el_.removeChild(s[d-1]);s.length=n.length},e}(xe);xe.registerComponent("LoadProgressBar",Hr);var Vr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update=fe(pe(Me(i),i.update),30),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})},t.update=function(e,t,i){var n=U(this.el_),r=U(this.player_.el()),a=e.width*t;if(r&&n){var s=e.left-r.left+a,o=e.width-a+(r.right-e.right),u=n.width/2;s<u?u+=u-s:o<u&&(u=o),u<0?u=0:u>n.width&&(u=n.width),this.el_.style.right="-"+u+"px",this.write(i)}},t.write=function(e){T(this.el_,e)},t.updateTime=function(r,a,s,o){var u=this;this.rafId_&&this.cancelAnimationFrame(this.rafId_),this.rafId_=this.requestAnimationFrame(function(){var e,t=u.player_.duration();if(u.player_.liveTracker&&u.player_.liveTracker.isLive()){var i=u.player_.liveTracker.liveWindow(),n=i-a*i;e=(n<1?"":"-")+xr(n,i)}else e=xr(s,t);u.update(r,a,e),o&&o()})},e}(xe);xe.registerComponent("TimeTooltip",Vr);var qr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update=fe(pe(Me(i),i.update),30),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})},t.update=function(e,t){var i=this.getChild("timeTooltip");if(i){var n=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();i.updateTime(e,t,n)}},e}(xe);qr.prototype.options_={children:[]},Ge||Ke||qr.prototype.options_.children.push("timeTooltip"),xe.registerComponent("PlayProgressBar",qr);var Wr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).update=fe(pe(Me(i),i.update),30),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t){var i=this,n=t*this.player_.duration();this.getChild("timeTooltip").updateTime(e,t,n,function(){i.el_.style.left=e.width*t+"px"})},e}(xe);Wr.prototype.options_={children:["timeTooltip"]},xe.registerComponent("MouseTimeDisplay",Wr);var zr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).setEventHandlers_(),i}De(e,n);var t=e.prototype;return t.setEventHandlers_=function(){this.update=fe(pe(this,this.update),30),this.on(this.player_,"timeupdate",this.update),this.on(this.player_,"ended",this.handleEnded),this.on(this.player_,"durationchange",this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.on(this.player_,["playing"],this.enableInterval_),this.on(this.player_,["ended","pause","waiting"],this.disableInterval_),"hidden"in h&&"visibilityState"in h&&this.on(h,"visibilitychange",this.toggleVisibility_)},t.toggleVisibility_=function(e){h.hidden?this.disableInterval_(e):(this.enableInterval_(),this.requestAnimationFrame(this.update))},t.enableInterval_=function(){var e=this;this.clearInterval(this.updateInterval),this.updateInterval=this.setInterval(function(){e.requestAnimationFrame(e.update)},30)},t.disableInterval_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&"ended"!==e.type||this.clearInterval(this.updateInterval)},t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})},t.update_=function(e,t){var i=this.player_.liveTracker,n=this.player_.duration();i&&i.isLive()&&(n=this.player_.liveTracker.liveCurrentTime()),this.el_.setAttribute("aria-valuenow",(100*t).toFixed(2)),this.el_.setAttribute("aria-valuetext",this.localize("progress bar timing: currentTime={1} duration={2}",[xr(e,n),xr(n,n)],"{1} of {2}")),this.bar&&this.bar.update(U(this.el_),t)},t.update=function(e){if(null!==this.el().offsetParent){var t=n.prototype.update.call(this);return this.update_(this.getCurrentTime_(),t),t}},t.getCurrentTime_=function(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()},t.handleEnded=function(e){this.update_(this.player_.duration(),1)},t.getPercent=function(){var e,t=this.getCurrentTime_(),i=this.player_.liveTracker;return i&&i.isLive()?(e=(t-i.seekableStart())/i.liveWindow(),i.atLiveEdge()&&(e=1)):e=t/this.player_.duration(),1<=e?1:e||0},t.handleMouseDown=function(e){V(e)&&(e.stopPropagation(),this.player_.scrubbing(!0),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),n.prototype.handleMouseDown.call(this,e))},t.handleMouseMove=function(e){if(V(e)){var t,i=this.calculateDistance(e),n=this.player_.liveTracker;if(n&&n.isLive()){var r=n.seekableStart(),a=n.liveCurrentTime();if(a<=(t=r+i*n.liveWindow())&&(t=a),t<=r&&(t=r+.1),t===1/0)return}else(t=i*this.player_.duration())===this.player_.duration()&&(t-=.1);this.player_.currentTime(t)}},t.enable=function(){n.prototype.enable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.show()},t.disable=function(){n.prototype.disable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.hide()},t.handleMouseUp=function(e){n.prototype.handleMouseUp.call(this,e),e&&e.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying&&St(this.player_.play())},t.stepForward=function(){this.player_.currentTime(this.player_.currentTime()+5)},t.stepBack=function(){this.player_.currentTime(this.player_.currentTime()-5)},t.handleAction=function(e){this.player_.paused()?this.player_.play():this.player_.pause()},t.handleKeyDown=function(e){if(At.isEventKey(e,"Space")||At.isEventKey(e,"Enter"))e.preventDefault(),e.stopPropagation(),this.handleAction(e);else if(At.isEventKey(e,"Home"))e.preventDefault(),e.stopPropagation(),this.player_.currentTime(0);else if(At.isEventKey(e,"End"))e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.duration());else if(/^[0-9]$/.test(At(e))){e.preventDefault(),e.stopPropagation();var t=10*(At.codes[At(e)]-At.codes[0])/100;this.player_.currentTime(this.player_.duration()*t)}else At.isEventKey(e,"PgDn")?(e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.currentTime()-60)):At.isEventKey(e,"PgUp")?(e.preventDefault(),e.stopPropagation(),this.player_.currentTime(this.player_.currentTime()+60)):n.prototype.handleKeyDown.call(this,e)},e}(Fr);zr.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},Ge||Ke||zr.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),xe.registerComponent("SeekBar",zr);var $r=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).handleMouseMove=fe(pe(Me(i),i.handleMouseMove),30),i.throttledHandleMouseSeek=fe(pe(Me(i),i.handleMouseSeek),30),i.enable(),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-control vjs-control"})},t.handleMouseMove=function(e){var t=this.getChild("seekBar");if(t){var i=t.getChild("mouseTimeDisplay"),n=t.el(),r=U(n),a=M(n,e).x;1<a?a=1:a<0&&(a=0),i&&i.update(r,a)}},t.handleMouseSeek=function(e){var t=this.getChild("seekBar");t&&t.handleMouseMove(e)},t.enabled=function(){return this.enabled_},t.disable=function(){this.children().forEach(function(e){return e.disable&&e.disable()}),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDown),this.off(this.el_,"mousemove",this.handleMouseMove),this.handleMouseUp(),this.addClass("disabled"),this.enabled_=!1)},t.enable=function(){this.children().forEach(function(e){return e.enable&&e.enable()}),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDown),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)},t.handleMouseDown=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseDown(e),this.on(t,"mousemove",this.throttledHandleMouseSeek),this.on(t,"touchmove",this.throttledHandleMouseSeek),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchend",this.handleMouseUp)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseUp(e),this.off(t,"mousemove",this.throttledHandleMouseSeek),this.off(t,"touchmove",this.throttledHandleMouseSeek),this.off(t,"mouseup",this.handleMouseUp),this.off(t,"touchend",this.handleMouseUp)},e}(xe);$r.prototype.options_={children:["seekBar"]},xe.registerComponent("ProgressControl",$r);var Gr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,["enterpictureinpicture","leavepictureinpicture"],i.handlePictureInPictureChange),h.pictureInPictureEnabled||i.disable(),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-picture-in-picture-control "+n.prototype.buildCSSClass.call(this)},t.handlePictureInPictureChange=function(e){this.player_.isInPictureInPicture()?this.controlText("Exit Picture-in-Picture"):this.controlText("Picture-in-Picture")},t.handleClick=function(e){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()},e}(wr);Gr.prototype.controlText_="Picture-in-Picture",xe.registerComponent("PictureInPictureToggle",Gr);var Xr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"fullscreenchange",i.handleFullscreenChange),!1===h[e.fsApi_.fullscreenEnabled]&&i.disable(),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-fullscreen-control "+n.prototype.buildCSSClass.call(this)},t.handleFullscreenChange=function(e){this.player_.isFullscreen()?this.controlText("Non-Fullscreen"):this.controlText("Fullscreen")},t.handleClick=function(e){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()},e}(wr);Xr.prototype.controlText_="Fullscreen",xe.registerComponent("FullscreenToggle",Xr);var Kr=function(e){function t(){return e.apply(this,arguments)||this}return De(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})},t}(xe);xe.registerComponent("VolumeLevel",Kr);var Yr=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on("slideractive",i.updateLastVolume_),i.on(e,"volumechange",i.updateARIAAttributes),e.ready(function(){return i.updateARIAAttributes()}),i}De(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})},t.handleMouseDown=function(e){V(e)&&n.prototype.handleMouseDown.call(this,e)},t.handleMouseMove=function(e){V(e)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(e)))},t.checkMuted=function(){this.player_.muted()&&this.player_.muted(!1)},t.getPercent=function(){return this.player_.muted()?0:this.player_.volume()},t.stepForward=function(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)},t.stepBack=function(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)},t.updateARIAAttributes=function(e){var t=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",t),this.el_.setAttribute("aria-valuetext",t+"%")},t.volumeAsPercentage_=function(){return Math.round(100*this.player_.volume())},t.updateLastVolume_=function(){var e=this,t=this.player_.volume();this.one("sliderinactive",function(){0===e.player_.volume()&&e.player_.lastVolume_(t)})},e}(Fr);Yr.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},Yr.prototype.playerEvent="volumechange",xe.registerComponent("VolumeBar",Yr);var Qr=function(n){function e(e,t){var i;return void 0===t&&(t={}),t.vertical=t.vertical||!1,"undefined"!=typeof t.volumeBar&&!o(t.volumeBar)||(t.volumeBar=t.volumeBar||{},t.volumeBar.vertical=t.vertical),function(e,t){t.tech_&&!t.tech_.featuresVolumeControl&&e.addClass("vjs-hidden"),e.on(t,"loadstart",function(){t.tech_.featuresVolumeControl?e.removeClass("vjs-hidden"):e.addClass("vjs-hidden")})}(Me(i=n.call(this,e,t)||this),e),i.throttledHandleMouseMove=fe(pe(Me(i),i.handleMouseMove),30),i.on("mousedown",i.handleMouseDown),i.on("touchstart",i.handleMouseDown),i.on(i.volumeBar,["focus","slideractive"],function(){i.volumeBar.addClass("vjs-slider-active"),i.addClass("vjs-slider-active"),i.trigger("slideractive")}),i.on(i.volumeBar,["blur","sliderinactive"],function(){i.volumeBar.removeClass("vjs-slider-active"),i.removeClass("vjs-slider-active"),i.trigger("sliderinactive")}),i}De(e,n);var t=e.prototype;return t.createEl=function(){var e="vjs-volume-horizontal";return this.options_.vertical&&(e="vjs-volume-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-control vjs-control "+e})},t.handleMouseDown=function(e){var t=this.el_.ownerDocument;this.on(t,"mousemove",this.throttledHandleMouseMove),this.on(t,"touchmove",this.throttledHandleMouseMove),this.on(t,"mouseup",this.handleMouseUp),this.on(t,"touchend",this.handleMouseUp)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument;this.off(t,"mousemove",this.throttledHandleMouseMove),this.off(t,"touchmove",this.throttledHandleMouseMove),this.off(t,"mouseup",this.handleMouseUp),this.off(t,"touchend",this.handleMouseUp)},t.handleMouseMove=function(e){this.volumeBar.handleMouseMove(e)},e}(xe);Qr.prototype.options_={children:["volumeBar"]},xe.registerComponent("VolumeControl",Qr);var Jr=function(n){function e(e,t){var i;return function(e,t){t.tech_&&!t.tech_.featuresMuteControl&&e.addClass("vjs-hidden"),e.on(t,"loadstart",function(){t.tech_.featuresMuteControl?e.removeClass("vjs-hidden"):e.addClass("vjs-hidden")})}(Me(i=n.call(this,e,t)||this),e),i.on(e,["loadstart","volumechange"],i.update),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-mute-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){var t=this.player_.volume(),i=this.player_.lastVolume_();if(0===t){var n=i<.1?.1:i;this.player_.volume(n),this.player_.muted(!1)}else this.player_.muted(!this.player_.muted())},t.update=function(e){this.updateIcon_(),this.updateControlText_()},t.updateIcon_=function(){var e=this.player_.volume(),t=3;Ge&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===e||this.player_.muted()?t=0:e<.33?t=1:e<.67&&(t=2);for(var i=0;i<4;i++)E(this.el_,"vjs-vol-"+i);C(this.el_,"vjs-vol-"+t)},t.updateControlText_=function(){var e=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==e&&this.controlText(e)},e}(wr);Jr.prototype.controlText_="Mute",xe.registerComponent("MuteToggle",Jr);var Zr=function(n){function e(e,t){var i;return void 0===t&&(t={}),"undefined"!=typeof t.inline?t.inline=t.inline:t.inline=!0,"undefined"!=typeof t.volumeControl&&!o(t.volumeControl)||(t.volumeControl=t.volumeControl||{},t.volumeControl.vertical=!t.inline),(i=n.call(this,e,t)||this).on(e,["loadstart"],i.volumePanelState_),i.on(i.muteToggle,"keyup",i.handleKeyPress),i.on(i.volumeControl,"keyup",i.handleVolumeControlKeyUp),i.on("keydown",i.handleKeyPress),i.on("mouseover",i.handleMouseOver),i.on("mouseout",i.handleMouseOut),i.on(i.volumeControl,["slideractive"],i.sliderActive_),i.on(i.volumeControl,["sliderinactive"],i.sliderInactive_),i}De(e,n);var t=e.prototype;return t.sliderActive_=function(){this.addClass("vjs-slider-active")},t.sliderInactive_=function(){this.removeClass("vjs-slider-active")},t.volumePanelState_=function(){this.volumeControl.hasClass("vjs-hidden")&&this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-hidden"),this.volumeControl.hasClass("vjs-hidden")&&!this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-mute-toggle-only")},t.createEl=function(){var e="vjs-volume-panel-horizontal";return this.options_.inline||(e="vjs-volume-panel-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-panel vjs-control "+e})},t.dispose=function(){this.handleMouseOut(),n.prototype.dispose.call(this)},t.handleVolumeControlKeyUp=function(e){At.isEventKey(e,"Esc")&&this.muteToggle.focus()},t.handleMouseOver=function(e){this.addClass("vjs-hover"),ue(h,"keyup",pe(this,this.handleKeyPress))},t.handleMouseOut=function(e){this.removeClass("vjs-hover"),le(h,"keyup",pe(this,this.handleKeyPress))},t.handleKeyPress=function(e){At.isEventKey(e,"Esc")&&this.handleMouseOut()},e}(xe);Zr.prototype.options_={children:["muteToggle","volumeControl"]},xe.registerComponent("VolumePanel",Zr);var ea=function(n){function e(e,t){var i;return i=n.call(this,e,t)||this,t&&(i.menuButton_=t.menuButton),i.focusedChild_=-1,i.on("keydown",i.handleKeyDown),i.boundHandleBlur_=pe(Me(i),i.handleBlur),i.boundHandleTapClick_=pe(Me(i),i.handleTapClick),i}De(e,n);var t=e.prototype;return t.addEventListenerForItem=function(e){e instanceof xe&&(this.on(e,"blur",this.boundHandleBlur_),this.on(e,["tap","click"],this.boundHandleTapClick_))},t.removeEventListenerForItem=function(e){e instanceof xe&&(this.off(e,"blur",this.boundHandleBlur_),this.off(e,["tap","click"],this.boundHandleTapClick_))},t.removeChild=function(e){"string"==typeof e&&(e=this.getChild(e)),this.removeEventListenerForItem(e),n.prototype.removeChild.call(this,e)},t.addItem=function(e){var t=this.addChild(e);t&&this.addEventListenerForItem(t)},t.createEl=function(){var e=this.options_.contentElType||"ul";this.contentEl_=b(e,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");var t=n.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return t.appendChild(this.contentEl_),ue(t,"click",function(e){e.preventDefault(),e.stopImmediatePropagation()}),t},t.dispose=function(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,n.prototype.dispose.call(this)},t.handleBlur=function(e){var t=e.relatedTarget||h.activeElement;if(!this.children().some(function(e){return e.el()===t})){var i=this.menuButton_;i&&i.buttonPressed_&&t!==i.el().firstChild&&i.unpressButton()}},t.handleTapClick=function(t){if(this.menuButton_){this.menuButton_.unpressButton();var e=this.children();if(!Array.isArray(e))return;var i=e.filter(function(e){return e.el()===t.target})[0];if(!i)return;"CaptionSettingsMenuItem"!==i.name()&&this.menuButton_.focus()}},t.handleKeyDown=function(e){At.isEventKey(e,"Left")||At.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):(At.isEventKey(e,"Right")||At.isEventKey(e,"Up"))&&(e.preventDefault(),e.stopPropagation(),this.stepBack())},t.stepForward=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_+1),this.focus(e)},t.stepBack=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_-1),this.focus(e)},t.focus=function(e){void 0===e&&(e=0);var t=this.children().slice();t.length&&t[0].className&&/vjs-menu-title/.test(t[0].className)&&t.shift(),0<t.length&&(e<0?e=0:e>=t.length&&(e=t.length-1),t[this.focusedChild_=e].el_.focus())},e}(xe);xe.registerComponent("Menu",ea);var ta=function(r){function e(e,t){var i;void 0===t&&(t={}),(i=r.call(this,e,t)||this).menuButton_=new wr(e,t),i.menuButton_.controlText(i.controlText_),i.menuButton_.el_.setAttribute("aria-haspopup","true");var n=wr.prototype.buildCSSClass();return i.menuButton_.el_.className=i.buildCSSClass()+" "+n,i.menuButton_.removeClass("vjs-control"),i.addChild(i.menuButton_),i.update(),i.enabled_=!0,i.on(i.menuButton_,"tap",i.handleClick),i.on(i.menuButton_,"click",i.handleClick),i.on(i.menuButton_,"keydown",i.handleKeyDown),i.on(i.menuButton_,"mouseenter",function(){i.addClass("vjs-hover"),i.menu.show(),ue(h,"keyup",pe(Me(i),i.handleMenuKeyUp))}),i.on("mouseleave",i.handleMouseLeave),i.on("keydown",i.handleSubmenuKeyDown),i}De(e,r);var t=e.prototype;return t.update=function(){var e=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=e,this.addChild(e),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?this.hide():this.show()},t.createMenu=function(){var e=new ea(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title){var t=b("li",{className:"vjs-menu-title",innerHTML:Le(this.options_.title),tabIndex:-1});this.hideThreshold_+=1;var i=new xe(this.player_,{el:t});e.addItem(i)}if(this.items=this.createItems(),this.items)for(var n=0;n<this.items.length;n++)e.addItem(this.items[n]);return e},t.createItems=function(){},t.createEl=function(){return r.prototype.createEl.call(this,"div",{className:this.buildWrapperCSSClass()},{})},t.buildWrapperCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+wr.prototype.buildCSSClass()+" "+r.prototype.buildCSSClass.call(this)},t.buildCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+r.prototype.buildCSSClass.call(this)},t.controlText=function(e,t){return void 0===t&&(t=this.menuButton_.el()),this.menuButton_.controlText(e,t)},t.dispose=function(){this.handleMouseLeave(),r.prototype.dispose.call(this)},t.handleClick=function(e){this.buttonPressed_?this.unpressButton():this.pressButton()},t.handleMouseLeave=function(e){this.removeClass("vjs-hover"),le(h,"keyup",pe(this,this.handleMenuKeyUp))},t.focus=function(){this.menuButton_.focus()},t.blur=function(){this.menuButton_.blur()},t.handleKeyDown=function(e){At.isEventKey(e,"Esc")||At.isEventKey(e,"Tab")?(this.buttonPressed_&&this.unpressButton(),At.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus())):(At.isEventKey(e,"Up")||At.isEventKey(e,"Down"))&&(this.buttonPressed_||(e.preventDefault(),this.pressButton()))},t.handleMenuKeyUp=function(e){(At.isEventKey(e,"Esc")||At.isEventKey(e,"Tab"))&&this.removeClass("vjs-hover")},t.handleSubmenuKeyPress=function(e){this.handleSubmenuKeyDown(e)},t.handleSubmenuKeyDown=function(e){(At.isEventKey(e,"Esc")||At.isEventKey(e,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),At.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus()))},t.pressButton=function(){if(this.enabled_){if(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),Ge&&y())return;this.menu.focus()}},t.unpressButton=function(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))},t.disable=function(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()},t.enable=function(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()},e}(xe);xe.registerComponent("MenuButton",ta);var ia=function(a){function e(e,t){var i,n=t.tracks;if((i=a.call(this,e,t)||this).items.length<=1&&i.hide(),!n)return Me(i);var r=pe(Me(i),i.update);return n.addEventListener("removetrack",r),n.addEventListener("addtrack",r),i.player_.on("ready",r),i.player_.on("dispose",function(){n.removeEventListener("removetrack",r),n.removeEventListener("addtrack",r)}),i}return De(e,a),e}(ta);xe.registerComponent("TrackButton",ia);var na=["Tab","Esc","Up","Down","Right","Left"],ra=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).selectable=t.selectable,i.isSelected_=t.selected||!1,i.multiSelectable=t.multiSelectable,i.selected(i.isSelected_),i.selectable?i.multiSelectable?i.el_.setAttribute("role","menuitemcheckbox"):i.el_.setAttribute("role","menuitemradio"):i.el_.setAttribute("role","menuitem"),i}De(e,n);var t=e.prototype;return t.createEl=function(e,t,i){return this.nonIconControl=!0,n.prototype.createEl.call(this,"li",m({className:"vjs-menu-item",innerHTML:'<span class="vjs-menu-item-text">'+this.localize(this.options_.label)+"</span>",tabIndex:-1},t),i)},t.handleKeyDown=function(t){na.some(function(e){return At.isEventKey(t,e)})||n.prototype.handleKeyDown.call(this,t)},t.handleClick=function(e){this.selected(!0)},t.selected=function(e){this.selectable&&(e?(this.addClass("vjs-selected"),this.el_.setAttribute("aria-checked","true"),this.controlText(", selected"),this.isSelected_=!0):(this.removeClass("vjs-selected"),this.el_.setAttribute("aria-checked","false"),this.controlText(""),this.isSelected_=!1))},e}(vr);xe.registerComponent("MenuItem",ra);var aa=function(u){function e(e,t){var n,i=t.track,r=e.textTracks();t.label=i.label||i.language||"Unknown",t.selected="showing"===i.mode,(n=u.call(this,e,t)||this).track=i,n.kinds=(t.kinds||[t.kind||n.track.kind]).filter(Boolean);function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(Me(n),t)}function s(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleSelectedLanguageChange.apply(Me(n),t)}var o;e.on(["loadstart","texttrackchange"],a),r.addEventListener("change",a),r.addEventListener("selectedlanguagechange",s),n.on("dispose",function(){e.off(["loadstart","texttrackchange"],a),r.removeEventListener("change",a),r.removeEventListener("selectedlanguagechange",s)}),void 0===r.onchange&&n.on(["tap","click"],function(){if("object"!=typeof v.Event)try{o=new v.Event("change")}catch(e){}o||(o=h.createEvent("Event")).initEvent("change",!0,!0),r.dispatchEvent(o)});return n.handleTracksChange(),n}De(e,u);var t=e.prototype;return t.handleClick=function(e){var t=this.track,i=this.player_.textTracks();if(u.prototype.handleClick.call(this,e),i)for(var n=0;n<i.length;n++){var r=i[n];-1!==this.kinds.indexOf(r.kind)&&(r===t?"showing"!==r.mode&&(r.mode="showing"):"disabled"!==r.mode&&(r.mode="disabled"))}},t.handleTracksChange=function(e){var t="showing"===this.track.mode;t!==this.isSelected_&&this.selected(t)},t.handleSelectedLanguageChange=function(e){if("showing"===this.track.mode){var t=this.player_.cache_.selectedLanguage;if(t&&t.enabled&&t.language===this.track.language&&t.kind!==this.track.kind)return;this.player_.cache_.selectedLanguage={enabled:!0,language:this.track.language,kind:this.track.kind}}},t.dispose=function(){this.track=null,u.prototype.dispose.call(this)},e}(ra);xe.registerComponent("TextTrackMenuItem",aa);var sa=function(i){function e(e,t){return t.track={player:e,kind:t.kind,kinds:t.kinds,default:!1,mode:"disabled"},t.kinds||(t.kinds=[t.kind]),t.label?t.track.label=t.label:t.track.label=t.kinds.join(" and ")+" off",t.selectable=!0,t.multiSelectable=!1,i.call(this,e,t)||this}De(e,i);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<this.options_.kinds.indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i!==this.isSelected_&&this.selected(i)},t.handleSelectedLanguageChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<["captions","descriptions","subtitles"].indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i&&(this.player_.cache_.selectedLanguage={enabled:!1})},e}(aa);xe.registerComponent("OffTextTrackMenuItem",sa);var oa=function(i){function e(e,t){return void 0===t&&(t={}),t.tracks=e.textTracks(),i.call(this,e,t)||this}return De(e,i),e.prototype.createItems=function(e,t){var i;void 0===e&&(e=[]),void 0===t&&(t=aa),this.label_&&(i=this.label_+" off"),e.push(new sa(this.player_,{kinds:this.kinds_,kind:this.kind_,label:i})),this.hideThreshold_+=1;var n=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(var r=0;r<n.length;r++){var a=n[r];if(-1<this.kinds_.indexOf(a.kind)){var s=new t(this.player_,{track:a,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1});s.addClass("vjs-"+a.kind+"-menu-item"),e.push(s)}}return e},e}(ia);xe.registerComponent("TextTrackButton",oa);var ua=function(s){function e(e,t){var i,n=t.track,r=t.cue,a=e.currentTime();return t.selectable=!0,t.multiSelectable=!1,t.label=r.text,t.selected=r.startTime<=a&&a<r.endTime,(i=s.call(this,e,t)||this).track=n,i.cue=r,n.addEventListener("cuechange",pe(Me(i),i.update)),i}De(e,s);var t=e.prototype;return t.handleClick=function(e){s.prototype.handleClick.call(this),this.player_.currentTime(this.cue.startTime),this.update(this.cue.startTime)},t.update=function(e){var t=this.cue,i=this.player_.currentTime();this.selected(t.startTime<=i&&i<t.endTime)},e}(ra);xe.registerComponent("ChaptersTrackMenuItem",ua);var la=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildWrapperCSSClass.call(this)},t.update=function(e){this.track_&&(!e||"addtrack"!==e.type&&"removetrack"!==e.type)||this.setTrack(this.findChaptersTrack()),n.prototype.update.call(this)},t.setTrack=function(e){if(this.track_!==e){if(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_){var t=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);t&&t.removeEventListener("load",this.updateHandler_),this.track_=null}if(this.track_=e,this.track_){this.track_.mode="hidden";var i=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);i&&i.addEventListener("load",this.updateHandler_)}}},t.findChaptersTrack=function(){for(var e=this.player_.textTracks()||[],t=e.length-1;0<=t;t--){var i=e[t];if(i.kind===this.kind_)return i}},t.getMenuCaption=function(){return this.track_&&this.track_.label?this.track_.label:this.localize(Le(this.kind_))},t.createMenu=function(){return this.options_.title=this.getMenuCaption(),n.prototype.createMenu.call(this)},t.createItems=function(){var e=[];if(!this.track_)return e;var t=this.track_.cues;if(!t)return e;for(var i=0,n=t.length;i<n;i++){var r=t[i],a=new ua(this.player_,{track:this.track_,cue:r});e.push(a)}return e},e}(oa);la.prototype.kind_="chapters",la.prototype.controlText_="Chapters",xe.registerComponent("ChaptersButton",la);var ca=function(s){function e(e,t,i){var n;n=s.call(this,e,t,i)||this;var r=e.textTracks(),a=pe(Me(n),n.handleTracksChange);return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}De(e,s);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!1,n=0,r=t.length;n<r;n++){var a=t[n];if(a.kind!==this.kind_&&"showing"===a.mode){i=!0;break}}i?this.disable():this.enable()},t.buildCSSClass=function(){return"vjs-descriptions-button "+s.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-descriptions-button "+s.prototype.buildWrapperCSSClass.call(this)},e}(oa);ca.prototype.kind_="descriptions",ca.prototype.controlText_="Descriptions",xe.registerComponent("DescriptionsButton",ca);var ha=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildWrapperCSSClass.call(this)},e}(oa);ha.prototype.kind_="subtitles",ha.prototype.controlText_="Subtitles",xe.registerComponent("SubtitlesButton",ha);var da=function(n){function e(e,t){var i;return t.track={player:e,kind:t.kind,label:t.kind+" settings",selectable:!1,default:!1,mode:"disabled"},t.selectable=!1,t.name="CaptionSettingsMenuItem",(i=n.call(this,e,t)||this).addClass("vjs-texttrack-settings"),i.controlText(", opens "+t.kind+" settings dialog"),i}return De(e,n),e.prototype.handleClick=function(e){this.player().getChild("textTrackSettings").open()},e}(aa);xe.registerComponent("CaptionSettingsMenuItem",da);var pa=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-captions-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-captions-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new da(this.player_,{kind:this.kind_})),this.hideThreshold_+=1),n.prototype.createItems.call(this,e)},e}(oa);pa.prototype.kind_="captions",pa.prototype.controlText_="Captions",xe.registerComponent("CaptionsButton",pa);var fa=function(r){function e(){return r.apply(this,arguments)||this}return De(e,r),e.prototype.createEl=function(e,t,i){var n='<span class="vjs-menu-item-text">'+this.localize(this.options_.label);return"captions"===this.options_.track.kind&&(n+='\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> '+this.localize("Captions")+"</span>\n "),n+="</span>",r.prototype.createEl.call(this,e,m({innerHTML:n},t),i)},e}(aa);xe.registerComponent("SubsCapsMenuItem",fa);var ma=function(n){function e(e,t){var i;return void 0===t&&(t={}),(i=n.call(this,e,t)||this).label_="subtitles",-1<["en","en-us","en-ca","fr-ca"].indexOf(i.player_.language_)&&(i.label_="captions"),i.menuButton_.controlText(Le(i.label_)),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subs-caps-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subs-caps-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new da(this.player_,{kind:this.label_})),this.hideThreshold_+=1),e=n.prototype.createItems.call(this,e,fa)},e}(oa);ma.prototype.kinds_=["captions","subtitles"],ma.prototype.controlText_="Subtitles",xe.registerComponent("SubsCapsButton",ma);var ga=function(s){function e(e,t){var n,i=t.track,r=e.audioTracks();t.label=i.label||i.language||"Unknown",t.selected=i.enabled,(n=s.call(this,e,t)||this).track=i,n.addClass("vjs-"+i.kind+"-menu-item");function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(Me(n),t)}return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}De(e,s);var t=e.prototype;return t.createEl=function(e,t,i){var n='<span class="vjs-menu-item-text">'+this.localize(this.options_.label);return"main-desc"===this.options_.track.kind&&(n+='\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> '+this.localize("Descriptions")+"</span>\n "),n+="</span>",s.prototype.createEl.call(this,e,m({innerHTML:n},t),i)},t.handleClick=function(e){var t=this.player_.audioTracks();s.prototype.handleClick.call(this,e);for(var i=0;i<t.length;i++){var n=t[i];n.enabled=n===this.track}},t.handleTracksChange=function(e){this.selected(this.track.enabled)},e}(ra);xe.registerComponent("AudioTrackMenuItem",ga);var ya=function(i){function e(e,t){return void 0===t&&(t={}),t.tracks=e.audioTracks(),i.call(this,e,t)||this}De(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-audio-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-audio-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(e){void 0===e&&(e=[]),this.hideThreshold_=1;for(var t=this.player_.audioTracks(),i=0;i<t.length;i++){var n=t[i];e.push(new ga(this.player_,{track:n,selectable:!0,multiSelectable:!1}))}return e},e}(ia);ya.prototype.controlText_="Audio Track",xe.registerComponent("AudioTrackButton",ya);var va=function(a){function e(e,t){var i,n=t.rate,r=parseFloat(n,10);return t.label=n,t.selected=1===r,t.selectable=!0,t.multiSelectable=!1,(i=a.call(this,e,t)||this).label=n,i.rate=r,i.on(e,"ratechange",i.update),i}De(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player().playbackRate(this.rate)},t.update=function(e){this.selected(this.player().playbackRate()===this.rate)},e}(ra);va.prototype.contentElType="button",xe.registerComponent("PlaybackRateMenuItem",va);var _a=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).updateVisibility(),i.updateLabel(),i.on(e,"loadstart",i.updateVisibility),i.on(e,"ratechange",i.updateLabel),i}De(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this);return this.labelEl_=b("div",{className:"vjs-playback-rate-value",innerHTML:"1x"}),e.appendChild(this.labelEl_),e},t.dispose=function(){this.labelEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildWrapperCSSClass.call(this)},t.createMenu=function(){var e=new ea(this.player()),t=this.playbackRates();if(t)for(var i=t.length-1;0<=i;i--)e.addChild(new va(this.player(),{rate:t[i]+"x"}));return e},t.updateARIAAttributes=function(){this.el().setAttribute("aria-valuenow",this.player().playbackRate())},t.handleClick=function(e){for(var t=this.player().playbackRate(),i=this.playbackRates(),n=i[0],r=0;r<i.length;r++)if(i[r]>t){n=i[r];break}this.player().playbackRate(n)},t.playbackRates=function(){return this.options_.playbackRates||this.options_.playerOptions&&this.options_.playerOptions.playbackRates},t.playbackRateSupported=function(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&0<this.playbackRates().length},t.updateVisibility=function(e){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")},t.updateLabel=function(e){this.playbackRateSupported()&&(this.labelEl_.innerHTML=this.player().playbackRate()+"x")},e}(ta);_a.prototype.controlText_="Playback Rate",xe.registerComponent("PlaybackRateMenuButton",_a);var ba=function(e){function t(){return e.apply(this,arguments)||this}De(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-spacer "+e.prototype.buildCSSClass.call(this)},i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:this.buildCSSClass()})},t}(xe);xe.registerComponent("Spacer",ba);var Ta=function(t){function e(){return t.apply(this,arguments)||this}De(e,t);var i=e.prototype;return i.buildCSSClass=function(){return"vjs-custom-control-spacer "+t.prototype.buildCSSClass.call(this)},i.createEl=function(){var e=t.prototype.createEl.call(this,{className:this.buildCSSClass()});return e.innerHTML=" ",e},e}(ba);xe.registerComponent("CustomControlSpacer",Ta);var Sa=function(e){function t(){return e.apply(this,arguments)||this}return De(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-control-bar",dir:"ltr"})},t}(xe);Sa.prototype.options_={children:["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","fullscreenToggle"]},"exitPictureInPicture"in h&&Sa.prototype.options_.children.splice(Sa.prototype.options_.children.length-1,0,"pictureInPictureToggle"),xe.registerComponent("ControlBar",Sa);var ka=function(n){function e(e,t){var i;return(i=n.call(this,e,t)||this).on(e,"error",i.open),i}De(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-error-display "+n.prototype.buildCSSClass.call(this)},t.content=function(){var e=this.player().error();return e?this.localize(e.message):""},e}(It);ka.prototype.options_=Oe(It.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),xe.registerComponent("ErrorDisplay",ka);var Ca="vjs-text-track-settings",Ea=["#000","Black"],wa=["#00F","Blue"],Aa=["#0FF","Cyan"],Pa=["#0F0","Green"],Ia=["#F0F","Magenta"],La=["#F00","Red"],Oa=["#FFF","White"],xa=["#FF0","Yellow"],Da=["1","Opaque"],Ua=["0.5","Semi-Transparent"],Ra=["0","Transparent"],Ma={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[Ea,Oa,La,Pa,wa,xa,Ia,Aa]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Transparency",options:[Da,Ua,Ra]},color:{selector:".vjs-fg-color > select",id:"captions-foreground-color-%s",label:"Color",options:[Oa,Ea,La,Pa,wa,xa,Ia,Aa]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Dropshadow"]]},fontFamily:{selector:".vjs-font-family > select",id:"captions-font-family-%s",label:"Font Family",options:[["proportionalSansSerif","Proportional Sans-Serif"],["monospaceSansSerif","Monospace Sans-Serif"],["proportionalSerif","Proportional Serif"],["monospaceSerif","Monospace Serif"],["casual","Casual"],["script","Script"],["small-caps","Small Caps"]]},fontPercent:{selector:".vjs-font-percent > select",id:"captions-font-size-%s",label:"Font Size",options:[["0.50","50%"],["0.75","75%"],["1.00","100%"],["1.25","125%"],["1.50","150%"],["1.75","175%"],["2.00","200%"],["3.00","300%"],["4.00","400%"]],default:2,parser:function(e){return"1.00"===e?null:Number(e)}},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Transparency",options:[Da,Ua]},windowColor:{selector:".vjs-window-color > select",id:"captions-window-color-%s",label:"Color"},windowOpacity:{selector:".vjs-window-opacity > select",id:"captions-window-opacity-%s",label:"Transparency",options:[Ra,Ua,Da]}};function Na(e,t){if(t&&(e=t(e)),e&&"none"!==e)return e}Ma.windowColor.options=Ma.backgroundColor.options;var Ba=function(n){function e(e,t){var i;return t.temporary=!1,(i=n.call(this,e,t)||this).updateDisplay=pe(Me(i),i.updateDisplay),i.fill(),i.hasBeenOpened_=i.hasBeenFilled_=!0,i.endDialog=b("p",{className:"vjs-control-text",textContent:i.localize("End of dialog window.")}),i.el().appendChild(i.endDialog),i.setDefaults(),void 0===t.persistTextTrackSettings&&(i.options_.persistTextTrackSettings=i.options_.playerOptions.persistTextTrackSettings),i.on(i.$(".vjs-done-button"),"click",function(){i.saveSettings(),i.close()}),i.on(i.$(".vjs-default-button"),"click",function(){i.setDefaults(),i.updateDisplay()}),r(Ma,function(e){i.on(i.$(e.selector),"change",i.updateDisplay)}),i.options_.persistTextTrackSettings&&i.restoreSettings(),i}De(e,n);var t=e.prototype;return t.dispose=function(){this.endDialog=null,n.prototype.dispose.call(this)},t.createElSelect_=function(e,t,i){var n=this;void 0===t&&(t=""),void 0===i&&(i="label");var r=Ma[e],a=r.id.replace("%s",this.id_),s=[t,a].join(" ").trim();return["<"+i+' id="'+a+'" class="'+("label"===i?"vjs-label":"")+'">',this.localize(r.label),"</"+i+">",'<select aria-labelledby="'+s+'">'].concat(r.options.map(function(e){var t=a+"-"+e[1].replace(/\W+/g,"");return['<option id="'+t+'" value="'+e[0]+'" ','aria-labelledby="'+s+" "+t+'">',n.localize(e[1]),"</option>"].join("")})).concat("</select>").join("")},t.createElFgColor_=function(){var e="captions-text-legend-"+this.id_;return['<fieldset class="vjs-fg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Text"),"</legend>",this.createElSelect_("color",e),'<span class="vjs-text-opacity vjs-opacity">',this.createElSelect_("textOpacity",e),"</span>","</fieldset>"].join("")},t.createElBgColor_=function(){var e="captions-background-"+this.id_;return['<fieldset class="vjs-bg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Background"),"</legend>",this.createElSelect_("backgroundColor",e),'<span class="vjs-bg-opacity vjs-opacity">',this.createElSelect_("backgroundOpacity",e),"</span>","</fieldset>"].join("")},t.createElWinColor_=function(){var e="captions-window-"+this.id_;return['<fieldset class="vjs-window-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Window"),"</legend>",this.createElSelect_("windowColor",e),'<span class="vjs-window-opacity vjs-opacity">',this.createElSelect_("windowOpacity",e),"</span>","</fieldset>"].join("")},t.createElColors_=function(){return b("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})},t.createElFont_=function(){return b("div",{className:"vjs-track-settings-font",innerHTML:['<fieldset class="vjs-font-percent vjs-track-setting">',this.createElSelect_("fontPercent","","legend"),"</fieldset>",'<fieldset class="vjs-edge-style vjs-track-setting">',this.createElSelect_("edgeStyle","","legend"),"</fieldset>",'<fieldset class="vjs-font-family vjs-track-setting">',this.createElSelect_("fontFamily","","legend"),"</fieldset>"].join("")})},t.createElControls_=function(){var e=this.localize("restore all settings to the default values");return b("div",{className:"vjs-track-settings-controls",innerHTML:['<button type="button" class="vjs-default-button" title="'+e+'">',this.localize("Reset"),'<span class="vjs-control-text"> '+e+"</span>","</button>",'<button type="button" class="vjs-done-button">'+this.localize("Done")+"</button>"].join("")})},t.content=function(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]},t.label=function(){return this.localize("Caption Settings Dialog")},t.description=function(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")},t.buildCSSClass=function(){return n.prototype.buildCSSClass.call(this)+" vjs-text-track-settings"},t.getValues=function(){var r=this;return function(i,n,e){return void 0===e&&(e=0),a(i).reduce(function(e,t){return n(e,i[t],t)},e)}(Ma,function(e,t,i){var n=function(e,t){return Na(e.options[e.options.selectedIndex].value,t)}(r.$(t.selector),t.parser);return void 0!==n&&(e[i]=n),e},{})},t.setValues=function(i){var n=this;r(Ma,function(e,t){!function(e,t,i){if(t)for(var n=0;n<e.options.length;n++)if(Na(e.options[n].value,i)===t){e.selectedIndex=n;break}}(n.$(e.selector),i[t],e.parser)})},t.setDefaults=function(){var i=this;r(Ma,function(e){var t=e.hasOwnProperty("default")?e.default:0;i.$(e.selector).selectedIndex=t})},t.restoreSettings=function(){var e;try{e=JSON.parse(v.localStorage.getItem(Ca))}catch(e){p.warn(e)}e&&this.setValues(e)},t.saveSettings=function(){if(this.options_.persistTextTrackSettings){var e=this.getValues();try{Object.keys(e).length?v.localStorage.setItem(Ca,JSON.stringify(e)):v.localStorage.removeItem(Ca)}catch(e){p.warn(e)}}},t.updateDisplay=function(){var e=this.player_.getChild("textTrackDisplay");e&&e.updateDisplay()},t.conditionalBlur_=function(){this.previouslyActiveEl_=null;var e=this.player_.controlBar,t=e&&e.subsCapsButton,i=e&&e.captionsButton;t?t.focus():i&&i.focus()},e}(It);xe.registerComponent("TextTrackSettings",Ba);var ja=function(a){function e(e,t){var i,n=t.ResizeObserver||v.ResizeObserver;null===t.ResizeObserver&&(n=!1);var r=Oe({createEl:!n,reportTouchActivity:!1},t);return(i=a.call(this,e,r)||this).ResizeObserver=t.ResizeObserver||v.ResizeObserver,i.loadListener_=null,i.resizeObserver_=null,i.debouncedHandler_=function(n,r,a,s){var o;void 0===s&&(s=v);function e(){var e=this,t=arguments,i=function(){i=o=null,a||n.apply(e,t)};!o&&a&&n.apply(e,t),s.clearTimeout(o),o=s.setTimeout(i,r)}return e.cancel=function(){s.clearTimeout(o),o=null},e}(function(){i.resizeHandler()},100,!1,Me(i)),n?(i.resizeObserver_=new i.ResizeObserver(i.debouncedHandler_),i.resizeObserver_.observe(e.el())):(i.loadListener_=function(){if(i.el_&&i.el_.contentWindow){var e=i.debouncedHandler_,t=i.unloadListener_=function(){le(this,"resize",e),le(this,"unload",t),t=null};ue(i.el_.contentWindow,"unload",t),ue(i.el_.contentWindow,"resize",e)}},i.one("load",i.loadListener_)),i}De(e,a);var t=e.prototype;return t.createEl=function(){return a.prototype.createEl.call(this,"iframe",{className:"vjs-resize-manager",tabIndex:-1},{"aria-hidden":"true"})},t.resizeHandler=function(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")},t.dispose=function(){this.debouncedHandler_&&this.debouncedHandler_.cancel(),this.resizeObserver_&&(this.player_.el()&&this.resizeObserver_.unobserve(this.player_.el()),this.resizeObserver_.disconnect()),this.loadListener_&&this.off("load",this.loadListener_),this.el_&&this.el_.contentWindow&&this.unloadListener_&&this.unloadListener_.call(this.el_.contentWindow),this.ResizeObserver=null,this.resizeObserver=null,this.debouncedHandler_=null,this.loadListener_=null,a.prototype.dispose.call(this)},e}(xe);xe.registerComponent("ResizeManager",ja);var Fa=function(r){function e(e,t){var i,n=Oe({createEl:!1},t);return(i=r.call(this,e,n)||this).reset_(),i.on(i.player_,"durationchange",i.handleDurationchange),it&&"hidden"in h&&"visibilityState"in h&&i.on(h,"visibilitychange",i.handleVisibilityChange),i}De(e,r);var t=e.prototype;return t.handleVisibilityChange=function(){this.player_.duration()===1/0&&(h.hidden?this.stopTracking():this.startTracking())},t.isBehind_=function(){if(!this.timeupdateSeen_)return!1;var e=this.liveCurrentTime(),t=this.player_.currentTime(),i=2*this.seekableIncrement_+.07;return e!==1/0&&t<=e-i},t.trackLive_=function(){this.pastSeekEnd_=this.pastSeekEnd_;var e=this.player_.seekable();if(e&&e.length){var t=this.seekableEnd();t!==this.lastSeekEnd_&&(this.lastSeekEnd_&&(this.seekableIncrementList_=this.seekableIncrementList_.slice(-11),this.seekableIncrementList_.push(Math.abs(t-this.lastSeekEnd_)),3<this.seekableIncrementList_.length&&(this.seekableIncrement_=function(e){var t=Math.floor(e.length/2),i=[].concat(e).sort(function(e,t){return e-t});return e.length%2!=0?i[t]:(i[t-1]+i[t])/2}(this.seekableIncrementList_))),this.pastSeekEnd_=0,this.lastSeekEnd_=t,this.trigger("seekableendchange")),this.pastSeekEnd_=this.pastSeekEnd()+.03,this.isBehind_()!==this.behindLiveEdge()&&(this.behindLiveEdge_=this.isBehind_(),this.trigger("liveedgechange"))}},t.handleDurationchange=function(){this.player_.duration()===1/0?this.startTracking():this.stopTracking()},t.startTracking=function(){var e=this;this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLive_,30),this.trackLive_(),this.on(this.player_,"play",this.trackLive_),this.on(this.player_,"pause",this.trackLive_),this.timeupdateSeen_||(this.one(this.player_,"play",this.handlePlay),this.handleTimeupdate=function(){e.timeupdateSeen_=!0,e.handleTimeupdate=null},this.one(this.player_,"timeupdate",this.handleTimeupdate)))},t.handlePlay=function(){this.one(this.player_,"timeupdate",this.seekToLiveEdge)},t.reset_=function(){this.pastSeekEnd_=0,this.lastSeekEnd_=null,this.behindLiveEdge_=null,this.timeupdateSeen_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.seekableIncrement_=12,this.seekableIncrementList_=[],this.off(this.player_,"play",this.trackLive_),this.off(this.player_,"pause",this.trackLive_),this.off(this.player_,"play",this.handlePlay),this.off(this.player_,"timeupdate",this.seekToLiveEdge),this.handleTimeupdate&&(this.off(this.player_,"timeupdate",this.handleTimeupdate),this.handleTimeupdate=null)},t.stopTracking=function(){this.isTracking()&&this.reset_()},t.seekableEnd=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.end(i));return t.length?t.sort()[t.length-1]:1/0},t.seekableStart=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.start(i));return t.length?t.sort()[0]:0},t.liveWindow=function(){var e=this.liveCurrentTime();return e===1/0?1/0:e-this.seekableStart()},t.isLive=function(){return this.isTracking()},t.atLiveEdge=function(){return!this.behindLiveEdge()},t.liveCurrentTime=function(){return this.pastSeekEnd()+this.seekableEnd()},t.pastSeekEnd=function(){return this.pastSeekEnd_},t.behindLiveEdge=function(){return this.behindLiveEdge_},t.isTracking=function(){return"number"==typeof this.trackingInterval_},t.seekToLiveEdge=function(){this.atLiveEdge()||(this.player_.currentTime(this.liveCurrentTime()),this.player_.paused()&&this.player_.play())},t.dispose=function(){this.stopTracking(),r.prototype.dispose.call(this)},e}(xe);xe.registerComponent("LiveTracker",Fa);function Ha(e){var t=e.el();if(t.hasAttribute("src"))return e.triggerSourceset(t.src),!0;var i=e.$$("source"),n=[],r="";if(!i.length)return!1;for(var a=0;a<i.length;a++){var s=i[a].src;s&&-1===n.indexOf(s)&&n.push(s)}return!!n.length&&(1===n.length&&(r=n[0]),e.triggerSourceset(r),!0)}function Va(e,t){for(var i={},n=0;n<e.length&&!((i=Object.getOwnPropertyDescriptor(e[n],t))&&i.set&&i.get);n++);return i.enumerable=!0,i.configurable=!0,i}function qa(a){var s=a.el();if(!s.resetSourceWatch_){function t(r){return function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=r.apply(s,t);return Ha(a),n}}var i={},e=function(e){return Va([e.el(),v.HTMLMediaElement.prototype,v.Element.prototype,za],"innerHTML")}(a);["append","appendChild","insertAdjacentHTML"].forEach(function(e){s[e]&&(i[e]=s[e],s[e]=t(i[e]))}),Object.defineProperty(s,"innerHTML",Oe(e,{set:t(e.set)})),s.resetSourceWatch_=function(){s.resetSourceWatch_=null,Object.keys(i).forEach(function(e){s[e]=i[e]}),Object.defineProperty(s,"innerHTML",e)},a.one("sourceset",s.resetSourceWatch_)}}function Wa(n){if(n.featuresSourceset){var r=n.el();if(!r.resetSourceset_){var i=function(e){return Va([e.el(),v.HTMLMediaElement.prototype,$a],"src")}(n),a=r.setAttribute,t=r.load;Object.defineProperty(r,"src",Oe(i,{set:function(e){var t=i.set.call(r,e);return n.triggerSourceset(r.src),t}})),r.setAttribute=function(e,t){var i=a.call(r,e,t);return/src/i.test(e)&&n.triggerSourceset(r.src),i},r.load=function(){var e=t.call(r);return Ha(n)||(n.triggerSourceset(""),qa(n)),e},r.currentSrc?n.triggerSourceset(r.currentSrc):Ha(n)||qa(n),r.resetSourceset_=function(){r.resetSourceset_=null,r.load=t,r.setAttribute=a,Object.defineProperty(r,"src",i),r.resetSourceWatch_&&r.resetSourceWatch_()}}}}var za=Object.defineProperty({},"innerHTML",{get:function(){return this.cloneNode(!0).innerHTML},set:function(e){var t=h.createElement(this.nodeName.toLowerCase());t.innerHTML=e;for(var i=h.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return this.innerText="",v.Element.prototype.appendChild.call(this,i),this.innerHTML}}),$a=Object.defineProperty({},"src",{get:function(){return this.hasAttribute("src")?Rt(v.Element.prototype.getAttribute.call(this,"src")):""},set:function(e){return v.Element.prototype.setAttribute.call(this,"src",e),e}}),Ga=function(c){function o(e,t){var i;i=c.call(this,e,t)||this;var n=e.source,r=!1;if(n&&(i.el_.currentSrc!==n.src||e.tag&&3===e.tag.initNetworkState_)?i.setSource(n):i.handleLateInit_(i.el_),e.enableSourceset&&i.setupSourcesetHandling_(),i.el_.hasChildNodes()){for(var a=i.el_.childNodes,s=a.length,o=[];s--;){var u=a[s];"track"===u.nodeName.toLowerCase()&&(i.featuresNativeTextTracks?(i.remoteTextTrackEls().addTrackElement_(u),i.remoteTextTracks().addTrack(u.track),i.textTracks().addTrack(u.track),r||i.el_.hasAttribute("crossorigin")||!Nt(u.src)||(r=!0)):o.push(u))}for(var l=0;l<o.length;l++)i.el_.removeChild(o[l])}return i.proxyNativeTracks_(),i.featuresNativeTextTracks&&r&&p.warn("Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\nThis may prevent text tracks from loading."),i.restoreMetadataTracksInIOSNativePlayer_(),(st||ze||Qe)&&!0===e.nativeControlsForTouch&&i.setControls(!0),i.proxyWebkitFullscreen_(),i.triggerReady(),i}De(o,c);var e=o.prototype;return e.dispose=function(){this.el_&&this.el_.resetSourceset_&&this.el_.resetSourceset_(),o.disposeMediaElement(this.el_),this.options_=null,c.prototype.dispose.call(this)},e.setupSourcesetHandling_=function(){Wa(this)},e.restoreMetadataTracksInIOSNativePlayer_=function(){function e(){i=[];for(var e=0;e<n.length;e++){var t=n[e];"metadata"===t.kind&&i.push({track:t,storedMode:t.mode})}}var i,n=this.textTracks();e(),n.addEventListener("change",e),this.on("dispose",function(){return n.removeEventListener("change",e)});function r(){for(var e=0;e<i.length;e++){var t=i[e];"disabled"===t.track.mode&&t.track.mode!==t.storedMode&&(t.track.mode=t.storedMode)}n.removeEventListener("change",r)}this.on("webkitbeginfullscreen",function(){n.removeEventListener("change",e),n.removeEventListener("change",r),n.addEventListener("change",r)}),this.on("webkitendfullscreen",function(){n.removeEventListener("change",e),n.addEventListener("change",e),n.removeEventListener("change",r)})},e.overrideNative_=function(e,t){var i=this;if(t===this["featuresNative"+e+"Tracks"]){var n=e.toLowerCase();this[n+"TracksListeners_"]&&Object.keys(this[n+"TracksListeners_"]).forEach(function(e){i.el()[n+"Tracks"].removeEventListener(e,i[n+"TracksListeners_"][e])}),this["featuresNative"+e+"Tracks"]=!t,this[n+"TracksListeners_"]=null,this.proxyNativeTracksForType_(n)}},e.overrideNativeAudioTracks=function(e){this.overrideNative_("Audio",e)},e.overrideNativeVideoTracks=function(e){this.overrideNative_("Video",e)},e.proxyNativeTracksForType_=function(e){var n=this,t=En[e],r=this.el()[t.getterName],a=this[t.getterName]();if(this["featuresNative"+t.capitalName+"Tracks"]&&r&&r.addEventListener){function i(){for(var e=[],t=0;t<a.length;t++){for(var i=!1,n=0;n<r.length;n++)if(r[n]===a[t]){i=!0;break}i||e.push(a[t])}for(;e.length;)a.removeTrack(e.shift())}var s={change:function(e){a.trigger({type:"change",target:a,currentTarget:a,srcElement:a})},addtrack:function(e){a.addTrack(e.track)},removetrack:function(e){a.removeTrack(e.track)}};this[t.getterName+"Listeners_"]=s,Object.keys(s).forEach(function(t){var i=s[t];r.addEventListener(t,i),n.on("dispose",function(e){return r.removeEventListener(t,i)})}),this.on("loadstart",i),this.on("dispose",function(e){return n.off("loadstart",i)})}},e.proxyNativeTracks_=function(){var t=this;En.names.forEach(function(e){t.proxyNativeTracksForType_(e)})},e.createEl=function(){var e=this.options_.tag;if(!e||!this.options_.playerElIngest&&!this.movingMediaElementInDOM){if(e){var t=e.cloneNode(!0);e.parentNode&&e.parentNode.insertBefore(t,e),o.disposeMediaElement(e),e=t}else{e=h.createElement("video");var i=Oe({},this.options_.tag&&P(this.options_.tag));st&&!0===this.options_.nativeControlsForTouch||delete i.controls,A(e,m(i,{id:this.options_.techId,class:"vjs-tech"}))}e.playerId=this.options_.playerId}"undefined"!=typeof this.options_.preload&&L(e,"preload",this.options_.preload);for(var n=["loop","muted","playsinline","autoplay"],r=0;r<n.length;r++){var a=n[r],s=this.options_[a];"undefined"!=typeof s&&(s?L(e,a,a):O(e,a),e[a]=s)}return e},e.handleLateInit_=function(e){if(0!==e.networkState&&3!==e.networkState){if(0===e.readyState){function t(){i=!0}var i=!1;this.on("loadstart",t);function n(){i||this.trigger("loadstart")}return this.on("loadedmetadata",n),void this.ready(function(){this.off("loadstart",t),this.off("loadedmetadata",n),i||this.trigger("loadstart")})}var r=["loadstart"];r.push("loadedmetadata"),2<=e.readyState&&r.push("loadeddata"),3<=e.readyState&&r.push("canplay"),4<=e.readyState&&r.push("canplaythrough"),this.ready(function(){r.forEach(function(e){this.trigger(e)},this)})}},e.setCurrentTime=function(e){try{this.el_.currentTime=e}catch(e){p(e,"Video is not ready. (Video.js)")}},e.duration=function(){var t=this;if(this.el_.duration===1/0&&Ke&&et&&0===this.el_.currentTime){return this.on("timeupdate",function e(){0<t.el_.currentTime&&(t.el_.duration===1/0&&t.trigger("durationchange"),t.off("timeupdate",e))}),NaN}return this.el_.duration||NaN},e.width=function(){return this.el_.offsetWidth},e.height=function(){return this.el_.offsetHeight},e.proxyWebkitFullscreen_=function(){var e=this;if("webkitDisplayingFullscreen"in this.el_){function t(){this.trigger("fullscreenchange",{isFullscreen:!1})}function i(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",t),this.trigger("fullscreenchange",{isFullscreen:!0}))}this.on("webkitbeginfullscreen",i),this.on("dispose",function(){e.off("webkitbeginfullscreen",i),e.off("webkitendfullscreen",t)})}},e.supportsFullScreen=function(){if("function"==typeof this.el_.webkitEnterFullScreen){var e=v.navigator&&v.navigator.userAgent||"";if(/Android/.test(e)||!/Chrome|Mac OS X 10.5/.test(e))return!0}return!1},e.enterFullScreen=function(){var e=this.el_;e.paused&&e.networkState<=e.HAVE_METADATA?(this.el_.play(),this.setTimeout(function(){e.pause(),e.webkitEnterFullScreen()},0)):e.webkitEnterFullScreen()},e.exitFullScreen=function(){this.el_.webkitExitFullScreen()},e.requestPictureInPicture=function(){return this.el_.requestPictureInPicture()},e.src=function(e){if(void 0===e)return this.el_.src;this.setSrc(e)},e.reset=function(){o.resetMediaElement(this.el_)},e.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc},e.setControls=function(e){this.el_.controls=!!e},e.addTextTrack=function(e,t,i){return this.featuresNativeTextTracks?this.el_.addTextTrack(e,t,i):c.prototype.addTextTrack.call(this,e,t,i)},e.createRemoteTextTrack=function(e){if(!this.featuresNativeTextTracks)return c.prototype.createRemoteTextTrack.call(this,e);var t=h.createElement("track");return e.kind&&(t.kind=e.kind),e.label&&(t.label=e.label),(e.language||e.srclang)&&(t.srclang=e.language||e.srclang),e.default&&(t.default=e.default),e.id&&(t.id=e.id),e.src&&(t.src=e.src),t},e.addRemoteTextTrack=function(e,t){var i=c.prototype.addRemoteTextTrack.call(this,e,t);return this.featuresNativeTextTracks&&this.el().appendChild(i),i},e.removeRemoteTextTrack=function(e){if(c.prototype.removeRemoteTextTrack.call(this,e),this.featuresNativeTextTracks)for(var t=this.$$("track"),i=t.length;i--;)e!==t[i]&&e!==t[i].track||this.el().removeChild(t[i])},e.getVideoPlaybackQuality=function(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();var e={};return"undefined"!=typeof this.el().webkitDroppedFrameCount&&"undefined"!=typeof this.el().webkitDecodedFrameCount&&(e.droppedVideoFrames=this.el().webkitDroppedFrameCount,e.totalVideoFrames=this.el().webkitDecodedFrameCount),v.performance&&"function"==typeof v.performance.now?e.creationTime=v.performance.now():v.performance&&v.performance.timing&&"number"==typeof v.performance.timing.navigationStart&&(e.creationTime=v.Date.now()-v.performance.timing.navigationStart),e},o}(nr);if(c()){Ga.TEST_VID=h.createElement("video");var Xa=h.createElement("track");Xa.kind="captions",Xa.srclang="en",Xa.label="English",Ga.TEST_VID.appendChild(Xa)}Ga.isSupported=function(){try{Ga.TEST_VID.volume=.5}catch(e){return!1}return!(!Ga.TEST_VID||!Ga.TEST_VID.canPlayType)},Ga.canPlayType=function(e){return Ga.TEST_VID.canPlayType(e)},Ga.canPlaySource=function(e,t){return Ga.canPlayType(e.type)},Ga.canControlVolume=function(){try{var e=Ga.TEST_VID.volume;return Ga.TEST_VID.volume=e/2+.1,e!==Ga.TEST_VID.volume}catch(e){return!1}},Ga.canMuteVolume=function(){try{var e=Ga.TEST_VID.muted;return Ga.TEST_VID.muted=!e,Ga.TEST_VID.muted?L(Ga.TEST_VID,"muted","muted"):O(Ga.TEST_VID,"muted"),e!==Ga.TEST_VID.muted}catch(e){return!1}},Ga.canControlPlaybackRate=function(){if(Ke&&et&&tt<58)return!1;try{var e=Ga.TEST_VID.playbackRate;return Ga.TEST_VID.playbackRate=e/2+.1,e!==Ga.TEST_VID.playbackRate}catch(e){return!1}},Ga.canOverrideAttributes=function(){try{function e(){}Object.defineProperty(h.createElement("video"),"src",{get:e,set:e}),Object.defineProperty(h.createElement("audio"),"src",{get:e,set:e}),Object.defineProperty(h.createElement("video"),"innerHTML",{get:e,set:e}),Object.defineProperty(h.createElement("audio"),"innerHTML",{get:e,set:e})}catch(e){return!1}return!0},Ga.supportsNativeTextTracks=function(){return rt||Ge&&et},Ga.supportsNativeVideoTracks=function(){return!(!Ga.TEST_VID||!Ga.TEST_VID.videoTracks)},Ga.supportsNativeAudioTracks=function(){return!(!Ga.TEST_VID||!Ga.TEST_VID.audioTracks)},Ga.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],Ga.prototype.featuresVolumeControl=Ga.canControlVolume(),Ga.prototype.featuresMuteControl=Ga.canMuteVolume(),Ga.prototype.featuresPlaybackRate=Ga.canControlPlaybackRate(),Ga.prototype.featuresSourceset=Ga.canOverrideAttributes(),Ga.prototype.movingMediaElementInDOM=!Ge,Ga.prototype.featuresFullscreenResize=!0,Ga.prototype.featuresProgressEvents=!0,Ga.prototype.featuresTimeupdateEvents=!0,Ga.prototype.featuresNativeTextTracks=Ga.supportsNativeTextTracks(),Ga.prototype.featuresNativeVideoTracks=Ga.supportsNativeVideoTracks(),Ga.prototype.featuresNativeAudioTracks=Ga.supportsNativeAudioTracks();var Ka=Ga.TEST_VID&&Ga.TEST_VID.constructor.prototype.canPlayType,Ya=/^application\/(?:x-|vnd\.apple\.)mpegurl/i;Ga.patchCanPlayType=function(){4<=Ye&&!Je&&!et&&(Ga.TEST_VID.constructor.prototype.canPlayType=function(e){return e&&Ya.test(e)?"maybe":Ka.call(this,e)})},Ga.unpatchCanPlayType=function(){var e=Ga.TEST_VID.constructor.prototype.canPlayType;return Ga.TEST_VID.constructor.prototype.canPlayType=Ka,e},Ga.patchCanPlayType(),Ga.disposeMediaElement=function(e){if(e){for(e.parentNode&&e.parentNode.removeChild(e);e.hasChildNodes();)e.removeChild(e.firstChild);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},Ga.resetMediaElement=function(e){if(e){for(var t=e.querySelectorAll("source"),i=t.length;i--;)e.removeChild(t[i]);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach(function(e){Ga.prototype[e]=function(){return this.el_[e]||this.el_.hasAttribute(e)}}),["muted","defaultMuted","autoplay","loop","playsinline"].forEach(function(t){Ga.prototype["set"+Le(t)]=function(e){(this.el_[t]=e)?this.el_.setAttribute(t,t):this.el_.removeAttribute(t)}}),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","played","networkState","readyState","videoWidth","videoHeight"].forEach(function(e){Ga.prototype[e]=function(){return this.el_[e]}}),["volume","src","poster","preload","playbackRate","defaultPlaybackRate"].forEach(function(t){Ga.prototype["set"+Le(t)]=function(e){this.el_[t]=e}}),["pause","load","play"].forEach(function(e){Ga.prototype[e]=function(){return this.el_[e]()}}),nr.withSourceHandlers(Ga),Ga.nativeSourceHandler={},Ga.nativeSourceHandler.canPlayType=function(e){try{return Ga.TEST_VID.canPlayType(e)}catch(e){return""}},Ga.nativeSourceHandler.canHandleSource=function(e,t){if(e.type)return Ga.nativeSourceHandler.canPlayType(e.type);if(e.src){var i=Mt(e.src);return Ga.nativeSourceHandler.canPlayType("video/"+i)}return""},Ga.nativeSourceHandler.handleSource=function(e,t,i){t.setSrc(e.src)},Ga.nativeSourceHandler.dispose=function(){},Ga.registerSourceHandler(Ga.nativeSourceHandler),nr.registerTech("Html5",Ga);var Qa=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],Ja={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},Za=["tiny","xsmall","small","medium","large","xlarge","huge"],es={};Za.forEach(function(e){var t="x"===e.charAt(0)?"x-"+e.substring(1):e;es[e]="vjs-layout-"+t});var ts={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0},is=function(c){function l(e,t,i){var n;if(e.id=e.id||t.id||"vjs_video_"+te(),(t=m(l.getTagSettings(e),t)).initChildren=!1,t.createEl=!1,t.evented=!1,t.reportTouchActivity=!1,!t.language)if("function"==typeof e.closest){var r=e.closest("[lang]");r&&r.getAttribute&&(t.language=r.getAttribute("lang"))}else for(var a=e;a&&1===a.nodeType;){if(P(a).hasOwnProperty("lang")){t.language=a.getAttribute("lang");break}a=a.parentNode}if((n=c.call(this,null,t,i)||this).boundDocumentFullscreenChange_=pe(Me(n),n.documentFullscreenChange_),n.boundFullWindowOnEscKey_=pe(Me(n),n.fullWindowOnEscKey),n.log=f(n.id_),n.fsApi_=pt,n.isPosterFromTech_=!1,n.queuedCallbacks_=[],n.isReady_=!1,n.hasStarted_=!1,n.userActive_=!1,!n.options_||!n.options_.techOrder||!n.options_.techOrder.length)throw new Error("No techOrder specified. Did you overwrite videojs.options instead of just changing the properties you want to override?");if(n.tag=e,n.tagAttributes=e&&P(e),n.language(n.options_.language),t.languages){var s={};Object.getOwnPropertyNames(t.languages).forEach(function(e){s[e.toLowerCase()]=t.languages[e]}),n.languages_=s}else n.languages_=l.prototype.options_.languages;n.resetCache_(),n.poster_=t.poster||"",n.controls_=!!t.controls,e.controls=!1,e.removeAttribute("controls"),n.changingSrc_=!1,n.playCallbacks_=[],n.playTerminatedQueue_=[],e.hasAttribute("autoplay")?n.autoplay(!0):n.autoplay(n.options_.autoplay),t.plugins&&Object.keys(t.plugins).forEach(function(e){if("function"!=typeof n[e])throw new Error('plugin "'+e+'" does not exist')}),n.scrubbing_=!1,n.el_=n.createEl(),we(Me(n),{eventBusKey:"el_"}),n.fluid_&&n.on("playerreset",n.updateStyleEl_);var o=Oe(n.options_);t.plugins&&Object.keys(t.plugins).forEach(function(e){n[e](t.plugins[e])}),n.options_.playerOptions=o,n.middleware_=[],n.initChildren(),n.isAudio("audio"===e.nodeName.toLowerCase()),n.controls()?n.addClass("vjs-controls-enabled"):n.addClass("vjs-controls-disabled"),n.el_.setAttribute("role","region"),n.isAudio()?n.el_.setAttribute("aria-label",n.localize("Audio Player")):n.el_.setAttribute("aria-label",n.localize("Video Player")),n.isAudio()&&n.addClass("vjs-audio"),n.flexNotSupported_()&&n.addClass("vjs-no-flex"),st&&n.addClass("vjs-touch-enabled"),Ge||n.addClass("vjs-workinghover"),l.players[n.id_]=Me(n);var u=d.split(".")[0];return n.addClass("vjs-v"+u),n.userActive(!0),n.reportUserActivity(),n.one("play",n.listenForUserActivity_),n.on("stageclick",n.handleStageClick_),n.on("keydown",n.handleKeyDown),n.breakpoints(n.options_.breakpoints),n.responsive(n.options_.responsive),n}De(l,c);var e=l.prototype;return e.dispose=function(){var n=this;this.trigger("dispose"),this.off("dispose"),le(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),le(h,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),l.players[this.id_]=null,this.tag&&this.tag.player&&(this.tag.player=null),this.el_&&this.el_.player&&(this.el_.player=null),this.tech_&&(this.tech_.dispose(),this.isPosterFromTech_=!1,this.poster_=""),this.playerElIngest_&&(this.playerElIngest_=null),this.tag&&(this.tag=null),function(e){ar[e.id()]=null}(this),An.names.forEach(function(e){var t=An[e],i=n[t.getterName]();i&&i.off&&i.off()}),c.prototype.dispose.call(this)},e.createEl=function(){var t,i=this.tag,e=this.playerElIngest_=i.parentNode&&i.parentNode.hasAttribute&&i.parentNode.hasAttribute("data-vjs-player"),n="video-js"===this.tag.tagName.toLowerCase();e?t=this.el_=i.parentNode:n||(t=this.el_=c.prototype.createEl.call(this,"div"));var r=P(i);if(n){for(t=this.el_=i,i=this.tag=h.createElement("video");t.children.length;)i.appendChild(t.firstChild);k(t,"video-js")||C(t,"video-js"),t.appendChild(i),e=this.playerElIngest_=t,Object.keys(t).forEach(function(e){try{i[e]=t[e]}catch(e){}})}if(i.setAttribute("tabindex","-1"),r.tabindex="-1",(it||et&&at)&&(i.setAttribute("role","application"),r.role="application"),i.removeAttribute("width"),i.removeAttribute("height"),"width"in r&&delete r.width,"height"in r&&delete r.height,Object.getOwnPropertyNames(r).forEach(function(e){n&&"class"===e||t.setAttribute(e,r[e]),n&&i.setAttribute(e,r[e])}),i.playerId=i.id,i.id+="_html5_api",i.className="vjs-tech",i.player=t.player=this,this.addClass("vjs-paused"),!0!==v.VIDEOJS_NO_DYNAMIC_STYLE){this.styleEl_=Q("vjs-styles-dimensions");var a=W(".vjs-styles-defaults"),s=W("head");s.insertBefore(this.styleEl_,a?a.nextSibling:s.firstChild)}this.fill_=!1,this.fluid_=!1,this.width(this.options_.width),this.height(this.options_.height),this.fill(this.options_.fill),this.fluid(this.options_.fluid),this.aspectRatio(this.options_.aspectRatio);for(var o=i.getElementsByTagName("a"),u=0;u<o.length;u++){var l=o.item(u);C(l,"vjs-hidden"),l.setAttribute("hidden","hidden")}return i.initNetworkState_=i.networkState,i.parentNode&&!e&&i.parentNode.insertBefore(t,i),S(i,t),this.children_.unshift(i),this.el_.setAttribute("lang",this.language_),this.el_=t},e.width=function(e){return this.dimension("width",e)},e.height=function(e){return this.dimension("height",e)},e.dimension=function(e,t){var i=e+"_";if(void 0===t)return this[i]||0;if(""===t)return this[i]=void 0,void this.updateStyleEl_();var n=parseFloat(t);isNaN(n)?p.error('Improper value "'+t+'" supplied for for '+e):(this[i]=n,this.updateStyleEl_())},e.fluid=function(e){if(void 0===e)return!!this.fluid_;this.fluid_=!!e,Ce(this)&&this.off("playerreset",this.updateStyleEl_),e?(this.addClass("vjs-fluid"),this.fill(!1),function(e,t){Ce(e)?t():(e.eventedCallbacks||(e.eventedCallbacks=[]),e.eventedCallbacks.push(t))}(function(){this.on("playerreset",this.updateStyleEl_)})):this.removeClass("vjs-fluid"),this.updateStyleEl_()},e.fill=function(e){if(void 0===e)return!!this.fill_;this.fill_=!!e,e?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")},e.aspectRatio=function(e){if(void 0===e)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(e))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=e,this.fluid(!0),this.updateStyleEl_()},e.updateStyleEl_=function(){if(!0!==v.VIDEOJS_NO_DYNAMIC_STYLE){var e,t,i,n=(void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:0<this.videoWidth()?this.videoWidth()+":"+this.videoHeight():"16:9").split(":"),r=n[1]/n[0];e=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/r:this.videoWidth()||300,t=void 0!==this.height_?this.height_:e*r,i=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(i),J(this.styleEl_,"\n ."+i+" {\n width: "+e+"px;\n height: "+t+"px;\n }\n\n ."+i+".vjs-fluid {\n padding-top: "+100*r+"%;\n }\n ")}else{var a="number"==typeof this.width_?this.width_:this.options_.width,s="number"==typeof this.height_?this.height_:this.options_.height,o=this.tech_&&this.tech_.el();o&&(0<=a&&(o.width=a),0<=s&&(o.height=s))}},e.loadTech_=function(e,t){var i=this;this.tech_&&this.unloadTech_();var n=Le(e),r=e.charAt(0).toLowerCase()+e.slice(1);"Html5"!==n&&this.tag&&(nr.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=n,this.isReady_=!1;var a={source:t,autoplay:"string"!=typeof this.autoplay()&&this.autoplay(),nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:this.id()+"_"+r+"_api",playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,muted:this.options_.muted,poster:this.poster(),language:this.language(),playerElIngest:this.playerElIngest_||!1,"vtt.js":this.options_["vtt.js"],canOverridePoster:!!this.options_.techCanOverridePoster,enableSourceset:this.options_.enableSourceset,Promise:this.options_.Promise};An.names.forEach(function(e){var t=An[e];a[t.getterName]=i[t.privateName]}),m(a,this.options_[n]),m(a,this.options_[r]),m(a,this.options_[e.toLowerCase()]),this.tag&&(a.tag=this.tag),t&&t.src===this.cache_.src&&0<this.cache_.currentTime&&(a.startTime=this.cache_.currentTime);var s=nr.getTech(e);if(!s)throw new Error("No Tech named '"+n+"' exists! '"+n+"' should be registered using videojs.registerTech()'");this.tech_=new s(a),this.tech_.ready(pe(this,this.handleTechReady_),!0),Et(this.textTracksJson_||[],this.tech_),Qa.forEach(function(e){i.on(i.tech_,e,i["handleTech"+Le(e)+"_"])}),Object.keys(Ja).forEach(function(t){i.on(i.tech_,t,function(e){0===i.tech_.playbackRate()&&i.tech_.seeking()?i.queuedCallbacks_.push({callback:i["handleTech"+Ja[t]+"_"].bind(i),event:e}):i["handleTech"+Ja[t]+"_"](e)})}),this.on(this.tech_,"loadstart",this.handleTechLoadStart_),this.on(this.tech_,"sourceset",this.handleTechSourceset_),this.on(this.tech_,"waiting",this.handleTechWaiting_),this.on(this.tech_,"ended",this.handleTechEnded_),this.on(this.tech_,"seeking",this.handleTechSeeking_),this.on(this.tech_,"play",this.handleTechPlay_),this.on(this.tech_,"firstplay",this.handleTechFirstPlay_),this.on(this.tech_,"pause",this.handleTechPause_),this.on(this.tech_,"durationchange",this.handleTechDurationChange_),this.on(this.tech_,"fullscreenchange",this.handleTechFullscreenChange_),this.on(this.tech_,"enterpictureinpicture",this.handleTechEnterPictureInPicture_),this.on(this.tech_,"leavepictureinpicture",this.handleTechLeavePictureInPicture_),this.on(this.tech_,"error",this.handleTechError_),this.on(this.tech_,"loadedmetadata",this.updateStyleEl_),this.on(this.tech_,"posterchange",this.handleTechPosterChange_),this.on(this.tech_,"textdata",this.handleTechTextData_),this.on(this.tech_,"ratechange",this.handleTechRateChange_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===n&&this.tag||S(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)},e.unloadTech_=function(){var i=this;An.names.forEach(function(e){var t=An[e];i[t.privateName]=i[t.getterName]()}),this.textTracksJson_=Ct(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1},e.tech=function(e){return void 0===e&&p.warn("Using the tech directly can be dangerous. I hope you know what you're doing.\nSee https://github.com/videojs/video.js/issues/2617 for more info.\n"),this.tech_},e.addTechControlsListeners_=function(){this.removeTechControlsListeners_(),this.on(this.tech_,"mouseup",this.handleTechClick_),this.on(this.tech_,"dblclick",this.handleTechDoubleClick_),this.on(this.tech_,"touchstart",this.handleTechTouchStart_),this.on(this.tech_,"touchmove",this.handleTechTouchMove_),this.on(this.tech_,"touchend",this.handleTechTouchEnd_),this.on(this.tech_,"tap",this.handleTechTap_)},e.removeTechControlsListeners_=function(){this.off(this.tech_,"tap",this.handleTechTap_),this.off(this.tech_,"touchstart",this.handleTechTouchStart_),this.off(this.tech_,"touchmove",this.handleTechTouchMove_),this.off(this.tech_,"touchend",this.handleTechTouchEnd_),this.off(this.tech_,"mouseup",this.handleTechClick_),this.off(this.tech_,"dblclick",this.handleTechDoubleClick_)},e.handleTechReady_=function(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()},e.handleTechLoadStart_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):(this.trigger("loadstart"),this.trigger("firstplay")),this.manualAutoplay_(this.autoplay())},e.manualAutoplay_=function(t){var n=this;if(this.tech_&&"string"==typeof t){function e(){var e=n.muted();n.muted(!0);function t(){n.muted(e)}n.playTerminatedQueue_.push(t);var i=n.play();if(Tt(i))return i.catch(t)}var i;if("any"===t&&!0!==this.muted()?Tt(i=this.play())&&(i=i.catch(e)):i="muted"===t&&!0!==this.muted()?e():this.play(),Tt(i))return i.then(function(){n.trigger({type:"autoplay-success",autoplay:t})}).catch(function(e){n.trigger({type:"autoplay-failure",autoplay:t})})}},e.updateSourceCaches_=function(e){void 0===e&&(e="");var t=e,i="";"string"!=typeof t&&(t=e.src,i=e.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],t&&!i&&(i=function(e,t){if(!t)return"";if(e.cache_.source.src===t&&e.cache_.source.type)return e.cache_.source.type;var i=e.cache_.sources.filter(function(e){return e.src===t});if(i.length)return i[0].type;for(var n=e.$$("source"),r=0;r<n.length;r++){var a=n[r];if(a.type&&a.src&&a.src===t)return a.type}return fr(t)}(this,t)),this.cache_.source=Oe({},e,{src:t,type:i});for(var n=this.cache_.sources.filter(function(e){return e.src&&e.src===t}),r=[],a=this.$$("source"),s=[],o=0;o<a.length;o++){var u=P(a[o]);r.push(u),u.src&&u.src===t&&s.push(u.src)}s.length&&!n.length?this.cache_.sources=r:n.length||(this.cache_.sources=[this.cache_.source]),this.cache_.src=t},e.handleTechSourceset_=function(e){var i=this;if(!this.changingSrc_){var t=function(e){return i.updateSourceCaches_(e)},n=this.currentSource().src,r=e.src;n&&!/^blob:/.test(n)&&/^blob:/.test(r)&&(this.lastSource_&&(this.lastSource_.tech===r||this.lastSource_.player===n)||(t=function(){})),t(r),e.src||this.tech_.any(["sourceset","loadstart"],function(e){if("sourceset"!==e.type){var t=i.techGet("currentSrc");i.lastSource_.tech=t,i.updateSourceCaches_(t)}})}this.lastSource_={player:this.currentSource().src,tech:e.src},this.trigger({src:e.src,type:"sourceset"})},e.hasStarted=function(e){if(void 0===e)return this.hasStarted_;e!==this.hasStarted_&&(this.hasStarted_=e,this.hasStarted_?(this.addClass("vjs-has-started"),this.trigger("firstplay")):this.removeClass("vjs-has-started"))},e.handleTechPlay_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")},e.handleTechRateChange_=function(){0<this.tech_.playbackRate()&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach(function(e){return e.callback(e.event)}),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")},e.handleTechWaiting_=function(){var t=this;this.addClass("vjs-waiting"),this.trigger("waiting");var i=this.currentTime();this.on("timeupdate",function e(){i!==t.currentTime()&&(t.removeClass("vjs-waiting"),t.off("timeupdate",e))})},e.handleTechCanPlay_=function(){this.removeClass("vjs-waiting"),this.trigger("canplay")},e.handleTechCanPlayThrough_=function(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")},e.handleTechPlaying_=function(){this.removeClass("vjs-waiting"),this.trigger("playing")},e.handleTechSeeking_=function(){this.addClass("vjs-seeking"),this.trigger("seeking")},e.handleTechSeeked_=function(){this.removeClass("vjs-seeking"),this.removeClass("vjs-ended"),this.trigger("seeked")},e.handleTechFirstPlay_=function(){this.options_.starttime&&(p.warn("Passing the `starttime` option to the player will be deprecated in 6.0"),this.currentTime(this.options_.starttime)),this.addClass("vjs-has-started"),this.trigger("firstplay")},e.handleTechPause_=function(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")},e.handleTechEnded_=function(){this.addClass("vjs-ended"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")},e.handleTechDurationChange_=function(){this.duration(this.techGet_("duration"))},e.handleTechClick_=function(e){V(e)&&this.controls_&&(this.paused()?St(this.play()):this.pause())},e.handleTechDoubleClick_=function(t){this.controls_&&(Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),function(e){return e.contains(t.target)})||void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.doubleClick&&!1===this.options_.userActions.doubleClick||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.doubleClick?this.options_.userActions.doubleClick.call(this,t):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen()))},e.handleTechTap_=function(){this.userActive(!this.userActive())},e.handleTechTouchStart_=function(){this.userWasActive=this.userActive()},e.handleTechTouchMove_=function(){this.userWasActive&&this.reportUserActivity()},e.handleTechTouchEnd_=function(e){e.preventDefault()},e.handleStageClick_=function(){this.reportUserActivity()},e.toggleFullscreenClass_=function(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")},e.documentFullscreenChange_=function(e){var t=this.el(),i=h[this.fsApi_.fullscreenElement]===t;!i&&t.matches?i=t.matches(":"+this.fsApi_.fullscreen):!i&&t.msMatchesSelector&&(i=t.msMatchesSelector(":"+this.fsApi_.fullscreen)),this.isFullscreen(i),!1===this.isFullscreen()&&le(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.fsApi_.prefixed&&this.trigger("fullscreenchange")},e.handleTechFullscreenChange_=function(e,t){t&&this.isFullscreen(t.isFullscreen),this.trigger("fullscreenchange")},e.togglePictureInPictureClass_=function(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")},e.handleTechEnterPictureInPicture_=function(e){this.isInPictureInPicture(!0)},e.handleTechLeavePictureInPicture_=function(e){this.isInPictureInPicture(!1)},e.handleTechError_=function(){var e=this.tech_.error();this.error(e)},e.handleTechTextData_=function(e,t){var i=null;1<arguments.length&&(i=t),this.trigger("textdata",i)},e.getCache=function(){return this.cache_},e.resetCache_=function(){this.cache_={currentTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],volume:1}},e.techCall_=function(e,t){this.ready(function(){if(e in cr)return function(e,t,i,n){return t[i](e.reduce(dr(i),n))}(this.middleware_,this.tech_,e,t);if(e in hr)return ur(this.middleware_,this.tech_,e,t);try{this.tech_&&this.tech_[e](t)}catch(e){throw p(e),e}},!0)},e.techGet_=function(t){if(this.tech_&&this.tech_.isReady_){if(t in lr)return function(e,t,i){return e.reduceRight(dr(i),t[i]())}(this.middleware_,this.tech_,t);if(t in hr)return ur(this.middleware_,this.tech_,t);try{return this.tech_[t]()}catch(e){if(void 0===this.tech_[t])throw p("Video.js: "+t+" method not defined for "+this.techName_+" playback technology.",e),e;if("TypeError"===e.name)throw p("Video.js: "+t+" unavailable on "+this.techName_+" playback technology element.",e),this.tech_.isReady_=!1,e;throw p(e),e}}},e.play=function(){var t=this,e=this.options_.Promise||v.Promise;return e?new e(function(e){t.play_(e)}):this.play_()},e.play_=function(e){var t=this;void 0===e&&(e=St),this.playCallbacks_.push(e);var i=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc()));if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!i)return this.waitToPlay_=function(e){t.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(i||!rt&&!Ge||this.load());var n=this.techGet_("play");null===n?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(n)},e.runPlayTerminatedQueue_=function(){var e=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],e.forEach(function(e){e()})},e.runPlayCallbacks_=function(t){var e=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],e.forEach(function(e){e(t)})},e.pause=function(){this.techCall_("pause")},e.paused=function(){return!1!==this.techGet_("paused")},e.played=function(){return this.techGet_("played")||ct(0,0)},e.scrubbing=function(e){if("undefined"==typeof e)return this.scrubbing_;this.scrubbing_=!!e,e?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")},e.currentTime=function(e){return"undefined"!=typeof e?(e<0&&(e=0),void this.techCall_("setCurrentTime",e)):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)},e.duration=function(e){if(void 0===e)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(e=parseFloat(e))<0&&(e=1/0),e!==this.cache_.duration&&((this.cache_.duration=e)===1/0?(this.addClass("vjs-live"),this.options_.liveui&&this.player_.liveTracker&&this.addClass("vjs-liveui")):(this.removeClass("vjs-live"),this.removeClass("vjs-liveui")),isNaN(e)||this.trigger("durationchange"))},e.remainingTime=function(){return this.duration()-this.currentTime()},e.remainingTimeDisplay=function(){return Math.floor(this.duration())-Math.floor(this.currentTime())},e.buffered=function(){var e=this.techGet_("buffered");return e&&e.length||(e=ct(0,0)),e},e.bufferedPercent=function(){return ht(this.buffered(),this.duration())},e.bufferedEnd=function(){var e=this.buffered(),t=this.duration(),i=e.end(e.length-1);return t<i&&(i=t),i},e.volume=function(e){var t;return void 0!==e?(t=Math.max(0,Math.min(1,parseFloat(e))),this.cache_.volume=t,this.techCall_("setVolume",t),void(0<t&&this.lastVolume_(t))):(t=parseFloat(this.techGet_("volume")),isNaN(t)?1:t)},e.muted=function(e){if(void 0===e)return this.techGet_("muted")||!1;this.techCall_("setMuted",e)},e.defaultMuted=function(e){return void 0!==e?this.techCall_("setDefaultMuted",e):this.techGet_("defaultMuted")||!1},e.lastVolume_=function(e){if(void 0===e||0===e)return this.cache_.lastVolume;this.cache_.lastVolume=e},e.supportsFullScreen=function(){return this.techGet_("supportsFullScreen")||!1},e.isFullscreen=function(e){return void 0!==e?(this.isFullscreen_=!!e,void this.toggleFullscreenClass_()):!!this.isFullscreen_},e.requestFullscreen=function(e){var t;this.isFullscreen(!0),this.fsApi_.requestFullscreen?(ue(h,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.fsApi_.prefixed||(t=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==e&&(t=e)),St(this.el_[this.fsApi_.requestFullscreen](t))):this.tech_.supportsFullScreen()?this.techCall_("enterFullScreen"):(this.enterFullWindow(),this.trigger("fullscreenchange"))},e.exitFullscreen=function(){this.isFullscreen(!1),this.fsApi_.requestFullscreen?St(h[this.fsApi_.exitFullscreen]()):this.tech_.supportsFullScreen()?this.techCall_("exitFullScreen"):(this.exitFullWindow(),this.trigger("fullscreenchange"))},e.enterFullWindow=function(){this.isFullWindow=!0,this.docOrigOverflow=h.documentElement.style.overflow,ue(h,"keydown",this.boundFullWindowOnEscKey_),h.documentElement.style.overflow="hidden",C(h.body,"vjs-full-window"),this.trigger("enterFullWindow")},e.fullWindowOnEscKey=function(e){At.isEventKey(e,"Esc")&&(!0===this.isFullscreen()?this.exitFullscreen():this.exitFullWindow())},e.exitFullWindow=function(){this.isFullWindow=!1,le(h,"keydown",this.boundFullWindowOnEscKey_),h.documentElement.style.overflow=this.docOrigOverflow,E(h.body,"vjs-full-window"),this.trigger("exitFullWindow")},e.isInPictureInPicture=function(e){return void 0!==e?(this.isInPictureInPicture_=!!e,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_},e.requestPictureInPicture=function(){if("pictureInPictureEnabled"in h)return this.techGet_("requestPictureInPicture")},e.exitPictureInPicture=function(){if("pictureInPictureEnabled"in h)return h.exitPictureInPicture()},e.handleKeyDown=function(e){var t=this.options_.userActions;if(t&&t.hotkeys){!function(e){var t=e.tagName.toLowerCase();if(e.isContentEditable)return!0;if("input"===t)return-1===["button","checkbox","hidden","radio","reset","submit"].indexOf(e.type);return-1!==["textarea"].indexOf(t)}(this.el_.ownerDocument.activeElement)&&("function"==typeof t.hotkeys?t.hotkeys.call(this,e):this.handleHotkeys(e))}},e.handleHotkeys=function(e){var t=this.options_.userActions?this.options_.userActions.hotkeys:{},i=t.fullscreenKey,n=void 0===i?function(e){return At.isEventKey(e,"f")}:i,r=t.muteKey,a=void 0===r?function(e){return At.isEventKey(e,"m")}:r,s=t.playPauseKey,o=void 0===s?function(e){return At.isEventKey(e,"k")||At.isEventKey(e,"Space")}:s;if(n.call(this,e)){e.preventDefault(),e.stopPropagation();var u=xe.getComponent("FullscreenToggle");!1!==h[this.fsApi_.fullscreenEnabled]&&u.prototype.handleClick.call(this,e)}else if(a.call(this,e)){e.preventDefault(),e.stopPropagation(),xe.getComponent("MuteToggle").prototype.handleClick.call(this,e)}else if(o.call(this,e)){e.preventDefault(),e.stopPropagation(),xe.getComponent("PlayToggle").prototype.handleClick.call(this,e)}},e.canPlayType=function(e){for(var t,i=0,n=this.options_.techOrder;i<n.length;i++){var r=n[i],a=nr.getTech(r);if(a=a||xe.getComponent(r)){if(a.isSupported()&&(t=a.canPlayType(e)))return t}else p.error('The "'+r+'" tech is undefined. Skipped browser support check for that tech.')}return""},e.selectSource=function(e){function t(e,i,n){var r;return e.some(function(t){return i.some(function(e){if(r=n(t,e))return!0})}),r}function i(e,t){var i=e[0];if(e[1].canPlaySource(t,r.options_[i.toLowerCase()]))return{source:t,tech:i}}var n,r=this,a=this.options_.techOrder.map(function(e){return[e,nr.getTech(e)]}).filter(function(e){var t=e[0],i=e[1];return i?i.isSupported():(p.error('The "'+t+'" tech is undefined. Skipped browser support check for that tech.'),!1)});return(this.options_.sourceOrder?t(e,a,(n=i,function(e,t){return n(t,e)})):t(a,e,i))||!1},e.src=function(e){var i=this;if("undefined"==typeof e)return this.cache_.src||"";var n=function t(e){if(Array.isArray(e)){var i=[];e.forEach(function(e){e=t(e),Array.isArray(e)?i=i.concat(e):s(e)&&i.push(e)}),e=i}else e="string"==typeof e&&e.trim()?[gr({src:e})]:s(e)&&"string"==typeof e.src&&e.src&&e.src.trim()?[gr(e)]:[];return e}(e);n.length?(this.changingSrc_=!0,this.cache_.sources=n,this.updateSourceCaches_(n[0]),or(this,n[0],function(e,t){if(i.middleware_=t,i.cache_.sources=n,i.updateSourceCaches_(e),i.src_(e))return 1<n.length?i.src(n.slice(1)):(i.changingSrc_=!1,i.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0),void i.triggerReady());!function(e,t){e.forEach(function(e){return e.setTech&&e.setTech(t)})}(t,i.tech_)})):this.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0)},e.src_=function(e){var t=this,i=this.selectSource([e]);return!i||(function(e,t){return Le(e)===Le(t)}(i.tech,this.techName_)?this.ready(function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",e):this.techCall_("src",e.src),this.changingSrc_=!1},!0):(this.changingSrc_=!0,this.loadTech_(i.tech,i.source),this.tech_.ready(function(){t.changingSrc_=!1})),!1)},e.load=function(){this.techCall_("load")},e.reset=function(){var e=this,t=this.options_.Promise||v.Promise;this.paused()||!t?this.doReset_():St(this.play().then(function(){return e.doReset_()}))},e.doReset_=function(){this.tech_&&this.tech_.clearTracks("text"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),Ce(this)&&this.trigger("playerreset")},e.resetControlBarUI_=function(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()},e.resetProgressBar_=function(){this.currentTime(0);var e=this.controlBar,t=e.durationDisplay,i=e.remainingTimeDisplay;t&&t.updateContent(),i&&i.updateContent()},e.resetPlaybackRate_=function(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()},e.resetVolumeBar_=function(){this.volume(1),this.trigger("volumechange")},e.currentSources=function(){var e=this.currentSource(),t=[];return 0!==Object.keys(e).length&&t.push(e),this.cache_.sources||t},e.currentSource=function(){return this.cache_.source||{}},e.currentSrc=function(){return this.currentSource()&&this.currentSource().src||""},e.currentType=function(){return this.currentSource()&&this.currentSource().type||""},e.preload=function(e){return void 0!==e?(this.techCall_("setPreload",e),void(this.options_.preload=e)):this.techGet_("preload")},e.autoplay=function(e){if(void 0===e)return this.options_.autoplay||!1;var t;"string"==typeof e&&/(any|play|muted)/.test(e)?(this.options_.autoplay=e,this.manualAutoplay_(e),t=!1):this.options_.autoplay=!!e,t="undefined"==typeof t?this.options_.autoplay:t,this.tech_&&this.techCall_("setAutoplay",t)},e.playsinline=function(e){return void 0!==e?(this.techCall_("setPlaysinline",e),this.options_.playsinline=e,this):this.techGet_("playsinline")},e.loop=function(e){return void 0!==e?(this.techCall_("setLoop",e),void(this.options_.loop=e)):this.techGet_("loop")},e.poster=function(e){if(void 0===e)return this.poster_;(e=e||"")!==this.poster_&&(this.poster_=e,this.techCall_("setPoster",e),this.isPosterFromTech_=!1,this.trigger("posterchange"))},e.handleTechPosterChange_=function(){if((!this.poster_||this.options_.techCanOverridePoster)&&this.tech_&&this.tech_.poster){var e=this.tech_.poster()||"";e!==this.poster_&&(this.poster_=e,this.isPosterFromTech_=!0,this.trigger("posterchange"))}},e.controls=function(e){if(void 0===e)return!!this.controls_;e=!!e,this.controls_!==e&&(this.controls_=e,this.usingNativeControls()&&this.techCall_("setControls",e),this.controls_?(this.removeClass("vjs-controls-disabled"),this.addClass("vjs-controls-enabled"),this.trigger("controlsenabled"),this.usingNativeControls()||this.addTechControlsListeners_()):(this.removeClass("vjs-controls-enabled"),this.addClass("vjs-controls-disabled"),this.trigger("controlsdisabled"),this.usingNativeControls()||this.removeTechControlsListeners_()))},e.usingNativeControls=function(e){if(void 0===e)return!!this.usingNativeControls_;e=!!e,this.usingNativeControls_!==e&&(this.usingNativeControls_=e,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))},e.error=function(e){if(void 0===e)return this.error_||null;if(this.options_.suppressNotSupportedError&&e&&e.message&&e.message===this.localize(this.options_.notSupportedMessage)){function t(){this.error(e)}return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],t),void this.one("loadstart",function(){this.off(["click","touchstart"],t)})}if(null===e)return this.error_=e,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new vt(e),this.addClass("vjs-error"),p.error("(CODE:"+this.error_.code+" "+vt.errorTypes[this.error_.code]+")",this.error_.message,this.error_),this.trigger("error")},e.reportUserActivity=function(e){this.userActivity_=!0},e.userActive=function(e){if(void 0===e)return this.userActive_;if((e=!!e)!==this.userActive_){if(this.userActive_=e,this.userActive_)return this.userActivity_=!0,this.removeClass("vjs-user-inactive"),this.addClass("vjs-user-active"),void this.trigger("useractive");this.tech_&&this.tech_.one("mousemove",function(e){e.stopPropagation(),e.preventDefault()}),this.userActivity_=!1,this.removeClass("vjs-user-active"),this.addClass("vjs-user-inactive"),this.trigger("userinactive")}},e.listenForUserActivity_=function(){var t,i,n,r=pe(this,this.reportUserActivity);this.on("mousedown",function(){r(),this.clearInterval(t),t=this.setInterval(r,250)}),this.on("mousemove",function(e){e.screenX===i&&e.screenY===n||(i=e.screenX,n=e.screenY,r())}),this.on("mouseup",function(e){r(),this.clearInterval(t)});var a,e=this.getChild("controlBar");!e||Ge||Ke||(e.on("mouseenter",function(e){this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout,this.player().options_.inactivityTimeout=0}),e.on("mouseleave",function(e){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout})),this.on("keydown",r),this.on("keyup",r),this.setInterval(function(){if(this.userActivity_){this.userActivity_=!1,this.userActive(!0),this.clearTimeout(a);var e=this.options_.inactivityTimeout;e<=0||(a=this.setTimeout(function(){this.userActivity_||this.userActive(!1)},e))}},250)},e.playbackRate=function(e){if(void 0===e)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",e)},e.defaultPlaybackRate=function(e){return void 0!==e?this.techCall_("setDefaultPlaybackRate",e):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1},e.isAudio=function(e){if(void 0===e)return!!this.isAudio_;this.isAudio_=!!e},e.addTextTrack=function(e,t,i){if(this.tech_)return this.tech_.addTextTrack(e,t,i)},e.addRemoteTextTrack=function(e,t){if(this.tech_)return this.tech_.addRemoteTextTrack(e,t)},e.removeRemoteTextTrack=function(e){void 0===e&&(e={});var t=e.track;if(t=t||e,this.tech_)return this.tech_.removeRemoteTextTrack(t)},e.getVideoPlaybackQuality=function(){return this.techGet_("getVideoPlaybackQuality")},e.videoWidth=function(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0},e.videoHeight=function(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0},e.language=function(e){if(void 0===e)return this.language_;this.language_=String(e).toLowerCase()},e.languages=function(){return Oe(l.prototype.options_.languages,this.languages_)},e.toJSON=function(){var e=Oe(this.options_),t=e.tracks;e.tracks=[];for(var i=0;i<t.length;i++){var n=t[i];(n=Oe(n)).player=void 0,e.tracks[i]=n}return e},e.createModal=function(e,t){var i=this;(t=t||{}).content=e||"";var n=new It(this,t);return this.addChild(n),n.on("dispose",function(){i.removeChild(n)}),n.open(),n},e.updateCurrentBreakpoint_=function(){if(this.responsive())for(var e=this.currentBreakpoint(),t=this.currentWidth(),i=0;i<Za.length;i++){var n=Za[i];if(t<=this.breakpoints_[n]){if(e===n)return;e&&this.removeClass(es[e]),this.addClass(es[n]),this.breakpoint_=n;break}}},e.removeCurrentBreakpoint_=function(){var e=this.currentBreakpointClass();this.breakpoint_="",e&&this.removeClass(e)},e.breakpoints=function(e){return void 0===e||(this.breakpoint_="",this.breakpoints_=m({},ts,e),this.updateCurrentBreakpoint_()),m(this.breakpoints_)},e.responsive=function(e){return void 0===e?this.responsive_:(e=Boolean(e))!==this.responsive_?((this.responsive_=e)?(this.on("playerresize",this.updateCurrentBreakpoint_),this.updateCurrentBreakpoint_()):(this.off("playerresize",this.updateCurrentBreakpoint_),this.removeCurrentBreakpoint_()),e):void 0},e.currentBreakpoint=function(){return this.breakpoint_},e.currentBreakpointClass=function(){return es[this.breakpoint_]||""},e.loadMedia=function(e,t){var i=this;if(e&&"object"==typeof e){this.reset(),this.cache_.media=Oe(e);var n=this.cache_.media,r=n.artwork,a=n.poster,s=n.src,o=n.textTracks;!r&&a&&(this.cache_.media.artwork=[{src:a,type:fr(a)}]),s&&this.src(s),a&&this.poster(a),Array.isArray(o)&&o.forEach(function(e){return i.addRemoteTextTrack(e,!1)}),this.ready(t)}},e.getMedia=function(){if(this.cache_.media)return Oe(this.cache_.media);var e=this.poster(),t={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),function(e){return{kind:e.kind,label:e.label,language:e.language,src:e.src}})};return e&&(t.poster=e,t.artwork=[{src:t.poster,type:fr(t.poster)}]),t},l.getTagSettings=function(e){var t={sources:[],tracks:[]},i=P(e),n=i["data-setup"];if(k(e,"vjs-fill")&&(i.fill=!0),k(e,"vjs-fluid")&&(i.fluid=!0),null!==n){var r=bt(n||"{}"),a=r[0],s=r[1];a&&p.error(a),m(i,s)}if(m(t,i),e.hasChildNodes())for(var o=e.childNodes,u=0,l=o.length;u<l;u++){var c=o[u],h=c.nodeName.toLowerCase();"source"===h?t.sources.push(P(c)):"track"===h&&t.tracks.push(P(c))}return t},e.flexNotSupported_=function(){var e=h.createElement("i");return!("flexBasis"in e.style||"webkitFlexBasis"in e.style||"mozFlexBasis"in e.style||"msFlexBasis"in e.style||"msFlexOrder"in e.style)},l}(xe);An.names.forEach(function(e){var t=An[e];is.prototype[t.getterName]=function(){return this.tech_?this.tech_[t.getterName]():(this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName])}}),is.players={};var ns=v.navigator;is.prototype.options_={techOrder:nr.defaultTechOrder_,html5:{},flash:{},inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:ns&&(ns.languages&&ns.languages[0]||ns.userLanguage||ns.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1},["ended","seeking","seekable","networkState","readyState"].forEach(function(e){is.prototype[e]=function(){return this.techGet_(e)}}),Qa.forEach(function(e){is.prototype["handleTech"+Le(e)+"_"]=function(){return this.trigger(e)}}),xe.registerComponent("Player",is);function rs(e){return hs.hasOwnProperty(e)}function as(e){return rs(e)?hs[e]:void 0}function ss(e,t){e[cs]=e[cs]||{},e[cs][t]=!0}function os(e,t,i){var n=(i?"before":"")+"pluginsetup";e.trigger(n,t),e.trigger(n+":"+t.name,t)}function us(r,a){return a.prototype.name=r,function(){os(this,{name:r,plugin:a,instance:null},!0);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=Re(a,[this].concat(t));return this[r]=function(){return n},os(this,n.getEventHash()),n}}var ls="plugin",cs="activePlugins_",hs={},ds=function(){function i(e){if(this.constructor===i)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=e,we(this),delete this.trigger,Pe(this,this.constructor.defaultState),ss(e,this.name),this.dispose=pe(this,this.dispose),e.on("dispose",this.dispose)}var e=i.prototype;return e.version=function(){return this.constructor.VERSION},e.getEventHash=function(e){return void 0===e&&(e={}),e.name=this.name,e.plugin=this.constructor,e.instance=this,e},e.trigger=function(e,t){return void 0===t&&(t={}),ce(this.eventBusEl_,e,this.getEventHash(t))},e.handleStateChanged=function(e){},e.dispose=function(){var e=this.name,t=this.player;this.trigger("dispose"),this.off(),t.off("dispose",this.dispose),t[cs][e]=!1,this.player=this.state=null,t[e]=us(e,hs[e])},i.isBasic=function(e){var t="string"==typeof e?as(e):e;return"function"==typeof t&&!i.prototype.isPrototypeOf(t.prototype)},i.registerPlugin=function(e,t){if("string"!=typeof e)throw new Error('Illegal plugin name, "'+e+'", must be a string, was '+typeof e+".");if(rs(e))p.warn('A plugin named "'+e+'" already exists. You may want to avoid re-registering plugins!');else if(is.prototype.hasOwnProperty(e))throw new Error('Illegal plugin name, "'+e+'", cannot share a name with an existing player method!');if("function"!=typeof t)throw new Error('Illegal plugin for "'+e+'", must be a function, was '+typeof t+".");return hs[e]=t,e!==ls&&(i.isBasic(t)?is.prototype[e]=function(t,i){function n(){os(this,{name:t,plugin:i,instance:null},!0);var e=i.apply(this,arguments);return ss(this,t),os(this,{name:t,plugin:i,instance:e}),e}return Object.keys(i).forEach(function(e){n[e]=i[e]}),n}(e,t):is.prototype[e]=us(e,t)),t},i.deregisterPlugin=function(e){if(e===ls)throw new Error("Cannot de-register base plugin.");rs(e)&&(delete hs[e],delete is.prototype[e])},i.getPlugins=function(e){var i;return void 0===e&&(e=Object.keys(hs)),e.forEach(function(e){var t=as(e);t&&((i=i||{})[e]=t)}),i},i.getPluginVersion=function(e){var t=as(e);return t&&t.VERSION||""},i}();ds.getPlugin=as,ds.BASE_PLUGIN_NAME=ls,ds.registerPlugin(ls,ds),is.prototype.usingPlugin=function(e){return!!this[cs]&&!0===this[cs][e]},is.prototype.hasPlugin=function(e){return!!rs(e)};var ps=function(e){return 0===e.indexOf("#")?e.slice(1):e};function fs(e,i,t){var n=fs.getPlayer(e);if(n)return i&&p.warn('Player "'+e+'" is already initialised. Options will not be applied.'),t&&n.ready(t),n;var r="string"==typeof e?W("#"+ps(e)):e;if(!g(r))throw new TypeError("The element or ID supplied is not valid. (videojs)");r.ownerDocument.defaultView&&r.ownerDocument.body.contains(r)||p.warn("The element supplied is not included in the DOM"),i=i||{},fs.hooks("beforesetup").forEach(function(e){var t=e(r,Oe(i));s(t)&&!Array.isArray(t)?i=Oe(i,t):p.error("please return an object in beforesetup hooks")});var a=xe.getComponent("Player");return n=new a(r,i,t),fs.hooks("setup").forEach(function(e){return e(n)}),n}if(fs.hooks_={},fs.hooks=function(e,t){return fs.hooks_[e]=fs.hooks_[e]||[],t&&(fs.hooks_[e]=fs.hooks_[e].concat(t)),fs.hooks_[e]},fs.hook=function(e,t){fs.hooks(e,t)},fs.hookOnce=function(i,e){fs.hooks(i,[].concat(e).map(function(t){return function e(){return fs.removeHook(i,e),t.apply(void 0,arguments)}}))},fs.removeHook=function(e,t){var i=fs.hooks(e).indexOf(t);return!(i<=-1)&&(fs.hooks_[e]=fs.hooks_[e].slice(),fs.hooks_[e].splice(i,1),!0)},!0!==v.VIDEOJS_NO_DYNAMIC_STYLE&&c()){var ms=W(".vjs-styles-defaults");if(!ms){ms=Q("vjs-styles-defaults");var gs=W("head");gs&&gs.insertBefore(ms,gs.firstChild),J(ms,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ")}}K(1,fs),fs.VERSION=d,fs.options=is.prototype.options_,fs.getPlayers=function(){return is.players},fs.getPlayer=function(e){var t,i=is.players;if("string"==typeof e){var n=ps(e),r=i[n];if(r)return r;t=W("#"+n)}else t=e;if(g(t)){var a=t,s=a.player,o=a.playerId;if(s||i[o])return s||i[o]}},fs.getAllPlayers=function(){return Object.keys(is.players).map(function(e){return is.players[e]}).filter(Boolean)},fs.players=is.players,fs.getComponent=xe.getComponent,fs.registerComponent=function(e,t){nr.isTech(t)&&p.warn("The "+e+" tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)"),xe.registerComponent.call(xe,e,t)},fs.getTech=nr.getTech,fs.registerTech=nr.registerTech,fs.use=function(e,t){rr[e]=rr[e]||[],rr[e].push(t)},Object.defineProperty(fs,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(fs.middleware,"TERMINATOR",{value:sr,writeable:!1,enumerable:!0}),fs.browser=ot,fs.TOUCH_ENABLED=st,fs.extend=function(e,t){void 0===t&&(t={});var i=function(){e.apply(this,arguments)},n={};for(var r in"object"==typeof t?(t.constructor!==Object.prototype.constructor&&(i=t.constructor),n=t):"function"==typeof t&&(i=t),function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.super_=t)}(i,e),n)n.hasOwnProperty(r)&&(i.prototype[r]=n[r]);return i},fs.mergeOptions=Oe,fs.bind=pe,fs.registerPlugin=ds.registerPlugin,fs.deregisterPlugin=ds.deregisterPlugin,fs.plugin=function(e,t){return p.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),ds.registerPlugin(e,t)},fs.getPlugins=ds.getPlugins,fs.getPlugin=ds.getPlugin,fs.getPluginVersion=ds.getPluginVersion,fs.addLanguage=function(e,t){var i;return e=(""+e).toLowerCase(),fs.options.languages=Oe(fs.options.languages,((i={})[e]=t,i)),fs.options.languages[e]},fs.log=p,fs.createLogger=f,fs.createTimeRange=fs.createTimeRanges=ct,fs.formatTime=xr,fs.setFormatTime=function(e){Or=e},fs.resetFormatTime=function(){Or=Lr},fs.parseUrl=Ut,fs.isCrossOrigin=Nt,fs.EventTarget=me,fs.on=ue,fs.one=he,fs.off=le,fs.trigger=ce,fs.xhr=gn,fs.TextTrack=Tn,fs.AudioTrack=Sn,fs.VideoTrack=kn,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach(function(e){fs[e]=function(){return p.warn("videojs."+e+"() is deprecated; use videojs.dom."+e+"() instead"),$[e].apply(null,arguments)}}),fs.computedStyle=n,fs.dom=$,fs.url=Xt;var ys=wt(function(e,t){var i,c,n,r,h;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/\?#]*\/)*.*?)??(;.*?)?(\?.*?)?(#.*?)?$/,c=/^([^\/?#]*)(.*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g,h={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=h.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=h.normalizePath(n.path),h.buildURLFromParts(n)}var r=h.parseURL(t);if(!r)throw new Error("Error trying to parse relative URL.");if(r.scheme)return i.alwaysNormalize?(r.path=h.normalizePath(r.path),h.buildURLFromParts(r)):t;var a=h.parseURL(e);if(!a)throw new Error("Error trying to parse base URL.");if(!a.netLoc&&a.path&&"/"!==a.path[0]){var s=c.exec(a.path);a.netLoc=s[1],a.path=s[2]}a.netLoc&&!a.path&&(a.path="/");var o={scheme:a.scheme,netLoc:r.netLoc,path:null,params:r.params,query:r.query,fragment:r.fragment};if(!r.netLoc&&(o.netLoc=a.netLoc,"/"!==r.path[0]))if(r.path){var u=a.path,l=u.substring(0,u.lastIndexOf("/")+1)+r.path;o.path=h.normalizePath(l)}else o.path=a.path,r.params||(o.params=a.params,r.query||(o.query=a.query));return null===o.path&&(o.path=i.alwaysNormalize?h.normalizePath(r.path):r.path),h.buildURLFromParts(o)},parseURL:function(e){var t=i.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=h});
+/*! @name m3u8-parser @version 4.4.0 @license Apache-2.0 */function vs(){return(vs=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i=arguments[t];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e}).apply(this,arguments)}function _s(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}function bs(e){for(var t,i=e.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),n={},r=i.length;r--;)""!==i[r]&&((t=/([^=]*)=(.*)/.exec(i[r]).slice(1))[0]=t[0].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^['"](.*)['"]$/g,"$1"),n[t[0]]=t[1]);return n}var Ts=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},t.trigger=function(e,t){var i,n,r,a=this.listeners[e];if(a)if(2===arguments.length)for(n=a.length,i=0;i<n;++i)a[i].call(this,t);else for(r=Array.prototype.slice.call(arguments,1),n=a.length,i=0;i<n;++i)a[i].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}(),Ss=function(t){function e(){var e;return(e=t.call(this)||this).buffer="",e}return _s(e,t),e.prototype.push=function(e){var t;for(this.buffer+=e,t=this.buffer.indexOf("\n");-1<t;t=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,t)),this.buffer=this.buffer.substring(t+1)},e}(Ts),ks=function(t){function e(){var e;return(e=t.call(this)||this).customParsers=[],e.tagMappers=[],e}_s(e,t);var i=e.prototype;return i.push=function(n){var u,l,c=this;0!==(n=n.trim()).length&&("#"===n[0]?this.tagMappers.reduce(function(e,t){var i=t(n);return i===n?e:e.concat([i])},[n]).forEach(function(e){for(var t=0;t<c.customParsers.length;t++)if(c.customParsers[t].call(c,e))return;if(0===e.indexOf("#EXT"))if(e=e.replace("\r",""),u=/^#EXTM3U/.exec(e))c.trigger("data",{type:"tag",tagType:"m3u"});else{if(u=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(e))return l={type:"tag",tagType:"inf"},u[1]&&(l.duration=parseFloat(u[1])),u[2]&&(l.title=u[2]),void c.trigger("data",l);if(u=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"targetduration"},u[1]&&(l.duration=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#ZEN-TOTAL-DURATION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"totalduration"},u[1]&&(l.duration=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"version"},u[1]&&(l.version=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return l={type:"tag",tagType:"media-sequence"},u[1]&&(l.number=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return l={type:"tag",tagType:"discontinuity-sequence"},u[1]&&(l.number=parseInt(u[1],10)),void c.trigger("data",l);if(u=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(e))return l={type:"tag",tagType:"playlist-type"},u[1]&&(l.playlistType=u[1]),void c.trigger("data",l);if(u=/^#EXT-X-BYTERANGE:?([0-9.]*)?@?([0-9.]*)?/.exec(e))return l={type:"tag",tagType:"byterange"},u[1]&&(l.length=parseInt(u[1],10)),u[2]&&(l.offset=parseInt(u[2],10)),void c.trigger("data",l);if(u=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(e))return l={type:"tag",tagType:"allow-cache"},u[1]&&(l.allowed=!/NO/.test(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-MAP:?(.*)$/.exec(e)){if(l={type:"tag",tagType:"map"},u[1]){var i=bs(u[1]);if(i.URI&&(l.uri=i.URI),i.BYTERANGE){var n=i.BYTERANGE.split("@"),r=n[0],a=n[1];l.byterange={},r&&(l.byterange.length=parseInt(r,10)),a&&(l.byterange.offset=parseInt(a,10))}}c.trigger("data",l)}else if(u=/^#EXT-X-STREAM-INF:?(.*)$/.exec(e)){if(l={type:"tag",tagType:"stream-inf"},u[1]){if(l.attributes=bs(u[1]),l.attributes.RESOLUTION){var s=l.attributes.RESOLUTION.split("x"),o={};s[0]&&(o.width=parseInt(s[0],10)),s[1]&&(o.height=parseInt(s[1],10)),l.attributes.RESOLUTION=o}l.attributes.BANDWIDTH&&(l.attributes.BANDWIDTH=parseInt(l.attributes.BANDWIDTH,10)),l.attributes["PROGRAM-ID"]&&(l.attributes["PROGRAM-ID"]=parseInt(l.attributes["PROGRAM-ID"],10))}c.trigger("data",l)}else{if(u=/^#EXT-X-MEDIA:?(.*)$/.exec(e))return l={type:"tag",tagType:"media"},u[1]&&(l.attributes=bs(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-ENDLIST/.exec(e))c.trigger("data",{type:"tag",tagType:"endlist"});else if(u=/^#EXT-X-DISCONTINUITY/.exec(e))c.trigger("data",{type:"tag",tagType:"discontinuity"});else{if(u=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(e))return l={type:"tag",tagType:"program-date-time"},u[1]&&(l.dateTimeString=u[1],l.dateTimeObject=new Date(u[1])),void c.trigger("data",l);if(u=/^#EXT-X-KEY:?(.*)$/.exec(e))return l={type:"tag",tagType:"key"},u[1]&&(l.attributes=bs(u[1]),l.attributes.IV&&("0x"===l.attributes.IV.substring(0,2).toLowerCase()&&(l.attributes.IV=l.attributes.IV.substring(2)),l.attributes.IV=l.attributes.IV.match(/.{8}/g),l.attributes.IV[0]=parseInt(l.attributes.IV[0],16),l.attributes.IV[1]=parseInt(l.attributes.IV[1],16),l.attributes.IV[2]=parseInt(l.attributes.IV[2],16),l.attributes.IV[3]=parseInt(l.attributes.IV[3],16),l.attributes.IV=new Uint32Array(l.attributes.IV))),void c.trigger("data",l);if(u=/^#EXT-X-START:?(.*)$/.exec(e))return l={type:"tag",tagType:"start"},u[1]&&(l.attributes=bs(u[1]),l.attributes["TIME-OFFSET"]=parseFloat(l.attributes["TIME-OFFSET"]),l.attributes.PRECISE=/YES/.test(l.attributes.PRECISE)),void c.trigger("data",l);if(u=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-out-cont"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);if(u=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-out"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);if(u=/^#EXT-X-CUE-IN:?(.*)?$/.exec(e))return l={type:"tag",tagType:"cue-in"},u[1]?l.data=u[1]:l.data="",void c.trigger("data",l);c.trigger("data",{type:"tag",data:e.slice(4)})}}}else c.trigger("data",{type:"comment",text:e.slice(1)})}):this.trigger("data",{type:"uri",uri:n}))},i.addParser=function(e){var t=this,i=e.expression,n=e.customType,r=e.dataParser,a=e.segment;"function"!=typeof r&&(r=function(e){return e}),this.customParsers.push(function(e){if(i.exec(e))return t.trigger("data",{type:"custom",data:r(e),customType:n,segment:a}),!0})},i.addTagMapper=function(e){var t=e.expression,i=e.map;this.tagMappers.push(function(e){return t.test(e)?i(e):e})},e}(Ts);function Cs(e){return!!e&&"object"==typeof e}function Es(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return t.reduce(function(t,i){return Object.keys(i).forEach(function(e){Array.isArray(t[e])&&Array.isArray(i[e])?t[e]=t[e].concat(i[e]):Cs(t[e])&&Cs(i[e])?t[e]=Es(t[e],i[e]):t[e]=i[e]}),t},{})}function ws(e){return e.reduce(function(e,t){return e.concat(t)},[])}function As(e){if(!e.length)return[];for(var t=[],i=0;i<e.length;i++)t.push(e[i]);return t}var Ps=function(t){function e(){var e;(e=t.call(this)||this).lineStream=new Ss,e.parseStream=new ks,e.lineStream.pipe(e.parseStream);var r,a,s=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e),o=[],u={},l={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},c=0;return e.manifest={allowCache:!0,discontinuityStarts:[],segments:[]},e.parseStream.on("data",function(t){var i,n;({tag:function(){({"allow-cache":function(){this.manifest.allowCache=t.allowed,"allowed"in t||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange:function(){var e={};"length"in t&&((u.byterange=e).length=t.length,"offset"in t||(this.trigger("info",{message:"defaulting offset to zero"}),t.offset=0)),"offset"in t&&((u.byterange=e).offset=t.offset)},endlist:function(){this.manifest.endList=!0},inf:function(){"mediaSequence"in this.manifest||(this.manifest.mediaSequence=0,this.trigger("info",{message:"defaulting media sequence to zero"})),"discontinuitySequence"in this.manifest||(this.manifest.discontinuitySequence=0,this.trigger("info",{message:"defaulting discontinuity sequence to zero"})),0<t.duration&&(u.duration=t.duration),0===t.duration&&(u.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=o},key:function(){if(t.attributes)if("NONE"!==t.attributes.METHOD)if(t.attributes.URI){if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===t.attributes.KEYFORMAT){return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(t.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===t.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==t.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):t.attributes.KEYID&&"0x"===t.attributes.KEYID.substring(0,2)?void(this.manifest.contentProtection={"com.widevine.alpha":{attributes:{schemeIdUri:t.attributes.KEYFORMAT,keyId:t.attributes.KEYID.substring(2)},pssh:function(e){for(var t=v.atob(e||""),i=new Uint8Array(t.length),n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i}(t.attributes.URI.split(",")[1])}}):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}))}t.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),a={method:t.attributes.METHOD||"AES-128",uri:t.attributes.URI},"undefined"!=typeof t.attributes.IV&&(a.iv=t.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else a=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence":function(){isFinite(t.number)?this.manifest.mediaSequence=t.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+t.number})},"discontinuity-sequence":function(){isFinite(t.number)?(this.manifest.discontinuitySequence=t.number,c=t.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+t.number})},"playlist-type":function(){/VOD|EVENT/.test(t.playlistType)?this.manifest.playlistType=t.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+t.playlist})},map:function(){r={},t.uri&&(r.uri=t.uri),t.byterange&&(r.byterange=t.byterange)},"stream-inf":function(){this.manifest.playlists=o,this.manifest.mediaGroups=this.manifest.mediaGroups||l,t.attributes?(u.attributes||(u.attributes={}),vs(u.attributes,t.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media:function(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||l,t.attributes&&t.attributes.TYPE&&t.attributes["GROUP-ID"]&&t.attributes.NAME){var e=this.manifest.mediaGroups[t.attributes.TYPE];e[t.attributes["GROUP-ID"]]=e[t.attributes["GROUP-ID"]]||{},i=e[t.attributes["GROUP-ID"]],(n={default:/yes/i.test(t.attributes.DEFAULT)}).default?n.autoselect=!0:n.autoselect=/yes/i.test(t.attributes.AUTOSELECT),t.attributes.LANGUAGE&&(n.language=t.attributes.LANGUAGE),t.attributes.URI&&(n.uri=t.attributes.URI),t.attributes["INSTREAM-ID"]&&(n.instreamId=t.attributes["INSTREAM-ID"]),t.attributes.CHARACTERISTICS&&(n.characteristics=t.attributes.CHARACTERISTICS),t.attributes.FORCED&&(n.forced=/yes/i.test(t.attributes.FORCED)),i[t.attributes.NAME]=n}else this.trigger("warn",{message:"ignoring incomplete or missing media group"})},discontinuity:function(){c+=1,u.discontinuity=!0,this.manifest.discontinuityStarts.push(o.length)},"program-date-time":function(){"undefined"==typeof this.manifest.dateTimeString&&(this.manifest.dateTimeString=t.dateTimeString,this.manifest.dateTimeObject=t.dateTimeObject),u.dateTimeString=t.dateTimeString,u.dateTimeObject=t.dateTimeObject},targetduration:function(){!isFinite(t.duration)||t.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+t.duration}):this.manifest.targetDuration=t.duration},totalduration:function(){!isFinite(t.duration)||t.duration<0?this.trigger("warn",{message:"ignoring invalid total duration: "+t.duration}):this.manifest.totalDuration=t.duration},start:function(){t.attributes&&!isNaN(t.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:t.attributes["TIME-OFFSET"],precise:t.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out":function(){u.cueOut=t.data},"cue-out-cont":function(){u.cueOutCont=t.data},"cue-in":function(){u.cueIn=t.data}}[t.tagType]||function(){}).call(s)},uri:function(){u.uri=t.uri,o.push(u),!this.manifest.targetDuration||"duration"in u||(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),u.duration=this.manifest.targetDuration),a&&(u.key=a),u.timeline=c,r&&(u.map=r),u={}},comment:function(){},custom:function(){t.segment?(u.custom=u.custom||{},u.custom[t.customType]=t.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[t.customType]=t.data)}})[t.type].call(s)}),e}_s(e,t);var i=e.prototype;return i.push=function(e){this.lineStream.push(e)},i.end=function(){this.lineStream.push("\n")},i.addParser=function(e){this.parseStream.addParser(e)},i.addTagMapper=function(e){this.parseStream.addTagMapper(e)},e}(Ts),Is="INVALID_NUMBER_OF_PERIOD",Ls="DASH_EMPTY_MANIFEST",Os="DASH_INVALID_XML",xs="NO_BASE_URL",Ds="SEGMENT_TIME_UNSPECIFIED",Us="UNSUPPORTED_UTC_TIMING_SCHEME";
+/*! @name mpd-parser @version 0.8.1 @license Apache-2.0 */function Rs(e,t){return/^[a-z]+:/i.test(t)?t:(/\/\//i.test(e)||(e=eo.buildAbsoluteURL(v.location.href,e)),eo.buildAbsoluteURL(e,t))}function Ms(e){var t=e.baseUrl,i=void 0===t?"":t,n=e.source,r=void 0===n?"":n,a=e.range,s=void 0===a?"":a,o=e.indexRange,u=void 0===o?"":o,l={uri:r,resolvedUri:Rs(i||"",r)};if(s||u){var c=(s||u).split("-"),h=parseInt(c[0],10),d=parseInt(c[1],10);l.byterange={length:d-h+1,offset:h}}return l}function Ns(e){var t=e.type,i=void 0===t?"static":t,n=e.duration,r=e.timescale,a=void 0===r?1:r,s=e.sourceDuration,o=to[i](e),u=function(e,t){for(var i=[],n=e;n<t;n++)i.push(n);return i}(o.start,o.end).map(function(o){return function(e,t){var i=o.duration,n=o.timescale,r=void 0===n?1:n,a=o.periodIndex,s=o.startNumber;return{number:(void 0===s?1:s)+e,duration:i/r,timeline:a,time:t*i}}}(e));if("static"===i){var l=u.length-1;u[l].duration=s-n/a*l}return u}function Bs(e){var t=e.baseUrl,i=e.initialization,n=void 0===i?{}:i,r=e.sourceDuration,a=e.timescale,s=void 0===a?1:a,o=e.indexRange,u=void 0===o?"":o,l=e.duration;if(!t)throw new Error(xs);var c=Ms({baseUrl:t,source:n.sourceURL,range:n.range}),h=Ms({baseUrl:t,source:t,indexRange:u});if(h.map=c,l){var d=Ns(e);d.length&&(h.duration=d[0].duration,h.timeline=d[0].timeline)}else r&&(h.duration=r/s,h.timeline=0);return h.number=0,[h]}function js(e,t,i){for(var n=e.sidx.map?e.sidx.map:null,r=e.sidx.duration,a=e.timeline||0,s=e.sidx.byterange,o=s.offset+s.length,u=t.timescale,l=t.references.filter(function(e){return 1!==e.referenceType}),c=[],h=o+t.firstOffset,d=0;d<l.length;d++){var p=t.references[d],f=p.referencedSize,m=p.subsegmentDuration,g=Bs({baseUrl:i,timescale:u,timeline:a,periodIndex:a,duration:m,sourceDuration:r,indexRange:h+"-"+(h+f-1)})[0];n&&(g.map=n),c.push(g),h+=f}return e.segments=c,e}function Fs(e){return function(t){return Object.keys(t).map(function(e){return t[e]})}(e.reduce(function(e,t){var i,n=t.attributes.id+(t.attributes.lang||"");e[n]?(t.segments[0]&&(t.segments[0].discontinuity=!0),(i=e[n].segments).push.apply(i,t.segments),t.attributes.contentProtection&&(e[n].attributes.contentProtection=t.attributes.contentProtection)):e[n]=t;return e},{})).map(function(e){return e.discontinuityStarts=function(e,n){return e.reduce(function(e,t,i){return t[n]&&e.push(i),e},[])}(e.segments,"discontinuity"),e})}function Hs(e,t){if(void 0===t&&(t={}),!Object.keys(t).length)return e;for(var i in e){var n=e[i];if(n.sidx){var r=n.sidx.uri+"-"+(s=n.sidx.byterange,void 0,o=s.offset+s.length-1,s.offset+"-"+o),a=t[r]&&t[r].sidx;n.sidx&&a&&js(n,a,n.sidx.resolvedUri)}}var s,o;return e}function Vs(e){var t,i=e.attributes,n=e.segments,r=e.sidx,a={attributes:(t={NAME:i.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:i.width,height:i.height},CODECS:i.codecs,BANDWIDTH:i.bandwidth},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1};return i.contentProtection&&(a.contentProtection=i.contentProtection),r&&(a.sidx=r),a}function qs(e,t){var i;if(void 0===t&&(t={}),!e.length)return{};var n=e[0].attributes,r=n.sourceDuration,a=n.minimumUpdatePeriod,s=void 0===a?0:a,o=Fs(e.filter(function(e){var t=e.attributes;return"video/mp4"===t.mimeType||"video"===t.contentType})).map(Vs),u=Fs(e.filter(function(e){var t=e.attributes;return"audio/mp4"===t.mimeType||"audio"===t.contentType})),l=e.filter(function(e){var t=e.attributes;return"text/vtt"===t.mimeType||"text"===t.contentType}),c={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:(i={AUDIO:{},VIDEO:{}},i["CLOSED-CAPTIONS"]={},i.SUBTITLES={},i),uri:"",duration:r,playlists:Hs(o,t),minimumUpdatePeriod:1e3*s};return u.length&&(c.mediaGroups.AUDIO.audio=function(e,s){var o;void 0===s&&(s={});var t=e.reduce(function(e,t){var i=t.attributes.role&&t.attributes.role.value||"",n=t.attributes.lang||"",r="main";if(n){var a=i?" ("+i+")":"";r=t.attributes.lang+a}return e[r]&&e[r].playlists[0].attributes.BANDWIDTH>t.attributes.bandwidth||(e[r]={language:n,autoselect:!0,default:"main"===i,playlists:Hs([function(e){var t,i=e.attributes,n=e.segments,r=e.sidx,a={attributes:(t={NAME:i.id,BANDWIDTH:i.bandwidth,CODECS:i.codecs},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1};return i.contentProtection&&(a.contentProtection=i.contentProtection),r&&(a.sidx=r),a}(t)],s),uri:""},"undefined"==typeof o&&"main"===i&&((o=t).default=!0)),e},{});o||(t[Object.keys(t)[0]].default=!0);return t}(u,t)),l.length&&(c.mediaGroups.SUBTITLES.subs=function(e,n){return void 0===n&&(n={}),e.reduce(function(e,t){var i=t.attributes.lang||"text";return e[i]||(e[i]={language:i,default:!1,autoselect:!1,playlists:Hs([function(e){var t,i=e.attributes,n=e.segments;return"undefined"==typeof n&&(n=[{uri:i.baseUrl,timeline:i.periodIndex,resolvedUri:i.baseUrl||"",duration:i.sourceDuration,number:0}],i.duration=i.sourceDuration),{attributes:(t={NAME:i.id,BANDWIDTH:i.bandwidth},t["PROGRAM-ID"]=1,t),uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:i.baseUrl||"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1}}(t)],n),uri:""}),e},{})}(l,t)),c}function Ws(e,t){for(var i,n,r,a,s,o,u,l,c,h,d,p,f=e.type,m=void 0===f?"static":f,g=e.minimumUpdatePeriod,y=void 0===g?0:g,v=e.media,_=void 0===v?"":v,b=e.sourceDuration,T=e.timescale,S=void 0===T?1:T,k=e.startNumber,C=void 0===k?1:k,E=e.periodIndex,w=[],A=-1,P=0;P<t.length;P++){var I=t[P],L=I.d,O=I.r||0,x=I.t||0;A<0&&(A=x),x&&A<x&&(A=x);var D=void 0;if(O<0){var U=P+1;D=U===t.length?"dynamic"===m&&0<y&&0<_.indexOf("$Number$")?(n=A,r=L,void 0,a=(i=e).NOW,s=i.clientOffset,o=i.availabilityStartTime,u=i.timescale,l=void 0===u?1:u,c=i.start,h=void 0===c?0:c,d=i.minimumUpdatePeriod,p=(a+s)/1e3+(void 0===d?0:d)-(o+h),Math.ceil((p*l-n)/r)):(b*S-A)/L:(t[U].t-A)/L}else D=O+1;for(var R=C+w.length+D,M=C+w.length;M<R;)w.push({number:M,duration:L/S,time:A,timeline:E}),A+=L,M++}return w}function zs(e,t){return e.replace(io,function(a){return function(e,t,i,n){if("$$"===e)return"$";if("undefined"==typeof a[t])return e;var r=""+a[t];return"RepresentationID"===t?r:(n=i?parseInt(n,10):1)<=r.length?r:new Array(n-r.length+1).join("0")+r}}(t))}function $s(i,e){var n={RepresentationID:i.id,Bandwidth:i.bandwidth||0},t=i.initialization,r=void 0===t?{sourceURL:"",range:""}:t,a=Ms({baseUrl:i.baseUrl,source:zs(r.sourceURL,n),range:r.range});return function(e,t){return e.duration||t?e.duration?Ns(e):Ws(e,t):[{number:e.startNumber||1,duration:e.sourceDuration,time:0,timeline:e.periodIndex}]}(i,e).map(function(e){n.Number=e.number,n.Time=e.time;var t=zs(i.media||"",n);return{uri:t,timeline:e.timeline,duration:e.duration,resolvedUri:Rs(i.baseUrl||"",t),map:a,number:e.number}})}function Gs(t,e){var i=t.duration,n=t.segmentUrls,r=void 0===n?[]:n;if(!i&&!e||i&&e)throw new Error(Ds);var a,s=r.map(function(e){return function(e,t){var i=e.baseUrl,n=e.initialization,r=void 0===n?{}:n,a=Ms({baseUrl:i,source:r.sourceURL,range:r.range}),s=Ms({baseUrl:i,source:t.media,range:t.mediaRange});return s.map=a,s}(t,e)});return i&&(a=Ns(t)),e&&(a=Ws(t,e)),a.map(function(e,t){if(s[t]){var i=s[t];return i.timeline=e.timeline,i.duration=e.duration,i.number=e.number,i}}).filter(function(e){return e})}function Xs(e){var t,i,n=e.attributes,r=e.segmentInfo;r.template?(i=$s,t=Es(n,r.template)):r.base?(i=Bs,t=Es(n,r.base)):r.list&&(i=Gs,t=Es(n,r.list));var a={attributes:n};if(!i)return a;var s=i(t,r.timeline);if(t.duration){var o=t,u=o.duration,l=o.timescale,c=void 0===l?1:l;t.duration=u/c}else s.length?t.duration=s.reduce(function(e,t){return Math.max(e,Math.ceil(t.duration))},0):t.duration=0;return a.attributes=t,a.segments=s,r.base&&t.indexRange&&(a.sidx=s[0],a.segments=[]),a}function Ks(e,t){return As(e.childNodes).filter(function(e){return e.tagName===t})}function Ys(e){return e.textContent.trim()}function Qs(e){var t=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(e);if(!t)return 0;var i=t.slice(1),n=i[0],r=i[1],a=i[2],s=i[3],o=i[4],u=i[5];return 31536e3*parseFloat(n||0)+2592e3*parseFloat(r||0)+86400*parseFloat(a||0)+3600*parseFloat(s||0)+60*parseFloat(o||0)+parseFloat(u||0)}function Js(e){return e&&e.attributes?As(e.attributes).reduce(function(e,t){var i=no[t.name]||no.DEFAULT;return e[t.name]=i(t.value),e},{}):{}}var Zs,eo=(function(e,t){var i,c,n,r,h;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/\?#]*\/)*.*?)??(;.*?)?(\?.*?)?(#.*?)?$/,c=/^([^\/?#]*)(.*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g,h={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=h.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=h.normalizePath(n.path),h.buildURLFromParts(n)}var r=h.parseURL(t);if(!r)throw new Error("Error trying to parse relative URL.");if(r.scheme)return i.alwaysNormalize?(r.path=h.normalizePath(r.path),h.buildURLFromParts(r)):t;var a=h.parseURL(e);if(!a)throw new Error("Error trying to parse base URL.");if(!a.netLoc&&a.path&&"/"!==a.path[0]){var s=c.exec(a.path);a.netLoc=s[1],a.path=s[2]}a.netLoc&&!a.path&&(a.path="/");var o={scheme:a.scheme,netLoc:r.netLoc,path:null,params:r.params,query:r.query,fragment:r.fragment};if(!r.netLoc&&(o.netLoc=a.netLoc,"/"!==r.path[0]))if(r.path){var u=a.path,l=u.substring(0,u.lastIndexOf("/")+1)+r.path;o.path=h.normalizePath(l)}else o.path=a.path,r.params||(o.params=a.params,r.query||(o.query=a.query));return null===o.path&&(o.path=i.alwaysNormalize?h.normalizePath(r.path):r.path),h.buildURLFromParts(o)},parseURL:function(e){var t=i.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=h}(Zs={exports:{}},Zs.exports),Zs.exports),to={static:function(e){var t=e.duration,i=e.timescale,n=void 0===i?1:i,r=e.sourceDuration;return{start:0,end:Math.ceil(r/(t/n))}},dynamic:function(e){var t=e.NOW,i=e.clientOffset,n=e.availabilityStartTime,r=e.timescale,a=void 0===r?1:r,s=e.duration,o=e.start,u=void 0===o?0:o,l=e.minimumUpdatePeriod,c=void 0===l?0:l,h=e.timeShiftBufferDepth,d=void 0===h?1/0:h,p=(t+i)/1e3,f=n+u,m=p+c-f,g=Math.ceil(m*a/s),y=Math.floor((p-f-d)*a/s),v=Math.floor((p-f)*a/s);return{start:Math.max(0,y),end:Math.min(g,v)}}},io=/\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g,no={mediaPresentationDuration:function(e){return Qs(e)},availabilityStartTime:function(e){return function(e){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(e)&&(e+="Z"),Date.parse(e)}(e)/1e3},minimumUpdatePeriod:function(e){return Qs(e)},timeShiftBufferDepth:function(e){return Qs(e)},start:function(e){return Qs(e)},width:function(e){return parseInt(e,10)},height:function(e){return parseInt(e,10)},bandwidth:function(e){return parseInt(e,10)},startNumber:function(e){return parseInt(e,10)},timescale:function(e){return parseInt(e,10)},duration:function(e){var t=parseInt(e,10);return isNaN(t)?Qs(e):t},d:function(e){return parseInt(e,10)},t:function(e){return parseInt(e,10)},r:function(e){return parseInt(e,10)},DEFAULT:function(e){return e}};function ro(e,i){return i.length?ws(e.map(function(t){return i.map(function(e){return Rs(t,Ys(e))})})):e}function ao(e){var t=Ks(e,"SegmentTemplate")[0],i=Ks(e,"SegmentList")[0],n=i&&Ks(i,"SegmentURL").map(function(e){return Es({tag:"SegmentURL"},Js(e))}),r=Ks(e,"SegmentBase")[0],a=i||t,s=a&&Ks(a,"SegmentTimeline")[0],o=i||r||t,u=o&&Ks(o,"Initialization")[0],l=t&&Js(t);l&&u?l.initialization=u&&Js(u):l&&l.initialization&&(l.initialization={sourceURL:l.initialization});var c={template:l,timeline:s&&Ks(s,"S").map(function(e){return Js(e)}),list:i&&Es(Js(i),{segmentUrls:n,initialization:Js(u)}),base:r&&Es(Js(r),{initialization:Js(u)})};return Object.keys(c).forEach(function(e){c[e]||delete c[e]}),c}function so(e){return e.reduce(function(e,t){var i=Js(t),n=_o[i.schemeIdUri];if(n){e[n]={attributes:i};var r=Ks(t,"cenc:pssh")[0];if(r){var a=Ys(r),s=a&&function(e){for(var t=v.atob(e),i=new Uint8Array(t.length),n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i}(a);e[n].pssh=s}}return e},{})}function oo(c,h,d){return function(e){var t=Js(e),i=ro(h,Ks(e,"BaseURL")),n=Ks(e,"Role")[0],r={role:Js(n)},a=Es(c,t,r),s=so(Ks(e,"ContentProtection"));Object.keys(s).length&&(a=Es(a,{contentProtection:s}));var o=ao(e),u=Ks(e,"Representation"),l=Es(d,o);return ws(u.map(function(a,s,o){return function(e){var t=Ks(e,"BaseURL"),i=ro(s,t),n=Es(a,Js(e)),r=ao(e);return i.map(function(e){return{segmentInfo:Es(o,r),attributes:Es(n,{baseUrl:e})}})}}(a,i,l)))}}function uo(e,t){void 0===t&&(t={});var i=t,n=i.manifestUri,r=void 0===n?"":n,a=i.NOW,s=void 0===a?Date.now():a,o=i.clientOffset,u=void 0===o?0:o,l=Ks(e,"Period");if(!l.length)throw new Error(Is);var c=Js(e),h=ro([r],Ks(e,"BaseURL"));return c.sourceDuration=c.mediaPresentationDuration||0,c.NOW=s,c.clientOffset=u,ws(l.map(function(l,c){return function(e,t){var i=ro(c,Ks(e,"BaseURL")),n=Js(e),r=parseInt(n.id,10),a=v.isNaN(r)?t:r,s=Es(l,{periodIndex:a}),o=Ks(e,"AdaptationSet"),u=ao(e);return ws(o.map(oo(s,i,u)))}}(c,h)))}function lo(e){if(""===e)throw new Error(Ls);var t=(new v.DOMParser).parseFromString(e,"application/xml"),i=t&&"MPD"===t.documentElement.tagName?t.documentElement:null;if(!i||i&&0<i.getElementsByTagName("parsererror").length)throw new Error(Os);return i}function co(e,t){return void 0===t&&(t={}),qs(function(e){return e.map(Xs)}(uo(lo(e),t)),t.sidxMapping)}function ho(e){return function(e){var t=Ks(e,"UTCTiming")[0];if(!t)return null;var i=Js(t);switch(i.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":i.method="HEAD";break;case"urn:mpeg:dash:utc:http-xsdate:2014":case"urn:mpeg:dash:utc:http-iso:2014":case"urn:mpeg:dash:utc:http-xsdate:2012":case"urn:mpeg:dash:utc:http-iso:2012":i.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":i.method="DIRECT",i.value=Date.parse(i.value);break;case"urn:mpeg:dash:utc:http-ntp:2014":case"urn:mpeg:dash:utc:ntp:2014":case"urn:mpeg:dash:utc:sntp:2014":default:throw new Error(Us)}return i}(lo(e))}var po,fo,mo,go,yo,vo,_o={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"},bo=function(e){return e>>>0},To=function(e){return("00"+e.toString(16)).slice(-2)};mo=function(e){return po(e,["moov","trak"]).reduce(function(e,t){var i,n,r,a,s;return(i=po(t,["tkhd"])[0])?(n=i[0],a=bo(i[r=0===n?12:20]<<24|i[r+1]<<16|i[r+2]<<8|i[r+3]),(s=po(t,["mdia","mdhd"])[0])?(r=0===(n=s[0])?12:20,e[a]=bo(s[r]<<24|s[r+1]<<16|s[r+2]<<8|s[r+3]),e):null):null},{})},go=function(r,e){var t,i,n;return t=po(e,["moof","traf"]),i=[].concat.apply([],t.map(function(n){return po(n,["tfhd"]).map(function(e){var t,i;return t=bo(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),i=r[t]||9e4,(po(n,["tfdt"]).map(function(e){var t,i;return t=e[0],i=bo(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),1===t&&(i*=Math.pow(2,32),i+=bo(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),i})[0]||1/0)/i})})),n=Math.min.apply(null,i),isFinite(n)?n:0},yo=function(e){var t=po(e,["moov","trak"]),o=[];return t.forEach(function(e){var t=po(e,["mdia","hdlr"]),s=po(e,["tkhd"]);t.forEach(function(e,t){var i,n,r=fo(e.subarray(8,12)),a=s[t];"vide"===r&&(n=0===(i=new DataView(a.buffer,a.byteOffset,a.byteLength)).getUint8(0)?i.getUint32(12):i.getUint32(20),o.push(n))})}),o},vo=function(e){var t=po(e,["moov","trak"]),p=[];return t.forEach(function(e){var t,i,n={},r=po(e,["tkhd"])[0];r&&(i=(t=new DataView(r.buffer,r.byteOffset,r.byteLength)).getUint8(0),n.id=0===i?t.getUint32(12):t.getUint32(20));var a=po(e,["mdia","hdlr"])[0];if(a){var s=fo(a.subarray(8,12));n.type="vide"===s?"video":"soun"===s?"audio":s}var o=po(e,["mdia","minf","stbl","stsd"])[0];if(o){var u=o.subarray(8);n.codec=fo(u.subarray(4,8));var l,c=po(u,[n.codec])[0];c&&(/^[a-z]vc[1-9]$/i.test(n.codec)?(l=c.subarray(78),"avcC"===fo(l.subarray(4,8))&&11<l.length?(n.codec+=".",n.codec+=To(l[9]),n.codec+=To(l[10]),n.codec+=To(l[11])):n.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(n.codec)&&(l=c.subarray(28),"esds"===fo(l.subarray(4,8))&&20<l.length&&0!==l[19]?(n.codec+="."+To(l[19]),n.codec+="."+To(l[20]>>>2&63).replace(/^0/,"")):n.codec="mp4a.40.2"))}var h=po(e,["mdia","mdhd"])[0];if(h&&r){var d=0===i?12:20;n.timescale=bo(h[d]<<24|h[1+d]<<16|h[2+d]<<8|h[3+d])}p.push(n)}),p};function So(e){return new Date(1e3*e-20828448e5)}function ko(e){return{isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}}function Co(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){var i;return!!a[e]&&(i=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(i,1),-1<i)},this.trigger=function(e){var t,i,n,r;if(t=a[e])if(2===arguments.length)for(n=t.length,i=0;i<n;++i)t[i].call(this,arguments[1]);else{for(r=[],i=arguments.length,i=1;i<arguments.length;++i)r.push(arguments[i]);for(n=t.length,i=0;i<n;++i)t[i].apply(this,r)}},this.dispose=function(){a={}}}}var Eo,wo,Ao={findBox:po=function(e,t){var i,n,r,a,s,o=[];if(!t.length)return null;for(i=0;i<e.byteLength;)n=bo(e[i]<<24|e[i+1]<<16|e[i+2]<<8|e[i+3]),r=fo(e.subarray(i+4,i+8)),a=1<n?i+n:e.byteLength,r===t[0]&&(1===t.length?o.push(e.subarray(i+8,a)):(s=po(e.subarray(i+8,a),t.slice(1))).length&&(o=o.concat(s))),i=a;return o},parseType:fo=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),t+=String.fromCharCode(e[2]),t+=String.fromCharCode(e[3])},timescale:mo,startTime:go,videoTrackIds:yo,tracks:vo},Po=Ao.parseType,Io={avc1:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{dataReferenceIndex:t.getUint16(6),width:t.getUint16(24),height:t.getUint16(26),horizresolution:t.getUint16(28)+t.getUint16(30)/16,vertresolution:t.getUint16(32)+t.getUint16(34)/16,frameCount:t.getUint16(40),depth:t.getUint16(74),config:Eo(e.subarray(78,e.byteLength))}},avcC:function(e){var t,i,n,r,a=new DataView(e.buffer,e.byteOffset,e.byteLength),s={configurationVersion:e[0],avcProfileIndication:e[1],profileCompatibility:e[2],avcLevelIndication:e[3],lengthSizeMinusOne:3&e[4],sps:[],pps:[]},o=31&e[5];for(n=6,r=0;r<o;r++)i=a.getUint16(n),n+=2,s.sps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;for(t=e[n],n++,r=0;r<t;r++)i=a.getUint16(n),n+=2,s.pps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;return s},btrt:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{bufferSizeDB:t.getUint32(0),maxBitrate:t.getUint32(4),avgBitrate:t.getUint32(8)}},esds:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),esId:e[6]<<8|e[7],streamPriority:31&e[8],decoderConfig:{objectProfileIndication:e[11],streamType:e[12]>>>2&63,bufferSize:e[13]<<16|e[14]<<8|e[15],maxBitrate:e[16]<<24|e[17]<<16|e[18]<<8|e[19],avgBitrate:e[20]<<24|e[21]<<16|e[22]<<8|e[23],decoderConfigDescriptor:{tag:e[24],length:e[25],audioObjectType:e[26]>>>3&31,samplingFrequencyIndex:(7&e[26])<<1|e[27]>>>7&1,channelConfiguration:e[27]>>>3&15}}}},ftyp:function(e){for(var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={majorBrand:Po(e.subarray(0,4)),minorVersion:t.getUint32(4),compatibleBrands:[]},n=8;n<e.byteLength;)i.compatibleBrands.push(Po(e.subarray(n,n+4))),n+=4;return i},dinf:function(e){return{boxes:Eo(e)}},dref:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),dataReferences:Eo(e.subarray(8))}},hdlr:function(e){var t={version:new DataView(e.buffer,e.byteOffset,e.byteLength).getUint8(0),flags:new Uint8Array(e.subarray(1,4)),handlerType:Po(e.subarray(8,12)),name:""},i=8;for(i=24;i<e.byteLength;i++){if(0===e[i]){i++;break}t.name+=String.fromCharCode(e[i])}return t.name=decodeURIComponent(escape(t.name)),t},mdat:function(e){return{byteLength:e.byteLength,nals:function(e){var t,i,n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=[];for(t=0;t+4<e.length;t+=i)if(i=n.getUint32(t),t+=4,i<=0)r.push("<span style='color:red;'>MALFORMED DATA</span>");else switch(31&e[t]){case 1:r.push("slice_layer_without_partitioning_rbsp");break;case 5:r.push("slice_layer_without_partitioning_rbsp_idr");break;case 6:r.push("sei_rbsp");break;case 7:r.push("seq_parameter_set_rbsp");break;case 8:r.push("pic_parameter_set_rbsp");break;case 9:r.push("access_unit_delimiter_rbsp");break;default:r.push("UNKNOWN NAL - "+e[t]&31)}return r}(e)}},mdhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=4,r={version:i.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),language:""};return 1===r.version?(n+=4,r.creationTime=So(i.getUint32(n)),n+=8,r.modificationTime=So(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=8):(r.creationTime=So(i.getUint32(n)),n+=4,r.modificationTime=So(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=4),r.duration=i.getUint32(n),n+=4,t=i.getUint16(n),r.language+=String.fromCharCode(96+(t>>10)),r.language+=String.fromCharCode(96+((992&t)>>5)),r.language+=String.fromCharCode(96+(31&t)),r},mdia:function(e){return{boxes:Eo(e)}},mfhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sequenceNumber:e[4]<<24|e[5]<<16|e[6]<<8|e[7]}},minf:function(e){return{boxes:Eo(e)}},mp4a:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={dataReferenceIndex:t.getUint16(6),channelcount:t.getUint16(16),samplesize:t.getUint16(18),samplerate:t.getUint16(24)+t.getUint16(26)/65536};return 28<e.byteLength&&(i.streamDescriptor=Eo(e.subarray(28))[0]),i},moof:function(e){return{boxes:Eo(e)}},moov:function(e){return{boxes:Eo(e)}},mvex:function(e){return{boxes:Eo(e)}},mvhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=So(t.getUint32(i)),i+=8,n.modificationTime=So(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=8):(n.creationTime=So(t.getUint32(i)),i+=4,n.modificationTime=So(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=4),n.duration=t.getUint32(i),i+=4,n.rate=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,i+=8,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,i+=24,n.nextTrackId=t.getUint32(i),n},pdin:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),rate:t.getUint32(4),initialDelay:t.getUint32(8)}},sdtp:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]};for(t=4;t<e.byteLength;t++)i.samples.push({dependsOn:(48&e[t])>>4,isDependedOn:(12&e[t])>>2,hasRedundancy:3&e[t]});return i},sidx:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),references:[],referenceId:i.getUint32(4),timescale:i.getUint32(8),earliestPresentationTime:i.getUint32(12),firstOffset:i.getUint32(16)},r=i.getUint16(22);for(t=24;r;t+=12,r--)n.references.push({referenceType:(128&e[t])>>>7,referencedSize:2147483647&i.getUint32(t),subsegmentDuration:i.getUint32(t+4),startsWithSap:!!(128&e[t+8]),sapType:(112&e[t+8])>>>4,sapDeltaTime:268435455&i.getUint32(t+8)});return n},smhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),balance:e[4]+e[5]/256}},stbl:function(e){return{boxes:Eo(e)}},stco:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),chunkOffsets:[]},r=i.getUint32(4);for(t=8;r;t+=4,r--)n.chunkOffsets.push(i.getUint32(t));return n},stsc:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=i.getUint32(4),r={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleToChunks:[]};for(t=8;n;t+=12,n--)r.sampleToChunks.push({firstChunk:i.getUint32(t),samplesPerChunk:i.getUint32(t+4),sampleDescriptionIndex:i.getUint32(t+8)});return r},stsd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleDescriptions:Eo(e.subarray(8))}},stsz:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleSize:i.getUint32(4),entries:[]};for(t=12;t<e.byteLength;t+=4)n.entries.push(i.getUint32(t));return n},stts:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),timeToSamples:[]},r=i.getUint32(4);for(t=8;r;t+=8,r--)n.timeToSamples.push({sampleCount:i.getUint32(t),sampleDelta:i.getUint32(t+4)});return n},styp:function(e){return Io.ftyp(e)},tfdt:function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4)),baseMediaDecodeTime:e[4]<<24|e[5]<<16|e[6]<<8|e[7]};return 1===t.version&&(t.baseMediaDecodeTime*=Math.pow(2,32),t.baseMediaDecodeTime+=e[8]<<24|e[9]<<16|e[10]<<8|e[11]),t},tfhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:i.getUint32(4)},r=1&n.flags[2],a=2&n.flags[2],s=8&n.flags[2],o=16&n.flags[2],u=32&n.flags[2],l=65536&n.flags[0],c=131072&n.flags[0];return t=8,r&&(t+=4,n.baseDataOffset=i.getUint32(12),t+=4),a&&(n.sampleDescriptionIndex=i.getUint32(t),t+=4),s&&(n.defaultSampleDuration=i.getUint32(t),t+=4),o&&(n.defaultSampleSize=i.getUint32(t),t+=4),u&&(n.defaultSampleFlags=i.getUint32(t)),l&&(n.durationIsEmpty=!0),!r&&c&&(n.baseDataOffsetIsMoof=!0),n},tkhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=So(t.getUint32(i)),i+=8,n.modificationTime=So(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=8):(n.creationTime=So(t.getUint32(i)),i+=4,n.modificationTime=So(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=4),n.duration=t.getUint32(i),i+=4,i+=8,n.layer=t.getUint16(i),i+=2,n.alternateGroup=t.getUint16(i),i+=2,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,n.width=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.height=t.getUint16(i)+t.getUint16(i+2)/16,n},traf:function(e){return{boxes:Eo(e)}},trak:function(e){return{boxes:Eo(e)}},trex:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:t.getUint32(4),defaultSampleDescriptionIndex:t.getUint32(8),defaultSampleDuration:t.getUint32(12),defaultSampleSize:t.getUint32(16),sampleDependsOn:3&e[20],sampleIsDependedOn:(192&e[21])>>6,sampleHasRedundancy:(48&e[21])>>4,samplePaddingValue:(14&e[21])>>1,sampleIsDifferenceSample:!!(1&e[21]),sampleDegradationPriority:t.getUint16(22)}},trun:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]},n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=1&i.flags[2],a=4&i.flags[2],s=1&i.flags[1],o=2&i.flags[1],u=4&i.flags[1],l=8&i.flags[1],c=n.getUint32(4),h=8;for(r&&(i.dataOffset=n.getInt32(h),h+=4),a&&c&&(t={flags:ko(e.subarray(h,h+4))},h+=4,s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t),c--);c--;)t={},s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),u&&(t.flags=ko(e.subarray(h,h+4)),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t);return i},"url ":function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4))}},vmhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),graphicsmode:t.getUint16(4),opcolor:new Uint16Array([t.getUint16(6),t.getUint16(8),t.getUint16(10)])}}},Lo={inspect:Eo=function(e){for(var t,i,n,r,a,s=0,o=[],u=new ArrayBuffer(e.length),l=new Uint8Array(u),c=0;c<e.length;++c)l[c]=e[c];for(t=new DataView(u);s<e.byteLength;)i=t.getUint32(s),n=Po(e.subarray(s+4,s+8)),r=1<i?s+i:e.byteLength,(a=(Io[n]||function(e){return{data:e}})(e.subarray(s+8,r))).size=i,a.type=n,o.push(a),s=r;return o},textify:wo=function(e,t){var a;return t=t||0,a=new Array(2*t+1).join(" "),e.map(function(r,e){return a+r.type+"\n"+Object.keys(r).filter(function(e){return"type"!==e&&"boxes"!==e}).map(function(e){var t=a+" "+e+": ",i=r[e];if(i instanceof Uint8Array||i instanceof Uint32Array){var n=Array.prototype.slice.call(new Uint8Array(i.buffer,i.byteOffset,i.byteLength)).map(function(e){return" "+("00"+e.toString(16)).slice(-2)}).join("").match(/.{1,24}/g);return n?1===n.length?t+"<"+n.join("").slice(1)+">":t+"<\n"+n.map(function(e){return a+" "+e}).join("\n")+"\n"+a+" >":t+"<>"}return t+JSON.stringify(i,null,2).split("\n").map(function(e,t){return 0===t?e:a+" "+e}).join("\n")}).join("\n")+(r.boxes?"\n"+wo(r.boxes,t+1):"")}).join("\n")},parseTfdt:Io.tfdt,parseHdlr:Io.hdlr,parseTfhd:Io.tfhd,parseTrun:Io.trun,parseSidx:Io.sidx},Oo=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}t+=r,r=n=0}return i},xo=function(e){return 181!==e.payload[0]?null:49!=(e.payload[1]<<8|e.payload[2])?null:"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])?null:3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},Do=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},Uo=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},Ro=4;Co.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),this.on("partialdone",function(e){t.partialFlush(e)}),this.on("endedtimeline",function(e){t.endTimeline(e)}),this.on("reset",function(e){t.reset(e)}),t},Co.prototype.push=function(e){this.trigger("data",e)},Co.prototype.flush=function(e){this.trigger("done",e)},Co.prototype.partialFlush=function(e){this.trigger("partialdone",e)},Co.prototype.endTimeline=function(e){this.trigger("endedtimeline",e)},Co.prototype.reset=function(e){this.trigger("reset",e)};function Mo(){Mo.prototype.init.call(this),this.captionPackets_=[],this.ccStreams_=[new Vo(0,0),new Vo(0,1),new Vo(1,0),new Vo(1,1)],this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("partialdone",this.trigger.bind(this,"partialdone")),e.on("done",this.trigger.bind(this,"done"))},this)}var No=Co;(Mo.prototype=new No).push=function(e){var t,i,n;if("sei_rbsp"===e.nalUnitType&&(t=Oo(e.escapedRBSP)).payloadType===Ro&&(i=xo(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));n=Do(e.pts,i),this.captionPackets_=this.captionPackets_.concat(n),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},Mo.prototype.flushCCStreams=function(t){this.ccStreams_.forEach(function(e){return"flush"===t?e.flush():e.partialFlush()},this)},Mo.prototype.flushStream=function(e){this.captionPackets_.length&&(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2&&this.dispatchCea608Packet(e)},this),this.captionPackets_.length=0),this.flushCCStreams(e)},Mo.prototype.flush=function(){return this.flushStream("flush")},Mo.prototype.partialFlush=function(){return this.flushStream("partialFlush")},Mo.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},Mo.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},Mo.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},Mo.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},Mo.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)};function Bo(e){return null===e?"":(e=Fo[e]||e,String.fromCharCode(e))}function jo(){for(var e=[],t=15;t--;)e.push("");return e}var Fo={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},Ho=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Vo=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a;if((t=32639&e.ccData)!==this.lastControlCode_){if(4096==(61440&t)?this.lastControlCode_=t:t!==this.PADDING_&&(this.lastControlCode_=null),n=t>>>8,r=255&t,t!==this.PADDING_)if(t===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(t===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),i=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=i,this.startPts_=e.pts;else if(t===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(e.pts);else if(t===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(e.pts);else if(t===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(e.pts);else if(t===this.CARRIAGE_RETURN_)this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts;else if(t===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1);else if(t===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(e.pts),this.displayed_=jo();else if(t===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=jo();else if(t===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=jo()),this.mode_="paintOn",this.startPts_=e.pts;else if(this.isSpecialCharacter(n,r))a=Bo((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isExtCharacter(n,r))"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),a=Bo((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isMidRowCode(n,r))this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&r)&&this.addFormatting(e.pts,["i"]),1==(1&r)&&this.addFormatting(e.pts,["u"]);else if(this.isOffsetControlCode(n,r))this.column_+=3&r;else if(this.isPAC(n,r)){var s=Ho.indexOf(7968&t);"rollUp"===this.mode_&&(s-this.rollUpRows_+1<0&&(s=this.rollUpRows_-1),this.setRollUp(e.pts,s)),s!==this.row_&&(this.clearFormatting(e.pts),this.row_=s),1&r&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&t)&&(this.column_=4*((14&t)>>1)),this.isColorPAC(r)&&14==(14&r)&&this.addFormatting(e.pts,["i"])}else this.isNormalChar(n)&&(0===r&&(r=null),a=Bo(n),a+=Bo(r),this[this.mode_](e.pts,a),this.column_+=a.length)}else this.lastControlCode_=null}};Vo.prototype=new No,Vo.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e){try{return e.trim()}catch(e){return""}}).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_})},Vo.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=jo(),this.nonDisplayed_=jo(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Vo.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},Vo.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},Vo.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},Vo.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},Vo.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},Vo.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},Vo.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},Vo.prototype.isNormalChar=function(e){return 32<=e&&e<=127},Vo.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=jo(),this.displayed_=jo()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},Vo.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);var i=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,i)},Vo.prototype.clearFormatting=function(e){if(this.formatting_.length){var t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},"");this.formatting_=[],this[this.mode_](e,t)}},Vo.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];i+=t,this.nonDisplayed_[this.row_]=i},Vo.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i},Vo.prototype.shiftRowsUp_=function(){var e;for(e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},Vo.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i};function qo(e,t){for(var i=e,n=0;n<t.length;n++){var r=t[n];if(i<r.size)return r;i-=r.size}return null}function Wo(e,c){var n=Ao.findBox(e,["moof","traf"]),t=Ao.findBox(e,["mdat"]),h={},r=[];return t.forEach(function(e,t){var i=n[t];r.push({mdat:e,traf:i})}),r.forEach(function(e){var t,i=e.mdat,n=e.traf,r=Ao.findBox(n,["tfhd"]),a=Lo.parseTfhd(r[0]),s=a.trackId,o=Ao.findBox(n,["tfdt"]),u=0<o.length?Lo.parseTfdt(o[0]).baseMediaDecodeTime:0,l=Ao.findBox(n,["trun"]);c===s&&0<l.length&&(t=function(e,t,i){var n,r,a,s,o=new DataView(e.buffer,e.byteOffset,e.byteLength),u=[];for(r=0;r+4<e.length;r+=a)if(a=o.getUint32(r),r+=4,!(a<=0))switch(31&e[r]){case 6:var l=e.subarray(r+1,r+1+a),c=qo(r,t);n={nalUnitType:"sei_rbsp",size:a,data:l,escapedRBSP:$o(l),trackId:i},c?(n.pts=c.pts,n.dts=c.dts,s=c):(n.pts=s.pts,n.dts=s.dts),u.push(n)}return u}(i,function(e,t,i){var n=t,r=i.defaultSampleDuration||0,a=i.defaultSampleSize||0,s=i.trackId,o=[];return e.forEach(function(e){var t=Lo.parseTrun(e).samples;t.forEach(function(e){void 0===e.duration&&(e.duration=r),void 0===e.size&&(e.size=a),e.trackId=s,e.dts=n,void 0===e.compositionTimeOffset&&(e.compositionTimeOffset=0),e.pts=n+e.compositionTimeOffset,n+=e.duration}),o=o.concat(t)}),o}(l,u,a),s),h[s]||(h[s]=[]),h[s]=h[s].concat(t))}),h}function zo(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}var $o=Uo,Go=Mo,Xo=function(){var t,a,s,o,u,i,n=!1;this.isInitialized=function(){return n},this.init=function(e){t=new Go,n=!0,i=!!e&&e.isPartial,t.on("data",function(e){e.startTime=e.startPts/o,e.endTime=e.endPts/o,u.captions.push(e),u.captionStreams[e.stream]=!0})},this.isNewInit=function(e,t){return!(e&&0===e.length||t&&"object"==typeof t&&0===Object.keys(t).length)&&(s!==e[0]||o!==t[s])},this.parse=function(e,t,i){var n;if(!this.isInitialized())return null;if(!t||!i)return null;if(this.isNewInit(t,i))s=t[0],o=i[s];else if(null===s||!o)return a.push(e),null;for(;0<a.length;){var r=a.shift();this.parse(r,t,i)}return null!==(n=function(e,t,i){return null===t?null:{seiNals:Wo(e,t)[t],timescale:i}}(e,s,o))&&n.seiNals?(this.pushNals(n.seiNals),this.flushStream(),u):null},this.pushNals=function(e){if(!this.isInitialized()||!e||0===e.length)return null;e.forEach(function(e){t.push(e)})},this.flushStream=function(){if(!this.isInitialized())return null;i?t.partialFlush():t.flush()},this.clearParsedCaptions=function(){u.captions=[],u.captionStreams={}},this.resetCaptionStream=function(){if(!this.isInitialized())return null;t.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){a=[],o=s=null,u?this.clearParsedCaptions():u={captions:[],captionStreams:{}},this.resetCaptionStream()},this.reset()},Ko=27,Yo=15,Qo=21;new No;function Jo(e){var t=31&e[1];return t<<=8,t|=e[2]}function Zo(e){return!!(64&e[1])}function eu(e){var t=0;return 1<(48&e[3])>>>4&&(t+=e[4]+1),t}function tu(e){switch(e){case 5:return"slice_layer_without_partitioning_rbsp_idr";case 6:return"sei_rbsp";case 7:return"seq_parameter_set_rbsp";case 8:return"pic_parameter_set_rbsp";case 9:return"access_unit_delimiter_rbsp";default:return null}}function iu(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var nu,ru,au,su,ou={parseType:function(e,t){var i=Jo(e);return 0===i?"pat":i===t?"pmt":t?"pes":null},parsePat:function(e){var t=Zo(e),i=4+eu(e);return t&&(i+=e[i]+1),(31&e[i+10])<<8|e[i+11]},parsePmt:function(e){var t={},i=Zo(e),n=4+eu(e);if(i&&(n+=e[n]+1),1&e[n+5]){var r;r=3+((15&e[n+1])<<8|e[n+2])-4;for(var a=12+((15&e[n+10])<<8|e[n+11]);a<r;){var s=n+a;t[(31&e[s+1])<<8|e[s+2]]=e[s],a+=5+((15&e[s+3])<<8|e[s+4])}return t}},parsePayloadUnitStartIndicator:Zo,parsePesType:function(e,t){switch(t[Jo(e)]){case Ko:return"video";case Yo:return"audio";case Qo:return"timed-metadata";default:return null}},parsePesTime:function(e){if(!Zo(e))return null;var t=4+eu(e);if(t>=e.byteLength)return null;var i,n=null;return 192&(i=e[t+7])&&((n={}).pts=(14&e[t+9])<<27|(255&e[t+10])<<20|(254&e[t+11])<<12|(255&e[t+12])<<5|(254&e[t+13])>>>3,n.pts*=4,n.pts+=(6&e[t+13])>>>1,n.dts=n.pts,64&i&&(n.dts=(14&e[t+14])<<27|(255&e[t+15])<<20|(254&e[t+16])<<12|(255&e[t+17])<<5|(254&e[t+18])>>>3,n.dts*=4,n.dts+=(6&e[t+18])>>>1)),n},videoPacketContainsKeyFrame:function(e){for(var t=4+eu(e),i=e.subarray(t),n=0,r=0,a=!1;r<i.byteLength-3;r++)if(1===i[r+2]){n=r+5;break}for(;n<i.byteLength;)switch(i[n]){case 0:if(0!==i[n-1]){n+=2;break}if(0!==i[n-2]){n++;break}for(r+3!==n-2&&"slice_layer_without_partitioning_rbsp_idr"===tu(31&i[r+3])&&(a=!0);1!==i[++n]&&n<i.length;);r=n-2,n+=3;break;case 1:if(0!==i[n-1]||0!==i[n-2]){n+=3;break}"slice_layer_without_partitioning_rbsp_idr"===tu(31&i[r+3])&&(a=!0),r=n-2,n+=3;break;default:n+=3}return i=i.subarray(r),n-=r,r=0,i&&3<i.byteLength&&"slice_layer_without_partitioning_rbsp_idr"===tu(31&i[r+3])&&(a=!0),a}},uu=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],lu={isLikelyAacData:function(e){return e[0]==="I".charCodeAt(0)&&e[1]==="D".charCodeAt(0)&&e[2]==="3".charCodeAt(0)},parseId3TagSize:function(e,t){var i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&e[t+5])>>4?20+i:10+i},parseAdtsSize:function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i},parseType:function(e,t){return e[t]==="I".charCodeAt(0)&&e[t+1]==="D".charCodeAt(0)&&e[t+2]==="3".charCodeAt(0)?"timed-metadata":!0&e[t]&&240==(240&e[t+1])?"audio":null},parseSampleRate:function(e){for(var t=0;t+5<e.length;){if(255===e[t]&&240==(246&e[t+1]))return uu[(60&e[t+2])>>>2];t++}return null},parseAacTimestamp:function(e){var t,i,n;t=10,64&e[5]&&(t+=4,t+=iu(e.subarray(10,14)));do{if((i=iu(e.subarray(t+4,t+8)))<1)return null;if("PRIV"===String.fromCharCode(e[t],e[t+1],e[t+2],e[t+3])){n=e.subarray(t+10,t+i+10);for(var r=0;r<n.byteLength;r++)if(0===n[r]){if("com.apple.streaming.transportStreamTimestamp"!==unescape(function(e,t,i){var n,r="";for(n=t;n<i;n++)r+="%"+("00"+e[n].toString(16)).slice(-2);return r}(n,0,r)))break;var a=n.subarray(r+1),s=(1&a[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2;return s*=4,s+=3&a[7]}}t+=10,t+=i}while(t<e.byteLength);return null}},cu=9e4,hu=(nu=function(e){return 9e4*e},ru=function(e,t){return e*t},au=function(e){return e/9e4},su=function(e,t){return e/t},zo),du={};du.ts=ou,du.aac=lu;function pu(e,t,i){for(var n,r,a,s,o=0,u=yu,l=!1;u<=e.byteLength;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o++,u++;else{switch(n=e.subarray(o,u),du.ts.parseType(n,t.pid)){case"pes":r=du.ts.parsePesType(n,t.table),a=du.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=du.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)}if(l)break;o+=yu,u+=yu}for(o=(u=e.byteLength)-yu,l=!1;0<=o;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o--,u--;else{switch(n=e.subarray(o,u),du.ts.parseType(n,t.pid)){case"pes":r=du.ts.parsePesType(n,t.table),a=du.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=du.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)}if(l)break;o-=yu,u-=yu}}function fu(e,t,i){for(var n,r,a,s,o,u,l,c=0,h=yu,d=!1,p={data:[],size:0};h<e.byteLength;)if(71!==e[c]||71!==e[h])c++,h++;else{switch(n=e.subarray(c,h),du.ts.parseType(n,t.pid)){case"pes":if(r=du.ts.parsePesType(n,t.table),a=du.ts.parsePayloadUnitStartIndicator(n),"video"===r&&(a&&!d&&(s=du.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),d=!0),!i.firstKeyFrame)){if(a&&0!==p.size){for(o=new Uint8Array(p.size),u=0;p.data.length;)l=p.data.shift(),o.set(l,u),u+=l.byteLength;if(du.ts.videoPacketContainsKeyFrame(o)){var f=du.ts.parsePesTime(o);f&&(i.firstKeyFrame=f,i.firstKeyFrame.type="video")}p.size=0}p.data.push(n),p.size+=n.byteLength}}if(d&&i.firstKeyFrame)break;c+=yu,h+=yu}for(c=(h=e.byteLength)-yu,d=!1;0<=c;)if(71!==e[c]||71!==e[h])c--,h--;else{switch(n=e.subarray(c,h),du.ts.parseType(n,t.pid)){case"pes":r=du.ts.parsePesType(n,t.table),a=du.ts.parsePayloadUnitStartIndicator(n),"video"===r&&a&&(s=du.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),d=!0)}if(d)break;c-=yu,h-=yu}}function mu(e){var t={pid:null,table:null},i={};for(var n in function(e,t){for(var i,n=0,r=yu;r<e.byteLength;)if(71!==e[n]||71!==e[r])n++,r++;else{switch(i=e.subarray(n,r),du.ts.parseType(i,t.pid)){case"pat":t.pid||(t.pid=du.ts.parsePat(i));break;case"pmt":t.table||(t.table=du.ts.parsePmt(i))}if(t.pid&&t.table)return;n+=yu,r+=yu}}(e,t),t.table){if(t.table.hasOwnProperty(n))switch(t.table[n]){case Ko:i.video=[],fu(e,t,i),0===i.video.length&&delete i.video;break;case Yo:i.audio=[],pu(e,t,i),0===i.audio.length&&delete i.audio}}return i}var gu=cu,yu=188,vu=function(e,t){var i;return(i=du.aac.isLikelyAacData(e)?function(e){for(var t,i=!1,n=0,r=null,a=null,s=0,o=0;3<=e.length-o;){switch(du.aac.parseType(e,o)){case"timed-metadata":if(e.length-o<10){i=!0;break}if((s=du.aac.parseId3TagSize(e,o))>e.length){i=!0;break}null===a&&(t=e.subarray(o,o+s),a=du.aac.parseAacTimestamp(t)),o+=s;break;case"audio":if(e.length-o<7){i=!0;break}if((s=du.aac.parseAdtsSize(e,o))>e.length){i=!0;break}null===r&&(t=e.subarray(o,o+s),r=du.aac.parseSampleRate(t)),n++,o+=s;break;default:o++}if(i)return null}if(null===r||null===a)return null;var u=gu/r;return{audio:[{type:"audio",dts:a,pts:a},{type:"audio",dts:a+1024*n*u,pts:a+1024*n*u}]}}(e):mu(e))&&(i.audio||i.video)?(function(e,t){if(e.audio&&e.audio.length){var i=t;"undefined"==typeof i&&(i=e.audio[0].dts),e.audio.forEach(function(e){e.dts=hu(e.dts,i),e.pts=hu(e.pts,i),e.dtsTime=e.dts/gu,e.ptsTime=e.pts/gu})}if(e.video&&e.video.length){var n=t;if("undefined"==typeof n&&(n=e.video[0].dts),e.video.forEach(function(e){e.dts=hu(e.dts,n),e.pts=hu(e.pts,n),e.dtsTime=e.dts/gu,e.ptsTime=e.pts/gu}),e.firstKeyFrame){var r=e.firstKeyFrame;r.dts=hu(r.dts,n),r.pts=hu(r.pts,n),r.dtsTime=r.dts/gu,r.ptsTime=r.dts/gu}}}(i,t),i):null};function _u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var bu=function(e,t,i){return t&&Tu(e.prototype,t),i&&Tu(e,i),e};function Tu(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}var Su=null,ku=(Cu.prototype.decrypt=function(e,t,i,n,r,a){var s=this._key[1],o=e^s[0],u=n^s[1],l=i^s[2],c=t^s[3],h=void 0,d=void 0,p=void 0,f=s.length/4-2,m=void 0,g=4,y=this._tables[1],v=y[0],_=y[1],b=y[2],T=y[3],S=y[4];for(m=0;m<f;m++)h=v[o>>>24]^_[u>>16&255]^b[l>>8&255]^T[255&c]^s[g],d=v[u>>>24]^_[l>>16&255]^b[c>>8&255]^T[255&o]^s[g+1],p=v[l>>>24]^_[c>>16&255]^b[o>>8&255]^T[255&u]^s[g+2],c=v[c>>>24]^_[o>>16&255]^b[u>>8&255]^T[255&l]^s[g+3],g+=4,o=h,u=d,l=p;for(m=0;m<4;m++)r[(3&-m)+a]=S[o>>>24]<<24^S[u>>16&255]<<16^S[l>>8&255]<<8^S[255&c]^s[g++],h=o,o=u,u=l,l=c,c=h},Cu);function Cu(e){_u(this,Cu),Su=Su||function(){var e=[[[],[],[],[],[]],[[],[],[],[],[]]],t=e[0],i=e[1],n=t[4],r=i[4],a=void 0,s=void 0,o=void 0,u=[],l=[],c=void 0,h=void 0,d=void 0,p=void 0,f=void 0;for(a=0;a<256;a++)l[(u[a]=a<<1^283*(a>>7))^a]=a;for(s=o=0;!n[s];s^=c||1,o=l[o]||1)for(d=(d=o^o<<1^o<<2^o<<3^o<<4)>>8^255&d^99,f=16843009*u[h=u[c=u[r[n[s]=d]=s]]]^65537*h^257*c^16843008*s,p=257*u[d]^16843008*d,a=0;a<4;a++)t[a][s]=p=p<<24^p>>>8,i[a][d]=f=f<<24^f>>>8;for(a=0;a<5;a++)t[a]=t[a].slice(0),i[a]=i[a].slice(0);return e}(),this._tables=[[Su[0][0].slice(),Su[0][1].slice(),Su[0][2].slice(),Su[0][3].slice(),Su[0][4].slice()],[Su[1][0].slice(),Su[1][1].slice(),Su[1][2].slice(),Su[1][3].slice(),Su[1][4].slice()]];var t=void 0,i=void 0,n=void 0,r=void 0,a=void 0,s=this._tables[0][4],o=this._tables[1],u=e.length,l=1;if(4!==u&&6!==u&&8!==u)throw new Error("Invalid aes key size");for(r=e.slice(0),a=[],this._key=[r,a],t=u;t<4*u+28;t++)n=r[t-1],(t%u==0||8===u&&t%u==4)&&(n=s[n>>>24]<<24^s[n>>16&255]<<16^s[n>>8&255]<<8^s[255&n],t%u==0&&(n=n<<8^n>>>24^l<<24,l=l<<1^283*(l>>7))),r[t]=r[t-u]^n;for(i=0;t;i++,t--)n=r[3&i?t:t-4],a[i]=t<=4||i<4?n:o[0][s[n>>>24]]^o[1][s[n>>16&255]]^o[2][s[n>>8&255]]^o[3][s[255&n]]}var Eu=(wu.prototype.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},wu.prototype.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},wu.prototype.trigger=function(e,t){var i=this.listeners[e];if(i)if(2===arguments.length)for(var n=i.length,r=0;r<n;++r)i[r].call(this,t);else for(var a=Array.prototype.slice.call(arguments,1),s=i.length,o=0;o<s;++o)i[o].apply(this,a)},wu.prototype.dispose=function(){this.listeners={}},wu.prototype.pipe=function(t){this.on("data",function(e){t.push(e)})},wu);function wu(){_u(this,wu),this.listeners={}}var Au,Pu=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(Iu,Au=Eu),Iu.prototype.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},Iu.prototype.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},Iu);function Iu(){_u(this,Iu);var e=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,Au.call(this,Eu));return e.jobs=[],e.delay=1,e.timeout_=null,e}function Lu(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24}function Ou(e,t,i){var n=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),r=new ku(Array.prototype.slice.call(t)),a=new Uint8Array(e.byteLength),s=new Int32Array(a.buffer),o=void 0,u=void 0,l=void 0,c=void 0,h=void 0,d=void 0,p=void 0,f=void 0,m=void 0;for(o=i[0],u=i[1],l=i[2],c=i[3],m=0;m<n.length;m+=4)h=Lu(n[m]),d=Lu(n[m+1]),p=Lu(n[m+2]),f=Lu(n[m+3]),r.decrypt(h,d,p,f,s,m),s[m]=Lu(s[m]^o),s[m+1]=Lu(s[m+1]^u),s[m+2]=Lu(s[m+2]^l),s[m+3]=Lu(s[m+3]^c),o=h,u=d,l=p,c=f;return a}var xu=(Du.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=Ou(t,i,n);r.set(e,t.byteOffset)}},bu(Du,null,[{key:"STEP",get:function(){return 32e3}}]),Du);function Du(e,t,i,n){_u(this,Du);var r=Du.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new Pu,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([Lu(a[o-4]),Lu(a[o-3]),Lu(a[o-2]),Lu(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){n(null,function(e){return e.subarray(0,e.byteLength-e[e.byteLength-1])}(s))})}function Uu(e,t){return/^[a-z]+:/i.test(t)?t:(/\/\//i.test(e)||(e=ys.buildAbsoluteURL(v.location.href,e)),ys.buildAbsoluteURL(e,t))}function Ru(e,t,i){return e&&i.responseURL&&t!==i.responseURL?i.responseURL:t}function Mu(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}
/**
* @videojs/http-streaming
- * @version 1.10.3
+ * @version 1.10.6
* @copyright 2019 Brightcove, Inc
* @license Apache-2.0
*/
-var Ic=function(e,t,i){return t&&Oc(e.prototype,t),i&&Oc(e,i),e};function Oc(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function xc(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function Uc(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function Dc(r,a){["AUDIO","SUBTITLES"].forEach(function(e){for(var t in r.mediaGroups[e])for(var i in r.mediaGroups[e][t]){var n=r.mediaGroups[e][t][i];a(n,e,t,i)}})}function Rc(e,t){var i=Fc(e,{}),n=i.playlists[t.uri];if(!n)return null;if(n.segments&&t.segments&&n.segments.length===t.segments.length&&n.endList===t.endList&&n.mediaSequence===t.mediaSequence)return null;var r=Fc(n,t);n.segments&&(r.segments=function(e,t,i){var n=t.slice();i=i||0;for(var r=Math.min(e.length,t.length+i),a=i;a<r;a++)n[a-i]=Fc(e[a],n[a-i]);return n}(n.segments,t.segments,t.mediaSequence-n.mediaSequence)),r.segments.forEach(function(e){!function(e,t){e.resolvedUri||(e.resolvedUri=Ac(t,e.uri)),e.key&&!e.key.resolvedUri&&(e.key.resolvedUri=Ac(t,e.key.uri)),e.map&&!e.map.resolvedUri&&(e.map.resolvedUri=Ac(t,e.map.uri))}(e,r.resolvedUri)});for(var a=0;a<i.playlists.length;a++)i.playlists[a].uri===t.uri&&(i.playlists[a]=r);return i.playlists[t.uri]=r,i}function Mc(e){for(var t=e.playlists.length;t--;){var i=e.playlists[t];(e.playlists[i.uri]=i).resolvedUri=Ac(e.uri,i.uri),i.id=t,i.attributes||(i.attributes={},Vc.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute."))}}function Bc(t){Dc(t,function(e){e.uri&&(e.resolvedUri=Ac(t.uri,e.uri))})}function Nc(e,t){var i=e.segments[e.segments.length-1];return t&&i&&i.duration?1e3*i.duration:500*(e.targetDuration||10)}var jc=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var i=[],n=!0,r=!1,a=void 0;try{for(var s,o=e[Symbol.iterator]();!(n=(s=o.next()).done)&&(i.push(s.value),!t||i.length!==t);n=!0);}catch(e){r=!0,a=e}finally{try{!n&&o.return&&o.return()}finally{if(r)throw a}}return i}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},Fc=bs.mergeOptions,Vc=bs.log,Hc=(xc(qc,bs.EventTarget),Ic(qc,[{key:"playlistRequestError",value:function(e,t,i){this.request=null,i&&(this.state=i),this.error={playlist:this.master.playlists[t],status:e.status,message:"HLS playlist request error at URL: "+t+".",responseText:e.responseText,code:500<=e.status?4:2},this.trigger("error")}},{key:"haveMetadata",value:function(e,t){var i=this;this.request=null,this.state="HAVE_METADATA";var n=new Rs;this.customTagParsers.forEach(function(e){return n.addParser(e)}),this.customTagMappers.forEach(function(e){return n.addTagMapper(e)}),n.push(e.responseText),n.end(),n.manifest.uri=t,n.manifest.attributes=n.manifest.attributes||{};var r=Rc(this.master,n.manifest);this.targetDuration=n.manifest.targetDuration,r?(this.master=r,this.media_=this.master.playlists[n.manifest.uri]):this.trigger("playlistunchanged"),this.media().endList||(v.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=v.setTimeout(function(){i.trigger("mediaupdatetimeout")},Nc(this.media(),!!r))),this.trigger("loadedplaylist")}},{key:"dispose",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.finalRenditionTimeout)}},{key:"stopRequest",value:function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort()}}},{key:"media",value:function(i,e){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}if(v.clearTimeout(this.finalRenditionTimeout),e){var t=i.targetDuration/2*1e3||5e3;this.finalRenditionTimeout=v.setTimeout(this.media.bind(this,i,!1),t)}else{var r=this.state,a=!this.media_||i.uri!==this.media_.uri;if(this.master.playlists[i.uri].endList)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=i,void(a&&(this.trigger("mediachanging"),this.trigger("mediachange")));if(a){if(this.state="SWITCHING_MEDIA",this.request){if(i.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.request=this.hls_.xhr({uri:i.resolvedUri,withCredentials:this.withCredentials},function(e,t){if(n.request){if(i.resolvedUri=Pc(n.handleManifestRedirects,i.resolvedUri,t),e)return n.playlistRequestError(n.request,i.uri,r);n.haveMetadata(t,i.uri),"HAVE_MASTER"===r?n.trigger("loadedmetadata"):n.trigger("mediachange")}})}}}},{key:"pause",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")}},{key:"load",value:function(e){var t=this;v.clearTimeout(this.mediaUpdateTimeout);var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=v.setTimeout(function(){return t.load()},n)}else this.started?i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()}},{key:"start",value:function(){var n=this;this.started=!0,this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(n.request){if(n.request=null,e)return n.error={status:t.status,message:"HLS playlist request error at URL: "+n.srcUrl+".",responseText:t.responseText,code:2},"HAVE_NOTHING"===n.state&&(n.started=!1),n.trigger("error");var i=new Rs;return n.customTagParsers.forEach(function(e){return i.addParser(e)}),n.customTagMappers.forEach(function(e){return i.addTagMapper(e)}),i.push(t.responseText),i.end(),n.state="HAVE_MASTER",n.srcUrl=Pc(n.handleManifestRedirects,n.srcUrl,t),i.manifest.uri=n.srcUrl,i.manifest.playlists?(n.master=i.manifest,Mc(n.master),Bc(n.master),n.trigger("loadedplaylist"),void(n.request||n.media(i.manifest.playlists[0]))):(n.master={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:v.location.href,playlists:[{uri:n.srcUrl,id:0,resolvedUri:n.srcUrl,attributes:{}}]},n.master.playlists[n.srcUrl]=n.master.playlists[0],n.haveMetadata(t,n.srcUrl),n.trigger("loadedmetadata"))}})}}]),qc);function qc(e,t){var i=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};Lc(this,qc);var n=Uc(this,(qc.__proto__||Object.getPrototypeOf(qc)).call(this)),r=i.withCredentials,a=void 0!==r&&r,s=i.handleManifestRedirects,o=void 0!==s&&s;n.srcUrl=e,n.hls_=t,n.withCredentials=a,n.handleManifestRedirects=o;var u=t.options_;if(n.customTagParsers=u&&u.customTagParsers||[],n.customTagMappers=u&&u.customTagMappers||[],!n.srcUrl)throw new Error("A non-empty playlist URL is required");return n.state="HAVE_NOTHING",n.on("mediaupdatetimeout",function(){"HAVE_METADATA"===n.state&&(n.state="HAVE_CURRENT_METADATA",n.request=n.hls_.xhr({uri:Ac(n.master.uri,n.media().uri),withCredentials:n.withCredentials},function(e,t){if(n.request)return e?n.playlistRequestError(n.request,n.media().uri,"HAVE_METADATA"):void n.haveMetadata(n.request,n.media().uri)}))}),n}function zc(e,t,i){var n,r;return"undefined"==typeof t&&(t=e.mediaSequence+e.segments.length),t<e.mediaSequence?0:(n=function(e,t){var i=0,n=t-e.mediaSequence,r=e.segments[n];if(r){if("undefined"!=typeof r.start)return{result:r.start,precise:!0};if("undefined"!=typeof r.end)return{result:r.end-r.duration,precise:!0}}for(;n--;){if("undefined"!=typeof(r=e.segments[n]).end)return{result:i+r.end,precise:!0};if(i+=r.duration,"undefined"!=typeof r.start)return{result:i+r.start,precise:!0}}return{result:i,precise:!1}}(e,t)).precise?n.result:(r=function(e,t){for(var i=0,n=void 0,r=t-e.mediaSequence;r<e.segments.length;r++){if("undefined"!=typeof(n=e.segments[r]).start)return{result:n.start-i,precise:!0};if(i+=n.duration,"undefined"!=typeof n.end)return{result:n.end-i,precise:!0}}return{result:-1,precise:!1}}(e,t)).precise?r.result:n.result+i}function Wc(e,t,i){if(!e)return 0;if("number"!=typeof i&&(i=0),"undefined"==typeof t){if(e.totalDuration)return e.totalDuration;if(!e.endList)return v.Infinity}return zc(e,t,i)}function Gc(e,t,i){var n=0;if(i<t){var r=[i,t];t=r[0],i=r[1]}if(t<0){for(var a=t;a<Math.min(0,i);a++)n+=e.targetDuration;t=0}for(var s=t;s<i;s++)n+=e.segments[s].duration;return n}function $c(e){if(!e.segments.length)return 0;for(var t=e.segments.length-1,i=e.segments[t].duration||e.targetDuration,n=i+2*e.targetDuration;t--&&!(n<=(i+=e.segments[t].duration)););return Math.max(0,t)}function Xc(e,t,i){if(!e||!e.segments)return null;if(e.endList)return Wc(e);if(null===t)return null;t=t||0;var n=i?$c(e):e.segments.length;return zc(e,e.mediaSequence+n,t)}function Kc(e){return e-Math.floor(e)==0}function Yc(e,t){if(Kc(t))return t+.1*e;for(var i=t.toString().split(".")[1].length,n=1;n<=i;n++){var r=Math.pow(10,n),a=t*r;if(Kc(a)||n===i)return(a+e)/r}}function Qc(e){return e.excludeUntil&&e.excludeUntil>Date.now()}function Jc(e){return e.excludeUntil&&e.excludeUntil===1/0}function Zc(e){var t=Qc(e);return!e.disabled&&!t}function eh(e,t){return t.attributes&&t.attributes[e]}function th(e,t){if(1===e.playlists.length)return!0;var i=t.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===e.playlists.filter(function(e){return!!Zc(e)&&(e.attributes.BANDWIDTH||0)<i}).length}function ih(){return function e(t,n){t=Ch({timeout:45e3},t);var i=e.beforeRequest||bs.Hls.xhr.beforeRequest;if(i&&"function"==typeof i){var r=i(t);r&&(t=r)}var a=wh(t,function(e,t){var i=a.response;!e&&i&&(a.responseTime=Date.now(),a.roundTripTime=a.responseTime-a.requestTime,a.bytesReceived=i.byteLength||i.length,a.bandwidth||(a.bandwidth=Math.floor(a.bytesReceived/a.roundTripTime*8*1e3))),t.headers&&(a.responseHeaders=t.headers),e&&"ETIMEDOUT"===e.code&&(a.timedout=!0),e||a.aborted||200===t.statusCode||206===t.statusCode||0===t.statusCode||(e=new Error("XHR Failed with a response of: "+(a&&(i||a.responseText)))),n(e,a)}),s=a.abort;return a.abort=function(){return a.aborted=!0,s.apply(a,arguments)},a.uri=t.uri,a.requestTime=Date.now(),a}}function nh(e){var t={};return e.byterange&&(t.Range=function(e){var t;return t=e.offset+e.length-1,"bytes="+e.offset+"-"+t}(e.byterange)),t}function rh(e,t){var i=e.toString(16);return"00".substring(0,2-i.length)+i+(t%2?" ":"")}function ah(e){return 32<=e&&e<126?String.fromCharCode(e):"."}function sh(i){var n={};return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}function oh(e){var t=e.byterange||{length:1/0,offset:0};return[t.length,t.offset,e.resolvedUri].join(",")}function uh(e){return e.resolvedUri}function lh(e){for(var t=Array.prototype.slice.call(e),i="",n=0;n<t.length/16;n++)i+=t.slice(16*n,16*n+16).map(rh).join("")+" "+t.slice(16*n,16*n+16).map(ah).join("")+"\n";return i}function ch(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i,r=e.callback;if(!r)throw new Error("getProgramTime: callback must be provided");if(!t||void 0===n)return r({message:"getProgramTime: playlist and time must be provided"});var a=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i=0,n=void 0,r=0;r<t.segments.length&&!(e<=(i=(n=t.segments[r]).videoTimingInfo?n.videoTimingInfo.transmuxedPresentationEnd:i+n.duration));r++);var a=t.segments[t.segments.length-1];if(a.videoTimingInfo&&a.videoTimingInfo.transmuxedPresentationEnd<e)return null;if(i<e){if(e>i+.25*a.duration)return null;n=a}return{segment:n,estimatedStart:n.videoTimingInfo?n.videoTimingInfo.transmuxedPresentationStart:i-n.duration,type:n.videoTimingInfo?"accurate":"estimate"}}(n,t);if(!a)return r({message:"valid programTime was not found"});if("estimate"===a.type)return r({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:a.estimatedStart});var s={mediaSeconds:n},o=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,n=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*n)}(n,a.segment);return o&&(s.programDateTime=o.toISOString()),r(null,s)}function hh(e){var t=e.programTime,i=e.playlist,n=e.retryCount,r=void 0===n?2:n,a=e.seekTo,s=e.pauseAfterSeek,o=void 0===s||s,u=e.tech,l=e.callback;if(!l)throw new Error("seekToProgramTime: callback must be provided");if("undefined"==typeof t||!i||!a)return l({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"});if(!i.endList&&!u.hasStarted_)return l({message:"player must be playing a live stream to start buffering"});if(!function(e){if(!e.segments||0===e.segments.length)return!1;for(var t=0;t<e.segments.length;t++){if(!e.segments[t].dateTimeObject)return!1}return!0}(i))return l({message:"programDateTime tags must be provided in the manifest "+i.resolvedUri});var c=function(e,t){var i=void 0;try{i=new Date(e)}catch(e){return null}if(!t||!t.segments||0===t.segments.length)return null;var n=t.segments[0];if(i<n.dateTimeObject)return null;for(var r=0;r<t.segments.length-1;r++){if(n=t.segments[r],i<t.segments[r+1].dateTimeObject)break}var a=t.segments[t.segments.length-1],s=a.dateTimeObject,o=a.videoTimingInfo?function(e){return e.transmuxedPresentationEnd-e.transmuxedPresentationStart-e.transmuxerPrependedSeconds}(a.videoTimingInfo):a.duration+.25*a.duration;return new Date(s.getTime()+1e3*o)<i?null:(s<i&&(n=a),{segment:n,estimatedStart:n.videoTimingInfo?n.videoTimingInfo.transmuxedPresentationStart:kh.duration(t,t.mediaSequence+t.segments.indexOf(n)),type:n.videoTimingInfo?"accurate":"estimate"})}(t,i);if(!c)return l({message:t+" was not found in the stream"});var h=c.segment,d=function(e,t){var i=void 0,n=void 0;try{i=new Date(e),n=new Date(t)}catch(e){}var r=i.getTime();return(n.getTime()-r)/1e3}(h.dateTimeObject,t);if("estimate"===c.type)return 0===r?l({message:t+" is not buffered yet. Try again"}):(a(c.estimatedStart+d),void u.one("seeked",function(){hh({programTime:t,playlist:i,retryCount:r-1,seekTo:a,pauseAfterSeek:o,tech:u,callback:l})}));var p=h.start+d;u.one("seeked",function(){return l(null,u.currentTime())}),o&&u.pause(),a(p)}function dh(e,t){var i=[],n=void 0;if(e&&e.length)for(n=0;n<e.length;n++)t(e.start(n),e.end(n))&&i.push([e.start(n),e.end(n)]);return bs.createTimeRanges(i)}function ph(e,i){return dh(e,function(e,t){return e-Ah<=i&&i<=t+Ah})}function fh(e,t){return dh(e,function(e){return t<=e-Ah})}function mh(e){var t=[];if(!e||!e.length)return"";for(var i=0;i<e.length;i++)t.push(e.start(i)+" => "+e.end(i));return t.join(", ")}function gh(e){for(var t=[],i=0;i<e.length;i++)t.push({start:e.start(i),end:e.end(i)});return t}function yh(e,t,i){var n=void 0,r=void 0;if(i&&i.cues)for(n=i.cues.length;n--;)(r=i.cues[n]).startTime<=t&&r.endTime>=e&&i.removeCue(r)}function vh(e){return isNaN(e)||Math.abs(e)===1/0?Number.MAX_VALUE:e}function _h(e,t,i){var n=v.WebKitDataCue||v.VTTCue;if(t&&t.forEach(function(e){var t=e.stream;this.inbandTextTracks_[t].addCue(new n(e.startTime+this.timestampOffset,e.endTime+this.timestampOffset,e.text))},e),i){var r=vh(e.mediaSource_.duration);if(i.forEach(function(e){var i=e.cueTime+this.timestampOffset;!("number"!=typeof i||v.isNaN(i)||i<0)&&i<1/0&&e.frames.forEach(function(e){var t=new n(i,i,e.value||e.url||e.data||"");t.frame=e,t.value=e,function(e){Object.defineProperties(e.frame,{id:{get:function(){return bs.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),e.value.key}},value:{get:function(){return bs.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),e.value.data}},privateData:{get:function(){return bs.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),e.value.data}}})}(t),this.metadataTrack_.addCue(t)},this)},e),e.metadataTrack_&&e.metadataTrack_.cues&&e.metadataTrack_.cues.length){for(var a=e.metadataTrack_.cues,s=[],o=0;o<a.length;o++)a[o]&&s.push(a[o]);var u=s.reduce(function(e,t){var i=e[t.startTime]||[];return i.push(t),e[t.startTime]=i,e},{}),l=Object.keys(u).sort(function(e,t){return Number(e)-Number(t)});l.forEach(function(e,t){var i=u[e],n=Number(l[t+1])||r;i.forEach(function(e){e.endTime=n})})}}}var bh=bs.createTimeRange,Th=Yc.bind(null,1),Sh=Yc.bind(null,-1),kh={duration:Wc,seekable:function(e,t){var i=t||0,n=Xc(e,t,!0);return null===n?bh():bh(i,n)},safeLiveIndex:$c,getMediaInfoForTime:function(e,t,i,n){var r=void 0,a=void 0,s=e.segments.length,o=t-n;if(o<0){if(0<i)for(r=i-1;0<=r;r--)if(a=e.segments[r],0<(o+=Sh(a.duration)))return{mediaIndex:r,startTime:n-Gc(e,i,r)};return{mediaIndex:0,startTime:t}}if(i<0){for(r=i;r<0;r++)if((o-=e.targetDuration)<0)return{mediaIndex:0,startTime:t};i=0}for(r=i;r<s;r++)if(a=e.segments[r],(o-=Th(a.duration))<0)return{mediaIndex:r,startTime:n+Gc(e,i,r)};return{mediaIndex:s-1,startTime:t}},isEnabled:Zc,isDisabled:function(e){return e.disabled},isBlacklisted:Qc,isIncompatible:Jc,playlistEnd:Xc,isAes:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].key)return!0;return!1},isFmp4:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].map)return!0;return!1},hasAttribute:eh,estimateSegmentRequestTime:function(e,t,i,n){var r=3<arguments.length&&void 0!==n?n:0;return eh("BANDWIDTH",i)?(e*i.attributes.BANDWIDTH-8*r)/t:NaN},isLowestEnabledRendition:th},wh=bs.xhr,Ch=bs.mergeOptions,Eh=Object.freeze({createTransferableMessage:sh,initSegmentId:oh,segmentKeyId:uh,hexDump:lh,tagDump:function(e){var t=e.bytes;return lh(t)},textRanges:function(e){var t,i,n="",r=void 0;for(r=0;r<e.length;r++)n+=(i=r,(t=e).start(i)+"-"+t.end(i)+" ");return n}}),Ah=1/30,Ph="undefined"!=typeof window?window:{},Lh="undefined"==typeof Symbol?"__target":Symbol(),Ih="application/javascript",Oh=Ph.BlobBuilder||Ph.WebKitBlobBuilder||Ph.MozBlobBuilder||Ph.MSBlobBuilder,xh=Ph.URL||Ph.webkitURL||xh&&xh.msURL,Uh=Ph.Worker;function Dh(r,a){return function(e){var t=this;if(!a)return new Uh(r);if(Uh&&!e){var i=Nh(a.toString().replace(/^function.+?{/,"").slice(0,-1));return this[Lh]=new Uh(i),function(e,t){if(!e||!t)return;var i=e.terminate;e.objURL=t,e.terminate=function(){e.objURL&&xh.revokeObjectURL(e.objURL),i.call(e)}}(this[Lh],i),this[Lh]}var n={postMessage:function(e){t.onmessage&&setTimeout(function(){t.onmessage({data:e,target:n})})}};a.call(n),this.postMessage=function(e){setTimeout(function(){n.onmessage({data:e,target:t})})},this.isThisThread=!0}}if(Uh){var Rh,Mh=Nh("self.onmessage = function () {}"),Bh=new Uint8Array(1);try{(Rh=new Uh(Mh)).postMessage(Bh,[Bh.buffer])}catch(e){Uh=null}finally{xh.revokeObjectURL(Mh),Rh&&Rh.terminate()}}function Nh(t){try{return xh.createObjectURL(new Blob([t],{type:Ih}))}catch(e){var i=new Oh;return i.append(t),xh.createObjectURL(i.getBlob(type))}}function jh(e){return e.map(function(e){return e.replace(/avc1\.(\d+)\.(\d+)/i,function(e,t,i){return"avc1."+("00"+Number(t).toString(16)).slice(-2)+"00"+("00"+Number(i).toString(16)).slice(-2)})})}function Fh(e){var t,i=0<arguments.length&&void 0!==e?e:"",n={codecCount:0};return n.codecCount=i.split(",").length,n.codecCount=n.codecCount||2,(t=/(^|\s|,)+(avc[13])([^ ,]*)/i.exec(i))&&(n.videoCodec=t[2],n.videoObjectTypeIndicator=t[3]),n.audioProfile=/(^|\s|,)+mp4a.[0-9A-Fa-f]+\.([0-9A-Fa-f]+)/i.exec(i),n.audioProfile=n.audioProfile&&n.audioProfile[2],n}function Vh(e,t,i){return e+"/"+t+'; codecs="'+i.filter(function(e){return!!e}).join(", ")+'"'}function Hh(e,t){var i=function(e){return e.segments&&e.segments.length&&e.segments[0].map?"mp4":"mp2t"}(t),n=function(e){var t=e.attributes||{};return t.CODECS?Fh(t.CODECS):Gh}(t),r=t.attributes||{},a=!0,s=!1;if(!t)return[];if(e.mediaGroups.AUDIO&&r.AUDIO){var o=e.mediaGroups.AUDIO[r.AUDIO];if(o)for(var u in a=!(s=!0),o)if(!o[u].uri&&!o[u].playlists){a=!0;break}}s&&!n.audioProfile&&(a||(n.audioProfile=function(e,t){if(!e.mediaGroups.AUDIO||!t)return null;var i=e.mediaGroups.AUDIO[t];if(!i)return null;for(var n in i){var r=i[n];if(r.default&&r.playlists)return Fh(r.playlists[0].attributes.CODECS).audioProfile}return null}(e,r.AUDIO)),n.audioProfile||(bs.log.warn("Multiple audio tracks present but no audio codec string is specified. Attempting to use the default audio codec (mp4a.40.2)"),n.audioProfile=Gh.audioProfile));var l={};n.videoCodec&&(l.video=""+n.videoCodec+n.videoObjectTypeIndicator),n.audioProfile&&(l.audio="mp4a.40."+n.audioProfile);var c=Vh("audio",i,[l.audio]),h=Vh("video",i,[l.video]),d=Vh("video",i,[l.video,l.audio]);return s?!a&&l.video?[h,c]:a||l.video?[d,c]:[c,c]:l.video?[d]:[c]}function qh(e){return/mp4a\.\d+.\d+/i.test(e)}function zh(e){return/avc1\.[\da-f]+/i.test(e)}var Wh=new Dh("./transmuxer-worker.worker.js",function(e,t){var Rt=this;!function(){var o,t,i,r,a,n,e,s,u,l,c,h,d,p,f,m,g,y,v,_,b,T,S,k,w,C,E,A,P,L,I,O,x,U,D,R,M,B,N,j,F=Math.pow(2,32)-1;!function(){var e;if(T={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],smhd:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],styp:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[]},"undefined"!=typeof Uint8Array){for(e in T)T.hasOwnProperty(e)&&(T[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);S=new Uint8Array(["i".charCodeAt(0),"s".charCodeAt(0),"o".charCodeAt(0),"m".charCodeAt(0)]),w=new Uint8Array(["a".charCodeAt(0),"v".charCodeAt(0),"c".charCodeAt(0),"1".charCodeAt(0)]),k=new Uint8Array([0,0,0,1]),C=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]),E=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]),A={video:C,audio:E},I=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),L=new Uint8Array([0,0,0,0,0,0,0,0]),O=new Uint8Array([0,0,0,0,0,0,0,0]),x=O,U=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),D=O,P=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}}(),o=function(e){var t,i,n=[],r=0;for(t=1;t<arguments.length;t++)n.push(arguments[t]);for(t=n.length;t--;)r+=n[t].byteLength;for(i=new Uint8Array(r+8),new DataView(i.buffer,i.byteOffset,i.byteLength).setUint32(0,i.byteLength),i.set(e,4),t=0,r=8;t<n.length;t++)i.set(n[t],r),r+=n[t].byteLength;return i},t=function(){return o(T.dinf,o(T.dref,I))},i=function(e){return o(T.esds,new Uint8Array([0,0,0,0,3,25,0,0,0,4,17,64,21,0,6,0,0,0,218,192,0,0,218,192,5,2,e.audioobjecttype<<3|e.samplingfrequencyindex>>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},f=function(e){return o(T.hdlr,A[e])},p=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(t[12]=e.samplerate>>>24&255,t[13]=e.samplerate>>>16&255,t[14]=e.samplerate>>>8&255,t[15]=255&e.samplerate),o(T.mdhd,t)},d=function(e){return o(T.mdia,p(e),f(e.type),n(e))},a=function(e){return o(T.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},n=function(e){return o(T.minf,"video"===e.type?o(T.vmhd,P):o(T.smhd,L),t(),g(e))},e=function(e,t){for(var i=[],n=t.length;n--;)i[n]=v(t[n]);return o.apply(null,[T.moof,a(e)].concat(i))},s=function(e){for(var t=e.length,i=[];t--;)i[t]=c(e[t]);return o.apply(null,[T.moov,l(4294967295)].concat(i).concat(u(e)))},u=function(e){for(var t=e.length,i=[];t--;)i[t]=_(e[t]);return o.apply(null,[T.mvex].concat(i))},l=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,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 o(T.mvhd,t)},m=function(e){var t,i,n=e.samples||[],r=new Uint8Array(4+n.length);for(i=0;i<n.length;i++)t=n[i].flags,r[i+4]=t.dependsOn<<4|t.isDependedOn<<2|t.hasRedundancy;return o(T.sdtp,r)},g=function(e){return o(T.stbl,y(e),o(T.stts,D),o(T.stsc,x),o(T.stsz,U),o(T.stco,O))},y=function(e){return o(T.stsd,new Uint8Array([0,0,0,0,0,0,0,1]),"video"===e.type?R(e):M(e))},R=function(e){var t,i=e.sps||[],n=e.pps||[],r=[],a=[];for(t=0;t<i.length;t++)r.push((65280&i[t].byteLength)>>>8),r.push(255&i[t].byteLength),r=r.concat(Array.prototype.slice.call(i[t]));for(t=0;t<n.length;t++)a.push((65280&n[t].byteLength)>>>8),a.push(255&n[t].byteLength),a=a.concat(Array.prototype.slice.call(n[t]));return o(T.avc1,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,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),o(T.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([i.length]).concat(r).concat([n.length]).concat(a))),o(T.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))},M=function(e){return o(T.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),i(e))},h=function(e){var t=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,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,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return o(T.tkhd,t)},v=function(e){var t,i,n,r,a,s;return t=o(T.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),a=Math.floor(e.baseMediaDecodeTime/(1+F)),s=Math.floor(e.baseMediaDecodeTime%(1+F)),i=o(T.tfdt,new Uint8Array([1,0,0,0,a>>>24&255,a>>>16&255,a>>>8&255,255&a,s>>>24&255,s>>>16&255,s>>>8&255,255&s])),92,"audio"===e.type?(n=b(e,92),o(T.traf,t,i,n)):(r=m(e),n=b(e,r.length+92),o(T.traf,t,i,n,r))},c=function(e){return e.duration=e.duration||4294967295,o(T.trak,h(e),d(e))},_=function(e){var t=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==e.type&&(t[t.length-1]=0),o(T.trex,t)},j=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},N=function(e,t){var i,n,r,a;for(t+=20+16*(n=e.samples||[]).length,i=j(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size,r.flags.isLeading<<2|r.flags.dependsOn,r.flags.isDependedOn<<6|r.flags.hasRedundancy<<4|r.flags.paddingValue<<1|r.flags.isNonSyncSample,61440&r.flags.degradationPriority,15&r.flags.degradationPriority,(4278190080&r.compositionTimeOffset)>>>24,(16711680&r.compositionTimeOffset)>>>16,(65280&r.compositionTimeOffset)>>>8,255&r.compositionTimeOffset]);return o(T.trun,new Uint8Array(i))},B=function(e,t){var i,n,r,a;for(t+=20+8*(n=e.samples||[]).length,i=j(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size]);return o(T.trun,new Uint8Array(i))},b=function(e,t){return"audio"===e.type?B(e,t):N(e,t)};var V,H,q,z,W,G={ftyp:r=function(){return o(T.ftyp,S,k,S,w)},mdat:function(e){return o(T.mdat,e)},moof:e,moov:s,initSegment:function(e){var t,i=r(),n=s(e);return(t=new Uint8Array(i.byteLength+n.byteLength)).set(i),t.set(n,i.byteLength),t}},$=function(e){return e>>>0};q=function(e){return V(e,["moov","trak"]).reduce(function(e,t){var i,n,r,a,s;return(i=V(t,["tkhd"])[0])?(n=i[0],a=$(i[r=0===n?12:20]<<24|i[r+1]<<16|i[r+2]<<8|i[r+3]),(s=V(t,["mdia","mdhd"])[0])?(r=0===(n=s[0])?12:20,e[a]=$(s[r]<<24|s[r+1]<<16|s[r+2]<<8|s[r+3]),e):null):null},{})},z=function(r,e){var t,i,n;return t=V(e,["moof","traf"]),i=[].concat.apply([],t.map(function(n){return V(n,["tfhd"]).map(function(e){var t,i;return t=$(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),i=r[t]||9e4,(V(n,["tfdt"]).map(function(e){var t,i;return t=e[0],i=$(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),1===t&&(i*=Math.pow(2,32),i+=$(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),i})[0]||1/0)/i})})),n=Math.min.apply(null,i),isFinite(n)?n:0},W=function(e){var t=V(e,["moov","trak"]),o=[];return t.forEach(function(e){var t=V(e,["mdia","hdlr"]),s=V(e,["tkhd"]);t.forEach(function(e,t){var i,n,r=H(e.subarray(8,12)),a=s[t];"vide"===r&&(n=0===(i=new DataView(a.buffer,a.byteOffset,a.byteLength)).getUint8(0)?i.getUint32(12):i.getUint32(20),o.push(n))})}),o};function X(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){var i;return!!a[e]&&(i=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(i,1),-1<i)},this.trigger=function(e){var t,i,n,r;if(t=a[e])if(2===arguments.length)for(n=t.length,i=0;i<n;++i)t[i].call(this,arguments[1]);else{for(r=[],i=arguments.length,i=1;i<arguments.length;++i)r.push(arguments[i]);for(n=t.length,i=0;i<n;++i)t[i].apply(this,r)}},this.dispose=function(){a={}}}}var K={findBox:V=function(e,t){var i,n,r,a,s,o=[];if(!t.length)return null;for(i=0;i<e.byteLength;)n=$(e[i]<<24|e[i+1]<<16|e[i+2]<<8|e[i+3]),r=H(e.subarray(i+4,i+8)),a=1<n?i+n:e.byteLength,r===t[0]&&(1===t.length?o.push(e.subarray(i+8,a)):(s=V(e.subarray(i+8,a),t.slice(1))).length&&(o=o.concat(s))),i=a;return o},parseType:H=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),t+=String.fromCharCode(e[2]),t+=String.fromCharCode(e[3])},timescale:q,startTime:z,videoTrackIds:W};X.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),t},X.prototype.push=function(e){this.trigger("data",e)},X.prototype.flush=function(e){this.trigger("done",e)};function Y(e){for(var t=[];e--;)t.push(0);return t}function Q(){Q.prototype.init.call(this),this.captionPackets_=[],this.ccStreams_=[new Oe(0,0),new Oe(0,1),new Oe(1,0),new Oe(1,1)],this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("done",this.trigger.bind(this,"done"))},this)}var J,Z,ee,te,ie,ne=X,re=function(e){var t,i,n=[],r=[];for(t=n.byteLength=0;t<e.length;t++)"access_unit_delimiter_rbsp"===(i=e[t]).nalUnitType?(n.length&&(n.duration=i.dts-n.dts,r.push(n)),(n=[i]).byteLength=i.data.byteLength,n.pts=i.pts,n.dts=i.dts):("slice_layer_without_partitioning_rbsp_idr"===i.nalUnitType&&(n.keyFrame=!0),n.duration=i.dts-n.dts,n.byteLength+=i.data.byteLength,n.push(i));return r.length&&(!n.duration||n.duration<=0)&&(n.duration=r[r.length-1].duration),r.push(n),r},ae=function(e){var t,i,n=[],r=[];for(n.byteLength=0,n.nalCount=0,n.duration=0,n.pts=e[0].pts,n.dts=e[0].dts,r.byteLength=0,r.nalCount=0,r.duration=0,r.pts=e[0].pts,r.dts=e[0].dts,t=0;t<e.length;t++)(i=e[t]).keyFrame?(n.length&&(r.push(n),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration),(n=[i]).nalCount=i.length,n.byteLength=i.byteLength,n.pts=i.pts,n.dts=i.dts,n.duration=i.duration):(n.duration+=i.duration,n.nalCount+=i.length,n.byteLength+=i.byteLength,n.push(i));return r.length&&n.duration<=0&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration,r.push(n),r},se=function(e){var t;return!e[0][0].keyFrame&&1<e.length&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e},oe=function(e,t){var i,n,r,a,s,o,u,l=t||0,c=[];for(i=0;i<e.length;i++)for(a=e[i],n=0;n<a.length;n++)s=a[n],o=s,u=void 0,(u={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}}).dataOffset=l,u.compositionTimeOffset=o.pts-o.dts,u.duration=o.duration,u.size=4*o.length,u.size+=o.byteLength,o.keyFrame&&(u.flags.dependsOn=2,u.flags.isNonSyncSample=0),l+=(r=u).size,c.push(r);return c},ue=function(e){var t,i,n,r,a,s,o=0,u=e.byteLength,l=e.nalCount,c=new Uint8Array(u+4*l),h=new DataView(c.buffer);for(t=0;t<e.length;t++)for(r=e[t],i=0;i<r.length;i++)for(a=r[i],n=0;n<a.length;n++)s=a[n],h.setUint32(o,s.data.byteLength),o+=4,c.set(s.data,o),o+=s.data.byteLength;return c},le=[33,16,5,32,164,27],ce=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],he={96e3:[le,[227,64],Y(154),[56]],88200:[le,[231],Y(170),[56]],64e3:[le,[248,192],Y(240),[56]],48e3:[le,[255,192],Y(268),[55,148,128],Y(54),[112]],44100:[le,[255,192],Y(268),[55,163,128],Y(84),[112]],32e3:[le,[255,192],Y(268),[55,234],Y(226),[112]],24e3:[le,[255,192],Y(268),[55,255,128],Y(268),[111,112],Y(126),[224]],16e3:[le,[255,192],Y(268),[55,255,128],Y(268),[111,255],Y(269),[223,108],Y(195),[1,192]],12e3:[ce,Y(268),[3,127,248],Y(268),[6,255,240],Y(268),[13,255,224],Y(268),[27,253,128],Y(259),[56]],11025:[ce,Y(268),[3,127,248],Y(268),[6,255,240],Y(268),[13,255,224],Y(268),[27,255,192],Y(268),[55,175,128],Y(108),[112]],8e3:[ce,Y(268),[3,121,16],Y(47),[7]]},de=(J=he,Object.keys(J).reduce(function(e,t){return e[t]=new Uint8Array(J[t].reduce(function(e,t){return e.concat(t)},[])),e},{})),pe=(Z=function(e){return 9e4*e},ee=function(e,t){return e*t},te=function(e){return e/9e4},ie=function(e,t){return e/t},function(e,t){return Z(ie(e,t))}),fe=function(e,t){return ee(te(e),t)},me=function(e,t,i,n){var r,a,s,o,u=0,l=0,c=0;if(t.length&&(r=pe(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(9e4/(e.samplerate/1024)),i&&n&&(u=r-Math.max(i,n),c=(l=Math.floor(u/a))*a),!(l<1||45e3<c))){for(s=(s=de[e.samplerate])||t[0].data,o=0;o<l;o++)t.splice(o,0,{data:s});e.baseMediaDecodeTime-=Math.floor(fe(c,e.samplerate))}},ge=function(e,t,i){return t.minSegmentDts>=i?e:(t.minSegmentDts=1/0,e.filter(function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)}))},ye=function(e){var t,i,n=[];for(t=0;t<e.length;t++)i=e[t],n.push({size:i.data.byteLength,duration:1024});return n},ve=function(e){var t,i,n=0,r=new Uint8Array(function(e){var t,i=0;for(t=0;t<e.length;t++)i+=e[t].data.byteLength;return i}(e));for(t=0;t<e.length;t++)i=e[t],r.set(i.data,n),n+=i.data.byteLength;return r},_e=function(e){delete e.minSegmentDts,delete e.maxSegmentDts,delete e.minSegmentPts,delete e.maxSegmentPts},be=function(e,t){var i,n=e.minSegmentDts;return t||(n-=e.timelineStartInfo.dts),i=e.timelineStartInfo.baseMediaDecodeTime,i+=n,i=Math.max(0,i),"audio"===e.type&&(i*=e.samplerate/9e4,i=Math.floor(i)),i},Te=function(e,t){"number"==typeof t.pts&&(void 0===e.timelineStartInfo.pts&&(e.timelineStartInfo.pts=t.pts),void 0===e.minSegmentPts?e.minSegmentPts=t.pts:e.minSegmentPts=Math.min(e.minSegmentPts,t.pts),void 0===e.maxSegmentPts?e.maxSegmentPts=t.pts:e.maxSegmentPts=Math.max(e.maxSegmentPts,t.pts)),"number"==typeof t.dts&&(void 0===e.timelineStartInfo.dts&&(e.timelineStartInfo.dts=t.dts),void 0===e.minSegmentDts?e.minSegmentDts=t.dts:e.minSegmentDts=Math.min(e.minSegmentDts,t.dts),void 0===e.maxSegmentDts?e.maxSegmentDts=t.dts:e.maxSegmentDts=Math.max(e.maxSegmentDts,t.dts))},Se=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}t+=r,r=n=0}return i},ke=function(e){return 181!==e.payload[0]?null:49!=(e.payload[1]<<8|e.payload[2])?null:"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])?null:3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},we=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},Ce=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},Ee=4;(Q.prototype=new ne).push=function(e){var t,i,n;if("sei_rbsp"===e.nalUnitType&&(t=Se(e.escapedRBSP)).payloadType===Ee&&(i=ke(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));n=we(e.pts,i),this.captionPackets_=this.captionPackets_.concat(n),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},Q.prototype.flush=function(){this.captionPackets_.length?(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2&&this.dispatchCea608Packet(e)},this),this.captionPackets_.length=0,this.ccStreams_.forEach(function(e){e.flush()},this)):this.ccStreams_.forEach(function(e){e.flush()},this)},Q.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},Q.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},Q.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},Q.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},Q.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)};function Ae(e){return null===e?"":(e=Le[e]||e,String.fromCharCode(e))}function Pe(){for(var e=[],t=15;t--;)e.push("");return e}var Le={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},Ie=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Oe=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a;if((t=32639&e.ccData)!==this.lastControlCode_){if(4096==(61440&t)?this.lastControlCode_=t:t!==this.PADDING_&&(this.lastControlCode_=null),n=t>>>8,r=255&t,t!==this.PADDING_)if(t===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(t===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),i=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=i,this.startPts_=e.pts;else if(t===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(e.pts);else if(t===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(e.pts);else if(t===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(e.pts);else if(t===this.CARRIAGE_RETURN_)this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts;else if(t===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1);else if(t===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(e.pts),this.displayed_=Pe();else if(t===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=Pe();else if(t===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=Pe()),this.mode_="paintOn",this.startPts_=e.pts;else if(this.isSpecialCharacter(n,r))a=Ae((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isExtCharacter(n,r))"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),a=Ae((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isMidRowCode(n,r))this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&r)&&this.addFormatting(e.pts,["i"]),1==(1&r)&&this.addFormatting(e.pts,["u"]);else if(this.isOffsetControlCode(n,r))this.column_+=3&r;else if(this.isPAC(n,r)){var s=Ie.indexOf(7968&t);"rollUp"===this.mode_&&(s-this.rollUpRows_+1<0&&(s=this.rollUpRows_-1),this.setRollUp(e.pts,s)),s!==this.row_&&(this.clearFormatting(e.pts),this.row_=s),1&r&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&t)&&(this.column_=4*((14&t)>>1)),this.isColorPAC(r)&&14==(14&r)&&this.addFormatting(e.pts,["i"])}else this.isNormalChar(n)&&(0===r&&(r=null),a=Ae(n),a+=Ae(r),this[this.mode_](e.pts,a),this.column_+=a.length)}else this.lastControlCode_=null}};Oe.prototype=new ne,Oe.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e){try{return e.trim()}catch(e){return""}}).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_})},Oe.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=Pe(),this.nonDisplayed_=Pe(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Oe.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},Oe.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},Oe.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},Oe.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},Oe.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},Oe.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},Oe.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},Oe.prototype.isNormalChar=function(e){return 32<=e&&e<=127},Oe.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=Pe(),this.displayed_=Pe()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},Oe.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);var i=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,i)},Oe.prototype.clearFormatting=function(e){if(this.formatting_.length){var t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},"");this.formatting_=[],this[this.mode_](e,t)}},Oe.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];i+=t,this.nonDisplayed_[this.row_]=i},Oe.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i},Oe.prototype.shiftRowsUp_=function(){var e;for(e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},Oe.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i};function xe(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}function Ue(e){var t,i;Ue.prototype.init.call(this),this.type_=e,this.push=function(e){e.type===this.type_&&(void 0===i&&(i=e.dts),e.dts=xe(e.dts,i),e.pts=xe(e.pts,i),t=e.dts,this.trigger("data",e))},this.flush=function(){i=t,this.trigger("done")},this.discontinuity=function(){t=i=void 0}}var De={CaptionStream:Q,Cea608Stream:Oe},Re={H264_STREAM_TYPE:27,ADTS_STREAM_TYPE:15,METADATA_STREAM_TYPE:21};Ue.prototype=new ne;function Me(e,t,i){var n,r="";for(n=t;n<i;n++)r+="%"+("00"+e[n].toString(16)).slice(-2);return r}function Be(e,t,i){return decodeURIComponent(Me(e,t,i))}function Ne(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var je,Fe=Ue,Ve={TXXX:function(e){var t;if(3===e.data[0]){for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=Be(e.data,1,t),e.value=Be(e.data,t+1,e.data.length).replace(/\0*$/,"");break}e.data=e.value}},WXXX:function(e){var t;if(3===e.data[0])for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=Be(e.data,1,t),e.url=Be(e.data,t+1,e.data.length);break}},PRIV:function(e){var t,i;for(t=0;t<e.data.length;t++)if(0===e.data[t]){e.owner=(i=e.data,unescape(Me(i,0,t)));break}e.privateData=e.data.subarray(t+1),e.data=e.privateData}};(je=function(e){var t,u={debug:!(!e||!e.debug),descriptor:e&&e.descriptor},l=0,c=[],h=0;if(je.prototype.init.call(this),this.dispatchType=Re.METADATA_STREAM_TYPE.toString(16),u.descriptor)for(t=0;t<u.descriptor.length;t++)this.dispatchType+=("00"+u.descriptor[t].toString(16)).slice(-2);this.push=function(e){var t,i,n,r,a;if("timed-metadata"===e.type)if(e.dataAlignmentIndicator&&(h=0,c.length=0),0===c.length&&(e.data.length<10||e.data[0]!=="I".charCodeAt(0)||e.data[1]!=="D".charCodeAt(0)||e.data[2]!=="3".charCodeAt(0)))u.debug;else if(c.push(e),h+=e.data.byteLength,1===c.length&&(l=Ne(e.data.subarray(6,10)),l+=10),!(h<l)){for(t={data:new Uint8Array(l),frames:[],pts:c[0].pts,dts:c[0].dts},a=0;a<l;)t.data.set(c[0].data.subarray(0,l-a),a),a+=c[0].data.byteLength,h-=c[0].data.byteLength,c.shift();i=10,64&t.data[5]&&(i+=4,i+=Ne(t.data.subarray(10,14)),l-=Ne(t.data.subarray(16,20)));do{if((n=Ne(t.data.subarray(i+4,i+8)))<1)return;if((r={id:String.fromCharCode(t.data[i],t.data[i+1],t.data[i+2],t.data[i+3]),data:t.data.subarray(i+10,i+n+10)}).key=r.id,Ve[r.id]&&(Ve[r.id](r),"com.apple.streaming.transportStreamTimestamp"===r.owner)){var s=r.data,o=(1&s[3])<<30|s[4]<<22|s[5]<<14|s[6]<<6|s[7]>>>2;o*=4,o+=3&s[7],r.timeStamp=o,void 0===t.pts&&void 0===t.dts&&(t.pts=r.timeStamp,t.dts=r.timeStamp),this.trigger("timestamp",r)}t.frames.push(r),i+=10,i+=n}while(i<l);this.trigger("data",t)}}}).prototype=new ne;var He,qe,ze,We=je,Ge=Fe;(He=function(){var r=new Uint8Array(188),a=0;He.prototype.init.call(this),this.push=function(e){var t,i=0,n=188;for(a?((t=new Uint8Array(e.byteLength+a)).set(r.subarray(0,a)),t.set(e,a),a=0):t=e;n<t.byteLength;)71!==t[i]||71!==t[n]?(i++,n++):(this.trigger("data",t.subarray(i,n)),i+=188,n+=188);i<t.byteLength&&(r.set(t.subarray(i),0),a=t.byteLength-i)},this.flush=function(){188===a&&71===r[0]&&(this.trigger("data",r),a=0),this.trigger("done")}}).prototype=new ne,(qe=function(){var n,r,a,s;qe.prototype.init.call(this),(s=this).packetsWaitingForPmt=[],this.programMapTable=void 0,n=function(e,t){var i=0;t.payloadUnitStartIndicator&&(i+=e[i]+1),"pat"===t.type?r(e.subarray(i),t):a(e.subarray(i),t)},r=function(e,t){t.section_number=e[7],t.last_section_number=e[8],s.pmtPid=(31&e[10])<<8|e[11],t.pmtPid=s.pmtPid},a=function(e,t){var i,n;if(1&e[5]){for(s.programMapTable={video:null,audio:null,"timed-metadata":{}},i=3+((15&e[1])<<8|e[2])-4,n=12+((15&e[10])<<8|e[11]);n<i;){var r=e[n],a=(31&e[n+1])<<8|e[n+2];r===Re.H264_STREAM_TYPE&&null===s.programMapTable.video?s.programMapTable.video=a:r===Re.ADTS_STREAM_TYPE&&null===s.programMapTable.audio?s.programMapTable.audio=a:r===Re.METADATA_STREAM_TYPE&&(s.programMapTable["timed-metadata"][a]=r),n+=5+((15&e[n+3])<<8|e[n+4])}t.programMapTable=s.programMapTable}},this.push=function(e){var t={},i=4;if(t.payloadUnitStartIndicator=!!(64&e[1]),t.pid=31&e[1],t.pid<<=8,t.pid|=e[2],1<(48&e[3])>>>4&&(i+=e[i]+1),0===t.pid)t.type="pat",n(e.subarray(i),t),this.trigger("data",t);else if(t.pid===this.pmtPid)for(t.type="pmt",n(e.subarray(i),t),this.trigger("data",t);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([e,i,t]):this.processPes_(e,i,t)},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=Re.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=Re.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i)}}).prototype=new ne,qe.STREAM_TYPES={h264:27,adts:15},(ze=function(){function n(e,t,i){var n,r,a=new Uint8Array(e.size),s={type:t},o=0,u=0;if(e.data.length&&!(e.size<9)){for(s.trackId=e.data[0].pid,o=0;o<e.data.length;o++)r=e.data[o],a.set(r.data,u),u+=r.data.byteLength;!function(e,t){var i;t.packetLength=6+(e[4]<<8|e[5]),t.dataAlignmentIndicator=0!=(4&e[6]),192&(i=e[7])&&(t.pts=(14&e[9])<<27|(255&e[10])<<20|(254&e[11])<<12|(255&e[12])<<5|(254&e[13])>>>3,t.pts*=4,t.pts+=(6&e[13])>>>1,t.dts=t.pts,64&i&&(t.dts=(14&e[14])<<27|(255&e[15])<<20|(254&e[16])<<12|(255&e[17])<<5|(254&e[18])>>>3,t.dts*=4,t.dts+=(6&e[18])>>>1)),t.data=e.subarray(9+e[8])}(a,s),n="video"===t||s.packetLength<=e.size,(i||n)&&(e.size=0,e.data.length=0),n&&l.trigger("data",s)}}var l=this,r={data:[],size:0},a={data:[],size:0},s={data:[],size:0};ze.prototype.init.call(this),this.push=function(i){({pat:function(){},pes:function(){var e,t;switch(i.streamType){case Re.H264_STREAM_TYPE:case Re.H264_STREAM_TYPE:e=r,t="video";break;case Re.ADTS_STREAM_TYPE:e=a,t="audio";break;case Re.METADATA_STREAM_TYPE:e=s,t="timed-metadata";break;default:return}i.payloadUnitStartIndicator&&n(e,t,!0),e.data.push(i),e.size+=i.data.byteLength},pmt:function(){var e={type:"metadata",tracks:[]},t=i.programMapTable;null!==t.video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),l.trigger("data",e)}})[i.type]()},this.flush=function(){n(r,"video"),n(a,"audio"),n(s,"timed-metadata"),this.trigger("done")}}).prototype=new ne;var $e={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:He,TransportParseStream:qe,ElementaryStream:ze,TimestampRolloverStream:Ge,CaptionStream:De.CaptionStream,Cea608Stream:De.Cea608Stream,MetadataStream:We};for(var Xe in Re)Re.hasOwnProperty(Xe)&&($e[Xe]=Re[Xe]);var Ke,Ye=$e,Qe=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(Ke=function(){var l;Ke.prototype.init.call(this),this.push=function(e){var t,i,n,r,a,s,o=0,u=0;if("audio"===e.type)for(l?(r=l,(l=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),l.set(e.data,r.byteLength)):l=e.data;o+5<l.length;)if(255===l[o]&&240==(246&l[o+1])){if(i=2*(1&~l[o+1]),t=(3&l[o+3])<<11|l[o+4]<<3|(224&l[o+5])>>5,s=9e4*(a=1024*(1+(3&l[o+6])))/Qe[(60&l[o+2])>>>2],n=o+t,l.byteLength<n)return;if(this.trigger("data",{pts:e.pts+u*s,dts:e.dts+u*s,sampleCount:a,audioobjecttype:1+(l[o+2]>>>6&3),channelcount:(1&l[o+2])<<2|(192&l[o+3])>>>6,samplerate:Qe[(60&l[o+2])>>>2],samplingfrequencyindex:(60&l[o+2])>>>2,samplesize:16,data:l.subarray(o+7+i,n)}),l.byteLength===n)return void(l=void 0);u++,l=l.subarray(n)}else o++},this.flush=function(){this.trigger("done")}}).prototype=new ne;var Je,Ze,et,tt=Ke,it=function(n){var r=n.byteLength,a=0,s=0;this.length=function(){return 8*r},this.bitsAvailable=function(){return 8*r+s},this.loadWord=function(){var e=n.byteLength-r,t=new Uint8Array(4),i=Math.min(4,r);if(0===i)throw new Error("no bytes available");t.set(n.subarray(e,e+i)),a=new DataView(t.buffer).getUint32(0),s=8*i,r-=i},this.skipBits=function(e){var t;e<s||(e-=s,e-=8*(t=Math.floor(e/8)),r-=t,this.loadWord()),a<<=e,s-=e},this.readBits=function(e){var t=Math.min(s,e),i=a>>>32-t;return 0<(s-=t)?a<<=t:0<r&&this.loadWord(),0<(t=e-t)?i<<t|this.readBits(t):i},this.skipLeadingZeros=function(){var e;for(e=0;e<s;++e)if(0!=(a&2147483648>>>e))return a<<=e,s-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()};(Ze=function(){var i,n,r=0;Ze.prototype.init.call(this),this.push=function(e){var t;for(n=n?((t=new Uint8Array(n.byteLength+e.data.byteLength)).set(n),t.set(e.data,n.byteLength),t):e.data;r<n.byteLength-3;r++)if(1===n[r+2]){i=r+5;break}for(;i<n.byteLength;)switch(n[i]){case 0:if(0!==n[i-1]){i+=2;break}if(0!==n[i-2]){i++;break}for(r+3!==i-2&&this.trigger("data",n.subarray(r+3,i-2));1!==n[++i]&&i<n.length;);r=i-2,i+=3;break;case 1:if(0!==n[i-1]||0!==n[i-2]){i+=3;break}this.trigger("data",n.subarray(r+3,i-2)),r=i-2,i+=3;break;default:i+=3}n=n.subarray(r),i-=r,r=0},this.flush=function(){n&&3<n.byteLength&&this.trigger("data",n.subarray(r+3)),n=null,r=0,this.trigger("done")}}).prototype=new ne,et={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(Je=function(){var i,n,r,a,s,o,_,t=new Ze;Je.prototype.init.call(this),(i=this).push=function(e){"video"===e.type&&(n=e.trackId,r=e.pts,a=e.dts,t.push(e))},t.on("data",function(e){var t={trackId:n,pts:r,dts:a,data:e};switch(31&e[0]){case 5:t.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:t.nalUnitType="sei_rbsp",t.escapedRBSP=s(e.subarray(1));break;case 7:t.nalUnitType="seq_parameter_set_rbsp",t.escapedRBSP=s(e.subarray(1)),t.config=o(t.escapedRBSP);break;case 8:t.nalUnitType="pic_parameter_set_rbsp";break;case 9:t.nalUnitType="access_unit_delimiter_rbsp"}i.trigger("data",t)}),t.on("done",function(){i.trigger("done")}),this.flush=function(){t.flush()},_=function(e,t){var i,n=8,r=8;for(i=0;i<e;i++)0!==r&&(r=(n+t.readExpGolomb()+256)%256),n=0===r?n:r},s=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},o=function(e){var t,i,n,r,a,s,o,u,l,c,h,d,p,f=0,m=0,g=0,y=0,v=1;if(i=(t=new it(e)).readUnsignedByte(),r=t.readUnsignedByte(),n=t.readUnsignedByte(),t.skipUnsignedExpGolomb(),et[i]&&(3===(a=t.readUnsignedExpGolomb())&&t.skipBits(1),t.skipUnsignedExpGolomb(),t.skipUnsignedExpGolomb(),t.skipBits(1),t.readBoolean()))for(h=3!==a?8:12,p=0;p<h;p++)t.readBoolean()&&_(p<6?16:64,t);if(t.skipUnsignedExpGolomb(),0===(s=t.readUnsignedExpGolomb()))t.readUnsignedExpGolomb();else if(1===s)for(t.skipBits(1),t.skipExpGolomb(),t.skipExpGolomb(),o=t.readUnsignedExpGolomb(),p=0;p<o;p++)t.skipExpGolomb();if(t.skipUnsignedExpGolomb(),t.skipBits(1),u=t.readUnsignedExpGolomb(),l=t.readUnsignedExpGolomb(),0===(c=t.readBits(1))&&t.skipBits(1),t.skipBits(1),t.readBoolean()&&(f=t.readUnsignedExpGolomb(),m=t.readUnsignedExpGolomb(),g=t.readUnsignedExpGolomb(),y=t.readUnsignedExpGolomb()),t.readBoolean()&&t.readBoolean()){switch(t.readUnsignedByte()){case 1:d=[1,1];break;case 2:d=[12,11];break;case 3:d=[10,11];break;case 4:d=[16,11];break;case 5:d=[40,33];break;case 6:d=[24,11];break;case 7:d=[20,11];break;case 8:d=[32,11];break;case 9:d=[80,33];break;case 10:d=[18,11];break;case 11:d=[15,11];break;case 12:d=[64,33];break;case 13:d=[160,99];break;case 14:d=[4,3];break;case 15:d=[3,2];break;case 16:d=[2,1];break;case 255:d=[t.readUnsignedByte()<<8|t.readUnsignedByte(),t.readUnsignedByte()<<8|t.readUnsignedByte()]}d&&(v=d[0]/d[1])}return{profileIdc:i,levelIdc:n,profileCompatibility:r,width:Math.ceil((16*(u+1)-2*f-2*m)*v),height:(2-c)*(l+1)*16-2*g-2*y}}}).prototype=new ne;var nt,rt={H264Stream:Je,NalByteStream:Ze},at=function(e){return e[0]==="I".charCodeAt(0)&&e[1]==="D".charCodeAt(0)&&e[2]==="3".charCodeAt(0)},st=function(e,t){var i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&e[t+5])>>4?20+i:10+i},ot=function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i};(nt=function(){var o=new Uint8Array,u=0;nt.prototype.init.call(this),this.setTimestamp=function(e){u=e},this.push=function(e){var t,i,n,r,a=0,s=0;for(o.length?(r=o.length,(o=new Uint8Array(e.byteLength+r)).set(o.subarray(0,r)),o.set(e,r)):o=e;3<=o.length-s;)if(o[s]!=="I".charCodeAt(0)||o[s+1]!=="D".charCodeAt(0)||o[s+2]!=="3".charCodeAt(0))if(255!=(255&o[s])||240!=(240&o[s+1]))s++;else{if(o.length-s<7)break;if(s+(a=ot(o,s))>o.length)break;n={type:"audio",data:o.subarray(s,s+a),pts:u,dts:u},this.trigger("data",n),s+=a}else{if(o.length-s<10)break;if(s+(a=st(o,s))>o.length)break;i={type:"timed-metadata",data:o.subarray(s,s+a)},this.trigger("data",i),s+=a}t=o.length-s,o=0<t?o.subarray(s):new Uint8Array}}).prototype=new ne;function ut(e,t){var i;if(e.length!==t.length)return!1;for(i=0;i<e.length;i++)if(e[i]!==t[i])return!1;return!0}function lt(e,t,i,n,r,a){return{start:{dts:e,pts:e+(i-t)},end:{dts:e+(n-t),pts:e+(r-i)},prependedContentDuration:a,baseMediaDecodeTime:e}}var ct,ht,dt,pt,ft=nt,mt=rt.H264Stream,gt=at,yt=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],vt=["width","height","profileIdc","levelIdc","profileCompatibility"];(ht=function(r,a){var s=[],o=0,u=0,l=0,c=1/0;a=a||{},ht.prototype.init.call(this),this.push=function(t){Te(r,t),r&&yt.forEach(function(e){r[e]=t[e]}),s.push(t)},this.setEarliestDts=function(e){u=e-r.timelineStartInfo.baseMediaDecodeTime},this.setVideoBaseMediaDecodeTime=function(e){c=e},this.setAudioAppendStart=function(e){l=e},this.flush=function(){var e,t,i,n;0!==s.length&&(e=ge(s,r,u),r.baseMediaDecodeTime=be(r,a.keepOriginalTimestamps),me(r,e,l,c),r.samples=ye(e),i=G.mdat(ve(e)),s=[],t=G.moof(o,[r]),n=new Uint8Array(t.byteLength+i.byteLength),o++,n.set(t),n.set(i,t.byteLength),_e(r),this.trigger("data",{track:r,boxes:n})),this.trigger("done","AudioSegmentStream")}}).prototype=new ne,(ct=function(c,h){var t,i,d=0,p=[],f=[];h=h||{},ct.prototype.init.call(this),delete c.minPTS,this.gopCache_=[],this.push=function(e){Te(c,e),"seq_parameter_set_rbsp"!==e.nalUnitType||t||(t=e.config,c.sps=[e.data],vt.forEach(function(e){c[e]=t[e]},this)),"pic_parameter_set_rbsp"!==e.nalUnitType||i||(i=e.data,c.pps=[e.data]),p.push(e)},this.flush=function(){for(var e,t,i,n,r,a,s,o,u=0;p.length&&"access_unit_delimiter_rbsp"!==p[0].nalUnitType;)p.shift();if(0===p.length)return this.resetStream_(),void this.trigger("done","VideoSegmentStream");if(e=re(p),(i=ae(e))[0][0].keyFrame||((t=this.getGopForFusion_(p[0],c))?(u=t.duration,i.unshift(t),i.byteLength+=t.byteLength,i.nalCount+=t.nalCount,i.pts=t.pts,i.dts=t.dts,i.duration+=t.duration):i=se(i)),f.length){var l;if(!(l=h.alignGopsAtEnd?this.alignGopsAtEnd_(i):this.alignGopsAtStart_(i)))return this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");_e(c),i=l}Te(c,i),c.samples=oe(i),r=G.mdat(ue(i)),c.baseMediaDecodeTime=be(c,h.keepOriginalTimestamps),this.trigger("processedGopsInfo",i.map(function(e){return{pts:e.pts,dts:e.dts,byteLength:e.byteLength}})),s=i[0],o=i[i.length-1],this.trigger("segmentTimingInfo",lt(c.baseMediaDecodeTime,s.dts,s.pts,o.dts+o.duration,o.pts+o.duration,u)),this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.trigger("baseMediaDecodeTime",c.baseMediaDecodeTime),this.trigger("timelineStartInfo",c.timelineStartInfo),n=G.moof(d,[c]),a=new Uint8Array(n.byteLength+r.byteLength),d++,a.set(n),a.set(r,n.byteLength),this.trigger("data",{track:c,boxes:a}),this.resetStream_(),this.trigger("done","VideoSegmentStream")},this.resetStream_=function(){_e(c),i=t=void 0},this.getGopForFusion_=function(e){var t,i,n,r,a,s=1/0;for(a=0;a<this.gopCache_.length;a++)n=(r=this.gopCache_[a]).gop,c.pps&&ut(c.pps[0],r.pps[0])&&c.sps&&ut(c.sps[0],r.sps[0])&&(n.dts<c.timelineStartInfo.dts||-1e4<=(t=e.dts-n.dts-n.duration)&&t<=45e3&&(!i||t<s)&&(i=r,s=t));return i?i.gop:null},this.alignGopsAtStart_=function(e){var t,i,n,r,a,s,o,u;for(a=e.byteLength,s=e.nalCount,o=e.duration,t=i=0;t<f.length&&i<e.length&&(n=f[t],r=e[i],n.pts!==r.pts);)r.pts>n.pts?t++:(i++,a-=r.byteLength,s-=r.nalCount,o-=r.duration);return 0===i?e:i===e.length?null:((u=e.slice(i)).byteLength=a,u.duration=o,u.nalCount=s,u.pts=u[0].pts,u.dts=u[0].dts,u)},this.alignGopsAtEnd_=function(e){var t,i,n,r,a,s,o;for(t=f.length-1,i=e.length-1,a=null,s=!1;0<=t&&0<=i;){if(n=f[t],r=e[i],n.pts===r.pts){s=!0;break}n.pts>r.pts?t--:(t===f.length-1&&(a=i),i--)}if(!s&&null===a)return null;if(0===(o=s?i:a))return e;var u=e.slice(o),l=u.reduce(function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e},{byteLength:0,duration:0,nalCount:0});return u.byteLength=l.byteLength,u.duration=l.duration,u.nalCount=l.nalCount,u.pts=u[0].pts,u.dts=u[0].dts,u},this.alignGopsWith=function(e){f=e}}).prototype=new ne,(pt=function(e,t){this.numberOfTracks=0,this.metadataStream=t,"undefined"!=typeof(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps&&(this.keepOriginalTimestamps=e.keepOriginalTimestamps),this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,pt.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBoxes.push(e.boxes),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track),void("audio"===e.track.type&&(this.audioTrack=e.track)))}}).prototype=new ne,pt.prototype.flush=function(e){var t,i,n,r,a=0,s={captions:[],captionStreams:{},metadata:[],info:{}},o=0;if(this.pendingTracks.length<this.numberOfTracks){if("VideoSegmentStream"!==e&&"AudioSegmentStream"!==e)return;if(this.remuxTracks)return;if(0===this.pendingTracks.length)return this.emittedTracks++,void(this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}for(this.videoTrack?(o=this.videoTrack.timelineStartInfo.pts,vt.forEach(function(e){s.info[e]=this.videoTrack[e]},this)):this.audioTrack&&(o=this.audioTrack.timelineStartInfo.pts,yt.forEach(function(e){s.info[e]=this.audioTrack[e]},this)),1===this.pendingTracks.length?s.type=this.pendingTracks[0].type:s.type="combined",this.emittedTracks+=this.pendingTracks.length,n=G.initSegment(this.pendingTracks),s.initSegment=new Uint8Array(n.byteLength),s.initSegment.set(n),s.data=new Uint8Array(this.pendingBytes),r=0;r<this.pendingBoxes.length;r++)s.data.set(this.pendingBoxes[r],a),a+=this.pendingBoxes[r].byteLength;for(r=0;r<this.pendingCaptions.length;r++)(t=this.pendingCaptions[r]).startTime=t.startPts,this.keepOriginalTimestamps||(t.startTime-=o),t.startTime/=9e4,t.endTime=t.endPts,this.keepOriginalTimestamps||(t.endTime-=o),t.endTime/=9e4,s.captionStreams[t.stream]=!0,s.captions.push(t);for(r=0;r<this.pendingMetadata.length;r++)(i=this.pendingMetadata[r]).cueTime=i.pts,this.keepOriginalTimestamps||(i.cueTime-=o),i.cueTime/=9e4,s.metadata.push(i);s.metadata.dispatchType=this.metadataStream.dispatchType,this.pendingTracks.length=0,this.videoTrack=null,this.pendingBoxes.length=0,this.pendingCaptions.length=0,this.pendingBytes=0,this.pendingMetadata.length=0,this.trigger("data",s),this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},(dt=function(n){var r,a,s=this,i=!0;dt.prototype.init.call(this),n=n||{},this.baseMediaDecodeTime=n.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var t={};(this.transmuxPipeline_=t).type="aac",t.metadataStream=new Ye.MetadataStream,t.aacStream=new ft,t.audioTimestampRolloverStream=new Ye.TimestampRolloverStream("audio"),t.timedMetadataTimestampRolloverStream=new Ye.TimestampRolloverStream("timed-metadata"),t.adtsStream=new tt,t.coalesceStream=new pt(n,t.metadataStream),t.headOfPipeline=t.aacStream,t.aacStream.pipe(t.audioTimestampRolloverStream).pipe(t.adtsStream),t.aacStream.pipe(t.timedMetadataTimestampRolloverStream).pipe(t.metadataStream).pipe(t.coalesceStream),t.metadataStream.on("timestamp",function(e){t.aacStream.setTimestamp(e.timeStamp)}),t.aacStream.on("data",function(e){"timed-metadata"!==e.type||t.audioSegmentStream||(a=a||{timelineStartInfo:{baseMediaDecodeTime:s.baseMediaDecodeTime},codec:"adts",type:"audio"},t.coalesceStream.numberOfTracks++,t.audioSegmentStream=new ht(a,n),t.adtsStream.pipe(t.audioSegmentStream).pipe(t.coalesceStream))}),t.coalesceStream.on("data",this.trigger.bind(this,"data")),t.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setupTsPipeline=function(){var i={};(this.transmuxPipeline_=i).type="ts",i.metadataStream=new Ye.MetadataStream,i.packetStream=new Ye.TransportPacketStream,i.parseStream=new Ye.TransportParseStream,i.elementaryStream=new Ye.ElementaryStream,i.videoTimestampRolloverStream=new Ye.TimestampRolloverStream("video"),i.audioTimestampRolloverStream=new Ye.TimestampRolloverStream("audio"),i.timedMetadataTimestampRolloverStream=new Ye.TimestampRolloverStream("timed-metadata"),i.adtsStream=new tt,i.h264Stream=new mt,i.captionStream=new Ye.CaptionStream,i.coalesceStream=new pt(n,i.metadataStream),i.headOfPipeline=i.packetStream,i.packetStream.pipe(i.parseStream).pipe(i.elementaryStream),i.elementaryStream.pipe(i.videoTimestampRolloverStream).pipe(i.h264Stream),i.elementaryStream.pipe(i.audioTimestampRolloverStream).pipe(i.adtsStream),i.elementaryStream.pipe(i.timedMetadataTimestampRolloverStream).pipe(i.metadataStream).pipe(i.coalesceStream),i.h264Stream.pipe(i.captionStream).pipe(i.coalesceStream),i.elementaryStream.on("data",function(e){var t;if("metadata"===e.type){for(t=e.tracks.length;t--;)r||"video"!==e.tracks[t].type?a||"audio"!==e.tracks[t].type||((a=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime):(r=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime;r&&!i.videoSegmentStream&&(i.coalesceStream.numberOfTracks++,i.videoSegmentStream=new ct(r,n),i.videoSegmentStream.on("timelineStartInfo",function(e){a&&(a.timelineStartInfo=e,i.audioSegmentStream.setEarliestDts(e.dts))}),i.videoSegmentStream.on("processedGopsInfo",s.trigger.bind(s,"gopInfo")),i.videoSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"videoSegmentTimingInfo")),i.videoSegmentStream.on("baseMediaDecodeTime",function(e){a&&i.audioSegmentStream.setVideoBaseMediaDecodeTime(e)}),i.h264Stream.pipe(i.videoSegmentStream).pipe(i.coalesceStream)),a&&!i.audioSegmentStream&&(i.coalesceStream.numberOfTracks++,i.audioSegmentStream=new ht(a,n),i.adtsStream.pipe(i.audioSegmentStream).pipe(i.coalesceStream))}}),i.coalesceStream.on("data",this.trigger.bind(this,"data")),i.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setBaseMediaDecodeTime=function(e){var t=this.transmuxPipeline_;n.keepOriginalTimestamps||(this.baseMediaDecodeTime=e),a&&(a.timelineStartInfo.dts=void 0,a.timelineStartInfo.pts=void 0,_e(a),n.keepOriginalTimestamps||(a.timelineStartInfo.baseMediaDecodeTime=e),t.audioTimestampRolloverStream&&t.audioTimestampRolloverStream.discontinuity()),r&&(t.videoSegmentStream&&(t.videoSegmentStream.gopCache_=[],t.videoTimestampRolloverStream.discontinuity()),r.timelineStartInfo.dts=void 0,r.timelineStartInfo.pts=void 0,_e(r),t.captionStream.reset(),n.keepOriginalTimestamps||(r.timelineStartInfo.baseMediaDecodeTime=e)),t.timedMetadataTimestampRolloverStream&&t.timedMetadataTimestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(e){a&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e)},this.alignGopsWith=function(e){r&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e)},this.push=function(e){if(i){var t=gt(e);t&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),i=!1}this.transmuxPipeline_.headOfPipeline.push(e)},this.flush=function(){i=!0,this.transmuxPipeline_.headOfPipeline.flush()},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset()}}).prototype=new ne;function _t(e){return new Date(1e3*e-20828448e5)}function bt(e){return{isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}}function Tt(e,t){for(var i=e,n=0;n<t.length;n++){var r=t[n];if(i<r.size)return r;i-=r.size}return null}function St(e,c){var n=K.findBox(e,["moof","traf"]),t=K.findBox(e,["mdat"]),h={},r=[];return t.forEach(function(e,t){var i=n[t];r.push({mdat:e,traf:i})}),r.forEach(function(e){var t,i=e.mdat,n=e.traf,r=K.findBox(n,["tfhd"]),a=Pt.parseTfhd(r[0]),s=a.trackId,o=K.findBox(n,["tfdt"]),u=0<o.length?Pt.parseTfdt(o[0]).baseMediaDecodeTime:0,l=K.findBox(n,["trun"]);c===s&&0<l.length&&(t=function(e,t,i){var n,r,a,s,o=new DataView(e.buffer,e.byteOffset,e.byteLength),u=[];for(r=0;r+4<e.length;r+=a)if(a=o.getUint32(r),r+=4,!(a<=0))switch(31&e[r]){case 6:var l=e.subarray(r+1,r+1+a),c=Tt(r,t);n={nalUnitType:"sei_rbsp",size:a,data:l,escapedRBSP:Lt(l),trackId:i},c?(n.pts=c.pts,n.dts=c.dts,s=c):(n.pts=s.pts,n.dts=s.dts),u.push(n)}return u}(i,function(e,t,i){var n=t,r=i.defaultSampleDuration||0,a=i.defaultSampleSize||0,s=i.trackId,o=[];return e.forEach(function(e){var t=Pt.parseTrun(e).samples;t.forEach(function(e){void 0===e.duration&&(e.duration=r),void 0===e.size&&(e.size=a),e.trackId=s,e.dts=n,void 0===e.compositionTimeOffset&&(e.compositionTimeOffset=0),e.pts=n+e.compositionTimeOffset,n+=e.duration}),o=o.concat(t)}),o}(l,u,a),s),h[s]||(h[s]=[]),h[s]=h[s].concat(t))}),h}var kt,wt,Ct={Transmuxer:dt,VideoSegmentStream:ct,AudioSegmentStream:ht,AUDIO_PROPERTIES:yt,VIDEO_PROPERTIES:vt,generateVideoSegmentTimingInfo:lt},Et=K.parseType,At={avc1:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{dataReferenceIndex:t.getUint16(6),width:t.getUint16(24),height:t.getUint16(26),horizresolution:t.getUint16(28)+t.getUint16(30)/16,vertresolution:t.getUint16(32)+t.getUint16(34)/16,frameCount:t.getUint16(40),depth:t.getUint16(74),config:kt(e.subarray(78,e.byteLength))}},avcC:function(e){var t,i,n,r,a=new DataView(e.buffer,e.byteOffset,e.byteLength),s={configurationVersion:e[0],avcProfileIndication:e[1],profileCompatibility:e[2],avcLevelIndication:e[3],lengthSizeMinusOne:3&e[4],sps:[],pps:[]},o=31&e[5];for(n=6,r=0;r<o;r++)i=a.getUint16(n),n+=2,s.sps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;for(t=e[n],n++,r=0;r<t;r++)i=a.getUint16(n),n+=2,s.pps.push(new Uint8Array(e.subarray(n,n+i))),n+=i;return s},btrt:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{bufferSizeDB:t.getUint32(0),maxBitrate:t.getUint32(4),avgBitrate:t.getUint32(8)}},esds:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),esId:e[6]<<8|e[7],streamPriority:31&e[8],decoderConfig:{objectProfileIndication:e[11],streamType:e[12]>>>2&63,bufferSize:e[13]<<16|e[14]<<8|e[15],maxBitrate:e[16]<<24|e[17]<<16|e[18]<<8|e[19],avgBitrate:e[20]<<24|e[21]<<16|e[22]<<8|e[23],decoderConfigDescriptor:{tag:e[24],length:e[25],audioObjectType:e[26]>>>3&31,samplingFrequencyIndex:(7&e[26])<<1|e[27]>>>7&1,channelConfiguration:e[27]>>>3&15}}}},ftyp:function(e){for(var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={majorBrand:Et(e.subarray(0,4)),minorVersion:t.getUint32(4),compatibleBrands:[]},n=8;n<e.byteLength;)i.compatibleBrands.push(Et(e.subarray(n,n+4))),n+=4;return i},dinf:function(e){return{boxes:kt(e)}},dref:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),dataReferences:kt(e.subarray(8))}},hdlr:function(e){var t={version:new DataView(e.buffer,e.byteOffset,e.byteLength).getUint8(0),flags:new Uint8Array(e.subarray(1,4)),handlerType:Et(e.subarray(8,12)),name:""},i=8;for(i=24;i<e.byteLength;i++){if(0===e[i]){i++;break}t.name+=String.fromCharCode(e[i])}return t.name=decodeURIComponent(escape(t.name)),t},mdat:function(e){return{byteLength:e.byteLength,nals:function(e){var t,i,n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=[];for(t=0;t+4<e.length;t+=i)if(i=n.getUint32(t),t+=4,i<=0)r.push("<span style='color:red;'>MALFORMED DATA</span>");else switch(31&e[t]){case 1:r.push("slice_layer_without_partitioning_rbsp");break;case 5:r.push("slice_layer_without_partitioning_rbsp_idr");break;case 6:r.push("sei_rbsp");break;case 7:r.push("seq_parameter_set_rbsp");break;case 8:r.push("pic_parameter_set_rbsp");break;case 9:r.push("access_unit_delimiter_rbsp");break;default:r.push("UNKNOWN NAL - "+e[t]&31)}return r}(e)}},mdhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=4,r={version:i.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),language:""};return 1===r.version?(n+=4,r.creationTime=_t(i.getUint32(n)),n+=8,r.modificationTime=_t(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=8):(r.creationTime=_t(i.getUint32(n)),n+=4,r.modificationTime=_t(i.getUint32(n)),n+=4,r.timescale=i.getUint32(n),n+=4),r.duration=i.getUint32(n),n+=4,t=i.getUint16(n),r.language+=String.fromCharCode(96+(t>>10)),r.language+=String.fromCharCode(96+((992&t)>>5)),r.language+=String.fromCharCode(96+(31&t)),r},mdia:function(e){return{boxes:kt(e)}},mfhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sequenceNumber:e[4]<<24|e[5]<<16|e[6]<<8|e[7]}},minf:function(e){return{boxes:kt(e)}},mp4a:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={dataReferenceIndex:t.getUint16(6),channelcount:t.getUint16(16),samplesize:t.getUint16(18),samplerate:t.getUint16(24)+t.getUint16(26)/65536};return 28<e.byteLength&&(i.streamDescriptor=kt(e.subarray(28))[0]),i},moof:function(e){return{boxes:kt(e)}},moov:function(e){return{boxes:kt(e)}},mvex:function(e){return{boxes:kt(e)}},mvhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=_t(t.getUint32(i)),i+=8,n.modificationTime=_t(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=8):(n.creationTime=_t(t.getUint32(i)),i+=4,n.modificationTime=_t(t.getUint32(i)),i+=4,n.timescale=t.getUint32(i),i+=4),n.duration=t.getUint32(i),i+=4,n.rate=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,i+=8,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,i+=24,n.nextTrackId=t.getUint32(i),n},pdin:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4)),rate:t.getUint32(4),initialDelay:t.getUint32(8)}},sdtp:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]};for(t=4;t<e.byteLength;t++)i.samples.push({dependsOn:(48&e[t])>>4,isDependedOn:(12&e[t])>>2,hasRedundancy:3&e[t]});return i},sidx:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),references:[],referenceId:i.getUint32(4),timescale:i.getUint32(8),earliestPresentationTime:i.getUint32(12),firstOffset:i.getUint32(16)},r=i.getUint16(22);for(t=24;r;t+=12,r--)n.references.push({referenceType:(128&e[t])>>>7,referencedSize:2147483647&i.getUint32(t),subsegmentDuration:i.getUint32(t+4),startsWithSap:!!(128&e[t+8]),sapType:(112&e[t+8])>>>4,sapDeltaTime:268435455&i.getUint32(t+8)});return n},smhd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),balance:e[4]+e[5]/256}},stbl:function(e){return{boxes:kt(e)}},stco:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),chunkOffsets:[]},r=i.getUint32(4);for(t=8;r;t+=4,r--)n.chunkOffsets.push(i.getUint32(t));return n},stsc:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n=i.getUint32(4),r={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleToChunks:[]};for(t=8;n;t+=12,n--)r.sampleToChunks.push({firstChunk:i.getUint32(t),samplesPerChunk:i.getUint32(t+4),sampleDescriptionIndex:i.getUint32(t+8)});return r},stsd:function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleDescriptions:kt(e.subarray(8))}},stsz:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),sampleSize:i.getUint32(4),entries:[]};for(t=12;t<e.byteLength;t+=4)n.entries.push(i.getUint32(t));return n},stts:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),timeToSamples:[]},r=i.getUint32(4);for(t=8;r;t+=8,r--)n.timeToSamples.push({sampleCount:i.getUint32(t),sampleDelta:i.getUint32(t+4)});return n},styp:function(e){return At.ftyp(e)},tfdt:function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4)),baseMediaDecodeTime:e[4]<<24|e[5]<<16|e[6]<<8|e[7]};return 1===t.version&&(t.baseMediaDecodeTime*=Math.pow(2,32),t.baseMediaDecodeTime+=e[8]<<24|e[9]<<16|e[10]<<8|e[11]),t},tfhd:function(e){var t,i=new DataView(e.buffer,e.byteOffset,e.byteLength),n={version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:i.getUint32(4)},r=1&n.flags[2],a=2&n.flags[2],s=8&n.flags[2],o=16&n.flags[2],u=32&n.flags[2],l=65536&n.flags[0],c=131072&n.flags[0];return t=8,r&&(t+=4,n.baseDataOffset=i.getUint32(12),t+=4),a&&(n.sampleDescriptionIndex=i.getUint32(t),t+=4),s&&(n.defaultSampleDuration=i.getUint32(t),t+=4),o&&(n.defaultSampleSize=i.getUint32(t),t+=4),u&&(n.defaultSampleFlags=i.getUint32(t)),l&&(n.durationIsEmpty=!0),!r&&c&&(n.baseDataOffsetIsMoof=!0),n},tkhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=4,n={version:t.getUint8(0),flags:new Uint8Array(e.subarray(1,4))};return 1===n.version?(i+=4,n.creationTime=_t(t.getUint32(i)),i+=8,n.modificationTime=_t(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=8):(n.creationTime=_t(t.getUint32(i)),i+=4,n.modificationTime=_t(t.getUint32(i)),i+=4,n.trackId=t.getUint32(i),i+=4,i+=4),n.duration=t.getUint32(i),i+=4,i+=8,n.layer=t.getUint16(i),i+=2,n.alternateGroup=t.getUint16(i),i+=2,n.volume=t.getUint8(i)+t.getUint8(i+1)/8,i+=2,i+=2,n.matrix=new Uint32Array(e.subarray(i,i+36)),i+=36,n.width=t.getUint16(i)+t.getUint16(i+2)/16,i+=4,n.height=t.getUint16(i)+t.getUint16(i+2)/16,n},traf:function(e){return{boxes:kt(e)}},trak:function(e){return{boxes:kt(e)}},trex:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:t.getUint32(4),defaultSampleDescriptionIndex:t.getUint32(8),defaultSampleDuration:t.getUint32(12),defaultSampleSize:t.getUint32(16),sampleDependsOn:3&e[20],sampleIsDependedOn:(192&e[21])>>6,sampleHasRedundancy:(48&e[21])>>4,samplePaddingValue:(14&e[21])>>1,sampleIsDifferenceSample:!!(1&e[21]),sampleDegradationPriority:t.getUint16(22)}},trun:function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]},n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=1&i.flags[2],a=4&i.flags[2],s=1&i.flags[1],o=2&i.flags[1],u=4&i.flags[1],l=8&i.flags[1],c=n.getUint32(4),h=8;for(r&&(i.dataOffset=n.getInt32(h),h+=4),a&&c&&(t={flags:bt(e.subarray(h,h+4))},h+=4,s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t),c--);c--;)t={},s&&(t.duration=n.getUint32(h),h+=4),o&&(t.size=n.getUint32(h),h+=4),u&&(t.flags=bt(e.subarray(h,h+4)),h+=4),l&&(t.compositionTimeOffset=n.getUint32(h),h+=4),i.samples.push(t);return i},"url ":function(e){return{version:e[0],flags:new Uint8Array(e.subarray(1,4))}},vmhd:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{version:e[0],flags:new Uint8Array(e.subarray(1,4)),graphicsmode:t.getUint16(4),opcolor:new Uint16Array([t.getUint16(6),t.getUint16(8),t.getUint16(10)])}}},Pt={inspect:kt=function(e){for(var t,i,n,r,a,s=0,o=[],u=new ArrayBuffer(e.length),l=new Uint8Array(u),c=0;c<e.length;++c)l[c]=e[c];for(t=new DataView(u);s<e.byteLength;)i=t.getUint32(s),n=Et(e.subarray(s+4,s+8)),r=1<i?s+i:e.byteLength,(a=(At[n]||function(e){return{data:e}})(e.subarray(s+8,r))).size=i,a.type=n,o.push(a),s=r;return o},textify:wt=function(e,t){var a;return t=t||0,a=new Array(2*t+1).join(" "),e.map(function(r,e){return a+r.type+"\n"+Object.keys(r).filter(function(e){return"type"!==e&&"boxes"!==e}).map(function(e){var t=a+" "+e+": ",i=r[e];if(i instanceof Uint8Array||i instanceof Uint32Array){var n=Array.prototype.slice.call(new Uint8Array(i.buffer,i.byteOffset,i.byteLength)).map(function(e){return" "+("00"+e.toString(16)).slice(-2)}).join("").match(/.{1,24}/g);return n?1===n.length?t+"<"+n.join("").slice(1)+">":t+"<\n"+n.map(function(e){return a+" "+e}).join("\n")+"\n"+a+" >":t+"<>"}return t+JSON.stringify(i,null,2).split("\n").map(function(e,t){return 0===t?e:a+" "+e}).join("\n")}).join("\n")+(r.boxes?"\n"+wt(r.boxes,t+1):"")}).join("\n")},parseTfdt:At.tfdt,parseHdlr:At.hdlr,parseTfhd:At.tfhd,parseTrun:At.trun,parseSidx:At.sidx},Lt=Ce,It=De.CaptionStream,Ot={generator:G,probe:K,Transmuxer:Ct.Transmuxer,AudioSegmentStream:Ct.AudioSegmentStream,VideoSegmentStream:Ct.VideoSegmentStream,CaptionParser:function(){var t,a,s,o,u,e=!1;this.isInitialized=function(){return e},this.init=function(){t=new It,e=!0,t.on("data",function(e){e.startTime=e.startPts/o,e.endTime=e.endPts/o,u.captions.push(e),u.captionStreams[e.stream]=!0})},this.isNewInit=function(e,t){return!(e&&0===e.length||t&&"object"==typeof t&&0===Object.keys(t).length)&&(s!==e[0]||o!==t[s])},this.parse=function(e,t,i){var n;if(!this.isInitialized())return null;if(!t||!i)return null;if(this.isNewInit(t,i))s=t[0],o=i[s];else if(!s||!o)return a.push(e),null;for(;0<a.length;){var r=a.shift();this.parse(r,t,i)}return null!==(n=function(e,t,i){return t?{seiNals:St(e,t)[t],timescale:i}:null}(e,s,o))&&n.seiNals?(this.pushNals(n.seiNals),this.flushStream(),u):null},this.pushNals=function(e){if(!this.isInitialized()||!e||0===e.length)return null;e.forEach(function(e){t.push(e)})},this.flushStream=function(){if(!this.isInitialized())return null;t.flush()},this.clearParsedCaptions=function(){u.captions=[],u.captionStreams={}},this.resetCaptionStream=function(){if(!this.isInitialized())return null;t.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){a=[],o=s=null,u?this.clearParsedCaptions():u={captions:[],captionStreams:{}},this.resetCaptionStream()},this.reset()}};function xt(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}var Ut=(function(e,t,i){return t&&xt(e.prototype,t),i&&xt(e,i),e}(Dt,[{key:"init",value:function(){this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new Ot.Transmuxer(this.options),function(n,e){e.on("data",function(e){var t=e.initSegment;e.initSegment={data:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength};var i=e.data;e.data=i.buffer,n.postMessage({action:"data",segment:e,byteOffset:i.byteOffset,byteLength:i.byteLength},[e.data])}),e.captionStream&&e.captionStream.on("data",function(e){n.postMessage({action:"caption",data:e})}),e.on("done",function(e){n.postMessage({action:"done"})}),e.on("gopInfo",function(e){n.postMessage({action:"gopInfo",gopInfo:e})}),e.on("videoSegmentTimingInfo",function(e){n.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:e})})}(this.self,this.transmuxer)}},{key:"push",value:function(e){var t=new Uint8Array(e.data,e.byteOffset,e.byteLength);this.transmuxer.push(t)}},{key:"reset",value:function(){this.init()}},{key:"setTimestampOffset",value:function(e){var t=e.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(9e4*t))}},{key:"setAudioAppendStart",value:function(e){this.transmuxer.setAudioAppendStart(Math.ceil(9e4*e.appendStart))}},{key:"flush",value:function(e){this.transmuxer.flush()}},{key:"resetCaptions",value:function(){this.transmuxer.resetCaptions()}},{key:"alignGopsWith",value:function(e){this.transmuxer.alignGopsWith(e.gopsToAlignWith.slice())}}]),Dt);function Dt(e,t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,Dt),this.options=t||{},this.self=e,this.init()}new function(t){t.onmessage=function(e){"init"===e.data.action&&e.data.options?this.messageHandlers=new Ut(t,e.data.options):(this.messageHandlers||(this.messageHandlers=new Ut(t)),e.data&&e.data.action&&"init"!==e.data.action&&this.messageHandlers[e.data.action]&&this.messageHandlers[e.data.action](e.data))}}(Rt)}()}),Gh={videoCodec:"avc1",videoObjectTypeIndicator:".4d400d",audioProfile:"2"},$h=(xc(Xh,bs.EventTarget),Ic(Xh,[{key:"data_",value:function(e){var t=e.data.segment;t.data=new Uint8Array(t.data,e.data.byteOffset,e.data.byteLength),t.initSegment=new Uint8Array(t.initSegment.data,t.initSegment.byteOffset,t.initSegment.byteLength),function(e,t,i){var n=t.player_;if(i.captions&&i.captions.length)for(var r in e.inbandTextTracks_||(e.inbandTextTracks_={}),i.captionStreams)if(!e.inbandTextTracks_[r]){n.tech_.trigger({type:"usage",name:"hls-608"});var a=n.textTracks().getTrackById(r);e.inbandTextTracks_[r]=a||n.addRemoteTextTrack({kind:"captions",id:r,label:r},!1).track}i.metadata&&i.metadata.length&&!e.metadataTrack_&&(e.metadataTrack_=n.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,e.metadataTrack_.inBandMetadataTrackDispatchType=i.metadata.dispatchType)}(this,this.mediaSource_,t),this.pendingBuffers_.push(t)}},{key:"done_",value:function(e){"closed"!==this.mediaSource_.readyState?this.processPendingSegments_():this.pendingBuffers_.length=0}},{key:"videoSegmentTimingInfo_",value:function(e){var t={start:{decode:e.start.dts/9e4,presentation:e.start.pts/9e4},end:{decode:e.end.dts/9e4,presentation:e.end.pts/9e4},baseMediaDecodeTime:e.baseMediaDecodeTime/9e4};e.prependedContentDuration&&(t.prependedContentDuration=e.prependedContentDuration/9e4),this.trigger({type:"videoSegmentTimingInfo",videoSegmentTimingInfo:t})}},{key:"createRealSourceBuffers_",value:function(){var n=this,r=["audio","video"];r.forEach(function(t){if(n[t+"Codec_"]&&!n[t+"Buffer_"]){var i=null;if(n.mediaSource_[t+"Buffer_"])(i=n.mediaSource_[t+"Buffer_"]).updating=!1;else{var e=t+'/mp4;codecs="'+n[t+"Codec_"]+'"';i=function(e,t){var i=e.addSourceBuffer(t),n=Object.create(null);function r(t){"function"==typeof i[t]?n[t]=function(){return i[t].apply(i,arguments)}:"undefined"==typeof n[t]&&Object.defineProperty(n,t,{get:function(){return i[t]},set:function(e){return i[t]=e}})}for(var a in n.updating=!1,n.realBuffer_=i)r(a);return n}(n.mediaSource_.nativeMediaSource_,e),n.mediaSource_[t+"Buffer_"]=i}n[t+"Buffer_"]=i,["update","updatestart","updateend"].forEach(function(e){i.addEventListener(e,function(){if("audio"!==t||!n.audioDisabled_)return"updateend"===e&&(n[t+"Buffer_"].updating=!1),r.every(function(e){return!("audio"!==e||!n.audioDisabled_)||t===e||!n[e+"Buffer_"]||!n[e+"Buffer_"].updating})?n.trigger(e):void 0})})}})}},{key:"appendBuffer",value:function(e){if(this.bufferUpdating_=!0,this.audioBuffer_&&this.audioBuffer_.buffered.length){var t=this.audioBuffer_.buffered;this.transmuxer_.postMessage({action:"setAudioAppendStart",appendStart:t.end(t.length-1)})}this.videoBuffer_&&this.transmuxer_.postMessage({action:"alignGopsWith",gopsToAlignWith:function(e,t,i){if("undefined"==typeof t||null===t||!e.length)return[];var n=Math.ceil(9e4*(t-i+3)),r=void 0;for(r=0;r<e.length&&!(e[r].pts>n);r++);return e.slice(r)}(this.gopBuffer_,this.mediaSource_.player_?this.mediaSource_.player_.currentTime():null,this.timeMapping_)}),this.transmuxer_.postMessage({action:"push",data:e.buffer,byteOffset:e.byteOffset,byteLength:e.byteLength},[e.buffer]),this.transmuxer_.postMessage({action:"flush"})}},{key:"appendGopInfo_",value:function(e){this.gopBuffer_=function(e,t,i){if(!t.length)return e;if(i)return t.slice();for(var n=t[0].pts,r=0;r<e.length&&!(e[r].pts>=n);r++);return e.slice(0,r).concat(t)}(this.gopBuffer_,e.data.gopInfo,this.safeAppend_)}},{key:"remove",value:function(e,t){if(this.videoBuffer_&&(this.videoBuffer_.updating=!0,this.videoBuffer_.remove(e,t),this.gopBuffer_=function(e,t,i,n){for(var r=Math.ceil(9e4*(t-n)),a=Math.ceil(9e4*(i-n)),s=e.slice(),o=e.length;o--&&!(e[o].pts<=a););if(-1===o)return s;for(var u=o+1;u--&&!(e[u].pts<=r););return u=Math.max(u,0),s.splice(u,o-u+1),s}(this.gopBuffer_,e,t,this.timeMapping_)),!this.audioDisabled_&&this.audioBuffer_&&(this.audioBuffer_.updating=!0,this.audioBuffer_.remove(e,t)),yh(e,t,this.metadataTrack_),this.inbandTextTracks_)for(var i in this.inbandTextTracks_)yh(e,t,this.inbandTextTracks_[i])}},{key:"processPendingSegments_",value:function(){var e={video:{segments:[],bytes:0},audio:{segments:[],bytes:0},captions:[],metadata:[]};e=this.pendingBuffers_.reduce(function(e,t){var i=t.type,n=t.data,r=t.initSegment;return e[i].segments.push(n),e[i].bytes+=n.byteLength,e[i].initSegment=r,t.captions&&(e.captions=e.captions.concat(t.captions)),t.info&&(e[i].info=t.info),t.metadata&&(e.metadata=e.metadata.concat(t.metadata)),e},e),this.videoBuffer_||this.audioBuffer_||(0===e.video.bytes&&(this.videoCodec_=null),0===e.audio.bytes&&(this.audioCodec_=null),this.createRealSourceBuffers_()),e.audio.info&&this.mediaSource_.trigger({type:"audioinfo",info:e.audio.info}),e.video.info&&this.mediaSource_.trigger({type:"videoinfo",info:e.video.info}),this.appendAudioInitSegment_&&(!this.audioDisabled_&&this.audioBuffer_&&(e.audio.segments.unshift(e.audio.initSegment),e.audio.bytes+=e.audio.initSegment.byteLength),this.appendAudioInitSegment_=!1);var t=!1;this.videoBuffer_&&e.video.bytes?(e.video.segments.unshift(e.video.initSegment),e.video.bytes+=e.video.initSegment.byteLength,this.concatAndAppendSegments_(e.video,this.videoBuffer_)):!this.videoBuffer_||!this.audioDisabled_&&this.audioBuffer_||(t=!0),_h(this,e.captions,e.metadata),!this.audioDisabled_&&this.audioBuffer_&&this.concatAndAppendSegments_(e.audio,this.audioBuffer_),this.pendingBuffers_.length=0,t&&this.trigger("updateend"),this.bufferUpdating_=!1}},{key:"concatAndAppendSegments_",value:function(e,t){var i=0,n=void 0;if(e.bytes){n=new Uint8Array(e.bytes),e.segments.forEach(function(e){n.set(e,i),i+=e.byteLength});try{t.updating=!0,t.appendBuffer(n)}catch(e){this.mediaSource_.player_&&this.mediaSource_.player_.error({code:-3,type:"APPEND_BUFFER_ERR",message:e.message,originalError:e})}}}},{key:"abort",value:function(){this.videoBuffer_&&this.videoBuffer_.abort(),!this.audioDisabled_&&this.audioBuffer_&&this.audioBuffer_.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"reset"}),this.pendingBuffers_.length=0,this.bufferUpdating_=!1}}]),Xh);function Xh(e,t){Lc(this,Xh);var i=Uc(this,(Xh.__proto__||Object.getPrototypeOf(Xh)).call(this,bs.EventTarget));i.timestampOffset_=0,i.pendingBuffers_=[],i.bufferUpdating_=!1,i.mediaSource_=e,i.codecs_=t,i.audioCodec_=null,i.videoCodec_=null,i.audioDisabled_=!1,i.appendAudioInitSegment_=!0,i.gopBuffer_=[],i.timeMapping_=0,i.safeAppend_=11<=bs.browser.IE_VERSION;var n={remux:!1,alignGopsAtEnd:i.safeAppend_};return i.codecs_.forEach(function(e){qh(e)?i.audioCodec_=e:zh(e)&&(i.videoCodec_=e)}),i.transmuxer_=new Wh,i.transmuxer_.postMessage({action:"init",options:n}),i.transmuxer_.onmessage=function(e){return"data"===e.data.action?i.data_(e):"done"===e.data.action?i.done_(e):"gopInfo"===e.data.action?i.appendGopInfo_(e):"videoSegmentTimingInfo"===e.data.action?i.videoSegmentTimingInfo_(e.data.videoSegmentTimingInfo):void 0},Object.defineProperty(i,"timestampOffset",{get:function(){return this.timestampOffset_},set:function(e){"number"==typeof e&&0<=e&&(this.timestampOffset_=e,this.appendAudioInitSegment_=!0,this.gopBuffer_.length=0,this.timeMapping_=0,this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:e}))}}),Object.defineProperty(i,"appendWindowStart",{get:function(){return(this.videoBuffer_||this.audioBuffer_).appendWindowStart},set:function(e){this.videoBuffer_&&(this.videoBuffer_.appendWindowStart=e),this.audioBuffer_&&(this.audioBuffer_.appendWindowStart=e)}}),Object.defineProperty(i,"updating",{get:function(){return!!(this.bufferUpdating_||!this.audioDisabled_&&this.audioBuffer_&&this.audioBuffer_.updating||this.videoBuffer_&&this.videoBuffer_.updating)}}),Object.defineProperty(i,"buffered",{get:function(){return function(e,t,i){var n=null,r=null,a=0,s=[],o=[];if(!e&&!t)return bs.createTimeRange();if(!e)return t.buffered;if(!t)return e.buffered;if(i)return e.buffered;if(0===e.buffered.length&&0===t.buffered.length)return bs.createTimeRange();for(var u=e.buffered,l=t.buffered,c=u.length;c--;)s.push({time:u.start(c),type:"start"}),s.push({time:u.end(c),type:"end"});for(c=l.length;c--;)s.push({time:l.start(c),type:"start"}),s.push({time:l.end(c),type:"end"});for(s.sort(function(e,t){return e.time-t.time}),c=0;c<s.length;c++)"start"===s[c].type?2===++a&&(n=s[c].time):"end"===s[c].type&&1===--a&&(r=s[c].time),null!==n&&null!==r&&(o.push([n,r]),r=n=null);return bs.createTimeRanges(o)}(this.videoBuffer_,this.audioBuffer_,this.audioDisabled_)}}),i}var Kh=(xc(Yh,bs.EventTarget),Ic(Yh,[{key:"addSeekableRange_",value:function(e,t){var i=void 0;if(this.duration!==1/0)throw(i=new Error("MediaSource.addSeekableRange() can only be invoked when the duration is Infinity")).name="InvalidStateError",i.code=11,i;(t>this.nativeMediaSource_.duration||isNaN(this.nativeMediaSource_.duration))&&(this.nativeMediaSource_.duration=t)}},{key:"addSourceBuffer",value:function(e){var t=void 0,i=function(e){var r={type:"",parameters:{}},t=e.trim().split(";");return r.type=t.shift().trim(),t.forEach(function(e){var t=e.trim().split("=");if(1<t.length){var i=t[0].replace(/"/g,"").trim(),n=t[1].replace(/"/g,"").trim();r.parameters[i]=n}}),r}(e);if(/^(video|audio)\/mp2t$/i.test(i.type)){var n=[];i.parameters&&i.parameters.codecs&&(n=i.parameters.codecs.split(","),n=(n=jh(n)).filter(function(e){return qh(e)||zh(e)})),0===n.length&&(n=["avc1.4d400d","mp4a.40.2"]),t=new $h(this,n),0!==this.sourceBuffers.length&&(this.sourceBuffers[0].createRealSourceBuffers_(),t.createRealSourceBuffers_(),this.sourceBuffers[0].audioDisabled_=!0)}else t=this.nativeMediaSource_.addSourceBuffer(e);return this.sourceBuffers.push(t),t}}]),Yh);function Yh(){Lc(this,Yh);var a=Uc(this,(Yh.__proto__||Object.getPrototypeOf(Yh)).call(this)),e=void 0;for(e in a.nativeMediaSource_=new v.MediaSource,a.nativeMediaSource_)e in Yh.prototype||"function"!=typeof a.nativeMediaSource_[e]||(a[e]=a.nativeMediaSource_[e].bind(a.nativeMediaSource_));return a.duration_=NaN,Object.defineProperty(a,"duration",{get:function(){return this.duration_===1/0?this.duration_:this.nativeMediaSource_.duration},set:function(e){(this.duration_=e)===1/0||(this.nativeMediaSource_.duration=e)}}),Object.defineProperty(a,"seekable",{get:function(){return this.duration_===1/0?bs.createTimeRanges([[0,this.nativeMediaSource_.duration]]):this.nativeMediaSource_.seekable}}),Object.defineProperty(a,"readyState",{get:function(){return this.nativeMediaSource_.readyState}}),Object.defineProperty(a,"activeSourceBuffers",{get:function(){return this.activeSourceBuffers_}}),a.sourceBuffers=[],a.activeSourceBuffers_=[],a.updateActiveSourceBuffers_=function(){if(a.activeSourceBuffers_.length=0,1===a.sourceBuffers.length){var e=a.sourceBuffers[0];return e.appendAudioInitSegment_=!0,e.audioDisabled_=!e.audioCodec_,void a.activeSourceBuffers_.push(e)}for(var i=!1,n=!0,t=0;t<a.player_.audioTracks().length;t++){var r=a.player_.audioTracks()[t];if(r.enabled&&"main"!==r.kind){n=!(i=!0);break}}a.sourceBuffers.forEach(function(e,t){if(e.appendAudioInitSegment_=!0,e.videoCodec_&&e.audioCodec_)e.audioDisabled_=i;else if(e.videoCodec_&&!e.audioCodec_)e.audioDisabled_=!0,n=!1;else if(!e.videoCodec_&&e.audioCodec_&&(e.audioDisabled_=t?n:!n,e.audioDisabled_))return;a.activeSourceBuffers_.push(e)})},a.onPlayerMediachange_=function(){a.sourceBuffers.forEach(function(e){e.appendAudioInitSegment_=!0})},a.onHlsReset_=function(){a.sourceBuffers.forEach(function(e){e.transmuxer_&&e.transmuxer_.postMessage({action:"resetCaptions"})})},a.onHlsSegmentTimeMapping_=function(t){a.sourceBuffers.forEach(function(e){return e.timeMapping_=t.mapping})},["sourceopen","sourceclose","sourceended"].forEach(function(e){this.nativeMediaSource_.addEventListener(e,this.trigger.bind(this))},a),a.on("sourceopen",function(e){var t=h.querySelector('[src="'+a.url_+'"]');t&&(a.player_=bs(t.parentNode),a.player_&&(a.player_.tech_.on("hls-reset",a.onHlsReset_),a.player_.tech_.on("hls-segment-time-mapping",a.onHlsSegmentTimeMapping_),a.player_.audioTracks&&a.player_.audioTracks()&&(a.player_.audioTracks().on("change",a.updateActiveSourceBuffers_),a.player_.audioTracks().on("addtrack",a.updateActiveSourceBuffers_),a.player_.audioTracks().on("removetrack",a.updateActiveSourceBuffers_)),a.player_.on("mediachange",a.onPlayerMediachange_)))}),a.on("sourceended",function(e){for(var t=vh(a.duration),i=0;i<a.sourceBuffers.length;i++){var n=a.sourceBuffers[i],r=n.metadataTrack_&&n.metadataTrack_.cues;r&&r.length&&(r[r.length-1].endTime=t)}}),a.on("sourceclose",function(e){this.sourceBuffers.forEach(function(e){e.transmuxer_&&e.transmuxer_.terminate()}),this.sourceBuffers.length=0,this.player_&&(this.player_.audioTracks&&this.player_.audioTracks()&&(this.player_.audioTracks().off("change",this.updateActiveSourceBuffers_),this.player_.audioTracks().off("addtrack",this.updateActiveSourceBuffers_),this.player_.audioTracks().off("removetrack",this.updateActiveSourceBuffers_)),this.player_.el_&&this.player_.off("mediachange",this.onPlayerMediachange_),this.player_.tech_&&this.player_.tech_.el_&&(this.player_.tech_.off("hls-reset",this.onHlsReset_),this.player_.tech_.off("hls-segment-time-mapping",this.onHlsSegmentTimeMapping_)))}),a}var Qh=0;bs.mediaSources={};function Jh(e,t){var i=bs.mediaSources[e];if(!i)throw new Error("Media Source not found (Video.js)");i.trigger({type:"sourceopen",swfId:t})}function Zh(){return!!v.MediaSource&&!!v.MediaSource.isTypeSupported&&v.MediaSource.isTypeSupported('video/mp4;codecs="avc1.4d400d,mp4a.40.2"')}function ed(){if(this.MediaSource={open:Jh,supportsNativeMediaSources:Zh},Zh())return new Kh;throw new Error("Cannot use create a virtual MediaSource for this video")}ed.open=Jh,ed.supportsNativeMediaSources=Zh;var td={createObjectURL:function(e){var t=void 0;return e instanceof Kh?(t=v.URL.createObjectURL(e.nativeMediaSource_),e.url_=t):e instanceof Kh?(t="blob:vjs-media-source/"+Qh,Qh++,bs.mediaSources[t]=e,t):(t=v.URL.createObjectURL(e),e.url_=t)}};bs.MediaSource=ed,bs.URL=td;function id(e,t){for(var s=void 0,o=sd(e,{duration:t.duration,minimumUpdatePeriod:t.minimumUpdatePeriod}),i=0;i<t.playlists.length;i++){var n=Rc(o,t.playlists[i]);n?o=n:s=!0}return Dc(t,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r=e.playlists[0].uri,a=Rc(o,e.playlists[0]);a&&((o=a).mediaGroups[t][i][n].playlists[0]=o.playlists[r],s=!1)}}),s?null:o}function nd(e){var t=e.byterange.offset+e.byterange.length-1;return e.uri+"-"+e.byterange.offset+"-"+t}function rd(e,t){var i,n,r={};for(var a in e){var s=e[a].sidx;if(s){var o=nd(s);if(!t[o])break;var u=t[o].sidxInfo;i=u,n=s,(Boolean(!i.map&&!n.map)||Boolean(i.map&&n.map&&i.map.byterange.offset===n.map.byterange.offset&&i.map.byterange.length===n.map.byterange.length))&&i.uri===n.uri&&i.byterange.offset===n.byterange.offset&&i.byterange.length===n.byterange.length&&(r[o]=t[o])}}return r}function ad(e,t,i,n,r){var a={uri:Pc(n.handleManifestRedirects,e.resolvedUri),byterange:e.byterange,playlist:t};return i(bs.mergeOptions(a,{responseType:"arraybuffer",headers:nh(a)}),r)}var sd=bs.mergeOptions,od=(xc(ud,bs.EventTarget),Ic(ud,[{key:"setupChildLoader",value:function(e,t){this.masterPlaylistLoader_=e,this.childPlaylist_=t}},{key:"dispose",value:function(){this.stopRequest(),this.loadedPlaylists_={},v.clearTimeout(this.minimumUpdatePeriodTimeout_),v.clearTimeout(this.mediaRequest_),v.clearTimeout(this.mediaUpdateTimeout)}},{key:"hasPendingRequest",value:function(){return this.request||this.mediaRequest_}},{key:"stopRequest",value:function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort()}}},{key:"sidxRequestFinished_",value:function(r,a,s,o){var u=this;return function(e,t){if(u.request){if(u.request=null,e)return u.error={status:t.status,message:"DASH playlist request error at URL: "+r.uri,response:t.response,code:2},s&&(u.state=s),u.trigger("error"),o(a,null);var i=new Uint8Array(t.response),n=bu.parseSidx(i.subarray(8));return o(a,n)}}}},{key:"media",value:function(i){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var r=this.state;if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}var e=!this.media_||i.uri!==this.media_.uri;if(e&&this.loadedPlaylists_[i.uri]&&this.loadedPlaylists_[i.uri].endList)return this.state="HAVE_METADATA",this.media_=i,void(e&&(this.trigger("mediachanging"),this.trigger("mediachange")));if(e)if(this.media_&&this.trigger("mediachanging"),i.sidx){var t=void 0,a=void 0;a=this.masterPlaylistLoader_?(t=this.masterPlaylistLoader_.master,this.masterPlaylistLoader_.sidxMapping_):(t=this.master,this.sidxMapping_);var s=nd(i.sidx);a[s]={sidxInfo:i.sidx},this.request=ad(i.sidx,i,this.hls_.xhr,{handleManifestRedirects:this.handleManifestRedirects},this.sidxRequestFinished_(i,t,r,function(e,t){if(!e||!t)throw new Error("failed to request sidx");a[s].sidx=t,n.haveMetadata({startingState:r,playlist:e.playlists[i.uri]})}))}else this.mediaRequest_=v.setTimeout(this.haveMetadata.bind(this,{startingState:r,playlist:i}),0)}},{key:"haveMetadata",value:function(e){var t=e.startingState,i=e.playlist;this.state="HAVE_METADATA",this.loadedPlaylists_[i.uri]=i,this.mediaRequest_=null,this.refreshMedia_(i.uri),"HAVE_MASTER"===t?this.trigger("loadedmetadata"):this.trigger("mediachange")}},{key:"pause",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.minimumUpdatePeriodTimeout_),"HAVE_NOTHING"===this.state&&(this.started=!1)}},{key:"load",value:function(e){var t=this;v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.minimumUpdatePeriodTimeout_);var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=v.setTimeout(function(){return t.load()},n)}else this.started?this.trigger("loadedplaylist"):this.start()}},{key:"parseMasterXml",value:function(){var a=vo(this.masterXml_,{manifestUri:this.srcUrl,clientOffset:this.clientOffset_,sidxMapping:this.sidxMapping_});a.uri=this.srcUrl;for(var e=0;e<a.playlists.length;e++){var t="placeholder-uri-"+e;a.playlists[e].uri=t,a.playlists[t]=a.playlists[e]}return Dc(a,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r="placeholder-uri-"+t+"-"+i+"-"+n;e.playlists[0].uri=r,a.playlists[r]=e.playlists[0]}}),Mc(a),Bc(a),a}},{key:"start",value:function(){var i=this;this.started=!0,this.masterPlaylistLoader_?this.mediaRequest_=v.setTimeout(this.haveMaster_.bind(this),0):this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(i.request){if(i.request=null,e)return i.error={status:t.status,message:"DASH playlist request error at URL: "+i.srcUrl,responseText:t.responseText,code:2},"HAVE_NOTHING"===i.state&&(i.started=!1),i.trigger("error");i.masterXml_=t.responseText,t.responseHeaders&&t.responseHeaders.date?i.masterLoaded_=Date.parse(t.responseHeaders.date):i.masterLoaded_=Date.now(),i.srcUrl=Pc(i.handleManifestRedirects,i.srcUrl,t),i.syncClientServerClock_(i.onClientServerClockSync_.bind(i))}})}},{key:"syncClientServerClock_",value:function(n){var r=this,a=_o(this.masterXml_);return null===a?(this.clientOffset_=this.masterLoaded_-Date.now(),n()):"DIRECT"===a.method?(this.clientOffset_=a.value-Date.now(),n()):void(this.request=this.hls_.xhr({uri:Ac(this.srcUrl,a.value),method:a.method,withCredentials:this.withCredentials},function(e,t){if(r.request){if(e)return r.clientOffset_=r.masterLoaded_-Date.now(),n();var i=void 0;i="HEAD"===a.method?t.responseHeaders&&t.responseHeaders.date?Date.parse(t.responseHeaders.date):r.masterLoaded_:Date.parse(t.responseText),r.clientOffset_=i-Date.now(),n()}}))}},{key:"haveMaster_",value:function(){this.state="HAVE_MASTER",this.mediaRequest_=null,this.masterPlaylistLoader_?this.media_||this.media(this.childPlaylist_):(this.master=this.parseMasterXml(),this.trigger("loadedplaylist"))}},{key:"onClientServerClockSync_",value:function(){var e=this;this.haveMaster_(),this.hasPendingRequest()||this.media_||this.media(this.master.playlists[0]),this.master&&this.master.minimumUpdatePeriod&&(this.minimumUpdatePeriodTimeout_=v.setTimeout(function(){e.trigger("minimumUpdatePeriod")},this.master.minimumUpdatePeriod))}},{key:"refreshXml_",value:function(){var s=this;this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(s.request){if(s.request=null,e)return s.error={status:t.status,message:"DASH playlist request error at URL: "+s.srcUrl,responseText:t.responseText,code:2},"HAVE_NOTHING"===s.state&&(s.started=!1),s.trigger("error");s.masterXml_=t.responseText,s.sidxMapping_=function(e,t,i,a){var n=vo(e,{manifestUri:t,clientOffset:i}),s=rd(n.playlists,a);return Dc(n,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r=e.playlists;s=sd(s,rd(r,a))}}),s}(s.masterXml_,s.srcUrl,s.clientOffset_,s.sidxMapping_);var i=s.parseMasterXml(),n=id(s.master,i);if(n){var r=nd(s.media().sidx);if(s.sidxMapping_[r])s.master=n;else{var a=s.media();s.request=ad(a.sidx,a,s.hls_.xhr,{handleManifestRedirects:s.handleManifestRedirects},s.sidxRequestFinished_(a,i,s.state,function(e,t){if(!e||!t)throw new Error("failed to request sidx on minimumUpdatePeriod");s.sidxMapping_[r].sidx=t,s.minimumUpdatePeriodTimeout_=v.setTimeout(function(){s.trigger("minimumUpdatePeriod")},s.master.minimumUpdatePeriod),s.refreshMedia_(s.media().uri)}))}}s.minimumUpdatePeriodTimeout_=v.setTimeout(function(){s.trigger("minimumUpdatePeriod")},s.master.minimumUpdatePeriod)}})}},{key:"refreshMedia_",value:function(e){var t=this;if(!e)throw new Error("refreshMedia_ must take a media uri");var i=void 0,n=void 0;n=this.masterPlaylistLoader_?(i=this.masterPlaylistLoader_.master,this.masterPlaylistLoader_.parseMasterXml()):(i=this.master,this.parseMasterXml());var r=id(i,n);r?(this.masterPlaylistLoader_?this.masterPlaylistLoader_.master=r:this.master=r,this.media_=r.playlists[e]):(this.media_=n.playlists[e],this.trigger("playlistunchanged")),this.media().endList||(this.mediaUpdateTimeout=v.setTimeout(function(){t.trigger("mediaupdatetimeout")},Nc(this.media(),!!r))),this.trigger("loadedplaylist")}}]),ud);function ud(e,t){var i=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},n=arguments[3];Lc(this,ud);var r=Uc(this,(ud.__proto__||Object.getPrototypeOf(ud)).call(this)),a=i.withCredentials,s=void 0!==a&&a,o=i.handleManifestRedirects,u=void 0!==o&&o;if(r.hls_=t,r.withCredentials=s,r.handleManifestRedirects=u,!e)throw new Error("A non-empty playlist URL or playlist is required");return r.on("minimumUpdatePeriod",function(){r.refreshXml_()}),r.on("mediaupdatetimeout",function(){r.refreshMedia_(r.media().uri)}),r.state="HAVE_NOTHING",r.loadedPlaylists_={},"string"==typeof e?(r.srcUrl=e,r.sidxMapping_={},Uc(r)):(r.setupChildLoader(n,e),r)}function ld(e){return bs.log.debug?bs.log.debug.bind(bs,"VHS:",e+" >"):function(){}}function cd(){}var hd=(Ic(dd,[{key:"createSourceBuffer_",value:function(e,t){var i=this;this.sourceBuffer_=this.mediaSource.addSourceBuffer(e),this.logger_("created SourceBuffer"),t&&(t.trigger("sourcebufferadded"),this.mediaSource.sourceBuffers.length<2)?t.on("sourcebufferadded",function(){i.start_()}):this.start_()}},{key:"start_",value:function(){var t=this;this.started_=!0,this.onUpdateendCallback_=function(){var e=t.pendingCallback_;t.pendingCallback_=null,t.sourceBuffer_.removing=!1,t.logger_("buffered ["+mh(t.buffered())+"]"),e&&e(),t.runCallback_()},this.sourceBuffer_.addEventListener("updateend",this.onUpdateendCallback_),this.runCallback_()}},{key:"abort",value:function(e){var t=this;this.processedAppend_&&this.queueCallback_(function(){t.sourceBuffer_.abort()},e)}},{key:"appendBuffer",value:function(e,t){var i=this;this.processedAppend_=!0,this.queueCallback_(function(){e.videoSegmentTimingInfoCallback&&i.sourceBuffer_.addEventListener("videoSegmentTimingInfo",e.videoSegmentTimingInfoCallback),i.sourceBuffer_.appendBuffer(e.bytes)},function(){e.videoSegmentTimingInfoCallback&&i.sourceBuffer_.removeEventListener("videoSegmentTimingInfo",e.videoSegmentTimingInfoCallback),t()})}},{key:"buffered",value:function(){return this.sourceBuffer_?this.sourceBuffer_.buffered:bs.createTimeRanges()}},{key:"remove",value:function(e,t,i){var n=this,r=2<arguments.length&&void 0!==i?i:cd;this.processedAppend_&&this.queueCallback_(function(){n.logger_("remove ["+e+" => "+t+"]"),n.sourceBuffer_.removing=!0,n.sourceBuffer_.remove(e,t)},r)}},{key:"updating",value:function(){return!this.sourceBuffer_||this.sourceBuffer_.updating||!!this.pendingCallback_&&this.pendingCallback_!==cd}},{key:"timestampOffset",value:function(e){var t=this;return"undefined"!=typeof e&&(this.queueCallback_(function(){t.sourceBuffer_.timestampOffset=e,t.runCallback_()}),this.timestampOffset_=e),this.timestampOffset_}},{key:"queueCallback_",value:function(e,t){this.callbacks_.push([e.bind(this),t]),this.runCallback_()}},{key:"runCallback_",value:function(){var e=void 0;!this.updating()&&this.callbacks_.length&&this.started_&&(e=this.callbacks_.shift(),this.pendingCallback_=e[1],e[0]())}},{key:"dispose",value:function(){function e(){t.sourceBuffer_&&"open"===t.mediaSource.readyState&&t.sourceBuffer_.abort(),t.sourceBuffer_.removeEventListener("updateend",e)}var t=this;this.sourceBuffer_.removeEventListener("updateend",this.onUpdateendCallback_),this.sourceBuffer_.removing?this.sourceBuffer_.addEventListener("updateend",e):e()}}]),dd);function dd(e,t,i,n){Lc(this,dd),this.callbacks_=[],this.pendingCallback_=null,this.timestampOffset_=0,this.mediaSource=e,this.processedAppend_=!1,this.type_=i,this.mimeType_=t,this.logger_=ld("SourceUpdater["+i+"]["+t+"]"),"closed"===e.readyState?e.addEventListener("sourceopen",this.createSourceBuffer_.bind(this,t,n)):this.createSourceBuffer_(t,n)}function pd(e){e.forEach(function(e){e.abort()})}function fd(e,t){return t.timedout?{status:t.status,message:"HLS request timed-out at URL: "+t.uri,code:wd,xhr:t}:t.aborted?{status:t.status,message:"HLS request aborted at URL: "+t.uri,code:Cd,xhr:t}:e?{status:t.status,message:"HLS request errored at URL: "+t.uri,code:kd,xhr:t}:null}function md(i,n,r){var a=0,s=!1;return function(e,t){if(!s)return e?(s=!0,pd(i),r(e,t)):(a+=1)===i.length?(t.endOfAllRequests=Date.now(),t.encryptedBytes?function(n,r,a){n.addEventListener("message",function e(t){if(t.data.source===r.requestId){n.removeEventListener("message",e);var i=t.data.decrypted;return r.bytes=new Uint8Array(i.bytes,i.byteOffset,i.byteLength),a(null,r)}});var e=void 0;e=r.key.bytes.slice?r.key.bytes.slice():new Uint32Array(Array.prototype.slice.call(r.key.bytes)),n.postMessage(sh({source:r.requestId,encrypted:r.encryptedBytes,key:e,iv:r.key.iv}),[r.encryptedBytes.buffer,e.buffer])}(n,t,r):r(null,t)):void 0}}function gd(t,i){return function(e){return t.stats=bs.mergeOptions(t.stats,function(e){var t=e.target,i={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-t.requestTime||0};return i.bytesReceived=e.loaded,i.bandwidth=Math.floor(i.bytesReceived/i.roundTripTime*8*1e3),i}(e)),!t.stats.firstBytesReceivedAt&&t.stats.bytesReceived&&(t.stats.firstBytesReceivedAt=Date.now()),i(e,t)}}function yd(e,t,i,n,r,a,s){var o=[],u=md(o,i,s);if(r.key&&!r.key.bytes){var l=e(bs.mergeOptions(t,{uri:r.key.resolvedUri,responseType:"arraybuffer"}),function(a,s){return function(e,t){var i=t.response,n=fd(e,t);if(n)return s(n,a);if(16!==i.byteLength)return s({status:t.status,message:"Invalid HLS key at URL: "+t.uri,code:kd,xhr:t},a);var r=new DataView(i);return a.key.bytes=new Uint32Array([r.getUint32(0),r.getUint32(4),r.getUint32(8),r.getUint32(12)]),s(null,a)}}(r,u));o.push(l)}if(r.map&&!r.map.bytes){var c=e(bs.mergeOptions(t,{uri:r.map.resolvedUri,responseType:"arraybuffer",headers:nh(r.map)}),function(r,a,s){return function(e,t){var i=t.response,n=fd(e,t);return n?s(n,r):0===i.byteLength?s({status:t.status,message:"Empty HLS segment content at URL: "+t.uri,code:kd,xhr:t},r):(r.map.bytes=new Uint8Array(t.response),a&&!a.isInitialized()&&a.init(),r.map.timescales=yu.timescale(r.map.bytes),r.map.videoTrackIds=yu.videoTrackIds(r.map.bytes),s(null,r))}}(r,n,u));o.push(c)}var h=e(bs.mergeOptions(t,{uri:r.resolvedUri,responseType:"arraybuffer",headers:nh(r)}),function(a,s,o){return function(e,t){var i=t.response,n=fd(e,t),r=void 0;return n?o(n,a):0===i.byteLength?o({status:t.status,message:"Empty HLS segment content at URL: "+t.uri,code:kd,xhr:t},a):(a.stats=function(e){return{bandwidth:e.bandwidth,bytesReceived:e.bytesReceived||0,roundTripTime:e.roundTripTime||0}}(t),a.key?a.encryptedBytes=new Uint8Array(t.response):a.bytes=new Uint8Array(t.response),s&&a.map&&a.map.bytes&&(s.isInitialized()||s.init(),(r=s.parse(a.bytes,a.map.videoTrackIds,a.map.timescales))&&r.captions&&(a.captionStreams=r.captionStreams,a.fmp4Captions=r.captions)),o(null,a))}}(r,n,u));return h.addEventListener("progress",gd(r,a)),o.push(h),function(){return pd(o)}}function vd(e,t){var i;return e&&(i=v.getComputedStyle(e))?i[t]:""}function _d(e,n){var r=e.slice();e.sort(function(e,t){var i=n(e,t);return 0===i?r.indexOf(e)-r.indexOf(t):i})}function bd(e,t){var i=void 0,n=void 0;return e.attributes.BANDWIDTH&&(i=e.attributes.BANDWIDTH),i=i||v.Number.MAX_VALUE,t.attributes.BANDWIDTH&&(n=t.attributes.BANDWIDTH),i-(n=n||v.Number.MAX_VALUE)}function Td(e){return"number"==typeof e&&isFinite(e)}var Sd={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,BUFFER_LOW_WATER_LINE_RATE:1},kd=2,wd=-101,Cd=-102,Ed=(xc(Ad,bs.EventTarget),Ic(Ad,[{key:"resetStats_",value:function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0}},{key:"dispose",value:function(){this.state="DISPOSED",this.pause(),this.abort_(),this.sourceUpdater_&&this.sourceUpdater_.dispose(),this.resetStats_(),this.captionParser_&&this.captionParser_.reset()}},{key:"abort",value:function(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)}},{key:"abort_",value:function(){this.pendingSegment_&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null}},{key:"error",value:function(e){return"undefined"!=typeof e&&(this.error_=e),this.pendingSegment_=null,this.error_}},{key:"endOfStream",value:function(){this.ended_=!0,this.pause(),this.trigger("ended")}},{key:"buffered_",value:function(){return this.sourceUpdater_?this.sourceUpdater_.buffered():bs.createTimeRanges()}},{key:"initSegment",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=oh(e),r=this.initSegments_[n];return i&&!r&&e.bytes&&(this.initSegments_[n]=r={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes,timescales:e.timescales,videoTrackIds:e.videoTrackIds}),r||e}},{key:"segmentKey",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=uh(e),r=this.keyCache_[n];this.cacheEncryptionKeys_&&i&&!r&&e.bytes&&(this.keyCache_[n]=r={resolvedUri:e.resolvedUri,bytes:e.bytes});var a={resolvedUri:(r||e).resolvedUri};return r&&(a.bytes=r.bytes),a}},{key:"couldBeginLoading_",value:function(){return this.playlist_&&(this.sourceUpdater_||this.mimeType_&&"INIT"===this.state)&&!this.paused()}},{key:"load",value:function(){if(this.monitorBuffer_(),this.playlist_){if(this.syncController_.setDateTimeMapping(this.playlist_),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY")}}},{key:"init_",value:function(){return this.state="READY",this.sourceUpdater_=new hd(this.mediaSource_,this.mimeType_,this.loaderType_,this.sourceBufferEmitter_),this.resetEverything(),this.monitorBuffer_()}},{key:"playlist",value:function(e,t){var i=1<arguments.length&&void 0!==t?t:{};if(e){var n=this.playlist_,r=this.pendingSegment_;this.playlist_=e,this.xhrOptions_=i,this.hasPlayed_()||(e.syncInfo={mediaSequence:e.mediaSequence,time:0});var a=null;if(n&&(n.id?a=n.id:n.uri&&(a=n.uri)),this.logger_("playlist update ["+a+" => "+(e.id||e.uri)+"]"),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(n&&n.uri===e.uri){var s=e.mediaSequence-n.mediaSequence;this.logger_("live window shift ["+s+"]"),null!==this.mediaIndex&&(this.mediaIndex-=s),r&&(r.mediaIndex-=s,0<=r.mediaIndex&&(r.segment=e.segments[r.mediaIndex])),this.syncController_.saveExpiredSegmentInfo(n,e)}else null!==this.mediaIndex&&this.resyncLoader()}}},{key:"pause",value:function(){this.checkBufferTimeout_&&(v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)}},{key:"paused",value:function(){return null===this.checkBufferTimeout_}},{key:"mimeType",value:function(e,t){this.mimeType_||(this.mimeType_=e,this.sourceBufferEmitter_=t,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_())}},{key:"resetEverything",value:function(e){this.ended_=!1,this.resetLoader(),this.remove(0,this.duration_(),e),this.captionParser_&&this.captionParser_.clearAllCaptions(),this.trigger("reseteverything")}},{key:"resetLoader",value:function(){this.fetchAtBuffer_=!1,this.resyncLoader()}},{key:"resyncLoader",value:function(){this.mediaIndex=null,this.syncPoint_=null,this.abort()}},{key:"remove",value:function(e,t,i){if(this.sourceUpdater_&&this.sourceUpdater_.remove(e,t,i),yh(e,t,this.segmentMetadataTrack_),this.inbandTextTracks_)for(var n in this.inbandTextTracks_)yh(e,t,this.inbandTextTracks_[n])}},{key:"monitorBuffer_",value:function(){this.checkBufferTimeout_&&v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=v.setTimeout(this.monitorBufferTick_.bind(this),1)}},{key:"monitorBufferTick_",value:function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=v.setTimeout(this.monitorBufferTick_.bind(this),500)}},{key:"fillBuffer_",value:function(){if(!this.sourceUpdater_.updating()){this.syncPoint_||(this.syncPoint_=this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_()));var e=this.checkBuffer_(this.buffered_(),this.playlist_,this.mediaIndex,this.hasPlayed_(),this.currentTime_(),this.syncPoint_);e&&(this.isEndOfStream_(e.mediaIndex)?this.endOfStream():e.mediaIndex===this.playlist_.segments.length-1&&"ended"===this.mediaSource_.readyState&&!this.seeking_()||(e.timeline!==this.currentTimeline_&&(this.syncController_.reset(),e.timestampOffset=e.startOfSegment,this.captionParser_&&this.captionParser_.clearAllCaptions()),this.loadSegment_(e)))}}},{key:"isEndOfStream_",value:function(e,t){return function(e,t,i){if(!e||!t)return!1;var n=i===e.segments.length;return e.endList&&"open"===t.readyState&&n}(1<arguments.length&&void 0!==t?t:this.playlist_,this.mediaSource_,e)&&!this.sourceUpdater_.updating()}},{key:"checkBuffer_",value:function(e,t,i,n,r,a){var s=0,o=void 0;e.length&&(s=e.end(e.length-1));var u=Math.max(0,s-r);if(!t.segments.length)return null;if(u>=this.goalBufferLength_())return null;if(!n&&1<=u)return null;if(null===a)return i=this.getSyncSegmentCandidate_(t),this.generateSegmentInfo_(t,i,null,!0);if(null!==i){var l=t.segments[i];return o=l&&l.end?l.end:s,this.generateSegmentInfo_(t,i+1,o,!1)}if(this.fetchAtBuffer_){var c=kh.getMediaInfoForTime(t,s,a.segmentIndex,a.time);i=c.mediaIndex,o=c.startTime}else{var h=kh.getMediaInfoForTime(t,r,a.segmentIndex,a.time);i=h.mediaIndex,o=h.startTime}return this.generateSegmentInfo_(t,i,o,!1)}},{key:"getSyncSegmentCandidate_",value:function(e){var t=this;if(-1===this.currentTimeline_)return 0;var i=e.segments.map(function(e,t){return{timeline:e.timeline,segmentIndex:t}}).filter(function(e){return e.timeline===t.currentTimeline_});return i.length?i[Math.min(i.length-1,1)].segmentIndex:Math.max(e.segments.length-1,0)}},{key:"generateSegmentInfo_",value:function(e,t,i,n){if(t<0||t>=e.segments.length)return null;var r=e.segments[t];return{requestId:"segment-loader-"+Math.random(),uri:r.resolvedUri,mediaIndex:t,isSyncRequest:n,startOfSegment:i,playlist:e,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:r.timeline,duration:r.duration,segment:r}}},{key:"abortRequestEarly_",value:function(e){if(this.hls_.tech_.paused()||!this.xhrOptions_.timeout||!this.playlist_.attributes.BANDWIDTH)return!1;if(Date.now()-(e.firstBytesReceivedAt||Date.now())<1e3)return!1;var t=this.currentTime_(),i=e.bandwidth,n=this.pendingSegment_.duration,r=kh.estimateSegmentRequestTime(n,i,this.playlist_,e.bytesReceived),a=function(e,t,i){var n=2<arguments.length&&void 0!==i?i:1;return((e.length?e.end(e.length-1):0)-t)/n}(this.buffered_(),t,this.hls_.tech_.playbackRate())-1;if(r<=a)return!1;var s=function(e){var t=e.master,i=e.currentTime,n=e.bandwidth,r=e.duration,a=e.segmentDuration,s=e.timeUntilRebuffer,o=e.currentTimeline,u=e.syncController,l=t.playlists.filter(function(e){return!kh.isIncompatible(e)}),c=l.filter(kh.isEnabled);c.length||(c=l.filter(function(e){return!kh.isDisabled(e)}));var h=c.filter(kh.hasAttribute.bind(null,"BANDWIDTH")).map(function(e){var t=u.getSyncPoint(e,r,o,i)?1:2;return{playlist:e,rebufferingImpact:kh.estimateSegmentRequestTime(a,n,e)*t-s}}),d=h.filter(function(e){return e.rebufferingImpact<=0});return _d(d,function(e,t){return bd(t.playlist,e.playlist)}),d.length?d[0]:(_d(h,function(e,t){return e.rebufferingImpact-t.rebufferingImpact}),h[0]||null)}({master:this.hls_.playlists.master,currentTime:t,bandwidth:i,duration:this.duration_(),segmentDuration:n,timeUntilRebuffer:a,currentTimeline:this.currentTimeline_,syncController:this.syncController_});if(s){var o=r-a-s.rebufferingImpact,u=.5;return a<=Ah&&(u=1),!(!s.playlist||s.playlist.uri===this.playlist_.uri||o<u)&&(this.bandwidth=s.playlist.attributes.BANDWIDTH*Sd.BANDWIDTH_VARIANCE+1,this.abort(),this.trigger("earlyabort"),!0)}}},{key:"handleProgress_",value:function(e,t){this.pendingSegment_&&t.requestId===this.pendingSegment_.requestId&&!this.abortRequestEarly_(t.stats)&&this.trigger("progress")}},{key:"loadSegment_",value:function(e){this.state="WAITING",this.pendingSegment_=e,this.trimBackBuffer_(e),e.abortRequests=yd(this.hls_.xhr,this.xhrOptions_,this.decrypter_,this.captionParser_,this.createSimplifiedSegmentObj_(e),this.handleProgress_.bind(this),this.segmentRequestFinished_.bind(this))}},{key:"trimBackBuffer_",value:function(e){var t=function(e,t,i){var n=void 0;return n=e.length&&0<e.start(0)&&e.start(0)<t?e.start(0):t-30,Math.min(n,t-i)}(this.seekable_(),this.currentTime_(),this.playlist_.targetDuration||10);0<t&&this.remove(0,t)}},{key:"createSimplifiedSegmentObj_",value:function(e){var t=e.segment,i={resolvedUri:t.resolvedUri,byterange:t.byterange,requestId:e.requestId};if(t.key){var n=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]);i.key=this.segmentKey(t.key),i.key.iv=n}return t.map&&(i.map=this.initSegment(t.map)),i}},{key:"segmentRequestFinished_",value:function(e,t){if(this.mediaRequests+=1,t.stats&&(this.mediaBytesTransferred+=t.stats.bytesReceived,this.mediaTransferDuration+=t.stats.roundTripTime),this.pendingSegment_){if(t.requestId===this.pendingSegment_.requestId){if(e)return this.pendingSegment_=null,this.state="READY",e.code===Cd?void(this.mediaRequestsAborted+=1):(this.pause(),e.code===wd?(this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,void this.trigger("bandwidthupdate")):(this.mediaRequestsErrored+=1,this.error(e),void this.trigger("error")));this.bandwidth=t.stats.bandwidth,this.roundTrip=t.stats.roundTripTime,t.map&&(t.map=this.initSegment(t.map,!0)),t.key&&this.segmentKey(t.key,!0),this.processSegmentResponse_(t)}}else this.mediaRequestsAborted+=1}},{key:"processSegmentResponse_",value:function(e){var t=this.pendingSegment_;t.bytes=e.bytes,e.map&&(t.segment.map.bytes=e.map.bytes),t.endOfAllRequests=e.endOfAllRequests,e.fmp4Captions&&(function(e,t,i){for(var n in i)if(!e[n]){t.trigger({type:"usage",name:"hls-608"});var r=t.textTracks().getTrackById(n);e[n]=r||t.addRemoteTextTrack({kind:"captions",id:n,label:n},!1).track}}(this.inbandTextTracks_,this.hls_.tech_,e.captionStreams),function(e){var r=e.inbandTextTracks,t=e.captionArray,a=e.timestampOffset;if(t){var s=window.WebKitDataCue||window.VTTCue;t.forEach(function(e){var t=e.stream,i=e.startTime,n=e.endTime;r[t]&&(i+=a,n+=a,r[t].addCue(new s(i,n,e.text)))})}}({inbandTextTracks:this.inbandTextTracks_,captionArray:e.fmp4Captions,timestampOffset:0}),this.captionParser_&&this.captionParser_.clearParsedCaptions()),this.handleSegment_()}},{key:"handleSegment_",value:function(){var e=this;if(this.pendingSegment_){var t=this.pendingSegment_,i=t.segment,n=this.syncController_.probeSegmentInfo(t);"undefined"==typeof this.startingMedia_&&n&&(n.containsAudio||n.containsVideo)&&(this.startingMedia_={containsAudio:n.containsAudio,containsVideo:n.containsVideo});var r=function(e,t,i){return"main"===e&&t&&i?i.containsAudio||i.containsVideo?t.containsVideo&&!i.containsVideo?"Only audio found in segment when we expected video. We can't switch to audio only from a stream that had video. To get rid of this message, please add codec information to the manifest.":!t.containsVideo&&i.containsVideo?"Video found in segment when we expected only audio. We can't switch to a stream with video from an audio only stream. To get rid of this message, please add codec information to the manifest.":null:"Neither audio nor video found in segment.":null}(this.loaderType_,this.startingMedia_,n);if(r)return this.error({message:r,blacklistDuration:1/0}),void this.trigger("error");if(t.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");null!==t.timestampOffset&&t.timestampOffset!==this.sourceUpdater_.timestampOffset()&&(this.sourceUpdater_.timestampOffset(t.timestampOffset),this.trigger("timestampoffset"));var a=this.syncController_.mappingForTimeline(t.timeline);if(null!==a&&this.trigger({type:"segmenttimemapping",mapping:a}),this.state="APPENDING",i.map){var s=oh(i.map);if(!this.activeInitSegmentId_||this.activeInitSegmentId_!==s){var o=this.initSegment(i.map);this.sourceUpdater_.appendBuffer({bytes:o.bytes},function(){e.activeInitSegmentId_=s})}}t.byteLength=t.bytes.byteLength,"number"==typeof i.start&&"number"==typeof i.end?this.mediaSecondsLoaded+=i.end-i.start:this.mediaSecondsLoaded+=i.duration,this.logger_(function(e){var t=e.segment,i=t.start,n=t.end,r=e.playlist,a=r.mediaSequence,s=r.id,o=r.segments,u=void 0===o?[]:o,l=e.mediaIndex,c=e.timeline;return["appending ["+l+"] of ["+a+", "+(a+u.length)+"] from playlist ["+s+"]","["+i+" => "+n+"] in timeline ["+c+"]"].join(" ")}(t)),this.sourceUpdater_.appendBuffer({bytes:t.bytes,videoSegmentTimingInfoCallback:this.handleVideoSegmentTimingInfo_.bind(this,t.requestId)},this.handleUpdateEnd_.bind(this))}else this.state="READY"}},{key:"handleVideoSegmentTimingInfo_",value:function(e,t){if(this.pendingSegment_&&e===this.pendingSegment_.requestId){var i=this.pendingSegment_.segment;i.videoTimingInfo||(i.videoTimingInfo={}),i.videoTimingInfo.transmuxerPrependedSeconds=t.videoSegmentTimingInfo.prependedContentDuration||0,i.videoTimingInfo.transmuxedPresentationStart=t.videoSegmentTimingInfo.start.presentation,i.videoTimingInfo.transmuxedPresentationEnd=t.videoSegmentTimingInfo.end.presentation,i.videoTimingInfo.baseMediaDecodeTime=t.videoSegmentTimingInfo.baseMediaDecodeTime}}},{key:"handleUpdateEnd_",value:function(){if(!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_,t=e.segment,i=null!==this.mediaIndex;this.pendingSegment_=null,this.recordThroughput_(e),this.addSegmentMetadataCue_(e),this.state="READY",this.mediaIndex=e.mediaIndex,this.fetchAtBuffer_=!0,this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate"),t.end&&this.currentTime_()-t.end>3*e.playlist.targetDuration?this.resetEverything():(i&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.isEndOfStream_(e.mediaIndex+1,e.playlist)&&this.endOfStream(),this.paused()||this.monitorBuffer_())}},{key:"recordThroughput_",value:function(e){var t=this.throughput.rate,i=Date.now()-e.endOfAllRequests+1,n=Math.floor(e.byteLength/i*8*1e3);this.throughput.rate+=(n-t)/++this.throughput.count}},{key:"addSegmentMetadataCue_",value:function(e){if(this.segmentMetadataTrack_){var t=e.segment,i=t.start,n=t.end;if(Td(i)&&Td(n)){yh(i,n,this.segmentMetadataTrack_);var r=v.WebKitDataCue||v.VTTCue,a={custom:t.custom,dateTimeObject:t.dateTimeObject,dateTimeString:t.dateTimeString,bandwidth:e.playlist.attributes.BANDWIDTH,resolution:e.playlist.attributes.RESOLUTION,codecs:e.playlist.attributes.CODECS,byteLength:e.byteLength,uri:e.uri,timeline:e.timeline,playlist:e.playlist.uri,start:i,end:n},s=new r(i,n,JSON.stringify(a));s.value=a,this.segmentMetadataTrack_.addCue(s)}}}}]),Ad);function Ad(e){Lc(this,Ad);var t=Uc(this,(Ad.__proto__||Object.getPrototypeOf(Ad)).call(this));if(!e)throw new TypeError("Initialization settings are required");if("function"!=typeof e.currentTime)throw new TypeError("No currentTime getter specified");if(!e.mediaSource)throw new TypeError("No MediaSource specified");return t.bandwidth=e.bandwidth,t.throughput={rate:0,count:0},t.roundTrip=NaN,t.resetStats_(),t.mediaIndex=null,t.hasPlayed_=e.hasPlayed,t.currentTime_=e.currentTime,t.seekable_=e.seekable,t.seeking_=e.seeking,t.duration_=e.duration,t.mediaSource_=e.mediaSource,t.hls_=e.hls,t.loaderType_=e.loaderType,t.startingMedia_=void 0,t.segmentMetadataTrack_=e.segmentMetadataTrack,t.goalBufferLength_=e.goalBufferLength,t.sourceType_=e.sourceType,t.inbandTextTracks_=e.inbandTextTracks,t.state_="INIT",t.checkBufferTimeout_=null,t.error_=void 0,t.currentTimeline_=-1,t.pendingSegment_=null,t.mimeType_=null,t.sourceUpdater_=null,t.xhrOptions_=null,t.activeInitSegmentId_=null,t.initSegments_={},t.cacheEncryptionKeys_=e.cacheEncryptionKeys,t.keyCache_={},"main"===t.loaderType_?t.captionParser_=new nc:t.captionParser_=null,t.decrypter_=e.decrypter,t.syncController_=e.syncController,t.syncPoint_={segmentIndex:0,time:0},t.syncController_.on("syncinfoupdate",function(){return t.trigger("syncinfoupdate")}),t.mediaSource_.addEventListener("sourceopen",function(){return t.ended_=!1}),t.fetchAtBuffer_=!1,t.logger_=ld("SegmentLoader["+t.loaderType_+"]"),Object.defineProperty(t,"state",{get:function(){return this.state_},set:function(e){e!==this.state_&&(this.logger_(this.state_+" -> "+e),this.state_=e)}}),t}function Pd(e){return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}var Ld=new Uint8Array("\n\n".split("").map(function(e){return e.charCodeAt(0)})),Id=(xc(Od,Ed),Ic(Od,[{key:"buffered_",value:function(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues.length)return bs.createTimeRanges();var e=this.subtitlesTrack_.cues,t=e[0].startTime,i=e[e.length-1].startTime;return bs.createTimeRanges([[t,i]])}},{key:"initSegment",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=oh(e),r=this.initSegments_[n];if(i&&!r&&e.bytes){var a=Ld.byteLength+e.bytes.byteLength,s=new Uint8Array(a);s.set(e.bytes),s.set(Ld,e.bytes.byteLength),this.initSegments_[n]=r={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:s}}return r||e}},{key:"couldBeginLoading_",value:function(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()}},{key:"init_",value:function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}},{key:"track",value:function(e){return"undefined"==typeof e||(this.subtitlesTrack_=e,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_}},{key:"remove",value:function(e,t){yh(e,t,this.subtitlesTrack_)}},{key:"fillBuffer_",value:function(){var e=this;this.syncPoint_||(this.syncPoint_=this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_()));var t=this.checkBuffer_(this.buffered_(),this.playlist_,this.mediaIndex,this.hasPlayed_(),this.currentTime_(),this.syncPoint_);if(t=this.skipEmptySegments_(t)){if(null===this.syncController_.timestampOffsetForTimeline(t.timeline))return this.syncController_.one("timestampoffset",function(){e.state="READY",e.paused()||e.monitorBuffer_()}),void(this.state="WAITING_ON_TIMELINE");this.loadSegment_(t)}}},{key:"skipEmptySegments_",value:function(e){for(;e&&e.segment.empty;)e=this.generateSegmentInfo_(e.playlist,e.mediaIndex+1,e.startOfSegment+e.duration,e.isSyncRequest);return e}},{key:"handleSegment_",value:function(){var t=this;if(this.pendingSegment_&&this.subtitlesTrack_){this.state="APPENDING";var e=this.pendingSegment_,i=e.segment;if("function"!=typeof v.WebVTT&&this.subtitlesTrack_&&this.subtitlesTrack_.tech_){function n(){t.subtitlesTrack_.tech_.off("vttjsloaded",r),t.error({message:"Error loading vtt.js"}),t.state="READY",t.pause(),t.trigger("error")}var r=void 0;return r=function(){t.subtitlesTrack_.tech_.off("vttjserror",n),t.handleSegment_()},this.state="WAITING_ON_VTTJS",this.subtitlesTrack_.tech_.one("vttjsloaded",r),void this.subtitlesTrack_.tech_.one("vttjserror",n)}i.requested=!0;try{this.parseVTTCues_(e)}catch(e){return this.error({message:e.message}),this.state="READY",this.pause(),this.trigger("error")}if(this.updateTimeMapping_(e,this.syncController_.timelines[e.timeline],this.playlist_),e.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");e.byteLength=e.bytes.byteLength,this.mediaSecondsLoaded+=i.duration,e.cues.length&&this.remove(e.cues[0].endTime,e.cues[e.cues.length-1].endTime),e.cues.forEach(function(e){t.subtitlesTrack_.addCue(e)}),this.handleUpdateEnd_()}else this.state="READY"}},{key:"parseVTTCues_",value:function(t){var e=void 0,i=!1;"function"==typeof v.TextDecoder?e=new v.TextDecoder("utf8"):(e=v.WebVTT.StringDecoder(),i=!0);var n=new v.WebVTT.Parser(v,v.vttjs,e);if(t.cues=[],t.timestampmap={MPEGTS:0,LOCAL:0},n.oncue=t.cues.push.bind(t.cues),n.ontimestampmap=function(e){return t.timestampmap=e},n.onparsingerror=function(e){bs.log.warn("Error encountered when parsing cues: "+e.message)},t.segment.map){var r=t.segment.map.bytes;i&&(r=Pd(r)),n.parse(r)}var a=t.bytes;i&&(a=Pd(a)),n.parse(a),n.flush()}},{key:"updateTimeMapping_",value:function(e,t,i){var n=e.segment;if(t)if(e.cues.length){var r=e.timestampmap,a=r.MPEGTS/9e4-r.LOCAL+t.mapping;if(e.cues.forEach(function(e){e.startTime+=a,e.endTime+=a}),!i.syncInfo){var s=e.cues[0].startTime,o=e.cues[e.cues.length-1].startTime;i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:Math.min(s,o-n.duration)}}}else n.empty=!0}}]),Od);function Od(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};Lc(this,Od);var i=Uc(this,(Od.__proto__||Object.getPrototypeOf(Od)).call(this,e,t));return i.mediaSource_=null,i.subtitlesTrack_=null,i}function xd(e,t){for(var i=e.cues,n=0;n<i.length;n++){var r=i[n];if(t>=r.adStartTime&&t<=r.adEndTime)return r}return null}var Ud=hc,Dd=[{name:"VOD",run:function(e,t,i,n,r){if(i===1/0)return null;return{time:0,segmentIndex:0}}},{name:"ProgramDateTime",run:function(e,t,i,n,r){if(!e.datetimeToDisplayTime)return null;var a=t.segments||[],s=null,o=null;r=r||0;for(var u=0;u<a.length;u++){var l=a[u];if(l.dateTimeObject){var c=l.dateTimeObject.getTime()/1e3+e.datetimeToDisplayTime,h=Math.abs(r-c);if(null!==o&&(0===h||o<h))break;o=h,s={time:c,segmentIndex:u}}}return s}},{name:"Segment",run:function(e,t,i,n,r){var a=t.segments||[],s=null,o=null;r=r||0;for(var u=0;u<a.length;u++){var l=a[u];if(l.timeline===n&&"undefined"!=typeof l.start){var c=Math.abs(r-l.start);if(null!==o&&o<c)break;(!s||null===o||c<=o)&&(o=c,s={time:l.start,segmentIndex:u})}}return s}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o<t.discontinuityStarts.length;o++){var u=t.discontinuityStarts[o],l=t.discontinuitySequence+o+1,c=e.discontinuities[l];if(c){var h=Math.abs(r-c.time);if(null!==s&&s<h)break;(!a||null===s||h<=s)&&(s=h,a={time:c.time,segmentIndex:u})}}return a}},{name:"Playlist",run:function(e,t,i,n,r){return t.syncInfo?{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence}:null}}],Rd=(xc(Md,bs.EventTarget),Ic(Md,[{key:"getSyncPoint",value:function(e,t,i,n){var r=this.runStrategies_(e,t,i,n);return r.length?this.selectSyncPoint_(r,{key:"time",value:n}):null}},{key:"getExpiredTime",value:function(e,t){if(!e||!e.segments)return null;var i=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!i.length)return null;var n=this.selectSyncPoint_(i,{key:"segmentIndex",value:0});return 0<n.segmentIndex&&(n.time*=-1),Math.abs(n.time+Gc(e,n.segmentIndex,0))}},{key:"runStrategies_",value:function(e,t,i,n){for(var r=[],a=0;a<Dd.length;a++){var s=Dd[a],o=s.run(this,e,t,i,n);o&&(o.strategy=s.name,r.push({strategy:s.name,syncPoint:o}))}return r}},{key:"selectSyncPoint_",value:function(e,t){for(var i=e[0].syncPoint,n=Math.abs(e[0].syncPoint[t.key]-t.value),r=e[0].strategy,a=1;a<e.length;a++){var s=Math.abs(e[a].syncPoint[t.key]-t.value);s<n&&(n=s,i=e[a].syncPoint,r=e[a].strategy)}return this.logger_("syncPoint for ["+t.key+": "+t.value+"] chosen with strategy ["+r+"]: [time:"+i.time+", segmentIndex:"+i.segmentIndex+"]"),i}},{key:"saveExpiredSegmentInfo",value:function(e,t){for(var i=t.mediaSequence-e.mediaSequence-1;0<=i;i--){var n=e.segments[i];if(n&&"undefined"!=typeof n.start){t.syncInfo={mediaSequence:e.mediaSequence+i,time:n.start},this.logger_("playlist refresh sync: [time:"+t.syncInfo.time+", mediaSequence: "+t.syncInfo.mediaSequence+"]"),this.trigger("syncinfoupdate");break}}}},{key:"setDateTimeMapping",value:function(e){if(!this.datetimeToDisplayTime&&e.segments&&e.segments.length&&e.segments[0].dateTimeObject){var t=e.segments[0].dateTimeObject.getTime()/1e3;this.datetimeToDisplayTime=-t}}},{key:"reset",value:function(){this.inspectCache_=void 0}},{key:"probeSegmentInfo",value:function(e){var t=e.segment,i=e.playlist,n=void 0;return(n=t.map?this.probeMp4Segment_(e):this.probeTsSegment_(e))&&this.calculateSegmentTimeMapping_(e,n)&&(this.saveDiscontinuitySyncInfo_(e),i.syncInfo||(i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:t.start})),n}},{key:"probeMp4Segment_",value:function(e){var t=e.segment,i=yu.timescale(t.map.bytes),n=yu.startTime(i,e.bytes);return null!==e.timestampOffset&&(e.timestampOffset-=n),{start:n,end:n+t.duration}}},{key:"probeTsSegment_",value:function(e){var t=Ud(e.bytes,this.inspectCache_),i=void 0,n=void 0;return t?(t.video&&2===t.video.length?(this.inspectCache_=t.video[1].dts,i=t.video[0].dtsTime,n=t.video[1].dtsTime):t.audio&&2===t.audio.length&&(this.inspectCache_=t.audio[1].dts,i=t.audio[0].dtsTime,n=t.audio[1].dtsTime),{start:i,end:n,containsVideo:t.video&&2===t.video.length,containsAudio:t.audio&&2===t.audio.length}):null}},{key:"timestampOffsetForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].time}},{key:"mappingForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].mapping}},{key:"calculateSegmentTimeMapping_",value:function(e,t){var i=e.segment,n=this.timelines[e.timeline];if(null!==e.timestampOffset)n={time:e.startOfSegment,mapping:e.startOfSegment-t.start},this.timelines[e.timeline]=n,this.trigger("timestampoffset"),this.logger_("time mapping for timeline "+e.timeline+": [time: "+n.time+"] [mapping: "+n.mapping+"]"),i.start=e.startOfSegment,i.end=t.end+n.mapping;else{if(!n)return!1;i.start=t.start+n.mapping,i.end=t.end+n.mapping}return!0}},{key:"saveDiscontinuitySyncInfo_",value:function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts&&t.discontinuityStarts.length)for(var n=0;n<t.discontinuityStarts.length;n++){var r=t.discontinuityStarts[n],a=t.discontinuitySequence+n+1,s=r-e.mediaIndex,o=Math.abs(s);if(!this.discontinuities[a]||this.discontinuities[a].accuracy>o){var u=void 0;u=s<0?i.start-Gc(t,e.mediaIndex,r):i.end+Gc(t,e.mediaIndex+1,r),this.discontinuities[a]={time:u,accuracy:o}}}}}]),Md);function Md(){Lc(this,Md);var e=Uc(this,(Md.__proto__||Object.getPrototypeOf(Md)).call(this));return e.inspectCache_=void 0,e.timelines=[],e.discontinuities=[],e.datetimeToDisplayTime=null,e.logger_=ld("SyncController"),e}function Bd(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null)}function Nd(e,t){(t.activePlaylistLoader=e).load()}function jd(t){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){qd[e](e,t)});var i=t.mediaTypes,e=t.masterPlaylistLoader,n=t.tech,r=t.hls;["AUDIO","SUBTITLES"].forEach(function(e){i[e].activeGroup=function(a,s){return function(t){var e=s.masterPlaylistLoader,i=s.mediaTypes[a].groups,n=e.media();if(!n)return null;var r=null;return n.attributes[a]&&(r=i[n.attributes[a]]),r=r||i.main,"undefined"==typeof t?r:null===t?null:r.filter(function(e){return e.id===t.id})[0]||null}}(e,t),i[e].activeTrack=zd[e](e,t),i[e].onGroupChanged=function(o,u){return function(){var e=u.segmentLoaders,t=e[o],i=e.main,n=u.mediaTypes[o],r=n.activeTrack(),a=n.activeGroup(r),s=n.activePlaylistLoader;Bd(t,n),a&&(a.playlistLoader?(t.resyncLoader(),Nd(a.playlistLoader,n)):s&&i.resetEverything())}}(e,t),i[e].onTrackChanged=function(o,u){return function(){var e=u.segmentLoaders,t=e[o],i=e.main,n=u.mediaTypes[o],r=n.activeTrack(),a=n.activeGroup(r),s=n.activePlaylistLoader;Bd(t,n),a&&(a.playlistLoader?(s!==a.playlistLoader&&(t.track&&t.track(r),t.resetEverything()),Nd(a.playlistLoader,n)):i.resetEverything())}}(e,t)});var a=i.AUDIO.activeGroup(),s=(a.filter(function(e){return e.default})[0]||a[0]).id;function o(){i.AUDIO.onTrackChanged(),n.trigger({type:"usage",name:"hls-audio-change"})}for(var u in i.AUDIO.tracks[s].enabled=!0,i.AUDIO.onTrackChanged(),e.on("mediachange",function(){["AUDIO","SUBTITLES"].forEach(function(e){return i[e].onGroupChanged()})}),n.audioTracks().addEventListener("change",o),n.remoteTextTracks().addEventListener("change",i.SUBTITLES.onTrackChanged),r.on("dispose",function(){n.audioTracks().removeEventListener("change",o),n.remoteTextTracks().removeEventListener("change",i.SUBTITLES.onTrackChanged)}),n.clearTracks("audio"),i.AUDIO.tracks)n.audioTracks().addTrack(i.AUDIO.tracks[u])}var Fd=new Dh("./decrypter-worker.worker.js",function(e,t){var i,c,g,n,r,u,s,a=this;i=function(e,t,i){return t&&o(e.prototype,t),i&&o(e,i),e},c=null,d.prototype.decrypt=function(e,t,i,n,r,a){var s=this._key[1],o=e^s[0],u=n^s[1],l=i^s[2],c=t^s[3],h=void 0,d=void 0,p=void 0,f=s.length/4-2,m=void 0,g=4,y=this._tables[1],v=y[0],_=y[1],b=y[2],T=y[3],S=y[4];for(m=0;m<f;m++)h=v[o>>>24]^_[u>>16&255]^b[l>>8&255]^T[255&c]^s[g],d=v[u>>>24]^_[l>>16&255]^b[c>>8&255]^T[255&o]^s[g+1],p=v[l>>>24]^_[c>>16&255]^b[o>>8&255]^T[255&u]^s[g+2],c=v[c>>>24]^_[o>>16&255]^b[u>>8&255]^T[255&l]^s[g+3],g+=4,o=h,u=d,l=p;for(m=0;m<4;m++)r[(3&-m)+a]=S[o>>>24]<<24^S[u>>16&255]<<16^S[l>>8&255]<<8^S[255&c]^s[g++],h=o,o=u,u=l,l=c,c=h},g=d,l.prototype.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},l.prototype.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},l.prototype.trigger=function(e,t){var i=this.listeners[e];if(i)if(2===arguments.length)for(var n=i.length,r=0;r<n;++r)i[r].call(this,t);else for(var a=Array.prototype.slice.call(arguments,1),s=i.length,o=0;o<s;++o)i[o].apply(this,a)},l.prototype.dispose=function(){this.listeners={}},l.prototype.pipe=function(t){this.on("data",function(e){t.push(e)})},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(p,r=n=l),p.prototype.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},p.prototype.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},u=p,f.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=function(e,t,i){var n=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),r=new g(Array.prototype.slice.call(t)),a=new Uint8Array(e.byteLength),s=new Int32Array(a.buffer),o=void 0,u=void 0,l=void 0,c=void 0,h=void 0,d=void 0,p=void 0,f=void 0,m=void 0;for(o=i[0],u=i[1],l=i[2],c=i[3],m=0;m<n.length;m+=4)h=y(n[m]),d=y(n[m+1]),p=y(n[m+2]),f=y(n[m+3]),r.decrypt(h,d,p,f,s,m),s[m]=y(s[m]^o),s[m+1]=y(s[m+1]^u),s[m+2]=y(s[m+2]^l),s[m+3]=y(s[m+3]^c),o=h,u=d,l=p,c=f;return a}(t,i,n);r.set(e,t.byteOffset)}},i(f,null,[{key:"STEP",get:function(){return 32e3}}]),s=f,new function(a){a.onmessage=function(e){var i=e.data,t=new Uint8Array(i.encrypted.bytes,i.encrypted.byteOffset,i.encrypted.byteLength),n=new Uint32Array(i.key.bytes,i.key.byteOffset,i.key.byteLength/4),r=new Uint32Array(i.iv.bytes,i.iv.byteOffset,i.iv.byteLength/4);new s(t,n,r,function(e,t){a.postMessage(function(i){var n={};return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}({source:i.source,decrypted:t}),[t.buffer])})}}(a);function h(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function d(e){h(this,d),c=c||function(){var e=[[[],[],[],[],[]],[[],[],[],[],[]]],t=e[0],i=e[1],n=t[4],r=i[4],a=void 0,s=void 0,o=void 0,u=[],l=[],c=void 0,h=void 0,d=void 0,p=void 0,f=void 0;for(a=0;a<256;a++)l[(u[a]=a<<1^283*(a>>7))^a]=a;for(s=o=0;!n[s];s^=c||1,o=l[o]||1)for(d=(d=o^o<<1^o<<2^o<<3^o<<4)>>8^255&d^99,f=16843009*u[h=u[c=u[r[n[s]=d]=s]]]^65537*h^257*c^16843008*s,p=257*u[d]^16843008*d,a=0;a<4;a++)t[a][s]=p=p<<24^p>>>8,i[a][d]=f=f<<24^f>>>8;for(a=0;a<5;a++)t[a]=t[a].slice(0),i[a]=i[a].slice(0);return e}(),this._tables=[[c[0][0].slice(),c[0][1].slice(),c[0][2].slice(),c[0][3].slice(),c[0][4].slice()],[c[1][0].slice(),c[1][1].slice(),c[1][2].slice(),c[1][3].slice(),c[1][4].slice()]];var t=void 0,i=void 0,n=void 0,r=void 0,a=void 0,s=this._tables[0][4],o=this._tables[1],u=e.length,l=1;if(4!==u&&6!==u&&8!==u)throw new Error("Invalid aes key size");for(r=e.slice(0),a=[],this._key=[r,a],t=u;t<4*u+28;t++)n=r[t-1],(t%u==0||8===u&&t%u==4)&&(n=s[n>>>24]<<24^s[n>>16&255]<<16^s[n>>8&255]<<8^s[255&n],t%u==0&&(n=n<<8^n>>>24^l<<24,l=l<<1^283*(l>>7))),r[t]=r[t-u]^n;for(i=0;t;i++,t--)n=r[3&i?t:t-4],a[i]=t<=4||i<4?n:o[0][s[n>>>24]]^o[1][s[n>>16&255]]^o[2][s[n>>8&255]]^o[3][s[255&n]]}function l(){h(this,l),this.listeners={}}function p(){h(this,p);var e=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,r.call(this,n));return e.jobs=[],e.delay=1,e.timeout_=null,e}function y(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24}function f(e,t,i,n){h(this,f);var r=f.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new u,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([y(a[o-4]),y(a[o-3]),y(a[o-2]),y(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){n(null,function(e){return e.subarray(0,e.byteLength-e[e.byteLength-1])}(s))})}}),Vd={AUDIO:function(u,l){return function(){var e=l.segmentLoaders[u],t=l.mediaTypes[u],i=l.blacklistCurrentPlaylist;Bd(e,t);var n=t.activeTrack(),r=t.activeGroup(),a=(r.filter(function(e){return e.default})[0]||r[0]).id,s=t.tracks[a];if(n!==s){for(var o in bs.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),t.tracks)t.tracks[o].enabled=t.tracks[o]===s;t.onTrackChanged()}else i({message:"Problem encountered loading the default audio track."})}},SUBTITLES:function(n,r){return function(){var e=r.segmentLoaders[n],t=r.mediaTypes[n];bs.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),Bd(e,t);var i=t.activeTrack();i&&(i.mode="disabled"),t.onTrackChanged()}}},Hd={AUDIO:function(e,t,i){if(t){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Vd[e](e,i))}},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Vd[e](e,i))}},qd={AUDIO:function(e,t){var i,n,r=t.hls,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,h=l.tracks,d=t.masterPlaylistLoader;for(var p in u[e]&&0!==Object.keys(u[e]).length||(u[e]={main:{default:{default:!0}}}),u[e])for(var f in c[p]||(c[p]=[]),u[e][p]){var m=u[e][p][f],g=void 0;if(g=m.resolvedUri?new Hc(m.resolvedUri,r,o):m.playlists&&"dash"===a?new od(m.playlists[0],r,o,d):null,m=bs.mergeOptions({id:f,playlistLoader:g},m),Hd[e](e,m.playlistLoader,t),c[p].push(m),"undefined"==typeof h[f]){var y=new bs.AudioTrack({id:f,kind:(i=m,n=void 0,n=i.default?"main":"alternative",i.characteristics&&0<=i.characteristics.indexOf("public.accessibility.describes-video")&&(n="main-desc"),n),enabled:!1,language:m.language,default:m.default,label:f});h[f]=y}}s.on("error",Vd[e](e,t))},SUBTITLES:function(e,t){var i=t.tech,n=t.hls,r=t.sourceType,a=t.segmentLoaders[e],s=t.requestOptions,o=t.master.mediaGroups,u=t.mediaTypes[e],l=u.groups,c=u.tracks,h=t.masterPlaylistLoader;for(var d in o[e])for(var p in l[d]||(l[d]=[]),o[e][d])if(!o[e][d][p].forced){var f=o[e][d][p],m=void 0;if("hls"===r?m=new Hc(f.resolvedUri,n,s):"dash"===r&&(m=new od(f.playlists[0],n,s,h)),f=bs.mergeOptions({id:p,playlistLoader:m},f),Hd[e](e,f.playlistLoader,t),l[d].push(f),"undefined"==typeof c[p]){var g=i.addRemoteTextTrack({id:p,kind:"subtitles",default:f.default&&f.autoselect,language:f.language,label:p},!1).track;c[p]=g}}a.on("error",Vd[e](e,t))},"CLOSED-CAPTIONS":function(e,t){var i=t.tech,n=t.master.mediaGroups,r=t.mediaTypes[e],a=r.groups,s=r.tracks;for(var o in n[e])for(var u in a[o]||(a[o]=[]),n[e][o]){var l=n[e][o][u];if(l.instreamId.match(/CC\d/)&&(a[o].push(bs.mergeOptions({id:u},l)),"undefined"==typeof s[u])){var c=i.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default&&l.autoselect,language:l.language,label:u},!1).track;s[u]=c}}}},zd={AUDIO:function(i,n){return function(){var e=n.mediaTypes[i].tracks;for(var t in e)if(e[t].enabled)return e[t];return null}},SUBTITLES:function(i,n){return function(){var e=n.mediaTypes[i].tracks;for(var t in e)if("showing"===e[t].mode)return e[t];return null}}},Wd=void 0,Gd=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred"],$d=(xc(Xd,bs.EventTarget),Ic(Xd,[{key:"setupMasterPlaylistLoaderListeners_",value:function(){var n=this;this.masterPlaylistLoader_.on("loadedmetadata",function(){var e=n.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;th(n.masterPlaylistLoader_.master,n.masterPlaylistLoader_.media())?n.requestOptions_.timeout=0:n.requestOptions_.timeout=t,e.endList&&"none"!==n.tech_.preload()&&(n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.mainSegmentLoader_.load()),jd({sourceType:n.sourceType_,segmentLoaders:{AUDIO:n.audioSegmentLoader_,SUBTITLES:n.subtitleSegmentLoader_,main:n.mainSegmentLoader_},tech:n.tech_,requestOptions:n.requestOptions_,masterPlaylistLoader:n.masterPlaylistLoader_,hls:n.hls_,master:n.master(),mediaTypes:n.mediaTypes_,blacklistCurrentPlaylist:n.blacklistCurrentPlaylist.bind(n)}),n.triggerPresenceUsage_(n.master(),e);try{n.setupSourceBuffers_()}catch(e){return bs.log.warn("Failed to create SourceBuffers",e),n.mediaSource.endOfStream("decode")}n.setupFirstPlay(),!n.mediaTypes_.AUDIO.activePlaylistLoader||n.mediaTypes_.AUDIO.activePlaylistLoader.media()?n.trigger("selectedinitialmedia"):n.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",function(){n.trigger("selectedinitialmedia")})}),this.masterPlaylistLoader_.on("loadedplaylist",function(){var e=n.masterPlaylistLoader_.media();if(!e){n.excludeUnsupportedVariants_();var t=void 0;return n.enableLowInitialPlaylist&&(t=n.selectInitialPlaylist()),t=t||n.selectPlaylist(),n.initialMedia_=t,void n.masterPlaylistLoader_.media(n.initialMedia_)}if(n.useCueTags_&&n.updateAdCues_(e),n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.updateDuration(),n.tech_.paused()||(n.mainSegmentLoader_.load(),n.audioSegmentLoader_&&n.audioSegmentLoader_.load()),!e.endList){function i(){var e=n.seekable();0!==e.length&&n.mediaSource.addSeekableRange_(e.start(0),e.end(0))}n.duration()!==1/0?n.tech_.one("durationchange",function e(){n.duration()===1/0?i():n.tech_.one("durationchange",e)}):i()}}),this.masterPlaylistLoader_.on("error",function(){n.blacklistCurrentPlaylist(n.masterPlaylistLoader_.error)}),this.masterPlaylistLoader_.on("mediachanging",function(){n.mainSegmentLoader_.abort(),n.mainSegmentLoader_.pause()}),this.masterPlaylistLoader_.on("mediachange",function(){var e=n.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;th(n.masterPlaylistLoader_.master,n.masterPlaylistLoader_.media())?n.requestOptions_.timeout=0:n.requestOptions_.timeout=t,n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.mainSegmentLoader_.load(),n.tech_.trigger({type:"mediachange",bubbles:!0})}),this.masterPlaylistLoader_.on("playlistunchanged",function(){var e=n.masterPlaylistLoader_.media();n.stuckAtPlaylistEnd_(e)&&(n.blacklistCurrentPlaylist({message:"Playlist no longer updating."}),n.tech_.trigger("playliststuck"))}),this.masterPlaylistLoader_.on("renditiondisabled",function(){n.tech_.trigger({type:"usage",name:"hls-rendition-disabled"})}),this.masterPlaylistLoader_.on("renditionenabled",function(){n.tech_.trigger({type:"usage",name:"hls-rendition-enabled"})})}},{key:"triggerPresenceUsage_",value:function(e,t){var i=e.mediaGroups||{},n=!0,r=Object.keys(i.AUDIO);for(var a in i.AUDIO)for(var s in i.AUDIO[a])i.AUDIO[a][s].uri||(n=!1);n&&this.tech_.trigger({type:"usage",name:"hls-demuxed"}),Object.keys(i.SUBTITLES).length&&this.tech_.trigger({type:"usage",name:"hls-webvtt"}),Wd.Playlist.isAes(t)&&this.tech_.trigger({type:"usage",name:"hls-aes"}),Wd.Playlist.isFmp4(t)&&this.tech_.trigger({type:"usage",name:"hls-fmp4"}),r.length&&1<Object.keys(i.AUDIO[r[0]]).length&&this.tech_.trigger({type:"usage",name:"hls-alternate-audio"}),this.useCueTags_&&this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"})}},{key:"setupSegmentLoaderListeners_",value:function(){var a=this;this.mainSegmentLoader_.on("bandwidthupdate",function(){var e=a.selectPlaylist(),t=a.masterPlaylistLoader_.media(),i=a.tech_.buffered(),n=i.length?i.end(i.length-1)-a.tech_.currentTime():0,r=a.bufferLowWaterLine();(!t.endList||a.duration()<Sd.MAX_BUFFER_LOW_WATER_LINE||e.attributes.BANDWIDTH<t.attributes.BANDWIDTH||r<=n)&&a.masterPlaylistLoader_.media(e),a.tech_.trigger("bandwidthupdate")}),this.mainSegmentLoader_.on("progress",function(){a.trigger("progress")}),this.mainSegmentLoader_.on("error",function(){a.blacklistCurrentPlaylist(a.mainSegmentLoader_.error())}),this.mainSegmentLoader_.on("syncinfoupdate",function(){a.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("timestampoffset",function(){a.tech_.trigger({type:"usage",name:"hls-timestamp-offset"})}),this.audioSegmentLoader_.on("syncinfoupdate",function(){a.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("ended",function(){a.onEndOfStream()}),this.mainSegmentLoader_.on("earlyabort",function(){a.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120)}),this.mainSegmentLoader_.on("reseteverything",function(){a.tech_.trigger("hls-reset")}),this.mainSegmentLoader_.on("segmenttimemapping",function(e){a.tech_.trigger({type:"hls-segment-time-mapping",mapping:e.mapping})}),this.audioSegmentLoader_.on("ended",function(){a.onEndOfStream()})}},{key:"mediaSecondsLoaded_",value:function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)}},{key:"load",value:function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()}},{key:"smoothQualityChange_",value:function(){var e=this.selectPlaylist();e!==this.masterPlaylistLoader_.media()&&(this.masterPlaylistLoader_.media(e),this.mainSegmentLoader_.resetLoader())}},{key:"fastQualityChange_",value:function(){var e=this,t=this.selectPlaylist();t!==this.masterPlaylistLoader_.media()&&(this.masterPlaylistLoader_.media(t),this.mainSegmentLoader_.resetEverything(function(){bs.browser.IE_VERSION||bs.browser.IS_EDGE?e.tech_.setCurrentTime(e.tech_.currentTime()+.04):e.tech_.setCurrentTime(e.tech_.currentTime())}))}},{key:"play",value:function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.seekTo_(0),this.hasPlayed_()&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()<e.start(0)?this.seekTo_(e.end(e.length-1)):void 0}}},{key:"setupFirstPlay",value:function(){var e=this,t=this.masterPlaylistLoader_.media();if(!t||this.tech_.paused()||this.hasPlayed_())return!1;if(!t.endList){var i=this.seekable();if(!i.length)return!1;if(bs.browser.IE_VERSION&&0===this.tech_.readyState())return this.tech_.one("loadedmetadata",function(){e.trigger("firstplay"),e.seekTo_(i.end(0)),e.hasPlayed_=function(){return!0}}),!1;this.trigger("firstplay"),this.seekTo_(i.end(0))}return this.hasPlayed_=function(){return!0},this.load(),!0}},{key:"handleSourceOpen_",value:function(){try{this.setupSourceBuffers_()}catch(e){return bs.log.warn("Failed to create Source Buffers",e),this.mediaSource.endOfStream("decode")}if(this.tech_.autoplay()){var e=this.tech_.play();"undefined"!=typeof e&&"function"==typeof e.then&&e.then(null,function(e){})}this.trigger("sourceopen")}},{key:"onEndOfStream",value:function(){var e=this.mainSegmentLoader_.ended_;if(this.mediaTypes_.AUDIO.activePlaylistLoader&&(e=!this.mainSegmentLoader_.startingMedia_||this.mainSegmentLoader_.startingMedia_.containsVideo?e&&this.audioSegmentLoader_.ended_:this.audioSegmentLoader_.ended_),e){this.logger_("calling mediaSource.endOfStream()");try{this.mediaSource.endOfStream()}catch(e){bs.log.warn("Failed to call media source endOfStream",e)}}}},{key:"stuckAtPlaylistEnd_",value:function(e){if(!this.seekable().length)return!1;var t=this.syncController_.getExpiredTime(e,this.mediaSource.duration);if(null===t)return!1;var i=Wd.Playlist.playlistEnd(e,t),n=this.tech_.currentTime(),r=this.tech_.buffered();if(!r.length)return i-n<=.1;var a=r.end(r.length-1);return a-n<=.1&&i-a<=.1}},{key:"blacklistCurrentPlaylist",value:function(e,t){var i,n=0<arguments.length&&void 0!==e?e:{},r=t,a=void 0;if(a=n.playlist||this.masterPlaylistLoader_.media(),r=r||n.blacklistDuration||this.blacklistDuration,!a){this.error=n;try{return this.mediaSource.endOfStream("network")}catch(e){return this.trigger("error")}}var s=1===this.masterPlaylistLoader_.master.playlists.filter(Zc).length,o=this.masterPlaylistLoader_.master.playlists;return 1===o.length?(bs.log.warn("Problem encountered with the current HLS playlist. Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.masterPlaylistLoader_.load(s)):(s&&(bs.log.warn("Removing all playlists from the blacklist because the last rendition is about to be blacklisted."),o.forEach(function(e){e.excludeUntil!==1/0&&delete e.excludeUntil}),this.tech_.trigger("retryplaylist")),a.excludeUntil=Date.now()+1e3*r,this.tech_.trigger("blacklistplaylist"),this.tech_.trigger({type:"usage",name:"hls-rendition-blacklisted"}),i=this.selectPlaylist(),bs.log.warn("Problem encountered with the current HLS playlist."+(n.message?" "+n.message:"")+" Switching to another playlist."),this.masterPlaylistLoader_.media(i,s))}},{key:"pauseLoading",value:function(){this.mainSegmentLoader_.pause(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.pause(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.pause()}},{key:"setCurrentTime",value:function(e){var t=ph(this.tech_.buffered(),e);return this.masterPlaylistLoader_&&this.masterPlaylistLoader_.media()&&this.masterPlaylistLoader_.media().segments?t&&t.length?e:(this.mainSegmentLoader_.resetEverything(),this.mainSegmentLoader_.abort(),this.mediaTypes_.AUDIO.activePlaylistLoader&&(this.audioSegmentLoader_.resetEverything(),this.audioSegmentLoader_.abort()),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&(this.subtitleSegmentLoader_.resetEverything(),this.subtitleSegmentLoader_.abort()),void this.load()):0}},{key:"duration",value:function(){return this.masterPlaylistLoader_?this.mediaSource?this.mediaSource.duration:Wd.Playlist.duration(this.masterPlaylistLoader_.media()):0}},{key:"seekable",value:function(){return this.seekable_}},{key:"onSyncInfoUpdate_",value:function(){var e=void 0,t=void 0;if(this.masterPlaylistLoader_){var i=this.masterPlaylistLoader_.media();if(i){var n=this.syncController_.getExpiredTime(i,this.mediaSource.duration);if(null!==n&&0!==(e=Wd.Playlist.seekable(i,n)).length){if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(i=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),null===(n=this.syncController_.getExpiredTime(i,this.mediaSource.duration)))return;if(0===(t=Wd.Playlist.seekable(i,n)).length)return}var r=void 0,a=void 0;this.seekable_&&this.seekable_.length&&(r=this.seekable_.end(0),a=this.seekable_.start(0)),t?t.start(0)>e.end(0)||e.start(0)>t.end(0)?this.seekable_=e:this.seekable_=bs.createTimeRanges([[t.start(0)>e.start(0)?t.start(0):e.start(0),t.end(0)<e.end(0)?t.end(0):e.end(0)]]):this.seekable_=e,this.seekable_&&this.seekable_.length&&this.seekable_.end(0)===r&&this.seekable_.start(0)===a||(this.logger_("seekable updated ["+mh(this.seekable_)+"]"),this.tech_.trigger("seekablechanged"))}}}}},{key:"updateDuration",value:function(){function e(){t.logger_("Setting duration from "+t.mediaSource.duration+" => "+n);try{t.mediaSource.duration=n}catch(e){bs.log.warn("Failed to set media source duration",e)}t.tech_.trigger("durationchange"),t.mediaSource.removeEventListener("sourceopen",e)}var t=this,i=this.mediaSource.duration,n=Wd.Playlist.duration(this.masterPlaylistLoader_.media()),r=this.tech_.buffered();0<r.length&&(n=Math.max(n,r.end(r.length-1))),i!==n&&("open"!==this.mediaSource.readyState?this.mediaSource.addEventListener("sourceopen",e):e())}},{key:"dispose",value:function(){var n=this;this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),["AUDIO","SUBTITLES"].forEach(function(e){var t=n.mediaTypes_[e].groups;for(var i in t)t[i].forEach(function(e){e.playlistLoader&&e.playlistLoader.dispose()})}),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose()}},{key:"master",value:function(){return this.masterPlaylistLoader_.master}},{key:"media",value:function(){return this.masterPlaylistLoader_.media()||this.initialMedia_}},{key:"setupSourceBuffers_",value:function(){var e,t=this.masterPlaylistLoader_.media();if(t&&"open"===this.mediaSource.readyState){if((e=Hh(this.masterPlaylistLoader_.master,t)).length<1)return this.error="No compatible SourceBuffer configuration for the variant stream:"+t.resolvedUri,this.mediaSource.endOfStream("decode");this.configureLoaderMimeTypes_(e),this.excludeIncompatibleVariants_(t)}}},{key:"configureLoaderMimeTypes_",value:function(e){var t=1<e.length&&-1===e[0].indexOf(",")&&e[0]!==e[1]?new bs.EventTarget:null;this.mainSegmentLoader_.mimeType(e[0],t),e[1]&&this.audioSegmentLoader_.mimeType(e[1],t)}},{key:"excludeUnsupportedVariants_",value:function(){this.master().playlists.forEach(function(e){e.attributes.CODECS&&v.MediaSource&&v.MediaSource.isTypeSupported&&!v.MediaSource.isTypeSupported('video/mp4; codecs="'+function(e){return e.replace(/avc1\.(\d+)\.(\d+)/i,function(e){return jh([e])[0]})}(e.attributes.CODECS)+'"')&&(e.excludeUntil=1/0)})}},{key:"excludeIncompatibleVariants_",value:function(e){var i=2,n=null,t=void 0;e.attributes.CODECS&&(t=Fh(e.attributes.CODECS),n=t.videoCodec,i=t.codecCount),this.master().playlists.forEach(function(e){var t={codecCount:2,videoCodec:null};e.attributes.CODECS&&(t=Fh(e.attributes.CODECS)),t.codecCount!==i&&(e.excludeUntil=1/0),t.videoCodec!==n&&(e.excludeUntil=1/0)})}},{key:"updateAdCues_",value:function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){var n=2<arguments.length&&void 0!==i?i:0;if(e.segments)for(var r=n,a=void 0,s=0;s<e.segments.length;s++){var o=e.segments[s];if(a=a||xd(t,r+o.duration/2)){if("cueIn"in o){a.endTime=r,a.adEndTime=r,r+=o.duration,a=null;continue}if(r<a.endTime){r+=o.duration;continue}a.endTime+=o.duration}else if("cueOut"in o&&((a=new v.VTTCue(r,r+o.duration,o.cueOut)).adStartTime=r,a.adEndTime=r+parseFloat(o.cueOut),t.addCue(a)),"cueOutCont"in o){var u,l,c=o.cueOutCont.split("/").map(parseFloat),h=jc(c,2);u=h[0],l=h[1],(a=new v.VTTCue(r,r+o.duration,"")).adStartTime=r-u,a.adEndTime=a.adStartTime+l,t.addCue(a)}r+=o.duration}}(e,this.cueTagsTrack_,t)}},{key:"goalBufferLength",value:function(){var e=this.tech_.currentTime(),t=Sd.GOAL_BUFFER_LENGTH,i=Sd.GOAL_BUFFER_LENGTH_RATE,n=Math.max(t,Sd.MAX_GOAL_BUFFER_LENGTH);return Math.min(t+e*i,n)}},{key:"bufferLowWaterLine",value:function(){var e=this.tech_.currentTime(),t=Sd.BUFFER_LOW_WATER_LINE,i=Sd.BUFFER_LOW_WATER_LINE_RATE,n=Math.max(t,Sd.MAX_BUFFER_LOW_WATER_LINE);return Math.min(t+e*i,n)}}]),Xd);function Xd(e){Lc(this,Xd);var t=Uc(this,(Xd.__proto__||Object.getPrototypeOf(Xd)).call(this)),i=e.url,n=e.handleManifestRedirects,r=e.withCredentials,a=e.tech,s=e.bandwidth,o=e.externHls,u=e.useCueTags,l=e.blacklistDuration,c=e.enableLowInitialPlaylist,h=e.sourceType,d=e.seekTo,p=e.cacheEncryptionKeys;if(!i)throw new Error("A non-empty playlist URL is required");Wd=o,t.withCredentials=r,t.tech_=a,t.hls_=a.hls,t.seekTo_=d,t.sourceType_=h,t.useCueTags_=u,t.blacklistDuration=l,t.enableLowInitialPlaylist=c,t.useCueTags_&&(t.cueTagsTrack_=t.tech_.addTextTrack("metadata","ad-cues"),t.cueTagsTrack_.inBandMetadataTrackDispatchType=""),t.requestOptions_={withCredentials:r,handleManifestRedirects:n,timeout:null},t.mediaTypes_=function(){var t={};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){t[e]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:cd,activeTrack:cd,onGroupChanged:cd,onTrackChanged:cd}}),t}(),t.mediaSource=new bs.MediaSource,t.mediaSource.addEventListener("sourceopen",t.handleSourceOpen_.bind(t)),t.seekable_=bs.createTimeRanges(),t.hasPlayed_=function(){return!1},t.syncController_=new Rd(e),t.segmentMetadataTrack_=a.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,t.decrypter_=new Fd,t.inbandTextTracks_={};var f={hls:t.hls_,mediaSource:t.mediaSource,currentTime:t.tech_.currentTime.bind(t.tech_),seekable:function(){return t.seekable()},seeking:function(){return t.tech_.seeking()},duration:function(){return t.mediaSource.duration},hasPlayed:function(){return t.hasPlayed_()},goalBufferLength:function(){return t.goalBufferLength()},bandwidth:s,syncController:t.syncController_,decrypter:t.decrypter_,sourceType:t.sourceType_,inbandTextTracks:t.inbandTextTracks_,cacheEncryptionKeys:p};return t.masterPlaylistLoader_="dash"===t.sourceType_?new od(i,t.hls_,t.requestOptions_):new Hc(i,t.hls_,t.requestOptions_),t.setupMasterPlaylistLoaderListeners_(),t.mainSegmentLoader_=new Ed(bs.mergeOptions(f,{segmentMetadataTrack:t.segmentMetadataTrack_,loaderType:"main"}),e),t.audioSegmentLoader_=new Ed(bs.mergeOptions(f,{loaderType:"audio"}),e),t.subtitleSegmentLoader_=new Id(bs.mergeOptions(f,{loaderType:"vtt"}),e),t.setupSegmentLoaderListeners_(),Gd.forEach(function(e){t[e+"_"]=function(e){return this.audioSegmentLoader_[e]+this.mainSegmentLoader_[e]}.bind(t,e)}),t.logger_=ld("MPC"),t.masterPlaylistLoader_.load(),t}function Kd(e,t,i){Lc(this,Kd);var n=e.masterPlaylistController_,r=n[(e.options_.smoothQualityChange?"smooth":"fast")+"QualityChange_"].bind(n);if(t.attributes.RESOLUTION){var a=t.attributes.RESOLUTION;this.width=a.width,this.height=a.height}this.bandwidth=t.attributes.BANDWIDTH,this.id=i,this.enabled=function(r,a,s){return function(e){var t=r.master.playlists[a],i=Jc(t),n=Zc(t);return"undefined"==typeof e?n:(e?delete t.disabled:t.disabled=!0,e===n||i||(s(),e?r.trigger("renditionenabled"):r.trigger("renditiondisabled")),e)}}(e.playlists,t.uri,r)}var Yd=["seeking","seeked","pause","playing","error"],Qd=(Ic(Jd,[{key:"monitorCurrentTime_",value:function(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&v.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=v.setTimeout(this.monitorCurrentTime_.bind(this),250)}},{key:"checkCurrentTime_",value:function(){if(this.tech_.seeking()&&this.fixesBadSeeks_())return this.consecutiveUpdates=0,void(this.lastRecordedTime=this.tech_.currentTime());if(!this.tech_.paused()&&!this.tech_.seeking()){var e=this.tech_.currentTime(),t=this.tech_.buffered();if(this.lastRecordedTime===e&&(!t.length||e+.1>=t.end(t.length-1)))return this.techWaiting_();5<=this.consecutiveUpdates&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e)}}},{key:"cancelTimer_",value:function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null}},{key:"fixesBadSeeks_",value:function(){if(!this.tech_.seeking())return!1;var e=this.seekable(),t=this.tech_.currentTime(),i=void 0;return this.afterSeekableWindow_(e,t,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(i=e.end(e.length-1)),this.beforeSeekableWindow_(e,t)&&(i=e.start(0)+.1),"undefined"!=typeof i&&(this.logger_("Trying to seek outside of seekable at time "+t+" with seekable range "+mh(e)+". Seeking to "+i+"."),this.seekTo(i),!0)}},{key:"waiting_",value:function(){if(!this.techWaiting_()){var e=this.tech_.currentTime(),t=this.tech_.buffered(),i=ph(t,e);return i.length&&e+3<=i.end(0)?(this.cancelTimer_(),this.seekTo(e),this.logger_("Stopped at "+e+" while inside a buffered region ["+i.start(0)+" -> "+i.end(0)+"]. Attempting to resume playback by seeking to the current time."),void this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})):void 0}}},{key:"techWaiting_",value:function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return!0;if(this.tech_.seeking()||null!==this.timer_)return!0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.seekTo(i),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}var n=this.tech_.buffered(),r=fh(n,t);if(this.videoUnderflow_(r,n,t))return this.cancelTimer_(),this.seekTo(t),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;if(0<r.length){var a=r.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+a+", seeking to "+r.start(0)),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*a,t),!0}return!1}},{key:"afterSeekableWindow_",value:function(e,t,i,n){var r=3<arguments.length&&void 0!==n&&n;if(!e.length)return!1;var a=e.end(e.length-1)+.1;return!i.endList&&r&&(a=e.end(e.length-1)+3*i.targetDuration),a<t}},{key:"beforeSeekableWindow_",value:function(e,t){return!!(e.length&&0<e.start(0)&&t<e.start(0)-.1)}},{key:"videoUnderflow_",value:function(e,t,i){if(0===e.length){var n=this.gapFromVideoUnderflow_(t,i);if(n)return this.logger_("Encountered a gap in video from "+n.start+" to "+n.end+". Seeking to current time "+i),!0}return!1}},{key:"skipTheGap_",value:function(e){var t=this.tech_.buffered(),i=this.tech_.currentTime(),n=fh(t,i);this.cancelTimer_(),0!==n.length&&i===e&&(this.logger_("skipTheGap_:","currentTime:",i,"scheduled currentTime:",e,"nextRange start:",n.start(0)),this.seekTo(n.start(0)+Ah),this.tech_.trigger({type:"usage",name:"hls-gap-skip"}))}},{key:"gapFromVideoUnderflow_",value:function(e,t){for(var i=function(e){if(e.length<2)return bs.createTimeRanges();for(var t=[],i=1;i<e.length;i++){var n=e.end(i-1),r=e.start(i);t.push([n,r])}return bs.createTimeRanges(t)}(e),n=0;n<i.length;n++){var r=i.start(n),a=i.end(n);if(t-r<4&&2<t-r)return{start:r,end:a}}return null}}]),Jd);function Jd(e){var t=this;Lc(this,Jd),this.tech_=e.tech,this.seekable=e.seekable,this.seekTo=e.seekTo,this.allowSeeksWithinUnsafeLiveWindow=e.allowSeeksWithinUnsafeLiveWindow,this.media=e.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.timer_=null,this.checkCurrentTimeTimeout_=null,this.logger_=ld("PlaybackWatcher"),this.logger_("initialize");function i(){return t.monitorCurrentTime_()}function n(){return t.techWaiting_()}function r(){return t.cancelTimer_()}function a(){return t.fixesBadSeeks_()}this.tech_.on("seekablechanged",a),this.tech_.on("waiting",n),this.tech_.on(Yd,r),this.tech_.on("canplay",i),this.dispose=function(){t.logger_("dispose"),t.tech_.off("seekablechanged",a),t.tech_.off("waiting",n),t.tech_.off(Yd,r),t.tech_.off("canplay",i),t.checkCurrentTimeTimeout_&&v.clearTimeout(t.checkCurrentTimeTimeout_),t.cancelTimer_()}}function Zd(e){!function t(i,e){var n=0,r=0,a=bs.mergeOptions(ep,e);i.ready(function(){i.trigger({type:"usage",name:"hls-error-reload-initialized"})});function s(){r&&i.currentTime(r)}function o(e){null!=e&&(r=i.duration()!==1/0&&i.currentTime()||0,i.one("loadedmetadata",s),i.src(e),i.trigger({type:"usage",name:"hls-error-reload"}),i.play())}function u(){if(Date.now()-n<1e3*a.errorInterval)i.trigger({type:"usage",name:"hls-error-reload-canceled"});else{if(a.getSource&&"function"==typeof a.getSource)return n=Date.now(),a.getSource.call(i,o);bs.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}}function l(){i.off("loadedmetadata",s),i.off("error",u),i.off("dispose",l)}i.on("error",u),i.on("dispose",l),i.reloadSourceOnError=function(e){l(),t(i,e)}}(this,e)}var ep={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_)}};bs.use("*",function(t){return{setSource:function(e,t){t(null,e)},setCurrentTime:function(e){return t.vhs&&t.currentSource().src===t.vhs.source_.src&&t.vhs.setCurrentTime(e),e},play:function(){t.vhs&&t.currentSource().src===t.vhs.source_.src&&t.vhs.setCurrentTime(t.tech_.currentTime())}}});var tp={PlaylistLoader:Hc,Playlist:kh,Decrypter:Cc,AsyncStream:Tc,decrypt:wc,utils:Eh,STANDARD_PLAYLIST_SELECTOR:function(){return function(e,t,i,n,r){var a=e.playlists.map(function(e){var t,i;return t=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height,{bandwidth:e.attributes.BANDWIDTH||v.Number.MAX_VALUE,width:t,height:i,playlist:e}});_d(a,function(e,t){return e.bandwidth-t.bandwidth});var s=(a=a.filter(function(e){return!kh.isIncompatible(e.playlist)})).filter(function(e){return kh.isEnabled(e.playlist)});s.length||(s=a.filter(function(e){return!kh.isDisabled(e.playlist)}));var o=s.filter(function(e){return e.bandwidth*Sd.BANDWIDTH_VARIANCE<t}),u=o[o.length-1],l=o.filter(function(e){return e.bandwidth===u.bandwidth})[0];if(!1===r){var c=l||s[0]||a[0];return c?c.playlist:null}var h=o.filter(function(e){return e.width&&e.height});_d(h,function(e,t){return e.width-t.width});var d=h.filter(function(e){return e.width===i&&e.height===n});u=d[d.length-1];var p=d.filter(function(e){return e.bandwidth===u.bandwidth})[0],f=void 0,m=void 0,g=void 0;p||(m=(f=h.filter(function(e){return e.width>i||e.height>n})).filter(function(e){return e.width===f[0].width&&e.height===f[0].height}),u=m[m.length-1],g=m.filter(function(e){return e.bandwidth===u.bandwidth})[0]);var y=g||p||l||s[0]||a[0];return y?y.playlist:null}(this.playlists.master,this.systemBandwidth,parseInt(vd(this.tech_.el(),"width"),10),parseInt(vd(this.tech_.el(),"height"),10),this.limitRenditionByPlayerDimensions)},INITIAL_PLAYLIST_SELECTOR:function(){var e=this.playlists.master.playlists.filter(kh.isEnabled);return _d(e,function(e,t){return bd(e,t)}),e.filter(function(e){return Fh(e.attributes.CODECS).videoCodec})[0]||null},comparePlaylistBandwidth:bd,comparePlaylistResolution:function(e,t){var i=void 0,n=void 0;return e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width&&(i=e.attributes.RESOLUTION.width),i=i||v.Number.MAX_VALUE,t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width&&(n=t.attributes.RESOLUTION.width),i===(n=n||v.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:ih()};["GOAL_BUFFER_LENGTH","MAX_GOAL_BUFFER_LENGTH","GOAL_BUFFER_LENGTH_RATE","BUFFER_LOW_WATER_LINE","MAX_BUFFER_LOW_WATER_LINE","BUFFER_LOW_WATER_LINE_RATE","BANDWIDTH_VARIANCE"].forEach(function(t){Object.defineProperty(tp,t,{get:function(){return bs.log.warn("using Hls."+t+" is UNSAFE be sure you know what you are doing"),Sd[t]},set:function(e){bs.log.warn("using Hls."+t+" is UNSAFE be sure you know what you are doing"),"number"!=typeof e||e<0?bs.log.warn("value of Hls."+t+" must be greater than or equal to 0"):Sd[t]=e}})});function ip(e){return/^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i.test(e)?"hls":/^application\/dash\+xml/i.test(e)?"dash":null}function np(e,t){for(var i=t.media(),n=-1,r=0;r<e.length;r++)if(e[r].id===i.uri){n=r;break}e.selectedIndex_=n,e.trigger({selectedIndex:n,type:"change"})}var rp="videojs-vhs";tp.canPlaySource=function(){return bs.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};function ap(e){if("dash"===e.options_.sourceType){var t=bs.players[e.tech_.options_.playerId];if(t.eme){var i=function(e,t,i){if(!e)return e;var n={};for(var r in e)n[r]={audioContentType:'audio/mp4; codecs="'+i.attributes.CODECS+'"',videoContentType:'video/mp4; codecs="'+t.attributes.CODECS+'"'},t.contentProtection&&t.contentProtection[r]&&t.contentProtection[r].pssh&&(n[r].pssh=t.contentProtection[r].pssh),"string"==typeof e[r]&&(n[r].url=e[r]);return bs.mergeOptions(e,n)}(e.source_.keySystems,e.playlists.media(),e.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader.media());i&&(t.currentSource().keySystems=i,t.eme.initializeMediaKeys&&t.eme.initializeMediaKeys())}}}function sp(){if(!window.localStorage)return null;var e=window.localStorage.getItem(rp);if(!e)return null;try{return JSON.parse(e)}catch(e){return null}}tp.supportsNativeHls=function(){var t=h.createElement("video");if(!bs.getTech("Html5").isSupported())return!1;return["application/vnd.apple.mpegurl","audio/mpegurl","audio/x-mpegurl","application/x-mpegurl","video/x-mpegurl","video/mpegurl","application/mpegurl"].some(function(e){return/maybe|probably/i.test(t.canPlayType(e))})}(),tp.supportsNativeDash=!!bs.getTech("Html5").isSupported()&&/maybe|probably/i.test(h.createElement("video").canPlayType("application/dash+xml")),tp.supportsTypeNatively=function(e){return"hls"===e?tp.supportsNativeHls:"dash"===e&&tp.supportsNativeDash},tp.isSupported=function(){return bs.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};var op=bs.getComponent("Component"),up=(xc(lp,op),Ic(lp,[{key:"setOptions_",value:function(){var t=this;if(this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.handleManifestRedirects=this.options_.handleManifestRedirects||!1,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.smoothQualityChange=this.options_.smoothQualityChange||!1,this.options_.useBandwidthFromLocalStorage="undefined"!=typeof this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,"number"!=typeof this.options_.blacklistDuration&&(this.options_.blacklistDuration=300),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage){var e=sp();e&&e.bandwidth&&(this.options_.bandwidth=e.bandwidth,this.tech_.trigger({type:"usage",name:"hls-bandwidth-from-local-storage"})),e&&e.throughput&&(this.options_.throughput=e.throughput,this.tech_.trigger({type:"usage",name:"hls-throughput-from-local-storage"}))}"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=Sd.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===Sd.INITIAL_BANDWIDTH,["withCredentials","limitRenditionByPlayerDimensions","bandwidth","smoothQualityChange","customTagParsers","customTagMappers","handleManifestRedirects","cacheEncryptionKeys"].forEach(function(e){"undefined"!=typeof t.source_[e]&&(t.options_[e]=t.source_[e])}),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions}},{key:"src",value:function(e,t){var i=this;e&&(this.setOptions_(),this.options_.url=this.source_.src,this.options_.tech=this.tech_,this.options_.externHls=tp,this.options_.sourceType=ip(t),this.options_.seekTo=function(e){i.tech_.setCurrentTime(e),i.setCurrentTime(e)},this.masterPlaylistController_=new $d(this.options_),this.playbackWatcher_=new Qd(bs.mergeOptions(this.options_,{seekable:function(){return i.seekable()},media:function(){return i.masterPlaylistController_.media()}})),this.masterPlaylistController_.on("error",function(){bs.players[i.tech_.options_.playerId].error(i.masterPlaylistController_.error)}),this.masterPlaylistController_.selectPlaylist=this.selectPlaylist?this.selectPlaylist.bind(this):tp.STANDARD_PLAYLIST_SELECTOR.bind(this),this.masterPlaylistController_.selectInitialPlaylist=tp.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.masterPlaylistController_.masterPlaylistLoader_,this.mediaSource=this.masterPlaylistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get:function(){return this.masterPlaylistController_.selectPlaylist},set:function(e){this.masterPlaylistController_.selectPlaylist=e.bind(this)}},throughput:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.throughput.rate},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.throughput.rate=e,this.masterPlaylistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.bandwidth},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.bandwidth=e,this.masterPlaylistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get:function(){var e=1/(this.bandwidth||1),t=void 0;return t=0<this.throughput?1/this.throughput:0,Math.floor(1/(e+t))},set:function(){bs.log.error('The "systemBandwidth" property is read-only')}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return i.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return i.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return i.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return i.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return i.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return i.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return i.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return i.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},buffered:{get:function(){return gh(i.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return i.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return i.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return i.tech_.name_},enumerable:!0},duration:{get:function(){return i.tech_.duration()},enumerable:!0},master:{get:function(){return i.playlists.master},enumerable:!0},playerDimensions:{get:function(){return i.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return gh(i.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return i.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",function(){i.options_.useBandwidthFromLocalStorage&&function(e){if(window.localStorage){var t=sp();t=t?bs.mergeOptions(t,e):e;try{window.localStorage.setItem(rp,JSON.stringify(t))}catch(e){return}}}({bandwidth:i.bandwidth,throughput:Math.round(i.throughput)})}),this.masterPlaylistController_.on("selectedinitialmedia",function(){!function(i){var e=i.playlists;i.representations=function(){return e.master.playlists.filter(function(e){return!Jc(e)}).map(function(e,t){return new Kd(i,e,e.uri)})}}(i),ap(i)}),this.on(this.masterPlaylistController_,"progress",function(){this.tech_.trigger("progress")}),this.tech_.ready(function(){return i.setupQualityLevels_()}),this.tech_.el()&&this.tech_.src(bs.URL.createObjectURL(this.masterPlaylistController_.mediaSource)))}},{key:"setupQualityLevels_",value:function(){var e=this,t=bs.players[this.tech_.options_.playerId];t&&t.qualityLevels&&(this.qualityLevels_=t.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",function(){!function(t,e){e.representations().forEach(function(e){t.addQualityLevel(e)}),np(t,e.playlists)}(e.qualityLevels_,e)}),this.playlists.on("mediachange",function(){np(e.qualityLevels_,e.playlists)}))}},{key:"play",value:function(){this.masterPlaylistController_.play()}},{key:"setCurrentTime",value:function(e){this.masterPlaylistController_.setCurrentTime(e)}},{key:"duration",value:function(){return this.masterPlaylistController_.duration()}},{key:"seekable",value:function(){return this.masterPlaylistController_.seekable()}},{key:"dispose",value:function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.hls&&delete this.tech_.hls,function e(t,i,n){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,i);if(void 0===r){var a=Object.getPrototypeOf(t);return null===a?void 0:e(a,i,n)}if("value"in r)return r.value;var s=r.get;return void 0!==s?s.call(n):void 0}(lp.prototype.__proto__||Object.getPrototypeOf(lp.prototype),"dispose",this).call(this)}},{key:"convertToProgramTime",value:function(e,t){return ch({playlist:this.masterPlaylistController_.media(),time:e,callback:t})}},{key:"seekToProgramTime",value:function(e,t,i,n){var r=!(2<arguments.length&&void 0!==i)||i,a=3<arguments.length&&void 0!==n?n:2;return hh({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:a,pauseAfterSeek:r,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})}}]),lp);function lp(e,t,i){Lc(this,lp);var n=Uc(this,(lp.__proto__||Object.getPrototypeOf(lp)).call(this,t,i.hls));if(t.options_&&t.options_.playerId){var r=bs(t.options_.playerId);r.hasOwnProperty("hls")||Object.defineProperty(r,"hls",{get:function(){return bs.log.warn("player.hls is deprecated. Use player.tech().hls instead."),t.trigger({type:"usage",name:"hls-player-access"}),n},configurable:!0}),r.vhs=n,(r.dash=n).player_=r}if(n.tech_=t,n.source_=e,n.stats={},n.setOptions_(),n.options_.overrideNative&&t.overrideNativeAudioTracks&&t.overrideNativeVideoTracks)t.overrideNativeAudioTracks(!0),t.overrideNativeVideoTracks(!0);else if(n.options_.overrideNative&&(t.featuresNativeVideoTracks||t.featuresNativeAudioTracks))throw new Error("Overriding native HLS requires emulated tracks. See https://git.io/vMpjB");return n.on(h,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],function(e){var t=h.fullscreenElement||h.webkitFullscreenElement||h.mozFullScreenElement||h.msFullscreenElement;t&&t.contains(n.tech_.el())&&n.masterPlaylistController_.smoothQualityChange_()}),n.on(n.tech_,"seeking",function(){0===this.tech_.currentTime()&&this.tech_.player_.loop()&&this.setCurrentTime(0)}),n.on(n.tech_,"error",function(){this.masterPlaylistController_&&this.masterPlaylistController_.pauseLoading()}),n.on(n.tech_,"play",n.play),n}var cp={name:"videojs-http-streaming",VERSION:"1.10.3",canHandleSource:function(e,t){var i=bs.mergeOptions(bs.options,1<arguments.length&&void 0!==t?t:{});return cp.canPlayType(e.type,i)},handleSource:function(e,t,i){var n=bs.mergeOptions(bs.options,2<arguments.length&&void 0!==i?i:{});return t.hls=new up(e,t,n),t.hls.xhr=ih(),t.hls.src(e.src,e.type),t.hls},canPlayType:function(e,t){var i=bs.mergeOptions(bs.options,1<arguments.length&&void 0!==t?t:{}).hls.overrideNative,n=ip(e);return n&&(!tp.supportsTypeNatively(n)||i)?"maybe":""}};return"undefined"!=typeof bs.MediaSource&&"undefined"!=typeof bs.URL||(bs.MediaSource=ed,bs.URL=td),ed.supportsNativeMediaSources()&&bs.getTech("Html5").registerSourceHandler(cp,0),bs.HlsHandler=up,bs.HlsSourceHandler=cp,bs.Hls=tp,bs.use||bs.registerComponent("Hls",tp),bs.options.hls=bs.options.hls||{},bs.registerPlugin?bs.registerPlugin("reloadSourceOnError",Zd):bs.plugin("reloadSourceOnError",Zd),bs}); \ No newline at end of file
+var Nu=function(e,t,i){return t&&Bu(e.prototype,t),i&&Bu(e,i),e};function Bu(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function ju(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function Fu(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function Hu(r,a){["AUDIO","SUBTITLES"].forEach(function(e){for(var t in r.mediaGroups[e])for(var i in r.mediaGroups[e][t]){var n=r.mediaGroups[e][t][i];a(n,e,t,i)}})}function Vu(e,t){var i=Gu(e,{}),n=i.playlists[t.uri];if(!n)return null;if(n.segments&&t.segments&&n.segments.length===t.segments.length&&n.endList===t.endList&&n.mediaSequence===t.mediaSequence)return null;var r=Gu(n,t);n.segments&&(r.segments=function(e,t,i){var n=t.slice();i=i||0;for(var r=Math.min(e.length,t.length+i),a=i;a<r;a++)n[a-i]=Gu(e[a],n[a-i]);return n}(n.segments,t.segments,t.mediaSequence-n.mediaSequence)),r.segments.forEach(function(e){!function(e,t){e.resolvedUri||(e.resolvedUri=Uu(t,e.uri)),e.key&&!e.key.resolvedUri&&(e.key.resolvedUri=Uu(t,e.key.uri)),e.map&&!e.map.resolvedUri&&(e.map.resolvedUri=Uu(t,e.map.uri))}(e,r.resolvedUri)});for(var a=0;a<i.playlists.length;a++)i.playlists[a].uri===t.uri&&(i.playlists[a]=r);return i.playlists[t.uri]=r,i}function qu(e){for(var t=e.playlists.length;t--;){var i=e.playlists[t];(e.playlists[i.uri]=i).resolvedUri=Uu(e.uri,i.uri),i.id=t,i.attributes||(i.attributes={},Xu.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute."))}}function Wu(t){Hu(t,function(e){e.uri&&(e.resolvedUri=Uu(t.uri,e.uri))})}function zu(e,t){var i=e.segments[e.segments.length-1];return t&&i&&i.duration?1e3*i.duration:500*(e.targetDuration||10)}var $u=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var i=[],n=!0,r=!1,a=void 0;try{for(var s,o=e[Symbol.iterator]();!(n=(s=o.next()).done)&&(i.push(s.value),!t||i.length!==t);n=!0);}catch(e){r=!0,a=e}finally{try{!n&&o.return&&o.return()}finally{if(r)throw a}}return i}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},Gu=fs.mergeOptions,Xu=fs.log,Ku=(ju(Yu,fs.EventTarget),Nu(Yu,[{key:"playlistRequestError",value:function(e,t,i){this.request=null,i&&(this.state=i),this.error={playlist:this.master.playlists[t],status:e.status,message:"HLS playlist request error at URL: "+t+".",responseText:e.responseText,code:500<=e.status?4:2},this.trigger("error")}},{key:"haveMetadata",value:function(e,t){var i=this;this.request=null,this.state="HAVE_METADATA";var n=new Ps;this.customTagParsers.forEach(function(e){return n.addParser(e)}),this.customTagMappers.forEach(function(e){return n.addTagMapper(e)}),n.push(e.responseText),n.end(),n.manifest.uri=t,n.manifest.attributes=n.manifest.attributes||{};var r=Vu(this.master,n.manifest);this.targetDuration=n.manifest.targetDuration,r?(this.master=r,this.media_=this.master.playlists[n.manifest.uri]):this.trigger("playlistunchanged"),this.media().endList||(v.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=v.setTimeout(function(){i.trigger("mediaupdatetimeout")},zu(this.media(),!!r))),this.trigger("loadedplaylist")}},{key:"dispose",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.finalRenditionTimeout)}},{key:"stopRequest",value:function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort()}}},{key:"media",value:function(i,e){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}if(v.clearTimeout(this.finalRenditionTimeout),e){var t=i.targetDuration/2*1e3||5e3;this.finalRenditionTimeout=v.setTimeout(this.media.bind(this,i,!1),t)}else{var r=this.state,a=!this.media_||i.uri!==this.media_.uri;if(this.master.playlists[i.uri].endList)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=i,void(a&&(this.trigger("mediachanging"),this.trigger("mediachange")));if(a){if(this.state="SWITCHING_MEDIA",this.request){if(i.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.request=this.hls_.xhr({uri:i.resolvedUri,withCredentials:this.withCredentials},function(e,t){if(n.request){if(i.resolvedUri=Ru(n.handleManifestRedirects,i.resolvedUri,t),e)return n.playlistRequestError(n.request,i.uri,r);n.haveMetadata(t,i.uri),"HAVE_MASTER"===r?n.trigger("loadedmetadata"):n.trigger("mediachange")}})}}}},{key:"pause",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")}},{key:"load",value:function(e){var t=this;v.clearTimeout(this.mediaUpdateTimeout);var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=v.setTimeout(function(){return t.load()},n)}else this.started?i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()}},{key:"start",value:function(){var n=this;this.started=!0,this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(n.request){if(n.request=null,e)return n.error={status:t.status,message:"HLS playlist request error at URL: "+n.srcUrl+".",responseText:t.responseText,code:2},"HAVE_NOTHING"===n.state&&(n.started=!1),n.trigger("error");var i=new Ps;return n.customTagParsers.forEach(function(e){return i.addParser(e)}),n.customTagMappers.forEach(function(e){return i.addTagMapper(e)}),i.push(t.responseText),i.end(),n.state="HAVE_MASTER",n.srcUrl=Ru(n.handleManifestRedirects,n.srcUrl,t),i.manifest.uri=n.srcUrl,i.manifest.playlists?(n.master=i.manifest,qu(n.master),Wu(n.master),n.trigger("loadedplaylist"),void(n.request||n.media(i.manifest.playlists[0]))):(n.master={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:v.location.href,playlists:[{uri:n.srcUrl,id:0,resolvedUri:n.srcUrl,attributes:{}}]},n.master.playlists[n.srcUrl]=n.master.playlists[0],n.haveMetadata(t,n.srcUrl),n.trigger("loadedmetadata"))}})}}]),Yu);function Yu(e,t){var i=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};Mu(this,Yu);var n=Fu(this,(Yu.__proto__||Object.getPrototypeOf(Yu)).call(this)),r=i.withCredentials,a=void 0!==r&&r,s=i.handleManifestRedirects,o=void 0!==s&&s;n.srcUrl=e,n.hls_=t,n.withCredentials=a,n.handleManifestRedirects=o;var u=t.options_;if(n.customTagParsers=u&&u.customTagParsers||[],n.customTagMappers=u&&u.customTagMappers||[],!n.srcUrl)throw new Error("A non-empty playlist URL is required");return n.state="HAVE_NOTHING",n.on("mediaupdatetimeout",function(){"HAVE_METADATA"===n.state&&(n.state="HAVE_CURRENT_METADATA",n.request=n.hls_.xhr({uri:Uu(n.master.uri,n.media().uri),withCredentials:n.withCredentials},function(e,t){if(n.request)return e?n.playlistRequestError(n.request,n.media().uri,"HAVE_METADATA"):void n.haveMetadata(n.request,n.media().uri)}))}),n}function Qu(e,t,i){var n,r;return"undefined"==typeof t&&(t=e.mediaSequence+e.segments.length),t<e.mediaSequence?0:(n=function(e,t){var i=0,n=t-e.mediaSequence,r=e.segments[n];if(r){if("undefined"!=typeof r.start)return{result:r.start,precise:!0};if("undefined"!=typeof r.end)return{result:r.end-r.duration,precise:!0}}for(;n--;){if("undefined"!=typeof(r=e.segments[n]).end)return{result:i+r.end,precise:!0};if(i+=r.duration,"undefined"!=typeof r.start)return{result:i+r.start,precise:!0}}return{result:i,precise:!1}}(e,t)).precise?n.result:(r=function(e,t){for(var i=0,n=void 0,r=t-e.mediaSequence;r<e.segments.length;r++){if("undefined"!=typeof(n=e.segments[r]).start)return{result:n.start-i,precise:!0};if(i+=n.duration,"undefined"!=typeof n.end)return{result:n.end-i,precise:!0}}return{result:-1,precise:!1}}(e,t)).precise?r.result:n.result+i}function Ju(e,t,i){if(!e)return 0;if("number"!=typeof i&&(i=0),"undefined"==typeof t){if(e.totalDuration)return e.totalDuration;if(!e.endList)return v.Infinity}return Qu(e,t,i)}function Zu(e,t,i){var n=0;if(i<t){var r=[i,t];t=r[0],i=r[1]}if(t<0){for(var a=t;a<Math.min(0,i);a++)n+=e.targetDuration;t=0}for(var s=t;s<i;s++)n+=e.segments[s].duration;return n}function el(e){if(!e.segments.length)return 0;for(var t=e.segments.length-1,i=e.segments[t].duration||e.targetDuration,n=i+2*e.targetDuration;t--&&!(n<=(i+=e.segments[t].duration)););return Math.max(0,t)}function tl(e,t,i){if(!e||!e.segments)return null;if(e.endList)return Ju(e);if(null===t)return null;t=t||0;var n=i?el(e):e.segments.length;return Qu(e,e.mediaSequence+n,t)}function il(e){return e-Math.floor(e)==0}function nl(e,t){if(il(t))return t+.1*e;for(var i=t.toString().split(".")[1].length,n=1;n<=i;n++){var r=Math.pow(10,n),a=t*r;if(il(a)||n===i)return(a+e)/r}}function rl(e){return e.excludeUntil&&e.excludeUntil>Date.now()}function al(e){return e.excludeUntil&&e.excludeUntil===1/0}function sl(e){var t=rl(e);return!e.disabled&&!t}function ol(e,t){return t.attributes&&t.attributes[e]}function ul(e,t){if(1===e.playlists.length)return!0;var i=t.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===e.playlists.filter(function(e){return!!sl(e)&&(e.attributes.BANDWIDTH||0)<i}).length}function ll(){return function e(t,n){t=xl({timeout:45e3},t);var i=e.beforeRequest||fs.Hls.xhr.beforeRequest;if(i&&"function"==typeof i){var r=i(t);r&&(t=r)}var a=Ol(t,function(e,t){var i=a.response;!e&&i&&(a.responseTime=Date.now(),a.roundTripTime=a.responseTime-a.requestTime,a.bytesReceived=i.byteLength||i.length,a.bandwidth||(a.bandwidth=Math.floor(a.bytesReceived/a.roundTripTime*8*1e3))),t.headers&&(a.responseHeaders=t.headers),e&&"ETIMEDOUT"===e.code&&(a.timedout=!0),e||a.aborted||200===t.statusCode||206===t.statusCode||0===t.statusCode||(e=new Error("XHR Failed with a response of: "+(a&&(i||a.responseText)))),n(e,a)}),s=a.abort;return a.abort=function(){return a.aborted=!0,s.apply(a,arguments)},a.uri=t.uri,a.requestTime=Date.now(),a}}function cl(e){var t={};return e.byterange&&(t.Range=function(e){var t;return t=e.offset+e.length-1,"bytes="+e.offset+"-"+t}(e.byterange)),t}function hl(e,t){var i=e.toString(16);return"00".substring(0,2-i.length)+i+(t%2?" ":"")}function dl(e){return 32<=e&&e<126?String.fromCharCode(e):"."}function pl(i){var n={};return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}function fl(e){var t=e.byterange||{length:1/0,offset:0};return[t.length,t.offset,e.resolvedUri].join(",")}function ml(e){return e.resolvedUri}function gl(e){for(var t=Array.prototype.slice.call(e),i="",n=0;n<t.length/16;n++)i+=t.slice(16*n,16*n+16).map(hl).join("")+" "+t.slice(16*n,16*n+16).map(dl).join("")+"\n";return i}function yl(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i,r=e.callback;if(!r)throw new Error("getProgramTime: callback must be provided");if(!t||void 0===n)return r({message:"getProgramTime: playlist and time must be provided"});var a=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i=0,n=void 0,r=0;r<t.segments.length&&!(e<=(i=(n=t.segments[r]).videoTimingInfo?n.videoTimingInfo.transmuxedPresentationEnd:i+n.duration));r++);var a=t.segments[t.segments.length-1];if(a.videoTimingInfo&&a.videoTimingInfo.transmuxedPresentationEnd<e)return null;if(i<e){if(e>i+.25*a.duration)return null;n=a}return{segment:n,estimatedStart:n.videoTimingInfo?n.videoTimingInfo.transmuxedPresentationStart:i-n.duration,type:n.videoTimingInfo?"accurate":"estimate"}}(n,t);if(!a)return r({message:"valid programTime was not found"});if("estimate"===a.type)return r({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:a.estimatedStart});var s={mediaSeconds:n},o=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,n=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*n)}(n,a.segment);return o&&(s.programDateTime=o.toISOString()),r(null,s)}function vl(e){var t=e.programTime,i=e.playlist,n=e.retryCount,r=void 0===n?2:n,a=e.seekTo,s=e.pauseAfterSeek,o=void 0===s||s,u=e.tech,l=e.callback;if(!l)throw new Error("seekToProgramTime: callback must be provided");if("undefined"==typeof t||!i||!a)return l({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"});if(!i.endList&&!u.hasStarted_)return l({message:"player must be playing a live stream to start buffering"});if(!function(e){if(!e.segments||0===e.segments.length)return!1;for(var t=0;t<e.segments.length;t++){if(!e.segments[t].dateTimeObject)return!1}return!0}(i))return l({message:"programDateTime tags must be provided in the manifest "+i.resolvedUri});var c=function(e,t){var i=void 0;try{i=new Date(e)}catch(e){return null}if(!t||!t.segments||0===t.segments.length)return null;var n=t.segments[0];if(i<n.dateTimeObject)return null;for(var r=0;r<t.segments.length-1;r++){if(n=t.segments[r],i<t.segments[r+1].dateTimeObject)break}var a=t.segments[t.segments.length-1],s=a.dateTimeObject,o=a.videoTimingInfo?function(e){return e.transmuxedPresentationEnd-e.transmuxedPresentationStart-e.transmuxerPrependedSeconds}(a.videoTimingInfo):a.duration+.25*a.duration;return new Date(s.getTime()+1e3*o)<i?null:(s<i&&(n=a),{segment:n,estimatedStart:n.videoTimingInfo?n.videoTimingInfo.transmuxedPresentationStart:Ll.duration(t,t.mediaSequence+t.segments.indexOf(n)),type:n.videoTimingInfo?"accurate":"estimate"})}(t,i);if(!c)return l({message:t+" was not found in the stream"});var h=c.segment,d=function(e,t){var i=void 0,n=void 0;try{i=new Date(e),n=new Date(t)}catch(e){}var r=i.getTime();return(n.getTime()-r)/1e3}(h.dateTimeObject,t);if("estimate"===c.type)return 0===r?l({message:t+" is not buffered yet. Try again"}):(a(c.estimatedStart+d),void u.one("seeked",function(){vl({programTime:t,playlist:i,retryCount:r-1,seekTo:a,pauseAfterSeek:o,tech:u,callback:l})}));var p=h.start+d;u.one("seeked",function(){return l(null,u.currentTime())}),o&&u.pause(),a(p)}function _l(e,t){var i=[],n=void 0;if(e&&e.length)for(n=0;n<e.length;n++)t(e.start(n),e.end(n))&&i.push([e.start(n),e.end(n)]);return fs.createTimeRanges(i)}function bl(e,i){return _l(e,function(e,t){return e-.1<=i&&i<=t+.1})}function Tl(e,t){return _l(e,function(e){return t<=e-1/30})}function Sl(e){var t=[];if(!e||!e.length)return"";for(var i=0;i<e.length;i++)t.push(e.start(i)+" => "+e.end(i));return t.join(", ")}function kl(e){for(var t=[],i=0;i<e.length;i++)t.push({start:e.start(i),end:e.end(i)});return t}function Cl(e,t,i){var n=void 0,r=void 0;if(i&&i.cues)for(n=i.cues.length;n--;)(r=i.cues[n]).startTime<=t&&r.endTime>=e&&i.removeCue(r)}function El(e){return isNaN(e)||Math.abs(e)===1/0?Number.MAX_VALUE:e}function wl(e,t,i){var n=v.WebKitDataCue||v.VTTCue;if(t&&t.forEach(function(e){var t=e.stream;this.inbandTextTracks_[t].addCue(new n(e.startTime+this.timestampOffset,e.endTime+this.timestampOffset,e.text))},e),i){var r=El(e.mediaSource_.duration);if(i.forEach(function(e){var i=e.cueTime+this.timestampOffset;!("number"!=typeof i||v.isNaN(i)||i<0)&&i<1/0&&e.frames.forEach(function(e){var t=new n(i,i,e.value||e.url||e.data||"");t.frame=e,t.value=e,function(e){Object.defineProperties(e.frame,{id:{get:function(){return fs.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),e.value.key}},value:{get:function(){return fs.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),e.value.data}},privateData:{get:function(){return fs.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),e.value.data}}})}(t),this.metadataTrack_.addCue(t)},this)},e),e.metadataTrack_&&e.metadataTrack_.cues&&e.metadataTrack_.cues.length){for(var a=e.metadataTrack_.cues,s=[],o=0;o<a.length;o++)a[o]&&s.push(a[o]);var u=s.reduce(function(e,t){var i=e[t.startTime]||[];return i.push(t),e[t.startTime]=i,e},{}),l=Object.keys(u).sort(function(e,t){return Number(e)-Number(t)});l.forEach(function(e,t){var i=u[e],n=Number(l[t+1])||r;i.forEach(function(e){e.endTime=n})})}}}var Al=fs.createTimeRange,Pl=nl.bind(null,1),Il=nl.bind(null,-1),Ll={duration:Ju,seekable:function(e,t){var i=t||0,n=tl(e,t,!0);return null===n?Al():Al(i,n)},safeLiveIndex:el,getMediaInfoForTime:function(e,t,i,n){var r=void 0,a=void 0,s=e.segments.length,o=t-n;if(o<0){if(0<i)for(r=i-1;0<=r;r--)if(a=e.segments[r],0<(o+=Il(a.duration)))return{mediaIndex:r,startTime:n-Zu(e,i,r)};return{mediaIndex:0,startTime:t}}if(i<0){for(r=i;r<0;r++)if((o-=e.targetDuration)<0)return{mediaIndex:0,startTime:t};i=0}for(r=i;r<s;r++)if(a=e.segments[r],(o-=Pl(a.duration))<0)return{mediaIndex:r,startTime:n+Zu(e,i,r)};return{mediaIndex:s-1,startTime:t}},isEnabled:sl,isDisabled:function(e){return e.disabled},isBlacklisted:rl,isIncompatible:al,playlistEnd:tl,isAes:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].key)return!0;return!1},isFmp4:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].map)return!0;return!1},hasAttribute:ol,estimateSegmentRequestTime:function(e,t,i,n){var r=3<arguments.length&&void 0!==n?n:0;return ol("BANDWIDTH",i)?(e*i.attributes.BANDWIDTH-8*r)/t:NaN},isLowestEnabledRendition:ul},Ol=fs.xhr,xl=fs.mergeOptions,Dl=Object.freeze({createTransferableMessage:pl,initSegmentId:fl,segmentKeyId:ml,hexDump:gl,tagDump:function(e){var t=e.bytes;return gl(t)},textRanges:function(e){var t,i,n="",r=void 0;for(r=0;r<e.length;r++)n+=(i=r,(t=e).start(i)+"-"+t.end(i)+" ");return n}}),Ul="undefined"!=typeof window?window:{},Rl="undefined"==typeof Symbol?"__target":Symbol(),Ml="application/javascript",Nl=Ul.BlobBuilder||Ul.WebKitBlobBuilder||Ul.MozBlobBuilder||Ul.MSBlobBuilder,Bl=Ul.URL||Ul.webkitURL||Bl&&Bl.msURL,jl=Ul.Worker;function Fl(r,a){return function(e){var t=this;if(!a)return new jl(r);if(jl&&!e){var i=Wl(a.toString().replace(/^function.+?{/,"").slice(0,-1));return this[Rl]=new jl(i),function(e,t){if(!e||!t)return;var i=e.terminate;e.objURL=t,e.terminate=function(){e.objURL&&Bl.revokeObjectURL(e.objURL),i.call(e)}}(this[Rl],i),this[Rl]}var n={postMessage:function(e){t.onmessage&&setTimeout(function(){t.onmessage({data:e,target:n})})}};a.call(n),this.postMessage=function(e){setTimeout(function(){n.onmessage({data:e,target:t})})},this.isThisThread=!0}}if(jl){var Hl,Vl=Wl("self.onmessage = function () {}"),ql=new Uint8Array(1);try{(Hl=new jl(Vl)).postMessage(ql,[ql.buffer])}catch(e){jl=null}finally{Bl.revokeObjectURL(Vl),Hl&&Hl.terminate()}}function Wl(t){try{return Bl.createObjectURL(new Blob([t],{type:Ml}))}catch(e){var i=new Nl;return i.append(t),Bl.createObjectURL(i.getBlob(type))}}function zl(e){return e.map(function(e){return e.replace(/avc1\.(\d+)\.(\d+)/i,function(e,t,i){return"avc1."+("00"+Number(t).toString(16)).slice(-2)+"00"+("00"+Number(i).toString(16)).slice(-2)})})}function $l(e){var t,i=0<arguments.length&&void 0!==e?e:"",n={codecCount:0};return n.codecCount=i.split(",").length,n.codecCount=n.codecCount||2,(t=/(^|\s|,)+(avc[13])([^ ,]*)/i.exec(i))&&(n.videoCodec=t[2],n.videoObjectTypeIndicator=t[3]),n.audioProfile=/(^|\s|,)+mp4a.[0-9A-Fa-f]+\.([0-9A-Fa-f]+)/i.exec(i),n.audioProfile=n.audioProfile&&n.audioProfile[2],n}function Gl(e,t,i){return e+"/"+t+'; codecs="'+i.filter(function(e){return!!e}).join(", ")+'"'}function Xl(e,t){var i=function(e){return e.segments&&e.segments.length&&e.segments[0].map?"mp4":"mp2t"}(t),n=function(e){var t=e.attributes||{};return t.CODECS?$l(t.CODECS):Jl}(t),r=t.attributes||{},a=!0,s=!1;if(!t)return[];if(e.mediaGroups.AUDIO&&r.AUDIO){var o=e.mediaGroups.AUDIO[r.AUDIO];if(o)for(var u in a=!(s=!0),o)if(!o[u].uri&&!o[u].playlists){a=!0;break}}s&&!n.audioProfile&&(a||(n.audioProfile=function(e,t){if(!e.mediaGroups.AUDIO||!t)return null;var i=e.mediaGroups.AUDIO[t];if(!i)return null;for(var n in i){var r=i[n];if(r.default&&r.playlists)return $l(r.playlists[0].attributes.CODECS).audioProfile}return null}(e,r.AUDIO)),n.audioProfile||(fs.log.warn("Multiple audio tracks present but no audio codec string is specified. Attempting to use the default audio codec (mp4a.40.2)"),n.audioProfile=Jl.audioProfile));var l={};n.videoCodec&&(l.video=""+n.videoCodec+n.videoObjectTypeIndicator),n.audioProfile&&(l.audio="mp4a.40."+n.audioProfile);var c=Gl("audio",i,[l.audio]),h=Gl("video",i,[l.video]),d=Gl("video",i,[l.video,l.audio]);return s?!a&&l.video?[h,c]:a||l.video?[d,c]:[c,c]:l.video?[d]:[c]}function Kl(e){return/mp4a\.\d+.\d+/i.test(e)}function Yl(e){return/avc1\.[\da-f]+/i.test(e)}var Ql=new Fl("./transmuxer-worker.worker.js",function(e,t){var kt=this;!function(){function e(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){var i;return!!a[e]&&(i=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(i,1),-1<i)},this.trigger=function(e){var t,i,n,r;if(t=a[e])if(2===arguments.length)for(n=t.length,i=0;i<n;++i)t[i].call(this,arguments[1]);else{for(r=[],i=arguments.length,i=1;i<arguments.length;++i)r.push(arguments[i]);for(n=t.length,i=0;i<n;++i)t[i].apply(this,r)}},this.dispose=function(){a={}}}}e.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),this.on("partialdone",function(e){t.partialFlush(e)}),this.on("endedtimeline",function(e){t.endTimeline(e)}),this.on("reset",function(e){t.reset(e)}),t},e.prototype.push=function(e){this.trigger("data",e)},e.prototype.flush=function(e){this.trigger("done",e)},e.prototype.partialFlush=function(e){this.trigger("partialdone",e)},e.prototype.endTimeline=function(e){this.trigger("endedtimeline",e)},e.prototype.reset=function(e){this.trigger("reset",e)};var l,t,i,r,a,n,s,o,u,c,h,d,p,f,m,g,y,v,_,b,T,S,k,C,E,w,A,P,I,L,O,x,D,U,R,M,N,B,j,F,H=e,V=Math.pow(2,32)-1;!function(){var e;if(S={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],pasp:[],sdtp:[],smhd:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],styp:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[]},"undefined"!=typeof Uint8Array){for(e in S)S.hasOwnProperty(e)&&(S[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);k=new Uint8Array(["i".charCodeAt(0),"s".charCodeAt(0),"o".charCodeAt(0),"m".charCodeAt(0)]),E=new Uint8Array(["a".charCodeAt(0),"v".charCodeAt(0),"c".charCodeAt(0),"1".charCodeAt(0)]),C=new Uint8Array([0,0,0,1]),w=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]),A=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]),P={video:w,audio:A},O=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),L=new Uint8Array([0,0,0,0,0,0,0,0]),x=new Uint8Array([0,0,0,0,0,0,0,0]),D=x,U=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),R=x,I=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}}(),l=function(e){var t,i,n=[],r=0;for(t=1;t<arguments.length;t++)n.push(arguments[t]);for(t=n.length;t--;)r+=n[t].byteLength;for(i=new Uint8Array(r+8),new DataView(i.buffer,i.byteOffset,i.byteLength).setUint32(0,i.byteLength),i.set(e,4),t=0,r=8;t<n.length;t++)i.set(n[t],r),r+=n[t].byteLength;return i},t=function(){return l(S.dinf,l(S.dref,O))},i=function(e){return l(S.esds,new Uint8Array([0,0,0,0,3,25,0,0,0,4,17,64,21,0,6,0,0,0,218,192,0,0,218,192,5,2,e.audioobjecttype<<3|e.samplingfrequencyindex>>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},m=function(e){return l(S.hdlr,P[e])},f=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(t[12]=e.samplerate>>>24&255,t[13]=e.samplerate>>>16&255,t[14]=e.samplerate>>>8&255,t[15]=255&e.samplerate),l(S.mdhd,t)},p=function(e){return l(S.mdia,f(e),m(e.type),n(e))},a=function(e){return l(S.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},n=function(e){return l(S.minf,"video"===e.type?l(S.vmhd,I):l(S.smhd,L),t(),y(e))},s=function(e,t){for(var i=[],n=t.length;n--;)i[n]=_(t[n]);return l.apply(null,[S.moof,a(e)].concat(i))},o=function(e){for(var t=e.length,i=[];t--;)i[t]=h(e[t]);return l.apply(null,[S.moov,c(4294967295)].concat(i).concat(u(e)))},u=function(e){for(var t=e.length,i=[];t--;)i[t]=b(e[t]);return l.apply(null,[S.mvex].concat(i))},c=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,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 l(S.mvhd,t)},g=function(e){var t,i,n=e.samples||[],r=new Uint8Array(4+n.length);for(i=0;i<n.length;i++)t=n[i].flags,r[i+4]=t.dependsOn<<4|t.isDependedOn<<2|t.hasRedundancy;return l(S.sdtp,r)},y=function(e){return l(S.stbl,v(e),l(S.stts,R),l(S.stsc,D),l(S.stsz,U),l(S.stco,x))},v=function(e){return l(S.stsd,new Uint8Array([0,0,0,0,0,0,0,1]),"video"===e.type?M(e):N(e))},M=function(e){var t,i,n=e.sps||[],r=e.pps||[],a=[],s=[];for(t=0;t<n.length;t++)a.push((65280&n[t].byteLength)>>>8),a.push(255&n[t].byteLength),a=a.concat(Array.prototype.slice.call(n[t]));for(t=0;t<r.length;t++)s.push((65280&r[t].byteLength)>>>8),s.push(255&r[t].byteLength),s=s.concat(Array.prototype.slice.call(r[t]));if(i=[S.avc1,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,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),l(S.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([n.length],a,[r.length],s))),l(S.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],e.sarRatio){var o=e.sarRatio[0],u=e.sarRatio[1];i.push(l(S.pasp,new Uint8Array([(4278190080&o)>>24,(16711680&o)>>16,(65280&o)>>8,255&o,(4278190080&u)>>24,(16711680&u)>>16,(65280&u)>>8,255&u])))}return l.apply(null,i)},N=function(e){return l(S.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),i(e))},d=function(e){var t=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,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,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return l(S.tkhd,t)},_=function(e){var t,i,n,r,a,s;return t=l(S.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),a=Math.floor(e.baseMediaDecodeTime/(1+V)),s=Math.floor(e.baseMediaDecodeTime%(1+V)),i=l(S.tfdt,new Uint8Array([1,0,0,0,a>>>24&255,a>>>16&255,a>>>8&255,255&a,s>>>24&255,s>>>16&255,s>>>8&255,255&s])),92,"audio"===e.type?(n=T(e,92),l(S.traf,t,i,n)):(r=g(e),n=T(e,r.length+92),l(S.traf,t,i,n,r))},h=function(e){return e.duration=e.duration||4294967295,l(S.trak,d(e),p(e))},b=function(e){var t=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==e.type&&(t[t.length-1]=0),l(S.trex,t)},F=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},j=function(e,t){var i,n,r,a;for(t+=20+16*(n=e.samples||[]).length,i=F(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size,r.flags.isLeading<<2|r.flags.dependsOn,r.flags.isDependedOn<<6|r.flags.hasRedundancy<<4|r.flags.paddingValue<<1|r.flags.isNonSyncSample,61440&r.flags.degradationPriority,15&r.flags.degradationPriority,(4278190080&r.compositionTimeOffset)>>>24,(16711680&r.compositionTimeOffset)>>>16,(65280&r.compositionTimeOffset)>>>8,255&r.compositionTimeOffset]);return l(S.trun,new Uint8Array(i))},B=function(e,t){var i,n,r,a;for(t+=20+8*(n=e.samples||[]).length,i=F(n,t),a=0;a<n.length;a++)r=n[a],i=i.concat([(4278190080&r.duration)>>>24,(16711680&r.duration)>>>16,(65280&r.duration)>>>8,255&r.duration,(4278190080&r.size)>>>24,(16711680&r.size)>>>16,(65280&r.size)>>>8,255&r.size]);return l(S.trun,new Uint8Array(i))},T=function(e,t){return"audio"===e.type?B(e,t):j(e,t)};r=function(){return l(S.ftyp,k,C,k,E)};function q(e,t){var i={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return i.dataOffset=t,i.compositionTimeOffset=e.pts-e.dts,i.duration=e.duration,i.size=4*e.length,i.size+=e.byteLength,e.keyFrame&&(i.flags.dependsOn=2,i.flags.isNonSyncSample=0),i}function W(e){for(var t=[];e--;)t.push(0);return t}function z(){z.prototype.init.call(this),this.captionPackets_=[],this.ccStreams_=[new Ie(0,0),new Ie(0,1),new Ie(1,0),new Ie(1,1)],this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("partialdone",this.trigger.bind(this,"partialdone")),e.on("done",this.trigger.bind(this,"done"))},this)}var $,G,X,K,Y,Q=function(e){return l(S.mdat,e)},J=s,Z=function(e){var t,i=r(),n=o(e);return(t=new Uint8Array(i.byteLength+n.byteLength)).set(i),t.set(n,i.byteLength),t},ee=function(e){var t,i,n=[],r=[];for(r.byteLength=0,r.nalCount=0,r.duration=0,t=n.byteLength=0;t<e.length;t++)"access_unit_delimiter_rbsp"===(i=e[t]).nalUnitType?(n.length&&(n.duration=i.dts-n.dts,r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n)),(n=[i]).byteLength=i.data.byteLength,n.pts=i.pts,n.dts=i.dts):("slice_layer_without_partitioning_rbsp_idr"===i.nalUnitType&&(n.keyFrame=!0),n.duration=i.dts-n.dts,n.byteLength+=i.data.byteLength,n.push(i));return r.length&&(!n.duration||n.duration<=0)&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n),r},te=function(e){var t,i,n=[],r=[];for(n.byteLength=0,n.nalCount=0,n.duration=0,n.pts=e[0].pts,n.dts=e[0].dts,r.byteLength=0,r.nalCount=0,r.duration=0,r.pts=e[0].pts,r.dts=e[0].dts,t=0;t<e.length;t++)(i=e[t]).keyFrame?(n.length&&(r.push(n),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration),(n=[i]).nalCount=i.length,n.byteLength=i.byteLength,n.pts=i.pts,n.dts=i.dts,n.duration=i.duration):(n.duration+=i.duration,n.nalCount+=i.length,n.byteLength+=i.byteLength,n.push(i));return r.length&&n.duration<=0&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration,r.push(n),r},ie=function(e){var t;return!e[0][0].keyFrame&&1<e.length&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e},ne=function(e,t){var i,n,r,a,s,o=t||0,u=[];for(i=0;i<e.length;i++)for(a=e[i],n=0;n<a.length;n++)s=a[n],o+=(r=q(s,o)).size,u.push(r);return u},re=function(e){var t,i,n,r,a,s,o=0,u=e.byteLength,l=e.nalCount,c=new Uint8Array(u+4*l),h=new DataView(c.buffer);for(t=0;t<e.length;t++)for(r=e[t],i=0;i<r.length;i++)for(a=r[i],n=0;n<a.length;n++)s=a[n],h.setUint32(o,s.data.byteLength),o+=4,c.set(s.data,o),o+=s.data.byteLength;return c},ae=[33,16,5,32,164,27],se=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],oe={96e3:[ae,[227,64],W(154),[56]],88200:[ae,[231],W(170),[56]],64e3:[ae,[248,192],W(240),[56]],48e3:[ae,[255,192],W(268),[55,148,128],W(54),[112]],44100:[ae,[255,192],W(268),[55,163,128],W(84),[112]],32e3:[ae,[255,192],W(268),[55,234],W(226),[112]],24e3:[ae,[255,192],W(268),[55,255,128],W(268),[111,112],W(126),[224]],16e3:[ae,[255,192],W(268),[55,255,128],W(268),[111,255],W(269),[223,108],W(195),[1,192]],12e3:[se,W(268),[3,127,248],W(268),[6,255,240],W(268),[13,255,224],W(268),[27,253,128],W(259),[56]],11025:[se,W(268),[3,127,248],W(268),[6,255,240],W(268),[13,255,224],W(268),[27,255,192],W(268),[55,175,128],W(108),[112]],8e3:[se,W(268),[3,121,16],W(47),[7]]},ue=($=oe,Object.keys($).reduce(function(e,t){return e[t]=new Uint8Array($[t].reduce(function(e,t){return e.concat(t)},[])),e},{})),le=9e4,ce=(G=function(e){return 9e4*e},X=function(e,t){return e*t},K=function(e){return e/9e4},Y=function(e,t){return e/t},function(e,t){return G(Y(e,t))}),he=function(e,t){return X(K(e),t)},de=function(e,t,i){return K(i?e:e-t)},pe=function(e,t,i,n){var r,a,s,o,u,l=0,c=0,h=0;if(t.length&&(r=ce(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(le/(e.samplerate/1024)),i&&n&&(l=r-Math.max(i,n),h=(c=Math.floor(l/a))*a),!(c<1||le/2<h))){for(s=(s=ue[e.samplerate])||t[0].data,o=0;o<c;o++)u=t[0],t.splice(0,0,{data:s,dts:u.dts-a,pts:u.pts-a});e.baseMediaDecodeTime-=Math.floor(he(h,e.samplerate))}},fe=function(e,t,i){return t.minSegmentDts>=i?e:(t.minSegmentDts=1/0,e.filter(function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)}))},me=function(e){var t,i,n=[];for(t=0;t<e.length;t++)i=e[t],n.push({size:i.data.byteLength,duration:1024});return n},ge=function(e){var t,i,n=0,r=new Uint8Array(function(e){var t,i=0;for(t=0;t<e.length;t++)i+=e[t].data.byteLength;return i}(e));for(t=0;t<e.length;t++)i=e[t],r.set(i.data,n),n+=i.data.byteLength;return r},ye=le,ve=function(e){delete e.minSegmentDts,delete e.maxSegmentDts,delete e.minSegmentPts,delete e.maxSegmentPts},_e=function(e,t){var i,n=e.minSegmentDts;return t||(n-=e.timelineStartInfo.dts),i=e.timelineStartInfo.baseMediaDecodeTime,i+=n,i=Math.max(0,i),"audio"===e.type&&(i*=e.samplerate/ye,i=Math.floor(i)),i},be=function(e,t){"number"==typeof t.pts&&(void 0===e.timelineStartInfo.pts&&(e.timelineStartInfo.pts=t.pts),void 0===e.minSegmentPts?e.minSegmentPts=t.pts:e.minSegmentPts=Math.min(e.minSegmentPts,t.pts),void 0===e.maxSegmentPts?e.maxSegmentPts=t.pts:e.maxSegmentPts=Math.max(e.maxSegmentPts,t.pts)),"number"==typeof t.dts&&(void 0===e.timelineStartInfo.dts&&(e.timelineStartInfo.dts=t.dts),void 0===e.minSegmentDts?e.minSegmentDts=t.dts:e.minSegmentDts=Math.min(e.minSegmentDts,t.dts),void 0===e.maxSegmentDts?e.maxSegmentDts=t.dts:e.maxSegmentDts=Math.max(e.maxSegmentDts,t.dts))},Te=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}t+=r,r=n=0}return i},Se=function(e){return 181!==e.payload[0]?null:49!=(e.payload[1]<<8|e.payload[2])?null:"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])?null:3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},ke=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},Ce=4;(z.prototype=new H).push=function(e){var t,i,n;if("sei_rbsp"===e.nalUnitType&&(t=Te(e.escapedRBSP)).payloadType===Ce&&(i=Se(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));n=ke(e.pts,i),this.captionPackets_=this.captionPackets_.concat(n),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},z.prototype.flushCCStreams=function(t){this.ccStreams_.forEach(function(e){return"flush"===t?e.flush():e.partialFlush()},this)},z.prototype.flushStream=function(e){this.captionPackets_.length&&(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2&&this.dispatchCea608Packet(e)},this),this.captionPackets_.length=0),this.flushCCStreams(e)},z.prototype.flush=function(){return this.flushStream("flush")},z.prototype.partialFlush=function(){return this.flushStream("partialFlush")},z.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},z.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},z.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},z.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},z.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)};function Ee(e){return null===e?"":(e=Ae[e]||e,String.fromCharCode(e))}function we(){for(var e=[],t=15;t--;)e.push("");return e}var Ae={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},Pe=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Ie=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a;if((t=32639&e.ccData)!==this.lastControlCode_){if(4096==(61440&t)?this.lastControlCode_=t:t!==this.PADDING_&&(this.lastControlCode_=null),n=t>>>8,r=255&t,t!==this.PADDING_)if(t===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(t===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),i=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=i,this.startPts_=e.pts;else if(t===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(e.pts);else if(t===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(e.pts);else if(t===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(e.pts);else if(t===this.CARRIAGE_RETURN_)this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts;else if(t===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1);else if(t===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(e.pts),this.displayed_=we();else if(t===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=we();else if(t===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=we()),this.mode_="paintOn",this.startPts_=e.pts;else if(this.isSpecialCharacter(n,r))a=Ee((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isExtCharacter(n,r))"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),a=Ee((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isMidRowCode(n,r))this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&r)&&this.addFormatting(e.pts,["i"]),1==(1&r)&&this.addFormatting(e.pts,["u"]);else if(this.isOffsetControlCode(n,r))this.column_+=3&r;else if(this.isPAC(n,r)){var s=Pe.indexOf(7968&t);"rollUp"===this.mode_&&(s-this.rollUpRows_+1<0&&(s=this.rollUpRows_-1),this.setRollUp(e.pts,s)),s!==this.row_&&(this.clearFormatting(e.pts),this.row_=s),1&r&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&t)&&(this.column_=4*((14&t)>>1)),this.isColorPAC(r)&&14==(14&r)&&this.addFormatting(e.pts,["i"])}else this.isNormalChar(n)&&(0===r&&(r=null),a=Ee(n),a+=Ee(r),this[this.mode_](e.pts,a),this.column_+=a.length)}else this.lastControlCode_=null}};Ie.prototype=new H,Ie.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e){try{return e.trim()}catch(e){return""}}).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_})},Ie.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=we(),this.nonDisplayed_=we(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Ie.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},Ie.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},Ie.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},Ie.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},Ie.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},Ie.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},Ie.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},Ie.prototype.isNormalChar=function(e){return 32<=e&&e<=127},Ie.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=we(),this.displayed_=we()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},Ie.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);var i=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,i)},Ie.prototype.clearFormatting=function(e){if(this.formatting_.length){var t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},"");this.formatting_=[],this[this.mode_](e,t)}},Ie.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];i+=t,this.nonDisplayed_[this.row_]=i},Ie.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i},Ie.prototype.shiftRowsUp_=function(){var e;for(e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},Ie.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i};function Le(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}function Oe(e){var t,i;Oe.prototype.init.call(this),this.type_=e||"shared",this.push=function(e){"shared"!==this.type_&&e.type!==this.type_||(void 0===i&&(i=e.dts),e.dts=Le(e.dts,i),e.pts=Le(e.pts,i),t=e.dts,this.trigger("data",e))},this.flush=function(){i=t,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.discontinuity=function(){t=i=void 0},this.reset=function(){this.discontinuity(),this.trigger("reset")}}var xe={CaptionStream:z,Cea608Stream:Ie},De={H264_STREAM_TYPE:27,ADTS_STREAM_TYPE:15,METADATA_STREAM_TYPE:21};Oe.prototype=new H;function Ue(e,t,i){var n,r="";for(n=t;n<i;n++)r+="%"+("00"+e[n].toString(16)).slice(-2);return r}function Re(e,t,i){return decodeURIComponent(Ue(e,t,i))}function Me(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var Ne,Be=Oe,je={TXXX:function(e){var t;if(3===e.data[0]){for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=Re(e.data,1,t),e.value=Re(e.data,t+1,e.data.length).replace(/\0*$/,"");break}e.data=e.value}},WXXX:function(e){var t;if(3===e.data[0])for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=Re(e.data,1,t),e.url=Re(e.data,t+1,e.data.length);break}},PRIV:function(e){var t,i;for(t=0;t<e.data.length;t++)if(0===e.data[t]){e.owner=(i=e.data,unescape(Ue(i,0,t)));break}e.privateData=e.data.subarray(t+1),e.data=e.privateData}};(Ne=function(e){var t,u={debug:!(!e||!e.debug),descriptor:e&&e.descriptor},l=0,c=[],h=0;if(Ne.prototype.init.call(this),this.dispatchType=De.METADATA_STREAM_TYPE.toString(16),u.descriptor)for(t=0;t<u.descriptor.length;t++)this.dispatchType+=("00"+u.descriptor[t].toString(16)).slice(-2);this.push=function(e){var t,i,n,r,a;if("timed-metadata"===e.type)if(e.dataAlignmentIndicator&&(h=0,c.length=0),0===c.length&&(e.data.length<10||e.data[0]!=="I".charCodeAt(0)||e.data[1]!=="D".charCodeAt(0)||e.data[2]!=="3".charCodeAt(0)))u.debug;else if(c.push(e),h+=e.data.byteLength,1===c.length&&(l=Me(e.data.subarray(6,10)),l+=10),!(h<l)){for(t={data:new Uint8Array(l),frames:[],pts:c[0].pts,dts:c[0].dts},a=0;a<l;)t.data.set(c[0].data.subarray(0,l-a),a),a+=c[0].data.byteLength,h-=c[0].data.byteLength,c.shift();i=10,64&t.data[5]&&(i+=4,i+=Me(t.data.subarray(10,14)),l-=Me(t.data.subarray(16,20)));do{if((n=Me(t.data.subarray(i+4,i+8)))<1)return;if((r={id:String.fromCharCode(t.data[i],t.data[i+1],t.data[i+2],t.data[i+3]),data:t.data.subarray(i+10,i+n+10)}).key=r.id,je[r.id]&&(je[r.id](r),"com.apple.streaming.transportStreamTimestamp"===r.owner)){var s=r.data,o=(1&s[3])<<30|s[4]<<22|s[5]<<14|s[6]<<6|s[7]>>>2;o*=4,o+=3&s[7],r.timeStamp=o,void 0===t.pts&&void 0===t.dts&&(t.pts=r.timeStamp,t.dts=r.timeStamp),this.trigger("timestamp",r)}t.frames.push(r),i+=10,i+=n}while(i<l);this.trigger("data",t)}}}).prototype=new H;var Fe,He,Ve,qe=Ne,We=Be;(Fe=function(){var r=new Uint8Array(188),a=0;Fe.prototype.init.call(this),this.push=function(e){var t,i=0,n=188;for(a?((t=new Uint8Array(e.byteLength+a)).set(r.subarray(0,a)),t.set(e,a),a=0):t=e;n<t.byteLength;)71!==t[i]||71!==t[n]?(i++,n++):(this.trigger("data",t.subarray(i,n)),i+=188,n+=188);i<t.byteLength&&(r.set(t.subarray(i),0),a=t.byteLength-i)},this.flush=function(){188===a&&71===r[0]&&(this.trigger("data",r),a=0),this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.reset=function(){a=0,this.trigger("reset")}}).prototype=new H,(He=function(){var n,r,a,s;He.prototype.init.call(this),(s=this).packetsWaitingForPmt=[],this.programMapTable=void 0,n=function(e,t){var i=0;t.payloadUnitStartIndicator&&(i+=e[i]+1),"pat"===t.type?r(e.subarray(i),t):a(e.subarray(i),t)},r=function(e,t){t.section_number=e[7],t.last_section_number=e[8],s.pmtPid=(31&e[10])<<8|e[11],t.pmtPid=s.pmtPid},a=function(e,t){var i,n;if(1&e[5]){for(s.programMapTable={video:null,audio:null,"timed-metadata":{}},i=3+((15&e[1])<<8|e[2])-4,n=12+((15&e[10])<<8|e[11]);n<i;){var r=e[n],a=(31&e[n+1])<<8|e[n+2];r===De.H264_STREAM_TYPE&&null===s.programMapTable.video?s.programMapTable.video=a:r===De.ADTS_STREAM_TYPE&&null===s.programMapTable.audio?s.programMapTable.audio=a:r===De.METADATA_STREAM_TYPE&&(s.programMapTable["timed-metadata"][a]=r),n+=5+((15&e[n+3])<<8|e[n+4])}t.programMapTable=s.programMapTable}},this.push=function(e){var t={},i=4;if(t.payloadUnitStartIndicator=!!(64&e[1]),t.pid=31&e[1],t.pid<<=8,t.pid|=e[2],1<(48&e[3])>>>4&&(i+=e[i]+1),0===t.pid)t.type="pat",n(e.subarray(i),t),this.trigger("data",t);else if(t.pid===this.pmtPid)for(t.type="pmt",n(e.subarray(i),t),this.trigger("data",t);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([e,i,t]):this.processPes_(e,i,t)},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=De.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=De.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i)}}).prototype=new H,He.STREAM_TYPES={h264:27,adts:15},(Ve=function(){function n(e,t,i){var n,r,a=new Uint8Array(e.size),s={type:t},o=0,u=0;if(e.data.length&&!(e.size<9)){for(s.trackId=e.data[0].pid,o=0;o<e.data.length;o++)r=e.data[o],a.set(r.data,u),u+=r.data.byteLength;!function(e,t){var i;t.packetLength=6+(e[4]<<8|e[5]),t.dataAlignmentIndicator=0!=(4&e[6]),192&(i=e[7])&&(t.pts=(14&e[9])<<27|(255&e[10])<<20|(254&e[11])<<12|(255&e[12])<<5|(254&e[13])>>>3,t.pts*=4,t.pts+=(6&e[13])>>>1,t.dts=t.pts,64&i&&(t.dts=(14&e[14])<<27|(255&e[15])<<20|(254&e[16])<<12|(255&e[17])<<5|(254&e[18])>>>3,t.dts*=4,t.dts+=(6&e[18])>>>1)),t.data=e.subarray(9+e[8])}(a,s),n="video"===t||s.packetLength<=e.size,(i||n)&&(e.size=0,e.data.length=0),n&&l.trigger("data",s)}}var t,l=this,r={data:[],size:0},a={data:[],size:0},s={data:[],size:0};Ve.prototype.init.call(this),this.push=function(i){({pat:function(){},pes:function(){var e,t;switch(i.streamType){case De.H264_STREAM_TYPE:case De.H264_STREAM_TYPE:e=r,t="video";break;case De.ADTS_STREAM_TYPE:e=a,t="audio";break;case De.METADATA_STREAM_TYPE:e=s,t="timed-metadata";break;default:return}i.payloadUnitStartIndicator&&n(e,t,!0),e.data.push(i),e.size+=i.data.byteLength},pmt:function(){var e={type:"metadata",tracks:[]};null!==(t=i.programMapTable).video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),l.trigger("data",e)}})[i.type]()},this.reset=function(){r.size=0,r.data.length=0,a.size=0,a.data.length=0,this.trigger("reset")},this.flushStreams_=function(){n(r,"video"),n(a,"audio"),n(s,"timed-metadata")},this.flush=function(){this.flushStreams_(),this.trigger("done")}}).prototype=new H;var ze={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:Fe,TransportParseStream:He,ElementaryStream:Ve,TimestampRolloverStream:We,CaptionStream:xe.CaptionStream,Cea608Stream:xe.Cea608Stream,MetadataStream:qe};for(var $e in De)De.hasOwnProperty($e)&&(ze[$e]=De[$e]);var Ge,Xe=ze,Ke=le,Ye=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(Ge=function(u){var l,c=0;Ge.prototype.init.call(this),this.push=function(e){var t,i,n,r,a,s,o=0;if(u||(c=0),"audio"===e.type)for(l?(r=l,(l=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),l.set(e.data,r.byteLength)):l=e.data;o+5<l.length;)if(255===l[o]&&240==(246&l[o+1])){if(i=2*(1&~l[o+1]),t=(3&l[o+3])<<11|l[o+4]<<3|(224&l[o+5])>>5,s=(a=1024*(1+(3&l[o+6])))*Ke/Ye[(60&l[o+2])>>>2],n=o+t,l.byteLength<n)return;if(this.trigger("data",{pts:e.pts+c*s,dts:e.dts+c*s,sampleCount:a,audioobjecttype:1+(l[o+2]>>>6&3),channelcount:(1&l[o+2])<<2|(192&l[o+3])>>>6,samplerate:Ye[(60&l[o+2])>>>2],samplingfrequencyindex:(60&l[o+2])>>>2,samplesize:16,data:l.subarray(o+7+i,n)}),c++,l.byteLength===n)return void(l=void 0);l=l.subarray(n)}else o++},this.flush=function(){c=0,this.trigger("done")},this.reset=function(){l=void 0,this.trigger("reset")},this.endTimeline=function(){l=void 0,this.trigger("endedtimeline")}}).prototype=new H;var Qe,Je,Ze,et=Ge,tt=function(n){var r=n.byteLength,a=0,s=0;this.length=function(){return 8*r},this.bitsAvailable=function(){return 8*r+s},this.loadWord=function(){var e=n.byteLength-r,t=new Uint8Array(4),i=Math.min(4,r);if(0===i)throw new Error("no bytes available");t.set(n.subarray(e,e+i)),a=new DataView(t.buffer).getUint32(0),s=8*i,r-=i},this.skipBits=function(e){var t;e<s||(e-=s,e-=8*(t=Math.floor(e/8)),r-=t,this.loadWord()),a<<=e,s-=e},this.readBits=function(e){var t=Math.min(s,e),i=a>>>32-t;return 0<(s-=t)?a<<=t:0<r&&this.loadWord(),0<(t=e-t)?i<<t|this.readBits(t):i},this.skipLeadingZeros=function(){var e;for(e=0;e<s;++e)if(0!=(a&2147483648>>>e))return a<<=e,s-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()};(Je=function(){var n,r,a=0;Je.prototype.init.call(this),this.push=function(e){for(var t,i=(r=r?((t=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),t.set(e.data,r.byteLength),t):e.data).byteLength;a<i-3;a++)if(1===r[a+2]){n=a+5;break}for(;n<i;)switch(r[n]){case 0:if(0!==r[n-1]){n+=2;break}if(0!==r[n-2]){n++;break}for(a+3!==n-2&&this.trigger("data",r.subarray(a+3,n-2));1!==r[++n]&&n<i;);a=n-2,n+=3;break;case 1:if(0!==r[n-1]||0!==r[n-2]){n+=3;break}this.trigger("data",r.subarray(a+3,n-2)),a=n-2,n+=3;break;default:n+=3}r=r.subarray(a),n-=a,a=0},this.reset=function(){r=null,a=0,this.trigger("reset")},this.flush=function(){r&&3<r.byteLength&&this.trigger("data",r.subarray(a+3)),r=null,a=0,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")}}).prototype=new H,Ze={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(Qe=function(){var i,n,r,a,s,o,_,t=new Je;Qe.prototype.init.call(this),(i=this).push=function(e){"video"===e.type&&(n=e.trackId,r=e.pts,a=e.dts,t.push(e))},t.on("data",function(e){var t={trackId:n,pts:r,dts:a,data:e};switch(31&e[0]){case 5:t.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:t.nalUnitType="sei_rbsp",t.escapedRBSP=s(e.subarray(1));break;case 7:t.nalUnitType="seq_parameter_set_rbsp",t.escapedRBSP=s(e.subarray(1)),t.config=o(t.escapedRBSP);break;case 8:t.nalUnitType="pic_parameter_set_rbsp";break;case 9:t.nalUnitType="access_unit_delimiter_rbsp"}i.trigger("data",t)}),t.on("done",function(){i.trigger("done")}),t.on("partialdone",function(){i.trigger("partialdone")}),t.on("reset",function(){i.trigger("reset")}),t.on("endedtimeline",function(){i.trigger("endedtimeline")}),this.flush=function(){t.flush()},this.partialFlush=function(){t.partialFlush()},this.reset=function(){t.reset()},this.endTimeline=function(){t.endTimeline()},_=function(e,t){var i,n=8,r=8;for(i=0;i<e;i++)0!==r&&(r=(n+t.readExpGolomb()+256)%256),n=0===r?n:r},s=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a<n-2;)0===e[a]&&0===e[a+1]&&3===e[a+2]?(r.push(a+2),a+=2):a++;if(0===r.length)return e;t=n-r.length,i=new Uint8Array(t);var s=0;for(a=0;a<t;s++,a++)s===r[0]&&(s++,r.shift()),i[a]=e[s];return i},o=function(e){var t,i,n,r,a,s,o,u,l,c,h,d,p,f=0,m=0,g=0,y=0,v=1;if(i=(t=new tt(e)).readUnsignedByte(),r=t.readUnsignedByte(),n=t.readUnsignedByte(),t.skipUnsignedExpGolomb(),Ze[i]&&(3===(a=t.readUnsignedExpGolomb())&&t.skipBits(1),t.skipUnsignedExpGolomb(),t.skipUnsignedExpGolomb(),t.skipBits(1),t.readBoolean()))for(h=3!==a?8:12,p=0;p<h;p++)t.readBoolean()&&_(p<6?16:64,t);if(t.skipUnsignedExpGolomb(),0===(s=t.readUnsignedExpGolomb()))t.readUnsignedExpGolomb();else if(1===s)for(t.skipBits(1),t.skipExpGolomb(),t.skipExpGolomb(),o=t.readUnsignedExpGolomb(),p=0;p<o;p++)t.skipExpGolomb();if(t.skipUnsignedExpGolomb(),t.skipBits(1),u=t.readUnsignedExpGolomb(),l=t.readUnsignedExpGolomb(),0===(c=t.readBits(1))&&t.skipBits(1),t.skipBits(1),t.readBoolean()&&(f=t.readUnsignedExpGolomb(),m=t.readUnsignedExpGolomb(),g=t.readUnsignedExpGolomb(),y=t.readUnsignedExpGolomb()),t.readBoolean()&&t.readBoolean()){switch(t.readUnsignedByte()){case 1:d=[1,1];break;case 2:d=[12,11];break;case 3:d=[10,11];break;case 4:d=[16,11];break;case 5:d=[40,33];break;case 6:d=[24,11];break;case 7:d=[20,11];break;case 8:d=[32,11];break;case 9:d=[80,33];break;case 10:d=[18,11];break;case 11:d=[15,11];break;case 12:d=[64,33];break;case 13:d=[160,99];break;case 14:d=[4,3];break;case 15:d=[3,2];break;case 16:d=[2,1];break;case 255:d=[t.readUnsignedByte()<<8|t.readUnsignedByte(),t.readUnsignedByte()<<8|t.readUnsignedByte()]}d&&(v=d[0]/d[1])}return{profileIdc:i,levelIdc:n,profileCompatibility:r,width:Math.ceil((16*(u+1)-2*f-2*m)*v),height:(2-c)*(l+1)*16-2*g-2*y,sarRatio:d}}}).prototype=new H;var it,nt={H264Stream:Qe,NalByteStream:Je},rt=function(e){return e[0]==="I".charCodeAt(0)&&e[1]==="D".charCodeAt(0)&&e[2]==="3".charCodeAt(0)},at=function(e,t){var i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&e[t+5])>>4?20+i:10+i},st=function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i};(it=function(){var o=new Uint8Array,u=0;it.prototype.init.call(this),this.setTimestamp=function(e){u=e},this.push=function(e){var t,i,n,r,a=0,s=0;for(o.length?(r=o.length,(o=new Uint8Array(e.byteLength+r)).set(o.subarray(0,r)),o.set(e,r)):o=e;3<=o.length-s;)if(o[s]!=="I".charCodeAt(0)||o[s+1]!=="D".charCodeAt(0)||o[s+2]!=="3".charCodeAt(0))if(255!=(255&o[s])||240!=(240&o[s+1]))s++;else{if(o.length-s<7)break;if(s+(a=st(o,s))>o.length)break;n={type:"audio",data:o.subarray(s,s+a),pts:u,dts:u},this.trigger("data",n),s+=a}else{if(o.length-s<10)break;if(s+(a=at(o,s))>o.length)break;i={type:"timed-metadata",data:o.subarray(s,s+a)},this.trigger("data",i),s+=a}t=o.length-s,o=0<t?o.subarray(s):new Uint8Array},this.reset=function(){o=new Uint8Array,this.trigger("reset")},this.endTimeline=function(){o=new Uint8Array,this.trigger("endedtimeline")}}).prototype=new H;function ot(e,t){var i;if(e.length!==t.length)return!1;for(i=0;i<e.length;i++)if(e[i]!==t[i])return!1;return!0}function ut(e,t,i,n,r,a){return{start:{dts:e,pts:e+(i-t)},end:{dts:e+(n-t),pts:e+(r-i)},prependedContentDuration:a,baseMediaDecodeTime:e}}var lt,ct,ht,dt,pt=it,ft=nt.H264Stream,mt=rt,gt=le,yt=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],vt=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"];(ct=function(a,s){var o=[],u=0,l=0,c=0,h=1/0;s=s||{},ct.prototype.init.call(this),this.push=function(t){be(a,t),a&&yt.forEach(function(e){a[e]=t[e]}),o.push(t)},this.setEarliestDts=function(e){l=e-a.timelineStartInfo.baseMediaDecodeTime},this.setVideoBaseMediaDecodeTime=function(e){h=e},this.setAudioAppendStart=function(e){c=e},this.flush=function(){var e,t,i,n,r;0!==o.length&&(e=fe(o,a,l),a.baseMediaDecodeTime=_e(a,s.keepOriginalTimestamps),pe(a,e,c,h),a.samples=me(e),i=Q(ge(e)),o=[],t=J(u,[a]),n=new Uint8Array(t.byteLength+i.byteLength),u++,n.set(t),n.set(i,t.byteLength),ve(a),r=Math.ceil(1024*gt/a.samplerate),e.length&&this.trigger("timingInfo",{start:e[0].dts,end:e[0].dts+e.length*r}),this.trigger("data",{track:a,boxes:n})),this.trigger("done","AudioSegmentStream")},this.reset=function(){ve(a),o=[],this.trigger("reset")}}).prototype=new H,(lt=function(c,h){var t,i,d=0,p=[],f=[];h=h||{},lt.prototype.init.call(this),delete c.minPTS,this.gopCache_=[],this.push=function(e){be(c,e),"seq_parameter_set_rbsp"!==e.nalUnitType||t||(t=e.config,c.sps=[e.data],vt.forEach(function(e){c[e]=t[e]},this)),"pic_parameter_set_rbsp"!==e.nalUnitType||i||(i=e.data,c.pps=[e.data]),p.push(e)},this.flush=function(){for(var e,t,i,n,r,a,s,o,u=0;p.length&&"access_unit_delimiter_rbsp"!==p[0].nalUnitType;)p.shift();if(0===p.length)return this.resetStream_(),void this.trigger("done","VideoSegmentStream");if(e=ee(p),(i=te(e))[0][0].keyFrame||((t=this.getGopForFusion_(p[0],c))?(u=t.duration,i.unshift(t),i.byteLength+=t.byteLength,i.nalCount+=t.nalCount,i.pts=t.pts,i.dts=t.dts,i.duration+=t.duration):i=ie(i)),f.length){var l;if(!(l=h.alignGopsAtEnd?this.alignGopsAtEnd_(i):this.alignGopsAtStart_(i)))return this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");ve(c),i=l}be(c,i),c.samples=ne(i),r=Q(re(i)),c.baseMediaDecodeTime=_e(c,h.keepOriginalTimestamps),this.trigger("processedGopsInfo",i.map(function(e){return{pts:e.pts,dts:e.dts,byteLength:e.byteLength}})),s=i[0],o=i[i.length-1],this.trigger("segmentTimingInfo",ut(c.baseMediaDecodeTime,s.dts,s.pts,o.dts+o.duration,o.pts+o.duration,u)),this.trigger("timingInfo",{start:i[0].dts,end:i[i.length-1].dts+i[i.length-1].duration}),this.gopCache_.unshift({gop:i.pop(),pps:c.pps,sps:c.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),p=[],this.trigger("baseMediaDecodeTime",c.baseMediaDecodeTime),this.trigger("timelineStartInfo",c.timelineStartInfo),n=J(d,[c]),a=new Uint8Array(n.byteLength+r.byteLength),d++,a.set(n),a.set(r,n.byteLength),this.trigger("data",{track:c,boxes:a}),this.resetStream_(),this.trigger("done","VideoSegmentStream")},this.reset=function(){this.resetStream_(),p=[],this.gopCache_.length=0,f.length=0,this.trigger("reset")},this.resetStream_=function(){ve(c),i=t=void 0},this.getGopForFusion_=function(e){var t,i,n,r,a,s=1/0;for(a=0;a<this.gopCache_.length;a++)n=(r=this.gopCache_[a]).gop,c.pps&&ot(c.pps[0],r.pps[0])&&c.sps&&ot(c.sps[0],r.sps[0])&&(n.dts<c.timelineStartInfo.dts||-1e4<=(t=e.dts-n.dts-n.duration)&&t<=45e3&&(!i||t<s)&&(i=r,s=t));return i?i.gop:null},this.alignGopsAtStart_=function(e){var t,i,n,r,a,s,o,u;for(a=e.byteLength,s=e.nalCount,o=e.duration,t=i=0;t<f.length&&i<e.length&&(n=f[t],r=e[i],n.pts!==r.pts);)r.pts>n.pts?t++:(i++,a-=r.byteLength,s-=r.nalCount,o-=r.duration);return 0===i?e:i===e.length?null:((u=e.slice(i)).byteLength=a,u.duration=o,u.nalCount=s,u.pts=u[0].pts,u.dts=u[0].dts,u)},this.alignGopsAtEnd_=function(e){var t,i,n,r,a,s,o;for(t=f.length-1,i=e.length-1,a=null,s=!1;0<=t&&0<=i;){if(n=f[t],r=e[i],n.pts===r.pts){s=!0;break}n.pts>r.pts?t--:(t===f.length-1&&(a=i),i--)}if(!s&&null===a)return null;if(0===(o=s?i:a))return e;var u=e.slice(o),l=u.reduce(function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e},{byteLength:0,duration:0,nalCount:0});return u.byteLength=l.byteLength,u.duration=l.duration,u.nalCount=l.nalCount,u.pts=u[0].pts,u.dts=u[0].dts,u},this.alignGopsWith=function(e){f=e}}).prototype=new H,(dt=function(e,t){this.numberOfTracks=0,this.metadataStream=t,"undefined"!=typeof(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps?this.keepOriginalTimestamps=e.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,dt.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track,this.pendingBoxes.push(e.boxes)),void("audio"===e.track.type&&(this.audioTrack=e.track,this.pendingBoxes.unshift(e.boxes))))}}).prototype=new H,dt.prototype.flush=function(e){var t,i,n,r,a=0,s={captions:[],captionStreams:{},metadata:[],info:{}},o=0;if(this.pendingTracks.length<this.numberOfTracks){if("VideoSegmentStream"!==e&&"AudioSegmentStream"!==e)return;if(this.remuxTracks)return;if(0===this.pendingTracks.length)return this.emittedTracks++,void(this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(o=this.videoTrack.timelineStartInfo.pts,vt.forEach(function(e){s.info[e]=this.videoTrack[e]},this)):this.audioTrack&&(o=this.audioTrack.timelineStartInfo.pts,yt.forEach(function(e){s.info[e]=this.audioTrack[e]},this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?s.type=this.pendingTracks[0].type:s.type="combined",this.emittedTracks+=this.pendingTracks.length,n=Z(this.pendingTracks),s.initSegment=new Uint8Array(n.byteLength),s.initSegment.set(n),s.data=new Uint8Array(this.pendingBytes),r=0;r<this.pendingBoxes.length;r++)s.data.set(this.pendingBoxes[r],a),a+=this.pendingBoxes[r].byteLength;for(r=0;r<this.pendingCaptions.length;r++)(t=this.pendingCaptions[r]).startTime=de(t.startPts,o,this.keepOriginalTimestamps),t.endTime=de(t.endPts,o,this.keepOriginalTimestamps),s.captionStreams[t.stream]=!0,s.captions.push(t);for(r=0;r<this.pendingMetadata.length;r++)(i=this.pendingMetadata[r]).cueTime=de(i.pts,o,this.keepOriginalTimestamps),s.metadata.push(i);for(s.metadata.dispatchType=this.metadataStream.dispatchType,this.pendingTracks.length=0,this.videoTrack=null,this.pendingBoxes.length=0,this.pendingCaptions.length=0,this.pendingBytes=0,this.pendingMetadata.length=0,this.trigger("data",s),r=0;r<s.captions.length;r++)t=s.captions[r],this.trigger("caption",t);for(r=0;r<s.metadata.length;r++)i=s.metadata[r],this.trigger("id3Frame",i)}this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},dt.prototype.setRemux=function(e){this.remuxTracks=e},(ht=function(n){var r,a,s=this,i=!0;ht.prototype.init.call(this),n=n||{},this.baseMediaDecodeTime=n.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var t={};(this.transmuxPipeline_=t).type="aac",t.metadataStream=new Xe.MetadataStream,t.aacStream=new pt,t.audioTimestampRolloverStream=new Xe.TimestampRolloverStream("audio"),t.timedMetadataTimestampRolloverStream=new Xe.TimestampRolloverStream("timed-metadata"),t.adtsStream=new et,t.coalesceStream=new dt(n,t.metadataStream),t.headOfPipeline=t.aacStream,t.aacStream.pipe(t.audioTimestampRolloverStream).pipe(t.adtsStream),t.aacStream.pipe(t.timedMetadataTimestampRolloverStream).pipe(t.metadataStream).pipe(t.coalesceStream),t.metadataStream.on("timestamp",function(e){t.aacStream.setTimestamp(e.timeStamp)}),t.aacStream.on("data",function(e){"timed-metadata"!==e.type||t.audioSegmentStream||(a=a||{timelineStartInfo:{baseMediaDecodeTime:s.baseMediaDecodeTime},codec:"adts",type:"audio"},t.coalesceStream.numberOfTracks++,t.audioSegmentStream=new ct(a,n),t.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),t.adtsStream.pipe(t.audioSegmentStream).pipe(t.coalesceStream)),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r})}),t.coalesceStream.on("data",this.trigger.bind(this,"data")),t.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setupTsPipeline=function(){var i={};(this.transmuxPipeline_=i).type="ts",i.metadataStream=new Xe.MetadataStream,i.packetStream=new Xe.TransportPacketStream,i.parseStream=new Xe.TransportParseStream,i.elementaryStream=new Xe.ElementaryStream,i.timestampRolloverStream=new Xe.TimestampRolloverStream,i.adtsStream=new et,i.h264Stream=new ft,i.captionStream=new Xe.CaptionStream,i.coalesceStream=new dt(n,i.metadataStream),i.headOfPipeline=i.packetStream,i.packetStream.pipe(i.parseStream).pipe(i.elementaryStream).pipe(i.timestampRolloverStream),i.timestampRolloverStream.pipe(i.h264Stream),i.timestampRolloverStream.pipe(i.adtsStream),i.timestampRolloverStream.pipe(i.metadataStream).pipe(i.coalesceStream),i.h264Stream.pipe(i.captionStream).pipe(i.coalesceStream),i.elementaryStream.on("data",function(e){var t;if("metadata"===e.type){for(t=e.tracks.length;t--;)r||"video"!==e.tracks[t].type?a||"audio"!==e.tracks[t].type||((a=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime):(r=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime;r&&!i.videoSegmentStream&&(i.coalesceStream.numberOfTracks++,i.videoSegmentStream=new lt(r,n),i.videoSegmentStream.on("timelineStartInfo",function(e){a&&(a.timelineStartInfo=e,i.audioSegmentStream.setEarliestDts(e.dts))}),i.videoSegmentStream.on("processedGopsInfo",s.trigger.bind(s,"gopInfo")),i.videoSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"videoSegmentTimingInfo")),i.videoSegmentStream.on("baseMediaDecodeTime",function(e){a&&i.audioSegmentStream.setVideoBaseMediaDecodeTime(e)}),i.videoSegmentStream.on("timingInfo",s.trigger.bind(s,"videoTimingInfo")),i.h264Stream.pipe(i.videoSegmentStream).pipe(i.coalesceStream)),a&&!i.audioSegmentStream&&(i.coalesceStream.numberOfTracks++,i.audioSegmentStream=new ct(a,n),i.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),i.adtsStream.pipe(i.audioSegmentStream).pipe(i.coalesceStream)),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r})}}),i.coalesceStream.on("data",this.trigger.bind(this,"data")),i.coalesceStream.on("id3Frame",function(e){e.dispatchType=i.metadataStream.dispatchType,s.trigger("id3Frame",e)}),i.coalesceStream.on("caption",this.trigger.bind(this,"caption")),i.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setBaseMediaDecodeTime=function(e){var t=this.transmuxPipeline_;n.keepOriginalTimestamps||(this.baseMediaDecodeTime=e),a&&(a.timelineStartInfo.dts=void 0,a.timelineStartInfo.pts=void 0,ve(a),n.keepOriginalTimestamps||(a.timelineStartInfo.baseMediaDecodeTime=e),t.audioTimestampRolloverStream&&t.audioTimestampRolloverStream.discontinuity()),r&&(t.videoSegmentStream&&(t.videoSegmentStream.gopCache_=[]),r.timelineStartInfo.dts=void 0,r.timelineStartInfo.pts=void 0,ve(r),t.captionStream.reset(),n.keepOriginalTimestamps||(r.timelineStartInfo.baseMediaDecodeTime=e)),t.timestampRolloverStream&&t.timestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(e){a&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e)},this.setRemux=function(e){var t=this.transmuxPipeline_;n.remux=e,t&&t.coalesceStream&&t.coalesceStream.setRemux(e)},this.alignGopsWith=function(e){r&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e)},this.push=function(e){if(i){var t=mt(e);t&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),i=!1}this.transmuxPipeline_.headOfPipeline.push(e)},this.flush=function(){i=!0,this.transmuxPipeline_.headOfPipeline.flush()},this.endTimeline=function(){this.transmuxPipeline_.headOfPipeline.endTimeline()},this.reset=function(){this.transmuxPipeline_.headOfPipeline&&this.transmuxPipeline_.headOfPipeline.reset()},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset()}}).prototype=new H;var _t={Transmuxer:ht,VideoSegmentStream:lt,AudioSegmentStream:ct,AUDIO_PROPERTIES:yt,VIDEO_PROPERTIES:vt,generateVideoSegmentTimingInfo:ut};function bt(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}var Tt=(function(e,t,i){return t&&bt(e.prototype,t),i&&bt(e,i),e}(St,[{key:"init",value:function(){this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new _t.Transmuxer(this.options),function(n,e){e.on("data",function(e){var t=e.initSegment;e.initSegment={data:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength};var i=e.data;e.data=i.buffer,n.postMessage({action:"data",segment:e,byteOffset:i.byteOffset,byteLength:i.byteLength},[e.data])}),e.captionStream&&e.captionStream.on("data",function(e){n.postMessage({action:"caption",data:e})}),e.on("done",function(e){n.postMessage({action:"done"})}),e.on("gopInfo",function(e){n.postMessage({action:"gopInfo",gopInfo:e})}),e.on("videoSegmentTimingInfo",function(e){n.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:e})})}(this.self,this.transmuxer)}},{key:"push",value:function(e){var t=new Uint8Array(e.data,e.byteOffset,e.byteLength);this.transmuxer.push(t)}},{key:"reset",value:function(){this.init()}},{key:"setTimestampOffset",value:function(e){var t=e.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(9e4*t))}},{key:"setAudioAppendStart",value:function(e){this.transmuxer.setAudioAppendStart(Math.ceil(9e4*e.appendStart))}},{key:"flush",value:function(e){this.transmuxer.flush()}},{key:"resetCaptions",value:function(){this.transmuxer.resetCaptions()}},{key:"alignGopsWith",value:function(e){this.transmuxer.alignGopsWith(e.gopsToAlignWith.slice())}}]),St);function St(e,t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,St),this.options=t||{},this.self=e,this.init()}new function(t){t.onmessage=function(e){"init"===e.data.action&&e.data.options?this.messageHandlers=new Tt(t,e.data.options):(this.messageHandlers||(this.messageHandlers=new Tt(t)),e.data&&e.data.action&&"init"!==e.data.action&&this.messageHandlers[e.data.action]&&this.messageHandlers[e.data.action](e.data))}}(kt)}()}),Jl={videoCodec:"avc1",videoObjectTypeIndicator:".4d400d",audioProfile:"2"},Zl=(ju(ec,fs.EventTarget),Nu(ec,[{key:"data_",value:function(e){var t=e.data.segment;t.data=new Uint8Array(t.data,e.data.byteOffset,e.data.byteLength),t.initSegment=new Uint8Array(t.initSegment.data,t.initSegment.byteOffset,t.initSegment.byteLength),function(e,t,i){var n=t.player_;if(i.captions&&i.captions.length)for(var r in e.inbandTextTracks_||(e.inbandTextTracks_={}),i.captionStreams)if(!e.inbandTextTracks_[r]){n.tech_.trigger({type:"usage",name:"hls-608"});var a=n.textTracks().getTrackById(r);e.inbandTextTracks_[r]=a||n.addRemoteTextTrack({kind:"captions",id:r,label:r},!1).track}i.metadata&&i.metadata.length&&!e.metadataTrack_&&(e.metadataTrack_=n.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,e.metadataTrack_.inBandMetadataTrackDispatchType=i.metadata.dispatchType)}(this,this.mediaSource_,t),this.pendingBuffers_.push(t)}},{key:"done_",value:function(e){"closed"!==this.mediaSource_.readyState?this.processPendingSegments_():this.pendingBuffers_.length=0}},{key:"videoSegmentTimingInfo_",value:function(e){var t={start:{decode:e.start.dts/9e4,presentation:e.start.pts/9e4},end:{decode:e.end.dts/9e4,presentation:e.end.pts/9e4},baseMediaDecodeTime:e.baseMediaDecodeTime/9e4};e.prependedContentDuration&&(t.prependedContentDuration=e.prependedContentDuration/9e4),this.trigger({type:"videoSegmentTimingInfo",videoSegmentTimingInfo:t})}},{key:"createRealSourceBuffers_",value:function(){var n=this,r=["audio","video"];r.forEach(function(t){if(n[t+"Codec_"]&&!n[t+"Buffer_"]){var i=null;if(n.mediaSource_[t+"Buffer_"])(i=n.mediaSource_[t+"Buffer_"]).updating=!1;else{var e=t+'/mp4;codecs="'+n[t+"Codec_"]+'"';i=function(e,t){var i=e.addSourceBuffer(t),n=Object.create(null);function r(t){"function"==typeof i[t]?n[t]=function(){return i[t].apply(i,arguments)}:"undefined"==typeof n[t]&&Object.defineProperty(n,t,{get:function(){return i[t]},set:function(e){return i[t]=e}})}for(var a in n.updating=!1,n.realBuffer_=i)r(a);return n}(n.mediaSource_.nativeMediaSource_,e),n.mediaSource_[t+"Buffer_"]=i}n[t+"Buffer_"]=i,["update","updatestart","updateend"].forEach(function(e){i.addEventListener(e,function(){if("audio"!==t||!n.audioDisabled_)return"updateend"===e&&(n[t+"Buffer_"].updating=!1),r.every(function(e){return!("audio"!==e||!n.audioDisabled_)||t===e||!n[e+"Buffer_"]||!n[e+"Buffer_"].updating})?n.trigger(e):void 0})})}})}},{key:"appendBuffer",value:function(e){if(this.bufferUpdating_=!0,this.audioBuffer_&&this.audioBuffer_.buffered.length){var t=this.audioBuffer_.buffered;this.transmuxer_.postMessage({action:"setAudioAppendStart",appendStart:t.end(t.length-1)})}this.videoBuffer_&&this.transmuxer_.postMessage({action:"alignGopsWith",gopsToAlignWith:function(e,t,i){if("undefined"==typeof t||null===t||!e.length)return[];var n=Math.ceil(9e4*(t-i+3)),r=void 0;for(r=0;r<e.length&&!(e[r].pts>n);r++);return e.slice(r)}(this.gopBuffer_,this.mediaSource_.player_?this.mediaSource_.player_.currentTime():null,this.timeMapping_)}),this.transmuxer_.postMessage({action:"push",data:e.buffer,byteOffset:e.byteOffset,byteLength:e.byteLength},[e.buffer]),this.transmuxer_.postMessage({action:"flush"})}},{key:"appendGopInfo_",value:function(e){this.gopBuffer_=function(e,t,i){if(!t.length)return e;if(i)return t.slice();for(var n=t[0].pts,r=0;r<e.length&&!(e[r].pts>=n);r++);return e.slice(0,r).concat(t)}(this.gopBuffer_,e.data.gopInfo,this.safeAppend_)}},{key:"remove",value:function(e,t){if(this.videoBuffer_&&(this.videoBuffer_.updating=!0,this.videoBuffer_.remove(e,t),this.gopBuffer_=function(e,t,i,n){for(var r=Math.ceil(9e4*(t-n)),a=Math.ceil(9e4*(i-n)),s=e.slice(),o=e.length;o--&&!(e[o].pts<=a););if(-1===o)return s;for(var u=o+1;u--&&!(e[u].pts<=r););return u=Math.max(u,0),s.splice(u,o-u+1),s}(this.gopBuffer_,e,t,this.timeMapping_)),!this.audioDisabled_&&this.audioBuffer_&&(this.audioBuffer_.updating=!0,this.audioBuffer_.remove(e,t)),Cl(e,t,this.metadataTrack_),this.inbandTextTracks_)for(var i in this.inbandTextTracks_)Cl(e,t,this.inbandTextTracks_[i])}},{key:"processPendingSegments_",value:function(){var e={video:{segments:[],bytes:0},audio:{segments:[],bytes:0},captions:[],metadata:[]};if(!this.pendingBuffers_.length)return this.trigger("updateend"),void(this.bufferUpdating_=!1);e=this.pendingBuffers_.reduce(function(e,t){var i=t.type,n=t.data,r=t.initSegment;return e[i].segments.push(n),e[i].bytes+=n.byteLength,e[i].initSegment=r,t.captions&&(e.captions=e.captions.concat(t.captions)),t.info&&(e[i].info=t.info),t.metadata&&(e.metadata=e.metadata.concat(t.metadata)),e},e),this.videoBuffer_||this.audioBuffer_||(0===e.video.bytes&&(this.videoCodec_=null),0===e.audio.bytes&&(this.audioCodec_=null),this.createRealSourceBuffers_()),e.audio.info&&this.mediaSource_.trigger({type:"audioinfo",info:e.audio.info}),e.video.info&&this.mediaSource_.trigger({type:"videoinfo",info:e.video.info}),this.appendAudioInitSegment_&&(!this.audioDisabled_&&this.audioBuffer_&&(e.audio.segments.unshift(e.audio.initSegment),e.audio.bytes+=e.audio.initSegment.byteLength),this.appendAudioInitSegment_=!1);var t=!1;this.videoBuffer_&&e.video.bytes?(e.video.segments.unshift(e.video.initSegment),e.video.bytes+=e.video.initSegment.byteLength,this.concatAndAppendSegments_(e.video,this.videoBuffer_)):!this.videoBuffer_||!this.audioDisabled_&&this.audioBuffer_||(t=!0),wl(this,e.captions,e.metadata),!this.audioDisabled_&&this.audioBuffer_&&this.concatAndAppendSegments_(e.audio,this.audioBuffer_),this.pendingBuffers_.length=0,t&&this.trigger("updateend"),this.bufferUpdating_=!1}},{key:"concatAndAppendSegments_",value:function(e,t){var i=0,n=void 0;if(e.bytes){n=new Uint8Array(e.bytes),e.segments.forEach(function(e){n.set(e,i),i+=e.byteLength});try{t.updating=!0,t.appendBuffer(n)}catch(e){this.mediaSource_.player_&&this.mediaSource_.player_.error({code:-3,type:"APPEND_BUFFER_ERR",message:e.message,originalError:e})}}}},{key:"abort",value:function(){this.videoBuffer_&&this.videoBuffer_.abort(),!this.audioDisabled_&&this.audioBuffer_&&this.audioBuffer_.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"reset"}),this.pendingBuffers_.length=0,this.bufferUpdating_=!1}}]),ec);function ec(e,t){Mu(this,ec);var i=Fu(this,(ec.__proto__||Object.getPrototypeOf(ec)).call(this,fs.EventTarget));i.timestampOffset_=0,i.pendingBuffers_=[],i.bufferUpdating_=!1,i.mediaSource_=e,i.codecs_=t,i.audioCodec_=null,i.videoCodec_=null,i.audioDisabled_=!1,i.appendAudioInitSegment_=!0,i.gopBuffer_=[],i.timeMapping_=0,i.safeAppend_=11<=fs.browser.IE_VERSION;var n={remux:!1,alignGopsAtEnd:i.safeAppend_};return i.codecs_.forEach(function(e){Kl(e)?i.audioCodec_=e:Yl(e)&&(i.videoCodec_=e)}),i.transmuxer_=new Ql,i.transmuxer_.postMessage({action:"init",options:n}),i.transmuxer_.onmessage=function(e){return"data"===e.data.action?i.data_(e):"done"===e.data.action?i.done_(e):"gopInfo"===e.data.action?i.appendGopInfo_(e):"videoSegmentTimingInfo"===e.data.action?i.videoSegmentTimingInfo_(e.data.videoSegmentTimingInfo):void 0},Object.defineProperty(i,"timestampOffset",{get:function(){return this.timestampOffset_},set:function(e){"number"==typeof e&&0<=e&&(this.timestampOffset_=e,this.appendAudioInitSegment_=!0,this.gopBuffer_.length=0,this.timeMapping_=0,this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:e}))}}),Object.defineProperty(i,"appendWindowStart",{get:function(){return(this.videoBuffer_||this.audioBuffer_).appendWindowStart},set:function(e){this.videoBuffer_&&(this.videoBuffer_.appendWindowStart=e),this.audioBuffer_&&(this.audioBuffer_.appendWindowStart=e)}}),Object.defineProperty(i,"updating",{get:function(){return!!(this.bufferUpdating_||!this.audioDisabled_&&this.audioBuffer_&&this.audioBuffer_.updating||this.videoBuffer_&&this.videoBuffer_.updating)}}),Object.defineProperty(i,"buffered",{get:function(){return function(e,t,i){var n=null,r=null,a=0,s=[],o=[];if(!e&&!t)return fs.createTimeRange();if(!e)return t.buffered;if(!t)return e.buffered;if(i)return e.buffered;if(0===e.buffered.length&&0===t.buffered.length)return fs.createTimeRange();for(var u=e.buffered,l=t.buffered,c=u.length;c--;)s.push({time:u.start(c),type:"start"}),s.push({time:u.end(c),type:"end"});for(c=l.length;c--;)s.push({time:l.start(c),type:"start"}),s.push({time:l.end(c),type:"end"});for(s.sort(function(e,t){return e.time-t.time}),c=0;c<s.length;c++)"start"===s[c].type?2===++a&&(n=s[c].time):"end"===s[c].type&&1===--a&&(r=s[c].time),null!==n&&null!==r&&(o.push([n,r]),r=n=null);return fs.createTimeRanges(o)}(this.videoBuffer_,this.audioBuffer_,this.audioDisabled_)}}),i}var tc=(ju(ic,fs.EventTarget),Nu(ic,[{key:"addSeekableRange_",value:function(e,t){var i=void 0;if(this.duration!==1/0)throw(i=new Error("MediaSource.addSeekableRange() can only be invoked when the duration is Infinity")).name="InvalidStateError",i.code=11,i;(t>this.nativeMediaSource_.duration||isNaN(this.nativeMediaSource_.duration))&&(this.nativeMediaSource_.duration=t)}},{key:"addSourceBuffer",value:function(e){var t=void 0,i=function(e){var r={type:"",parameters:{}},t=e.trim().split(";");return r.type=t.shift().trim(),t.forEach(function(e){var t=e.trim().split("=");if(1<t.length){var i=t[0].replace(/"/g,"").trim(),n=t[1].replace(/"/g,"").trim();r.parameters[i]=n}}),r}(e);if(/^(video|audio)\/mp2t$/i.test(i.type)){var n=[];i.parameters&&i.parameters.codecs&&(n=i.parameters.codecs.split(","),n=(n=zl(n)).filter(function(e){return Kl(e)||Yl(e)})),0===n.length&&(n=["avc1.4d400d","mp4a.40.2"]),t=new Zl(this,n),0!==this.sourceBuffers.length&&(this.sourceBuffers[0].createRealSourceBuffers_(),t.createRealSourceBuffers_(),this.sourceBuffers[0].audioDisabled_=!0)}else t=this.nativeMediaSource_.addSourceBuffer(e);return this.sourceBuffers.push(t),t}}]),ic);function ic(){Mu(this,ic);var a=Fu(this,(ic.__proto__||Object.getPrototypeOf(ic)).call(this)),e=void 0;for(e in a.nativeMediaSource_=new v.MediaSource,a.nativeMediaSource_)e in ic.prototype||"function"!=typeof a.nativeMediaSource_[e]||(a[e]=a.nativeMediaSource_[e].bind(a.nativeMediaSource_));return a.duration_=NaN,Object.defineProperty(a,"duration",{get:function(){return this.duration_===1/0?this.duration_:this.nativeMediaSource_.duration},set:function(e){(this.duration_=e)===1/0||(this.nativeMediaSource_.duration=e)}}),Object.defineProperty(a,"seekable",{get:function(){return this.duration_===1/0?fs.createTimeRanges([[0,this.nativeMediaSource_.duration]]):this.nativeMediaSource_.seekable}}),Object.defineProperty(a,"readyState",{get:function(){return this.nativeMediaSource_.readyState}}),Object.defineProperty(a,"activeSourceBuffers",{get:function(){return this.activeSourceBuffers_}}),a.sourceBuffers=[],a.activeSourceBuffers_=[],a.updateActiveSourceBuffers_=function(){if(a.activeSourceBuffers_.length=0,1===a.sourceBuffers.length){var e=a.sourceBuffers[0];return e.appendAudioInitSegment_=!0,e.audioDisabled_=!e.audioCodec_,void a.activeSourceBuffers_.push(e)}for(var i=!1,n=!0,t=0;t<a.player_.audioTracks().length;t++){var r=a.player_.audioTracks()[t];if(r.enabled&&"main"!==r.kind){n=!(i=!0);break}}a.sourceBuffers.forEach(function(e,t){if(e.appendAudioInitSegment_=!0,e.videoCodec_&&e.audioCodec_)e.audioDisabled_=i;else if(e.videoCodec_&&!e.audioCodec_)e.audioDisabled_=!0,n=!1;else if(!e.videoCodec_&&e.audioCodec_&&(e.audioDisabled_=t?n:!n,e.audioDisabled_))return;a.activeSourceBuffers_.push(e)})},a.onPlayerMediachange_=function(){a.sourceBuffers.forEach(function(e){e.appendAudioInitSegment_=!0})},a.onHlsReset_=function(){a.sourceBuffers.forEach(function(e){e.transmuxer_&&e.transmuxer_.postMessage({action:"resetCaptions"})})},a.onHlsSegmentTimeMapping_=function(t){a.sourceBuffers.forEach(function(e){return e.timeMapping_=t.mapping})},["sourceopen","sourceclose","sourceended"].forEach(function(e){this.nativeMediaSource_.addEventListener(e,this.trigger.bind(this))},a),a.on("sourceopen",function(e){var t=h.querySelector('[src="'+a.url_+'"]');t&&(a.player_=fs(t.parentNode),a.player_&&(a.player_.tech_.on("hls-reset",a.onHlsReset_),a.player_.tech_.on("hls-segment-time-mapping",a.onHlsSegmentTimeMapping_),a.player_.audioTracks&&a.player_.audioTracks()&&(a.player_.audioTracks().on("change",a.updateActiveSourceBuffers_),a.player_.audioTracks().on("addtrack",a.updateActiveSourceBuffers_),a.player_.audioTracks().on("removetrack",a.updateActiveSourceBuffers_)),a.player_.on("mediachange",a.onPlayerMediachange_)))}),a.on("sourceended",function(e){for(var t=El(a.duration),i=0;i<a.sourceBuffers.length;i++){var n=a.sourceBuffers[i],r=n.metadataTrack_&&n.metadataTrack_.cues;r&&r.length&&(r[r.length-1].endTime=t)}}),a.on("sourceclose",function(e){this.sourceBuffers.forEach(function(e){e.transmuxer_&&e.transmuxer_.terminate()}),this.sourceBuffers.length=0,this.player_&&(this.player_.audioTracks&&this.player_.audioTracks()&&(this.player_.audioTracks().off("change",this.updateActiveSourceBuffers_),this.player_.audioTracks().off("addtrack",this.updateActiveSourceBuffers_),this.player_.audioTracks().off("removetrack",this.updateActiveSourceBuffers_)),this.player_.el_&&this.player_.off("mediachange",this.onPlayerMediachange_),this.player_.tech_&&this.player_.tech_.el_&&(this.player_.tech_.off("hls-reset",this.onHlsReset_),this.player_.tech_.off("hls-segment-time-mapping",this.onHlsSegmentTimeMapping_)))}),a}var nc=0;fs.mediaSources={};function rc(e,t){var i=fs.mediaSources[e];if(!i)throw new Error("Media Source not found (Video.js)");i.trigger({type:"sourceopen",swfId:t})}function ac(){return!!v.MediaSource&&!!v.MediaSource.isTypeSupported&&v.MediaSource.isTypeSupported('video/mp4;codecs="avc1.4d400d,mp4a.40.2"')}function sc(){if(this.MediaSource={open:rc,supportsNativeMediaSources:ac},ac())return new tc;throw new Error("Cannot use create a virtual MediaSource for this video")}sc.open=rc,sc.supportsNativeMediaSources=ac;var oc={createObjectURL:function(e){var t=void 0;return e instanceof tc?(t=v.URL.createObjectURL(e.nativeMediaSource_),e.url_=t):e instanceof tc?(t="blob:vjs-media-source/"+nc,nc++,fs.mediaSources[t]=e,t):(t=v.URL.createObjectURL(e),e.url_=t)}};fs.MediaSource=sc,fs.URL=oc;function uc(e,t){for(var s=void 0,o=dc(e,{duration:t.duration,minimumUpdatePeriod:t.minimumUpdatePeriod}),i=0;i<t.playlists.length;i++){var n=Vu(o,t.playlists[i]);n?o=n:s=!0}return Hu(t,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r=e.playlists[0].uri,a=Vu(o,e.playlists[0]);a&&((o=a).mediaGroups[t][i][n].playlists[0]=o.playlists[r],s=!1)}}),s?null:o}function lc(e){var t=e.byterange.offset+e.byterange.length-1;return e.uri+"-"+e.byterange.offset+"-"+t}function cc(e,t){var i,n,r={};for(var a in e){var s=e[a].sidx;if(s){var o=lc(s);if(!t[o])break;var u=t[o].sidxInfo;i=u,n=s,(Boolean(!i.map&&!n.map)||Boolean(i.map&&n.map&&i.map.byterange.offset===n.map.byterange.offset&&i.map.byterange.length===n.map.byterange.length))&&i.uri===n.uri&&i.byterange.offset===n.byterange.offset&&i.byterange.length===n.byterange.length&&(r[o]=t[o])}}return r}function hc(e,t,i,n,r){var a={uri:Ru(n.handleManifestRedirects,e.resolvedUri),byterange:e.byterange,playlist:t};return i(fs.mergeOptions(a,{responseType:"arraybuffer",headers:cl(a)}),r)}var dc=fs.mergeOptions,pc=(ju(fc,fs.EventTarget),Nu(fc,[{key:"setupChildLoader",value:function(e,t){this.masterPlaylistLoader_=e,this.childPlaylist_=t}},{key:"dispose",value:function(){this.stopRequest(),this.loadedPlaylists_={},v.clearTimeout(this.minimumUpdatePeriodTimeout_),v.clearTimeout(this.mediaRequest_),v.clearTimeout(this.mediaUpdateTimeout)}},{key:"hasPendingRequest",value:function(){return this.request||this.mediaRequest_}},{key:"stopRequest",value:function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort()}}},{key:"sidxRequestFinished_",value:function(r,a,s,o){var u=this;return function(e,t){if(u.request){if(u.request=null,e)return u.error={status:t.status,message:"DASH playlist request error at URL: "+r.uri,response:t.response,code:2},s&&(u.state=s),u.trigger("error"),o(a,null);var i=new Uint8Array(t.response),n=Lo.parseSidx(i.subarray(8));return o(a,n)}}}},{key:"media",value:function(i){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var r=this.state;if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}var e=!this.media_||i.uri!==this.media_.uri;if(e&&this.loadedPlaylists_[i.uri]&&this.loadedPlaylists_[i.uri].endList)return this.state="HAVE_METADATA",this.media_=i,void(e&&(this.trigger("mediachanging"),this.trigger("mediachange")));if(e)if(this.media_&&this.trigger("mediachanging"),i.sidx){var t=void 0,a=void 0;a=this.masterPlaylistLoader_?(t=this.masterPlaylistLoader_.master,this.masterPlaylistLoader_.sidxMapping_):(t=this.master,this.sidxMapping_);var s=lc(i.sidx);a[s]={sidxInfo:i.sidx},this.request=hc(i.sidx,i,this.hls_.xhr,{handleManifestRedirects:this.handleManifestRedirects},this.sidxRequestFinished_(i,t,r,function(e,t){if(!e||!t)throw new Error("failed to request sidx");a[s].sidx=t,n.haveMetadata({startingState:r,playlist:e.playlists[i.uri]})}))}else this.mediaRequest_=v.setTimeout(this.haveMetadata.bind(this,{startingState:r,playlist:i}),0)}},{key:"haveMetadata",value:function(e){var t=e.startingState,i=e.playlist;this.state="HAVE_METADATA",this.loadedPlaylists_[i.uri]=i,this.mediaRequest_=null,this.refreshMedia_(i.uri),"HAVE_MASTER"===t?this.trigger("loadedmetadata"):this.trigger("mediachange")}},{key:"pause",value:function(){this.stopRequest(),v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.minimumUpdatePeriodTimeout_),"HAVE_NOTHING"===this.state&&(this.started=!1)}},{key:"load",value:function(e){var t=this;v.clearTimeout(this.mediaUpdateTimeout),v.clearTimeout(this.minimumUpdatePeriodTimeout_);var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=v.setTimeout(function(){return t.load()},n)}else this.started?this.trigger("loadedplaylist"):this.start()}},{key:"parseMasterXml",value:function(){var a=co(this.masterXml_,{manifestUri:this.srcUrl,clientOffset:this.clientOffset_,sidxMapping:this.sidxMapping_});a.uri=this.srcUrl;for(var e=0;e<a.playlists.length;e++){var t="placeholder-uri-"+e;a.playlists[e].uri=t,a.playlists[t]=a.playlists[e]}return Hu(a,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r="placeholder-uri-"+t+"-"+i+"-"+n;e.playlists[0].uri=r,a.playlists[r]=e.playlists[0]}}),qu(a),Wu(a),a}},{key:"start",value:function(){var i=this;this.started=!0,this.masterPlaylistLoader_?this.mediaRequest_=v.setTimeout(this.haveMaster_.bind(this),0):this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(i.request){if(i.request=null,e)return i.error={status:t.status,message:"DASH playlist request error at URL: "+i.srcUrl,responseText:t.responseText,code:2},"HAVE_NOTHING"===i.state&&(i.started=!1),i.trigger("error");i.masterXml_=t.responseText,t.responseHeaders&&t.responseHeaders.date?i.masterLoaded_=Date.parse(t.responseHeaders.date):i.masterLoaded_=Date.now(),i.srcUrl=Ru(i.handleManifestRedirects,i.srcUrl,t),i.syncClientServerClock_(i.onClientServerClockSync_.bind(i))}})}},{key:"syncClientServerClock_",value:function(n){var r=this,a=ho(this.masterXml_);return null===a?(this.clientOffset_=this.masterLoaded_-Date.now(),n()):"DIRECT"===a.method?(this.clientOffset_=a.value-Date.now(),n()):void(this.request=this.hls_.xhr({uri:Uu(this.srcUrl,a.value),method:a.method,withCredentials:this.withCredentials},function(e,t){if(r.request){if(e)return r.clientOffset_=r.masterLoaded_-Date.now(),n();var i=void 0;i="HEAD"===a.method?t.responseHeaders&&t.responseHeaders.date?Date.parse(t.responseHeaders.date):r.masterLoaded_:Date.parse(t.responseText),r.clientOffset_=i-Date.now(),n()}}))}},{key:"haveMaster_",value:function(){this.state="HAVE_MASTER",this.mediaRequest_=null,this.masterPlaylistLoader_?this.media_||this.media(this.childPlaylist_):(this.master=this.parseMasterXml(),this.trigger("loadedplaylist"))}},{key:"onClientServerClockSync_",value:function(){var e=this;this.haveMaster_(),this.hasPendingRequest()||this.media_||this.media(this.master.playlists[0]),this.master&&this.master.minimumUpdatePeriod&&(this.minimumUpdatePeriodTimeout_=v.setTimeout(function(){e.trigger("minimumUpdatePeriod")},this.master.minimumUpdatePeriod))}},{key:"refreshXml_",value:function(){var o=this;this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(e,t){if(o.request){if(o.request=null,e)return o.error={status:t.status,message:"DASH playlist request error at URL: "+o.srcUrl,responseText:t.responseText,code:2},"HAVE_NOTHING"===o.state&&(o.started=!1),o.trigger("error");o.masterXml_=t.responseText,o.sidxMapping_=function(e,t,i,a){var n=co(e,{manifestUri:t,clientOffset:i}),s=cc(n.playlists,a);return Hu(n,function(e,t,i,n){if(e.playlists&&e.playlists.length){var r=e.playlists;s=dc(s,cc(r,a))}}),s}(o.masterXml_,o.srcUrl,o.clientOffset_,o.sidxMapping_);var i=o.parseMasterXml(),n=uc(o.master,i),r=o.media().sidx;if(n)if(r){var a=lc(r);if(!o.sidxMapping_[a]){var s=o.media();o.request=hc(s.sidx,s,o.hls_.xhr,{handleManifestRedirects:o.handleManifestRedirects},o.sidxRequestFinished_(s,i,o.state,function(e,t){if(!e||!t)throw new Error("failed to request sidx on minimumUpdatePeriod");o.sidxMapping_[a].sidx=t,o.minimumUpdatePeriodTimeout_=v.setTimeout(function(){o.trigger("minimumUpdatePeriod")},o.master.minimumUpdatePeriod),o.refreshMedia_(o.media().uri)}))}}else o.master=n;o.minimumUpdatePeriodTimeout_=v.setTimeout(function(){o.trigger("minimumUpdatePeriod")},o.master.minimumUpdatePeriod)}})}},{key:"refreshMedia_",value:function(e){var t=this;if(!e)throw new Error("refreshMedia_ must take a media uri");var i=void 0,n=void 0;n=this.masterPlaylistLoader_?(i=this.masterPlaylistLoader_.master,this.masterPlaylistLoader_.parseMasterXml()):(i=this.master,this.parseMasterXml());var r=uc(i,n);r?(this.masterPlaylistLoader_?this.masterPlaylistLoader_.master=r:this.master=r,this.media_=r.playlists[e]):(this.media_=n.playlists[e],this.trigger("playlistunchanged")),this.media().endList||(this.mediaUpdateTimeout=v.setTimeout(function(){t.trigger("mediaupdatetimeout")},zu(this.media(),!!r))),this.trigger("loadedplaylist")}}]),fc);function fc(e,t){var i=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},n=arguments[3];Mu(this,fc);var r=Fu(this,(fc.__proto__||Object.getPrototypeOf(fc)).call(this)),a=i.withCredentials,s=void 0!==a&&a,o=i.handleManifestRedirects,u=void 0!==o&&o;if(r.hls_=t,r.withCredentials=s,r.handleManifestRedirects=u,!e)throw new Error("A non-empty playlist URL or playlist is required");return r.on("minimumUpdatePeriod",function(){r.refreshXml_()}),r.on("mediaupdatetimeout",function(){r.refreshMedia_(r.media().uri)}),r.state="HAVE_NOTHING",r.loadedPlaylists_={},"string"==typeof e?(r.srcUrl=e,r.sidxMapping_={},Fu(r)):(r.setupChildLoader(n,e),r)}function mc(e){return fs.log.debug?fs.log.debug.bind(fs,"VHS:",e+" >"):function(){}}function gc(){}var yc=(Nu(vc,[{key:"createSourceBuffer_",value:function(e,t){var i=this;this.sourceBuffer_=this.mediaSource.addSourceBuffer(e),this.logger_("created SourceBuffer"),t&&(t.trigger("sourcebufferadded"),this.mediaSource.sourceBuffers.length<2)?t.on("sourcebufferadded",function(){i.start_()}):this.start_()}},{key:"start_",value:function(){var t=this;this.started_=!0,this.onUpdateendCallback_=function(){var e=t.pendingCallback_;t.pendingCallback_=null,t.sourceBuffer_.removing=!1,t.logger_("buffered ["+Sl(t.buffered())+"]"),e&&e(),t.runCallback_()},this.sourceBuffer_.addEventListener("updateend",this.onUpdateendCallback_),this.runCallback_()}},{key:"abort",value:function(e){var t=this;this.processedAppend_&&this.queueCallback_(function(){t.sourceBuffer_.abort()},e)}},{key:"appendBuffer",value:function(e,t){var i=this;this.processedAppend_=!0,this.queueCallback_(function(){e.videoSegmentTimingInfoCallback&&i.sourceBuffer_.addEventListener("videoSegmentTimingInfo",e.videoSegmentTimingInfoCallback),i.sourceBuffer_.appendBuffer(e.bytes)},function(){e.videoSegmentTimingInfoCallback&&i.sourceBuffer_.removeEventListener("videoSegmentTimingInfo",e.videoSegmentTimingInfoCallback),t()})}},{key:"buffered",value:function(){return this.sourceBuffer_?this.sourceBuffer_.buffered:fs.createTimeRanges()}},{key:"remove",value:function(e,t,i){var n=this,r=2<arguments.length&&void 0!==i?i:gc;this.processedAppend_&&this.queueCallback_(function(){n.logger_("remove ["+e+" => "+t+"]"),n.sourceBuffer_.removing=!0,n.sourceBuffer_.remove(e,t)},r)}},{key:"updating",value:function(){return!this.sourceBuffer_||this.sourceBuffer_.updating||!!this.pendingCallback_&&this.pendingCallback_!==gc}},{key:"timestampOffset",value:function(e){var t=this;return"undefined"!=typeof e&&(this.queueCallback_(function(){t.sourceBuffer_.timestampOffset=e,t.runCallback_()}),this.timestampOffset_=e),this.timestampOffset_}},{key:"queueCallback_",value:function(e,t){this.callbacks_.push([e.bind(this),t]),this.runCallback_()}},{key:"runCallback_",value:function(){var e=void 0;!this.updating()&&this.callbacks_.length&&this.started_&&(e=this.callbacks_.shift(),this.pendingCallback_=e[1],e[0]())}},{key:"dispose",value:function(){function e(){t.sourceBuffer_&&"open"===t.mediaSource.readyState&&t.sourceBuffer_.abort(),t.sourceBuffer_.removeEventListener("updateend",e)}var t=this;this.sourceBuffer_.removeEventListener("updateend",this.onUpdateendCallback_),this.sourceBuffer_.removing?this.sourceBuffer_.addEventListener("updateend",e):e()}}]),vc);function vc(e,t,i,n){Mu(this,vc),this.callbacks_=[],this.pendingCallback_=null,this.timestampOffset_=0,this.mediaSource=e,this.processedAppend_=!1,this.type_=i,this.mimeType_=t,this.logger_=mc("SourceUpdater["+i+"]["+t+"]"),"closed"===e.readyState?e.addEventListener("sourceopen",this.createSourceBuffer_.bind(this,t,n)):this.createSourceBuffer_(t,n)}function _c(e){e.forEach(function(e){e.abort()})}function bc(e,t){return t.timedout?{status:t.status,message:"HLS request timed-out at URL: "+t.uri,code:Lc,xhr:t}:t.aborted?{status:t.status,message:"HLS request aborted at URL: "+t.uri,code:Oc,xhr:t}:e?{status:t.status,message:"HLS request errored at URL: "+t.uri,code:Ic,xhr:t}:null}function Tc(i,n,r){var a=0,s=!1;return function(e,t){if(!s)return e?(s=!0,_c(i),r(e,t)):(a+=1)===i.length?(t.endOfAllRequests=Date.now(),t.encryptedBytes?function(n,r,a){n.addEventListener("message",function e(t){if(t.data.source===r.requestId){n.removeEventListener("message",e);var i=t.data.decrypted;return r.bytes=new Uint8Array(i.bytes,i.byteOffset,i.byteLength),a(null,r)}});var e=void 0;e=r.key.bytes.slice?r.key.bytes.slice():new Uint32Array(Array.prototype.slice.call(r.key.bytes)),n.postMessage(pl({source:r.requestId,encrypted:r.encryptedBytes,key:e,iv:r.key.iv}),[r.encryptedBytes.buffer,e.buffer])}(n,t,r):r(null,t)):void 0}}function Sc(t,i){return function(e){return t.stats=fs.mergeOptions(t.stats,function(e){var t=e.target,i={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-t.requestTime||0};return i.bytesReceived=e.loaded,i.bandwidth=Math.floor(i.bytesReceived/i.roundTripTime*8*1e3),i}(e)),!t.stats.firstBytesReceivedAt&&t.stats.bytesReceived&&(t.stats.firstBytesReceivedAt=Date.now()),i(e,t)}}function kc(e,t,i,n,r,a,s){var o=[],u=Tc(o,i,s);if(r.key&&!r.key.bytes){var l=e(fs.mergeOptions(t,{uri:r.key.resolvedUri,responseType:"arraybuffer"}),function(a,s){return function(e,t){var i=t.response,n=bc(e,t);if(n)return s(n,a);if(16!==i.byteLength)return s({status:t.status,message:"Invalid HLS key at URL: "+t.uri,code:Ic,xhr:t},a);var r=new DataView(i);return a.key.bytes=new Uint32Array([r.getUint32(0),r.getUint32(4),r.getUint32(8),r.getUint32(12)]),s(null,a)}}(r,u));o.push(l)}if(r.map&&!r.map.bytes){var c=e(fs.mergeOptions(t,{uri:r.map.resolvedUri,responseType:"arraybuffer",headers:cl(r.map)}),function(r,a,s){return function(e,t){var i=t.response,n=bc(e,t);return n?s(n,r):0===i.byteLength?s({status:t.status,message:"Empty HLS segment content at URL: "+t.uri,code:Ic,xhr:t},r):(r.map.bytes=new Uint8Array(t.response),a&&!a.isInitialized()&&a.init(),r.map.timescales=Ao.timescale(r.map.bytes),r.map.videoTrackIds=Ao.videoTrackIds(r.map.bytes),s(null,r))}}(r,n,u));o.push(c)}var h=e(fs.mergeOptions(t,{uri:r.resolvedUri,responseType:"arraybuffer",headers:cl(r)}),function(a,s,o){return function(e,t){var i=t.response,n=bc(e,t),r=void 0;return n?o(n,a):0===i.byteLength?o({status:t.status,message:"Empty HLS segment content at URL: "+t.uri,code:Ic,xhr:t},a):(a.stats=function(e){return{bandwidth:e.bandwidth,bytesReceived:e.bytesReceived||0,roundTripTime:e.roundTripTime||0}}(t),a.key?a.encryptedBytes=new Uint8Array(t.response):a.bytes=new Uint8Array(t.response),s&&a.map&&a.map.bytes&&(s.isInitialized()||s.init(),(r=s.parse(a.bytes,a.map.videoTrackIds,a.map.timescales))&&r.captions&&(a.captionStreams=r.captionStreams,a.fmp4Captions=r.captions)),o(null,a))}}(r,n,u));return h.addEventListener("progress",Sc(r,a)),o.push(h),function(){return _c(o)}}function Cc(e,t){var i;return e&&(i=v.getComputedStyle(e))?i[t]:""}function Ec(e,n){var r=e.slice();e.sort(function(e,t){var i=n(e,t);return 0===i?r.indexOf(e)-r.indexOf(t):i})}function wc(e,t){var i=void 0,n=void 0;return e.attributes.BANDWIDTH&&(i=e.attributes.BANDWIDTH),i=i||v.Number.MAX_VALUE,t.attributes.BANDWIDTH&&(n=t.attributes.BANDWIDTH),i-(n=n||v.Number.MAX_VALUE)}function Ac(e){return"number"==typeof e&&isFinite(e)}var Pc={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,BUFFER_LOW_WATER_LINE_RATE:1},Ic=2,Lc=-101,Oc=-102,xc=(ju(Dc,fs.EventTarget),Nu(Dc,[{key:"resetStats_",value:function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0}},{key:"dispose",value:function(){this.state="DISPOSED",this.pause(),this.abort_(),this.sourceUpdater_&&this.sourceUpdater_.dispose(),this.resetStats_(),this.captionParser_&&this.captionParser_.reset()}},{key:"abort",value:function(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)}},{key:"abort_",value:function(){this.pendingSegment_&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null}},{key:"error",value:function(e){return"undefined"!=typeof e&&(this.error_=e),this.pendingSegment_=null,this.error_}},{key:"endOfStream",value:function(){this.ended_=!0,this.pause(),this.trigger("ended")}},{key:"buffered_",value:function(){return this.sourceUpdater_?this.sourceUpdater_.buffered():fs.createTimeRanges()}},{key:"initSegment",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=fl(e),r=this.initSegments_[n];return i&&!r&&e.bytes&&(this.initSegments_[n]=r={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes,timescales:e.timescales,videoTrackIds:e.videoTrackIds}),r||e}},{key:"segmentKey",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=ml(e),r=this.keyCache_[n];this.cacheEncryptionKeys_&&i&&!r&&e.bytes&&(this.keyCache_[n]=r={resolvedUri:e.resolvedUri,bytes:e.bytes});var a={resolvedUri:(r||e).resolvedUri};return r&&(a.bytes=r.bytes),a}},{key:"couldBeginLoading_",value:function(){return this.playlist_&&(this.sourceUpdater_||this.mimeType_&&"INIT"===this.state)&&!this.paused()}},{key:"load",value:function(){if(this.monitorBuffer_(),this.playlist_){if(this.syncController_.setDateTimeMapping(this.playlist_),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY")}}},{key:"init_",value:function(){return this.state="READY",this.sourceUpdater_=new yc(this.mediaSource_,this.mimeType_,this.loaderType_,this.sourceBufferEmitter_),this.resetEverything(),this.monitorBuffer_()}},{key:"playlist",value:function(e,t){var i=1<arguments.length&&void 0!==t?t:{};if(e){var n=this.playlist_,r=this.pendingSegment_;this.playlist_=e,this.xhrOptions_=i,this.hasPlayed_()||(e.syncInfo={mediaSequence:e.mediaSequence,time:0});var a=null;if(n&&(n.id?a=n.id:n.uri&&(a=n.uri)),this.logger_("playlist update ["+a+" => "+(e.id||e.uri)+"]"),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(n&&n.uri===e.uri){var s=e.mediaSequence-n.mediaSequence;this.logger_("live window shift ["+s+"]"),null!==this.mediaIndex&&(this.mediaIndex-=s),r&&(r.mediaIndex-=s,0<=r.mediaIndex&&(r.segment=e.segments[r.mediaIndex])),this.syncController_.saveExpiredSegmentInfo(n,e)}else null!==this.mediaIndex&&this.resyncLoader()}}},{key:"pause",value:function(){this.checkBufferTimeout_&&(v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)}},{key:"paused",value:function(){return null===this.checkBufferTimeout_}},{key:"mimeType",value:function(e,t){this.mimeType_||(this.mimeType_=e,this.sourceBufferEmitter_=t,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_())}},{key:"resetEverything",value:function(e){this.ended_=!1,this.resetLoader(),this.remove(0,this.duration_(),e),this.captionParser_&&this.captionParser_.clearAllCaptions(),this.trigger("reseteverything")}},{key:"resetLoader",value:function(){this.fetchAtBuffer_=!1,this.resyncLoader()}},{key:"resyncLoader",value:function(){this.mediaIndex=null,this.syncPoint_=null,this.abort()}},{key:"remove",value:function(e,t,i){if(this.sourceUpdater_&&this.sourceUpdater_.remove(e,t,i),Cl(e,t,this.segmentMetadataTrack_),this.inbandTextTracks_)for(var n in this.inbandTextTracks_)Cl(e,t,this.inbandTextTracks_[n])}},{key:"monitorBuffer_",value:function(){this.checkBufferTimeout_&&v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=v.setTimeout(this.monitorBufferTick_.bind(this),1)}},{key:"monitorBufferTick_",value:function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&v.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=v.setTimeout(this.monitorBufferTick_.bind(this),500)}},{key:"fillBuffer_",value:function(){if(!this.sourceUpdater_.updating()){this.syncPoint_||(this.syncPoint_=this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_()));var e=this.checkBuffer_(this.buffered_(),this.playlist_,this.mediaIndex,this.hasPlayed_(),this.currentTime_(),this.syncPoint_);e&&(this.isEndOfStream_(e.mediaIndex)?this.endOfStream():e.mediaIndex===this.playlist_.segments.length-1&&"ended"===this.mediaSource_.readyState&&!this.seeking_()||(e.timeline!==this.currentTimeline_&&(this.syncController_.reset(),e.timestampOffset=e.startOfSegment,this.captionParser_&&this.captionParser_.clearAllCaptions()),this.loadSegment_(e)))}}},{key:"isEndOfStream_",value:function(e,t){return function(e,t,i){if(!e||!t)return!1;var n=i===e.segments.length;return e.endList&&"open"===t.readyState&&n}(1<arguments.length&&void 0!==t?t:this.playlist_,this.mediaSource_,e)&&!this.sourceUpdater_.updating()}},{key:"checkBuffer_",value:function(e,t,i,n,r,a){var s=0,o=void 0;e.length&&(s=e.end(e.length-1));var u=Math.max(0,s-r);if(!t.segments.length)return null;if(u>=this.goalBufferLength_())return null;if(!n&&1<=u)return null;if(null===a)return i=this.getSyncSegmentCandidate_(t),this.generateSegmentInfo_(t,i,null,!0);if(null!==i)return t.segments[i],o=s,this.generateSegmentInfo_(t,i+1,o,!1);if(this.fetchAtBuffer_){var l=Ll.getMediaInfoForTime(t,s,a.segmentIndex,a.time);i=l.mediaIndex,o=l.startTime}else{var c=Ll.getMediaInfoForTime(t,r,a.segmentIndex,a.time);i=c.mediaIndex,o=c.startTime}return this.generateSegmentInfo_(t,i,o,!1)}},{key:"getSyncSegmentCandidate_",value:function(e){var t=this;if(-1===this.currentTimeline_)return 0;var i=e.segments.map(function(e,t){return{timeline:e.timeline,segmentIndex:t}}).filter(function(e){return e.timeline===t.currentTimeline_});return i.length?i[Math.min(i.length-1,1)].segmentIndex:Math.max(e.segments.length-1,0)}},{key:"generateSegmentInfo_",value:function(e,t,i,n){if(t<0||t>=e.segments.length)return null;var r=e.segments[t];return{requestId:"segment-loader-"+Math.random(),uri:r.resolvedUri,mediaIndex:t,isSyncRequest:n,startOfSegment:i,playlist:e,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:r.timeline,duration:r.duration,segment:r}}},{key:"abortRequestEarly_",value:function(e){if(this.hls_.tech_.paused()||!this.xhrOptions_.timeout||!this.playlist_.attributes.BANDWIDTH)return!1;if(Date.now()-(e.firstBytesReceivedAt||Date.now())<1e3)return!1;var t=this.currentTime_(),i=e.bandwidth,n=this.pendingSegment_.duration,r=Ll.estimateSegmentRequestTime(n,i,this.playlist_,e.bytesReceived),a=function(e,t,i){var n=2<arguments.length&&void 0!==i?i:1;return((e.length?e.end(e.length-1):0)-t)/n}(this.buffered_(),t,this.hls_.tech_.playbackRate())-1;if(r<=a)return!1;var s=function(e){var t=e.master,i=e.currentTime,n=e.bandwidth,r=e.duration,a=e.segmentDuration,s=e.timeUntilRebuffer,o=e.currentTimeline,u=e.syncController,l=t.playlists.filter(function(e){return!Ll.isIncompatible(e)}),c=l.filter(Ll.isEnabled);c.length||(c=l.filter(function(e){return!Ll.isDisabled(e)}));var h=c.filter(Ll.hasAttribute.bind(null,"BANDWIDTH")).map(function(e){var t=u.getSyncPoint(e,r,o,i)?1:2;return{playlist:e,rebufferingImpact:Ll.estimateSegmentRequestTime(a,n,e)*t-s}}),d=h.filter(function(e){return e.rebufferingImpact<=0});return Ec(d,function(e,t){return wc(t.playlist,e.playlist)}),d.length?d[0]:(Ec(h,function(e,t){return e.rebufferingImpact-t.rebufferingImpact}),h[0]||null)}({master:this.hls_.playlists.master,currentTime:t,bandwidth:i,duration:this.duration_(),segmentDuration:n,timeUntilRebuffer:a,currentTimeline:this.currentTimeline_,syncController:this.syncController_});if(s){var o=r-a-s.rebufferingImpact,u=.5;return a<=1/30&&(u=1),!(!s.playlist||s.playlist.uri===this.playlist_.uri||o<u)&&(this.bandwidth=s.playlist.attributes.BANDWIDTH*Pc.BANDWIDTH_VARIANCE+1,this.abort(),this.trigger("earlyabort"),!0)}}},{key:"handleProgress_",value:function(e,t){this.pendingSegment_&&t.requestId===this.pendingSegment_.requestId&&!this.abortRequestEarly_(t.stats)&&this.trigger("progress")}},{key:"loadSegment_",value:function(e){this.state="WAITING",this.pendingSegment_=e,this.trimBackBuffer_(e),e.abortRequests=kc(this.hls_.xhr,this.xhrOptions_,this.decrypter_,this.captionParser_,this.createSimplifiedSegmentObj_(e),this.handleProgress_.bind(this),this.segmentRequestFinished_.bind(this))}},{key:"trimBackBuffer_",value:function(e){var t=function(e,t,i){var n=void 0;return n=e.length&&0<e.start(0)&&e.start(0)<t?e.start(0):t-30,Math.min(n,t-i)}(this.seekable_(),this.currentTime_(),this.playlist_.targetDuration||10);0<t&&this.remove(0,t)}},{key:"createSimplifiedSegmentObj_",value:function(e){var t=e.segment,i={resolvedUri:t.resolvedUri,byterange:t.byterange,requestId:e.requestId};if(t.key){var n=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]);i.key=this.segmentKey(t.key),i.key.iv=n}return t.map&&(i.map=this.initSegment(t.map)),i}},{key:"segmentRequestFinished_",value:function(e,t){if(this.mediaRequests+=1,t.stats&&(this.mediaBytesTransferred+=t.stats.bytesReceived,this.mediaTransferDuration+=t.stats.roundTripTime),this.pendingSegment_){if(t.requestId===this.pendingSegment_.requestId){if(e)return this.pendingSegment_=null,this.state="READY",e.code===Oc?void(this.mediaRequestsAborted+=1):(this.pause(),e.code===Lc?(this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,void this.trigger("bandwidthupdate")):(this.mediaRequestsErrored+=1,this.error(e),void this.trigger("error")));this.bandwidth=t.stats.bandwidth,this.roundTrip=t.stats.roundTripTime,t.map&&(t.map=this.initSegment(t.map,!0)),t.key&&this.segmentKey(t.key,!0),this.processSegmentResponse_(t)}}else this.mediaRequestsAborted+=1}},{key:"processSegmentResponse_",value:function(e){var t=this.pendingSegment_;t.bytes=e.bytes,e.map&&(t.segment.map.bytes=e.map.bytes),t.endOfAllRequests=e.endOfAllRequests,e.fmp4Captions&&(function(e,t,i){for(var n in i)if(!e[n]){t.trigger({type:"usage",name:"hls-608"});var r=t.textTracks().getTrackById(n);e[n]=r||t.addRemoteTextTrack({kind:"captions",id:n,label:n},!1).track}}(this.inbandTextTracks_,this.hls_.tech_,e.captionStreams),function(e){var r=e.inbandTextTracks,t=e.captionArray,a=e.timestampOffset;if(t){var s=window.WebKitDataCue||window.VTTCue;t.forEach(function(e){var t=e.stream,i=e.startTime,n=e.endTime;r[t]&&(i+=a,n+=a,r[t].addCue(new s(i,n,e.text)))})}}({inbandTextTracks:this.inbandTextTracks_,captionArray:e.fmp4Captions,timestampOffset:0}),this.captionParser_&&this.captionParser_.clearParsedCaptions()),this.handleSegment_()}},{key:"handleSegment_",value:function(){var e=this;if(this.pendingSegment_){var t=this.pendingSegment_,i=t.segment,n=this.syncController_.probeSegmentInfo(t);"undefined"==typeof this.startingMedia_&&n&&(n.containsAudio||n.containsVideo)&&(this.startingMedia_={containsAudio:n.containsAudio,containsVideo:n.containsVideo});var r=function(e,t,i){return"main"===e&&t&&i?i.containsAudio||i.containsVideo?t.containsVideo&&!i.containsVideo?"Only audio found in segment when we expected video. We can't switch to audio only from a stream that had video. To get rid of this message, please add codec information to the manifest.":!t.containsVideo&&i.containsVideo?"Video found in segment when we expected only audio. We can't switch to a stream with video from an audio only stream. To get rid of this message, please add codec information to the manifest.":null:"Neither audio nor video found in segment.":null}(this.loaderType_,this.startingMedia_,n);if(r)return this.error({message:r,blacklistDuration:1/0}),void this.trigger("error");if(t.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");if(null!==t.timestampOffset&&t.timestampOffset!==this.sourceUpdater_.timestampOffset()){if(n&&n.segmentTimestampInfo){var a=n.segmentTimestampInfo[0].ptsTime,s=n.segmentTimestampInfo[0].dtsTime;t.timestampOffset-=a-s}this.sourceUpdater_.timestampOffset(t.timestampOffset),this.trigger("timestampoffset")}var o=this.syncController_.mappingForTimeline(t.timeline);if(null!==o&&this.trigger({type:"segmenttimemapping",mapping:o}),this.state="APPENDING",i.map){var u=fl(i.map);if(!this.activeInitSegmentId_||this.activeInitSegmentId_!==u){var l=this.initSegment(i.map);this.sourceUpdater_.appendBuffer({bytes:l.bytes},function(){e.activeInitSegmentId_=u})}}t.byteLength=t.bytes.byteLength,"number"==typeof i.start&&"number"==typeof i.end?this.mediaSecondsLoaded+=i.end-i.start:this.mediaSecondsLoaded+=i.duration,this.logger_(function(e){var t=e.segment,i=t.start,n=t.end,r=e.playlist,a=r.mediaSequence,s=r.id,o=r.segments,u=void 0===o?[]:o,l=e.mediaIndex,c=e.timeline;return["appending ["+l+"] of ["+a+", "+(a+u.length)+"] from playlist ["+s+"]","["+i+" => "+n+"] in timeline ["+c+"]"].join(" ")}(t)),this.sourceUpdater_.appendBuffer({bytes:t.bytes,videoSegmentTimingInfoCallback:this.handleVideoSegmentTimingInfo_.bind(this,t.requestId)},this.handleUpdateEnd_.bind(this))}else this.state="READY"}},{key:"handleVideoSegmentTimingInfo_",value:function(e,t){if(this.pendingSegment_&&e===this.pendingSegment_.requestId){var i=this.pendingSegment_.segment;i.videoTimingInfo||(i.videoTimingInfo={}),i.videoTimingInfo.transmuxerPrependedSeconds=t.videoSegmentTimingInfo.prependedContentDuration||0,i.videoTimingInfo.transmuxedPresentationStart=t.videoSegmentTimingInfo.start.presentation,i.videoTimingInfo.transmuxedPresentationEnd=t.videoSegmentTimingInfo.end.presentation,i.videoTimingInfo.baseMediaDecodeTime=t.videoSegmentTimingInfo.baseMediaDecodeTime}}},{key:"handleUpdateEnd_",value:function(){if(!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_,t=e.segment,i=null!==this.mediaIndex;this.pendingSegment_=null,this.recordThroughput_(e),this.addSegmentMetadataCue_(e),this.state="READY",this.mediaIndex=e.mediaIndex,this.fetchAtBuffer_=!0,this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate"),t.end&&this.currentTime_()-t.end>3*e.playlist.targetDuration?this.resetEverything():(i&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.isEndOfStream_(e.mediaIndex+1,e.playlist)&&this.endOfStream(),this.paused()||this.monitorBuffer_())}},{key:"recordThroughput_",value:function(e){var t=this.throughput.rate,i=Date.now()-e.endOfAllRequests+1,n=Math.floor(e.byteLength/i*8*1e3);this.throughput.rate+=(n-t)/++this.throughput.count}},{key:"addSegmentMetadataCue_",value:function(e){if(this.segmentMetadataTrack_){var t=e.segment,i=t.start,n=t.end;if(Ac(i)&&Ac(n)){Cl(i,n,this.segmentMetadataTrack_);var r=v.WebKitDataCue||v.VTTCue,a={custom:t.custom,dateTimeObject:t.dateTimeObject,dateTimeString:t.dateTimeString,bandwidth:e.playlist.attributes.BANDWIDTH,resolution:e.playlist.attributes.RESOLUTION,codecs:e.playlist.attributes.CODECS,byteLength:e.byteLength,uri:e.uri,timeline:e.timeline,playlist:e.playlist.uri,start:i,end:n},s=new r(i,n,JSON.stringify(a));s.value=a,this.segmentMetadataTrack_.addCue(s)}}}}]),Dc);function Dc(e){Mu(this,Dc);var t=Fu(this,(Dc.__proto__||Object.getPrototypeOf(Dc)).call(this));if(!e)throw new TypeError("Initialization settings are required");if("function"!=typeof e.currentTime)throw new TypeError("No currentTime getter specified");if(!e.mediaSource)throw new TypeError("No MediaSource specified");return t.bandwidth=e.bandwidth,t.throughput={rate:0,count:0},t.roundTrip=NaN,t.resetStats_(),t.mediaIndex=null,t.hasPlayed_=e.hasPlayed,t.currentTime_=e.currentTime,t.seekable_=e.seekable,t.seeking_=e.seeking,t.duration_=e.duration,t.mediaSource_=e.mediaSource,t.hls_=e.hls,t.loaderType_=e.loaderType,t.startingMedia_=void 0,t.segmentMetadataTrack_=e.segmentMetadataTrack,t.goalBufferLength_=e.goalBufferLength,t.sourceType_=e.sourceType,t.inbandTextTracks_=e.inbandTextTracks,t.state_="INIT",t.checkBufferTimeout_=null,t.error_=void 0,t.currentTimeline_=-1,t.pendingSegment_=null,t.mimeType_=null,t.sourceUpdater_=null,t.xhrOptions_=null,t.activeInitSegmentId_=null,t.initSegments_={},t.cacheEncryptionKeys_=e.cacheEncryptionKeys,t.keyCache_={},"main"===t.loaderType_?t.captionParser_=new Xo:t.captionParser_=null,t.decrypter_=e.decrypter,t.syncController_=e.syncController,t.syncPoint_={segmentIndex:0,time:0},t.syncController_.on("syncinfoupdate",function(){return t.trigger("syncinfoupdate")}),t.mediaSource_.addEventListener("sourceopen",function(){return t.ended_=!1}),t.fetchAtBuffer_=!1,t.logger_=mc("SegmentLoader["+t.loaderType_+"]"),Object.defineProperty(t,"state",{get:function(){return this.state_},set:function(e){e!==this.state_&&(this.logger_(this.state_+" -> "+e),this.state_=e)}}),t}function Uc(e){return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}var Rc=new Uint8Array("\n\n".split("").map(function(e){return e.charCodeAt(0)})),Mc=(ju(Nc,xc),Nu(Nc,[{key:"buffered_",value:function(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues.length)return fs.createTimeRanges();var e=this.subtitlesTrack_.cues,t=e[0].startTime,i=e[e.length-1].startTime;return fs.createTimeRanges([[t,i]])}},{key:"initSegment",value:function(e,t){var i=1<arguments.length&&void 0!==t&&t;if(!e)return null;var n=fl(e),r=this.initSegments_[n];if(i&&!r&&e.bytes){var a=Rc.byteLength+e.bytes.byteLength,s=new Uint8Array(a);s.set(e.bytes),s.set(Rc,e.bytes.byteLength),this.initSegments_[n]=r={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:s}}return r||e}},{key:"couldBeginLoading_",value:function(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()}},{key:"init_",value:function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}},{key:"track",value:function(e){return"undefined"==typeof e||(this.subtitlesTrack_=e,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_}},{key:"remove",value:function(e,t){Cl(e,t,this.subtitlesTrack_)}},{key:"fillBuffer_",value:function(){var e=this;this.syncPoint_||(this.syncPoint_=this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_()));var t=this.checkBuffer_(this.buffered_(),this.playlist_,this.mediaIndex,this.hasPlayed_(),this.currentTime_(),this.syncPoint_);if(t=this.skipEmptySegments_(t)){if(null===this.syncController_.timestampOffsetForTimeline(t.timeline))return this.syncController_.one("timestampoffset",function(){e.state="READY",e.paused()||e.monitorBuffer_()}),void(this.state="WAITING_ON_TIMELINE");this.loadSegment_(t)}}},{key:"skipEmptySegments_",value:function(e){for(;e&&e.segment.empty;)e=this.generateSegmentInfo_(e.playlist,e.mediaIndex+1,e.startOfSegment+e.duration,e.isSyncRequest);return e}},{key:"handleSegment_",value:function(){var t=this;if(this.pendingSegment_&&this.subtitlesTrack_){this.state="APPENDING";var e=this.pendingSegment_,i=e.segment;if("function"!=typeof v.WebVTT&&this.subtitlesTrack_&&this.subtitlesTrack_.tech_){function n(){t.subtitlesTrack_.tech_.off("vttjsloaded",r),t.error({message:"Error loading vtt.js"}),t.state="READY",t.pause(),t.trigger("error")}var r=void 0;return r=function(){t.subtitlesTrack_.tech_.off("vttjserror",n),t.handleSegment_()},this.state="WAITING_ON_VTTJS",this.subtitlesTrack_.tech_.one("vttjsloaded",r),void this.subtitlesTrack_.tech_.one("vttjserror",n)}i.requested=!0;try{this.parseVTTCues_(e)}catch(e){return this.error({message:e.message}),this.state="READY",this.pause(),this.trigger("error")}if(this.updateTimeMapping_(e,this.syncController_.timelines[e.timeline],this.playlist_),e.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");e.byteLength=e.bytes.byteLength,this.mediaSecondsLoaded+=i.duration,e.cues.length&&this.remove(e.cues[0].endTime,e.cues[e.cues.length-1].endTime),e.cues.forEach(function(e){t.subtitlesTrack_.addCue(e)}),this.handleUpdateEnd_()}else this.state="READY"}},{key:"parseVTTCues_",value:function(t){var e=void 0,i=!1;"function"==typeof v.TextDecoder?e=new v.TextDecoder("utf8"):(e=v.WebVTT.StringDecoder(),i=!0);var n=new v.WebVTT.Parser(v,v.vttjs,e);if(t.cues=[],t.timestampmap={MPEGTS:0,LOCAL:0},n.oncue=t.cues.push.bind(t.cues),n.ontimestampmap=function(e){return t.timestampmap=e},n.onparsingerror=function(e){fs.log.warn("Error encountered when parsing cues: "+e.message)},t.segment.map){var r=t.segment.map.bytes;i&&(r=Uc(r)),n.parse(r)}var a=t.bytes;i&&(a=Uc(a)),n.parse(a),n.flush()}},{key:"updateTimeMapping_",value:function(e,t,i){var n=e.segment;if(t)if(e.cues.length){var r=e.timestampmap,a=r.MPEGTS/9e4-r.LOCAL+t.mapping;if(e.cues.forEach(function(e){e.startTime+=a,e.endTime+=a}),!i.syncInfo){var s=e.cues[0].startTime,o=e.cues[e.cues.length-1].startTime;i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:Math.min(s,o-n.duration)}}}else n.empty=!0}}]),Nc);function Nc(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};Mu(this,Nc);var i=Fu(this,(Nc.__proto__||Object.getPrototypeOf(Nc)).call(this,e,t));return i.mediaSource_=null,i.subtitlesTrack_=null,i}function Bc(e,t){for(var i=e.cues,n=0;n<i.length;n++){var r=i[n];if(t>=r.adStartTime&&t<=r.adEndTime)return r}return null}var jc=vu,Fc=[{name:"VOD",run:function(e,t,i,n,r){if(i===1/0)return null;return{time:0,segmentIndex:0}}},{name:"ProgramDateTime",run:function(e,t,i,n,r){if(!e.datetimeToDisplayTime)return null;var a=t.segments||[],s=null,o=null;r=r||0;for(var u=0;u<a.length;u++){var l=a[u];if(l.dateTimeObject){var c=l.dateTimeObject.getTime()/1e3+e.datetimeToDisplayTime,h=Math.abs(r-c);if(null!==o&&(0===h||o<h))break;o=h,s={time:c,segmentIndex:u}}}return s}},{name:"Segment",run:function(e,t,i,n,r){var a=t.segments||[],s=null,o=null;r=r||0;for(var u=0;u<a.length;u++){var l=a[u];if(l.timeline===n&&"undefined"!=typeof l.start){var c=Math.abs(r-l.start);if(null!==o&&o<c)break;(!s||null===o||c<=o)&&(o=c,s={time:l.start,segmentIndex:u})}}return s}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o<t.discontinuityStarts.length;o++){var u=t.discontinuityStarts[o],l=t.discontinuitySequence+o+1,c=e.discontinuities[l];if(c){var h=Math.abs(r-c.time);if(null!==s&&s<h)break;(!a||null===s||h<=s)&&(s=h,a={time:c.time,segmentIndex:u})}}return a}},{name:"Playlist",run:function(e,t,i,n,r){return t.syncInfo?{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence}:null}}],Hc=(ju(Vc,fs.EventTarget),Nu(Vc,[{key:"getSyncPoint",value:function(e,t,i,n){var r=this.runStrategies_(e,t,i,n);return r.length?this.selectSyncPoint_(r,{key:"time",value:n}):null}},{key:"getExpiredTime",value:function(e,t){if(!e||!e.segments)return null;var i=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!i.length)return null;var n=this.selectSyncPoint_(i,{key:"segmentIndex",value:0});return 0<n.segmentIndex&&(n.time*=-1),Math.abs(n.time+Zu(e,n.segmentIndex,0))}},{key:"runStrategies_",value:function(e,t,i,n){for(var r=[],a=0;a<Fc.length;a++){var s=Fc[a],o=s.run(this,e,t,i,n);o&&(o.strategy=s.name,r.push({strategy:s.name,syncPoint:o}))}return r}},{key:"selectSyncPoint_",value:function(e,t){for(var i=e[0].syncPoint,n=Math.abs(e[0].syncPoint[t.key]-t.value),r=e[0].strategy,a=1;a<e.length;a++){var s=Math.abs(e[a].syncPoint[t.key]-t.value);s<n&&(n=s,i=e[a].syncPoint,r=e[a].strategy)}return this.logger_("syncPoint for ["+t.key+": "+t.value+"] chosen with strategy ["+r+"]: [time:"+i.time+", segmentIndex:"+i.segmentIndex+"]"),i}},{key:"saveExpiredSegmentInfo",value:function(e,t){for(var i=t.mediaSequence-e.mediaSequence-1;0<=i;i--){var n=e.segments[i];if(n&&"undefined"!=typeof n.start){t.syncInfo={mediaSequence:e.mediaSequence+i,time:n.start},this.logger_("playlist refresh sync: [time:"+t.syncInfo.time+", mediaSequence: "+t.syncInfo.mediaSequence+"]"),this.trigger("syncinfoupdate");break}}}},{key:"setDateTimeMapping",value:function(e){if(!this.datetimeToDisplayTime&&e.segments&&e.segments.length&&e.segments[0].dateTimeObject){var t=e.segments[0].dateTimeObject.getTime()/1e3;this.datetimeToDisplayTime=-t}}},{key:"reset",value:function(){this.inspectCache_=void 0}},{key:"probeSegmentInfo",value:function(e){var t=e.segment,i=e.playlist,n=void 0;return(n=t.map?this.probeMp4Segment_(e):this.probeTsSegment_(e))&&this.calculateSegmentTimeMapping_(e,n)&&(this.saveDiscontinuitySyncInfo_(e),i.syncInfo||(i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:t.start})),n}},{key:"probeMp4Segment_",value:function(e){var t=e.segment,i=Ao.timescale(t.map.bytes),n=Ao.startTime(i,e.bytes);return null!==e.timestampOffset&&(e.timestampOffset-=n),{start:n,end:n+t.duration}}},{key:"probeTsSegment_",value:function(e){var t=jc(e.bytes,this.inspectCache_),i=void 0,n=void 0,r=void 0;return t?(t.video&&2===t.video.length?(this.inspectCache_=t.video[1].dts,i=t.video[0].dtsTime,n=t.video[1].dtsTime,r=t.video):t.audio&&2===t.audio.length&&(this.inspectCache_=t.audio[1].dts,i=t.audio[0].dtsTime,n=t.audio[1].dtsTime,r=t.audio),{segmentTimestampInfo:r,start:i,end:n,containsVideo:t.video&&2===t.video.length,containsAudio:t.audio&&2===t.audio.length}):null}},{key:"timestampOffsetForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].time}},{key:"mappingForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].mapping}},{key:"calculateSegmentTimeMapping_",value:function(e,t){var i=e.segment,n=this.timelines[e.timeline];if(null!==e.timestampOffset)n={time:e.startOfSegment,mapping:e.startOfSegment-t.start},this.timelines[e.timeline]=n,this.trigger("timestampoffset"),this.logger_("time mapping for timeline "+e.timeline+": [time: "+n.time+"] [mapping: "+n.mapping+"]"),i.start=e.startOfSegment,i.end=t.end+n.mapping;else{if(!n)return!1;i.start=t.start+n.mapping,i.end=t.end+n.mapping}return!0}},{key:"saveDiscontinuitySyncInfo_",value:function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts&&t.discontinuityStarts.length)for(var n=0;n<t.discontinuityStarts.length;n++){var r=t.discontinuityStarts[n],a=t.discontinuitySequence+n+1,s=r-e.mediaIndex,o=Math.abs(s);if(!this.discontinuities[a]||this.discontinuities[a].accuracy>o){var u=void 0;u=s<0?i.start-Zu(t,e.mediaIndex,r):i.end+Zu(t,e.mediaIndex+1,r),this.discontinuities[a]={time:u,accuracy:o}}}}}]),Vc);function Vc(){Mu(this,Vc);var e=Fu(this,(Vc.__proto__||Object.getPrototypeOf(Vc)).call(this));return e.inspectCache_=void 0,e.timelines=[],e.discontinuities=[],e.datetimeToDisplayTime=null,e.logger_=mc("SyncController"),e}function qc(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null)}function Wc(e,t){(t.activePlaylistLoader=e).load()}function zc(t){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){Kc[e](e,t)});var i=t.mediaTypes,e=t.masterPlaylistLoader,n=t.tech,r=t.hls;["AUDIO","SUBTITLES"].forEach(function(e){i[e].activeGroup=function(a,s){return function(t){var e=s.masterPlaylistLoader,i=s.mediaTypes[a].groups,n=e.media();if(!n)return null;var r=null;return n.attributes[a]&&(r=i[n.attributes[a]]),r=r||i.main,"undefined"==typeof t?r:null===t?null:r.filter(function(e){return e.id===t.id})[0]||null}}(e,t),i[e].activeTrack=Yc[e](e,t),i[e].onGroupChanged=function(o,u){return function(){var e=u.segmentLoaders,t=e[o],i=e.main,n=u.mediaTypes[o],r=n.activeTrack(),a=n.activeGroup(r),s=n.activePlaylistLoader;qc(t,n),a&&(a.playlistLoader?(t.resyncLoader(),Wc(a.playlistLoader,n)):s&&i.resetEverything())}}(e,t),i[e].onTrackChanged=function(o,u){return function(){var e=u.segmentLoaders,t=e[o],i=e.main,n=u.mediaTypes[o],r=n.activeTrack(),a=n.activeGroup(r),s=n.activePlaylistLoader;qc(t,n),a&&(a.playlistLoader?(s!==a.playlistLoader&&(t.track&&t.track(r),t.resetEverything()),Wc(a.playlistLoader,n)):i.resetEverything())}}(e,t)});var a=i.AUDIO.activeGroup(),s=(a.filter(function(e){return e.default})[0]||a[0]).id;function o(){i.AUDIO.onTrackChanged(),n.trigger({type:"usage",name:"hls-audio-change"})}for(var u in i.AUDIO.tracks[s].enabled=!0,i.AUDIO.onTrackChanged(),e.on("mediachange",function(){["AUDIO","SUBTITLES"].forEach(function(e){return i[e].onGroupChanged()})}),n.audioTracks().addEventListener("change",o),n.remoteTextTracks().addEventListener("change",i.SUBTITLES.onTrackChanged),r.on("dispose",function(){n.audioTracks().removeEventListener("change",o),n.remoteTextTracks().removeEventListener("change",i.SUBTITLES.onTrackChanged)}),n.clearTracks("audio"),i.AUDIO.tracks)n.audioTracks().addTrack(i.AUDIO.tracks[u])}var $c=new Fl("./decrypter-worker.worker.js",function(e,t){var i,c,g,n,r,u,s,a=this;i=function(e,t,i){return t&&o(e.prototype,t),i&&o(e,i),e},c=null,d.prototype.decrypt=function(e,t,i,n,r,a){var s=this._key[1],o=e^s[0],u=n^s[1],l=i^s[2],c=t^s[3],h=void 0,d=void 0,p=void 0,f=s.length/4-2,m=void 0,g=4,y=this._tables[1],v=y[0],_=y[1],b=y[2],T=y[3],S=y[4];for(m=0;m<f;m++)h=v[o>>>24]^_[u>>16&255]^b[l>>8&255]^T[255&c]^s[g],d=v[u>>>24]^_[l>>16&255]^b[c>>8&255]^T[255&o]^s[g+1],p=v[l>>>24]^_[c>>16&255]^b[o>>8&255]^T[255&u]^s[g+2],c=v[c>>>24]^_[o>>16&255]^b[u>>8&255]^T[255&l]^s[g+3],g+=4,o=h,u=d,l=p;for(m=0;m<4;m++)r[(3&-m)+a]=S[o>>>24]<<24^S[u>>16&255]<<16^S[l>>8&255]<<8^S[255&c]^s[g++],h=o,o=u,u=l,l=c,c=h},g=d,l.prototype.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},l.prototype.off=function(e,t){if(!this.listeners[e])return!1;var i=this.listeners[e].indexOf(t);return this.listeners[e].splice(i,1),-1<i},l.prototype.trigger=function(e,t){var i=this.listeners[e];if(i)if(2===arguments.length)for(var n=i.length,r=0;r<n;++r)i[r].call(this,t);else for(var a=Array.prototype.slice.call(arguments,1),s=i.length,o=0;o<s;++o)i[o].apply(this,a)},l.prototype.dispose=function(){this.listeners={}},l.prototype.pipe=function(t){this.on("data",function(e){t.push(e)})},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(p,r=n=l),p.prototype.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},p.prototype.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},u=p,f.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=function(e,t,i){var n=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),r=new g(Array.prototype.slice.call(t)),a=new Uint8Array(e.byteLength),s=new Int32Array(a.buffer),o=void 0,u=void 0,l=void 0,c=void 0,h=void 0,d=void 0,p=void 0,f=void 0,m=void 0;for(o=i[0],u=i[1],l=i[2],c=i[3],m=0;m<n.length;m+=4)h=y(n[m]),d=y(n[m+1]),p=y(n[m+2]),f=y(n[m+3]),r.decrypt(h,d,p,f,s,m),s[m]=y(s[m]^o),s[m+1]=y(s[m+1]^u),s[m+2]=y(s[m+2]^l),s[m+3]=y(s[m+3]^c),o=h,u=d,l=p,c=f;return a}(t,i,n);r.set(e,t.byteOffset)}},i(f,null,[{key:"STEP",get:function(){return 32e3}}]),s=f,new function(a){a.onmessage=function(e){var i=e.data,t=new Uint8Array(i.encrypted.bytes,i.encrypted.byteOffset,i.encrypted.byteLength),n=new Uint32Array(i.key.bytes,i.key.byteOffset,i.key.byteLength/4),r=new Uint32Array(i.iv.bytes,i.iv.byteOffset,i.iv.byteLength/4);new s(t,n,r,function(e,t){a.postMessage(function(i){var n={};return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}({source:i.source,decrypted:t}),[t.buffer])})}}(a);function h(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function d(e){h(this,d),c=c||function(){var e=[[[],[],[],[],[]],[[],[],[],[],[]]],t=e[0],i=e[1],n=t[4],r=i[4],a=void 0,s=void 0,o=void 0,u=[],l=[],c=void 0,h=void 0,d=void 0,p=void 0,f=void 0;for(a=0;a<256;a++)l[(u[a]=a<<1^283*(a>>7))^a]=a;for(s=o=0;!n[s];s^=c||1,o=l[o]||1)for(d=(d=o^o<<1^o<<2^o<<3^o<<4)>>8^255&d^99,f=16843009*u[h=u[c=u[r[n[s]=d]=s]]]^65537*h^257*c^16843008*s,p=257*u[d]^16843008*d,a=0;a<4;a++)t[a][s]=p=p<<24^p>>>8,i[a][d]=f=f<<24^f>>>8;for(a=0;a<5;a++)t[a]=t[a].slice(0),i[a]=i[a].slice(0);return e}(),this._tables=[[c[0][0].slice(),c[0][1].slice(),c[0][2].slice(),c[0][3].slice(),c[0][4].slice()],[c[1][0].slice(),c[1][1].slice(),c[1][2].slice(),c[1][3].slice(),c[1][4].slice()]];var t=void 0,i=void 0,n=void 0,r=void 0,a=void 0,s=this._tables[0][4],o=this._tables[1],u=e.length,l=1;if(4!==u&&6!==u&&8!==u)throw new Error("Invalid aes key size");for(r=e.slice(0),a=[],this._key=[r,a],t=u;t<4*u+28;t++)n=r[t-1],(t%u==0||8===u&&t%u==4)&&(n=s[n>>>24]<<24^s[n>>16&255]<<16^s[n>>8&255]<<8^s[255&n],t%u==0&&(n=n<<8^n>>>24^l<<24,l=l<<1^283*(l>>7))),r[t]=r[t-u]^n;for(i=0;t;i++,t--)n=r[3&i?t:t-4],a[i]=t<=4||i<4?n:o[0][s[n>>>24]]^o[1][s[n>>16&255]]^o[2][s[n>>8&255]]^o[3][s[255&n]]}function l(){h(this,l),this.listeners={}}function p(){h(this,p);var e=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,r.call(this,n));return e.jobs=[],e.delay=1,e.timeout_=null,e}function y(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24}function f(e,t,i,n){h(this,f);var r=f.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new u,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([y(a[o-4]),y(a[o-3]),y(a[o-2]),y(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){n(null,function(e){return e.subarray(0,e.byteLength-e[e.byteLength-1])}(s))})}}),Gc={AUDIO:function(u,l){return function(){var e=l.segmentLoaders[u],t=l.mediaTypes[u],i=l.blacklistCurrentPlaylist;qc(e,t);var n=t.activeTrack(),r=t.activeGroup(),a=(r.filter(function(e){return e.default})[0]||r[0]).id,s=t.tracks[a];if(n!==s){for(var o in fs.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),t.tracks)t.tracks[o].enabled=t.tracks[o]===s;t.onTrackChanged()}else i({message:"Problem encountered loading the default audio track."})}},SUBTITLES:function(n,r){return function(){var e=r.segmentLoaders[n],t=r.mediaTypes[n];fs.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),qc(e,t);var i=t.activeTrack();i&&(i.mode="disabled"),t.onTrackChanged()}}},Xc={AUDIO:function(e,t,i){if(t){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Gc[e](e,i))}},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Gc[e](e,i))}},Kc={AUDIO:function(e,t){var i,n,r=t.hls,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,h=l.tracks,d=t.masterPlaylistLoader;for(var p in u[e]&&0!==Object.keys(u[e]).length||(u[e]={main:{default:{default:!0}}}),u[e])for(var f in c[p]||(c[p]=[]),u[e][p]){var m=u[e][p][f],g=void 0;if(g=m.resolvedUri?new Ku(m.resolvedUri,r,o):m.playlists&&"dash"===a?new pc(m.playlists[0],r,o,d):null,m=fs.mergeOptions({id:f,playlistLoader:g},m),Xc[e](e,m.playlistLoader,t),c[p].push(m),"undefined"==typeof h[f]){var y=new fs.AudioTrack({id:f,kind:(i=m,n=void 0,n=i.default?"main":"alternative",i.characteristics&&0<=i.characteristics.indexOf("public.accessibility.describes-video")&&(n="main-desc"),n),enabled:!1,language:m.language,default:m.default,label:f});h[f]=y}}s.on("error",Gc[e](e,t))},SUBTITLES:function(e,t){var i=t.tech,n=t.hls,r=t.sourceType,a=t.segmentLoaders[e],s=t.requestOptions,o=t.master.mediaGroups,u=t.mediaTypes[e],l=u.groups,c=u.tracks,h=t.masterPlaylistLoader;for(var d in o[e])for(var p in l[d]||(l[d]=[]),o[e][d])if(!o[e][d][p].forced){var f=o[e][d][p],m=void 0;if("hls"===r?m=new Ku(f.resolvedUri,n,s):"dash"===r&&(m=new pc(f.playlists[0],n,s,h)),f=fs.mergeOptions({id:p,playlistLoader:m},f),Xc[e](e,f.playlistLoader,t),l[d].push(f),"undefined"==typeof c[p]){var g=i.addRemoteTextTrack({id:p,kind:"subtitles",default:f.default&&f.autoselect,language:f.language,label:p},!1).track;c[p]=g}}a.on("error",Gc[e](e,t))},"CLOSED-CAPTIONS":function(e,t){var i=t.tech,n=t.master.mediaGroups,r=t.mediaTypes[e],a=r.groups,s=r.tracks;for(var o in n[e])for(var u in a[o]||(a[o]=[]),n[e][o]){var l=n[e][o][u];if(l.instreamId.match(/CC\d/)&&(a[o].push(fs.mergeOptions({id:u},l)),"undefined"==typeof s[u])){var c=i.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default&&l.autoselect,language:l.language,label:u},!1).track;s[u]=c}}}},Yc={AUDIO:function(i,n){return function(){var e=n.mediaTypes[i].tracks;for(var t in e)if(e[t].enabled)return e[t];return null}},SUBTITLES:function(i,n){return function(){var e=n.mediaTypes[i].tracks;for(var t in e)if("showing"===e[t].mode)return e[t];return null}}},Qc=void 0,Jc=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred"],Zc=(ju(eh,fs.EventTarget),Nu(eh,[{key:"setupMasterPlaylistLoaderListeners_",value:function(){var n=this;this.masterPlaylistLoader_.on("loadedmetadata",function(){var e=n.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;ul(n.masterPlaylistLoader_.master,n.masterPlaylistLoader_.media())?n.requestOptions_.timeout=0:n.requestOptions_.timeout=t,e.endList&&"none"!==n.tech_.preload()&&(n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.mainSegmentLoader_.load()),zc({sourceType:n.sourceType_,segmentLoaders:{AUDIO:n.audioSegmentLoader_,SUBTITLES:n.subtitleSegmentLoader_,main:n.mainSegmentLoader_},tech:n.tech_,requestOptions:n.requestOptions_,masterPlaylistLoader:n.masterPlaylistLoader_,hls:n.hls_,master:n.master(),mediaTypes:n.mediaTypes_,blacklistCurrentPlaylist:n.blacklistCurrentPlaylist.bind(n)}),n.triggerPresenceUsage_(n.master(),e);try{n.setupSourceBuffers_()}catch(e){return fs.log.warn("Failed to create SourceBuffers",e),n.mediaSource.endOfStream("decode")}n.setupFirstPlay(),!n.mediaTypes_.AUDIO.activePlaylistLoader||n.mediaTypes_.AUDIO.activePlaylistLoader.media()?n.trigger("selectedinitialmedia"):n.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",function(){n.trigger("selectedinitialmedia")})}),this.masterPlaylistLoader_.on("loadedplaylist",function(){var e=n.masterPlaylistLoader_.media();if(!e){n.excludeUnsupportedVariants_();var t=void 0;return n.enableLowInitialPlaylist&&(t=n.selectInitialPlaylist()),t=t||n.selectPlaylist(),n.initialMedia_=t,void n.masterPlaylistLoader_.media(n.initialMedia_)}if(n.useCueTags_&&n.updateAdCues_(e),n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.updateDuration(),n.tech_.paused()||(n.mainSegmentLoader_.load(),n.audioSegmentLoader_&&n.audioSegmentLoader_.load()),!e.endList){function i(){var e=n.seekable();0!==e.length&&n.mediaSource.addSeekableRange_(e.start(0),e.end(0))}n.duration()!==1/0?n.tech_.one("durationchange",function e(){n.duration()===1/0?i():n.tech_.one("durationchange",e)}):i()}}),this.masterPlaylistLoader_.on("error",function(){n.blacklistCurrentPlaylist(n.masterPlaylistLoader_.error)}),this.masterPlaylistLoader_.on("mediachanging",function(){n.mainSegmentLoader_.abort(),n.mainSegmentLoader_.pause()}),this.masterPlaylistLoader_.on("mediachange",function(){var e=n.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;ul(n.masterPlaylistLoader_.master,n.masterPlaylistLoader_.media())?n.requestOptions_.timeout=0:n.requestOptions_.timeout=t,n.mainSegmentLoader_.playlist(e,n.requestOptions_),n.mainSegmentLoader_.load(),n.tech_.trigger({type:"mediachange",bubbles:!0})}),this.masterPlaylistLoader_.on("playlistunchanged",function(){var e=n.masterPlaylistLoader_.media();n.stuckAtPlaylistEnd_(e)&&(n.blacklistCurrentPlaylist({message:"Playlist no longer updating."}),n.tech_.trigger("playliststuck"))}),this.masterPlaylistLoader_.on("renditiondisabled",function(){n.tech_.trigger({type:"usage",name:"hls-rendition-disabled"})}),this.masterPlaylistLoader_.on("renditionenabled",function(){n.tech_.trigger({type:"usage",name:"hls-rendition-enabled"})})}},{key:"triggerPresenceUsage_",value:function(e,t){var i=e.mediaGroups||{},n=!0,r=Object.keys(i.AUDIO);for(var a in i.AUDIO)for(var s in i.AUDIO[a])i.AUDIO[a][s].uri||(n=!1);n&&this.tech_.trigger({type:"usage",name:"hls-demuxed"}),Object.keys(i.SUBTITLES).length&&this.tech_.trigger({type:"usage",name:"hls-webvtt"}),Qc.Playlist.isAes(t)&&this.tech_.trigger({type:"usage",name:"hls-aes"}),Qc.Playlist.isFmp4(t)&&this.tech_.trigger({type:"usage",name:"hls-fmp4"}),r.length&&1<Object.keys(i.AUDIO[r[0]]).length&&this.tech_.trigger({type:"usage",name:"hls-alternate-audio"}),this.useCueTags_&&this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"})}},{key:"setupSegmentLoaderListeners_",value:function(){var a=this;this.mainSegmentLoader_.on("bandwidthupdate",function(){var e=a.selectPlaylist(),t=a.masterPlaylistLoader_.media(),i=a.tech_.buffered(),n=i.length?i.end(i.length-1)-a.tech_.currentTime():0,r=a.bufferLowWaterLine();(!t.endList||a.duration()<Pc.MAX_BUFFER_LOW_WATER_LINE||e.attributes.BANDWIDTH<t.attributes.BANDWIDTH||r<=n)&&a.masterPlaylistLoader_.media(e),a.tech_.trigger("bandwidthupdate")}),this.mainSegmentLoader_.on("progress",function(){a.trigger("progress")}),this.mainSegmentLoader_.on("error",function(){a.blacklistCurrentPlaylist(a.mainSegmentLoader_.error())}),this.mainSegmentLoader_.on("syncinfoupdate",function(){a.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("timestampoffset",function(){a.tech_.trigger({type:"usage",name:"hls-timestamp-offset"})}),this.audioSegmentLoader_.on("syncinfoupdate",function(){a.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("ended",function(){a.onEndOfStream()}),this.mainSegmentLoader_.on("earlyabort",function(){a.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120)}),this.mainSegmentLoader_.on("reseteverything",function(){a.tech_.trigger("hls-reset")}),this.mainSegmentLoader_.on("segmenttimemapping",function(e){a.tech_.trigger({type:"hls-segment-time-mapping",mapping:e.mapping})}),this.audioSegmentLoader_.on("ended",function(){a.onEndOfStream()})}},{key:"mediaSecondsLoaded_",value:function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)}},{key:"load",value:function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()}},{key:"smoothQualityChange_",value:function(){var e=this.selectPlaylist();e!==this.masterPlaylistLoader_.media()&&(this.masterPlaylistLoader_.media(e),this.mainSegmentLoader_.resetLoader())}},{key:"fastQualityChange_",value:function(){var e=this,t=this.selectPlaylist();t!==this.masterPlaylistLoader_.media()&&(this.masterPlaylistLoader_.media(t),this.mainSegmentLoader_.resetEverything(function(){fs.browser.IE_VERSION||fs.browser.IS_EDGE?e.tech_.setCurrentTime(e.tech_.currentTime()+.04):e.tech_.setCurrentTime(e.tech_.currentTime())}))}},{key:"play",value:function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.seekTo_(0),this.hasPlayed_()&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()<e.start(0)?this.seekTo_(e.end(e.length-1)):void 0}}},{key:"setupFirstPlay",value:function(){var e=this,t=this.masterPlaylistLoader_.media();if(!t||this.tech_.paused()||this.hasPlayed_())return!1;if(!t.endList){var i=this.seekable();if(!i.length)return!1;if(fs.browser.IE_VERSION&&0===this.tech_.readyState())return this.tech_.one("loadedmetadata",function(){e.trigger("firstplay"),e.seekTo_(i.end(0)),e.hasPlayed_=function(){return!0}}),!1;this.trigger("firstplay"),this.seekTo_(i.end(0))}return this.hasPlayed_=function(){return!0},this.load(),!0}},{key:"handleSourceOpen_",value:function(){try{this.setupSourceBuffers_()}catch(e){return fs.log.warn("Failed to create Source Buffers",e),this.mediaSource.endOfStream("decode")}if(this.tech_.autoplay()){var e=this.tech_.play();"undefined"!=typeof e&&"function"==typeof e.then&&e.then(null,function(e){})}this.trigger("sourceopen")}},{key:"onEndOfStream",value:function(){var e=this.mainSegmentLoader_.ended_;if(this.mediaTypes_.AUDIO.activePlaylistLoader&&(e=!this.mainSegmentLoader_.startingMedia_||this.mainSegmentLoader_.startingMedia_.containsVideo?e&&this.audioSegmentLoader_.ended_:this.audioSegmentLoader_.ended_),e){this.logger_("calling mediaSource.endOfStream()");try{this.mediaSource.endOfStream()}catch(e){fs.log.warn("Failed to call media source endOfStream",e)}}}},{key:"stuckAtPlaylistEnd_",value:function(e){if(!this.seekable().length)return!1;var t=this.syncController_.getExpiredTime(e,this.mediaSource.duration);if(null===t)return!1;var i=Qc.Playlist.playlistEnd(e,t),n=this.tech_.currentTime(),r=this.tech_.buffered();if(!r.length)return i-n<=.1;var a=r.end(r.length-1);return a-n<=.1&&i-a<=.1}},{key:"blacklistCurrentPlaylist",value:function(e,t){var i,n=0<arguments.length&&void 0!==e?e:{},r=t,a=void 0;if(a=n.playlist||this.masterPlaylistLoader_.media(),r=r||n.blacklistDuration||this.blacklistDuration,!a){this.error=n;try{return this.mediaSource.endOfStream("network")}catch(e){return this.trigger("error")}}var s=1===this.masterPlaylistLoader_.master.playlists.filter(sl).length,o=this.masterPlaylistLoader_.master.playlists;return 1===o.length?(fs.log.warn("Problem encountered with the current HLS playlist. Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.masterPlaylistLoader_.load(s)):(s&&(fs.log.warn("Removing all playlists from the blacklist because the last rendition is about to be blacklisted."),o.forEach(function(e){e.excludeUntil!==1/0&&delete e.excludeUntil}),this.tech_.trigger("retryplaylist")),a.excludeUntil=Date.now()+1e3*r,this.tech_.trigger("blacklistplaylist"),this.tech_.trigger({type:"usage",name:"hls-rendition-blacklisted"}),i=this.selectPlaylist(),fs.log.warn("Problem encountered with the current HLS playlist."+(n.message?" "+n.message:"")+" Switching to another playlist."),this.masterPlaylistLoader_.media(i,s))}},{key:"pauseLoading",value:function(){this.mainSegmentLoader_.pause(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.pause(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.pause()}},{key:"setCurrentTime",value:function(e){var t=bl(this.tech_.buffered(),e);return this.masterPlaylistLoader_&&this.masterPlaylistLoader_.media()&&this.masterPlaylistLoader_.media().segments?t&&t.length?e:(this.mainSegmentLoader_.resetEverything(),this.mainSegmentLoader_.abort(),this.mediaTypes_.AUDIO.activePlaylistLoader&&(this.audioSegmentLoader_.resetEverything(),this.audioSegmentLoader_.abort()),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&(this.subtitleSegmentLoader_.resetEverything(),this.subtitleSegmentLoader_.abort()),void this.load()):0}},{key:"duration",value:function(){return this.masterPlaylistLoader_?this.mediaSource?this.mediaSource.duration:Qc.Playlist.duration(this.masterPlaylistLoader_.media()):0}},{key:"seekable",value:function(){return this.seekable_}},{key:"onSyncInfoUpdate_",value:function(){var e=void 0,t=void 0;if(this.masterPlaylistLoader_){var i=this.masterPlaylistLoader_.media();if(i){var n=this.syncController_.getExpiredTime(i,this.mediaSource.duration);if(null!==n&&0!==(e=Qc.Playlist.seekable(i,n)).length){if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(i=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),null===(n=this.syncController_.getExpiredTime(i,this.mediaSource.duration)))return;if(0===(t=Qc.Playlist.seekable(i,n)).length)return}var r=void 0,a=void 0;this.seekable_&&this.seekable_.length&&(r=this.seekable_.end(0),a=this.seekable_.start(0)),t?t.start(0)>e.end(0)||e.start(0)>t.end(0)?this.seekable_=e:this.seekable_=fs.createTimeRanges([[t.start(0)>e.start(0)?t.start(0):e.start(0),t.end(0)<e.end(0)?t.end(0):e.end(0)]]):this.seekable_=e,this.seekable_&&this.seekable_.length&&this.seekable_.end(0)===r&&this.seekable_.start(0)===a||(this.logger_("seekable updated ["+Sl(this.seekable_)+"]"),this.tech_.trigger("seekablechanged"))}}}}},{key:"updateDuration",value:function(){function e(){t.logger_("Setting duration from "+t.mediaSource.duration+" => "+n);try{t.mediaSource.duration=n}catch(e){fs.log.warn("Failed to set media source duration",e)}t.tech_.trigger("durationchange"),t.mediaSource.removeEventListener("sourceopen",e)}var t=this,i=this.mediaSource.duration,n=Qc.Playlist.duration(this.masterPlaylistLoader_.media()),r=this.tech_.buffered();0<r.length&&(n=Math.max(n,r.end(r.length-1))),i!==n&&("open"!==this.mediaSource.readyState?this.mediaSource.addEventListener("sourceopen",e):e())}},{key:"dispose",value:function(){var n=this;this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),["AUDIO","SUBTITLES"].forEach(function(e){var t=n.mediaTypes_[e].groups;for(var i in t)t[i].forEach(function(e){e.playlistLoader&&e.playlistLoader.dispose()})}),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose()}},{key:"master",value:function(){return this.masterPlaylistLoader_.master}},{key:"media",value:function(){return this.masterPlaylistLoader_.media()||this.initialMedia_}},{key:"setupSourceBuffers_",value:function(){var e,t=this.masterPlaylistLoader_.media();if(t&&"open"===this.mediaSource.readyState){if((e=Xl(this.masterPlaylistLoader_.master,t)).length<1)return this.error="No compatible SourceBuffer configuration for the variant stream:"+t.resolvedUri,this.mediaSource.endOfStream("decode");this.configureLoaderMimeTypes_(e),this.excludeIncompatibleVariants_(t)}}},{key:"configureLoaderMimeTypes_",value:function(e){var t=1<e.length&&-1===e[0].indexOf(",")&&e[0]!==e[1]?new fs.EventTarget:null;this.mainSegmentLoader_.mimeType(e[0],t),e[1]&&this.audioSegmentLoader_.mimeType(e[1],t)}},{key:"excludeUnsupportedVariants_",value:function(){this.master().playlists.forEach(function(e){e.attributes.CODECS&&v.MediaSource&&v.MediaSource.isTypeSupported&&!v.MediaSource.isTypeSupported('video/mp4; codecs="'+function(e){return e.replace(/avc1\.(\d+)\.(\d+)/i,function(e){return zl([e])[0]})}(e.attributes.CODECS)+'"')&&(e.excludeUntil=1/0)})}},{key:"excludeIncompatibleVariants_",value:function(e){var i=2,n=null,t=void 0;e.attributes.CODECS&&(t=$l(e.attributes.CODECS),n=t.videoCodec,i=t.codecCount),this.master().playlists.forEach(function(e){var t={codecCount:2,videoCodec:null};e.attributes.CODECS&&(t=$l(e.attributes.CODECS)),t.codecCount!==i&&(e.excludeUntil=1/0),t.videoCodec!==n&&(e.excludeUntil=1/0)})}},{key:"updateAdCues_",value:function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){var n=2<arguments.length&&void 0!==i?i:0;if(e.segments)for(var r=n,a=void 0,s=0;s<e.segments.length;s++){var o=e.segments[s];if(a=a||Bc(t,r+o.duration/2)){if("cueIn"in o){a.endTime=r,a.adEndTime=r,r+=o.duration,a=null;continue}if(r<a.endTime){r+=o.duration;continue}a.endTime+=o.duration}else if("cueOut"in o&&((a=new v.VTTCue(r,r+o.duration,o.cueOut)).adStartTime=r,a.adEndTime=r+parseFloat(o.cueOut),t.addCue(a)),"cueOutCont"in o){var u,l,c=o.cueOutCont.split("/").map(parseFloat),h=$u(c,2);u=h[0],l=h[1],(a=new v.VTTCue(r,r+o.duration,"")).adStartTime=r-u,a.adEndTime=a.adStartTime+l,t.addCue(a)}r+=o.duration}}(e,this.cueTagsTrack_,t)}},{key:"goalBufferLength",value:function(){var e=this.tech_.currentTime(),t=Pc.GOAL_BUFFER_LENGTH,i=Pc.GOAL_BUFFER_LENGTH_RATE,n=Math.max(t,Pc.MAX_GOAL_BUFFER_LENGTH);return Math.min(t+e*i,n)}},{key:"bufferLowWaterLine",value:function(){var e=this.tech_.currentTime(),t=Pc.BUFFER_LOW_WATER_LINE,i=Pc.BUFFER_LOW_WATER_LINE_RATE,n=Math.max(t,Pc.MAX_BUFFER_LOW_WATER_LINE);return Math.min(t+e*i,n)}}]),eh);function eh(e){Mu(this,eh);var t=Fu(this,(eh.__proto__||Object.getPrototypeOf(eh)).call(this)),i=e.url,n=e.handleManifestRedirects,r=e.withCredentials,a=e.tech,s=e.bandwidth,o=e.externHls,u=e.useCueTags,l=e.blacklistDuration,c=e.enableLowInitialPlaylist,h=e.sourceType,d=e.seekTo,p=e.cacheEncryptionKeys;if(!i)throw new Error("A non-empty playlist URL is required");Qc=o,t.withCredentials=r,t.tech_=a,t.hls_=a.hls,t.seekTo_=d,t.sourceType_=h,t.useCueTags_=u,t.blacklistDuration=l,t.enableLowInitialPlaylist=c,t.useCueTags_&&(t.cueTagsTrack_=t.tech_.addTextTrack("metadata","ad-cues"),t.cueTagsTrack_.inBandMetadataTrackDispatchType=""),t.requestOptions_={withCredentials:r,handleManifestRedirects:n,timeout:null},t.mediaTypes_=function(){var t={};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){t[e]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:gc,activeTrack:gc,onGroupChanged:gc,onTrackChanged:gc}}),t}(),t.mediaSource=new fs.MediaSource,t.mediaSource.addEventListener("sourceopen",t.handleSourceOpen_.bind(t)),t.seekable_=fs.createTimeRanges(),t.hasPlayed_=function(){return!1},t.syncController_=new Hc(e),t.segmentMetadataTrack_=a.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,t.decrypter_=new $c,t.inbandTextTracks_={};var f={hls:t.hls_,mediaSource:t.mediaSource,currentTime:t.tech_.currentTime.bind(t.tech_),seekable:function(){return t.seekable()},seeking:function(){return t.tech_.seeking()},duration:function(){return t.mediaSource.duration},hasPlayed:function(){return t.hasPlayed_()},goalBufferLength:function(){return t.goalBufferLength()},bandwidth:s,syncController:t.syncController_,decrypter:t.decrypter_,sourceType:t.sourceType_,inbandTextTracks:t.inbandTextTracks_,cacheEncryptionKeys:p};return t.masterPlaylistLoader_="dash"===t.sourceType_?new pc(i,t.hls_,t.requestOptions_):new Ku(i,t.hls_,t.requestOptions_),t.setupMasterPlaylistLoaderListeners_(),t.mainSegmentLoader_=new xc(fs.mergeOptions(f,{segmentMetadataTrack:t.segmentMetadataTrack_,loaderType:"main"}),e),t.audioSegmentLoader_=new xc(fs.mergeOptions(f,{loaderType:"audio"}),e),t.subtitleSegmentLoader_=new Mc(fs.mergeOptions(f,{loaderType:"vtt"}),e),t.setupSegmentLoaderListeners_(),Jc.forEach(function(e){t[e+"_"]=function(e){return this.audioSegmentLoader_[e]+this.mainSegmentLoader_[e]}.bind(t,e)}),t.logger_=mc("MPC"),t.masterPlaylistLoader_.load(),t}function th(e,t,i){Mu(this,th);var n=e.masterPlaylistController_,r=n[(e.options_.smoothQualityChange?"smooth":"fast")+"QualityChange_"].bind(n);if(t.attributes.RESOLUTION){var a=t.attributes.RESOLUTION;this.width=a.width,this.height=a.height}this.bandwidth=t.attributes.BANDWIDTH,this.id=i,this.enabled=function(r,a,s){return function(e){var t=r.master.playlists[a],i=al(t),n=sl(t);return"undefined"==typeof e?n:(e?delete t.disabled:t.disabled=!0,e===n||i||(s(),e?r.trigger("renditionenabled"):r.trigger("renditiondisabled")),e)}}(e.playlists,t.uri,r)}var ih=["seeking","seeked","pause","playing","error"],nh=(Nu(rh,[{key:"monitorCurrentTime_",value:function(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&v.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=v.setTimeout(this.monitorCurrentTime_.bind(this),250)}},{key:"checkCurrentTime_",value:function(){if(this.tech_.seeking()&&this.fixesBadSeeks_())return this.consecutiveUpdates=0,void(this.lastRecordedTime=this.tech_.currentTime());if(!this.tech_.paused()&&!this.tech_.seeking()){var e=this.tech_.currentTime(),t=this.tech_.buffered();if(this.lastRecordedTime===e&&(!t.length||e+.1>=t.end(t.length-1)))return this.techWaiting_();5<=this.consecutiveUpdates&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e)}}},{key:"cancelTimer_",value:function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null}},{key:"fixesBadSeeks_",value:function(){if(!this.tech_.seeking())return!1;var e=this.seekable(),t=this.tech_.currentTime(),i=void 0;return this.afterSeekableWindow_(e,t,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(i=e.end(e.length-1)),this.beforeSeekableWindow_(e,t)&&(i=e.start(0)+.1),"undefined"!=typeof i&&(this.logger_("Trying to seek outside of seekable at time "+t+" with seekable range "+Sl(e)+". Seeking to "+i+"."),this.seekTo(i),!0)}},{key:"waiting_",value:function(){if(!this.techWaiting_()){var e=this.tech_.currentTime(),t=this.tech_.buffered(),i=bl(t,e);return i.length&&e+3<=i.end(0)?(this.cancelTimer_(),this.seekTo(e),this.logger_("Stopped at "+e+" while inside a buffered region ["+i.start(0)+" -> "+i.end(0)+"]. Attempting to resume playback by seeking to the current time."),void this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})):void 0}}},{key:"techWaiting_",value:function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return!0;if(this.tech_.seeking()||null!==this.timer_)return!0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.seekTo(i),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}var n=this.tech_.buffered(),r=Tl(n,t);if(this.videoUnderflow_(r,n,t))return this.cancelTimer_(),this.seekTo(t),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;if(0<r.length){var a=r.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+a+", seeking to "+r.start(0)),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*a,t),!0}return!1}},{key:"afterSeekableWindow_",value:function(e,t,i,n){var r=3<arguments.length&&void 0!==n&&n;if(!e.length)return!1;var a=e.end(e.length-1)+.1;return!i.endList&&r&&(a=e.end(e.length-1)+3*i.targetDuration),a<t}},{key:"beforeSeekableWindow_",value:function(e,t){return!!(e.length&&0<e.start(0)&&t<e.start(0)-.1)}},{key:"videoUnderflow_",value:function(e,t,i){if(0===e.length){var n=this.gapFromVideoUnderflow_(t,i);if(n)return this.logger_("Encountered a gap in video from "+n.start+" to "+n.end+". Seeking to current time "+i),!0}return!1}},{key:"skipTheGap_",value:function(e){var t=this.tech_.buffered(),i=this.tech_.currentTime(),n=Tl(t,i);this.cancelTimer_(),0!==n.length&&i===e&&(this.logger_("skipTheGap_:","currentTime:",i,"scheduled currentTime:",e,"nextRange start:",n.start(0)),this.seekTo(n.start(0)+1/30),this.tech_.trigger({type:"usage",name:"hls-gap-skip"}))}},{key:"gapFromVideoUnderflow_",value:function(e,t){for(var i=function(e){if(e.length<2)return fs.createTimeRanges();for(var t=[],i=1;i<e.length;i++){var n=e.end(i-1),r=e.start(i);t.push([n,r])}return fs.createTimeRanges(t)}(e),n=0;n<i.length;n++){var r=i.start(n),a=i.end(n);if(t-r<4&&2<t-r)return{start:r,end:a}}return null}}]),rh);function rh(e){var t=this;Mu(this,rh),this.tech_=e.tech,this.seekable=e.seekable,this.seekTo=e.seekTo,this.allowSeeksWithinUnsafeLiveWindow=e.allowSeeksWithinUnsafeLiveWindow,this.media=e.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.timer_=null,this.checkCurrentTimeTimeout_=null,this.logger_=mc("PlaybackWatcher"),this.logger_("initialize");function i(){return t.monitorCurrentTime_()}function n(){return t.techWaiting_()}function r(){return t.cancelTimer_()}function a(){return t.fixesBadSeeks_()}this.tech_.on("seekablechanged",a),this.tech_.on("waiting",n),this.tech_.on(ih,r),this.tech_.on("canplay",i),this.dispose=function(){t.logger_("dispose"),t.tech_.off("seekablechanged",a),t.tech_.off("waiting",n),t.tech_.off(ih,r),t.tech_.off("canplay",i),t.checkCurrentTimeTimeout_&&v.clearTimeout(t.checkCurrentTimeTimeout_),t.cancelTimer_()}}function ah(e){!function t(i,e){var n=0,r=0,a=fs.mergeOptions(sh,e);i.ready(function(){i.trigger({type:"usage",name:"hls-error-reload-initialized"})});function s(){r&&i.currentTime(r)}function o(e){null!=e&&(r=i.duration()!==1/0&&i.currentTime()||0,i.one("loadedmetadata",s),i.src(e),i.trigger({type:"usage",name:"hls-error-reload"}),i.play())}function u(){if(Date.now()-n<1e3*a.errorInterval)i.trigger({type:"usage",name:"hls-error-reload-canceled"});else{if(a.getSource&&"function"==typeof a.getSource)return n=Date.now(),a.getSource.call(i,o);fs.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}}function l(){i.off("loadedmetadata",s),i.off("error",u),i.off("dispose",l)}i.on("error",u),i.on("dispose",l),i.reloadSourceOnError=function(e){l(),t(i,e)}}(this,e)}var sh={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_)}};fs.use("*",function(t){return{setSource:function(e,t){t(null,e)},setCurrentTime:function(e){return t.vhs&&t.currentSource().src===t.vhs.source_.src&&t.vhs.setCurrentTime(e),e},play:function(){t.vhs&&t.currentSource().src===t.vhs.source_.src&&t.vhs.setCurrentTime(t.tech_.currentTime())}}});var oh={PlaylistLoader:Ku,Playlist:Ll,Decrypter:xu,AsyncStream:Pu,decrypt:Ou,utils:Dl,STANDARD_PLAYLIST_SELECTOR:function(){return function(e,t,i,n,r){var a=e.playlists.map(function(e){var t,i;return t=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height,{bandwidth:e.attributes.BANDWIDTH||v.Number.MAX_VALUE,width:t,height:i,playlist:e}});Ec(a,function(e,t){return e.bandwidth-t.bandwidth});var s=(a=a.filter(function(e){return!Ll.isIncompatible(e.playlist)})).filter(function(e){return Ll.isEnabled(e.playlist)});s.length||(s=a.filter(function(e){return!Ll.isDisabled(e.playlist)}));var o=s.filter(function(e){return e.bandwidth*Pc.BANDWIDTH_VARIANCE<t}),u=o[o.length-1],l=o.filter(function(e){return e.bandwidth===u.bandwidth})[0];if(!1===r){var c=l||s[0]||a[0];return c?c.playlist:null}var h=o.filter(function(e){return e.width&&e.height});Ec(h,function(e,t){return e.width-t.width});var d=h.filter(function(e){return e.width===i&&e.height===n});u=d[d.length-1];var p=d.filter(function(e){return e.bandwidth===u.bandwidth})[0],f=void 0,m=void 0,g=void 0;p||(m=(f=h.filter(function(e){return e.width>i||e.height>n})).filter(function(e){return e.width===f[0].width&&e.height===f[0].height}),u=m[m.length-1],g=m.filter(function(e){return e.bandwidth===u.bandwidth})[0]);var y=g||p||l||s[0]||a[0];return y?y.playlist:null}(this.playlists.master,this.systemBandwidth,parseInt(Cc(this.tech_.el(),"width"),10),parseInt(Cc(this.tech_.el(),"height"),10),this.limitRenditionByPlayerDimensions)},INITIAL_PLAYLIST_SELECTOR:function(){var e=this.playlists.master.playlists.filter(Ll.isEnabled);return Ec(e,function(e,t){return wc(e,t)}),e.filter(function(e){return $l(e.attributes.CODECS).videoCodec})[0]||null},comparePlaylistBandwidth:wc,comparePlaylistResolution:function(e,t){var i=void 0,n=void 0;return e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width&&(i=e.attributes.RESOLUTION.width),i=i||v.Number.MAX_VALUE,t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width&&(n=t.attributes.RESOLUTION.width),i===(n=n||v.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:ll()};["GOAL_BUFFER_LENGTH","MAX_GOAL_BUFFER_LENGTH","GOAL_BUFFER_LENGTH_RATE","BUFFER_LOW_WATER_LINE","MAX_BUFFER_LOW_WATER_LINE","BUFFER_LOW_WATER_LINE_RATE","BANDWIDTH_VARIANCE"].forEach(function(t){Object.defineProperty(oh,t,{get:function(){return fs.log.warn("using Hls."+t+" is UNSAFE be sure you know what you are doing"),Pc[t]},set:function(e){fs.log.warn("using Hls."+t+" is UNSAFE be sure you know what you are doing"),"number"!=typeof e||e<0?fs.log.warn("value of Hls."+t+" must be greater than or equal to 0"):Pc[t]=e}})});function uh(e){return/^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i.test(e)?"hls":/^application\/dash\+xml/i.test(e)?"dash":null}function lh(e,t){for(var i=t.media(),n=-1,r=0;r<e.length;r++)if(e[r].id===i.uri){n=r;break}e.selectedIndex_=n,e.trigger({selectedIndex:n,type:"change"})}var ch="videojs-vhs";oh.canPlaySource=function(){return fs.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};function hh(e){if("dash"===e.options_.sourceType){var t=fs.players[e.tech_.options_.playerId];if(t.eme){var i=function(e,t,i){if(!e)return e;var n={};for(var r in e)n[r]={audioContentType:'audio/mp4; codecs="'+i.attributes.CODECS+'"',videoContentType:'video/mp4; codecs="'+t.attributes.CODECS+'"'},t.contentProtection&&t.contentProtection[r]&&t.contentProtection[r].pssh&&(n[r].pssh=t.contentProtection[r].pssh),"string"==typeof e[r]&&(n[r].url=e[r]);return fs.mergeOptions(e,n)}(e.source_.keySystems,e.playlists.media(),e.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader.media());i&&(t.currentSource().keySystems=i,t.eme.initializeMediaKeys&&t.eme.initializeMediaKeys())}}}function dh(){if(!window.localStorage)return null;var e=window.localStorage.getItem(ch);if(!e)return null;try{return JSON.parse(e)}catch(e){return null}}oh.supportsNativeHls=function(){var t=h.createElement("video");if(!fs.getTech("Html5").isSupported())return!1;return["application/vnd.apple.mpegurl","audio/mpegurl","audio/x-mpegurl","application/x-mpegurl","video/x-mpegurl","video/mpegurl","application/mpegurl"].some(function(e){return/maybe|probably/i.test(t.canPlayType(e))})}(),oh.supportsNativeDash=!!fs.getTech("Html5").isSupported()&&/maybe|probably/i.test(h.createElement("video").canPlayType("application/dash+xml")),oh.supportsTypeNatively=function(e){return"hls"===e?oh.supportsNativeHls:"dash"===e&&oh.supportsNativeDash},oh.isSupported=function(){return fs.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};var ph=fs.getComponent("Component"),fh=(ju(mh,ph),Nu(mh,[{key:"setOptions_",value:function(){var t=this;if(this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.handleManifestRedirects=this.options_.handleManifestRedirects||!1,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.smoothQualityChange=this.options_.smoothQualityChange||!1,this.options_.useBandwidthFromLocalStorage="undefined"!=typeof this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,"number"!=typeof this.options_.blacklistDuration&&(this.options_.blacklistDuration=300),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage){var e=dh();e&&e.bandwidth&&(this.options_.bandwidth=e.bandwidth,this.tech_.trigger({type:"usage",name:"hls-bandwidth-from-local-storage"})),e&&e.throughput&&(this.options_.throughput=e.throughput,this.tech_.trigger({type:"usage",name:"hls-throughput-from-local-storage"}))}"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=Pc.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===Pc.INITIAL_BANDWIDTH,["withCredentials","limitRenditionByPlayerDimensions","bandwidth","smoothQualityChange","customTagParsers","customTagMappers","handleManifestRedirects","cacheEncryptionKeys"].forEach(function(e){"undefined"!=typeof t.source_[e]&&(t.options_[e]=t.source_[e])}),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions}},{key:"src",value:function(e,t){var i=this;e&&(this.setOptions_(),this.options_.url=this.source_.src,this.options_.tech=this.tech_,this.options_.externHls=oh,this.options_.sourceType=uh(t),this.options_.seekTo=function(e){i.tech_.setCurrentTime(e),i.setCurrentTime(e)},this.masterPlaylistController_=new Zc(this.options_),this.playbackWatcher_=new nh(fs.mergeOptions(this.options_,{seekable:function(){return i.seekable()},media:function(){return i.masterPlaylistController_.media()}})),this.masterPlaylistController_.on("error",function(){fs.players[i.tech_.options_.playerId].error(i.masterPlaylistController_.error)}),this.masterPlaylistController_.selectPlaylist=this.selectPlaylist?this.selectPlaylist.bind(this):oh.STANDARD_PLAYLIST_SELECTOR.bind(this),this.masterPlaylistController_.selectInitialPlaylist=oh.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.masterPlaylistController_.masterPlaylistLoader_,this.mediaSource=this.masterPlaylistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get:function(){return this.masterPlaylistController_.selectPlaylist},set:function(e){this.masterPlaylistController_.selectPlaylist=e.bind(this)}},throughput:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.throughput.rate},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.throughput.rate=e,this.masterPlaylistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.bandwidth},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.bandwidth=e,this.masterPlaylistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get:function(){var e=1/(this.bandwidth||1),t=void 0;return t=0<this.throughput?1/this.throughput:0,Math.floor(1/(e+t))},set:function(){fs.log.error('The "systemBandwidth" property is read-only')}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return i.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return i.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return i.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return i.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return i.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return i.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return i.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return i.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},buffered:{get:function(){return kl(i.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return i.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return i.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return i.tech_.name_},enumerable:!0},duration:{get:function(){return i.tech_.duration()},enumerable:!0},master:{get:function(){return i.playlists.master},enumerable:!0},playerDimensions:{get:function(){return i.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return kl(i.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return i.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",function(){i.options_.useBandwidthFromLocalStorage&&function(e){if(window.localStorage){var t=dh();t=t?fs.mergeOptions(t,e):e;try{window.localStorage.setItem(ch,JSON.stringify(t))}catch(e){return}}}({bandwidth:i.bandwidth,throughput:Math.round(i.throughput)})}),this.masterPlaylistController_.on("selectedinitialmedia",function(){!function(i){var e=i.playlists;i.representations=function(){return e.master.playlists.filter(function(e){return!al(e)}).map(function(e,t){return new th(i,e,e.uri)})}}(i),hh(i)}),this.on(this.masterPlaylistController_,"progress",function(){this.tech_.trigger("progress")}),this.tech_.ready(function(){return i.setupQualityLevels_()}),this.tech_.el()&&this.tech_.src(fs.URL.createObjectURL(this.masterPlaylistController_.mediaSource)))}},{key:"setupQualityLevels_",value:function(){var e=this,t=fs.players[this.tech_.options_.playerId];t&&t.qualityLevels&&(this.qualityLevels_=t.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",function(){!function(t,e){e.representations().forEach(function(e){t.addQualityLevel(e)}),lh(t,e.playlists)}(e.qualityLevels_,e)}),this.playlists.on("mediachange",function(){lh(e.qualityLevels_,e.playlists)}))}},{key:"play",value:function(){this.masterPlaylistController_.play()}},{key:"setCurrentTime",value:function(e){this.masterPlaylistController_.setCurrentTime(e)}},{key:"duration",value:function(){return this.masterPlaylistController_.duration()}},{key:"seekable",value:function(){return this.masterPlaylistController_.seekable()}},{key:"dispose",value:function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.hls&&delete this.tech_.hls,function e(t,i,n){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,i);if(void 0===r){var a=Object.getPrototypeOf(t);return null===a?void 0:e(a,i,n)}if("value"in r)return r.value;var s=r.get;return void 0!==s?s.call(n):void 0}(mh.prototype.__proto__||Object.getPrototypeOf(mh.prototype),"dispose",this).call(this)}},{key:"convertToProgramTime",value:function(e,t){return yl({playlist:this.masterPlaylistController_.media(),time:e,callback:t})}},{key:"seekToProgramTime",value:function(e,t,i,n){var r=!(2<arguments.length&&void 0!==i)||i,a=3<arguments.length&&void 0!==n?n:2;return vl({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:a,pauseAfterSeek:r,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})}}]),mh);function mh(e,t,i){Mu(this,mh);var n=Fu(this,(mh.__proto__||Object.getPrototypeOf(mh)).call(this,t,i.hls));if(t.options_&&t.options_.playerId){var r=fs(t.options_.playerId);r.hasOwnProperty("hls")||Object.defineProperty(r,"hls",{get:function(){return fs.log.warn("player.hls is deprecated. Use player.tech().hls instead."),t.trigger({type:"usage",name:"hls-player-access"}),n},configurable:!0}),r.vhs=n,(r.dash=n).player_=r}if(n.tech_=t,n.source_=e,n.stats={},n.setOptions_(),n.options_.overrideNative&&t.overrideNativeAudioTracks&&t.overrideNativeVideoTracks)t.overrideNativeAudioTracks(!0),t.overrideNativeVideoTracks(!0);else if(n.options_.overrideNative&&(t.featuresNativeVideoTracks||t.featuresNativeAudioTracks))throw new Error("Overriding native HLS requires emulated tracks. See https://git.io/vMpjB");return n.on(h,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],function(e){var t=h.fullscreenElement||h.webkitFullscreenElement||h.mozFullScreenElement||h.msFullscreenElement;t&&t.contains(n.tech_.el())&&n.masterPlaylistController_.smoothQualityChange_()}),n.on(n.tech_,"seeking",function(){0===this.tech_.currentTime()&&this.tech_.player_.loop()&&this.setCurrentTime(0)}),n.on(n.tech_,"error",function(){this.masterPlaylistController_&&this.masterPlaylistController_.pauseLoading()}),n.on(n.tech_,"play",n.play),n}var gh={name:"videojs-http-streaming",VERSION:"1.10.6",canHandleSource:function(e,t){var i=fs.mergeOptions(fs.options,1<arguments.length&&void 0!==t?t:{});return gh.canPlayType(e.type,i)},handleSource:function(e,t,i){var n=fs.mergeOptions(fs.options,2<arguments.length&&void 0!==i?i:{});return t.hls=new fh(e,t,n),t.hls.xhr=ll(),t.hls.src(e.src,e.type),t.hls},canPlayType:function(e,t){var i=fs.mergeOptions(fs.options,1<arguments.length&&void 0!==t?t:{}).hls.overrideNative,n=uh(e);return n&&(!oh.supportsTypeNatively(n)||i)?"maybe":""}};return"undefined"!=typeof fs.MediaSource&&"undefined"!=typeof fs.URL||(fs.MediaSource=sc,fs.URL=oc),sc.supportsNativeMediaSources()&&fs.getTech("Html5").registerSourceHandler(gh,0),fs.HlsHandler=fh,fs.HlsSourceHandler=gh,fs.Hls=oh,fs.use||fs.registerComponent("Hls",oh),fs.options.hls=fs.options.hls||{},fs.registerPlugin?fs.registerPlugin("reloadSourceOnError",ah):fs.plugin("reloadSourceOnError",ah),fs}); \ No newline at end of file
diff --git a/assets/js/videojs-vtt-thumbnails.min.js b/assets/js/videojs-vtt-thumbnails.min.js
index e1efca62..be86a201 100644
--- a/assets/js/videojs-vtt-thumbnails.min.js
+++ b/assets/js/videojs-vtt-thumbnails.min.js
@@ -1,7 +1,7 @@
/**
* videojs-vtt-thumbnails
* @version 0.0.13
- * @copyright 2019 Chris Boustead <chris@forgemotion.com>
+ * @copyright 2020 Chris Boustead <chris@forgemotion.com>
* @license MIT
*/
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],e):t.videojsVttThumbnails=e(t.videojs)}(this,function(i){"use strict";i=i&&i.hasOwnProperty("default")?i.default:i;!function(){function l(t){this.value=t}function t(i){var o,n;function a(t,e){try{var r=i[t](e),s=r.value;s instanceof l?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):u(r.done?"return":"normal",r.value)}catch(t){u("throw",t)}}function u(t,e){switch(t){case"return":o.resolve({value:e,done:!0});break;case"throw":o.reject(e);break;default:o.resolve({value:e,done:!1})}(o=o.next)?a(o.key,o.arg):n=null}this._invoke=function(s,i){return new Promise(function(t,e){var r={key:s,arg:i,resolve:t,reject:e,next:null};n?n=n.next=r:(o=n=r,a(s,i))})},"function"!=typeof i.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(t.prototype[Symbol.asyncIterator]=function(){return this}),t.prototype.next=function(t){return this._invoke("next",t)},t.prototype.throw=function(t){return this._invoke("throw",t)},t.prototype.return=function(t){return this._invoke("return",t)}}();var o={},n={},t=i.registerPlugin||i.plugin,e=function(r){var s=this;this.ready(function(){var t,e;t=s,e=i.mergeOptions(o,r),t.addClass("vjs-vtt-thumbnails"),t.vttThumbnails=new a(t,e)})},a=function(){function r(t,e){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),this.player=t,this.options=e,this.listenForDurationChange(),this.initializeThumbnails(),this.registeredEvents={},this}return r.prototype.src=function(t){this.resetPlugin(),this.options.src=t,this.initializeThumbnails()},r.prototype.detach=function(){this.resetPlugin()},r.prototype.resetPlugin=function(){this.thumbnailHolder&&this.thumbnailHolder.parentNode.removeChild(this.thumbnailHolder),this.progressBar&&this.progressBar.removeEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar&&this.progressBar.removeEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave),this.progressBar&&this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove),delete this.registeredEvents.progressBarMouseEnter,delete this.registeredEvents.progressBarMouseLeave,delete this.registeredEvents.progressBarMouseMove,delete this.progressBar,delete this.vttData,delete this.thumbnailHolder,delete this.lastStyle},r.prototype.listenForDurationChange=function(){this.player.on("durationchange",function(){})},r.prototype.initializeThumbnails=function(){var e=this;if(this.options.src){var t=this.getBaseUrl(),r=this.getFullyQualifiedUrl(this.options.src,t);this.getVttFile(r).then(function(t){e.vttData=e.processVtt(t),e.setupThumbnailElement()})}},r.prototype.getBaseUrl=function(){return[window.location.protocol,"//",window.location.hostname,window.location.port?":"+window.location.port:"",window.location.pathname].join("").split(/([^\/]*)$/gi).shift()},r.prototype.getVttFile=function(s){var i=this;return new Promise(function(t,e){var r=new XMLHttpRequest;r.data={resolve:t},r.addEventListener("load",i.vttFileLoaded),r.open("GET",s),r.send()})},r.prototype.vttFileLoaded=function(){this.data.resolve(this.responseText)},r.prototype.setupThumbnailElement=function(t){var e=this;this.progressBar=this.player.$(".vjs-progress-control");var r=document.createElement("div");r.setAttribute("class","vjs-vtt-thumbnail-display"),this.progressBar.appendChild(r),this.thumbnailHolder=r,this.registeredEvents.progressBarMouseEnter=function(){return e.onBarMouseenter()},this.registeredEvents.progressBarMouseLeave=function(){return e.onBarMouseleave()},this.progressBar.addEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar.addEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave)},r.prototype.onBarMouseenter=function(){var e=this;this.mouseMoveCallback=function(t){e.onBarMousemove(t)},this.registeredEvents.progressBarMouseMove=this.mouseMoveCallback,this.progressBar.addEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.showThumbnailHolder()},r.prototype.onBarMouseleave=function(){this.registeredEvents.progressBarMouseMove&&this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.hideThumbnailHolder()},r.prototype.getXCoord=function(t,e){var r=t.getBoundingClientRect(),s=document.documentElement;return e-(r.left+(window.pageXOffset||s.scrollLeft||0))},r.prototype.onBarMousemove=function(t){this.updateThumbnailStyle(this.getXCoord(this.progressBar,t.clientX),this.progressBar.offsetWidth)},r.prototype.getStyleForTime=function(t){for(var e=0;e<this.vttData.length;++e){var r=this.vttData[e];if(t>=r.start&&t<r.end){if(r.css.url&&!n[r.css.url]){var s=new Image;s.src=r.css.url,n[r.css.url]=s}return r.css}}},r.prototype.showThumbnailHolder=function(){this.thumbnailHolder.style.opacity="1"},r.prototype.hideThumbnailHolder=function(){this.thumbnailHolder.style.opacity="0"},r.prototype.updateThumbnailStyle=function(t,e){var r=(1-(e-t)/e)*this.player.duration(),s=this.getStyleForTime(r);if(!s)return this.hideThumbnailHolder();var i=(1-(e-t)/e)*e;if(this.thumbnailHolder.style.transform="translateX("+i+"px)",this.thumbnailHolder.style.marginLeft="-"+parseInt(s.width)/2+"px",!this.lastStyle||this.lastStyle!==s)for(var o in this.lastStyle=s)s.hasOwnProperty(o)&&(this.thumbnailHolder.style[o]=s[o])},r.prototype.processVtt=function(t){var a=this,u=[];return t.split(/[\r\n][\r\n]/i).forEach(function(t){if(t.match(/([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?( ?--> ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi)){var e=t.split(/[\r\n]/i),r=e[0].split(/ ?--> ?/i),s=r[0],i=r[1],o=e[1],n=a.getVttCss(o);u.push({start:a.getSecondsFromTimestamp(s),end:a.getSecondsFromTimestamp(i),css:n})}}),u},r.prototype.getFullyQualifiedUrl=function(t,e){return 0<=t.indexOf("//")?t:0===e.indexOf("//")?[e.replace(/\/$/gi,""),this.trim(t,"/")].join("/"):0<e.indexOf("//")?[this.trim(e,"/"),this.trim(t,"/")].join("/"):t},r.prototype.getPropsFromDef=function(t){var e=t.split(/#xywh=/i),r=e[0],s=e[1].match(/[0-9]+/gi);return{x:s[0],y:s[1],w:s[2],h:s[3],image:r}},r.prototype.getVttCss=function(t){var e={},r=void 0;if(r=0<=this.options.src.indexOf("//")?this.options.src.split(/([^\/]*)$/gi).shift():this.getBaseUrl()+this.options.src.split(/([^\/]*)$/gi).shift(),!(t=this.getFullyQualifiedUrl(t,r)).match(/#xywh=/i))return e.background='url("'+t+'")',e;var s=this.getPropsFromDef(t);return e.background='url("'+s.image+'") no-repeat -'+s.x+"px -"+s.y+"px",e.width=s.w+"px",e.height=s.h+"px",e.url=s.image,e},r.prototype.doconstructTimestamp=function(t){var e=t.split("."),r=e[0].split(":");return{milliseconds:parseInt(e[1])||0,seconds:parseInt(r.pop())||0,minutes:parseInt(r.pop())||0,hours:parseInt(r.pop())||0}},r.prototype.getSecondsFromTimestamp=function(t){var e=this.doconstructTimestamp(t);return parseInt(3600*e.hours+60*e.minutes+e.seconds+e.milliseconds/1e3)},r.prototype.trim=function(t,e){var r=[" ","\n","\r","\t","\f","\v"," "," "," "," "," "," "," "," "," "," "," "," ","​","\u2028","\u2029"," "].join(""),s=0,i=0;for(t+="",e&&(r=(e+"").replace(/([[\]().?/*{}+$^:])/g,"$1")),s=t.length,i=0;i<s;i++)if(-1===r.indexOf(t.charAt(i))){t=t.substring(i);break}for(i=(s=t.length)-1;0<=i;i--)if(-1===r.indexOf(t.charAt(i))){t=t.substring(0,i+1);break}return-1===r.indexOf(t.charAt(0))?t:""},r}();return t("vttThumbnails",e),e.VERSION="0.0.13",e}); \ No newline at end of file
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e=e||self).videojsVttThumbnails=t(e.videojs)}(this,function(i){"use strict";i=i&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i;function e(s){var r=this;this.ready(function(){var e,t;e=r,t=i.mergeOptions(n,s),e.addClass("vjs-vtt-thumbnails"),e.vttThumbnails=new a(e,t)})}var n={},o={},t=i.registerPlugin||i.plugin,a=function(){function e(e,t){return this.player=e,this.options=t,this.listenForDurationChange(),this.initializeThumbnails(),this.registeredEvents={},this}var t=e.prototype;return t.src=function(e){this.resetPlugin(),this.options.src=e,this.initializeThumbnails()},t.detach=function(){this.resetPlugin()},t.resetPlugin=function(){this.thumbnailHolder&&this.thumbnailHolder.parentNode.removeChild(this.thumbnailHolder),this.progressBar&&(this.progressBar.removeEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar.removeEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave),this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove)),delete this.registeredEvents.progressBarMouseEnter,delete this.registeredEvents.progressBarMouseLeave,delete this.registeredEvents.progressBarMouseMove,delete this.progressBar,delete this.vttData,delete this.thumbnailHolder,delete this.lastStyle},t.listenForDurationChange=function(){this.player.on("durationchange",function(){})},t.initializeThumbnails=function(){var e,t,s=this;this.options.src&&(e=this.getBaseUrl(),t=this.getFullyQualifiedUrl(this.options.src,e),this.getVttFile(t).then(function(e){s.vttData=s.processVtt(e),s.setupThumbnailElement()}))},t.getBaseUrl=function(){return[window.location.protocol,"//",window.location.hostname,window.location.port?":"+window.location.port:"",window.location.pathname].join("").split(/([^\/]*)$/gi).shift()},t.getVttFile=function(r){var i=this;return new Promise(function(e,t){var s=new XMLHttpRequest;s.data={resolve:e},s.addEventListener("load",i.vttFileLoaded),s.open("GET",r),s.overrideMimeType("text/plain; charset=utf-8"),s.send()})},t.vttFileLoaded=function(){this.data.resolve(this.responseText)},t.setupThumbnailElement=function(){var e=this,t=null;this.options.showTimestamp||(t=this.player.$(".vjs-mouse-display"));var s=document.createElement("div");s.setAttribute("class","vjs-vtt-thumbnail-display"),this.progressBar=this.player.$(".vjs-progress-control"),this.progressBar.appendChild(s),this.thumbnailHolder=s,t&&!this.options.showTimestamp&&t.classList.add("vjs-hidden"),this.registeredEvents.progressBarMouseEnter=function(){return e.onBarMouseenter()},this.registeredEvents.progressBarMouseLeave=function(){return e.onBarMouseleave()},this.progressBar.addEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar.addEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave)},t.onBarMouseenter=function(){var t=this;this.mouseMoveCallback=function(e){t.onBarMousemove(e)},this.registeredEvents.progressBarMouseMove=this.mouseMoveCallback,this.progressBar.addEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.showThumbnailHolder()},t.onBarMouseleave=function(){this.registeredEvents.progressBarMouseMove&&this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.hideThumbnailHolder()},t.getXCoord=function(e,t){var s=e.getBoundingClientRect(),r=document.documentElement;return t-(s.left+(window.pageXOffset||r.scrollLeft||0))},t.onBarMousemove=function(e){this.updateThumbnailStyle(i.dom.getPointerPosition(this.progressBar,e).x,this.progressBar.offsetWidth)},t.getStyleForTime=function(e){for(var t=0;t<this.vttData.length;++t){var s,r=this.vttData[t];if(e>=r.start&&e<r.end)return r.css.url&&!o[r.css.url]&&((s=new Image).src=r.css.url,o[r.css.url]=s),r.css}},t.showThumbnailHolder=function(){this.thumbnailHolder.style.opacity="1"},t.hideThumbnailHolder=function(){this.thumbnailHolder.style.opacity="0"},t.updateThumbnailStyle=function(e,t){var s=e*this.player.duration(),r=this.getStyleForTime(s);if(!r)return this.hideThumbnailHolder();var i=e*t,n=parseInt(r.width,10),o=n>>1,a=t-(i+o),l=i-o;if(0<l&&0<a?this.thumbnailHolder.style.transform="translateX("+(i-o)+"px)":l<=0?this.thumbnailHolder.style.transform="translateX(0px)":a<=0&&(this.thumbnailHolder.style.transform="translateX("+(t-n)+"px)"),!this.lastStyle||this.lastStyle!==r)for(var u in this.lastStyle=r)r.hasOwnProperty(u)&&(this.thumbnailHolder.style[u]=r[u])},t.processVtt=function(e){var a=this,l=[];return e.split(/[\r\n][\r\n]/i).forEach(function(e){var t,s,r,i,n,o;e.match(/([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?( ?--> ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi)&&(r=(s=(t=e.split(/[\r\n]/i))[0].split(/ ?--> ?/i))[0],i=s[1],n=t[1],o=a.getVttCss(n),l.push({start:a.getSecondsFromTimestamp(r),end:a.getSecondsFromTimestamp(i),css:o}))}),l},t.getFullyQualifiedUrl=function(e,t){return 0<=e.indexOf("//")?e:0===t.indexOf("//")?[t.replace(/\/$/gi,""),this.trim(e,"/")].join("/"):0<t.indexOf("//")?[this.trim(t,"/"),this.trim(e,"/")].join("/"):e},t.getPropsFromDef=function(e){var t=e.split(/#xywh=/i),s=t[0],r=t[1].match(/[0-9]+/gi);return{x:r[0],y:r[1],w:r[2],h:r[3],image:s}},t.getVttCss=function(e){var t={},s=0<=this.options.src.indexOf("//")?this.options.src.split(/([^\/]*)$/gi).shift():this.getBaseUrl()+this.options.src.split(/([^\/]*)$/gi).shift();if(!(e=this.getFullyQualifiedUrl(e,s)).match(/#xywh=/i))return t.background='url("'+e+'")',t;var r=this.getPropsFromDef(e);return t.background='url("'+r.image+'") no-repeat -'+r.x+"px -"+r.y+"px",t.width=r.w+"px",t.height=r.h+"px",t.url=r.image,t},t.deconstructTimestamp=function(e){var t=e.split("."),s=t[0].split(":");return{milliseconds:parseInt(t[1],10)||0,seconds:parseInt(s.pop(),10)||0,minutes:parseInt(s.pop(),10)||0,hours:parseInt(s.pop(),10)||0}},t.getSecondsFromTimestamp=function(e){var t=this.deconstructTimestamp(e);return parseInt(3600*t.hours+60*t.minutes+t.seconds+t.milliseconds/1e3,10)},t.trim=function(e,t){var s=[" ","\n","\r","\t","\f","\v"," "," "," "," "," "," "," "," "," "," "," "," ","​","\u2028","\u2029"," "].join(""),r=0,i=0;for(e+="",t&&(s=(t+"").replace(/([[\]().?/*{}+$^:])/g,"$1")),r=e.length,i=0;i<r;i++)if(-1===s.indexOf(e.charAt(i))){e=e.substring(i);break}for(i=(r=e.length)-1;0<=i;i--)if(-1===s.indexOf(e.charAt(i))){e=e.substring(0,i+1);break}return-1===s.indexOf(e.charAt(0))?e:""},e}();return t("vttThumbnails",e),e.VERSION="0.0.13",e}); \ No newline at end of file
diff --git a/assets/js/watch.js b/assets/js/watch.js
index a26cb505..e9ad2ddc 100644
--- a/assets/js/watch.js
+++ b/assets/js/watch.js
@@ -1,3 +1,5 @@
+var video_data = JSON.parse(document.getElementById('video_data').innerHTML);
+
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g, function (a, b) {
var r = o[b];
diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js
index 1e88fa27..ba741974 100644
--- a/assets/js/watched_widget.js
+++ b/assets/js/watched_widget.js
@@ -1,3 +1,5 @@
+var watched_data = JSON.parse(document.getElementById('watched_data').innerHTML);
+
function mark_watched(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none';
diff --git a/config/migrate-scripts/migrate-db-1eca969.sh b/config/migrate-scripts/migrate-db-1eca969.sh
new file mode 100755
index 00000000..f840d924
--- /dev/null
+++ b/config/migrate-scripts/migrate-db-1eca969.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN title CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN views CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN likes CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN dislikes CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN wilson_score CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN published CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN description CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN language CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN author CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN ucid CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN allowed_regions CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN is_family_friendly CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN genre CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN genre_url CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN license CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN sub_count_text CASCADE"
+psql invidious kemal -c "ALTER TABLE videos DROP COLUMN author_thumbnail CASCADE"
diff --git a/config/sql/playlists.sql b/config/sql/playlists.sql
index 46ff30ec..468496cb 100644
--- a/config/sql/playlists.sql
+++ b/config/sql/playlists.sql
@@ -1,3 +1,14 @@
+-- Type: public.privacy
+
+-- DROP TYPE public.privacy;
+
+CREATE TYPE public.privacy AS ENUM
+(
+ 'Public',
+ 'Unlisted',
+ 'Private'
+);
+
-- Table: public.playlists
-- DROP TABLE public.playlists;
diff --git a/config/sql/privacy.sql b/config/sql/privacy.sql
deleted file mode 100644
index 4356813e..00000000
--- a/config/sql/privacy.sql
+++ /dev/null
@@ -1,10 +0,0 @@
--- Type: public.privacy
-
--- DROP TYPE public.privacy;
-
-CREATE TYPE public.privacy AS ENUM
-(
- 'Public',
- 'Unlisted',
- 'Private'
-);
diff --git a/config/sql/videos.sql b/config/sql/videos.sql
index 6ded01de..8def2f83 100644
--- a/config/sql/videos.sql
+++ b/config/sql/videos.sql
@@ -7,23 +7,6 @@ CREATE TABLE public.videos
id text NOT NULL,
info text,
updated timestamp with time zone,
- title text,
- views bigint,
- likes integer,
- dislikes integer,
- wilson_score double precision,
- published timestamp with time zone,
- description text,
- language text,
- author text,
- ucid text,
- allowed_regions text[],
- is_family_friendly boolean,
- genre text,
- genre_url text,
- license text,
- sub_count_text text,
- author_thumbnail text,
CONSTRAINT videos_pkey PRIMARY KEY (id)
);
diff --git a/docker-compose.yml b/docker-compose.yml
index 1486f013..bc292c53 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,14 +1,18 @@
version: '3'
services:
postgres:
- build:
- context: .
- dockerfile: docker/Dockerfile.postgres
+ image: postgres:10
restart: unless-stopped
volumes:
- postgresdata:/var/lib/postgresql/data
+ - ./config/sql:/config/sql
+ - ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
+ environment:
+ POSTGRES_DB: invidious
+ POSTGRES_PASSWORD: kemal
+ POSTGRES_USER: kemal
healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
+ test: ["CMD", "pg_isready", "-U", "postgres"]
invidious:
build:
context: .
@@ -16,6 +20,21 @@ services:
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
+ environment:
+ # Adapted from ./config/config.yml
+ INVIDIOUS_CONFIG: |
+ channel_threads: 1
+ check_tables: true
+ feed_threads: 1
+ db:
+ user: kemal
+ password: kemal
+ host: postgres
+ port: 5432
+ dbname: invidious
+ full_refresh: false
+ https_only: false
+ domain:
depends_on:
- postgres
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 0defb92b..96f844fe 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,34 +1,33 @@
-FROM alpine:edge
-RUN apk add --no-cache crystal shards libc-dev \
- yaml-dev libxml2-dev sqlite-dev zlib-dev curl && \
- curl -Lo /etc/apk/keys/omarroth.rsa.pub https://github.com/omarroth/boringssl-alpine/releases/download/1.1.0-r0/omarroth.rsa.pub && \
- curl -Lo boringssl-dev.apk https://github.com/omarroth/boringssl-alpine/releases/download/1.1.0-r0/boringssl-dev-1.1.0-r0.apk && \
- curl -Lo lsquic.apk https://github.com/omarroth/lsquic-alpine/releases/download/2.6.3-r0/lsquic-2.6.3-r0.apk && \
- apk update && \
- apk add boringssl-dev.apk lsquic.apk && \
- rm -rf /var/cache/apk/* boringssl-dev.apk lsquic.apk
+FROM crystallang/crystal:0.35.1-alpine AS builder
+RUN apk add --no-cache curl sqlite-static
WORKDIR /invidious
COPY ./shard.yml ./shard.yml
-RUN shards update && shards install
-RUN cp /usr/lib/libcrypto.a ./lib/lsquic/src/lsquic/ext/libcrypto.a && \
- cp /usr/lib/libssl.a ./lib/lsquic/src/lsquic/ext/libssl.a && \
- cp /usr/lib/liblsquic.a ./lib/lsquic/src/lsquic/ext/liblsquic.a
+RUN shards update && shards install && \
+ # TODO: Document build instructions
+ # See https://github.com/omarroth/boringssl-alpine/blob/master/APKBUILD,
+ # https://github.com/omarroth/lsquic-alpine/blob/master/APKBUILD,
+ # https://github.com/omarroth/lsquic.cr/issues/1#issuecomment-631610081
+ # for details building static lib
+ curl -Lo ./lib/lsquic/src/lsquic/ext/liblsquic.a https://omar.yt/lsquic/liblsquic-v2.18.1.a
COPY ./src/ ./src/
# TODO: .git folder is required for building – this is destructive.
# See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION.
COPY ./.git/ ./.git/
-RUN crystal build --release --warnings all --error-on-warnings \
- # TODO: Remove next line, see https://github.com/crystal-lang/crystal/issues/7946
- -Dmusl \
- ./src/invidious.cr
+RUN crystal build ./src/invidious.cr \
+ --static --warnings all \
+ --link-flags "-lxml2 -llzma"
+FROM alpine:latest
RUN apk add --no-cache librsvg ttf-opensans
+WORKDIR /invidious
RUN addgroup -g 1000 -S invidious && \
adduser -u 1000 -S invidious -G invidious
COPY ./assets/ ./assets/
-COPY ./config/config.yml ./config/config.yml
+COPY --chown=invidious ./config/config.yml ./config/config.yml
+RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml
COPY ./config/sql/ ./config/sql/
COPY ./locales/ ./locales/
-RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml
+COPY --from=builder /invidious/invidious .
+
USER invidious
CMD [ "/invidious/invidious" ]
diff --git a/docker/Dockerfile.postgres b/docker/Dockerfile.postgres
deleted file mode 100644
index 720bdff8..00000000
--- a/docker/Dockerfile.postgres
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM postgres:10
-
-ENV POSTGRES_USER postgres
-
-ADD ./config/sql /config/sql
-ADD ./docker/entrypoint.postgres.sh /entrypoint.sh
-
-ENTRYPOINT [ "/entrypoint.sh" ]
-CMD [ "postgres" ]
diff --git a/docker/entrypoint.postgres.sh b/docker/entrypoint.postgres.sh
deleted file mode 100755
index f5fce309..00000000
--- a/docker/entrypoint.postgres.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-
-CMD="$@"
-if [ ! -f /var/lib/postgresql/data/setupFinished ]; then
- echo "### first run - setting up invidious database"
- /usr/local/bin/docker-entrypoint.sh postgres &
- sleep 10
- until runuser -l postgres -c 'pg_isready' 2>/dev/null; do
- >&2 echo "### Postgres is unavailable - waiting"
- sleep 5
- done
- >&2 echo "### importing table schemas"
- su postgres -c 'createdb invidious'
- su postgres -c 'psql -c "CREATE USER kemal WITH PASSWORD '"'kemal'"'"'
- su postgres -c 'psql invidious kemal < config/sql/channels.sql'
- su postgres -c 'psql invidious kemal < config/sql/videos.sql'
- su postgres -c 'psql invidious kemal < config/sql/channel_videos.sql'
- su postgres -c 'psql invidious kemal < config/sql/users.sql'
- su postgres -c 'psql invidious kemal < config/sql/session_ids.sql'
- su postgres -c 'psql invidious kemal < config/sql/nonces.sql'
- su postgres -c 'psql invidious kemal < config/sql/annotations.sql'
- su postgres -c 'psql invidious kemal < config/sql/playlists.sql'
- su postgres -c 'psql invidious kemal < config/sql/playlist_videos.sql'
- su postgres -c 'psql invidious kemal < config/sql/privacy.sql'
- touch /var/lib/postgresql/data/setupFinished
- echo "### invidious database setup finished"
- exit
-fi
-
-echo "running postgres /usr/local/bin/docker-entrypoint.sh $CMD"
-exec /usr/local/bin/docker-entrypoint.sh $CMD
diff --git a/docker/init-invidious-db.sh b/docker/init-invidious-db.sh
new file mode 100755
index 00000000..3808e673
--- /dev/null
+++ b/docker/init-invidious-db.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -eou pipefail
+
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
+ CREATE USER postgres;
+EOSQL
+
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/channels.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/videos.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/channel_videos.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/users.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/session_ids.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/nonces.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/annotations.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/playlists.sql
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < config/sql/playlist_videos.sql
diff --git a/kubernetes/.gitignore b/kubernetes/.gitignore
new file mode 100644
index 00000000..0ad51707
--- /dev/null
+++ b/kubernetes/.gitignore
@@ -0,0 +1 @@
+/charts/*.tgz
diff --git a/kubernetes/Chart.lock b/kubernetes/Chart.lock
new file mode 100644
index 00000000..1799798b
--- /dev/null
+++ b/kubernetes/Chart.lock
@@ -0,0 +1,6 @@
+dependencies:
+- name: postgresql
+ repository: https://kubernetes-charts.storage.googleapis.com/
+ version: 8.3.0
+digest: sha256:1feec3c396cbf27573dc201831ccd3376a4a6b58b2e7618ce30a89b8f5d707fd
+generated: "2020-02-07T13:39:38.624846+01:00"
diff --git a/kubernetes/Chart.yaml b/kubernetes/Chart.yaml
new file mode 100644
index 00000000..bb0838ad
--- /dev/null
+++ b/kubernetes/Chart.yaml
@@ -0,0 +1,22 @@
+apiVersion: v2
+name: invidious
+description: Invidious is an alternative front-end to YouTube
+version: 1.1.0
+appVersion: 0.20.1
+keywords:
+- youtube
+- proxy
+- video
+- privacy
+home: https://invidio.us/
+icon: https://raw.githubusercontent.com/omarroth/invidious/05988c1c49851b7d0094fca16aeaf6382a7f64ab/assets/favicon-32x32.png
+sources:
+- https://github.com/omarroth/invidious
+maintainers:
+- name: Leon Klingele
+ email: mail@leonklingele.de
+dependencies:
+- name: postgresql
+ version: ~8.3.0
+ repository: "https://kubernetes-charts.storage.googleapis.com/"
+engine: gotpl
diff --git a/kubernetes/README.md b/kubernetes/README.md
new file mode 100644
index 00000000..35478f99
--- /dev/null
+++ b/kubernetes/README.md
@@ -0,0 +1,41 @@
+# Invidious Helm chart
+
+Easily deploy Invidious to Kubernetes.
+
+## Installing Helm chart
+
+```sh
+# Build Helm dependencies
+$ helm dep build
+
+# Add PostgreSQL init scripts
+$ kubectl create configmap invidious-postgresql-init \
+ --from-file=../config/sql/channels.sql \
+ --from-file=../config/sql/videos.sql \
+ --from-file=../config/sql/channel_videos.sql \
+ --from-file=../config/sql/users.sql \
+ --from-file=../config/sql/session_ids.sql \
+ --from-file=../config/sql/nonces.sql \
+ --from-file=../config/sql/annotations.sql \
+ --from-file=../config/sql/playlists.sql \
+ --from-file=../config/sql/playlist_videos.sql
+
+# Install Helm app to your Kubernetes cluster
+$ helm install invidious ./
+```
+
+## Upgrading
+
+```sh
+# Upgrading is easy, too!
+$ helm upgrade invidious ./
+```
+
+## Uninstall
+
+```sh
+# Get rid of everything (except database)
+$ helm delete invidious
+
+# To also delete the database, remove all invidious-postgresql PVCs
+```
diff --git a/kubernetes/templates/_helpers.tpl b/kubernetes/templates/_helpers.tpl
new file mode 100644
index 00000000..52158b78
--- /dev/null
+++ b/kubernetes/templates/_helpers.tpl
@@ -0,0 +1,16 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "invidious.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+*/}}
+{{- define "invidious.fullname" -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/kubernetes/templates/configmap.yaml b/kubernetes/templates/configmap.yaml
new file mode 100644
index 00000000..58542a31
--- /dev/null
+++ b/kubernetes/templates/configmap.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "invidious.fullname" . }}
+ labels:
+ app: {{ template "invidious.name" . }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ release: {{ .Release.Name }}
+data:
+ INVIDIOUS_CONFIG: |
+{{ toYaml .Values.config | indent 4 }}
diff --git a/kubernetes/templates/deployment.yaml b/kubernetes/templates/deployment.yaml
new file mode 100644
index 00000000..bb0b832f
--- /dev/null
+++ b/kubernetes/templates/deployment.yaml
@@ -0,0 +1,61 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ template "invidious.fullname" . }}
+ labels:
+ app: {{ template "invidious.name" . }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ release: {{ .Release.Name }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ template "invidious.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app: {{ template "invidious.name" . }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ release: {{ .Release.Name }}
+ spec:
+ securityContext:
+ runAsUser: {{ .Values.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.securityContext.fsGroup }}
+ initContainers:
+ - name: wait-for-postgresql
+ image: postgres
+ args:
+ - /bin/sh
+ - -c
+ - until pg_isready -h {{ .Values.config.db.host }} -p {{ .Values.config.db.port }} -U {{ .Values.config.db.user }}; do echo waiting for database; sleep 2; done;
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - containerPort: 3000
+ env:
+ - name: INVIDIOUS_CONFIG
+ valueFrom:
+ configMapKeyRef:
+ key: INVIDIOUS_CONFIG
+ name: {{ template "invidious.fullname" . }}
+ securityContext:
+ allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }}
+ capabilities:
+ drop:
+ - ALL
+ resources:
+{{ toYaml .Values.resources | indent 10 }}
+ readinessProbe:
+ httpGet:
+ port: 3000
+ path: /
+ livenessProbe:
+ httpGet:
+ port: 3000
+ path: /
+ initialDelaySeconds: 15
+ restartPolicy: Always
diff --git a/kubernetes/templates/hpa.yaml b/kubernetes/templates/hpa.yaml
new file mode 100644
index 00000000..c6fbefe2
--- /dev/null
+++ b/kubernetes/templates/hpa.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.autoscaling.enabled }}
+apiVersion: autoscaling/v1
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ template "invidious.fullname" . }}
+ labels:
+ app: {{ template "invidious.name" . }}
+ chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+ release: {{ .Release.Name }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ template "invidious.fullname" . }}
+ minReplicas: {{ .Values.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.autoscaling.maxReplicas }}
+ targetCPUUtilizationPercentage: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
+{{- end }}
diff --git a/kubernetes/templates/service.yaml b/kubernetes/templates/service.yaml
new file mode 100644
index 00000000..01454d4e
--- /dev/null
+++ b/kubernetes/templates/service.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "invidious.fullname" . }}
+ labels:
+ app: {{ template "invidious.name" . }}
+ chart: {{ .Chart.Name }}
+ release: {{ .Release.Name }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - name: http
+ port: {{ .Values.service.port }}
+ targetPort: 3000
+ selector:
+ app: {{ template "invidious.name" . }}
+ release: {{ .Release.Name }}
+{{- if .Values.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.service.loadBalancerIP }}
+{{- end }}
diff --git a/kubernetes/values.yaml b/kubernetes/values.yaml
new file mode 100644
index 00000000..4d037022
--- /dev/null
+++ b/kubernetes/values.yaml
@@ -0,0 +1,56 @@
+name: invidious
+
+image:
+ repository: omarroth/invidious
+ tag: latest
+ pullPolicy: Always
+
+replicaCount: 1
+
+autoscaling:
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 16
+ targetCPUUtilizationPercentage: 50
+
+service:
+ type: clusterIP
+ port: 3000
+ #loadBalancerIP:
+
+resources: {}
+ #requests:
+ # cpu: 100m
+ # memory: 64Mi
+ #limits:
+ # cpu: 800m
+ # memory: 512Mi
+
+securityContext:
+ allowPrivilegeEscalation: false
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+
+# See https://github.com/helm/charts/tree/master/stable/postgresql
+postgresql:
+ postgresqlUsername: kemal
+ postgresqlPassword: kemal
+ postgresqlDatabase: invidious
+ initdbUsername: kemal
+ initdbPassword: kemal
+ initdbScriptsConfigMap: invidious-postgresql-init
+
+# Adapted from ../config/config.yml
+config:
+ channel_threads: 1
+ feed_threads: 1
+ db:
+ user: kemal
+ password: kemal
+ host: invidious-postgresql
+ port: 5432
+ dbname: invidious
+ full_refresh: false
+ https_only: false
+ domain:
diff --git a/locales/ar.json b/locales/ar.json
index c580a2d5..12bcc199 100644
--- a/locales/ar.json
+++ b/locales/ar.json
@@ -333,4 +333,4 @@
"Playlists": "قوائم التشغيل",
"Community": "المجتمع",
"Current version: ": "الإصدار الحالي: "
-}
+} \ No newline at end of file
diff --git a/locales/de.json b/locales/de.json
index 2e214b76..b685a842 100644
--- a/locales/de.json
+++ b/locales/de.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` Abonnenten",
"`x` videos": "`x` Videos",
- "`x` playlists": "",
+ "`x` playlists": "`x` Wiedergabelisten",
"LIVE": "LIVE",
"Shared `x` ago": "Vor `x` geteilt",
"Unsubscribe": "Abbestellen",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "Javascript Lizenzinformationen anzeigen.",
"View privacy policy.": "Datenschutzerklärung einsehen.",
"Trending": "Trending",
- "Public": "",
+ "Public": "Öffentlich",
"Unlisted": "Nicht aufgeführt",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privat",
+ "View all playlists": "Alle Wiedergabelisten anzeigen",
+ "Updated `x` ago": "Aktualisiert `x` vor",
+ "Delete playlist `x`?": "Wiedergabeliste löschen `x`?",
+ "Delete playlist": "Wiedergabeliste löschen",
+ "Create playlist": "Wiedergabeliste erstellen",
+ "Title": "Titel",
+ "Playlist privacy": "Vertrauliche Wiedergabeliste",
+ "Editing playlist `x`": "Wiedergabeliste bearbeiten `x`",
"Watch on YouTube": "Video auf YouTube ansehen",
"Hide annotations": "Anmerkungen ausblenden",
"Show annotations": "Anmerkungen anzeigen",
diff --git a/locales/en-US.json b/locales/en-US.json
index b61515c9..acd2b667 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -8,7 +8,7 @@
"": "`x` videos"
},
"`x` playlists": {
- "(\\D|^)1(\\D|$)": "`x` playlist",
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` playlist",
"": "`x` playlists"
},
"LIVE": "LIVE",
@@ -177,7 +177,7 @@
"View YouTube comments": "View YouTube comments",
"View more comments on Reddit": "View more comments on Reddit",
"View `x` comments": {
- "(\\D|^)1(\\D|$)": "View `x` comment",
+ "([^.,0-9]|^)1([^.,0-9]|$)": "View `x` comment",
"": "View `x` comments"
},
"View Reddit comments": "View Reddit comments",
diff --git a/locales/eo.json b/locales/eo.json
index 07e3a2cf..ae640e37 100644
--- a/locales/eo.json
+++ b/locales/eo.json
@@ -1,13 +1,13 @@
{
"`x` subscribers": "`x` abonantoj",
- "`x` videos": "`x` videoj",
- "`x` playlists": "",
+ "`x` videos": "`x` filmetoj",
+ "`x` playlists": "`x` ludlistoj",
"LIVE": "NUNA",
"Shared `x` ago": "Konigita antaŭ `x`",
"Unsubscribe": "Malaboni",
"Subscribe": "Aboni",
- "View channel on YouTube": "Vidi kanalon en YouTube",
- "View playlist on YouTube": "Vidi ludliston en YouTube",
+ "View channel on YouTube": "Vidi kanalon en JuTubo",
+ "View playlist on YouTube": "Vidi ludliston en JuTubo",
"newest": "pli novaj",
"oldest": "pli malnovaj",
"popular": "popularaj",
@@ -25,7 +25,7 @@
"Import and Export Data": "Importi kaj Eksporti Datumojn",
"Import": "Importi",
"Import Invidious data": "Importi datumojn de Invidious",
- "Import YouTube subscriptions": "Importi abonojn de YouTube",
+ "Import YouTube subscriptions": "Importi abonojn de JuTubo",
"Import FreeTube subscriptions (.db)": "Importi abonojn de FreeTube (.db)",
"Import NewPipe subscriptions (.json)": "Importi abonojn de NewPipe (.json)",
"Import NewPipe data (.zip)": "Importi datumojn de NewPipe (.zip)",
@@ -35,7 +35,7 @@
"Export data as JSON": "Eksporti datumojn kiel JSON",
"Delete account?": "Ĉu forigi konton?",
"History": "Historio",
- "An alternative front-end to YouTube": "Alternativa fasado al YouTube",
+ "An alternative front-end to YouTube": "Alternativa fasado al JuTubo",
"JavaScript license information": "Ĝavoskripta licenca informo",
"source": "fonto",
"Log in": "Ensaluti",
@@ -55,18 +55,18 @@
"Always loop: ": "Ĉiam ripeti: ",
"Autoplay: ": "Aŭtomate ludi: ",
"Play next by default: ": "Ludi sekvan defaŭlte: ",
- "Autoplay next video: ": "Aŭtomate ludi sekvan videon: ",
+ "Autoplay next video: ": "Aŭtomate ludi sekvan filmeton: ",
"Listen by default: ": "Aŭskulti defaŭlte: ",
- "Proxy videos: ": "Ĉu uzi prokuran servilon por videoj? ",
+ "Proxy videos: ": "Ĉu uzi prokuran servilon por filmetojn? ",
"Default speed: ": "Defaŭlta rapido: ",
- "Preferred video quality: ": "Preferita videkvalito: ",
+ "Preferred video quality: ": "Preferita filmetkvalito: ",
"Player volume: ": "Ludila sonforteco: ",
"Default comments: ": "Defaŭltaj komentoj: ",
- "youtube": "youtube",
- "reddit": "reddit",
+ "youtube": "JuTubo",
+ "reddit": "Reddit",
"Default captions: ": "Defaŭltaj subtekstoj: ",
"Fallback captions: ": "Retrodefaŭltaj subtekstoj: ",
- "Show related videos: ": "Ĉu montri rilatajn videojn? ",
+ "Show related videos: ": "Ĉu montri rilatajn filmetojn? ",
"Show annotations by default: ": "Ĉu montri prinotojn defaŭlte? ",
"Visual preferences": "Vidaj preferoj",
"Player style: ": "Ludila stilo: ",
@@ -78,20 +78,20 @@
"Subscription preferences": "Abonaj agordoj",
"Show annotations by default for subscribed channels: ": "Ĉu montri prinotojn defaŭlte por abonitaj kanaloj? ",
"Redirect homepage to feed: ": "Alidirekti hejmpâgon al fluo: ",
- "Number of videos shown in feed: ": "Nombro da videoj montritaj en fluo: ",
- "Sort videos by: ": "Ordi videojn laŭ: ",
+ "Number of videos shown in feed: ": "Nombro da filmetoj montritaj en fluo: ",
+ "Sort videos by: ": "Ordi filmetojn per: ",
"published": "publikigo",
"published - reverse": "publitigo - renverse",
"alphabetically": "alfabete",
"alphabetically - reverse": "alfabete - renverse",
"channel name": "kanala nombro",
"channel name - reverse": "kanala nombro - renverse",
- "Only show latest video from channel: ": "Nur montri pli novan videon el kanalo: ",
- "Only show latest unwatched video from channel: ": "Nur montri pli novan malviditan videon el kanalo: ",
+ "Only show latest video from channel: ": "Nur montri pli novan filmeton el kanalo: ",
+ "Only show latest unwatched video from channel: ": "Nur montri pli novan malviditan filmeton el kanalo: ",
"Only show unwatched: ": "Nur montri malviditajn: ",
"Only show notifications (if there are any): ": "Nur montri sciigojn (se estas): ",
"Enable web notifications": "Ebligi retejajn sciigojn",
- "`x` uploaded a video": "`x` alŝutis videon",
+ "`x` uploaded a video": "`x` alŝutis filmeton",
"`x` is live": "`x` estas nuna",
"Data preferences": "Datumagordoj",
"Clear watch history": "Forigi vidohistorion",
@@ -127,18 +127,18 @@
"View JavaScript license information.": "Vidi Ĝavoskriptan licencan informon.",
"View privacy policy.": "Vidi regularon pri privateco.",
"Trending": "Tendencoj",
- "Public": "",
+ "Public": "Publika",
"Unlisted": "Ne listigita",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
- "Watch on YouTube": "Vidi videon en Youtube",
+ "Private": "Privata",
+ "View all playlists": "Vidi ĉiujn ludlistojn",
+ "Updated `x` ago": "Ĝisdatigita antaŭ `x`",
+ "Delete playlist `x`?": "Ĉu forigi ludliston `x`?",
+ "Delete playlist": "Forigi ludliston",
+ "Create playlist": "Krei ludliston",
+ "Title": "Titolo",
+ "Playlist privacy": "Privateco de ludlisto",
+ "Editing playlist `x`": "Redaktante ludlisto `x`",
+ "Watch on YouTube": "Vidi filmeton en JuTubo",
"Hide annotations": "Kaŝi prinotojn",
"Show annotations": "Montri prinotojn",
"Genre: ": "Ĝenro: ",
@@ -153,7 +153,7 @@
"Premieres in `x`": "Premieras en `x`",
"Premieres `x`": "Premieras `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Saluton! Ŝajnas, ke vi havas Ĝavoskripton malebligitan. Klaku ĉi tie por vidi komentojn, memoru, ke la ŝargado povus daŭri iom pli.",
- "View YouTube comments": "Vidi komentojn de YouTube",
+ "View YouTube comments": "Vidi komentojn de JuTubo",
"View more comments on Reddit": "Vidi pli komentoj en Reddit",
"View `x` comments": "Vidi `x` komentojn",
"View Reddit comments": "Vidi komentojn de Reddit",
@@ -324,12 +324,12 @@
"Download as: ": "Elŝuti kiel: ",
"%A %B %-d, %Y": "%A %-d de %B %Y",
"(edited)": "(redaktita)",
- "YouTube comment permalink": "Fiksligilo de la komento en YouTube",
+ "YouTube comment permalink": "Fiksligilo de la komento en JuTubo",
"permalink": "konstanta ligilo",
"`x` marked it with a ❤": "`x` markis ĝin per ❤",
"Audio mode": "Aŭda reĝimo",
"Video mode": "Videa reĝimo",
- "Videos": "Videoj",
+ "Videos": "Filmetoj",
"Playlists": "Ludlistoj",
"Community": "Komunumo",
"Current version: ": "Nuna versio: "
diff --git a/locales/es.json b/locales/es.json
index 31ffed3b..7fc75003 100644
--- a/locales/es.json
+++ b/locales/es.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` suscriptores",
"`x` videos": "`x` vídeos",
- "`x` playlists": "",
+ "`x` playlists": "`x` listas de reproducción",
"LIVE": "DIRECTO",
"Shared `x` ago": "Compartido hace `x`",
"Unsubscribe": "Desuscribirse",
@@ -69,11 +69,11 @@
"Show related videos: ": "¿Mostrar vídeos relacionados? ",
"Show annotations by default: ": "¿Mostrar anotaciones por defecto? ",
"Visual preferences": "Preferencias visuales",
- "Player style: ": "",
+ "Player style: ": "Estilo de reproductor: ",
"Dark mode: ": "Modo oscuro: ",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "Tema: ",
+ "dark": "oscuro",
+ "light": "claro",
"Thin mode: ": "Modo compacto: ",
"Subscription preferences": "Preferencias de la suscripción",
"Show annotations by default for subscribed channels: ": "¿Mostrar anotaciones por defecto para los canales suscritos? ",
@@ -90,9 +90,9 @@
"Only show latest unwatched video from channel: ": "Mostrar solo el último vídeo sin ver del canal: ",
"Only show unwatched: ": "Mostrar solo los no vistos: ",
"Only show notifications (if there are any): ": "Mostrar solo notificaciones (si hay alguna): ",
- "Enable web notifications": "",
- "`x` uploaded a video": "",
- "`x` is live": "",
+ "Enable web notifications": "Habilitar notificaciones web",
+ "`x` uploaded a video": "`x` subió un video",
+ "`x` is live": "`x` esta en vivo",
"Data preferences": "Preferencias de los datos",
"Clear watch history": "Borrar el historial de reproducción",
"Import/export data": "Importar/Exportar datos",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "Ver información de licencia de JavaScript.",
"View privacy policy.": "Ver la política de privacidad.",
"Trending": "Tendencias",
- "Public": "",
+ "Public": "Público",
"Unlisted": "No listado",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privado",
+ "View all playlists": "Ver todas las listas de reproducción",
+ "Updated `x` ago": "Actualizado hace `x`",
+ "Delete playlist `x`?": "¿Eliminar la lista de reproducción `x`?",
+ "Delete playlist": "Eliminar lista de reproducción",
+ "Create playlist": "Crear lista de reproducción",
+ "Title": "Título",
+ "Playlist privacy": "Privacidad de la lista de reproducción",
+ "Editing playlist `x`": "Editando la lista de reproducción 'x'",
"Watch on YouTube": "Ver el vídeo en Youtube",
"Hide annotations": "Ocultar anotaciones",
"Show annotations": "Mostrar anotaciones",
@@ -151,7 +151,7 @@
"Shared `x`": "Compartido `x`",
"`x` views": "`x` visualizaciones",
"Premieres in `x`": "Se estrena en `x`",
- "Premieres `x`": "",
+ "Premieres `x`": "Estrenos `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tiene JavaScript desactivado. Haga clic aquí para ver los comentarios, pero tenga en cuenta que pueden tardar un poco más en cargarse.",
"View YouTube comments": "Ver los comentarios de YouTube",
"View more comments on Reddit": "Ver más comentarios en Reddit",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "%A %B %-d, %Y",
"(edited)": "(editado)",
"YouTube comment permalink": "Enlace permanente de YouTube del comentario",
- "permalink": "",
+ "permalink": "permalink",
"`x` marked it with a ❤": "`x` lo ha marcado con un ❤",
"Audio mode": "Modo de audio",
"Video mode": "Modo de vídeo",
"Videos": "Vídeos",
"Playlists": "Listas de reproducción",
- "Community": "",
+ "Community": "Comunidad",
"Current version: ": "Versión actual: "
} \ No newline at end of file
diff --git a/locales/eu.json b/locales/eu.json
index 352d84f1..61299c72 100644
--- a/locales/eu.json
+++ b/locales/eu.json
@@ -1,13 +1,13 @@
{
"`x` subscribers": "`x` harpidedun",
"`x` videos": "`x` bideo",
- "`x` playlists": "",
+ "`x` playlists": "`x` erreprodukzio-zerrenda",
"LIVE": "ZUZENEAN",
"Shared `x` ago": "Duela `x` partekatua",
"Unsubscribe": "Harpidetza kendu",
"Subscribe": "Harpidetu",
"View channel on YouTube": "Ikusi kanala YouTuben",
- "View playlist on YouTube": "",
+ "View playlist on YouTube": "Ikusi erreprodukzio-zerrenda YouTuben",
"newest": "berrienak",
"oldest": "zaharrenak",
"popular": "ospetsuenak",
@@ -16,66 +16,66 @@
"Previous page": "Aurreko orria",
"Clear watch history?": "Garbitu ikusitakoen historia?",
"New password": "Pasahitz berria",
- "New passwords must match": "",
- "Cannot change password for Google accounts": "",
- "Authorize token?": "",
+ "New passwords must match": "Pasahitza berriek bat egin behar dute",
+ "Cannot change password for Google accounts": "Ezin da pasahitza aldatu Google kontuetan",
+ "Authorize token?": "Baimendu tokena?",
"Authorize token for `x`?": "",
"Yes": "Bai",
"No": "Ez",
"Import and Export Data": "Datuak inportatu eta esportatu",
"Import": "Inportatu",
- "Import Invidious data": "Invidiouseko datuak inportatu",
- "Import YouTube subscriptions": "YouTubeko harpidetzak inportatu",
- "Import FreeTube subscriptions (.db)": "FreeTubeko harpidetzak inportatu (.db)",
- "Import NewPipe subscriptions (.json)": "NewPipeko harpidetzak inportatu (.json)",
- "Import NewPipe data (.zip)": "NewPipeko datuak inportatu (.zip)",
+ "Import Invidious data": "Inportatu Invidiouseko datuak",
+ "Import YouTube subscriptions": "Inportatu YouTubeko harpidetzak",
+ "Import FreeTube subscriptions (.db)": "Inportatu FreeTubeko harpidetzak (.db)",
+ "Import NewPipe subscriptions (.json)": "Inportatu NewPipeko harpidetzak (.json)",
+ "Import NewPipe data (.zip)": "Inportatu NewPipeko datuak (.zip)",
"Export": "Esportatu",
"Export subscriptions as OPML": "Esportatu harpidetzak OPML bezala",
- "Export subscriptions as OPML (for NewPipe & FreeTube)": "Harpidetzak OPML bezala esportatu (NewPipe eta FreeTuberako)",
- "Export data as JSON": "Datuak JSON bezala esportatu",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Esportatu harpidetzak OPML bezala (NewPipe eta FreeTuberako)",
+ "Export data as JSON": "Esportatu datuak JSON bezala",
"Delete account?": "Kontua ezabatu?",
"History": "Historia",
"An alternative front-end to YouTube": "YouTuberako interfaze alternatibo bat",
"JavaScript license information": "JavaScript lizentzia informazioa",
"source": "iturburua",
"Log in": "Saioa hasi",
- "Log in/register": "Saioa hasi/Izena eman",
- "Log in with Google": "Googlekin hasi saioa",
+ "Log in/register": "Hasi saioa / Eman izena",
+ "Log in with Google": "Hasi saioa Googlekin",
"User ID": "Erabiltzaile IDa",
"Password": "Pasahitza",
- "Time (h:mm:ss):": "Denbora (o:mm:ss):",
- "Text CAPTCHA": "Testu CAPTCHA",
- "Image CAPTCHA": "Irudi CAPTCHA",
- "Sign In": "",
- "Register": "",
- "E-mail": "",
+ "Time (h:mm:ss):": "Denbora (h:mm:ss):",
+ "Text CAPTCHA": "CAPTCHA testua",
+ "Image CAPTCHA": "CAPTCHA irudia",
+ "Sign In": "Hasi saioa",
+ "Register": "Eman izena",
+ "E-mail": "E-posta",
"Google verification code": "",
- "Preferences": "",
- "Player preferences": "",
+ "Preferences": "Hobespenak",
+ "Player preferences": "Erreproduzigailuaren hobespenak",
"Always loop: ": "",
- "Autoplay: ": "",
+ "Autoplay: ": "Automatikoki erreproduzitu: ",
"Play next by default: ": "",
- "Autoplay next video: ": "",
+ "Autoplay next video: ": "Erreproduzitu automatikoki hurrengo bideoa: ",
"Listen by default: ": "",
"Proxy videos: ": "",
"Default speed: ": "",
- "Preferred video quality: ": "",
- "Player volume: ": "",
- "Default comments: ": "",
- "youtube": "",
- "reddit": "",
- "Default captions: ": "",
+ "Preferred video quality: ": "Hobetsitako bideoaren kalitatea: ",
+ "Player volume: ": "Erreproduzigailuaren bolumena: ",
+ "Default comments: ": "Lehenetsitako iruzkinak: ",
+ "youtube": "youtube",
+ "reddit": "reddit",
+ "Default captions: ": "Lehenetsitako azpitituluak: ",
"Fallback captions: ": "",
- "Show related videos: ": "",
- "Show annotations by default: ": "",
- "Visual preferences": "",
- "Player style: ": "",
- "Dark mode: ": "",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Show related videos: ": "Erakutsi erlazionatutako bideoak: ",
+ "Show annotations by default: ": "Erakutsi oharrak modu lehenetsian: ",
+ "Visual preferences": "Hobespen bisualak",
+ "Player style: ": "Erreproduzigailu mota: ",
+ "Dark mode: ": "Gai iluna: ",
+ "Theme: ": "Gaia: ",
+ "dark": "iluna",
+ "light": "argia",
"Thin mode: ": "",
- "Subscription preferences": "",
+ "Subscription preferences": "Harpidetzen hobespenak",
"Show annotations by default for subscribed channels: ": "",
"Redirect homepage to feed: ": "",
"Number of videos shown in feed: ": "",
diff --git a/locales/fr.json b/locales/fr.json
index 928904c1..24cabdea 100644
--- a/locales/fr.json
+++ b/locales/fr.json
@@ -87,8 +87,8 @@
"channel name": "nom de la chaîne",
"channel name - reverse": "nom de la chaîne - inversé",
"Only show latest video from channel: ": "Afficher uniquement la dernière vidéo des chaînes auxquelles vous êtes abonnés : ",
- "Only show latest unwatched video from channel: ": "Afficher uniquement la dernière vidéo des chaînes auxquelles vous êtes abonnés qui n'a pas était regardée : ",
- "Only show unwatched: ": "Afficher uniquement les vidéos qui n'ont pas étaient regardées : ",
+ "Only show latest unwatched video from channel: ": "Afficher uniquement la dernière vidéo des chaînes auxquelles vous êtes abonnés qui n'a pas été regardée : ",
+ "Only show unwatched: ": "Afficher uniquement les vidéos qui n'ont pas été regardées : ",
"Only show notifications (if there are any): ": "Afficher uniquement les notifications (s'il y en a) : ",
"Enable web notifications": "Activer les notifications web",
"`x` uploaded a video": "`x` a partagé(e) une vidéo",
@@ -152,7 +152,7 @@
"`x` views": "`x` vues",
"Premieres in `x`": "Première dans `x`",
"Premieres `x`": "Première le `x`",
- "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Il semblerait que JavaScript soit désactivé. Cliquez ici pour voir les commentaires sans. Gardez à l'esprit que le chargement peut prendre plus de temps.",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Il semblerait que JavaScript soit désactivé. Cliquez ici pour voir les commentaires, mais gardez à l'esprit que le chargement peut prendre plus de temps.",
"View YouTube comments": "Voir les commentaires YouTube",
"View more comments on Reddit": "Voir plus de commentaires sur Reddit",
"View `x` comments": "Voir `x` commentaires",
@@ -160,7 +160,7 @@
"Hide replies": "Masquer les réponses",
"Show replies": "Afficher les réponses",
"Incorrect password": "Mot de passe incorrect",
- "Quota exceeded, try again in a few hours": "Nombre de tentative de connexion dépassée, réessayez dans quelques heures",
+ "Quota exceeded, try again in a few hours": "Nombre de tentatives de connexion dépassé, réessayez dans quelques heures",
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Impossible de se connecter, si après plusieurs tentative vous ne parvenez toujours pas à vous connecter, assurez-vous que l'authentification à deux facteurs (Authenticator ou SMS) est activée.",
"Invalid TFA code": "Code d'authentification à deux facteurs invalide",
"Login failed. This may be because two-factor authentication is not turned on for your account.": "La connexion a échoué. Cela peut être dû au fait que l'authentification à deux facteurs n'est pas activée sur votre compte.",
@@ -333,4 +333,4 @@
"Playlists": "Listes de lecture",
"Community": "Communauté",
"Current version: ": "Version actuelle : "
-}
+} \ No newline at end of file
diff --git a/locales/hu-HU.json b/locales/hu-HU.json
new file mode 100644
index 00000000..b21ae93a
--- /dev/null
+++ b/locales/hu-HU.json
@@ -0,0 +1,335 @@
+{
+ "`x` subscribers": "`x` feliratkozó",
+ "`x` videos": "`x` videó",
+ "`x` playlists": "`x` playlist",
+ "LIVE": "ÉLŐ",
+ "Shared `x` ago": "`x` óta megosztva",
+ "Unsubscribe": "Leiratkozás",
+ "Subscribe": "Feliratkozás",
+ "View channel on YouTube": "Csatokrna megtekintése a YouTube-on",
+ "View playlist on YouTube": "Playlist megtekintése a YouTube-on",
+ "newest": "legújabb",
+ "oldest": "legrégibb",
+ "popular": "népszerű",
+ "last": "utolsó",
+ "Next page": "Következő oldal",
+ "Previous page": "Előző oldal",
+ "Clear watch history?": "Megtekintési napló törlése?",
+ "New password": "Új jelszó",
+ "New passwords must match": "Az új jelszavaknak egyezniük kell",
+ "Cannot change password for Google accounts": "Google fiók jelszavát nem lehet cserélni",
+ "Authorize token?": "Token felhatalmazása?",
+ "Authorize token for `x`?": "Token felhatalmazása `x`-ra?",
+ "Yes": "Igen",
+ "No": "Nem",
+ "Import and Export Data": "Adatok importálása és exportálása",
+ "Import": "Importálás",
+ "Import Invidious data": "Invidious adatainak importálása",
+ "Import YouTube subscriptions": "YouTube feliratkozások importálása",
+ "Import FreeTube subscriptions (.db)": "FreeTube feliratkozások importálása (.db)",
+ "Import NewPipe subscriptions (.json)": "NewPipe feliratkozások importálása (.json)",
+ "Import NewPipe data (.zip)": "NewPipe adatainak importálása (.zip)",
+ "Export": "Exportálás",
+ "Export subscriptions as OPML": "Feliratkozások exportálása OPML-ként",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Feliratkozások exportálása OPML-ként (NewPipe és FreeTube számára)",
+ "Export data as JSON": "Adat exportálása JSON-ként",
+ "Delete account?": "Fiók törlése?",
+ "History": "Megtekintési napló",
+ "An alternative front-end to YouTube": "Alternatív YouTube front-end",
+ "JavaScript license information": "JavaScript licensz információ",
+ "source": "forrás",
+ "Log in": "Bejelentkezés",
+ "Log in/register": "Bejelentkezés/Regisztráció",
+ "Log in with Google": "Bejelentkezés Google fiókkal",
+ "User ID": "Felhasználó-ID",
+ "Password": "Jelszó",
+ "Time (h:mm:ss):": "Idő (h:mm:ss):",
+ "Text CAPTCHA": "Szöveg-CAPTCHA",
+ "Image CAPTCHA": "Kép-CAPTCHA",
+ "Sign In": "Bejelentkezés",
+ "Register": "Regisztráció",
+ "E-mail": "E-mail",
+ "Google verification code": "Google verifikációs kód",
+ "Preferences": "Beállítások",
+ "Player preferences": "Lejátszó beállítások",
+ "Always loop: ": "Mindig loop-ol: ",
+ "Autoplay: ": "Automatikus lejátszás: ",
+ "Play next by default: ": "Következő lejátszása alapértelmezésben: ",
+ "Autoplay next video: ": "Következő automatikus lejátszása: ",
+ "Listen by default: ": "Hallgatás alapértelmezésben: ",
+ "Proxy videos: ": "Proxy videók: ",
+ "Default speed: ": "Alapértelmezett sebesség: ",
+ "Preferred video quality: ": "Kívánt video minőség: ",
+ "Player volume: ": "Hangerő: ",
+ "Default comments: ": "Alapértelmezett kommentek: ",
+ "youtube": "YouTube",
+ "reddit": "Reddit",
+ "Default captions: ": "Alapértelmezett feliratok: ",
+ "Fallback captions: ": "Másodlagos feliratok: ",
+ "Show related videos: ": "Kapcsolódó videók mutatása: ",
+ "Show annotations by default: ": "Annotációk mutatása alapértelmetésben: ",
+ "Visual preferences": "Vizuális preferenciák",
+ "Player style: ": "Lejátszó stílusa: ",
+ "Dark mode: ": "Sötét mód: ",
+ "Theme: ": "Téma: ",
+ "dark": "Sötét",
+ "light": "Világos",
+ "Thin mode: ": "Vékony mód: ",
+ "Subscription preferences": "Feliratkozási beállítások",
+ "Show annotations by default for subscribed channels: ": "Annotációk mutatása alapértelmezésben feliratkozott csatornák esetében: ",
+ "Redirect homepage to feed: ": "Kezdő oldal átirányitása a feed-re: ",
+ "Number of videos shown in feed: ": "Feed-ben mutatott videók száma: ",
+ "Sort videos by: ": "Videók sorrendje: ",
+ "published": "közzétéve",
+ "published - reverse": "közzétéve (ford.)",
+ "alphabetically": "ABC sorrend",
+ "alphabetically - reverse": "ABC sorrend (ford.)",
+ "channel name": "csatorna neve",
+ "channel name - reverse": "csatorna neve (ford.)",
+ "Only show latest video from channel: ": "Csak a legutolsó videó mutatása a csatornából: ",
+ "Only show latest unwatched video from channel: ": "Csak a legutolsó nem megtekintett videó mutatása a csatornából: ",
+ "Only show unwatched: ": "Csak a nem megtekintettek mutatása: ",
+ "Only show notifications (if there are any): ": "Csak értesítések mutatása (ha van): ",
+ "Enable web notifications": "Web értesítések bekapcsolása",
+ "`x` uploaded a video": "`x` feltöltött egy videót",
+ "`x` is live": "`x` élő",
+ "Data preferences": "Adat beállítások",
+ "Clear watch history": "Megtekintési napló törlése",
+ "Import/export data": "Adat Import/Export",
+ "Change password": "Jelszócsere",
+ "Manage subscriptions": "Feliratkozások kezelése",
+ "Manage tokens": "Tokenek kezelése",
+ "Watch history": "Megtekintési napló",
+ "Delete account": "Fiók törlése",
+ "Administrator preferences": "Adminisztrátor beállítások",
+ "Default homepage: ": "Alapértelmezett honlap: ",
+ "Feed menu: ": "Feed menü: ",
+ "Top enabled: ": "Top lista engedélyezve: ",
+ "CAPTCHA enabled: ": "CAPTCHA engedélyezve: ",
+ "Login enabled: ": "Bejelentkezés engedélyezve: ",
+ "Registration enabled: ": "Registztráció engedélyezve: ",
+ "Report statistics: ": "Statisztikák gyűjtése: ",
+ "Save preferences": "Beállítások mentése",
+ "Subscription manager": "Feliratkozás kezelő",
+ "Token manager": "Token kezelő",
+ "Token": "Token",
+ "`x` subscriptions": "`x` feliratkozás",
+ "`x` tokens": "`x` token",
+ "Import/export": "Import/export",
+ "unsubscribe": "leiratkozás",
+ "revoke": "visszavonás",
+ "Subscriptions": "Feliratkozások",
+ "`x` unseen notifications": "`x` kimaradt érdesítés",
+ "search": "keresés",
+ "Log out": "Kijelentkezés",
+ "Released under the AGPLv3 by Omar Roth.": "Omar Roth által release-elve AGPLv3 licensz alatt.",
+ "Source available here.": "Forrás elérhető itt.",
+ "View JavaScript license information.": "JavaScript licensz inforkációk megtekintése.",
+ "View privacy policy.": "Adatvédelem irányelv megtekintése.",
+ "Trending": "Trending",
+ "Public": "Nyilvános",
+ "Unlisted": "Nem nyilvános",
+ "Private": "Privát",
+ "View all playlists": "Minden playlist megtekintése",
+ "Updated `x` ago": "Frissitve `x`",
+ "Delete playlist `x`?": "`x` playlist törlése?",
+ "Delete playlist": "Playlist törlése",
+ "Create playlist": "Playlist létrehozása",
+ "Title": "Címe",
+ "Playlist privacy": "Playlist láthatósága",
+ "Editing playlist `x`": "`x` playlist szerkesztése",
+ "Watch on YouTube": "Megtekintés a YouTube-on",
+ "Hide annotations": "Annotációk elrejtése",
+ "Show annotations": "Annotációk mutatása",
+ "Genre: ": "Zsáner: ",
+ "License: ": "Licensz: ",
+ "Family friendly? ": "Családbarát? ",
+ "Wilson score: ": "Wilson-ponstszém: ",
+ "Engagement: ": "Engagement: ",
+ "Whitelisted regions: ": "Engedélyezett régiók: ",
+ "Blacklisted regions: ": "Tiltott régiók: ",
+ "Shared `x`": "Megosztva `x`",
+ "`x` views": "`x` megtekintés",
+ "Premieres in `x`": "Premier `x`",
+ "Premieres `x`": "Premier `x`",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.",
+ "View YouTube comments": "YouTube kommentek megtekintése",
+ "View more comments on Reddit": "További Reddit kommentek megtekintése",
+ "View `x` comments": "`x` komment megtekintése",
+ "View Reddit comments": "Reddit kommentek megtekintése",
+ "Hide replies": "Válaszok elrejtése",
+ "Show replies": "Válaszok mutatása",
+ "Incorrect password": "Helytelen jelszó",
+ "Quota exceeded, try again in a few hours": "Kvóta túllépve, próbálkozz pár órával később",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Sikertelen belépés, győződj meg róla hogy a 2FA (Authenticator vagy SMS) engedélyezve van.",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Sikertelen belépés, győződj meg róla hogy a 2FA (Authenticator vagy SMS) engedélyezve van.",
+ "Wrong answer": "Rossz válasz",
+ "Erroneous CAPTCHA": "Hibás CAPTCHA",
+ "CAPTCHA is a required field": "A CAPTCHA kötelező",
+ "User ID is a required field": "A felhasználó-ID kötelező",
+ "Password is a required field": "A jelszó kötelező",
+ "Wrong username or password": "Rossz felhasználónév vagy jelszó",
+ "Please sign in using 'Log in with Google'": "Kérem, jelentkezzen be a \"Bejelentkezés Google-el\"",
+ "Password cannot be empty": "A jelszó nem lehet üres",
+ "Password cannot be longer than 55 characters": "A jelszó nem lehet hosszabb 55 betűnél",
+ "Please log in": "Kérem lépjen be",
+ "Invidious Private Feed for `x`": "`x` Invidious privát feed-je",
+ "channel:`x`": "`x` csatorna",
+ "Deleted or invalid channel": "Törölt vagy nemlétező csatorna",
+ "This channel does not exist.": "Ez a csatorna nem létezik.",
+ "Could not get channel info.": "Nem megszerezhető a csatorna információ.",
+ "Could not fetch comments": "Nem megszerezhetőek a kommentek",
+ "View `x` replies": "`x` válasz megtekintése",
+ "`x` ago": "`x` óta",
+ "Load more": "További betöltése",
+ "`x` points": "`x` pont",
+ "Could not create mix.": "Nem tudok mix-et készíteni.",
+ "Empty playlist": "Üres playlist",
+ "Not a playlist.": "Nem playlist.",
+ "Playlist does not exist.": "Nem létező playlist.",
+ "Could not pull trending pages.": "Nem tudom letölteni a trendek adatait.",
+ "Hidden field \"challenge\" is a required field": "A rejtett \"challenge\" mező kötelező",
+ "Hidden field \"token\" is a required field": "A rejtett \"token\" mező kötelező",
+ "Erroneous challenge": "Hibás challenge",
+ "Erroneous token": "Hibás token",
+ "No such user": "Nincs ilyen felhasználó",
+ "Token is expired, please try again": "Lejárt token, kérem próbáld újra",
+ "English": "",
+ "English (auto-generated)": "English (auto-genererat)",
+ "Afrikaans": "",
+ "Albanian": "",
+ "Amharic": "",
+ "Arabic": "",
+ "Armenian": "",
+ "Azerbaijani": "",
+ "Bangla": "",
+ "Basque": "",
+ "Belarusian": "",
+ "Bosnian": "",
+ "Bulgarian": "",
+ "Burmese": "",
+ "Catalan": "",
+ "Cebuano": "",
+ "Chinese (Simplified)": "",
+ "Chinese (Traditional)": "",
+ "Corsican": "",
+ "Croatian": "",
+ "Czech": "",
+ "Danish": "",
+ "Dutch": "",
+ "Esperanto": "",
+ "Estonian": "",
+ "Filipino": "",
+ "Finnish": "",
+ "French": "",
+ "Galician": "",
+ "Georgian": "",
+ "German": "",
+ "Greek": "",
+ "Gujarati": "",
+ "Haitian Creole": "",
+ "Hausa": "",
+ "Hawaiian": "",
+ "Hebrew": "",
+ "Hindi": "",
+ "Hmong": "",
+ "Hungarian": "",
+ "Icelandic": "",
+ "Igbo": "",
+ "Indonesian": "",
+ "Irish": "",
+ "Italian": "",
+ "Japanese": "",
+ "Javanese": "",
+ "Kannada": "",
+ "Kazakh": "",
+ "Khmer": "",
+ "Korean": "",
+ "Kurdish": "",
+ "Kyrgyz": "",
+ "Lao": "",
+ "Latin": "",
+ "Latvian": "",
+ "Lithuanian": "",
+ "Luxembourgish": "",
+ "Macedonian": "",
+ "Malagasy": "",
+ "Malay": "",
+ "Malayalam": "",
+ "Maltese": "",
+ "Maori": "",
+ "Marathi": "",
+ "Mongolian": "",
+ "Nepali": "",
+ "Norwegian Bokmål": "",
+ "Nyanja": "",
+ "Pashto": "",
+ "Persian": "",
+ "Polish": "",
+ "Portuguese": "",
+ "Punjabi": "",
+ "Romanian": "",
+ "Russian": "",
+ "Samoan": "",
+ "Scottish Gaelic": "",
+ "Serbian": "",
+ "Shona": "",
+ "Sindhi": "",
+ "Sinhala": "",
+ "Slovak": "",
+ "Slovenian": "",
+ "Somali": "",
+ "Southern Sotho": "",
+ "Spanish": "",
+ "Spanish (Latin America)": "",
+ "Sundanese": "",
+ "Swahili": "",
+ "Swedish": "",
+ "Tajik": "",
+ "Tamil": "",
+ "Telugu": "",
+ "Thai": "",
+ "Turkish": "",
+ "Ukrainian": "",
+ "Urdu": "",
+ "Uzbek": "",
+ "Vietnamese": "",
+ "Welsh": "",
+ "Western Frisian": "",
+ "Xhosa": "",
+ "Yiddish": "",
+ "Yoruba": "",
+ "Zulu": "",
+ "`x` years": "`x` év",
+ "`x` months": "`x` hónap",
+ "`x` weeks": "`x` hét",
+ "`x` days": "`x` nap",
+ "`x` hours": "`x` óra",
+ "`x` minutes": "`x` perc",
+ "`x` seconds": "`x` másodperc",
+ "Fallback comments: ": "Másodlagos kommentek: ",
+ "Popular": "Népszerű",
+ "Top": "Top",
+ "About": "Leírás",
+ "Rating: ": "Besorolás: ",
+ "Language: ": "Nyelv: ",
+ "View as playlist": "Megtekintés playlist-ként",
+ "Default": "Alapértelmezett",
+ "Music": "Zene",
+ "Gaming": "Játékok",
+ "News": "Hírek",
+ "Movies": "Filmek",
+ "Download": "Letöltés",
+ "Download as: ": "Letöltés mint: ",
+ "%A %B %-d, %Y": "",
+ "(edited)": "(szerkesztve)",
+ "YouTube comment permalink": "YouTube komment permalink",
+ "permalink": "permalink",
+ "`x` marked it with a ❤": "`x` jelölte ❤-vel",
+ "Audio mode": "Audio mód",
+ "Video mode": "Video mód",
+ "Videos": "Videók",
+ "Playlists": "Playlistek",
+ "Community": "Közösség",
+ "Current version: ": "Jelenlegi verzió: "
+} \ No newline at end of file
diff --git a/locales/it.json b/locales/it.json
index 47510d3f..2e993c81 100644
--- a/locales/it.json
+++ b/locales/it.json
@@ -1,13 +1,13 @@
{
- "`x` subscribers": {
+ "`x` subscribers.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscritto",
- "": "`x` iscritti"
+ "": "`x` iscritti."
},
- "`x` videos": {
+ "`x` videos.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` video",
- "": "`x` video"
+ "": "`x` video."
},
- "`x` playlists": "",
+ "`x` playlists": "`x` playlist",
"LIVE": "IN DIRETTA",
"Shared `x` ago": "Condiviso `x` fa",
"Unsubscribe": "Disiscriviti",
@@ -75,9 +75,9 @@
"Show related videos: ": "Mostra video correlati: ",
"Show annotations by default: ": "Mostra le annotazioni in modo predefinito: ",
"Visual preferences": "Preferenze grafiche",
- "Player style: ": "Stile riproduttore",
+ "Player style: ": "Stile riproduttore: ",
"Dark mode: ": "Tema scuro: ",
- "Theme: ": "Tema",
+ "Theme: ": "Tema: ",
"dark": "scuro",
"light": "chiaro",
"Thin mode: ": "Modalità per connessioni lente: ",
@@ -110,7 +110,7 @@
"Administrator preferences": "Preferenze amministratore",
"Default homepage: ": "Pagina principale predefinita: ",
"Feed menu: ": "Menu iscrizioni: ",
- "Top enabled: ": "",
+ "Top enabled: ": "Top abilitato: ",
"CAPTCHA enabled: ": "CAPTCHA attivati: ",
"Login enabled: ": "Accesso attivato: ",
"Registration enabled: ": "Registrazione attivata: ",
@@ -119,40 +119,40 @@
"Subscription manager": "Gestione delle iscrizioni",
"Token manager": "Gestione dei gettoni",
"Token": "Gettone",
- "`x` subscriptions": {
+ "`x` subscriptions.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` iscrizione",
- "": "`x` iscrizioni"
+ "": "`x` iscrizioni."
},
- "`x` tokens": {
+ "`x` tokens.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` gettone",
- "": "`x` gettoni"
+ "": "`x` gettoni."
},
"Import/export": "Importa/esporta",
"unsubscribe": "disiscriviti",
"revoke": "revoca",
"Subscriptions": "Iscrizioni",
- "`x` unseen notifications": {
+ "`x` unseen notifications.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` notifica non visualizzata",
- "": "`x` notifiche non visualizzate"
+ "": "`x` notifiche non visualizzate."
},
"search": "Cerca",
"Log out": "Esci",
"Released under the AGPLv3 by Omar Roth.": "Pubblicato con licenza AGPLv3 da Omar Roth.",
"Source available here.": "Codice sorgente.",
"View JavaScript license information.": "Guarda le informazioni di licenza del codice JavaScript.",
- "View privacy policy.": "Vedi la politica sulla privacy",
+ "View privacy policy.": "Vedi la politica sulla privacy.",
"Trending": "Tendenze",
- "Public": "",
+ "Public": "Pubblico",
"Unlisted": "Non elencati",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privato",
+ "View all playlists": "Visualizza tutte le playlist",
+ "Updated `x` ago": "Aggiornato `x` fa",
+ "Delete playlist `x`?": "Eliminare la playlist `x`?",
+ "Delete playlist": "Elimina playlist",
+ "Create playlist": "Crea playlist",
+ "Title": "Titolo",
+ "Playlist privacy": "Privacy playlist",
+ "Editing playlist `x`": "Modificando la playlist `x`",
"Watch on YouTube": "Guarda su YouTube",
"Hide annotations": "Nascondi annotazioni",
"Show annotations": "Mostra annotazioni",
@@ -164,12 +164,12 @@
"Whitelisted regions: ": "Regioni in lista bianca: ",
"Blacklisted regions: ": "Regioni in lista nera: ",
"Shared `x`": "Condiviso `x`",
- "`x` views": {
+ "`x` views.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizzazione",
- "": "`x` visualizzazioni"
+ "": "`x` visualizzazioni."
},
- "Premieres in `x`": "",
- "Premieres `x`": "",
+ "Premieres in `x`": "In anteprima in `x`",
+ "Premieres `x`": "In anteprima `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Ciao! Sembra che tu abbia disattivato JavaScript. Clicca qui per visualizzare i commenti. Considera che potrebbe volerci più tempo.",
"View YouTube comments": "Visualizza i commenti da YouTube",
"View more comments on Reddit": "Visualizza più commenti su Reddit",
@@ -198,15 +198,15 @@
"This channel does not exist.": "Questo canale non esiste.",
"Could not get channel info.": "Impossibile ottenere le informazioni del canale.",
"Could not fetch comments": "Impossibile recuperare i commenti",
- "View `x` replies": {
+ "View `x` replies.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "Visualizza `x` risposta",
- "": "Visualizza `x` risposte"
+ "": "Visualizza `x` risposte."
},
"`x` ago": "`x` fa",
"Load more": "Carica altro",
- "`x` points": {
+ "`x` points.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` punto",
- "": "`x` punti"
+ "": "`x` punti."
},
"Could not create mix.": "Impossibile creare il mix.",
"Empty playlist": "Playlist vuota",
@@ -325,33 +325,33 @@
"Yiddish": "Yiddish",
"Yoruba": "Yoruba",
"Zulu": "Zulu",
- "`x` years": {
+ "`x` years.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` anno",
- "": "`x` anni"
+ "": "`x` anni."
},
- "`x` months": {
+ "`x` months.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` mese",
- "": "`x` mesi"
+ "": "`x` mesi."
},
- "`x` weeks": {
+ "`x` weeks.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` settimana",
- "": "`x` settimane"
+ "": "`x` settimane."
},
- "`x` days": {
+ "`x` days.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` giorno",
- "": "`x` giorni"
+ "": "`x` giorni."
},
- "`x` hours": {
+ "`x` hours.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` ora",
- "": "`x` ore"
+ "": "`x` ore."
},
- "`x` minutes": {
+ "`x` minutes.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` minuto",
- "": "`x` minuti"
+ "": "`x` minuti."
},
- "`x` seconds": {
+ "`x` seconds.": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` secondo",
- "": "`x` secondi"
+ "": "`x` secondi."
},
"Fallback comments: ": "Commenti alternativi: ",
"Popular": "Popolare",
@@ -370,7 +370,7 @@
"%A %B %-d, %Y": "%A %-d %B %Y",
"(edited)": "(modificato)",
"YouTube comment permalink": "Link permanente al commento di YouTube",
- "permalink": "",
+ "permalink": "permalink",
"`x` marked it with a ❤": "`x` l'ha contrassegnato con un ❤",
"Audio mode": "Modalità audio",
"Video mode": "Modalità video",
diff --git a/locales/ja.json b/locales/ja.json
index e2aabd0b..e9ca0e62 100644
--- a/locales/ja.json
+++ b/locales/ja.json
@@ -8,7 +8,7 @@
"": "`x` 個の動画"
},
"`x` playlists": {
- "(\\D|^)1(\\D|$)": "`x` 個の再生リスト",
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個の再生リスト",
"": "`x` 個の再生リスト"
},
"LIVE": "ライブ",
@@ -177,7 +177,7 @@
"View YouTube comments": "YouTube のコメントを見る",
"View more comments on Reddit": "Reddit でコメントをもっと見る",
"View `x` comments": {
- "(\\D|^)1(\\D|$)": "`x` 件のコメントを見る",
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` 件のコメントを見る",
"": "`x` 件のコメントを見る"
},
"View Reddit comments": "Reddit のコメントを見る",
@@ -384,4 +384,4 @@
"Playlists": "プレイリスト",
"Community": "コミュニティ",
"Current version: ": "現在のバージョン: "
-}
+} \ No newline at end of file
diff --git a/locales/nb_NO.json b/locales/nb-NO.json
index d3bce6ac..ff40e27b 100644
--- a/locales/nb_NO.json
+++ b/locales/nb-NO.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` abonnenter",
"`x` videos": "`x` videoer",
- "`x` playlists": "",
+ "`x` playlists": "`x` spillelister",
"LIVE": "SANNTIDSVISNING",
"Shared `x` ago": "Delt for `x` siden",
"Unsubscribe": "Opphev abonnement",
@@ -25,13 +25,13 @@
"Import and Export Data": "Importer- og eksporter data",
"Import": "Importer",
"Import Invidious data": "Importer Invidious-data",
- "Import YouTube subscriptions": "Importer YouTube-abonnenter",
- "Import FreeTube subscriptions (.db)": "Importer FreeTube-abonnenter (.db)",
- "Import NewPipe subscriptions (.json)": "Importer NewPipe-abonnenter (.json)",
+ "Import YouTube subscriptions": "Importer YouTube-abonnementer",
+ "Import FreeTube subscriptions (.db)": "Importer FreeTube-abonnementer (.db)",
+ "Import NewPipe subscriptions (.json)": "Importer NewPipe-abonnementer (.json)",
"Import NewPipe data (.zip)": "Importer NewPipe-data (.zip)",
"Export": "Eksporter",
- "Export subscriptions as OPML": "Eksporter abonnenter som OPML",
- "Export subscriptions as OPML (for NewPipe & FreeTube)": "Eksporter abonnenter som OPML (for NewPipe og FreeTube)",
+ "Export subscriptions as OPML": "Eksporter abonnementer som OPML",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Eksporter abonnementer som OPML (for NewPipe og FreeTube)",
"Export data as JSON": "Eksporter data som JSON",
"Delete account?": "Slett konto?",
"History": "Historikk",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "Vis JavaScript-lisensinfo.",
"View privacy policy.": "Vis personvernspraksis.",
"Trending": "Trendsettende",
- "Public": "",
+ "Public": "Offentlig",
"Unlisted": "Ulistet",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privat",
+ "View all playlists": "Vis alle spillelister",
+ "Updated `x` ago": "Oppdatert `x` siden",
+ "Delete playlist `x`?": "Slett spillelisten `x`?",
+ "Delete playlist": "Slett spilleliste",
+ "Create playlist": "Opprett spilleliste",
+ "Title": "Tittel",
+ "Playlist privacy": "Vern av spilleliste",
+ "Editing playlist `x`": "Redigerer spillelisten `x`",
"Watch on YouTube": "Vis video på YouTube",
"Hide annotations": "Skjul merknader",
"Show annotations": "Vis merknader",
@@ -197,12 +197,12 @@
"Token is expired, please try again": "Symbol utløpt, prøv igjen",
"English": "Engelsk",
"English (auto-generated)": "Engelsk (auto-generert)",
- "Afrikaans": "",
+ "Afrikaans": "Afrikansk",
"Albanian": "Albansk",
- "Amharic": "",
+ "Amharic": "Amharisk",
"Arabic": "Arabisk",
"Armenian": "Armensk",
- "Azerbaijani": "",
+ "Azerbaijani": "Aserbajdsjansk",
"Bangla": "",
"Basque": "",
"Belarusian": "Hviterussisk",
@@ -217,16 +217,16 @@
"Croatian": "",
"Czech": "Tsjekkisk",
"Danish": "Dansk",
- "Dutch": "",
+ "Dutch": "Nederlandsk",
"Esperanto": "Esperanto",
- "Estonian": "",
- "Filipino": "",
+ "Estonian": "Estisk",
+ "Filipino": "Filippinsk",
"Finnish": "Finsk",
"French": "Fransk",
"Galician": "",
"Georgian": "",
- "German": "",
- "Greek": "",
+ "German": "Tysk",
+ "Greek": "Gresk",
"Gujarati": "",
"Haitian Creole": "",
"Hausa": "",
@@ -309,7 +309,7 @@
"`x` minutes": "`x` minutter",
"`x` seconds": "`x` sekunder",
"Fallback comments: ": "Tilbakefallskommentarer: ",
- "Popular": "Pupulært",
+ "Popular": "Populært",
"Top": "Topp",
"About": "Om",
"Rating: ": "Vurdering: ",
diff --git a/locales/nl.json b/locales/nl.json
index cb233cea..29af954a 100644
--- a/locales/nl.json
+++ b/locales/nl.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` abonnees",
"`x` videos": "`x` video's",
- "`x` playlists": "",
+ "`x` playlists": "`x` afspeellijsten",
"LIVE": "LIVE",
"Shared `x` ago": "Gedeeld: `x` geleden",
"Unsubscribe": "Deabonneren",
@@ -69,11 +69,11 @@
"Show related videos: ": "Gerelateerde video's tonen? ",
"Show annotations by default: ": "Standaard annotaties tonen? ",
"Visual preferences": "Visuele instellingen",
- "Player style: ": "",
+ "Player style: ": "Speler vormgeving",
"Dark mode: ": "Donkere modus: ",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "Thema: ",
+ "dark": "donker",
+ "light": "licht",
"Thin mode: ": "Smalle modus: ",
"Subscription preferences": "Abonnementsinstellingen",
"Show annotations by default for subscribed channels: ": "Standaard annotaties tonen voor geabonneerde kanalen? ",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "JavaScript-licentieinformatie tonen.",
"View privacy policy.": "Privacybeleid tonen",
"Trending": "Uitgelicht",
- "Public": "",
+ "Public": "Publiek",
"Unlisted": "Verborgen",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Privé",
+ "View all playlists": "Bekijk alle afspeellijsten",
+ "Updated `x` ago": "`x` geleden aangepast",
+ "Delete playlist `x`?": "Afspeellijst `x` verwijderen?",
+ "Delete playlist": "Verwijder afspeellijst",
+ "Create playlist": "Nieuwe afspeellijst",
+ "Title": "Titel",
+ "Playlist privacy": "Afspeellijst privacy",
+ "Editing playlist `x`": "Afspeellijst `x` wijzigen",
"Watch on YouTube": "Video bekijken op YouTube",
"Hide annotations": "Annotaties verbergen",
"Show annotations": "Annotaties tonen",
@@ -331,6 +331,7 @@
"Video mode": "Videomodus",
"Videos": "Video's",
"Playlists": "Afspeellijsten",
- "Community": "",
- "Current version: ": "Huidige versie: "
+ "Community": "Gemeenschap",
+ "Current version: ": "Huidige versie: ",
+ "Download is disabled.": "Downloaden is uitgeschakeld."
} \ No newline at end of file
diff --git a/locales/pl.json b/locales/pl.json
index 74847608..32ff0530 100644
--- a/locales/pl.json
+++ b/locales/pl.json
@@ -1,13 +1,13 @@
{
"`x` subscribers": "`x` subskrybcji",
"`x` videos": "`x` filmów",
- "`x` playlists": "",
+ "`x` playlists": "`x` playlist",
"LIVE": "NA ŻYWO",
"Shared `x` ago": "Udostępniono `x` temu",
"Unsubscribe": "Odsubskrybuj",
"Subscribe": "Subskrybuj",
"View channel on YouTube": "Wyświetl kanał na YouTube",
- "View playlist on YouTube": "",
+ "View playlist on YouTube": "Zobacz playlistę na YouTube",
"newest": "najnowsze",
"oldest": "najstarsze",
"popular": "popularne",
@@ -15,11 +15,11 @@
"Next page": "Następna strona",
"Previous page": "Poprzednia strona",
"Clear watch history?": "Wyczyścić historię?",
- "New password": "",
- "New passwords must match": "",
- "Cannot change password for Google accounts": "",
- "Authorize token?": "",
- "Authorize token for `x`?": "",
+ "New password": "Nowe hasło",
+ "New passwords must match": "Nowe hasła muszą być identyczne",
+ "Cannot change password for Google accounts": "Nie można zmienić hasła do konta Google",
+ "Authorize token?": "Autoryzować token?",
+ "Authorize token for `x`?": "Autoryzować token dla `x`?",
"Yes": "Tak",
"No": "Nie",
"Import and Export Data": "Import i eksport danych",
@@ -54,7 +54,7 @@
"Player preferences": "Ustawienia odtwarzacza",
"Always loop: ": "Zawsze zapętlaj: ",
"Autoplay: ": "Autoodtwarzanie: ",
- "Play next by default: ": "",
+ "Play next by default: ": "Domyślnie odtwarzaj następny: ",
"Autoplay next video: ": "Odtwórz następny film: ",
"Listen by default: ": "Tryb dźwiękowy: ",
"Proxy videos: ": "Filmy przez proxy? ",
@@ -62,21 +62,21 @@
"Preferred video quality: ": "Preferowana jakość filmów: ",
"Player volume: ": "Głośność odtwarzacza: ",
"Default comments: ": "Domyślne komentarze: ",
- "youtube": "",
- "reddit": "",
+ "youtube": "youtube",
+ "reddit": "reddit",
"Default captions: ": "Domyślne napisy: ",
"Fallback captions: ": "Zastępcze napisy: ",
"Show related videos: ": "Pokaż powiązane filmy? ",
- "Show annotations by default: ": "",
+ "Show annotations by default: ": "Domyślnie pokazuj adnotacje: ",
"Visual preferences": "Preferencje Wizualne",
- "Player style: ": "",
+ "Player style: ": "Styl odtwarzacza: ",
"Dark mode: ": "Ciemny motyw: ",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "Motyw: ",
+ "dark": "ciemny",
+ "light": "jasny",
"Thin mode: ": "Tryb minimalny: ",
"Subscription preferences": "Preferencje subskrybcji",
- "Show annotations by default for subscribed channels: ": "",
+ "Show annotations by default for subscribed channels: ": "Domyślnie wyświetlaj adnotacje dla subskrybowanych kanałów: ",
"Redirect homepage to feed: ": "Przekieruj stronę główną do subskrybcji: ",
"Number of videos shown in feed: ": "Liczba filmów widoczna na stronie subskrybcji: ",
"Sort videos by: ": "Sortuj filmy: ",
@@ -90,34 +90,34 @@
"Only show latest unwatched video from channel: ": "Pokazuj tylko najnowszy nie obejrzany film z kanału: ",
"Only show unwatched: ": "Pokazuj tylko nie obejrzane: ",
"Only show notifications (if there are any): ": "Pokazuj tylko powiadomienia (jeśli są): ",
- "Enable web notifications": "",
- "`x` uploaded a video": "",
- "`x` is live": "",
+ "Enable web notifications": "Włącz powiadomienia",
+ "`x` uploaded a video": "`x` dodał film",
+ "`x` is live": "'x ' jest na żywo",
"Data preferences": "Preferencje danych",
"Clear watch history": "Wyczyść historię",
"Import/export data": "Import/Eksport danych",
- "Change password": "",
+ "Change password": "Zmień hasło",
"Manage subscriptions": "Organizuj subskrybcje",
- "Manage tokens": "",
+ "Manage tokens": "Zarządzaj tokenami",
"Watch history": "Historia",
"Delete account": "Usuń konto",
"Administrator preferences": "Preferencje administratora",
"Default homepage: ": "Domyślna strona główna: ",
"Feed menu: ": "",
- "Top enabled: ": "",
+ "Top enabled: ": "\"Top\" aktywne: ",
"CAPTCHA enabled: ": "CAPTCHA aktywna? ",
"Login enabled: ": "Logowanie włączone? ",
"Registration enabled: ": "Rejestracja włączona? ",
"Report statistics: ": "Raportować statystyki? ",
"Save preferences": "Zapisz preferencje",
"Subscription manager": "Manager subskrybcji",
- "Token manager": "",
- "Token": "",
+ "Token manager": "Menedżer tokenów",
+ "Token": "Token",
"`x` subscriptions": "`x` subskrybcji",
"`x` tokens": "",
"Import/export": "Import/Eksport",
"unsubscribe": "odsubskrybuj",
- "revoke": "",
+ "revoke": "cofnij",
"Subscriptions": "Subskrybcje",
"`x` unseen notifications": "`x` nowych powiadomień",
"search": "szukaj",
@@ -127,20 +127,20 @@
"View JavaScript license information.": "Wyświetl informację o licencji JavaScript.",
"View privacy policy.": "Polityka prywatności.",
"Trending": "Na czasie",
- "Public": "",
- "Unlisted": "",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Public": "Publiczne",
+ "Unlisted": "Niewidoczne",
+ "Private": "Prywatne",
+ "View all playlists": "Pokaż wszystkie playlisty",
+ "Updated `x` ago": "Zaktualizowano `x` temu",
+ "Delete playlist `x`?": "Usunąć playlistę 'x '?",
+ "Delete playlist": "Usuń playlistę",
+ "Create playlist": "Utwórz playlistę",
+ "Title": "Tytuł",
+ "Playlist privacy": "Widoczność playlisty",
+ "Editing playlist `x`": "Edycja playlisty `x`",
"Watch on YouTube": "Zobacz film na YouTube",
- "Hide annotations": "",
- "Show annotations": "",
+ "Hide annotations": "Ukryj adnotacje",
+ "Show annotations": "Pokaż adnotacje",
"Genre: ": "Gatunek: ",
"License: ": "Licencja: ",
"Family friendly? ": "Przyjazny rodzinie? ",
@@ -151,7 +151,7 @@
"Shared `x`": "Udostępniono `x`",
"`x` views": "`x` wyświetleń",
"Premieres in `x`": "Publikacja za `x`",
- "Premieres `x`": "",
+ "Premieres `x`": "Publikacja za `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Cześć! Wygląda na to, że masz wyłączoną obsługę JavaScriptu. Kliknij tutaj, żeby zobaczyć komentarze. Pamiętaj, że wczytywanie może potrwać dłużej.",
"View YouTube comments": "Wyświetl komentarze z YouTube",
"View more comments on Reddit": "Wyświetl więcej komentarzy na Reddicie",
@@ -310,7 +310,7 @@
"`x` seconds": "`x` sekund",
"Fallback comments: ": "Zastępcze komentarze: ",
"Popular": "Popularne",
- "Top": "Najczęściej oglądane",
+ "Top": "Top",
"About": "Informacje",
"Rating: ": "Ocena: ",
"Language: ": "Język: ",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "",
"(edited)": "(edytowany)",
"YouTube comment permalink": "Odnośnik bezpośredni do komentarza na YouTube",
- "permalink": "",
+ "permalink": "bezpośredni odnośnik",
"`x` marked it with a ❤": "`x` oznaczonych ❤",
"Audio mode": "Tryb audio",
"Video mode": "Tryb wideo",
"Videos": "Filmy",
"Playlists": "Playlisty",
- "Community": "",
+ "Community": "Społeczność",
"Current version: ": "Aktualna wersja: "
} \ No newline at end of file
diff --git a/locales/pt-BR.json b/locales/pt-BR.json
new file mode 100644
index 00000000..9dd237c6
--- /dev/null
+++ b/locales/pt-BR.json
@@ -0,0 +1,336 @@
+{
+ "`x` subscribers": "`x` inscritos",
+ "`x` videos": "`x` videos",
+ "`x` playlists": "`x` lista de reprodução",
+ "LIVE": "AO VIVO",
+ "Shared `x` ago": "Compartilhado `x` atrás",
+ "Unsubscribe": "Desinscrever-se",
+ "Subscribe": "Inscrever-se",
+ "View channel on YouTube": "Ver canal no YouTube",
+ "View playlist on YouTube": "Ver lista de reprodução no YouTube",
+ "newest": "mais recentes",
+ "oldest": "mais antigos",
+ "popular": "populares",
+ "last": "último",
+ "Next page": "Próxima página",
+ "Previous page": "Página anterior",
+ "Clear watch history?": "Limpar histórico de reprodução?",
+ "New password": "Nova senha",
+ "New passwords must match": "Nova senha deve ser igual",
+ "Cannot change password for Google accounts": "Não é possível alterar sua senha da conta Google",
+ "Authorize token?": "Autorizar o token?",
+ "Authorize token for `x`?": "Autorizar o token para `x`?",
+ "Yes": "Sim",
+ "No": "Não",
+ "Import and Export Data": "Importar e Exportar Dados",
+ "Import": "Importar",
+ "Import Invidious data": "Importar datos do Invidious",
+ "Import YouTube subscriptions": "Importar inscrições do YouTube",
+ "Import FreeTube subscriptions (.db)": "Importar inscrições do FreeTube (.db)",
+ "Import NewPipe subscriptions (.json)": "Importar inscrições do NewPipe (.json)",
+ "Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
+ "Export": "Exportar",
+ "Export subscriptions as OPML": "Exportar inscrições como OPML",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar inscrições como OPML (para NewPipe e FreeTube)",
+ "Export data as JSON": "Exportar dados como JSON",
+ "Delete account?": "Deletar conta?",
+ "History": "Histórico",
+ "An alternative front-end to YouTube": "Uma interface alternativa para o YouTube",
+ "JavaScript license information": "Informação de licença do JavaScript",
+ "source": "código fonte",
+ "Log in": "Entrar",
+ "Log in/register": "Entrar/Registrar",
+ "Log in with Google": "Entrar com conta Google",
+ "User ID": "Usuário",
+ "Password": "Senha",
+ "Time (h:mm:ss):": "Hora (h:mm:ss):",
+ "Text CAPTCHA": "CAPTCHA em texto",
+ "Image CAPTCHA": "CAPTCHA em imagen",
+ "Sign In": "Entrar",
+ "Register": "Registrar",
+ "E-mail": "E-mail",
+ "Google verification code": "Código de verificação do Google",
+ "Preferences": "Preferências",
+ "Player preferences": "Preferências do reprodutor",
+ "Always loop: ": "Repetir sempre: ",
+ "Autoplay: ": "Reprodução automática: ",
+ "Play next by default: ": "Sempre reproduzir próximo: ",
+ "Autoplay next video: ": "Reproduzir próximo video automaticamente: ",
+ "Listen by default: ": "Sempre ativar som: ",
+ "Proxy videos: ": "Usar proxy nos videos: ",
+ "Default speed: ": "Velocidade preferida: ",
+ "Preferred video quality: ": "Qualidade de video preferida: ",
+ "Player volume: ": "Volume de reprodução: ",
+ "Default comments: ": "Preferência de comentários: ",
+ "youtube": "youtube",
+ "reddit": "reddit",
+ "Default captions: ": "Preferência de legendas: ",
+ "Fallback captions: ": "Legendas alternativas: ",
+ "Show related videos: ": "Ver videos relacionados: ",
+ "Show annotations by default: ": "Sempre mostrar anotações: ",
+ "Visual preferences": "Preferências visuais",
+ "Player style: ": "Estilo do reprodutor",
+ "Dark mode: ": "Modo escuro: ",
+ "Theme: ": "Tema",
+ "dark": "escuro",
+ "light": "claro",
+ "Thin mode: ": "Modo compacto: ",
+ "Subscription preferences": "Preferências de inscrições",
+ "Show annotations by default for subscribed channels: ": "Sempre mostrar anotações nos videos de canais inscritos ",
+ "Redirect homepage to feed: ": "Redirecionar página inicial para o feed: ",
+ "Number of videos shown in feed: ": "Número de videos no feed: ",
+ "Sort videos by: ": "Ordenar videos por: ",
+ "published": "publicado",
+ "published - reverse": "publicado - ordem inversa",
+ "alphabetically": "alfabética",
+ "alphabetically - reverse": "alfabética - ordem inversa",
+ "channel name": "nome do canal",
+ "channel name - reverse": "nome do canal - ordem inversa",
+ "Only show latest video from channel: ": "Mostrar apenas o video mais recente do canal: ",
+ "Only show latest unwatched video from channel: ": "Mostrar apenas o video mais recente não visualizados do canal: ",
+ "Only show unwatched: ": "Mostrar apenas videos não visualizados: ",
+ "Only show notifications (if there are any): ": "Mostrar apenas notificações (se existentes): ",
+ "Enable web notifications": "Ativar notificações pela web",
+ "`x` uploaded a video": "`x` publicou um novo video",
+ "`x` is live": "`x` está ao vivo",
+ "Data preferences": "Preferências de dados",
+ "Clear watch history": "Limpar histórico de reprodução",
+ "Import/export data": "Importar/Exportar dados",
+ "Change password": "Alterar senha",
+ "Manage subscriptions": "Gerenciar inscrições",
+ "Manage tokens": "Gerenciar tokens",
+ "Watch history": "Histórico de reprodução",
+ "Delete account": "Apagar sua conta",
+ "Administrator preferences": "Preferências de administrador",
+ "Default homepage: ": "Página de inicio padrão: ",
+ "Feed menu: ": "Menú do feed: ",
+ "Top enabled: ": "Habilitar destaques: ",
+ "CAPTCHA enabled: ": "Habilitar CAPTCHA: ",
+ "Login enabled: ": "Habilitar login: ",
+ "Registration enabled: ": "Habilitar registro: ",
+ "Report statistics: ": "Habilitar estatísticas: ",
+ "Save preferences": "Salvar preferências",
+ "Subscription manager": "Gerenciador de inscrições",
+ "Token manager": "Gerenciador de tokens",
+ "Token": "Token",
+ "`x` subscriptions": "`x` inscrições",
+ "`x` tokens": "`x` tokens",
+ "Import/export": "Importar/Exportar",
+ "unsubscribe": "desinscrever-se",
+ "revoke": "revogar",
+ "Subscriptions": "Inscrições",
+ "`x` unseen notifications": "`x` notificações não visualizadas",
+ "search": "procurar",
+ "Log out": "Sair",
+ "Released under the AGPLv3 by Omar Roth.": "Publicado sob a licença AGPLv3, por Omar Roth.",
+ "Source available here.": "Código fonte disponível aqui.",
+ "View JavaScript license information.": "Ver informações da licença do JavaScript.",
+ "View privacy policy.": "Ver a política de privacidade",
+ "Trending": "Trending",
+ "Public": "Público",
+ "Unlisted": "No listado",
+ "Private": "Privado",
+ "View all playlists": "Mostrar todas listas de reprodução",
+ "Updated `x` ago": "Enviado `x` atrás",
+ "Delete playlist `x`?": "Apagar a playlist `x`?",
+ "Delete playlist": "Apagar playlist",
+ "Create playlist": "Criar playlist",
+ "Title": "Título",
+ "Playlist privacy": "Privacidade da playlist",
+ "Editing playlist `x`": "Editando playlist",
+ "Watch on YouTube": "Assistir vídeo no YouTube",
+ "Hide annotations": "Ocultar anotações",
+ "Show annotations": "Mostrar anotações",
+ "Genre: ": "Gênero: ",
+ "License: ": "Licença: ",
+ "Family friendly? ": "Fistrar conteúdo impróprio: ",
+ "Wilson score: ": "Pontuação de Wilson: ",
+ "Engagement: ": "Engagement: ",
+ "Whitelisted regions: ": "Regiões permitidas: ",
+ "Blacklisted regions: ": "Regiões bloqueadas: ",
+ "Shared `x`": "Compartilhado `x`",
+ "`x` views": "`x` visualizações",
+ "Premieres in `x`": "Estreias em `x`",
+ "Premieres `x`": "Estreia `x`",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Oi! Parece que seu JavaScript está desativado. Clique aqui para ver os comentários, entretanto eles podem levar um pouco mais de tempo para carregar.",
+ "View YouTube comments": "Ver comentários do YouTube",
+ "View more comments on Reddit": "Ver mais comentários do Reddit",
+ "View `x` comments": "Ver `x` comentários",
+ "View Reddit comments": "Ver comentários do Reddit",
+ "Hide replies": "Ocultar respostas",
+ "Show replies": "Mostrar respostas",
+ "Incorrect password": "Senha incorreta",
+ "Quota exceeded, try again in a few hours": "Cota excedida, tente novamente em algumas horas",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Não foi possível fazer login, sua autenticação por dois passos (app autenticador ou sms) deve estar ativada.",
+ "Invalid TFA code": "Código TFA inválido",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Falha no login. Isso pode acontecer pois a autenticação por dois passos está desativada para sua conta.",
+ "Wrong answer": "Respuesta inválida",
+ "Erroneous CAPTCHA": "CAPTCHA inválido",
+ "CAPTCHA is a required field": "O CAPTCHA é um campo obrigatório",
+ "User ID is a required field": "O nome de usuário é um campo obrigatório",
+ "Password is a required field": "A senha é um campo obrigatório",
+ "Wrong username or password": "Nome de usuário ou senha inválidos",
+ "Please sign in using 'Log in with Google'": "Por favor, entre usando 'Entrar com conta Google'",
+ "Password cannot be empty": "A senha não pode estar vazia",
+ "Password cannot be longer than 55 characters": "A senha não pode ter mais que 55 caracteres",
+ "Please log in": "Por favor, inicie sua seção",
+ "Invidious Private Feed for `x`": "Feed Privado do Invidious para `x`",
+ "channel:`x`": "canal: `x`",
+ "Deleted or invalid channel": "Este canal foi apagado ou é inválido",
+ "This channel does not exist.": "Este canal não existe.",
+ "Could not get channel info.": "Não foi possível obter as informações do canal.",
+ "Could not fetch comments": "Não foi possível obter os comentários",
+ "View `x` replies": "Ver `x` respostas",
+ "`x` ago": "`x` atrás",
+ "Load more": "Carregar mais",
+ "`x` points": "`x` pontos",
+ "Could not create mix.": "Não foi possível criar o mix.",
+ "Empty playlist": "A lista de reprodução está vazia",
+ "Not a playlist.": "Lista de reprodução inválida.",
+ "Playlist does not exist.": "A lista de reprodução não existe.",
+ "Could not pull trending pages.": "Não foi possível oberter as páginas dos videos em alta.",
+ "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
+ "Hidden field \"token\" is a required field": "O campo oculto \"token\" é obrigatório",
+ "Erroneous challenge": "Desafío inválido",
+ "Erroneous token": "Símbolo inválido",
+ "No such user": "Usuario inválido",
+ "Token is expired, please try again": "Token expirou, tente novamente",
+ "English": "Inglês",
+ "English (auto-generated)": "Inglês (gerado automaticamente)",
+ "Afrikaans": "Africâner",
+ "Albanian": "Albanês",
+ "Amharic": "Amárico",
+ "Arabic": "Árabe",
+ "Armenian": "Armênio",
+ "Azerbaijani": "Azeri",
+ "Bangla": "Bengalês",
+ "Basque": "Basco",
+ "Belarusian": "Bielorrusso",
+ "Bosnian": "Língua Bósnia",
+ "Bulgarian": "Búlgaro",
+ "Burmese": "Birmanês",
+ "Catalan": "Catalão",
+ "Cebuano": "Cebuano",
+ "Chinese (Simplified)": "Chinês Simplificado",
+ "Chinese (Traditional)": "Chinês Tradicional",
+ "Corsican": "Corso",
+ "Croatian": "Croata",
+ "Czech": "Checo",
+ "Danish": "Dinamarquês",
+ "Dutch": "Holandês",
+ "Esperanto": "Esperanto",
+ "Estonian": "Estoniano",
+ "Filipino": "Filipino",
+ "Finnish": "Finlandês",
+ "French": "Francês",
+ "Galician": "Galego",
+ "Georgian": "Georgiano",
+ "German": "Alemão",
+ "Greek": "Grego",
+ "Gujarati": "Guzerate",
+ "Haitian Creole": "Crioulo Haitiano",
+ "Hausa": "Hauçá",
+ "Hawaiian": "Havaiano",
+ "Hebrew": "Hebraico",
+ "Hindi": "Hindi",
+ "Hmong": "Hmong",
+ "Hungarian": "Húngaro",
+ "Icelandic": "Islandês",
+ "Igbo": "Igbo",
+ "Indonesian": "Indonésio",
+ "Irish": "Irlandês",
+ "Italian": "Italiano",
+ "Japanese": "Japonês",
+ "Javanese": "Javanês",
+ "Kannada": "Canarẽs",
+ "Kazakh": "Cazaque",
+ "Khmer": "Khmer",
+ "Korean": "Coreano",
+ "Kurdish": "Curdo",
+ "Kyrgyz": "Quirguiz",
+ "Lao": "Laosiano",
+ "Latin": "Latim",
+ "Latvian": "Letão",
+ "Lithuanian": "Lituano",
+ "Luxembourgish": "Luxemburguês",
+ "Macedonian": "Macedônio",
+ "Malagasy": "Malgaxe",
+ "Malay": "Malaia",
+ "Malayalam": "Malaiala",
+ "Maltese": "Maltês",
+ "Maori": "Maori",
+ "Marathi": "Marathi",
+ "Mongolian": "Mongol",
+ "Nepali": "Nepalês",
+ "Norwegian Bokmål": "Bokmål Norueguês",
+ "Nyanja": "Nianja",
+ "Pashto": "Pachto",
+ "Persian": "Persa",
+ "Polish": "Polaco",
+ "Portuguese": "Português",
+ "Punjabi": "Panjábi",
+ "Romanian": "Língua Romena",
+ "Russian": "Russo",
+ "Samoan": "Samoano",
+ "Scottish Gaelic": "Ânglico Escocês",
+ "Serbian": "Língua Sérvia",
+ "Shona": "Xona",
+ "Sindhi": "Sindi",
+ "Sinhala": "Cingalês",
+ "Slovak": "Eslovaco",
+ "Slovenian": "Esloveno",
+ "Somali": "Língua Somalí",
+ "Southern Sotho": "Sesoto",
+ "Spanish": "Espanhol",
+ "Spanish (Latin America)": "Espanhol (América)",
+ "Sundanese": "Sondanese",
+ "Swahili": "Suaíli",
+ "Swedish": "Suéco",
+ "Tajik": "Tajiques",
+ "Tamil": "Tâmil",
+ "Telugu": "Telugo",
+ "Thai": "Tailandês",
+ "Turkish": "Turco",
+ "Ukrainian": "Ucraniano",
+ "Urdu": "Urdu",
+ "Uzbek": "Uzbeque",
+ "Vietnamese": "Vietnamita",
+ "Welsh": "Galês",
+ "Western Frisian": "Língua Frísia",
+ "Xhosa": "Xhosa",
+ "Yiddish": "Iídiche",
+ "Yoruba": "Iorubá",
+ "Zulu": "Língua Zulú",
+ "`x` years": "`x` anos",
+ "`x` months": "`x` meses",
+ "`x` weeks": "`x` semanas",
+ "`x` days": "`x` dias",
+ "`x` hours": "`x` horas",
+ "`x` minutes": "`x` minutos",
+ "`x` seconds": "`x` segundos",
+ "Fallback comments: ": "Comentários alternativos: ",
+ "Popular": "Populares",
+ "Top": "No topo",
+ "About": "Sobre",
+ "Rating: ": "Avaliação: ",
+ "Language: ": "Idioma: ",
+ "View as playlist": "Ver como lista de reprodução",
+ "Default": "Configuração padrão",
+ "Music": "Música",
+ "Gaming": "Video Games",
+ "News": "Notícias",
+ "Movies": "Filmes",
+ "Download": "Baixar",
+ "Download as: ": "Baixar como: ",
+ "%A %B %-d, %Y": "%A %-d %B %Y",
+ "(edited)": "(editado)",
+ "YouTube comment permalink": "Link permanente do comentário do YouTube",
+ "permalink": "Link permanente",
+ "`x` marked it with a ❤": "`x` foi marcado como ❤",
+ "Audio mode": "Modo de audio",
+ "Video mode": "Modo de video",
+ "Videos": "Vídeos",
+ "Playlists": "Listas de reprodução",
+ "Community": "Comunidade",
+ "Current version: ": "Versão atual: "
+} \ No newline at end of file
diff --git a/locales/pt-PT.json b/locales/pt-PT.json
new file mode 100644
index 00000000..ab7d3468
--- /dev/null
+++ b/locales/pt-PT.json
@@ -0,0 +1,387 @@
+{
+ "`x` subscribers.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscritores.",
+ "": "`x` subscritores."
+ },
+ "`x` videos.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` vídeos.",
+ "": "`x` vídeos."
+ },
+ "`x` playlists.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` listas de reprodução.",
+ "": "`x` listas de reprodução."
+ },
+ "LIVE": "Em direto",
+ "Shared `x` ago": "Partilhado `x` atrás",
+ "Unsubscribe": "Anular subscrição",
+ "Subscribe": "Subscrever",
+ "View channel on YouTube": "Ver canal no YouTube",
+ "View playlist on YouTube": "Ver lista de reprodução no YouTube",
+ "newest": "mais recentes",
+ "oldest": "mais antigos",
+ "popular": "popular",
+ "last": "últimos",
+ "Next page": "Próxima página",
+ "Previous page": "Página anterior",
+ "Clear watch history?": "Limpar histórico de reprodução?",
+ "New password": "Nova palavra-chave",
+ "New passwords must match": "As novas palavra-chaves devem corresponder",
+ "Cannot change password for Google accounts": "Não é possível alterar palavra-chave para contas do Google",
+ "Authorize token?": "Autorizar token?",
+ "Authorize token for `x`?": "Autorizar token para `x`?",
+ "Yes": "Sim",
+ "No": "Não",
+ "Import and Export Data": "Importar e Exportar Dados",
+ "Import": "Importar",
+ "Import Invidious data": "Importar dados do Invidious",
+ "Import YouTube subscriptions": "Importar subscrições do YouTube",
+ "Import FreeTube subscriptions (.db)": "Importar subscrições do FreeTube (.db)",
+ "Import NewPipe subscriptions (.json)": "Importar subscrições do NewPipe (.json)",
+ "Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
+ "Export": "Exportar",
+ "Export subscriptions as OPML": "Exportar subscrições como OPML",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar subscrições como OPML (para NewPipe e FreeTube)",
+ "Export data as JSON": "Exportar dados como JSON",
+ "Delete account?": "Eliminar conta?",
+ "History": "Histórico",
+ "An alternative front-end to YouTube": "Uma interface alternativa para o YouTube",
+ "JavaScript license information": "Informação de licença do JavaScript",
+ "source": "código-fonte",
+ "Log in": "Iniciar sessão",
+ "Log in/register": "Iniciar sessão/Registar",
+ "Log in with Google": "Iniciar sessão com o Google",
+ "User ID": "Utilizador",
+ "Password": "Palavra-chave",
+ "Time (h:mm:ss):": "Tempo (h:mm:ss):",
+ "Text CAPTCHA": "Texto CAPTCHA",
+ "Image CAPTCHA": "Imagem CAPTCHA",
+ "Sign In": "Iniciar Sessão",
+ "Register": "Registar",
+ "E-mail": "E-mail",
+ "Google verification code": "Código de verificação do Google",
+ "Preferences": "Preferências",
+ "Player preferences": "Preferências do reprodutor",
+ "Always loop: ": "Repetir sempre: ",
+ "Autoplay: ": "Reprodução automática: ",
+ "Play next by default: ": "Sempre reproduzir próximo: ",
+ "Autoplay next video: ": "Reproduzir próximo vídeo automaticamente: ",
+ "Listen by default: ": "Apenas áudio: ",
+ "Proxy videos: ": "Usar proxy nos vídeos: ",
+ "Default speed: ": "Velocidade preferida: ",
+ "Preferred video quality: ": "Qualidade de vídeo preferida: ",
+ "Player volume: ": "Volume da reprodução: ",
+ "Default comments: ": "Preferência dos comentários: ",
+ "youtube": "youtube",
+ "reddit": "reddit",
+ "Default captions: ": "Legendas predefinidas: ",
+ "Fallback captions: ": "Legendas alternativas: ",
+ "Show related videos: ": "Mostrar vídeos relacionados: ",
+ "Show annotations by default: ": "Mostrar sempre anotações: ",
+ "Visual preferences": "Preferências visuais",
+ "Player style: ": "Estilo do reprodutor: ",
+ "Dark mode: ": "Modo escuro: ",
+ "Theme: ": "Tema: ",
+ "dark": "escuro",
+ "light": "claro",
+ "Thin mode: ": "Modo compacto: ",
+ "Subscription preferences": "Preferências de subscrições",
+ "Show annotations by default for subscribed channels: ": "Mostrar sempre anotações para os canais subscritos: ",
+ "Redirect homepage to feed: ": "Redirecionar página inicial para subscrições: ",
+ "Number of videos shown in feed: ": "Número de vídeos nas subscrições: ",
+ "Sort videos by: ": "Ordenar vídeos por: ",
+ "published": "publicado",
+ "published - reverse": "publicado - inverso",
+ "alphabetically": "alfabeticamente",
+ "alphabetically - reverse": "alfabeticamente - inverso",
+ "channel name": "nome do canal",
+ "channel name - reverse": "nome do canal - inverso",
+ "Only show latest video from channel: ": "Mostrar apenas o vídeo mais recente do canal: ",
+ "Only show latest unwatched video from channel: ": "Mostrar apenas vídeos mais recentes não visualizados do canal: ",
+ "Only show unwatched: ": "Mostrar apenas vídeos não visualizados: ",
+ "Only show notifications (if there are any): ": "Mostrar apenas notificações (se existirem): ",
+ "Enable web notifications": "Ativar notificações pela web",
+ "`x` uploaded a video": "`x` publicou um novo vídeo",
+ "`x` is live": "`x` está em direto",
+ "Data preferences": "Preferências de dados",
+ "Clear watch history": "Limpar histórico de reprodução",
+ "Import/export data": "Importar/Exportar dados",
+ "Change password": "Alterar palavra-chave",
+ "Manage subscriptions": "Gerir as subscrições",
+ "Manage tokens": "Gerir tokens",
+ "Watch history": "Histórico de reprodução",
+ "Delete account": "Eliminar conta",
+ "Administrator preferences": "Preferências de administrador",
+ "Default homepage: ": "Página inicial padrão: ",
+ "Feed menu: ": "Menu de subscrições: ",
+ "Top enabled: ": "Top ativado: ",
+ "CAPTCHA enabled: ": "CAPTCHA ativado: ",
+ "Login enabled: ": "Iniciar sessão ativado: ",
+ "Registration enabled: ": "Registar ativado: ",
+ "Report statistics: ": "Relatório de estatísticas: ",
+ "Save preferences": "Gravar preferências",
+ "Subscription manager": "Gerir subscrições",
+ "Token manager": "Gerir tokens",
+ "Token": "Token",
+ "`x` subscriptions.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` subscrições.",
+ "": "`x` subscrições."
+ },
+ "`x` tokens.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` tokens.",
+ "": "`x` tokens."
+ },
+ "Import/export": "Importar/Exportar",
+ "unsubscribe": "Anular subscrição",
+ "revoke": "revogar",
+ "Subscriptions": "Subscrições",
+ "`x` unseen notifications.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` notificações não vistas.",
+ "": "`x` notificações não vistas."
+ },
+ "search": "Pesquisar",
+ "Log out": "Terminar sessão",
+ "Released under the AGPLv3 by Omar Roth.": "Publicado sob a licença AGPLv3, por Omar Roth.",
+ "Source available here.": "Código-fonte disponível aqui.",
+ "View JavaScript license information.": "Ver informações da licença do JavaScript.",
+ "View privacy policy.": "Ver a política de privacidade.",
+ "Trending": "Tendências",
+ "Public": "Público",
+ "Unlisted": "Não listado",
+ "Private": "Privado",
+ "View all playlists": "Ver todas as listas de reprodução",
+ "Updated `x` ago": "Atualizado `x` atrás",
+ "Delete playlist `x`?": "Eliminar a lista de reprodução 'x'?",
+ "Delete playlist": "Eliminar lista de reprodução",
+ "Create playlist": "Criar lista de reprodução",
+ "Title": "Título",
+ "Playlist privacy": "Privacidade da lista de reprodução",
+ "Editing playlist `x`": "A editar lista de reprodução 'x'",
+ "Watch on YouTube": "Ver no YouTube",
+ "Hide annotations": "Ocultar anotações",
+ "Show annotations": "Mostrar anotações",
+ "Genre: ": "Género: ",
+ "License: ": "Licença: ",
+ "Family friendly? ": "Filtrar conteúdo impróprio: ",
+ "Wilson score: ": "Pontuação de Wilson: ",
+ "Engagement: ": "Compromisso: ",
+ "Whitelisted regions: ": "Regiões permitidas: ",
+ "Blacklisted regions: ": "Regiões bloqueadas: ",
+ "Shared `x`": "Partilhado `x`",
+ "`x` views.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` visualizações.",
+ "": "`x` visualizações."
+ },
+ "Premieres in `x`": "Estreias em 'x'",
+ "Premieres `x`": "Estreias 'x'",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Oi! Parece que JavaScript está desativado. Clique aqui para ver os comentários, entretanto eles podem levar mais tempo para carregar.",
+ "View YouTube comments": "Ver comentários do YouTube",
+ "View more comments on Reddit": "Ver mais comentários no Reddit",
+ "View `x` comments.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentários.",
+ "": "Ver `x` comentários."
+ },
+ "View Reddit comments": "Ver comentários do Reddit",
+ "Hide replies": "Ocultar respostas",
+ "Show replies": "Mostrar respostas",
+ "Incorrect password": "Palavra-chave incorreta",
+ "Quota exceeded, try again in a few hours": "Cota excedida. Tente novamente dentro de algumas horas",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Não é possível iniciar sessão, certifique-se de que a autenticação de dois fatores (Autenticador ou SMS) está ativada.",
+ "Invalid TFA code": "Código TFA inválido",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Falhou o início de sessão. Isto pode ser devido a dois fatores de autenticação não está ativado para sua conta.",
+ "Wrong answer": "Resposta errada",
+ "Erroneous CAPTCHA": "CAPTCHA inválido",
+ "CAPTCHA is a required field": "CAPTCHA é um campo obrigatório",
+ "User ID is a required field": "O nome de utilizador é um campo obrigatório",
+ "Password is a required field": "Palavra-chave é um campo obrigatório",
+ "Wrong username or password": "Nome de utilizador ou palavra-chave incorreto",
+ "Please sign in using 'Log in with Google'": "Por favor, inicie sessão usando 'Iniciar sessão com o Google'",
+ "Password cannot be empty": "A palavra-chave não pode estar vazia",
+ "Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres",
+ "Please log in": "Por favor, inicie sessão",
+ "Invidious Private Feed for `x`": "Feed Privado do Invidious para `x`",
+ "channel:`x`": "canal:'x'",
+ "Deleted or invalid channel": "Canal apagado ou inválido",
+ "This channel does not exist.": "Este canal não existe.",
+ "Could not get channel info.": "Não foi possível obter as informações do canal.",
+ "Could not fetch comments": "Não foi possível obter os comentários",
+ "View `x` replies.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` respostas.",
+ "": "Ver `x` respostas."
+ },
+ "`x` ago": "`x` atrás",
+ "Load more": "Carregar mais",
+ "`x` points.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "'x' pontos.",
+ "": "'x' pontos."
+ },
+ "Could not create mix.": "Não foi possível criar mistura.",
+ "Empty playlist": "Lista de reprodução vazia",
+ "Not a playlist.": "Não é uma lista de reprodução.",
+ "Playlist does not exist.": "A lista de reprodução não existe.",
+ "Could not pull trending pages.": "Não foi possível obter páginas de tendências.",
+ "Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
+ "Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório",
+ "Erroneous challenge": "Desafio inválido",
+ "Erroneous token": "Token inválido",
+ "No such user": "Utilizador inválido",
+ "Token is expired, please try again": "Token expirou, tente novamente",
+ "English": "Inglês",
+ "English (auto-generated)": "Inglês (auto-gerado)",
+ "Afrikaans": "Africano",
+ "Albanian": "Albanês",
+ "Amharic": "Amárico",
+ "Arabic": "Árabe",
+ "Armenian": "Arménio",
+ "Azerbaijani": "Azerbaijano",
+ "Bangla": "Bangla",
+ "Basque": "Basco",
+ "Belarusian": "Bielorrusso",
+ "Bosnian": "Bósnio",
+ "Bulgarian": "Búlgaro",
+ "Burmese": "Birmanês",
+ "Catalan": "Catalão",
+ "Cebuano": "Cebuano",
+ "Chinese (Simplified)": "Chinês (Simplificado)",
+ "Chinese (Traditional)": "Chinês (Tradicional)",
+ "Corsican": "Corso",
+ "Croatian": "Croata",
+ "Czech": "Checo",
+ "Danish": "Dinamarquês",
+ "Dutch": "Holandês",
+ "Esperanto": "Esperanto",
+ "Estonian": "Estónio",
+ "Filipino": "Filipino",
+ "Finnish": "Finlandês",
+ "French": "Francês",
+ "Galician": "Galego",
+ "Georgian": "Georgiano",
+ "German": "Alemão",
+ "Greek": "Grego",
+ "Gujarati": "Guzerate",
+ "Haitian Creole": "Crioulo haitiano",
+ "Hausa": "Hauçá",
+ "Hawaiian": "Havaiano",
+ "Hebrew": "Hebraico",
+ "Hindi": "Hindi",
+ "Hmong": "Hmong",
+ "Hungarian": "Húngaro",
+ "Icelandic": "Islandês",
+ "Igbo": "Igbo",
+ "Indonesian": "Indonésio",
+ "Irish": "Irlandês",
+ "Italian": "Italiano",
+ "Japanese": "Japonês",
+ "Javanese": "Javanês",
+ "Kannada": "Canarim",
+ "Kazakh": "Cazaque",
+ "Khmer": "Khmer",
+ "Korean": "Coreano",
+ "Kurdish": "Curdo",
+ "Kyrgyz": "Quirguiz",
+ "Lao": "Laosiano",
+ "Latin": "Latim",
+ "Latvian": "Letão",
+ "Lithuanian": "Lituano",
+ "Luxembourgish": "Luxemburguês",
+ "Macedonian": "Macedónio",
+ "Malagasy": "Malgaxe",
+ "Malay": "Malaio",
+ "Malayalam": "Malaiala",
+ "Maltese": "Maltês",
+ "Maori": "Maori",
+ "Marathi": "Marathi",
+ "Mongolian": "Mongol",
+ "Nepali": "Nepalês",
+ "Norwegian Bokmål": "Bokmål norueguês",
+ "Nyanja": "Nyanja",
+ "Pashto": "Pashto",
+ "Persian": "Persa",
+ "Polish": "Polaco",
+ "Portuguese": "Português",
+ "Punjabi": "Punjabi",
+ "Romanian": "Romeno",
+ "Russian": "Russo",
+ "Samoan": "Samoano",
+ "Scottish Gaelic": "Gaélico escocês",
+ "Serbian": "Sérvio",
+ "Shona": "Shona",
+ "Sindhi": "Sindhi",
+ "Sinhala": "Cingalês",
+ "Slovak": "Eslovaco",
+ "Slovenian": "Esloveno",
+ "Somali": "Somali",
+ "Southern Sotho": "Sotho do Sul",
+ "Spanish": "Espanhol",
+ "Spanish (Latin America)": "Espanhol (América Latina)",
+ "Sundanese": "Sudanês",
+ "Swahili": "Suaíli",
+ "Swedish": "Sueco",
+ "Tajik": "Tajique",
+ "Tamil": "Tâmil",
+ "Telugu": "Telugu",
+ "Thai": "Tailandês",
+ "Turkish": "Turco",
+ "Ukrainian": "Ucraniano",
+ "Urdu": "Urdu",
+ "Uzbek": "Uzbeque",
+ "Vietnamese": "Vietnamita",
+ "Welsh": "Galês",
+ "Western Frisian": "Frísio Ocidental",
+ "Xhosa": "Xhosa",
+ "Yiddish": "Iídiche",
+ "Yoruba": "Ioruba",
+ "Zulu": "Zulu",
+ "`x` years.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` anos.",
+ "": "`x` anos."
+ },
+ "`x` months.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` meses.",
+ "": "`x` meses."
+ },
+ "`x` weeks.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` semanas.",
+ "": "`x` semanas."
+ },
+ "`x` days.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` dias.",
+ "": "`x` dias."
+ },
+ "`x` hours.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` horas.",
+ "": "`x` horas."
+ },
+ "`x` minutes.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` minutos.",
+ "": "`x` minutos."
+ },
+ "`x` seconds.": {
+ "([^.,0-9]|^)1([^.,0-9]|$)": "`x` segundos.",
+ "": "`x` segundos."
+ },
+ "Fallback comments: ": "Comentários alternativos: ",
+ "Popular": "Popular",
+ "Top": "Top",
+ "About": "Sobre",
+ "Rating: ": "Avaliação: ",
+ "Language: ": "Idioma: ",
+ "View as playlist": "Ver como lista de reprodução",
+ "Default": "Predefinição",
+ "Music": "Música",
+ "Gaming": "Jogos",
+ "News": "Notícias",
+ "Movies": "Filmes",
+ "Download": "Transferir",
+ "Download as: ": "Transferir como: ",
+ "%A %B %-d, %Y": "%A %B %-d, %Y",
+ "(edited)": "(editado)",
+ "YouTube comment permalink": "Link permanente do comentário do YouTube",
+ "permalink": "ligação permanente",
+ "`x` marked it with a ❤": "`x` foi marcado como ❤",
+ "Audio mode": "Modo de áudio",
+ "Video mode": "Modo de vídeo",
+ "Videos": "Vídeos",
+ "Playlists": "Listas de reprodução",
+ "Community": "Comunidade",
+ "Current version: ": "Versão atual: "
+} \ No newline at end of file
diff --git a/locales/ro.json b/locales/ro.json
new file mode 100644
index 00000000..08d2c386
--- /dev/null
+++ b/locales/ro.json
@@ -0,0 +1,336 @@
+{
+ "`x` subscribers": "`x` abonați",
+ "`x` videos": "`x` videoclipuri",
+ "`x` playlists": "`x` liste de redare",
+ "LIVE": "ÎN DIRECT",
+ "Shared `x` ago": "Adăugat acum `x`",
+ "Unsubscribe": "Dezabonați-vă",
+ "Subscribe": "Abonați-vă",
+ "View channel on YouTube": "Vedeți canalul pe YouTube",
+ "View playlist on YouTube": "Vedeți lista de redare pe YouTube",
+ "newest": "Data adăugării (cea mai recentă)",
+ "oldest": "Data adăugării (cea mai veche)",
+ "popular": "Cele mai populare",
+ "last": "Ultimele",
+ "Next page": "Pagina următoare",
+ "Previous page": "Pagina precedentă",
+ "Clear watch history?": "Doriți să ștergeți istoricul?",
+ "New password": "Parola nouă",
+ "New passwords must match": "Câmpurile \"Parolă nouă\" trebuie să fie identice",
+ "Cannot change password for Google accounts": "Parola pentru un cont Google nu poate fi schimbată de pe Invidious",
+ "Authorize token?": "Autorizați token-ul?",
+ "Authorize token for `x`?": "Autorizați token-ul pentru `x` ?",
+ "Yes": "Da",
+ "No": "Nu",
+ "Import and Export Data": "Importați și Exportați Datele",
+ "Import": "Importați",
+ "Import Invidious data": "Importați Datele de pe Invidious",
+ "Import YouTube subscriptions": "Importați abonamentele de pe YouTube",
+ "Import FreeTube subscriptions (.db)": "Importați abonamentele de pe FreeTube (.db)",
+ "Import NewPipe subscriptions (.json)": "Importați abonamentele de pe NewPipe (.json)",
+ "Import NewPipe data (.zip)": "Importați datele de pe NewPipe (.zip)",
+ "Export": "Exportați",
+ "Export subscriptions as OPML": "Exportați abonamentele în format OPML",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportați abonamentele în format OPML (pentru NewPipe și FreeTube)",
+ "Export data as JSON": "Exportați datele în format JSON",
+ "Delete account?": "Sunteți siguri că doriți să vă ștergeți contul?",
+ "History": "Istoric",
+ "An alternative front-end to YouTube": "O alternativă front-end pentru YouTube",
+ "JavaScript license information": "Informații despre licențele JavaScript",
+ "source": "sursă",
+ "Log in": "Conectați-vă",
+ "Log in/register": "Conectați-vă/Creați-vă un cont",
+ "Log in with Google": "Conectați-vă cu Google",
+ "User ID": "ID Utilizator",
+ "Password": "Parolă",
+ "Time (h:mm:ss):": "Ora (h:mm:ss) :",
+ "Text CAPTCHA": "Text CAPTCHA",
+ "Image CAPTCHA": "Imagine CAPTCHA",
+ "Sign In": "Conectați-vă",
+ "Register": "Înregistrați-vă",
+ "E-mail": "E-mail",
+ "Google verification code": "Cod de verificare Google",
+ "Preferences": "Preferințe",
+ "Player preferences": "Setări de redare",
+ "Always loop: ": "Reluați videoclipul la nesfârșit: ",
+ "Autoplay: ": "Porniți videoclipurile automat: ",
+ "Play next by default: ": "Vizionați următoarele videoclipuri în mod implicit: ",
+ "Autoplay next video: ": "Porniți următorul videoclip automat: ",
+ "Listen by default: ": "Numai audio: ",
+ "Proxy videos: ": "Redați videoclipurile printr-un proxy: ",
+ "Default speed: ": "Viteza de redare implicită: ",
+ "Preferred video quality: ": "Calitatea videoclipurilor: ",
+ "Player volume: ": "Volumul videoclipurilor: ",
+ "Default comments: ": "Sursa comentariilor: ",
+ "youtube": "YouTube",
+ "reddit": "Reddit",
+ "Default captions: ": "Subtitrări implicite: ",
+ "Fallback captions: ": "Subtitrări alternative: ",
+ "Show related videos: ": "Afișați videoclipurile asemănătoare: ",
+ "Show annotations by default: ": "Afișați adnotările în mod implicit: ",
+ "Visual preferences": "Preferințele site-ului",
+ "Player style: ": "Stilul player-ului : ",
+ "Dark mode: ": "Modul întunecat : ",
+ "Theme: ": "Tema : ",
+ "dark": "întunecat",
+ "light": "luminos",
+ "Thin mode: ": "Mod lejer: ",
+ "Subscription preferences": "Preferințele paginii de abonamente",
+ "Show annotations by default for subscribed channels: ": "Afișați adnotările în mod implicit pentru canalele la care v-ați abonat: ",
+ "Redirect homepage to feed: ": "Redirecționați pagina principală la pagina de abonamente: ",
+ "Number of videos shown in feed: ": "Numărul de videoclipuri afișate pe pagina de abonamente: ",
+ "Sort videos by: ": "Sortați videoclipurile în funcție de: ",
+ "published": "data publicării",
+ "published - reverse": "data publicării - inversată",
+ "alphabetically": "în ordine alfabetică",
+ "alphabetically - reverse": "în ordine alfabetică - inversată",
+ "channel name": "numele canalului",
+ "channel name - reverse": "numele canalului - inversat",
+ "Only show latest video from channel: ": "Afișați numai cel mai recent videoclip publicat de canalele la care v-ați abonat: ",
+ "Only show latest unwatched video from channel: ": "Afișați numai cel mai recent videoclip nevizionat publicat de canalele la care v-ați abonat: ",
+ "Only show unwatched: ": "Afișați numai videoclipurile nevizionate: ",
+ "Only show notifications (if there are any): ": "Afișați numai notificările (dacă există): ",
+ "Enable web notifications": "Activați notificările web",
+ "`x` uploaded a video": "`x` a publicat un videoclip",
+ "`x` is live": "`x` este în direct",
+ "Data preferences": "Preferințe legate de date",
+ "Clear watch history": "Ștergeți istoricul videoclipurilor vizionate",
+ "Import/export data": "Importați/exportați datele",
+ "Change password": "Schimbați parola",
+ "Manage subscriptions": "Gestionați abonamentele",
+ "Manage tokens": "Gestionați tokenele",
+ "Watch history": "Istoricul videoclipurilor vizionate",
+ "Delete account": "Ștergeți contul",
+ "Administrator preferences": "Preferințele Administratorului",
+ "Default homepage: ": "Pagina principală implicită: ",
+ "Feed menu: ": "Preferințe legate de pagina de abonamente: ",
+ "Top enabled: ": "Top activat: ",
+ "CAPTCHA enabled: ": "CAPTCHA activat : ",
+ "Login enabled: ": "Autentificare activată : ",
+ "Registration enabled: ": "Înregistrate activată: ",
+ "Report statistics: ": "Raportarea statisticilor: ",
+ "Save preferences": "Salvați preferințele",
+ "Subscription manager": "Gestionați abonamentele",
+ "Token manager": "Manager de Tokene",
+ "Token": "Token",
+ "`x` subscriptions": "`x` abonamente",
+ "`x` tokens": "`x` tokens",
+ "Import/export": "Importați/Exportați",
+ "unsubscribe": "dezabonați-vă",
+ "revoke": "revocați",
+ "Subscriptions": "Abonamente",
+ "`x` unseen notifications": "`x` notificări nevăzute",
+ "search": "căutați",
+ "Log out": "Deconectați-vă",
+ "Released under the AGPLv3 by Omar Roth.": "Publicat sub licența AGPLv3 de Omar Roth.",
+ "Source available here.": "Codul sursă este disponibil aici.",
+ "View JavaScript license information.": "Informații legate de licența JavaScript.",
+ "View privacy policy.": "Politica de confidențialitate.",
+ "Trending": "Tendințe",
+ "Public": "Public",
+ "Unlisted": "Necatalogat",
+ "Private": "Privat",
+ "View all playlists": "Afișați toate listele de redare",
+ "Updated `x` ago": "Actualizat acum `x`",
+ "Delete playlist `x`?": "Sigur doriți să ștergeți lista de redare?",
+ "Delete playlist": "Ștergeți lista de redare",
+ "Create playlist": "Creați o listă de redare",
+ "Title": "Titlu",
+ "Playlist privacy": "Parametrii de confidențialitate ai listei de redare",
+ "Editing playlist `x`": "Modificați lista de redare `x`",
+ "Watch on YouTube": "Urmăriți videoclipul pe YouTube",
+ "Hide annotations": "Ascundeți adnotările",
+ "Show annotations": "Afișați adnotările",
+ "Genre: ": "Categorie: ",
+ "License: ": "Licență: ",
+ "Family friendly? ": "Adecvat pentru întreaga familie? ",
+ "Wilson score: ": "Scor Wilson: ",
+ "Engagement: ": "Procentul celor care au apăsat pe \"Îmi place\" sau \"Nu îmi place\" : ",
+ "Whitelisted regions: ": "Regiunile de pe lista albă: ",
+ "Blacklisted regions: ": "Regiunile de pe lista neagră: ",
+ "Shared `x`": "Publicat pe `x`",
+ "`x` views": "`x` vizionări",
+ "Premieres in `x`": "Premiera în `x`",
+ "Premieres `x`": "Premiera pe `x`",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Se pare că ați dezactivat JavaScript. Apăsați aici pentru a vizualiza comentariile. Țineți minte faptul că încărcarea lor ar putea să dureze puțin mai mult.",
+ "View YouTube comments": "Vedeți comentariile de pe YouTube",
+ "View more comments on Reddit": "Vedeți mai multe comentarii pe Reddit",
+ "View `x` comments": "Afișați `x` comentarii",
+ "View Reddit comments": "Afișați comentariile de pe Reddit",
+ "Hide replies": "Ascundeți replicile",
+ "Show replies": "Afișați replicile",
+ "Incorrect password": "Parolă incorectă",
+ "Quota exceeded, try again in a few hours": "Numărul de tentative de conectare a fost depășit. Va rugăm să încercați din nou în câteva ore.",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Conectare eșuată. Dacă nu reușiți să vă conectați, verificați dacă ați activat autentificarea cu doi factori (Autentificator sau SMS).",
+ "Invalid TFA code": "Codul de autentificare cu doi factori este invalid",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Conectare eșuată. Acest lucru ar putea fi cauzat de faptul că nu ați activat autentificarea cu doi factori.",
+ "Wrong answer": "Răspuns invalid",
+ "Erroneous CAPTCHA": "CAPTCHA invalid",
+ "CAPTCHA is a required field": "Câmpul CAPTCHA este obligatoriu",
+ "User ID is a required field": "Câmpul ID Utilizator este obligatoriu",
+ "Password is a required field": "Câmpul Parolă este obligatoriu",
+ "Wrong username or password": "Nume de utilizator sau parolă invalidă",
+ "Please sign in using 'Log in with Google'": "Vă rog conectați-vă folosind \"Conectați-vă cu Google\"",
+ "Password cannot be empty": "Parola nu poate fi goală",
+ "Password cannot be longer than 55 characters": "Parola nu poate să conțină mai mult de 55 de caractere",
+ "Please log in": "Vă rog conectați-vă",
+ "Invidious Private Feed for `x`": "Feed RSS privat pentru `x`",
+ "channel:`x`": "canal:`x`",
+ "Deleted or invalid channel": "Canal șters sau invalid",
+ "This channel does not exist.": "Acest canal nu există.",
+ "Could not get channel info.": "Nu am putut primi informații despre acest canal.",
+ "Could not fetch comments": "Încărcarea comentariilor a eșuat.",
+ "View `x` replies": "Afișați `x` replici",
+ "`x` ago": "acum `x`",
+ "Load more": "Vedeți mai mult",
+ "`x` points": "`x` puncte",
+ "Could not create mix.": "Nu am putut crea această listă de redare.",
+ "Empty playlist": "Lista de redare este goală",
+ "Not a playlist.": "Lista de redare este invalidă.",
+ "Playlist does not exist.": "Această listă de redare nu există.",
+ "Could not pull trending pages.": "Încărcarea paginilor de tendințe a eșuat.",
+ "Hidden field \"challenge\" is a required field": "Câmpul ascuns \"challenge\" este un câmp obligatoriu",
+ "Hidden field \"token\" is a required field": "Câmpul ascuns \"token\" este un câmp obligatoriu",
+ "Erroneous challenge": "Challenge invalid",
+ "Erroneous token": "Token invalid",
+ "No such user": "Acest utilizator nu există",
+ "Token is expired, please try again": "Token-ul este expirat, vă rugăm să reîncercați.",
+ "English": "Engleză",
+ "English (auto-generated)": "Engleză (generată automat)",
+ "Afrikaans": "Afrikaans",
+ "Albanian": "Albaneză",
+ "Amharic": "Amharică",
+ "Arabic": "Arabă",
+ "Armenian": "Arméniană",
+ "Azerbaijani": "Azeră",
+ "Bangla": "Bangla",
+ "Basque": "Basque",
+ "Belarusian": "Belarusă",
+ "Bosnian": "Bosniacă",
+ "Bulgarian": "Bulgară",
+ "Burmese": "Birmană",
+ "Catalan": "Catalană",
+ "Cebuano": "Cebuano",
+ "Chinese (Simplified)": "Chineză (Simplificată)",
+ "Chinese (Traditional)": "Chinois (Tradițională)",
+ "Corsican": "Corsicană",
+ "Croatian": "Croată",
+ "Czech": "Cehă",
+ "Danish": "Daneză",
+ "Dutch": "Olandeză",
+ "Esperanto": "Esperanto",
+ "Estonian": "Estoniană",
+ "Filipino": "Filipineză",
+ "Finnish": "Finlandeză",
+ "French": "Franceză",
+ "Galician": "Galiciană",
+ "Georgian": "Georgiană",
+ "German": "Germană",
+ "Greek": "Greacă",
+ "Gujarati": "Gujarati",
+ "Haitian Creole": "Creola Haitiană",
+ "Hausa": "Haousa",
+ "Hawaiian": "Hawaiană",
+ "Hebrew": "Ebraică",
+ "Hindi": "Hindi",
+ "Hmong": "Hmong",
+ "Hungarian": "Ungară",
+ "Icelandic": "Islandeză",
+ "Igbo": "Igbo",
+ "Indonesian": "Indoneziană",
+ "Irish": "Irlandeză",
+ "Italian": "Italiană",
+ "Japanese": "Japoneză",
+ "Javanese": "Javaneză",
+ "Kannada": "Kannada",
+ "Kazakh": "Kazakh",
+ "Khmer": "Khmer",
+ "Korean": "Coreană",
+ "Kurdish": "Kurdă",
+ "Kyrgyz": "Kirghize",
+ "Lao": "Lao",
+ "Latin": "Latină",
+ "Latvian": "Letonă",
+ "Lithuanian": "Lituaniană",
+ "Luxembourgish": "Luxemburgheză",
+ "Macedonian": "Macedoniană",
+ "Malagasy": "Malgașă",
+ "Malay": "Malaieză",
+ "Malayalam": "Malayalam",
+ "Maltese": "Malteză",
+ "Maori": "Maori",
+ "Marathi": "Marathi",
+ "Mongolian": "Mongoliană",
+ "Nepali": "Nepaleză",
+ "Norwegian Bokmål": "Norvegiană",
+ "Nyanja": "Nyanja",
+ "Pashto": "Pachtou",
+ "Persian": "Persană",
+ "Polish": "Poloneză",
+ "Portuguese": "Portugheză",
+ "Punjabi": "Punjabi",
+ "Romanian": "Română",
+ "Russian": "Rusă",
+ "Samoan": "Samoan",
+ "Scottish Gaelic": "Galic Scoțian",
+ "Serbian": "Sârbă",
+ "Shona": "Shona",
+ "Sindhi": "Sindhi",
+ "Sinhala": "Sinhala",
+ "Slovak": "Slovacă",
+ "Slovenian": "Slovenă",
+ "Somali": "Somaleză",
+ "Southern Sotho": "Sotho de Sud",
+ "Spanish": "Spaniolă",
+ "Spanish (Latin America)": "Spaniolă (America Latină)",
+ "Sundanese": "Sundaneză",
+ "Swahili": "Swahili",
+ "Swedish": "Suedeză",
+ "Tajik": "Tajik",
+ "Tamil": "Tamil",
+ "Telugu": "Telugu",
+ "Thai": "Tailandeză",
+ "Turkish": "Turcă",
+ "Ukrainian": "Ucrainiană",
+ "Urdu": "Urdu",
+ "Uzbek": "Uzbek",
+ "Vietnamese": "Vietnameză",
+ "Welsh": "Galeză",
+ "Western Frisian": "Frisiană de Vest",
+ "Xhosa": "Xhosa",
+ "Yiddish": "Yiddish",
+ "Yoruba": "Yoruba",
+ "Zulu": "Zoulou",
+ "`x` years": "`x` ani",
+ "`x` months": "`x` luni",
+ "`x` weeks": "`x` săptămâni",
+ "`x` days": "`x` zile",
+ "`x` hours": "`x` ore",
+ "`x` minutes": "`x` minute",
+ "`x` seconds": "`x` secunde",
+ "Fallback comments: ": "Comentarii alternative: ",
+ "Popular": "Popular",
+ "Top": "Top",
+ "About": "Despre",
+ "Rating: ": "Evaluare: ",
+ "Language: ": "Limbă: ",
+ "View as playlist": "Vizualizați ca listă de redare",
+ "Default": "Implicit",
+ "Music": "Muzică",
+ "Gaming": "Jocuri Video",
+ "News": "Noutăți",
+ "Movies": "Filme",
+ "Download": "Descărcați",
+ "Download as: ": "Descărcați ca: ",
+ "%A %B %-d, %Y": "%A %-d %B %Y",
+ "(edited)": "(editat)",
+ "YouTube comment permalink": "Permalink pentru comentariul de pe YouTube",
+ "permalink": "permalink",
+ "`x` marked it with a ❤": "`x` l-a marcat cu o ❤",
+ "Audio mode": "Mod audio",
+ "Video mode": "Mod video",
+ "Videos": "Videoclipuri",
+ "Playlists": "Liste de redare",
+ "Community": "Comunitate",
+ "Current version: ": "Versiunea actuală: "
+} \ No newline at end of file
diff --git a/locales/ru.json b/locales/ru.json
index 29eb0197..e69b32e5 100644
--- a/locales/ru.json
+++ b/locales/ru.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` подписчиков",
"`x` videos": "`x` видео",
- "`x` playlists": "",
+ "`x` playlists": "`x` плейлистов",
"LIVE": "ПРЯМОЙ ЭФИР",
"Shared `x` ago": "Опубликовано `x` назад",
"Unsubscribe": "Отписаться",
@@ -69,11 +69,11 @@
"Show related videos: ": "Показывать похожие видео? ",
"Show annotations by default: ": "Всегда показывать аннотации? ",
"Visual preferences": "Настройки сайта",
- "Player style: ": "",
+ "Player style: ": "Стиль проигрывателя: ",
"Dark mode: ": "Тёмное оформление: ",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "Тема: ",
+ "dark": "темная",
+ "light": "светлая",
"Thin mode: ": "Облегчённое оформление: ",
"Subscription preferences": "Настройки подписок",
"Show annotations by default for subscribed channels: ": "Всегда показывать аннотации в видео каналов, на которые вы подписаны? ",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "Посмотреть информацию по лицензии JavaScript.",
"View privacy policy.": "Посмотреть политику конфиденциальности.",
"Trending": "В тренде",
- "Public": "",
+ "Public": "Публичный",
"Unlisted": "Нет в списке",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Приватный",
+ "View all playlists": "Посмотреть все плейлисты",
+ "Updated `x` ago": "Обновлено `x` назад",
+ "Delete playlist `x`?": "Удалить плейлист `x`?",
+ "Delete playlist": "Удалить плейлист",
+ "Create playlist": "Создать плейлист",
+ "Title": "Заголовок",
+ "Playlist privacy": "Конфиденциальность плейлиста",
+ "Editing playlist `x`": "Редактирование плейлиста `x`",
"Watch on YouTube": "Смотреть на YouTube",
"Hide annotations": "Скрыть аннотации",
"Show annotations": "Показать аннотации",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "%-d %B %Y, %A",
"(edited)": "(изменено)",
"YouTube comment permalink": "Прямая ссылка на YouTube",
- "permalink": "",
+ "permalink": "постоянная ссылка",
"`x` marked it with a ❤": "❤ от автора канала \"`x`\"",
"Audio mode": "Аудио режим",
"Video mode": "Видео режим",
"Videos": "Видео",
"Playlists": "Плейлисты",
- "Community": "",
+ "Community": "Сообщество",
"Current version: ": "Текущая версия: "
} \ No newline at end of file
diff --git a/locales/sr_Cyrl.json b/locales/sr_Cyrl.json
new file mode 100644
index 00000000..786532df
--- /dev/null
+++ b/locales/sr_Cyrl.json
@@ -0,0 +1,336 @@
+{
+ "`x` subscribers.": "",
+ "`x` videos.": "",
+ "`x` playlists.": "",
+ "LIVE": "",
+ "Shared `x` ago": "",
+ "Unsubscribe": "",
+ "Subscribe": "Пратите",
+ "View channel on YouTube": "Погледајте канал на YouTube-у",
+ "View playlist on YouTube": "Погледајте плејлисту на YouTube-у",
+ "newest": "",
+ "oldest": "",
+ "popular": "",
+ "last": "",
+ "Next page": "",
+ "Previous page": "",
+ "Clear watch history?": "",
+ "New password": "",
+ "New passwords must match": "",
+ "Cannot change password for Google accounts": "",
+ "Authorize token?": "",
+ "Authorize token for `x`?": "",
+ "Yes": "",
+ "No": "",
+ "Import and Export Data": "",
+ "Import": "",
+ "Import Invidious data": "",
+ "Import YouTube subscriptions": "",
+ "Import FreeTube subscriptions (.db)": "",
+ "Import NewPipe subscriptions (.json)": "",
+ "Import NewPipe data (.zip)": "",
+ "Export": "",
+ "Export subscriptions as OPML": "",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "",
+ "Export data as JSON": "",
+ "Delete account?": "",
+ "History": "",
+ "An alternative front-end to YouTube": "",
+ "JavaScript license information": "",
+ "source": "",
+ "Log in": "",
+ "Log in/register": "",
+ "Log in with Google": "",
+ "User ID": "",
+ "Password": "",
+ "Time (h:mm:ss):": "",
+ "Text CAPTCHA": "",
+ "Image CAPTCHA": "",
+ "Sign In": "",
+ "Register": "",
+ "E-mail": "",
+ "Google verification code": "",
+ "Preferences": "",
+ "Player preferences": "",
+ "Always loop: ": "",
+ "Autoplay: ": "",
+ "Play next by default: ": "",
+ "Autoplay next video: ": "",
+ "Listen by default: ": "",
+ "Proxy videos: ": "",
+ "Default speed: ": "",
+ "Preferred video quality: ": "",
+ "Player volume: ": "",
+ "Default comments: ": "",
+ "youtube": "",
+ "reddit": "",
+ "Default captions: ": "",
+ "Fallback captions: ": "",
+ "Show related videos: ": "",
+ "Show annotations by default: ": "",
+ "Visual preferences": "",
+ "Player style: ": "",
+ "Dark mode: ": "",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
+ "Thin mode: ": "",
+ "Subscription preferences": "",
+ "Show annotations by default for subscribed channels: ": "",
+ "Redirect homepage to feed: ": "",
+ "Number of videos shown in feed: ": "",
+ "Sort videos by: ": "",
+ "published": "",
+ "published - reverse": "",
+ "alphabetically": "",
+ "alphabetically - reverse": "",
+ "channel name": "",
+ "channel name - reverse": "",
+ "Only show latest video from channel: ": "",
+ "Only show latest unwatched video from channel: ": "",
+ "Only show unwatched: ": "",
+ "Only show notifications (if there are any): ": "",
+ "Enable web notifications": "",
+ "`x` uploaded a video": "",
+ "`x` is live": "",
+ "Data preferences": "",
+ "Clear watch history": "",
+ "Import/export data": "",
+ "Change password": "",
+ "Manage subscriptions": "",
+ "Manage tokens": "",
+ "Watch history": "",
+ "Delete account": "",
+ "Administrator preferences": "",
+ "Default homepage: ": "",
+ "Feed menu: ": "",
+ "Top enabled: ": "",
+ "CAPTCHA enabled: ": "",
+ "Login enabled: ": "",
+ "Registration enabled: ": "",
+ "Report statistics: ": "",
+ "Save preferences": "",
+ "Subscription manager": "",
+ "Token manager": "",
+ "Token": "",
+ "`x` subscriptions.": "",
+ "`x` tokens.": "",
+ "Import/export": "",
+ "unsubscribe": "",
+ "revoke": "",
+ "Subscriptions": "",
+ "`x` unseen notifications.": "",
+ "search": "",
+ "Log out": "",
+ "Released under the AGPLv3 by Omar Roth.": "",
+ "Source available here.": "",
+ "View JavaScript license information.": "",
+ "View privacy policy.": "",
+ "Trending": "",
+ "Public": "",
+ "Unlisted": "",
+ "Private": "",
+ "View all playlists": "",
+ "Updated `x` ago": "",
+ "Delete playlist `x`?": "",
+ "Delete playlist": "",
+ "Create playlist": "",
+ "Title": "",
+ "Playlist privacy": "",
+ "Editing playlist `x`": "",
+ "Watch on YouTube": "",
+ "Hide annotations": "",
+ "Show annotations": "",
+ "Genre: ": "",
+ "License: ": "",
+ "Family friendly? ": "",
+ "Wilson score: ": "",
+ "Engagement: ": "",
+ "Whitelisted regions: ": "",
+ "Blacklisted regions: ": "",
+ "Shared `x`": "",
+ "`x` views.": "",
+ "Premieres in `x`": "",
+ "Premieres `x`": "",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "",
+ "View YouTube comments": "",
+ "View more comments on Reddit": "",
+ "View `x` comments.": "",
+ "View Reddit comments": "",
+ "Hide replies": "",
+ "Show replies": "",
+ "Incorrect password": "",
+ "Quota exceeded, try again in a few hours": "",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "",
+ "Invalid TFA code": "",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "",
+ "Wrong answer": "",
+ "Erroneous CAPTCHA": "",
+ "CAPTCHA is a required field": "",
+ "User ID is a required field": "",
+ "Password is a required field": "",
+ "Wrong username or password": "",
+ "Please sign in using 'Log in with Google'": "",
+ "Password cannot be empty": "",
+ "Password cannot be longer than 55 characters": "",
+ "Please log in": "",
+ "Invidious Private Feed for `x`": "",
+ "channel:`x`": "",
+ "Deleted or invalid channel": "",
+ "This channel does not exist.": "",
+ "Could not get channel info.": "",
+ "Could not fetch comments": "",
+ "View `x` replies.": "",
+ "`x` ago": "",
+ "Load more": "",
+ "`x` points.": "",
+ "Could not create mix.": "",
+ "Empty playlist": "",
+ "Not a playlist.": "",
+ "Playlist does not exist.": "",
+ "Could not pull trending pages.": "",
+ "Hidden field \"challenge\" is a required field": "",
+ "Hidden field \"token\" is a required field": "",
+ "Erroneous challenge": "",
+ "Erroneous token": "",
+ "No such user": "",
+ "Token is expired, please try again": "",
+ "English": "",
+ "English (auto-generated)": "",
+ "Afrikaans": "",
+ "Albanian": "",
+ "Amharic": "",
+ "Arabic": "",
+ "Armenian": "",
+ "Azerbaijani": "",
+ "Bangla": "",
+ "Basque": "",
+ "Belarusian": "",
+ "Bosnian": "",
+ "Bulgarian": "",
+ "Burmese": "",
+ "Catalan": "",
+ "Cebuano": "",
+ "Chinese (Simplified)": "",
+ "Chinese (Traditional)": "",
+ "Corsican": "",
+ "Croatian": "",
+ "Czech": "",
+ "Danish": "",
+ "Dutch": "",
+ "Esperanto": "",
+ "Estonian": "",
+ "Filipino": "",
+ "Finnish": "",
+ "French": "",
+ "Galician": "",
+ "Georgian": "",
+ "German": "",
+ "Greek": "",
+ "Gujarati": "",
+ "Haitian Creole": "",
+ "Hausa": "",
+ "Hawaiian": "",
+ "Hebrew": "",
+ "Hindi": "",
+ "Hmong": "",
+ "Hungarian": "",
+ "Icelandic": "",
+ "Igbo": "",
+ "Indonesian": "",
+ "Irish": "",
+ "Italian": "",
+ "Japanese": "",
+ "Javanese": "",
+ "Kannada": "",
+ "Kazakh": "",
+ "Khmer": "",
+ "Korean": "",
+ "Kurdish": "",
+ "Kyrgyz": "",
+ "Lao": "",
+ "Latin": "",
+ "Latvian": "",
+ "Lithuanian": "",
+ "Luxembourgish": "",
+ "Macedonian": "",
+ "Malagasy": "",
+ "Malay": "",
+ "Malayalam": "",
+ "Maltese": "",
+ "Maori": "",
+ "Marathi": "",
+ "Mongolian": "",
+ "Nepali": "",
+ "Norwegian Bokmål": "",
+ "Nyanja": "",
+ "Pashto": "",
+ "Persian": "",
+ "Polish": "",
+ "Portuguese": "",
+ "Punjabi": "",
+ "Romanian": "",
+ "Russian": "",
+ "Samoan": "",
+ "Scottish Gaelic": "",
+ "Serbian": "",
+ "Shona": "",
+ "Sindhi": "",
+ "Sinhala": "",
+ "Slovak": "",
+ "Slovenian": "",
+ "Somali": "",
+ "Southern Sotho": "",
+ "Spanish": "",
+ "Spanish (Latin America)": "",
+ "Sundanese": "",
+ "Swahili": "",
+ "Swedish": "",
+ "Tajik": "",
+ "Tamil": "",
+ "Telugu": "",
+ "Thai": "",
+ "Turkish": "",
+ "Ukrainian": "",
+ "Urdu": "",
+ "Uzbek": "",
+ "Vietnamese": "",
+ "Welsh": "",
+ "Western Frisian": "",
+ "Xhosa": "",
+ "Yiddish": "",
+ "Yoruba": "",
+ "Zulu": "",
+ "`x` years.": "",
+ "`x` months.": "",
+ "`x` weeks.": "",
+ "`x` days.": "",
+ "`x` hours.": "",
+ "`x` minutes.": "",
+ "`x` seconds.": "",
+ "Fallback comments: ": "",
+ "Popular": "",
+ "Top": "",
+ "About": "",
+ "Rating: ": "",
+ "Language: ": "",
+ "View as playlist": "",
+ "Default": "",
+ "Music": "",
+ "Gaming": "",
+ "News": "",
+ "Movies": "",
+ "Download": "",
+ "Download as: ": "",
+ "%A %B %-d, %Y": "",
+ "(edited)": "",
+ "YouTube comment permalink": "",
+ "permalink": "",
+ "`x` marked it with a ❤": "",
+ "Audio mode": "",
+ "Video mode": "",
+ "Videos": "",
+ "Playlists": "",
+ "Community": "",
+ "Current version: ": "Тренутна верзија: "
+} \ No newline at end of file
diff --git a/locales/sv-SE.json b/locales/sv-SE.json
new file mode 100644
index 00000000..14e7d53e
--- /dev/null
+++ b/locales/sv-SE.json
@@ -0,0 +1,336 @@
+{
+ "`x` subscribers": "`x` prenumeranter",
+ "`x` videos": "`x` videor",
+ "`x` playlists": "`x` spellistor",
+ "LIVE": "LIVE",
+ "Shared `x` ago": "Delad `x` sedan",
+ "Unsubscribe": "Avprenumerera",
+ "Subscribe": "Prenumerera",
+ "View channel on YouTube": "Visa kanalen på YouTube",
+ "View playlist on YouTube": "Visa spellistan på YouTube",
+ "newest": "nyaste",
+ "oldest": "äldsta",
+ "popular": "populärt",
+ "last": "sista",
+ "Next page": "Nästa sida",
+ "Previous page": "Tidigare sida",
+ "Clear watch history?": "Töm visningshistorik?",
+ "New password": "Nytt lösenord",
+ "New passwords must match": "Nya lösenord måste stämma överens",
+ "Cannot change password for Google accounts": "Kan inte ändra lösenord på Google-konton",
+ "Authorize token?": "Auktorisera åtkomsttoken?",
+ "Authorize token for `x`?": "Auktorisera åtkomsttoken för `x`?",
+ "Yes": "Ja",
+ "No": "Nej",
+ "Import and Export Data": "Importera och exportera data",
+ "Import": "Importera",
+ "Import Invidious data": "Importera Invidious-data",
+ "Import YouTube subscriptions": "Importera YouTube-prenumerationer",
+ "Import FreeTube subscriptions (.db)": "Importera FreeTube-prenumerationer (.db)",
+ "Import NewPipe subscriptions (.json)": "Importera NewPipe-prenumerationer (.json)",
+ "Import NewPipe data (.zip)": "Importera NewPipe-data (.zip)",
+ "Export": "Exportera",
+ "Export subscriptions as OPML": "Exportera prenumerationer som OPML",
+ "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportera prenumerationer som OPML (för NewPipe och FreeTube)",
+ "Export data as JSON": "Exportera data som JSON",
+ "Delete account?": "Radera konto?",
+ "History": "Historik",
+ "An alternative front-end to YouTube": "Ett alternativt gränssnitt till YouTube",
+ "JavaScript license information": "JavaScript-licensinformation",
+ "source": "källa",
+ "Log in": "Logga in",
+ "Log in/register": "Logga in/registrera",
+ "Log in with Google": "Logga in med Google",
+ "User ID": "Användar-ID",
+ "Password": "Lösenord",
+ "Time (h:mm:ss):": "Tid (h:mm:ss):",
+ "Text CAPTCHA": "Text-CAPTCHA",
+ "Image CAPTCHA": "Bild-CAPTCHA",
+ "Sign In": "Inloggning",
+ "Register": "Registrera",
+ "E-mail": "E-post",
+ "Google verification code": "Google-bekräftelsekod",
+ "Preferences": "Inställningar",
+ "Player preferences": "Spelarinställningar",
+ "Always loop: ": "Loopa alltid: ",
+ "Autoplay: ": "Autouppspelning: ",
+ "Play next by default: ": "Spela nästa som förval: ",
+ "Autoplay next video: ": "Autouppspela nästa video: ",
+ "Listen by default: ": "Lyssna som förval: ",
+ "Proxy videos: ": "Proxy:a videor: ",
+ "Default speed: ": "Förvald hastighet: ",
+ "Preferred video quality: ": "Föredragen videokvalitet: ",
+ "Player volume: ": "Volym: ",
+ "Default comments: ": "Förvalda kommentarer: ",
+ "youtube": "YouTube",
+ "reddit": "Reddit",
+ "Default captions: ": "Förvalda undertexter: ",
+ "Fallback captions: ": "Ersättningsundertexter: ",
+ "Show related videos: ": "Visa relaterade videor? ",
+ "Show annotations by default: ": "Visa länkar-i-videon som förval? ",
+ "Visual preferences": "Visuella inställningar",
+ "Player style: ": "Spelarstil: ",
+ "Dark mode: ": "Mörkt läge: ",
+ "Theme: ": "Tema: ",
+ "dark": "Mörkt",
+ "light": "Ljust",
+ "Thin mode: ": "Lättviktigt läge: ",
+ "Subscription preferences": "Prenumerationsinställningar",
+ "Show annotations by default for subscribed channels: ": "Visa länkar-i-videor som förval för kanaler som prenumereras på? ",
+ "Redirect homepage to feed: ": "Omdirigera hemsida till flöde: ",
+ "Number of videos shown in feed: ": "Antal videor att visa i flödet: ",
+ "Sort videos by: ": "Sortera videor: ",
+ "published": "publicering",
+ "published - reverse": "publicering - omvänd",
+ "alphabetically": "alfabetiskt",
+ "alphabetically - reverse": "alfabetiskt - omvänd",
+ "channel name": "kanalnamn",
+ "channel name - reverse": "kanalnamn - omvänd",
+ "Only show latest video from channel: ": "Visa bara senaste videon från kanal: ",
+ "Only show latest unwatched video from channel: ": "Visa bara senaste osedda videon från kanal: ",
+ "Only show unwatched: ": "Visa bara osedda: ",
+ "Only show notifications (if there are any): ": "Visa endast aviseringar (om det finns några): ",
+ "Enable web notifications": "Slå på aviseringar",
+ "`x` uploaded a video": "`x` laddade upp en video",
+ "`x` is live": "`x` sänder live",
+ "Data preferences": "Datainställningar",
+ "Clear watch history": "Töm visningshistorik",
+ "Import/export data": "Importera/Exportera data",
+ "Change password": "Byt lösenord",
+ "Manage subscriptions": "Hantera prenumerationer",
+ "Manage tokens": "Hantera åtkomst-tokens",
+ "Watch history": "Visningshistorik",
+ "Delete account": "Radera konto",
+ "Administrator preferences": "Administratörsinställningar",
+ "Default homepage: ": "Förvald hemsida: ",
+ "Feed menu: ": "Flödesmeny: ",
+ "Top enabled: ": "Topp påslaget? ",
+ "CAPTCHA enabled: ": "CAPTCHA påslaget? ",
+ "Login enabled: ": "Inloggning påslaget? ",
+ "Registration enabled: ": "Registrering påslaget? ",
+ "Report statistics: ": "Rapportera in statistik? ",
+ "Save preferences": "Spara inställningar",
+ "Subscription manager": "Prenumerationshanterare",
+ "Token manager": "Åtkomst-token-hanterare",
+ "Token": "Åtkomst-token",
+ "`x` subscriptions": "`x` prenumerationer",
+ "`x` tokens": "`x` åtkomst-token",
+ "Import/export": "Importera/exportera",
+ "unsubscribe": "avprenumerera",
+ "revoke": "återkalla",
+ "Subscriptions": "Prenumerationer",
+ "`x` unseen notifications": "`x` osedda aviseringar",
+ "search": "sök",
+ "Log out": "Logga ut",
+ "Released under the AGPLv3 by Omar Roth.": "Utgiven under AGPLv3-licens av Omar Roth.",
+ "Source available here.": "Källkod tillgänglig här.",
+ "View JavaScript license information.": "Visa JavaScript-licensinformation.",
+ "View privacy policy.": "Visa privatlivspolicy.",
+ "Trending": "Trendar",
+ "Public": "Offentlig",
+ "Unlisted": "Olistad",
+ "Private": "Privat",
+ "View all playlists": "Visa alla spellistor",
+ "Updated `x` ago": "Uppdaterad `x` sedan",
+ "Delete playlist `x`?": "Radera spellistan `x`?",
+ "Delete playlist": "Radera spellista",
+ "Create playlist": "Skapa spellista",
+ "Title": "Titel",
+ "Playlist privacy": "Privatläge på spellista",
+ "Editing playlist `x`": "Redigerer spellistan `x`",
+ "Watch on YouTube": "Titta på YouTube",
+ "Hide annotations": "Dölj länkar-i-video",
+ "Show annotations": "Visa länkar-i-video",
+ "Genre: ": "Genre: ",
+ "License: ": "Licens: ",
+ "Family friendly? ": "Familjevänlig? ",
+ "Wilson score: ": "Wilson-poängsumma: ",
+ "Engagement: ": "Engagement: ",
+ "Whitelisted regions: ": "Vitlistade regioner: ",
+ "Blacklisted regions: ": "Svartlistade regioner: ",
+ "Shared `x`": "Delade `x`",
+ "`x` views": "`x` visningar",
+ "Premieres in `x`": "Premiär om `x`",
+ "Premieres `x`": "Premiär av `x`",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hej. Det ser ut som att du har JavaScript avstängt. Klicka här för att visa kommentarer, ha i åtanke att nedladdning tar längre tid.",
+ "View YouTube comments": "Visa YouTube-kommentarer",
+ "View more comments on Reddit": "Visa flera kommentarer på Reddit",
+ "View `x` comments": "Visa `x` kommentarer",
+ "View Reddit comments": "Visa Reddit-kommentarer",
+ "Hide replies": "Dölj svar",
+ "Show replies": "Visa svar",
+ "Incorrect password": "Fel lösenord",
+ "Quota exceeded, try again in a few hours": "Kvoten överskriden, försök igen om ett par timmar",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Kunde inte logga in, försäkra dig om att tvåfaktors-autentisering (Authenticator eller SMS) är påslagen.",
+ "Invalid TFA code": "Ogiltig tvåfaktor-kod",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Inloggning misslyckades. Detta kan vara för att tvåfaktors-autentisering inte är påslaget på ditt konto.",
+ "Wrong answer": "Fel svar",
+ "Erroneous CAPTCHA": "Ogiltig CAPTCHA",
+ "CAPTCHA is a required field": "CAPTCHA är ett obligatoriskt fält",
+ "User ID is a required field": "Användar-ID är ett obligatoriskt fält",
+ "Password is a required field": "Lösenord är ett obligatoriskt fält",
+ "Wrong username or password": "Ogiltigt användarnamn eller lösenord",
+ "Please sign in using 'Log in with Google'": "Logga in genom \"Google-inloggning\"",
+ "Password cannot be empty": "Lösenordet kan inte vara tomt",
+ "Password cannot be longer than 55 characters": "Lösenordet kan inte vara längre än 55 tecken",
+ "Please log in": "Logga in",
+ "Invidious Private Feed for `x`": "Ogiltig privat flöde för `x`",
+ "channel:`x`": "kanal `x`",
+ "Deleted or invalid channel": "Raderad eller ogiltig kanal",
+ "This channel does not exist.": "Denna kanal finns inte.",
+ "Could not get channel info.": "Kunde inte hämta kanalinfo.",
+ "Could not fetch comments": "Kunde inte hämta kommentarer",
+ "View `x` replies": "Visa `x` svar",
+ "`x` ago": "`x` sedan",
+ "Load more": "Ladda fler",
+ "`x` points": "`x` poäng",
+ "Could not create mix.": "Kunde inte skapa mix.",
+ "Empty playlist": "Spellistan är tom",
+ "Not a playlist.": "Ogiltig spellista.",
+ "Playlist does not exist.": "Spellistan finns inte.",
+ "Could not pull trending pages.": "Kunde inte hämta trendande sidor.",
+ "Hidden field \"challenge\" is a required field": "Dolt fält \"challenge\" är ett obligatoriskt fält",
+ "Hidden field \"token\" is a required field": "Dolt fält \"token\" är ett obligatoriskt fält",
+ "Erroneous challenge": "Felaktig challenge",
+ "Erroneous token": "Felaktig token",
+ "No such user": "Ogiltig användare",
+ "Token is expired, please try again": "Token föråldrad, försök igen",
+ "English": "",
+ "English (auto-generated)": "English (auto-genererat)",
+ "Afrikaans": "",
+ "Albanian": "",
+ "Amharic": "",
+ "Arabic": "",
+ "Armenian": "",
+ "Azerbaijani": "",
+ "Bangla": "",
+ "Basque": "",
+ "Belarusian": "",
+ "Bosnian": "",
+ "Bulgarian": "",
+ "Burmese": "",
+ "Catalan": "",
+ "Cebuano": "",
+ "Chinese (Simplified)": "",
+ "Chinese (Traditional)": "",
+ "Corsican": "",
+ "Croatian": "",
+ "Czech": "",
+ "Danish": "",
+ "Dutch": "",
+ "Esperanto": "",
+ "Estonian": "",
+ "Filipino": "",
+ "Finnish": "",
+ "French": "",
+ "Galician": "",
+ "Georgian": "",
+ "German": "",
+ "Greek": "",
+ "Gujarati": "",
+ "Haitian Creole": "",
+ "Hausa": "",
+ "Hawaiian": "",
+ "Hebrew": "",
+ "Hindi": "",
+ "Hmong": "",
+ "Hungarian": "",
+ "Icelandic": "",
+ "Igbo": "",
+ "Indonesian": "",
+ "Irish": "",
+ "Italian": "",
+ "Japanese": "",
+ "Javanese": "",
+ "Kannada": "",
+ "Kazakh": "",
+ "Khmer": "",
+ "Korean": "",
+ "Kurdish": "",
+ "Kyrgyz": "",
+ "Lao": "",
+ "Latin": "",
+ "Latvian": "",
+ "Lithuanian": "",
+ "Luxembourgish": "",
+ "Macedonian": "",
+ "Malagasy": "",
+ "Malay": "",
+ "Malayalam": "",
+ "Maltese": "",
+ "Maori": "",
+ "Marathi": "",
+ "Mongolian": "",
+ "Nepali": "",
+ "Norwegian Bokmål": "",
+ "Nyanja": "",
+ "Pashto": "",
+ "Persian": "",
+ "Polish": "",
+ "Portuguese": "",
+ "Punjabi": "",
+ "Romanian": "",
+ "Russian": "",
+ "Samoan": "",
+ "Scottish Gaelic": "",
+ "Serbian": "",
+ "Shona": "",
+ "Sindhi": "",
+ "Sinhala": "",
+ "Slovak": "",
+ "Slovenian": "",
+ "Somali": "",
+ "Southern Sotho": "",
+ "Spanish": "",
+ "Spanish (Latin America)": "",
+ "Sundanese": "",
+ "Swahili": "",
+ "Swedish": "",
+ "Tajik": "",
+ "Tamil": "",
+ "Telugu": "",
+ "Thai": "",
+ "Turkish": "",
+ "Ukrainian": "",
+ "Urdu": "",
+ "Uzbek": "",
+ "Vietnamese": "",
+ "Welsh": "",
+ "Western Frisian": "",
+ "Xhosa": "",
+ "Yiddish": "",
+ "Yoruba": "",
+ "Zulu": "",
+ "`x` years": "`x` år",
+ "`x` months": "`x` månader",
+ "`x` weeks": "`x` veckor",
+ "`x` days": "`x` dagar",
+ "`x` hours": "`x` timmar",
+ "`x` minutes": "`x` minuter",
+ "`x` seconds": "`x` sekunder",
+ "Fallback comments: ": "Fallback-kommentarer: ",
+ "Popular": "Populärt",
+ "Top": "Topp",
+ "About": "Om",
+ "Rating: ": "Betyg: ",
+ "Language: ": "Språk: ",
+ "View as playlist": "Visa som spellista",
+ "Default": "Förvalt",
+ "Music": "Musik",
+ "Gaming": "Spel",
+ "News": "Nyheter",
+ "Movies": "Filmer",
+ "Download": "Ladda ned",
+ "Download as: ": "Ladda ned som: ",
+ "%A %B %-d, %Y": "",
+ "(edited)": "(redigerad)",
+ "YouTube comment permalink": "Permanent YouTube-länk till innehållet",
+ "permalink": "permalänk",
+ "`x` marked it with a ❤": "`x` lämnade ett ❤",
+ "Audio mode": "Ljudläge",
+ "Video mode": "Videoläge",
+ "Videos": "Videor",
+ "Playlists": "Spellistor",
+ "Community": "Gemenskap",
+ "Current version: ": "Nuvarande version: "
+} \ No newline at end of file
diff --git a/locales/tr.json b/locales/tr.json
index 604d5afd..652dff6d 100644
--- a/locales/tr.json
+++ b/locales/tr.json
@@ -1,7 +1,7 @@
{
- "`x` subscribers": "",
- "`x` videos": "",
- "`x` playlists": "",
+ "`x` subscribers": "`x` abone",
+ "`x` videos": "`x` video",
+ "`x` playlists": "`x` çalma listesi",
"`x` subscribers.": "`x` abone.",
"`x` videos.": "`x` video.",
"LIVE": "CANLI",
@@ -56,20 +56,20 @@
"Player preferences": "Oynatıcı tercihleri",
"Always loop: ": "Sürekli döngü: ",
"Autoplay: ": "Otomatik oynat: ",
- "Play next by default: ": "Varsayılan olarak sonrakini oynat: ",
+ "Play next by default: ": "Öntanımlı olarak sonrakini oynat: ",
"Autoplay next video: ": "Sonraki videoyu otomatik oynat: ",
- "Listen by default: ": "Varsayılan olarak dinle: ",
+ "Listen by default: ": "Öntanımlı olarak dinle: ",
"Proxy videos: ": "Videoları proxy'le: ",
- "Default speed: ": "Varsayılan hız: ",
+ "Default speed: ": "Öntanımlı hız: ",
"Preferred video quality: ": "Tercih edilen video kalitesi: ",
"Player volume: ": "Oynatıcı ses seviyesi: ",
- "Default comments: ": "Varsayılan yorumlar: ",
+ "Default comments: ": "Öntanımlı yorumlar: ",
"youtube": "youtube",
"reddit": "reddit",
- "Default captions: ": "Varsayılan altyazılar: ",
+ "Default captions: ": "Öntanımlı altyazılar: ",
"Fallback captions: ": "Yedek altyazılar: ",
"Show related videos: ": "İlgili videoları göster: ",
- "Show annotations by default: ": "Varsayılan olarak ek açıklamaları göster: ",
+ "Show annotations by default: ": "Öntanımlı olarak ek açıklamaları göster: ",
"Visual preferences": "Görsel tercihler",
"Player style: ": "Oynatıcı biçimi: ",
"Dark mode: ": "Karanlık mod: ",
@@ -78,7 +78,7 @@
"light": "aydınlık",
"Thin mode: ": "İnce mod: ",
"Subscription preferences": "Abonelik tercihleri",
- "Show annotations by default for subscribed channels: ": "Abone olunan kanallar için ek açıklamaları varsayılan olarak göster: ",
+ "Show annotations by default for subscribed channels: ": "Abone olunan kanallar için ek açıklamaları öntanımlı olarak göster: ",
"Redirect homepage to feed: ": "Ana sayfayı akışa yönlendir: ",
"Number of videos shown in feed: ": "Akışta gösterilen video sayısı: ",
"Sort videos by: ": "Videoları sıralama kriteri: ",
@@ -104,7 +104,7 @@
"Watch history": "İzleme geçmişi",
"Delete account": "Hesap silme",
"Administrator preferences": "Yönetici tercihleri",
- "Default homepage: ": "Varsayılan ana sayfa: ",
+ "Default homepage: ": "Öntanımlı ana sayfa: ",
"Feed menu: ": "Akış menüsü: ",
"Top enabled: ": "Top etkin: ",
"CAPTCHA enabled: ": "CAPTCHA etkin: ",
@@ -113,13 +113,13 @@
"Report statistics: ": "Rapor istatistikleri: ",
"Save preferences": "Tercihleri kaydet",
"Subscription manager": "Abonelik yöneticisi",
- "`x` subscriptions": "",
- "`x` tokens": "",
+ "`x` subscriptions": "`x` abonelik",
+ "`x` tokens": "`x` belirteç",
"Token manager": "Jeton yöneticisi",
"Token": "Jeton",
"`x` subscriptions.": "`x` abonelik.",
"`x` tokens.": "`x` jeton.",
- "`x` unseen notifications": "",
+ "`x` unseen notifications": "`x` okunmamış bildirim",
"Import/export": "İçe/dışa aktar",
"unsubscribe": "abonelikten çık",
"revoke": "geri al",
@@ -127,18 +127,18 @@
"`x` unseen notifications.": "`x` okunmamış bildirim.",
"search": "ara",
"Log out": "Çıkış yap",
- "Public": "",
+ "Public": "Genel",
"Released under the AGPLv3 by Omar Roth.": "Omar Roth tarafından AGPLv3 altında yayımlandı.",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
- "Source available here.": "Kaynak kodu burada mevcut.",
+ "Private": "Özel",
+ "View all playlists": "Tüm çalma listelerini görüntüle",
+ "Updated `x` ago": "`x` önce güncellendi",
+ "Delete playlist `x`?": "`x` çalma listesini sil?",
+ "Delete playlist": "Çalma listesini sil",
+ "Create playlist": "Çalma listesi oluştur",
+ "Title": "Başlık",
+ "Playlist privacy": "Çalma listesi gizliliği",
+ "Editing playlist `x`": "`x` çalma listesi düzenleniyor",
+ "Source available here.": "Kaynak kodları burada bulunabilir.",
"View JavaScript license information.": "JavaScript lisans bilgilerini görüntüle.",
"View privacy policy.": "Gizlilik politikasını görüntüle.",
"Trending": "Trendler",
@@ -149,7 +149,7 @@
"Genre: ": "Tür: ",
"License: ": "Lisans: ",
"Family friendly? ": "Aile için uygun? ",
- "`x` views": "",
+ "`x` views": "`x` görüntüleme",
"Wilson score: ": "Wilson puanı: ",
"Engagement: ": "İzleyenlerin oy verme oranı: ",
"Whitelisted regions: ": "Beyaz listeye alınan bölgeler: ",
@@ -180,10 +180,10 @@
"Password cannot be empty": "Parola boş olamaz",
"Password cannot be longer than 55 characters": "Parola 55 karakterden uzun olamaz",
"Please log in": "Lütfen oturum açın",
- "View `x` replies": "",
+ "View `x` replies": "`x` yanıtı görüntüle",
"Invidious Private Feed for `x`": "`x` için İnvidious Özel Akışı",
"channel:`x`": "kanal:`x`",
- "`x` points": "",
+ "`x` points": "`x` puan",
"Deleted or invalid channel": "Silinmiş ya da geçersiz kanal",
"This channel does not exist.": "Bu kanal mevcut değil.",
"Could not get channel info.": "Kanal bilgisi alınamadı.",
@@ -323,7 +323,7 @@
"Rating: ": "Değerlendirme: ",
"Language: ": "Dil: ",
"View as playlist": "Oynatma listesi olarak görüntüle",
- "Default": "Varsayılan",
+ "Default": "Öntanımlı",
"Music": "Müzik",
"Gaming": "Oyun",
"News": "Haberler",
@@ -340,5 +340,5 @@
"Videos": "Videolar",
"Playlists": "Oynatma listeleri",
"Community": "Topluluk",
- "Current version: ": "Şu anki versiyon: "
+ "Current version: ": "Şu anki sürüm: "
} \ No newline at end of file
diff --git a/locales/uk.json b/locales/uk.json
index 0f8aa1b6..b04e0b2d 100644
--- a/locales/uk.json
+++ b/locales/uk.json
@@ -1,7 +1,7 @@
{
"`x` subscribers": "`x` підписників",
"`x` videos": "`x` відео",
- "`x` playlists": "",
+ "`x` playlists": "списки відтворення \"x\"",
"LIVE": "ПРЯМИЙ ЕФІР",
"Shared `x` ago": "Розміщено `x` назад",
"Unsubscribe": "Відписатися",
@@ -69,11 +69,11 @@
"Show related videos: ": "Показувати схожі відео? ",
"Show annotations by default: ": "Завжди показувати анотації? ",
"Visual preferences": "Налаштування сайту",
- "Player style: ": "",
+ "Player style: ": "Стиль програвача: ",
"Dark mode: ": "Темне оформлення: ",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "Тема: ",
+ "dark": "темна",
+ "light": "Світла",
"Thin mode: ": "Полегшене оформлення: ",
"Subscription preferences": "Налаштування підписок",
"Show annotations by default for subscribed channels: ": "Завжди показувати анотації у відео каналів, на які ви підписані? ",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "Переглянути інформацію щодо ліцензії JavaScript.",
"View privacy policy.": "Переглянути політику приватності.",
"Trending": "У тренді",
- "Public": "",
+ "Public": "Прилюдний",
"Unlisted": "Немає в списку",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "Особистий",
+ "View all playlists": "Переглянути всі списки відтворення",
+ "Updated `x` ago": "Оновлено `x` тому",
+ "Delete playlist `x`?": "Видалити список відтворення \"x\"?",
+ "Delete playlist": "Видалити список відтворення",
+ "Create playlist": "Створити список відтворення",
+ "Title": "Заголовок",
+ "Playlist privacy": "Конфіденційність списку відтворення",
+ "Editing playlist `x`": "Редагування списку відтворення \"x\"",
"Watch on YouTube": "Дивитися на YouTube",
"Hide annotations": "Приховати анотації",
"Show annotations": "Показати анотації",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "%-d %B %Y, %A",
"(edited)": "(змінено)",
"YouTube comment permalink": "Пряме посилання на коментар в YouTube",
- "permalink": "",
+ "permalink": "постійне посилання",
"`x` marked it with a ❤": "❤ цьому від каналу `x`",
"Audio mode": "Аудіорежим",
"Video mode": "Відеорежим",
"Videos": "Відео",
"Playlists": "Плейлисти",
- "Community": "",
+ "Community": "Спільнота",
"Current version: ": "Поточна версія: "
} \ No newline at end of file
diff --git a/locales/zh-CN.json b/locales/zh-CN.json
index ed8090ba..288f127d 100644
--- a/locales/zh-CN.json
+++ b/locales/zh-CN.json
@@ -1,7 +1,7 @@
{
- "`x` subscribers": "`x` 订阅者",
- "`x` videos": "`x` 视频",
- "`x` playlists": "",
+ "`x` subscribers": "`x` 位订阅者",
+ "`x` videos": "`x` 个视频",
+ "`x` playlists": "`x` 个播放列表",
"LIVE": "直播",
"Shared `x` ago": "`x` 前分享",
"Unsubscribe": "取消订阅",
@@ -69,11 +69,11 @@
"Show related videos: ": "显示相关视频?",
"Show annotations by default: ": "默认显示视频注释?",
"Visual preferences": "视觉选项",
- "Player style: ": "",
+ "Player style: ": "播放器样式:",
"Dark mode: ": "暗色模式:",
- "Theme: ": "",
- "dark": "",
- "light": "",
+ "Theme: ": "主题",
+ "dark": "暗色",
+ "light": "亮色",
"Thin mode: ": "窄页模式:",
"Subscription preferences": "订阅设置",
"Show annotations by default for subscribed channels: ": "在订阅频道的视频默认显示注释?",
@@ -127,17 +127,17 @@
"View JavaScript license information.": "查看 JavaScript 协议信息。",
"View privacy policy.": "查看隐私政策。",
"Trending": "时下流行",
- "Public": "",
+ "Public": "公开",
"Unlisted": "不公开",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
+ "Private": "私享",
+ "View all playlists": "查看所有播放列表",
+ "Updated `x` ago": "`x` 前更新",
+ "Delete playlist `x`?": "是否删除播放列表 `x`?",
+ "Delete playlist": "删除播放列表",
+ "Create playlist": "创建播放列表",
+ "Title": "标题",
+ "Playlist privacy": "播放列表隐私设置",
+ "Editing playlist `x`": "正在编辑播放列表 `x`",
"Watch on YouTube": "在 YouTube 观看",
"Hide annotations": "隐藏注释",
"Show annotations": "显示注释",
@@ -325,12 +325,12 @@
"%A %B %-d, %Y": "%Y年%-m月%-d日 %a",
"(edited)": "(已编辑)",
"YouTube comment permalink": "YouTube 评论永久链接",
- "permalink": "",
+ "permalink": "永久链接",
"`x` marked it with a ❤": "`x` 为此加 ❤",
"Audio mode": "音频模式",
"Video mode": "视频模式",
"Videos": "视频",
"Playlists": "播放列表",
- "Community": "",
+ "Community": "社区",
"Current version: ": "当前版本:"
} \ No newline at end of file
diff --git a/locales/zh-TW.json b/locales/zh-TW.json
index 47d1f04a..a8111750 100644
--- a/locales/zh-TW.json
+++ b/locales/zh-TW.json
@@ -1,13 +1,13 @@
{
"`x` subscribers": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱者",
- "": "`x` 個訂閱者"
+ "": "`x` 個訂閱者。"
},
"`x` videos": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 部影片",
- "": "`x` 部影片"
+ "": "`x` 部影片。"
},
- "`x` playlists": "",
+ "`x` playlists": "`x` 播放清單",
"LIVE": "直播",
"Shared `x` ago": "`x` 前分享",
"Unsubscribe": "取消訂閱",
@@ -58,44 +58,44 @@
"Google verification code": "Google 驗證碼",
"Preferences": "偏好設定",
"Player preferences": "播放器偏好設定",
- "Always loop: ": "總是循環播放:",
- "Autoplay: ": "自動播放:",
- "Play next by default: ": "預設播放下一部:",
- "Autoplay next video: ": "自動播放下一部影片:",
- "Listen by default: ": "預設聆聽:",
- "Proxy videos: ": "代理影片:",
- "Default speed: ": "預設速度:",
- "Preferred video quality: ": "偏好的影片畫質:",
- "Player volume: ": "播放器音量:",
- "Default comments: ": "預設留言:",
+ "Always loop: ": "總是循環播放: ",
+ "Autoplay: ": "自動播放: ",
+ "Play next by default: ": "預設播放下一部: ",
+ "Autoplay next video: ": "自動播放下一部影片: ",
+ "Listen by default: ": "預設聆聽: ",
+ "Proxy videos: ": "代理影片: ",
+ "Default speed: ": "預設速度: ",
+ "Preferred video quality: ": "偏好的影片畫質: ",
+ "Player volume: ": "播放器音量: ",
+ "Default comments: ": "預設留言: ",
"youtube": "youtube",
"reddit": "reddit",
- "Default captions: ": "預設字幕:",
- "Fallback captions: ": "汰退字幕:",
- "Show related videos: ": "顯示相關的影片:",
- "Show annotations by default: ": "預設顯示註釋:",
+ "Default captions: ": "預設字幕: ",
+ "Fallback captions: ": "汰退字幕: ",
+ "Show related videos: ": "顯示相關的影片: ",
+ "Show annotations by default: ": "預設顯示註釋: ",
"Visual preferences": "視覺偏好設定",
- "Player style: ": "播放器樣式",
- "Dark mode: ": "深色模式:",
- "Theme: ": "佈景主題",
+ "Player style: ": "播放器樣式: ",
+ "Dark mode: ": "深色模式: ",
+ "Theme: ": "佈景主題: ",
"dark": "深色",
"light": "淺色",
- "Thin mode: ": "精簡模式:",
+ "Thin mode: ": "精簡模式: ",
"Subscription preferences": "訂閱偏好設定",
- "Show annotations by default for subscribed channels: ": "預設為已訂閱的頻道顯示註釋?",
- "Redirect homepage to feed: ": "重新導向首頁至 feed:",
- "Number of videos shown in feed: ": "顯示在 feed 中的影片數量:",
- "Sort videos by: ": "以此種方式排序影片:",
+ "Show annotations by default for subscribed channels: ": "預設為已訂閱的頻道顯示註釋: ",
+ "Redirect homepage to feed: ": "重新導向首頁至 feed: ",
+ "Number of videos shown in feed: ": "顯示在 feed 中的影片數量: ",
+ "Sort videos by: ": "以此種方式排序影片: ",
"published": "已發佈",
"published - reverse": "已發佈 - 反向",
"alphabetically": "字母",
"alphabetically - reverse": "字母 - 反向",
"channel name": "頻道名稱",
"channel name - reverse": "頻道名稱 - 反向",
- "Only show latest video from channel: ": "僅顯示從頻道而來的最新影片:",
- "Only show latest unwatched video from channel: ": "僅顯示從頻道而來的未觀看影片:",
- "Only show unwatched: ": "僅顯示未觀看的:",
- "Only show notifications (if there are any): ": "僅顯示通知(如果有的話):",
+ "Only show latest video from channel: ": "僅顯示從頻道而來的最新影片: ",
+ "Only show latest unwatched video from channel: ": "僅顯示從頻道而來的未觀看影片: ",
+ "Only show unwatched: ": "僅顯示未觀看的: ",
+ "Only show notifications (if there are any): ": "僅顯示通知(如果有的話): ",
"Enable web notifications": "啟用網路通知",
"`x` uploaded a video": "`x` 上傳了一部影片",
"`x` is live": "`x` 正在直播",
@@ -108,24 +108,24 @@
"Watch history": "觀看歷史",
"Delete account": "刪除帳號",
"Administrator preferences": "管理員偏好設定",
- "Default homepage: ": "預設首頁:",
- "Feed menu: ": "Feed 選單:",
- "Top enabled: ": "頂部啟用:",
- "CAPTCHA enabled: ": "CAPTCHA 啟用:",
- "Login enabled: ": "啟用登入?",
- "Registration enabled: ": "啟用註冊?",
- "Report statistics: ": "回報統計?",
+ "Default homepage: ": "預設首頁: ",
+ "Feed menu: ": "Feed 選單: ",
+ "Top enabled: ": "頂部啟用: ",
+ "CAPTCHA enabled: ": "CAPTCHA 啟用: ",
+ "Login enabled: ": "啟用登入: ",
+ "Registration enabled: ": "啟用註冊: ",
+ "Report statistics: ": "回報統計: ",
"Save preferences": "儲存偏好設定",
"Subscription manager": "訂閱管理員",
"Token manager": "Token 管理員",
"Token": "Token",
"`x` subscriptions": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個訂閱",
- "": "`x` 個訂閱"
+ "": "`x` 個訂閱。"
},
"`x` tokens": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` token",
- "": "`x` tokens"
+ "": "`x` tokens。"
},
"Import/export": "匯入/匯出",
"unsubscribe": "取消訂閱",
@@ -133,7 +133,7 @@
"Subscriptions": "訂閱",
"`x` unseen notifications": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 個未讀的通知",
- "": "`x` 個未讀的通知"
+ "": "`x` 個未讀的通知。"
},
"search": "搜尋",
"Log out": "登出",
@@ -147,7 +147,7 @@
"Private": "私人",
"View all playlists": "檢視所有播放清單",
"Updated `x` ago": "更新於 `x` 之前",
- "Delete playlist `x`?": "刪除播放清單",
+ "Delete playlist `x`?": "刪除播放清單 `x`?",
"Delete playlist": "刪除播放清單",
"Create playlist": "建立播放清單",
"Title": "標題",
@@ -156,17 +156,17 @@
"Watch on YouTube": "在 YouTube 上觀看",
"Hide annotations": "隱藏註釋",
"Show annotations": "顯示註釋",
- "Genre: ": "風格:",
- "License: ": "授權條款:",
- "Family friendly? ": "家庭友好?",
- "Wilson score: ": "威爾遜分數:",
- "Engagement: ": "參與度:",
- "Whitelisted regions: ": "白名單區域:",
- "Blacklisted regions: ": "黑名單區域:",
+ "Genre: ": "風格: ",
+ "License: ": "授權條款: ",
+ "Family friendly? ": "家庭友好? ",
+ "Wilson score: ": "威爾遜分數: ",
+ "Engagement: ": "參與度: ",
+ "Whitelisted regions: ": "白名單區域: ",
+ "Blacklisted regions: ": "黑名單區域: ",
"Shared `x`": "`x` 發佈",
"`x` views": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 次檢視",
- "": "`x` 次檢視"
+ "": "`x` 次檢視。"
},
"Premieres in `x`": "首映於 `x`",
"Premieres `x`": "首映於 `x`",
@@ -200,13 +200,13 @@
"Could not fetch comments": "無法擷取留言",
"View `x` replies": {
"([^.,0-9]|^)1([^.,0-9]|$)": "檢視 `x` 則回覆",
- "": "檢視 `x` 則回覆"
+ "": "檢視 `x` 則回覆。"
},
"`x` ago": "`x` 以前",
"Load more": "載入更多",
"`x` points": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 點",
- "": "`x` 點"
+ "": "`x` 點。"
},
"Could not create mix.": "無法建立混合。",
"Empty playlist": "空的播放清單",
@@ -327,38 +327,38 @@
"Zulu": "祖魯語",
"`x` years": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 年",
- "": "`x` 年"
+ "": "`x` 年。"
},
"`x` months": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 月",
- "": "`x` 月"
+ "": "`x` 月。"
},
"`x` weeks": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 週",
- "": "`x` 週"
+ "": "`x` 週。"
},
"`x` days": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天",
- "": "`x` 天"
+ "": "`x` 天。"
},
"`x` hours": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 小時",
- "": "`x` 小時"
+ "": "`x` 小時。"
},
"`x` minutes": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 天",
- "": "`x` 天"
+ "": "`x` 分鐘。"
},
"`x` seconds": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` 秒",
- "": "`x` 秒"
+ "": "`x` 秒。"
},
- "Fallback comments: ": "汰退留言:",
+ "Fallback comments: ": "汰退留言: ",
"Popular": "熱門頻道",
"Top": "熱門影片",
"About": "關於",
- "Rating: ": "評分:",
- "Language: ": "語言:",
+ "Rating: ": "評分: ",
+ "Language: ": "語言: ",
"View as playlist": "以播放清單檢視",
"Default": "預設值",
"Music": "音樂",
@@ -366,16 +366,16 @@
"News": "新聞",
"Movies": "電影",
"Download": "下載",
- "Download as: ": "下載為:",
+ "Download as: ": "下載為: ",
"%A %B %-d, %Y": "%A %B %-d, %Y",
"(edited)": "(已編輯)",
"YouTube comment permalink": "YouTube 留言永久連結",
- "permalink": "",
+ "permalink": "永久連結",
"`x` marked it with a ❤": "`x` 為此標記 ❤",
"Audio mode": "音訊模式",
"Video mode": "視訊模式",
"Videos": "影片",
"Playlists": "播放清單",
"Community": "社群",
- "Current version: ": "目前版本:"
-}
+ "Current version: ": "目前版本: "
+} \ No newline at end of file
diff --git a/screenshots/03_subscriptions.png b/screenshots/03_subscriptions.png
deleted file mode 100644
index f5cfa8c1..00000000
--- a/screenshots/03_subscriptions.png
+++ /dev/null
Binary files differ
diff --git a/shard.yml b/shard.yml
index 96cdb1fc..f9af9cb8 100644
--- a/shard.yml
+++ b/shard.yml
@@ -11,13 +11,13 @@ targets:
dependencies:
pg:
github: will/crystal-pg
- version: ~> 0.19.0
+ version: ~> 0.21.1
sqlite3:
github: crystal-lang/crystal-sqlite3
- version: ~> 0.14.0
+ version: ~> 0.16.0
kemal:
github: kemalcr/kemal
- version: ~> 0.26.0
+ commit: dfe7dca08f4c9a9456d6132af5f6b59fcd6865e4
pool:
github: ysbaddaden/pool
version: ~> 0.2.3
@@ -25,9 +25,9 @@ dependencies:
github: omarroth/protodec
version: ~> 0.1.2
lsquic:
- github: omarroth/lsquic.cr
- version: ~> 0.1.3
+ github: iv-org/lsquic.cr
+ version: ~> 2.18.1-1
-crystal: 0.31.1
+crystal: 0.35.1
license: AGPLv3
diff --git a/spec/helpers_spec.cr b/spec/helpers_spec.cr
index 95222e0b..a8a3c6ce 100644
--- a/spec/helpers_spec.cr
+++ b/spec/helpers_spec.cr
@@ -9,8 +9,11 @@ require "../src/invidious/channels"
require "../src/invidious/comments"
require "../src/invidious/playlists"
require "../src/invidious/search"
+require "../src/invidious/trending"
require "../src/invidious/users"
+CONFIG = Config.from_yaml(File.open("config/config.yml"))
+
describe "Helper" do
describe "#produce_channel_videos_url" do
it "correctly produces url for requesting page `x` of a channel's videos" do
@@ -26,9 +29,9 @@ describe "Helper" do
describe "#produce_channel_search_url" do
it "correctly produces token for searching a specific channel" do
- produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "", 100).should eq("/browse_ajax?continuation=4qmFsgI-EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0RNVEF3WgA%3D&gl=US&hl=en")
+ produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "", 100).should eq("/browse_ajax?continuation=4qmFsgI2EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaGEVnWnpaV0Z5WTJnNEFYb0RNVEF3dUFFQVoA&gl=US&hl=en")
- produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "По ожиशुपतिरपि子而時ஸ்றீனி", 0).should eq("/browse_ajax?continuation=4qmFsgJ8EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0JNQT09Wj7Qn9C-INC-0LbQuOCktuClgeCkquCkpOCkv-CksOCkquCkv-WtkOiAjOaZguCuuOCvjeCuseCvgOCuqeCuvw%3D%3D&gl=US&hl=en")
+ produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "По ожиशुपतिरपि子而時ஸ்றீனி", 0).should eq("/browse_ajax?continuation=4qmFsgJ0EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaGEVnWnpaV0Z5WTJnNEFYb0JNTGdCQUE9PVo-0J_QviDQvtC20LjgpLbgpYHgpKrgpKTgpL_gpLDgpKrgpL_lrZDogIzmmYLgrrjgr43grrHgr4Dgrqngrr8%3D&gl=US&hl=en")
end
end
@@ -40,7 +43,7 @@ describe "Helper" do
describe "#extract_channel_playlists_cursor" do
it "correctly extracts a playlists cursor from the given URL" do
- extract_channel_playlists_cursor("/browse_ajax?continuation=4qmFsgLRARIYVUNDajk1NklGNjJGYlQ3R291c3phajl3GrQBRWdsd2JHRjViR2x6ZEhNWUF5QUJNQUk0QVdBQmFnQjZabEZWYkZCaE1XczFVbFpHZDJGV09XNWxWelI0V0RGR2VWSnVWbUZOV0Vwc1ZHcG5lRmd3TVU1aVZXdDRWMWN4YzFGdFNuTmtlbWh4VGpCd1NWTllVa1pTYTJNeFlVUmtlRmt3Y0ZWVWJWRXdWbnBzTkU1V1JqRmhNVGxFVm14dmQwMXFhRzVXZDdnQkFBJTNEJTNE&gl=US&hl=en", false).should eq("AIOkY9EQpi_gyn1_QrFuZ1reN81_MMmI1YmlBblw8j7JHItEFG5h7qcJTNd4W9x5Quk_CVZ028gW")
+ extract_channel_playlists_cursor("4qmFsgLRARIYVUNDajk1NklGNjJGYlQ3R291c3phajl3GrQBRWdsd2JHRjViR2x6ZEhNWUF5QUJNQUk0QVdBQmFnQjZabEZWYkZCaE1XczFVbFpHZDJGV09XNWxWelI0V0RGR2VWSnVWbUZOV0Vwc1ZHcG5lRmd3TVU1aVZXdDRWMWN4YzFGdFNuTmtlbWh4VGpCd1NWTllVa1pTYTJNeFlVUmtlRmt3Y0ZWVWJWRXdWbnBzTkU1V1JqRmhNVGxFVm14dmQwMXFhRzVXZDdnQkFBJTNEJTNE", false).should eq("AIOkY9EQpi_gyn1_QrFuZ1reN81_MMmI1YmlBblw8j7JHItEFG5h7qcJTNd4W9x5Quk_CVZ028gW")
end
end
@@ -124,6 +127,15 @@ describe "Helper" do
end
end
+ describe "#extract_plid" do
+ it "correctly extracts playlist ID from trending URL" do
+ extract_plid("/feed/trending?bp=4gIuCggvbS8wNHJsZhIiUExGZ3F1TG5MNTlhbVBud2pLbmNhZUp3MDYzZlU1M3Q0cA%3D%3D").should eq("PLFgquLnL59amPnwjKncaeJw063fU53t4p")
+ extract_plid("/feed/trending?bp=4gIvCgkvbS8wYnp2bTISIlBMaUN2Vkp6QnVwS2tDaFNnUDdGWFhDclo2aEp4NmtlTm0%3D").should eq("PLiCvVJzBupKkChSgP7FXXCrZ6hJx6keNm")
+ extract_plid("/feed/trending?bp=4gIuCggvbS8wNWpoZxIiUEwzWlE1Q3BOdWxRbUtPUDNJekdsYWN0V1c4dklYX0hFUA%3D%3D").should eq("PL3ZQ5CpNulQmKOP3IzGlactWW8vIX_HEP")
+ extract_plid("/feed/trending?bp=4gIuCggvbS8wMnZ4bhIiUEx6akZiYUZ6c21NUnFhdEJnVTdPeGNGTkZhQ2hqTkVERA%3D%3D").should eq("PLzjFbaFzsmMRqatBgU7OxcFNFaChjNEDD")
+ end
+ end
+
describe "#sign_token" do
it "correctly signs a given hash" do
token = {
diff --git a/src/invidious.cr b/src/invidious.cr
index 559214ac..284b238c 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -23,13 +23,18 @@ require "pg"
require "sqlite3"
require "xml"
require "yaml"
-require "zip"
+require "compress/zip"
require "protodec/utils"
require "./invidious/helpers/*"
require "./invidious/*"
+require "./invidious/routes/**"
+require "./invidious/jobs/**"
-CONFIG = Config.from_yaml(File.read("config/config.yml"))
-HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
+ENV_CONFIG_NAME = "INVIDIOUS_CONFIG"
+
+CONFIG_STR = ENV.has_key?(ENV_CONFIG_NAME) ? ENV.fetch(ENV_CONFIG_NAME) : File.read("config/config.yml")
+CONFIG = Config.from_yaml(CONFIG_STR)
+HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
PG_URL = URI.new(
scheme: "postgres",
@@ -45,19 +50,19 @@ ARCHIVE_URL = URI.parse("https://archive.org")
LOGIN_URL = URI.parse("https://accounts.google.com")
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
REDDIT_URL = URI.parse("https://www.reddit.com")
-TEXTCAPTCHA_URL = URI.parse("http://textcaptcha.com")
+TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
YT_URL = URI.parse("https://www.youtube.com")
-YT_IMG_URL = URI.parse("https://i.ytimg.com")
+HOST_URL = make_host_url(CONFIG, Kemal.config)
CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"}
MAX_ITEMS_PER_PAGE = 1500
-REQUEST_HEADERS_WHITELIST = {"Accept", "Accept-Encoding", "Cache-Control", "Connection", "Content-Length", "If-None-Match", "Range"}
-RESPONSE_HEADERS_BLACKLIST = {"Access-Control-Allow-Origin", "Alt-Svc", "Server"}
+REQUEST_HEADERS_WHITELIST = {"accept", "accept-encoding", "cache-control", "content-length", "if-none-match", "range"}
+RESPONSE_HEADERS_BLACKLIST = {"access-control-allow-origin", "alt-svc", "server"}
HTTP_CHUNK_SIZE = 10485760 # ~10MB
-CURRENT_BRANCH = {{ "#{`git branch | sed -n '/\* /s///p'`.strip}" }}
+CURRENT_BRANCH = {{ "#{`git branch | sed -n '/* /s///p'`.strip}" }}
CURRENT_COMMIT = {{ "#{`git rev-list HEAD --max-count=1 --abbrev-commit`.strip}" }}
CURRENT_VERSION = {{ "#{`git describe --tags --abbrev=0`.strip}" }}
@@ -81,21 +86,25 @@ LOCALES = {
"es" => load_locale("es"),
"eu" => load_locale("eu"),
"fr" => load_locale("fr"),
+ "hu" => load_locale("hu-HU"),
"is" => load_locale("is"),
"it" => load_locale("it"),
"ja" => load_locale("ja"),
- "nb_NO" => load_locale("nb_NO"),
+ "nb-NO" => load_locale("nb-NO"),
"nl" => load_locale("nl"),
"pl" => load_locale("pl"),
+ "pt-BR" => load_locale("pt-BR"),
+ "pt-PT" => load_locale("pt-PT"),
+ "ro" => load_locale("ro"),
"ru" => load_locale("ru"),
+ "sv" => load_locale("sv-SE"),
"tr" => load_locale("tr"),
"uk" => load_locale("uk"),
"zh-CN" => load_locale("zh-CN"),
"zh-TW" => load_locale("zh-TW"),
}
-YT_POOL = QUICPool.new(YT_URL, capacity: CONFIG.pool_size, timeout: 0.05)
-YT_IMG_POOL = HTTPPool.new(YT_IMG_URL, capacity: CONFIG.pool_size, timeout: 0.05)
+YT_POOL = QUICPool.new(YT_URL, capacity: CONFIG.pool_size, timeout: 0.1)
config = CONFIG
logger = Invidious::LogHandler.new
@@ -150,105 +159,47 @@ end
# Start jobs
-refresh_channels(PG_DB, logger, config)
-refresh_feeds(PG_DB, logger, config)
-subscribe_to_feeds(PG_DB, logger, HMAC_KEY, config)
+Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, logger, config)
+Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, logger, config)
+Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, logger, config, HMAC_KEY)
+Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB)
+Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new
-statistics = {
- "error" => "Statistics are not availabile.",
-}
if config.statistics_enabled
- spawn do
- statistics = {
- "version" => "2.0",
- "software" => SOFTWARE,
- "openRegistrations" => config.registration_enabled,
- "usage" => {
- "users" => {
- "total" => PG_DB.query_one("SELECT count(*) FROM users", as: Int64),
- "activeHalfyear" => PG_DB.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '6 months'", as: Int64),
- "activeMonth" => PG_DB.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '1 month'", as: Int64),
- },
- },
- "metadata" => {
- "updatedAt" => Time.utc.to_unix,
- "lastChannelRefreshedAt" => PG_DB.query_one?("SELECT updated FROM channels ORDER BY updated DESC LIMIT 1", as: Time).try &.to_unix || 0_i64,
- },
- }
-
- loop do
- sleep 1.minute
- Fiber.yield
-
- statistics["usage"].as(Hash)["users"].as(Hash)["total"] = PG_DB.query_one("SELECT count(*) FROM users", as: Int64)
- statistics["usage"].as(Hash)["users"].as(Hash)["activeHalfyear"] = PG_DB.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '6 months'", as: Int64)
- statistics["usage"].as(Hash)["users"].as(Hash)["activeMonth"] = PG_DB.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '1 month'", as: Int64)
- statistics["metadata"].as(Hash(String, Int64))["updatedAt"] = Time.utc.to_unix
- statistics["metadata"].as(Hash(String, Int64))["lastChannelRefreshedAt"] = PG_DB.query_one?("SELECT updated FROM channels ORDER BY updated DESC LIMIT 1", as: Time).try &.to_unix || 0_i64
- end
- end
+ Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE)
end
-top_videos = [] of Video
-if config.top_enabled
- spawn do
- pull_top_videos(config, PG_DB) do |videos|
- top_videos = videos
- end
- end
-end
-
-popular_videos = [] of ChannelVideo
-spawn do
- pull_popular_videos(PG_DB) do |videos|
- popular_videos = videos
- end
+if config.captcha_key
+ Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(logger, config)
end
-decrypt_function = [] of {name: String, value: Int32}
-spawn do
- update_decrypt_function do |function|
- decrypt_function = function
- end
-end
+connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32)
+Invidious::Jobs.register Invidious::Jobs::NotificationJob.new(connection_channel, PG_URL)
-if CONFIG.captcha_key
- spawn do
- bypass_captcha(CONFIG.captcha_key, logger) do |cookies|
- cookies.each do |cookie|
- config.cookies << cookie
- end
+Invidious::Jobs.start_all
- # Persist cookies between runs
- CONFIG.cookies = config.cookies
- File.write("config/config.yml", config.to_yaml)
- end
- end
+def popular_videos
+ Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
end
-connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32)
-spawn do
- connections = [] of Channel(PQ::Notification)
-
- PG.connect_listen(PG_URL, "notifications") { |event| connections.each { |connection| connection.send(event) } }
+DECRYPT_FUNCTION = Invidious::Jobs::UpdateDecryptFunctionJob::DECRYPT_FUNCTION
- loop do
- action, connection = connection_channel.receive
-
- case action
- when true
- connections << connection
- when false
- connections.delete(connection)
- end
+before_all do |env|
+ preferences = begin
+ Preferences.from_json(env.request.cookies["PREFS"]?.try &.value || "{}")
+ rescue
+ Preferences.from_json("{}")
end
-end
-before_all do |env|
- host_url = make_host_url(config, Kemal.config)
+ env.set "preferences", preferences
env.response.headers["X-XSS-Protection"] = "1; mode=block"
env.response.headers["X-Content-Type-Options"] = "nosniff"
- env.response.headers["Content-Security-Policy"] = "default-src blob: data: 'self' #{host_url} 'unsafe-inline' 'unsafe-eval'; media-src blob: 'self' #{host_url} https://*.googlevideo.com:443"
+ extra_media_csp = ""
+ if CONFIG.disabled?("local") || !preferences.local
+ extra_media_csp += " https://*.googlevideo.com:443"
+ end
+ # TODO: Remove style-src's 'unsafe-inline', requires to remove all inline styles (<style> [..] </style>, style=" [..] ")
+ env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}"
env.response.headers["Referrer-Policy"] = "same-origin"
if (Kemal.config.ssl || config.https_only) && config.hsts
@@ -266,12 +217,6 @@ before_all do |env|
"/latest_version",
}.any? { |r| env.request.resource.starts_with? r }
- begin
- preferences = Preferences.from_json(env.request.cookies["PREFS"]?.try &.value || "{}")
- rescue
- preferences = Preferences.from_json("{}")
- end
-
if env.request.cookies.has_key? "SID"
sid = env.request.cookies["SID"].value
@@ -293,6 +238,7 @@ before_all do |env|
}, HMAC_KEY, PG_DB, 1.week)
preferences = user.preferences
+ env.set "preferences", preferences
env.set "sid", sid
env.set "csrf_token", csrf_token
@@ -314,6 +260,7 @@ before_all do |env|
}, HMAC_KEY, PG_DB, 1.week)
preferences = user.preferences
+ env.set "preferences", preferences
env.set "sid", sid
env.set "csrf_token", csrf_token
@@ -331,7 +278,6 @@ before_all do |env|
preferences.dark_mode = dark_mode
preferences.thin_mode = thin_mode
preferences.locale = locale
- env.set "preferences", preferences
current_page = env.request.path
if env.request.query
@@ -347,473 +293,12 @@ before_all do |env|
env.set "current_page", URI.encode_www_form(current_page)
end
-get "/" do |env|
- preferences = env.get("preferences").as(Preferences)
- locale = LOCALES[preferences.locale]?
- user = env.get? "user"
-
- case preferences.default_home
- when ""
- templated "empty"
- when "Popular"
- templated "popular"
- when "Top"
- if config.top_enabled
- templated "top"
- else
- templated "empty"
- end
- when "Trending"
- env.redirect "/feed/trending"
- when "Subscriptions"
- if user
- env.redirect "/feed/subscriptions"
- else
- templated "popular"
- end
- when "Playlists"
- if user
- env.redirect "/view_all_playlists"
- else
- templated "popular"
- end
- end
-end
-
-get "/privacy" do |env|
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- templated "privacy"
-end
-
-get "/licenses" do |env|
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- rendered "licenses"
-end
-
-# Videos
-
-get "/watch" do |env|
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- region = env.params.query["region"]?
-
- if env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
- url = "/watch?" + env.params.query.to_s.gsub("%20", "").delete("+")
- next env.redirect url
- end
-
- if env.params.query["v"]?
- id = env.params.query["v"]
-
- if env.params.query["v"].empty?
- error_message = "Invalid parameters."
- env.response.status_code = 400
- next templated "error"
- end
-
- if id.size > 11
- url = "/watch?v=#{id[0, 11]}"
- env.params.query.delete_all("v")
- if env.params.query.size > 0
- url += "&#{env.params.query}"
- end
-
- next env.redirect url
- end
- else
- next env.redirect "/"
- end
-
- plid = env.params.query["list"]?
- continuation = process_continuation(PG_DB, env.params.query, plid, id)
-
- nojs = env.params.query["nojs"]?
-
- nojs ||= "0"
- nojs = nojs == "1"
-
- preferences = env.get("preferences").as(Preferences)
-
- user = env.get?("user").try &.as(User)
- if user
- subscriptions = user.subscriptions
- watched = user.watched
- notifications = user.notifications
- end
- subscriptions ||= [] of String
-
- params = process_video_params(env.params.query, preferences)
- env.params.query.delete_all("listen")
-
- begin
- video = get_video(id, PG_DB, region: params.region)
- rescue ex : VideoRedirect
- next env.redirect env.request.resource.gsub(id, ex.video_id)
- rescue ex
- error_message = ex.message
- env.response.status_code = 500
- logger.puts("#{id} : #{ex.message}")
- next templated "error"
- end
-
- if preferences.annotations_subscribed &&
- subscriptions.includes?(video.ucid) &&
- (env.params.query["iv_load_policy"]? || "1") == "1"
- params.annotations = true
- end
- env.params.query.delete_all("iv_load_policy")
-
- if watched && !watched.includes? id
- PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.as(User).email)
- end
-
- if notifications && notifications.includes? id
- PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
- env.get("user").as(User).notifications.delete(id)
- notifications.delete(id)
- end
-
- if nojs
- if preferences
- source = preferences.comments[0]
- if source.empty?
- source = preferences.comments[1]
- end
-
- if source == "youtube"
- begin
- comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
- rescue ex
- if preferences.comments[1] == "reddit"
- comments, reddit_thread = fetch_reddit_comments(id)
- comment_html = template_reddit_comments(comments, locale)
-
- comment_html = fill_links(comment_html, "https", "www.reddit.com")
- comment_html = replace_links(comment_html)
- end
- end
- elsif source == "reddit"
- begin
- comments, reddit_thread = fetch_reddit_comments(id)
- comment_html = template_reddit_comments(comments, locale)
-
- comment_html = fill_links(comment_html, "https", "www.reddit.com")
- comment_html = replace_links(comment_html)
- rescue ex
- if preferences.comments[1] == "youtube"
- comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
- end
- end
- end
- else
- comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
- end
-
- comment_html ||= ""
- end
-
- fmt_stream = video.fmt_stream(decrypt_function)
- adaptive_fmts = video.adaptive_fmts(decrypt_function)
-
- if params.local
- fmt_stream.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
- adaptive_fmts.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
- end
-
- video_streams = video.video_streams(adaptive_fmts)
- audio_streams = video.audio_streams(adaptive_fmts)
-
- # Older videos may not have audio sources available.
- # We redirect here so they're not unplayable
- if audio_streams.empty? && !video.live_now
- if params.quality == "dash"
- env.params.query.delete_all("quality")
- env.params.query["quality"] = "medium"
- next env.redirect "/watch?#{env.params.query}"
- elsif params.listen
- env.params.query.delete_all("listen")
- env.params.query["listen"] = "0"
- next env.redirect "/watch?#{env.params.query}"
- end
- end
-
- captions = video.captions
-
- preferred_captions = captions.select { |caption|
- params.preferred_captions.includes?(caption.name.simpleText) ||
- params.preferred_captions.includes?(caption.languageCode.split("-")[0])
- }
- preferred_captions.sort_by! { |caption|
- (params.preferred_captions.index(caption.name.simpleText) ||
- params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
- }
- captions = captions - preferred_captions
-
- aspect_ratio = "16:9"
-
- video.description_html = fill_links(video.description_html, "https", "www.youtube.com")
- video.description_html = replace_links(video.description_html)
-
- host_url = make_host_url(config, Kemal.config)
-
- if video.player_response["streamingData"]?.try &.["hlsManifestUrl"]?
- hlsvp = video.player_response["streamingData"]["hlsManifestUrl"].as_s
- hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", host_url)
- end
-
- thumbnail = "/vi/#{video.id}/maxres.jpg"
-
- if params.raw
- if params.listen
- url = audio_streams[0]["url"]
-
- audio_streams.each do |fmt|
- if fmt["bitrate"] == params.quality.rchop("k")
- url = fmt["url"]
- end
- end
- else
- url = fmt_stream[0]["url"]
-
- fmt_stream.each do |fmt|
- if fmt["label"].split(" - ")[0] == params.quality
- url = fmt["url"]
- end
- end
- end
-
- next env.redirect url
- end
-
- rvs = [] of Hash(String, String)
- video.info["rvs"]?.try &.split(",").each do |rv|
- rvs << HTTP::Params.parse(rv).to_h
- end
-
- rating = video.info["avg_rating"].to_f64
- if video.views > 0
- engagement = ((video.dislikes.to_f + video.likes.to_f)/video.views * 100)
- else
- engagement = 0
- end
-
- playability_status = video.player_response["playabilityStatus"]?
- if playability_status && playability_status["status"] == "LIVE_STREAM_OFFLINE" && !video.premiere_timestamp
- reason = playability_status["reason"]?.try &.as_s
- end
- reason ||= ""
-
- templated "watch"
-end
-
-get "/embed/" do |env|
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
-
- if plid = env.params.query["list"]?
- begin
- playlist = get_playlist(PG_DB, plid, locale: locale)
- offset = env.params.query["index"]?.try &.to_i? || 0
- videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
- rescue ex
- error_message = ex.message
- env.response.status_code = 500
- next templated "error"
- end
-
- url = "/embed/#{videos[0].id}?#{env.params.query}"
-
- if env.params.query.size > 0
- url += "?#{env.params.query}"
- end
- else
- url = "/"
- end
-
- env.redirect url
-end
-
-get "/embed/:id" do |env|
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- id = env.params.url["id"]
-
- plid = env.params.query["list"]?
- continuation = process_continuation(PG_DB, env.params.query, plid, id)
-
- if md = env.params.query["playlist"]?
- .try &.match(/[a-zA-Z0-9_-]{11}(,[a-zA-Z0-9_-]{11})*/)
- video_series = md[0].split(",")
- env.params.query.delete("playlist")
- end
-
- preferences = env.get("preferences").as(Preferences)
-
- if id.includes?("%20") || id.includes?("+") || env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
- id = env.params.url["id"].gsub("%20", "").delete("+")
-
- url = "/embed/#{id}"
-
- if env.params.query.size > 0
- url += "?#{env.params.query.to_s.gsub("%20", "").delete("+")}"
- end
-
- next env.redirect url
- end
-
- # YouTube embed supports `videoseries` with either `list=PLID`
- # or `playlist=VIDEO_ID,VIDEO_ID`
- case id
- when "videoseries"
- url = ""
-
- if plid
- begin
- playlist = get_playlist(PG_DB, plid, locale: locale)
- offset = env.params.query["index"]?.try &.to_i? || 0
- videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
- rescue ex
- error_message = ex.message
- env.response.status_code = 500
- next templated "error"
- end
-
- url = "/embed/#{videos[0].id}"
- elsif video_series
- url = "/embed/#{video_series.shift}"
- env.params.query["playlist"] = video_series.join(",")
- else
- next env.redirect "/"
- end
-
- if env.params.query.size > 0
- url += "?#{env.params.query}"
- end
-
- next env.redirect url
- when "live_stream"
- response = YT_POOL.client &.get("/embed/live_stream?channel=#{env.params.query["channel"]? || ""}")
- video_id = response.body.match(/"video_id":"(?<video_id>[a-zA-Z0-9_-]{11})"/).try &.["video_id"]
-
- env.params.query.delete_all("channel")
-
- if !video_id || video_id == "live_stream"
- error_message = "Video is unavailable."
- next templated "error"
- end
-
- url = "/embed/#{video_id}"
-
- if env.params.query.size > 0
- url += "?#{env.params.query}"
- end
-
- next env.redirect url
- when id.size > 11
- url = "/embed/#{id[0, 11]}"
-
- if env.params.query.size > 0
- url += "?#{env.params.query}"
- end
-
- next env.redirect url
- end
-
- params = process_video_params(env.params.query, preferences)
-
- user = env.get?("user").try &.as(User)
- if user
- subscriptions = user.subscriptions
- watched = user.watched
- notifications = user.notifications
- end
- subscriptions ||= [] of String
-
- begin
- video = get_video(id, PG_DB, region: params.region)
- rescue ex : VideoRedirect
- next env.redirect env.request.resource.gsub(id, ex.video_id)
- rescue ex
- error_message = ex.message
- env.response.status_code = 500
- next templated "error"
- end
-
- if preferences.annotations_subscribed &&
- subscriptions.includes?(video.ucid) &&
- (env.params.query["iv_load_policy"]? || "1") == "1"
- params.annotations = true
- end
-
- # if watched && !watched.includes? id
- # PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.as(User).email)
- # end
-
- if notifications && notifications.includes? id
- PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
- env.get("user").as(User).notifications.delete(id)
- notifications.delete(id)
- end
-
- fmt_stream = video.fmt_stream(decrypt_function)
- adaptive_fmts = video.adaptive_fmts(decrypt_function)
-
- if params.local
- fmt_stream.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
- adaptive_fmts.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
- end
-
- video_streams = video.video_streams(adaptive_fmts)
- audio_streams = video.audio_streams(adaptive_fmts)
-
- if audio_streams.empty? && !video.live_now
- if params.quality == "dash"
- env.params.query.delete_all("quality")
- next env.redirect "/embed/#{id}?#{env.params.query}"
- elsif params.listen
- env.params.query.delete_all("listen")
- env.params.query["listen"] = "0"
- next env.redirect "/embed/#{id}?#{env.params.query}"
- end
- end
-
- captions = video.captions
-
- preferred_captions = captions.select { |caption|
- params.preferred_captions.includes?(caption.name.simpleText) ||
- params.preferred_captions.includes?(caption.languageCode.split("-")[0])
- }
- preferred_captions.sort_by! { |caption|
- (params.preferred_captions.index(caption.name.simpleText) ||
- params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
- }
- captions = captions - preferred_captions
-
- aspect_ratio = nil
-
- video.description_html = fill_links(video.description_html, "https", "www.youtube.com")
- video.description_html = replace_links(video.description_html)
-
- host_url = make_host_url(config, Kemal.config)
-
- if video.player_response["streamingData"]?.try &.["hlsManifestUrl"]?
- hlsvp = video.player_response["streamingData"]["hlsManifestUrl"].as_s
- hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", host_url)
- end
-
- thumbnail = "/vi/#{video.id}/maxres.jpg"
-
- if params.raw
- url = fmt_stream[0]["url"]
-
- fmt_stream.each do |fmt|
- if fmt["label"].split(" - ")[0] == params.quality
- url = fmt["url"]
- end
- end
-
- next env.redirect url
- end
-
- rendered "embed"
-end
+Invidious::Routing.get "/", Invidious::Routes::Home
+Invidious::Routing.get "/privacy", Invidious::Routes::Privacy
+Invidious::Routing.get "/licenses", Invidious::Routes::Licenses
+Invidious::Routing.get "/watch", Invidious::Routes::Watch
+Invidious::Routing.get "/embed/", Invidious::Routes::Embed::Index
+Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed::Show
# Playlists
@@ -833,8 +318,14 @@ get "/view_all_playlists" do |env|
user = user.as(User)
- items = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 ORDER BY created", user.email, as: InvidiousPlaylist)
- items.map! do |item|
+ items_created = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+ items_created.map! do |item|
+ item.author = ""
+ item
+ end
+
+ items_saved = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id NOT LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+ items_saved.map! do |item|
item.author = ""
item
end
@@ -905,6 +396,25 @@ post "/create_playlist" do |env|
env.redirect "/playlist?list=#{playlist.id}"
end
+get "/subscribe_playlist" do |env|
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+
+ user = env.get? "user"
+ referer = get_referer(env)
+
+ if !user
+ next env.redirect "/"
+ end
+
+ user = user.as(User)
+
+ playlist_id = env.params.query["list"]
+ playlist = get_playlist(PG_DB, playlist_id, locale)
+ subscribe_playlist(PG_DB, user, playlist)
+
+ env.redirect "/playlist?list=#{playlist.id}"
+end
+
get "/delete_playlist" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
@@ -920,10 +430,6 @@ get "/delete_playlist" do |env|
sid = sid.as(String)
plid = env.params.query["list"]?
- if !plid || !plid.starts_with?("IV")
- next env.redirect referer
- end
-
playlist = PG_DB.query_one?("SELECT * FROM playlists WHERE id = $1", plid, as: InvidiousPlaylist)
if !playlist || playlist.author != user.email
next env.redirect referer
@@ -1222,29 +728,33 @@ post "/playlist_ajax" do |env|
end
end
- playlist_video = PlaylistVideo.new(
- title: video.title,
- id: video.id,
- author: video.author,
- ucid: video.ucid,
+ playlist_video = PlaylistVideo.new({
+ title: video.title,
+ id: video.id,
+ author: video.author,
+ ucid: video.ucid,
length_seconds: video.length_seconds,
- published: video.published,
- plid: playlist_id,
- live_now: video.live_now,
- index: Random::Secure.rand(0_i64..Int64::MAX)
- )
+ published: video.published,
+ plid: playlist_id,
+ live_now: video.live_now,
+ index: Random::Secure.rand(0_i64..Int64::MAX),
+ })
video_array = playlist_video.to_a
args = arg_array(video_array)
PG_DB.exec("INSERT INTO playlist_videos VALUES (#{args})", args: video_array)
- PG_DB.exec("UPDATE playlists SET index = array_append(index, $1), video_count = video_count + 1, updated = $2 WHERE id = $3", playlist_video.index, Time.utc, playlist_id)
+ PG_DB.exec("UPDATE playlists SET index = array_append(index, $1), video_count = cardinality(index) + 1, updated = $2 WHERE id = $3", playlist_video.index, Time.utc, playlist_id)
when "action_remove_video"
index = env.params.query["set_video_id"]
PG_DB.exec("DELETE FROM playlist_videos * WHERE index = $1", index)
- PG_DB.exec("UPDATE playlists SET index = array_remove(index, $1), video_count = video_count - 1, updated = $2 WHERE id = $3", index, Time.utc, playlist_id)
+ PG_DB.exec("UPDATE playlists SET index = array_remove(index, $1), video_count = cardinality(index) - 1, updated = $2 WHERE id = $3", index, Time.utc, playlist_id)
when "action_move_video_before"
# TODO: Playlist stub
+ else
+ error_message = {"error" => "Unsupported action #{action}"}.to_json
+ env.response.status_code = 400
+ next error_message
end
if redirect
@@ -1259,9 +769,9 @@ get "/playlist" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
user = env.get?("user").try &.as(User)
- plid = env.params.query["list"]?
referer = get_referer(env)
+ plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
if !plid
next env.redirect "/"
end
@@ -1328,16 +838,14 @@ get "/opensearch.xml" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/opensearchdescription+xml"
- host = make_host_url(config, Kemal.config)
-
XML.build(indent: " ", encoding: "UTF-8") do |xml|
xml.element("OpenSearchDescription", xmlns: "http://a9.com/-/spec/opensearch/1.1/") do
xml.element("ShortName") { xml.text "Invidious" }
xml.element("LongName") { xml.text "Invidious Search" }
xml.element("Description") { xml.text "Search for videos, channels, and playlists on Invidious" }
xml.element("InputEncoding") { xml.text "UTF-8" }
- xml.element("Image", width: 48, height: 48, type: "image/x-icon") { xml.text "#{host}/favicon.ico" }
- xml.element("Url", type: "text/html", method: "get", template: "#{host}/search?q={searchTerms}")
+ xml.element("Image", width: 48, height: 48, type: "image/x-icon") { xml.text "#{HOST_URL}/favicon.ico" }
+ xml.element("Url", type: "text/html", method: "get", template: "#{HOST_URL}/search?q={searchTerms}")
end
end
end
@@ -1446,9 +954,8 @@ post "/login" do |env|
traceback = IO::Memory.new
# See https://github.com/ytdl-org/youtube-dl/blob/2019.04.07/youtube_dl/extractor/youtube.py#L82
- # TODO: Convert to QUIC
begin
- client = make_client(LOGIN_URL)
+ client = QUIC::Client.new(LOGIN_URL)
headers = HTTP::Headers.new
login_page = client.get("/ServiceLogin")
@@ -1471,7 +978,6 @@ post "/login" do |env|
headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8"
headers["Google-Accounts-XSRF"] = "1"
- headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
response = client.post("/_/signin/sl/lookup", headers, login_req(lookup_req))
lookup_results = JSON.parse(response.body[5..-1])
@@ -1540,7 +1046,7 @@ post "/login" do |env|
case prompt_type
when "TWO_STEP_VERIFICATION"
prompt_type = 2
- when "LOGIN_CHALLENGE"
+ else # "LOGIN_CHALLENGE"
prompt_type = 4
end
@@ -1645,28 +1151,31 @@ post "/login" do |env|
traceback << "Logging in..."
- location = challenge_results[0][-1][2].to_s
+ location = URI.parse(challenge_results[0][-1][2].to_s)
cookies = HTTP::Cookies.from_headers(headers)
+ headers.delete("Content-Type")
+ headers.delete("Google-Accounts-XSRF")
+
loop do
- if !location || location.includes? "/ManageAccount"
+ if !location || location.path == "/ManageAccount"
break
end
# Occasionally there will be a second page after login confirming
# the user's phone number ("/b/0/SmsAuthInterstitial"), which we currently don't handle.
- if location.includes? "/b/0/SmsAuthInterstitial"
+ if location.path.starts_with? "/b/0/SmsAuthInterstitial"
traceback << "Unhandled dialog /b/0/SmsAuthInterstitial."
end
- login = client.get(location, headers)
- headers = login.cookies.add_request_headers(headers)
+ login = client.get(location.full_path, headers)
- cookies = HTTP::Cookies.from_headers(headers)
- location = login.headers["Location"]?
+ headers = login.cookies.add_request_headers(headers)
+ location = login.headers["Location"]?.try { |u| URI.parse(u) }
end
+ cookies = HTTP::Cookies.from_headers(headers)
sid = cookies["SID"]?.try &.value
if !sid
raise "Couldn't get SID."
@@ -1830,7 +1339,7 @@ post "/login" do |env|
env.response.status_code = 400
next templated "error"
end
- when "text"
+ else # "text"
answer = Digest::MD5.hexdigest(answer.downcase.strip)
found_valid_captcha = false
@@ -1855,8 +1364,8 @@ post "/login" do |env|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
user, sid = create_user(sid, email, password)
user_array = user.to_a
+ user_array[4] = user_array[4].to_json # User preferences
- user_array[4] = user_array[4].to_json
args = arg_array(user_array)
PG_DB.exec("INSERT INTO users VALUES (#{args})", args: user_array)
@@ -2083,10 +1592,6 @@ post "/preferences" do |env|
end
config.default_user_preferences.feed_menu = admin_feed_menu
- top_enabled = env.params.body["top_enabled"]?.try &.as(String)
- top_enabled ||= "off"
- config.top_enabled = top_enabled == "on"
-
captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String)
captcha_enabled ||= "off"
config.captcha_enabled = captcha_enabled == "on"
@@ -2237,10 +1742,14 @@ post "/watch_ajax" do |env|
case action
when "action_mark_watched"
if !user.watched.includes? id
- PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.email)
+ PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.email)
end
when "action_mark_unwatched"
PG_DB.exec("UPDATE users SET watched = array_remove(watched, $1) WHERE email = $2", id, user.email)
+ else
+ error_message = {"error" => "Unsupported action #{action}"}.to_json
+ env.response.status_code = 400
+ next error_message
end
if redirect
@@ -2304,8 +1813,7 @@ get "/modify_notifications" do |env|
end
headers = cookies.add_request_headers(headers)
- match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[A-Za-z0-9\_\-\=]+)"/)
- if match
+ if match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[^"]+)"/)
session_token = match["session_token"]
else
next env.redirect referer
@@ -2395,6 +1903,10 @@ post "/subscription_ajax" do |env|
end
when "action_remove_subscriptions"
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = array_remove(subscriptions, $1) WHERE email = $2", channel_id, email)
+ else
+ error_message = {"error" => "Unsupported action #{action}"}.to_json
+ env.response.status_code = 400
+ next error_message
end
if redirect
@@ -2440,20 +1952,39 @@ get "/subscription_manager" do |env|
end
subscriptions = PG_DB.query_all("SELECT * FROM channels WHERE id = ANY(#{values})", as: InvidiousChannel)
-
subscriptions.sort_by! { |channel| channel.author.downcase }
if action_takeout
- host_url = make_host_url(config, Kemal.config)
-
if format == "json"
env.response.content_type = "application/json"
env.response.headers["content-disposition"] = "attachment"
- next {
- "subscriptions" => user.subscriptions,
- "watch_history" => user.watched,
- "preferences" => user.preferences,
- }.to_json
+ playlists = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+
+ next JSON.build do |json|
+ json.object do
+ json.field "subscriptions", user.subscriptions
+ json.field "watch_history", user.watched
+ json.field "preferences", user.preferences
+ json.field "playlists" do
+ json.array do
+ playlists.each do |playlist|
+ json.object do
+ json.field "title", playlist.title
+ json.field "description", html_to_content(playlist.description_html)
+ json.field "privacy", playlist.privacy.to_s
+ json.field "videos" do
+ json.array do
+ PG_DB.query_all("SELECT id FROM playlist_videos WHERE plid = $1 ORDER BY array_position($2, index) LIMIT 500", playlist.id, playlist.index, as: String).each do |video_id|
+ json.string video_id
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
else
env.response.content_type = "application/xml"
env.response.headers["content-disposition"] = "attachment"
@@ -2471,7 +2002,7 @@ get "/subscription_manager" do |env|
if format == "newpipe"
xmlUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=#{channel.id}"
else
- xmlUrl = "#{host_url}/feed/channel/#{channel.id}"
+ xmlUrl = "#{HOST_URL}/feed/channel/#{channel.id}"
end
xml.element("outline", text: channel.author, title: channel.author,
@@ -2513,42 +2044,13 @@ post "/data_control" do |env|
if user
user = user.as(User)
- spawn do
- # Since import can take a while, if we're not done after 20 seconds
- # push out content to prevent timeout.
-
- # Interesting to note is that Chrome will try to render before the content has finished loading,
- # which is why we include a loading icon. Firefox and its derivatives will not see this page,
- # instead redirecting immediately once the connection has closed.
-
- # https://stackoverflow.com/q/2091239 is helpful but not directly applicable here.
-
- sleep 20.seconds
- env.response.puts %(<meta http-equiv="refresh" content="0; url=#{referer}">)
- env.response.puts %(<link rel="stylesheet" href="/css/ionicons.min.css?v=#{ASSET_COMMIT}">)
- env.response.puts %(<link rel="stylesheet" href="/css/default.css?v=#{ASSET_COMMIT}">)
- if env.get("preferences").as(Preferences).dark_mode == "dark"
- env.response.puts %(<link rel="stylesheet" href="/css/darktheme.css?v=#{ASSET_COMMIT}">)
- else
- env.response.puts %(<link rel="stylesheet" href="/css/lighttheme.css?v=#{ASSET_COMMIT}">)
- end
- env.response.puts %(<h3><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>)
- env.response.flush
-
- loop do
- env.response.puts %(<!-- keepalive #{Time.utc.to_unix} -->)
- env.response.flush
-
- sleep (20 + rand(11)).seconds
- end
- end
+ # TODO: Find a way to prevent browser timeout
HTTP::FormData.parse(env.request) do |part|
body = part.body.gets_to_end
- if body.empty?
- next
- end
+ next if body.empty?
+ # TODO: Unify into single import based on content-type
case part.name
when "import_invidious"
body = JSON.parse(body)
@@ -2569,9 +2071,55 @@ post "/data_control" do |env|
end
if body["preferences"]?
- user.preferences = Preferences.from_json(body["preferences"].to_json, user.preferences)
+ user.preferences = Preferences.from_json(body["preferences"].to_json)
PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", user.preferences.to_json, user.email)
end
+
+ if playlists = body["playlists"]?.try &.as_a?
+ playlists.each do |item|
+ title = item["title"]?.try &.as_s?.try &.delete("<>")
+ description = item["description"]?.try &.as_s?.try &.delete("\r")
+ privacy = item["privacy"]?.try &.as_s?.try { |privacy| PlaylistPrivacy.parse? privacy }
+
+ next if !title
+ next if !description
+ next if !privacy
+
+ playlist = create_playlist(PG_DB, title, privacy, user)
+ PG_DB.exec("UPDATE playlists SET description = $1 WHERE id = $2", description, playlist.id)
+
+ videos = item["videos"]?.try &.as_a?.try &.each_with_index do |video_id, idx|
+ raise "Playlist cannot have more than 500 videos" if idx > 500
+
+ video_id = video_id.try &.as_s?
+ next if !video_id
+
+ begin
+ video = get_video(video_id, PG_DB)
+ rescue ex
+ next
+ end
+
+ playlist_video = PlaylistVideo.new({
+ title: video.title,
+ id: video.id,
+ author: video.author,
+ ucid: video.ucid,
+ length_seconds: video.length_seconds,
+ published: video.published,
+ plid: playlist.id,
+ live_now: video.live_now,
+ index: Random::Secure.rand(0_i64..Int64::MAX),
+ })
+
+ video_array = playlist_video.to_a
+ args = arg_array(video_array)
+
+ PG_DB.exec("INSERT INTO playlist_videos VALUES (#{args})", args: video_array)
+ PG_DB.exec("UPDATE playlists SET index = array_append(index, $1), video_count = cardinality(index) + 1, updated = $2 WHERE id = $3", playlist_video.index, Time.utc, playlist.id)
+ end
+ end
+ end
when "import_youtube"
subscriptions = XML.parse(body)
user.subscriptions += subscriptions.xpath_nodes(%q(//outline[@type="rss"])).map do |channel|
@@ -2598,13 +2146,9 @@ post "/data_control" do |env|
next match["channel"]
elsif match = channel["url"].as_s.match(/\/user\/(?<user>.+)/)
response = YT_POOL.client &.get("/user/#{match["user"]}?disable_polymer=1&hl=en&gl=US")
- document = XML.parse_html(response.body)
- canonical = document.xpath_node(%q(//link[@rel="canonical"]))
-
- if canonical
- ucid = canonical["href"].split("/")[-1]
- next ucid
- end
+ html = XML.parse_html(response.body)
+ ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
+ next ucid if ucid
end
nil
@@ -2615,7 +2159,7 @@ post "/data_control" do |env|
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = $1 WHERE email = $2", user.subscriptions, user.email)
when "import_newpipe"
- Zip::Reader.open(IO::Memory.new(body)) do |file|
+ Compress::Zip::Reader.open(IO::Memory.new(body)) do |file|
file.each_entry do |entry|
if entry.filename == "newpipe.db"
tempfile = File.tempfile(".db")
@@ -2639,6 +2183,7 @@ post "/data_control" do |env|
end
end
end
+ else nil # Ignore
end
end
end
@@ -2980,6 +2525,10 @@ post "/token_ajax" do |env|
case action
when .starts_with? "action_revoke_token"
PG_DB.exec("DELETE FROM session_ids * WHERE id = $1 AND email = $2", session, user.email)
+ else
+ error_message = {"error" => "Unsupported action #{action}"}.to_json
+ env.response.status_code = 400
+ next error_message
end
if redirect
@@ -2994,12 +2543,7 @@ end
get "/feed/top" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
-
- if config.top_enabled
- templated "top"
- else
- env.redirect "/"
- end
+ env.redirect "/"
end
get "/feed/popular" do |env|
@@ -3122,12 +2666,10 @@ get "/feed/channel/:ucid" do |env|
next error_message
end
- rss = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}").body
- rss = XML.parse_html(rss)
-
- videos = [] of SearchVideo
+ response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}")
+ rss = XML.parse_html(response.body)
- rss.xpath_nodes("//feed/entry").each do |entry|
+ videos = rss.xpath_nodes("//feed/entry").map do |entry|
video_id = entry.xpath_node("videoid").not_nil!.content
title = entry.xpath_node("title").not_nil!.content
@@ -3139,41 +2681,39 @@ get "/feed/channel/:ucid" do |env|
description_html = entry.xpath_node("group/description").not_nil!.to_s
views = entry.xpath_node("group/community/statistics").not_nil!.["views"].to_i64
- videos << SearchVideo.new(
- title: title,
- id: video_id,
- author: author,
- ucid: ucid,
- published: published,
- views: views,
- description_html: description_html,
- length_seconds: 0,
- live_now: false,
- paid: false,
- premium: false,
- premiere_timestamp: nil
- )
+ SearchVideo.new({
+ title: title,
+ id: video_id,
+ author: author,
+ ucid: ucid,
+ published: published,
+ views: views,
+ description_html: description_html,
+ length_seconds: 0,
+ live_now: false,
+ paid: false,
+ premium: false,
+ premiere_timestamp: nil,
+ })
end
- host_url = make_host_url(config, Kemal.config)
-
XML.build(indent: " ", encoding: "UTF-8") do |xml|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
"xml:lang": "en-US") do
- xml.element("link", rel: "self", href: "#{host_url}#{env.request.resource}")
+ xml.element("link", rel: "self", href: "#{HOST_URL}#{env.request.resource}")
xml.element("id") { xml.text "yt:channel:#{channel.ucid}" }
xml.element("yt:channelId") { xml.text channel.ucid }
xml.element("title") { xml.text channel.author }
- xml.element("link", rel: "alternate", href: "#{host_url}/channel/#{channel.ucid}")
+ xml.element("link", rel: "alternate", href: "#{HOST_URL}/channel/#{channel.ucid}")
xml.element("author") do
xml.element("name") { xml.text channel.author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{channel.ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{channel.ucid}" }
end
videos.each do |video|
- video.to_xml(host_url, channel.auto_generated, params, xml)
+ video.to_xml(channel.auto_generated, params, xml)
end
end
end
@@ -3207,19 +2747,18 @@ get "/feed/private" do |env|
params = HTTP::Params.parse(env.params.query["params"]? || "")
videos, notifications = get_subscription_feed(PG_DB, user, max_results, page)
- host_url = make_host_url(config, Kemal.config)
XML.build(indent: " ", encoding: "UTF-8") do |xml|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
"xml:lang": "en-US") do
- xml.element("link", "type": "text/html", rel: "alternate", href: "#{host_url}/feed/subscriptions")
+ xml.element("link", "type": "text/html", rel: "alternate", href: "#{HOST_URL}/feed/subscriptions")
xml.element("link", "type": "application/atom+xml", rel: "self",
- href: "#{host_url}#{env.request.resource}")
+ href: "#{HOST_URL}#{env.request.resource}")
xml.element("title") { xml.text translate(locale, "Invidious Private Feed for `x`", user.email) }
(notifications + videos).each do |video|
- video.to_xml(locale, host_url, params, xml)
+ video.to_xml(locale, params, xml)
end
end
end
@@ -3233,8 +2772,6 @@ get "/feed/playlist/:plid" do |env|
plid = env.params.url["plid"]
params = HTTP::Params.parse(env.params.query["params"]? || "")
-
- host_url = make_host_url(config, Kemal.config)
path = env.request.path
if plid.starts_with? "IV"
@@ -3245,18 +2782,18 @@ get "/feed/playlist/:plid" do |env|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
"xml:lang": "en-US") do
- xml.element("link", rel: "self", href: "#{host_url}#{env.request.resource}")
+ xml.element("link", rel: "self", href: "#{HOST_URL}#{env.request.resource}")
xml.element("id") { xml.text "iv:playlist:#{plid}" }
xml.element("iv:playlistId") { xml.text plid }
xml.element("title") { xml.text playlist.title }
- xml.element("link", rel: "alternate", href: "#{host_url}/playlist?list=#{plid}")
+ xml.element("link", rel: "alternate", href: "#{HOST_URL}/playlist?list=#{plid}")
xml.element("author") do
xml.element("name") { xml.text playlist.author }
end
videos.each do |video|
- video.to_xml(host_url, false, xml)
+ video.to_xml(false, xml)
end
end
end
@@ -3275,7 +2812,8 @@ get "/feed/playlist/:plid" do |env|
when "url", "href"
full_path = URI.parse(node[attribute.name]).full_path
query_string_opt = full_path.starts_with?("/watch?v=") ? "&#{params}" : ""
- node[attribute.name] = "#{host_url}#{full_path}#{query_string_opt}"
+ node[attribute.name] = "#{HOST_URL}#{full_path}#{query_string_opt}"
+ else nil # Skip
end
end
end
@@ -3283,7 +2821,7 @@ get "/feed/playlist/:plid" do |env|
document = document.to_xml(options: XML::SaveOptions::NO_DECL)
document.scan(/<uri>(?<url>[^<]+)<\/uri>/).each do |match|
- content = "#{host_url}#{URI.parse(match["url"]).full_path}"
+ content = "#{HOST_URL}#{URI.parse(match["url"]).full_path}"
document = document.gsub(match[0], "<uri>#{content}</uri>")
end
@@ -3386,39 +2924,26 @@ post "/feed/webhook/:token" do |env|
}.to_json
PG_DB.exec("NOTIFY notifications, E'#{payload}'")
- video = ChannelVideo.new(
- id: id,
- title: video.title,
- published: published,
- updated: updated,
- ucid: video.ucid,
- author: author,
- length_seconds: video.length_seconds,
- live_now: video.live_now,
+ video = ChannelVideo.new({
+ id: id,
+ title: video.title,
+ published: published,
+ updated: updated,
+ ucid: video.ucid,
+ author: author,
+ length_seconds: video.length_seconds,
+ live_now: video.live_now,
premiere_timestamp: video.premiere_timestamp,
- views: video.views,
- )
-
- emails = PG_DB.query_all("UPDATE users SET notifications = notifications || $1 \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications) RETURNING email",
- video.id, video.published, video.ucid, as: String)
+ views: video.views,
+ })
- video_array = video.to_a
- args = arg_array(video_array)
-
- PG_DB.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = PG_DB.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, premiere_timestamp = $9, views = $10", args: video_array)
-
- # Update all users affected by insert
- if emails.empty?
- values = "'{}'"
- else
- values = "VALUES #{emails.map { |email| %((E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}')) }.join(",")}"
- end
+ live_now = $8, premiere_timestamp = $9, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
- PG_DB.exec("UPDATE users SET feed_needs_update = true WHERE email = ANY(#{values})")
+ PG_DB.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
end
@@ -3471,14 +2996,12 @@ get "/c/:user" do |env|
user = env.params.url["user"]
response = YT_POOL.client &.get("/c/#{user}")
- document = XML.parse_html(response.body)
+ html = XML.parse_html(response.body)
- anchor = document.xpath_node(%q(//a[contains(@class,"branded-page-header-title-link")]))
- if !anchor
- next env.redirect "/"
- end
+ ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
+ next env.redirect "/" if !ucid
- env.redirect anchor["href"]
+ env.redirect "/channel/#{ucid}"
end
# Legacy endpoint for /user/:username
@@ -3568,14 +3091,14 @@ get "/channel/:ucid" do |env|
item.author
end
end
- items = items.select { |item| item.is_a?(SearchPlaylist) }.map { |item| item.as(SearchPlaylist) }
+ items = items.select(&.is_a?(SearchPlaylist)).map(&.as(SearchPlaylist))
items.each { |item| item.author = "" }
else
sort_options = {"newest", "oldest", "popular"}
sort_by ||= "newest"
- items, count = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
- items.select! { |item| !item.paid }
+ count, items = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
+ items.reject! &.paid
env.set "search", "channel:#{channel.ucid} "
end
@@ -3670,7 +3193,7 @@ get "/channel/:ucid/community" do |env|
end
begin
- items = JSON.parse(fetch_channel_community(ucid, continuation, locale, config, Kemal.config, "json", thin_mode))
+ items = JSON.parse(fetch_channel_community(ucid, continuation, locale, "json", thin_mode))
rescue ex
env.response.status_code = 500
error_message = ex.message
@@ -3691,12 +3214,7 @@ get "/api/v1/stats" do |env|
next error_message
end
- if statistics["error"]?
- env.response.status_code = 500
- next statistics.to_json
- end
-
- statistics.to_json
+ Invidious::Jobs::StatisticsRefreshJob::STATISTICS.to_json
end
# YouTube provides "storyboards", which are sprites containing x * y
@@ -3723,7 +3241,6 @@ get "/api/v1/storyboards/:id" do |env|
end
storyboards = video.storyboards
-
width = env.params.query["width"]?
height = env.params.query["height"]?
@@ -3731,7 +3248,7 @@ get "/api/v1/storyboards/:id" do |env|
response = JSON.build do |json|
json.object do
json.field "storyboards" do
- generate_storyboards(json, id, storyboards, config, Kemal.config)
+ generate_storyboards(json, id, storyboards)
end
end
end
@@ -3761,8 +3278,10 @@ get "/api/v1/storyboards/:id" do |env|
end_time = storyboard[:interval].milliseconds
storyboard[:storyboard_count].times do |i|
- host_url = make_host_url(config, Kemal.config)
- url = storyboard[:url].gsub("$M", i).gsub("https://i9.ytimg.com", host_url)
+ url = storyboard[:url]
+ authority = /(i\d?).ytimg.com/.match(url).not_nil![1]?
+ url = storyboard[:url].gsub("$M", i).gsub(%r(https://i\d?.ytimg.com/sb/), "")
+ url = "#{HOST_URL}/sb/#{authority}/#{url}"
storyboard[:storyboard_height].times do |j|
storyboard[:storyboard_width].times do |k|
@@ -3837,10 +3356,10 @@ get "/api/v1/captions/:id" do |env|
env.response.content_type = "text/vtt; charset=UTF-8"
- caption = captions.select { |caption| caption.name.simpleText == label }
-
if lang
caption = captions.select { |caption| caption.languageCode == lang }
+ else
+ caption = captions.select { |caption| caption.name.simpleText == label }
end
if caption.empty?
@@ -3850,7 +3369,7 @@ get "/api/v1/captions/:id" do |env|
caption = caption[0]
end
- url = "#{caption.baseUrl}&tlang=#{tlang}"
+ url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path
# Auto-generated captions often have cues that aren't aligned properly with the video,
# as well as some other markup that makes it cumbersome, so we try to fix that here
@@ -4044,7 +3563,7 @@ get "/api/v1/annotations/:id" do |env|
cache_annotation(PG_DB, id, annotations)
end
- when "youtube"
+ else # "youtube"
response = YT_POOL.client &.get("/annotations_invideo?video_id=#{id}")
if response.status_code != 200
@@ -4085,7 +3604,7 @@ get "/api/v1/videos/:id" do |env|
next error_message
end
- video.to_json(locale, config, Kemal.config, decrypt_function)
+ video.to_json(locale)
end
get "/api/v1/trending" do |env|
@@ -4107,7 +3626,7 @@ get "/api/v1/trending" do |env|
videos = JSON.build do |json|
json.array do
trending.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4123,7 +3642,7 @@ get "/api/v1/popular" do |env|
JSON.build do |json|
json.array do
popular_videos.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4133,41 +3652,7 @@ get "/api/v1/top" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/json"
-
- if !config.top_enabled
- error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
- env.response.status_code = 400
- next error_message
- end
-
- JSON.build do |json|
- json.array do
- top_videos.each do |video|
- # Top videos have much more information than provided below (adaptiveFormats, etc)
- # but can be very out of date, so we only provide a subset here
-
- json.object do
- json.field "title", video.title
- json.field "videoId", video.id
- json.field "videoThumbnails" do
- generate_thumbnails(json, video.id, config, Kemal.config)
- end
-
- json.field "lengthSeconds", video.length_seconds
- json.field "viewCount", video.views
-
- json.field "author", video.author
- json.field "authorId", video.ucid
- json.field "authorUrl", "/channel/#{video.ucid}"
- json.field "published", video.published.to_unix
- json.field "publishedText", translate(locale, "`x` ago", recode_date(video.published, locale))
-
- json.field "description", html_to_content(video.description_html)
- json.field "descriptionHtml", video.description_html
- end
- end
- end
- end
+ "[]"
end
get "/api/v1/channels/:ucid" do |env|
@@ -4198,7 +3683,7 @@ get "/api/v1/channels/:ucid" do |env|
count = 0
else
begin
- videos, count = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
+ count, videos = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
rescue ex
error_message = {"error" => ex.message}.to_json
env.response.status_code = 500
@@ -4244,7 +3729,7 @@ get "/api/v1/channels/:ucid" do |env|
qualities.each do |quality|
json.object do
- json.field "url", channel.author_thumbnail.gsub(/=\d+/, "=s#{quality}")
+ json.field "url", channel.author_thumbnail.gsub(/=s\d+/, "=s#{quality}")
json.field "width", quality
json.field "height", quality
end
@@ -4267,7 +3752,7 @@ get "/api/v1/channels/:ucid" do |env|
json.field "latestVideos" do
json.array do
videos.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4328,7 +3813,7 @@ end
end
begin
- videos, count = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
+ count, videos = get_60_videos(channel.ucid, channel.author, page, channel.auto_generated, sort_by)
rescue ex
error_message = {"error" => ex.message}.to_json
env.response.status_code = 500
@@ -4338,7 +3823,7 @@ end
JSON.build do |json|
json.array do
videos.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4364,7 +3849,7 @@ end
JSON.build do |json|
json.array do
videos.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4379,9 +3864,9 @@ end
ucid = env.params.url["ucid"]
continuation = env.params.query["continuation"]?
- sort_by = env.params.query["sort"]?.try &.downcase
- sort_by ||= env.params.query["sort_by"]?.try &.downcase
- sort_by ||= "last"
+ sort_by = env.params.query["sort"]?.try &.downcase ||
+ env.params.query["sort_by"]?.try &.downcase ||
+ "last"
begin
channel = get_about_info(ucid, locale)
@@ -4403,9 +3888,7 @@ end
json.field "playlists" do
json.array do
items.each do |item|
- if item.is_a?(SearchPlaylist)
- item.to_json(locale, config, Kemal.config, json)
- end
+ item.to_json(locale, json) if item.is_a?(SearchPlaylist)
end
end
end
@@ -4434,7 +3917,7 @@ end
# sort_by = env.params.query["sort_by"]?.try &.downcase
begin
- fetch_channel_community(ucid, continuation, locale, config, Kemal.config, format, thin_mode)
+ fetch_channel_community(ucid, continuation, locale, format, thin_mode)
rescue ex
env.response.status_code = 400
error_message = {"error" => ex.message}.to_json
@@ -4460,7 +3943,7 @@ get "/api/v1/channels/search/:ucid" do |env|
JSON.build do |json|
json.array do
search_results.each do |item|
- item.to_json(locale, config, Kemal.config, json)
+ item.to_json(locale, json)
end
end
end
@@ -4505,7 +3988,7 @@ get "/api/v1/search" do |env|
JSON.build do |json|
json.array do
search_results.each do |item|
- item.to_json(locale, config, Kemal.config, json)
+ item.to_json(locale, json)
end
end
end
@@ -4521,9 +4004,8 @@ get "/api/v1/search/suggestions" do |env|
query ||= ""
begin
- response = QUIC::Client.get(
- "https://suggestqueries.google.com/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback"
- ).body
+ headers = HTTP::Headers{":authority" => "suggestqueries.google.com"}
+ response = YT_POOL.client &.get("/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback", headers).body
body = response[35..-2]
body = JSON.parse(body).as_a
@@ -4583,7 +4065,7 @@ end
next error_message
end
- response = playlist.to_json(offset, locale, config, Kemal.config, continuation: continuation)
+ response = playlist.to_json(offset, locale, continuation: continuation)
if format == "html"
response = JSON.parse(response)
@@ -4647,7 +4129,7 @@ get "/api/v1/mixes/:rdid" do |env|
json.field "videoThumbnails" do
json.array do
- generate_thumbnails(json, video.id, config, Kemal.config)
+ generate_thumbnails(json, video.id)
end
end
@@ -4682,7 +4164,7 @@ get "/api/v1/auth/notifications" do |env|
topics = env.params.query["topics"]?.try &.split(",").uniq.first(1000)
topics ||= [] of String
- create_notification_stream(env, config, Kemal.config, decrypt_function, topics, connection_channel)
+ create_notification_stream(env, topics, connection_channel)
end
post "/api/v1/auth/notifications" do |env|
@@ -4691,7 +4173,7 @@ post "/api/v1/auth/notifications" do |env|
topics = env.params.body["topics"]?.try &.split(",").uniq.first(1000)
topics ||= [] of String
- create_notification_stream(env, config, Kemal.config, decrypt_function, topics, connection_channel)
+ create_notification_stream(env, topics, connection_channel)
end
get "/api/v1/auth/preferences" do |env|
@@ -4705,7 +4187,7 @@ post "/api/v1/auth/preferences" do |env|
user = env.get("user").as(User)
begin
- preferences = Preferences.from_json(env.request.body || "{}", user.preferences)
+ preferences = Preferences.from_json(env.request.body || "{}")
rescue
preferences = user.preferences
end
@@ -4735,7 +4217,7 @@ get "/api/v1/auth/feed" do |env|
json.field "notifications" do
json.array do
notifications.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4743,7 +4225,7 @@ get "/api/v1/auth/feed" do |env|
json.field "videos" do
json.array do
videos.each do |video|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
@@ -4815,7 +4297,7 @@ get "/api/v1/auth/playlists" do |env|
JSON.build do |json|
json.array do
playlists.each do |playlist|
- playlist.to_json(0, locale, config, Kemal.config, json)
+ playlist.to_json(0, locale, json)
end
end
end
@@ -4846,10 +4328,8 @@ post "/api/v1/auth/playlists" do |env|
next error_message
end
- host_url = make_host_url(config, Kemal.config)
-
playlist = create_playlist(PG_DB, title, privacy, user)
- env.response.headers["Location"] = "#{host_url}/api/v1/auth/playlists/#{playlist.id}"
+ env.response.headers["Location"] = "#{HOST_URL}/api/v1/auth/playlists/#{playlist.id}"
env.response.status_code = 201
{
"title" => title,
@@ -4961,29 +4441,27 @@ post "/api/v1/auth/playlists/:plid/videos" do |env|
next error_message
end
- playlist_video = PlaylistVideo.new(
- title: video.title,
- id: video.id,
- author: video.author,
- ucid: video.ucid,
+ playlist_video = PlaylistVideo.new({
+ title: video.title,
+ id: video.id,
+ author: video.author,
+ ucid: video.ucid,
length_seconds: video.length_seconds,
- published: video.published,
- plid: plid,
- live_now: video.live_now,
- index: Random::Secure.rand(0_i64..Int64::MAX)
- )
+ published: video.published,
+ plid: plid,
+ live_now: video.live_now,
+ index: Random::Secure.rand(0_i64..Int64::MAX),
+ })
video_array = playlist_video.to_a
args = arg_array(video_array)
PG_DB.exec("INSERT INTO playlist_videos VALUES (#{args})", args: video_array)
- PG_DB.exec("UPDATE playlists SET index = array_append(index, $1), video_count = video_count + 1, updated = $2 WHERE id = $3", playlist_video.index, Time.utc, plid)
+ PG_DB.exec("UPDATE playlists SET index = array_append(index, $1), video_count = cardinality(index) + 1, updated = $2 WHERE id = $3", playlist_video.index, Time.utc, plid)
- host_url = make_host_url(config, Kemal.config)
-
- env.response.headers["Location"] = "#{host_url}/api/v1/auth/playlists/#{plid}/videos/#{playlist_video.index.to_u64.to_s(16).upcase}"
+ env.response.headers["Location"] = "#{HOST_URL}/api/v1/auth/playlists/#{plid}/videos/#{playlist_video.index.to_u64.to_s(16).upcase}"
env.response.status_code = 201
- playlist_video.to_json(locale, config, Kemal.config, index: playlist.index.size)
+ playlist_video.to_json(locale, index: playlist.index.size)
end
delete "/api/v1/auth/playlists/:plid/videos/:index" do |env|
@@ -5013,7 +4491,7 @@ delete "/api/v1/auth/playlists/:plid/videos/:index" do |env|
end
PG_DB.exec("DELETE FROM playlist_videos * WHERE index = $1", index)
- PG_DB.exec("UPDATE playlists SET index = array_remove(index, $1), video_count = video_count - 1, updated = $2 WHERE id = $3", index, Time.utc, plid)
+ PG_DB.exec("UPDATE playlists SET index = array_remove(index, $1), video_count = cardinality(index) - 1, updated = $2 WHERE id = $3", index, Time.utc, plid)
env.response.status_code = 204
end
@@ -5150,7 +4628,7 @@ get "/api/manifest/dash/id/:id" do |env|
# Since some implementations create playlists based on resolution regardless of different codecs,
# we can opt to only add a source to a representation if it has a unique height within that representation
- unique_res = env.params.query["unique_res"]? && (env.params.query["unique_res"] == "true" || env.params.query["unique_res"] == "1")
+ unique_res = env.params.query["unique_res"]?.try { |q| (q == "true" || q == "1").to_unsafe }
begin
video = get_video(id, PG_DB, region: region)
@@ -5161,8 +4639,8 @@ get "/api/manifest/dash/id/:id" do |env|
next
end
- if dashmpd = video.player_response["streamingData"]?.try &.["dashManifestUrl"]?.try &.as_s
- manifest = YT_POOL.client &.get(dashmpd).body
+ if dashmpd = video.dash_manifest_url
+ manifest = YT_POOL.client &.get(URI.parse(dashmpd).full_path).body
manifest = manifest.gsub(/<BaseURL>[^<]+<\/BaseURL>/) do |baseurl|
url = baseurl.lchop("<BaseURL>")
@@ -5178,16 +4656,16 @@ get "/api/manifest/dash/id/:id" do |env|
next manifest
end
- adaptive_fmts = video.adaptive_fmts(decrypt_function)
+ adaptive_fmts = video.adaptive_fmts
if local
adaptive_fmts.each do |fmt|
- fmt["url"] = URI.parse(fmt["url"]).full_path
+ fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path)
end
end
- audio_streams = video.audio_streams(adaptive_fmts)
- video_streams = video.video_streams(adaptive_fmts).sort_by { |stream| stream["fps"].to_i }.reverse
+ audio_streams = video.audio_streams
+ video_streams = video.video_streams.sort_by { |stream| {stream["width"].as_i, stream["fps"].as_i} }.reverse
XML.build(indent: " ", encoding: "UTF-8") do |xml|
xml.element("MPD", "xmlns": "urn:mpeg:dash:schema:mpd:2011",
@@ -5197,24 +4675,22 @@ get "/api/manifest/dash/id/:id" do |env|
i = 0
{"audio/mp4", "audio/webm"}.each do |mime_type|
- mime_streams = audio_streams.select { |stream| stream["type"].starts_with? mime_type }
- if mime_streams.empty?
- next
- end
+ mime_streams = audio_streams.select { |stream| stream["mimeType"].as_s.starts_with? mime_type }
+ next if mime_streams.empty?
xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true) do
mime_streams.each do |fmt|
- codecs = fmt["type"].split("codecs=")[1].strip('"')
- bandwidth = fmt["bitrate"].to_i * 1000
- itag = fmt["itag"]
- url = fmt["url"]
+ codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"')
+ bandwidth = fmt["bitrate"].as_i
+ itag = fmt["itag"].as_i
+ url = fmt["url"].as_s
xml.element("Representation", id: fmt["itag"], codecs: codecs, bandwidth: bandwidth) do
xml.element("AudioChannelConfiguration", schemeIdUri: "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
value: "2")
xml.element("BaseURL") { xml.text url }
- xml.element("SegmentBase", indexRange: fmt["index"]) do
- xml.element("Initialization", range: fmt["init"])
+ xml.element("SegmentBase", indexRange: "#{fmt["indexRange"]["start"]}-#{fmt["indexRange"]["end"]}") do
+ xml.element("Initialization", range: "#{fmt["initRange"]["start"]}-#{fmt["initRange"]["end"]}")
end
end
end
@@ -5223,23 +4699,24 @@ get "/api/manifest/dash/id/:id" do |env|
i += 1
end
+ potential_heights = {4320, 2160, 1440, 1080, 720, 480, 360, 240, 144}
+
{"video/mp4", "video/webm"}.each do |mime_type|
- mime_streams = video_streams.select { |stream| stream["type"].starts_with? mime_type }
- if mime_streams.empty?
- next
- end
+ mime_streams = video_streams.select { |stream| stream["mimeType"].as_s.starts_with? mime_type }
+ next if mime_streams.empty?
heights = [] of Int32
xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true, scanType: "progressive") do
mime_streams.each do |fmt|
- codecs = fmt["type"].split("codecs=")[1].strip('"')
- bandwidth = fmt["bitrate"]
- itag = fmt["itag"]
- url = fmt["url"]
- width, height = fmt["size"].split("x").map { |i| i.to_i }
+ codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"')
+ bandwidth = fmt["bitrate"].as_i
+ itag = fmt["itag"].as_i
+ url = fmt["url"].as_s
+ width = fmt["width"].as_i
+ height = fmt["height"].as_i
# Resolutions reported by YouTube player (may not accurately reflect source)
- height = [4320, 2160, 1440, 1080, 720, 480, 360, 240, 144].sort_by { |i| (height - i).abs }[0]
+ height = potential_heights.min_by { |i| (height - i).abs }
next if unique_res && heights.includes? height
heights << height
@@ -5247,8 +4724,8 @@ get "/api/manifest/dash/id/:id" do |env|
startWithSAP: "1", maxPlayoutRate: "1",
bandwidth: bandwidth, frameRate: fmt["fps"]) do
xml.element("BaseURL") { xml.text url }
- xml.element("SegmentBase", indexRange: fmt["index"]) do
- xml.element("Initialization", range: fmt["init"])
+ xml.element("SegmentBase", indexRange: "#{fmt["indexRange"]["start"]}-#{fmt["indexRange"]["end"]}") do
+ xml.element("Initialization", range: "#{fmt["initRange"]["start"]}-#{fmt["initRange"]["end"]}")
end
end
end
@@ -5262,10 +4739,10 @@ get "/api/manifest/dash/id/:id" do |env|
end
get "/api/manifest/hls_variant/*" do |env|
- manifest = YT_POOL.client &.get(env.request.path)
+ response = YT_POOL.client &.get(env.request.path)
- if manifest.status_code != 200
- env.response.status_code = manifest.status_code
+ if response.status_code != 200
+ env.response.status_code = response.status_code
next
end
@@ -5274,12 +4751,10 @@ get "/api/manifest/hls_variant/*" do |env|
env.response.content_type = "application/x-mpegURL"
env.response.headers.add("Access-Control-Allow-Origin", "*")
- host_url = make_host_url(config, Kemal.config)
-
- manifest = manifest.body
+ manifest = response.body
if local
- manifest = manifest.gsub("https://www.youtube.com", host_url)
+ manifest = manifest.gsub("https://www.youtube.com", HOST_URL)
manifest = manifest.gsub("index.m3u8", "index.m3u8?local=true")
end
@@ -5287,10 +4762,10 @@ get "/api/manifest/hls_variant/*" do |env|
end
get "/api/manifest/hls_playlist/*" do |env|
- manifest = YT_POOL.client &.get(env.request.path)
+ response = YT_POOL.client &.get(env.request.path)
- if manifest.status_code != 200
- env.response.status_code = manifest.status_code
+ if response.status_code != 200
+ env.response.status_code = response.status_code
next
end
@@ -5299,9 +4774,7 @@ get "/api/manifest/hls_playlist/*" do |env|
env.response.content_type = "application/x-mpegURL"
env.response.headers.add("Access-Control-Allow-Origin", "*")
- host_url = make_host_url(config, Kemal.config)
-
- manifest = manifest.body
+ manifest = response.body
if local
manifest = manifest.gsub(/^https:\/\/r\d---.{11}\.c\.youtube\.com[^\n]*/m) do |match|
@@ -5336,7 +4809,7 @@ get "/api/manifest/hls_playlist/*" do |env|
raw_params["local"] = "true"
- "#{host_url}/videoplayback?#{raw_params}"
+ "#{HOST_URL}/videoplayback?#{raw_params}"
end
end
@@ -5362,7 +4835,7 @@ get "/latest_version" do |env|
end
id ||= env.params.query["id"]?
- itag ||= env.params.query["itag"]?
+ itag ||= env.params.query["itag"]?.try &.to_i
region = env.params.query["region"]?
@@ -5377,26 +4850,16 @@ get "/latest_version" do |env|
video = get_video(id, PG_DB, region: region)
- fmt_stream = video.fmt_stream(decrypt_function)
- adaptive_fmts = video.adaptive_fmts(decrypt_function)
+ fmt = video.fmt_stream.find(nil) { |f| f["itag"].as_i == itag } || video.adaptive_fmts.find(nil) { |f| f["itag"].as_i == itag }
+ url = fmt.try &.["url"]?.try &.as_s
- urls = (fmt_stream + adaptive_fmts).select { |fmt| fmt["itag"] == itag }
- if urls.empty?
+ if !url
env.response.status_code = 404
next
- elsif urls.size > 1
- env.response.status_code = 409
- next
- end
-
- url = urls[0]["url"]
- if local
- url = URI.parse(url).full_path.not_nil!
end
- if title
- url += "&title=#{title}"
- end
+ url = URI.parse(url).full_path.not_nil! if local
+ url = "#{url}&title=#{title}" if title
env.redirect url
end
@@ -5489,8 +4952,8 @@ get "/videoplayback" do |env|
end
client = make_client(URI.parse(host), region)
-
response = HTTP::Client::Response.new(500)
+ error = ""
5.times do
begin
response = client.head(url, headers)
@@ -5515,12 +4978,14 @@ get "/videoplayback" do |env|
host = "https://r#{fvip}---#{mn}.googlevideo.com"
client = make_client(URI.parse(host), region)
rescue ex
+ error = ex.message
end
end
if response.status_code >= 400
env.response.status_code = response.status_code
- next
+ env.response.content_type = "text/plain"
+ next error
end
if url.includes? "&file=seg.ts"
@@ -5534,7 +4999,7 @@ get "/videoplayback" do |env|
client = make_client(URI.parse(host), region)
client.get(url, headers) do |response|
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes?(key)
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
@@ -5602,7 +5067,7 @@ get "/videoplayback" do |env|
end
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes?(key) && key != "Content-Range"
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase) && key.downcase != "content-range"
env.response.headers[key] = value
end
end
@@ -5651,11 +5116,9 @@ get "/videoplayback" do |env|
end
get "/ggpht/*" do |env|
- host = "https://yt3.ggpht.com"
- client = make_client(URI.parse(host))
url = env.request.path.lchop("/ggpht")
- headers = HTTP::Headers.new
+ headers = HTTP::Headers{":authority" => "yt3.ggpht.com"}
REQUEST_HEADERS_WHITELIST.each do |header|
if env.request.headers[header]?
headers[header] = env.request.headers[header]
@@ -5663,10 +5126,10 @@ get "/ggpht/*" do |env|
end
begin
- client.get(url, headers) do |response|
+ YT_POOL.client &.get(url, headers) do |response|
env.response.status_code = response.status_code
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes? key
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
@@ -5684,28 +5147,24 @@ get "/ggpht/*" do |env|
end
end
-options "/sb/:id/:storyboard/:index" do |env|
- env.response.headers.delete("Content-Type")
+options "/sb/:authority/:id/:storyboard/:index" do |env|
env.response.headers["Access-Control-Allow-Origin"] = "*"
env.response.headers["Access-Control-Allow-Methods"] = "GET, OPTIONS"
env.response.headers["Access-Control-Allow-Headers"] = "Content-Type, Range"
end
-get "/sb/:id/:storyboard/:index" do |env|
+get "/sb/:authority/:id/:storyboard/:index" do |env|
+ authority = env.params.url["authority"]
id = env.params.url["id"]
storyboard = env.params.url["storyboard"]
index = env.params.url["index"]
- if storyboard.starts_with? "storyboard_live"
- host = "https://i.ytimg.com"
- else
- host = "https://i9.ytimg.com"
- end
- client = make_client(URI.parse(host))
-
url = "/sb/#{id}/#{storyboard}/#{index}?#{env.params.query}"
headers = HTTP::Headers.new
+
+ headers[":authority"] = "#{authority}.ytimg.com"
+
REQUEST_HEADERS_WHITELIST.each do |header|
if env.request.headers[header]?
headers[header] = env.request.headers[header]
@@ -5713,14 +5172,15 @@ get "/sb/:id/:storyboard/:index" do |env|
end
begin
- client.get(url, headers) do |response|
+ YT_POOL.client &.get(url, headers) do |response|
env.response.status_code = response.status_code
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes? key
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
+ env.response.headers["Connection"] = "close"
env.response.headers["Access-Control-Allow-Origin"] = "*"
if response.status_code >= 300
@@ -5738,11 +5198,9 @@ get "/s_p/:id/:name" do |env|
id = env.params.url["id"]
name = env.params.url["name"]
- host = "https://i9.ytimg.com"
- client = make_client(URI.parse(host))
url = env.request.resource
- headers = HTTP::Headers.new
+ headers = HTTP::Headers{":authority" => "i9.ytimg.com"}
REQUEST_HEADERS_WHITELIST.each do |header|
if env.request.headers[header]?
headers[header] = env.request.headers[header]
@@ -5750,10 +5208,10 @@ get "/s_p/:id/:name" do |env|
end
begin
- client.get(url, headers) do |response|
+ YT_POOL.client &.get(url, headers) do |response|
env.response.status_code = response.status_code
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes? key
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
@@ -5783,7 +5241,7 @@ get "/yts/img/:name" do |env|
YT_POOL.client &.get(env.request.resource, headers) do |response|
env.response.status_code = response.status_code
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes? key
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
@@ -5805,9 +5263,11 @@ get "/vi/:id/:name" do |env|
id = env.params.url["id"]
name = env.params.url["name"]
+ headers = HTTP::Headers{":authority" => "i.ytimg.com"}
+
if name == "maxres.jpg"
- build_thumbnails(id, config, Kemal.config).each do |thumb|
- if YT_IMG_POOL.client &.head("/vi/#{id}/#{thumb[:url]}.jpg").status_code == 200
+ build_thumbnails(id).each do |thumb|
+ if YT_POOL.client &.head("/vi/#{id}/#{thumb[:url]}.jpg", headers).status_code == 200
name = thumb[:url] + ".jpg"
break
end
@@ -5815,7 +5275,6 @@ get "/vi/:id/:name" do |env|
end
url = "/vi/#{id}/#{name}"
- headers = HTTP::Headers.new
REQUEST_HEADERS_WHITELIST.each do |header|
if env.request.headers[header]?
headers[header] = env.request.headers[header]
@@ -5823,10 +5282,10 @@ get "/vi/:id/:name" do |env|
end
begin
- YT_IMG_POOL.client &.get(url, headers) do |response|
+ YT_POOL.client &.get(url, headers) do |response|
env.response.status_code = response.status_code
response.headers.each do |key, value|
- if !RESPONSE_HEADERS_BLACKLIST.includes? key
+ if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase)
env.response.headers[key] = value
end
end
@@ -5845,8 +5304,8 @@ get "/vi/:id/:name" do |env|
end
get "/Captcha" do |env|
- client = make_client(LOGIN_URL)
- response = client.get(env.request.resource)
+ headers = HTTP::Headers{":authority" => "accounts.google.com"}
+ response = YT_POOL.client &.get(env.request.resource, headers)
env.response.headers["Content-Type"] = response.headers["Content-Type"]
response.body
end
@@ -5870,7 +5329,7 @@ error 404 do |env|
response = YT_POOL.client &.get("/#{item}")
if response.status_code == 301
- response = YT_POOL.client &.get(response.headers["Location"])
+ response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).full_path)
end
if response.body.empty?
@@ -5879,10 +5338,10 @@ error 404 do |env|
end
html = XML.parse_html(response.body)
- ucid = html.xpath_node(%q(//meta[@itemprop="channelId"]))
+ ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
if ucid
- env.response.headers["Location"] = "/channel/#{ucid["content"]}"
+ env.response.headers["Location"] = "/channel/#{ucid}"
halt env, status_code: 302
end
@@ -5911,7 +5370,7 @@ end
error 500 do |env|
error_message = <<-END_HTML
Looks like you've found a bug in Invidious. Feel free to open a new issue
- <a href="https://github.com/omarroth/invidious/issues">here</a>
+ <a href="https://github.com/iv-org/invidious/issues">here</a>
or send an email to
<a href="mailto:#{CONFIG.admin_email}">#{CONFIG.admin_email}</a>.
END_HTML
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr
index 10e826e5..656b9953 100644
--- a/src/invidious/channels.cr
+++ b/src/invidious/channels.cr
@@ -1,22 +1,35 @@
struct InvidiousChannel
- db_mapping({
- id: String,
- author: String,
- updated: Time,
- deleted: Bool,
- subscribed: Time?,
- })
+ include DB::Serializable
+
+ property id : String
+ property author : String
+ property updated : Time
+ property deleted : Bool
+ property subscribed : Time?
end
struct ChannelVideo
- def to_json(locale, config, kemal_config, json : JSON::Builder)
+ include DB::Serializable
+
+ property id : String
+ property title : String
+ property published : Time
+ property updated : Time
+ property ucid : String
+ property author : String
+ property length_seconds : Int32 = 0
+ property live_now : Bool = false
+ property premiere_timestamp : Time? = nil
+ property views : Int64? = nil
+
+ def to_json(locale, json : JSON::Builder)
json.object do
json.field "type", "shortVideo"
json.field "title", self.title
json.field "videoId", self.id
json.field "videoThumbnails" do
- generate_thumbnails(json, self.id, config, Kemal.config)
+ generate_thumbnails(json, self.id)
end
json.field "lengthSeconds", self.length_seconds
@@ -31,17 +44,17 @@ struct ChannelVideo
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder | Nil = nil)
+ def to_json(locale, json : JSON::Builder | Nil = nil)
if json
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
end
end
end
- def to_xml(locale, host_url, query_params, xml : XML::Builder)
+ def to_xml(locale, query_params, xml : XML::Builder)
query_params["v"] = self.id
xml.element("entry") do
@@ -49,17 +62,17 @@ struct ChannelVideo
xml.element("yt:videoId") { xml.text self.id }
xml.element("yt:channelId") { xml.text self.ucid }
xml.element("title") { xml.text self.title }
- xml.element("link", rel: "alternate", href: "#{host_url}/watch?#{query_params}")
+ xml.element("link", rel: "alternate", href: "#{HOST_URL}/watch?#{query_params}")
xml.element("author") do
xml.element("name") { xml.text self.author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{self.ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" }
end
xml.element("content", type: "xhtml") do
xml.element("div", xmlns: "http://www.w3.org/1999/xhtml") do
- xml.element("a", href: "#{host_url}/watch?#{query_params}") do
- xml.element("img", src: "#{host_url}/vi/#{self.id}/mqdefault.jpg")
+ xml.element("a", href: "#{HOST_URL}/watch?#{query_params}") do
+ xml.element("img", src: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg")
end
end
end
@@ -69,64 +82,59 @@ struct ChannelVideo
xml.element("media:group") do
xml.element("media:title") { xml.text self.title }
- xml.element("media:thumbnail", url: "#{host_url}/vi/#{self.id}/mqdefault.jpg",
+ xml.element("media:thumbnail", url: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg",
width: "320", height: "180")
end
end
end
- def to_xml(locale, config, kemal_config, xml : XML::Builder | Nil = nil)
+ def to_xml(locale, xml : XML::Builder | Nil = nil)
if xml
- to_xml(locale, config, kemal_config, xml)
+ to_xml(locale, xml)
else
XML.build do |xml|
- to_xml(locale, config, kemal_config, xml)
+ to_xml(locale, xml)
end
end
end
- db_mapping({
- id: String,
- title: String,
- published: Time,
- updated: Time,
- ucid: String,
- author: String,
- length_seconds: {type: Int32, default: 0},
- live_now: {type: Bool, default: false},
- premiere_timestamp: {type: Time?, default: nil},
- views: {type: Int64?, default: nil},
- })
+ def to_tuple
+ {% begin %}
+ {
+ {{*@type.instance_vars.map { |var| var.name }}}
+ }
+ {% end %}
+ end
end
struct AboutRelatedChannel
- db_mapping({
- ucid: String,
- author: String,
- author_url: String,
- author_thumbnail: String,
- })
+ include DB::Serializable
+
+ property ucid : String
+ property author : String
+ property author_url : String
+ property author_thumbnail : String
end
# TODO: Refactor into either SearchChannel or InvidiousChannel
struct AboutChannel
- db_mapping({
- ucid: String,
- author: String,
- auto_generated: Bool,
- author_url: String,
- author_thumbnail: String,
- banner: String?,
- description_html: String,
- paid: Bool,
- total_views: Int64,
- sub_count: Int32,
- joined: Time,
- is_family_friendly: Bool,
- allowed_regions: Array(String),
- related_channels: Array(AboutRelatedChannel),
- tabs: Array(String),
- })
+ include DB::Serializable
+
+ property ucid : String
+ property author : String
+ property auto_generated : Bool
+ property author_url : String
+ property author_thumbnail : String
+ property banner : String?
+ property description_html : String
+ property paid : Bool
+ property total_views : Int64
+ property sub_count : Int32
+ property joined : Time
+ property is_family_friendly : Bool
+ property allowed_regions : Array(String)
+ property related_channels : Array(AboutRelatedChannel)
+ property tabs : Array(String)
end
class ChannelRedirect < Exception
@@ -213,23 +221,20 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
page = 1
- url = produce_channel_videos_url(ucid, page, auto_generated: auto_generated)
- response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
+ response = get_channel_videos_response(ucid, page, auto_generated: auto_generated)
- if json["content_html"]? && !json["content_html"].as_s.empty?
- document = XML.parse_html(json["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
-
- if auto_generated
- videos = extract_videos(nodeset)
- else
- videos = extract_videos(nodeset, ucid, author)
+ videos = [] of SearchVideo
+ begin
+ initial_data = JSON.parse(response.body).as_a.find &.["response"]?
+ raise "Could not extract JSON" if !initial_data
+ videos = extract_videos(initial_data.as_h, author, ucid)
+ rescue ex
+ if response.body.includes?("To continue with your YouTube experience, please fill out the form below.") ||
+ response.body.includes?("https://www.google.com/sorry/index")
+ raise "Could not extract channel info. Instance is likely blocked."
end
end
- videos ||= [] of ChannelVideo
-
rss.xpath_nodes("//feed/entry").each do |entry|
video_id = entry.xpath_node("videoid").not_nil!.content
title = entry.xpath_node("title").not_nil!.content
@@ -250,41 +255,28 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
premiere_timestamp = channel_video.try &.premiere_timestamp
- video = ChannelVideo.new(
- id: video_id,
- title: title,
- published: published,
- updated: Time.utc,
- ucid: ucid,
- author: author,
- length_seconds: length_seconds,
- live_now: live_now,
+ video = ChannelVideo.new({
+ id: video_id,
+ title: title,
+ published: published,
+ updated: Time.utc,
+ ucid: ucid,
+ author: author,
+ length_seconds: length_seconds,
+ live_now: live_now,
premiere_timestamp: premiere_timestamp,
- views: views,
- )
-
- emails = db.query_all("UPDATE users SET notifications = notifications || $1 \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications) RETURNING email",
- video.id, video.published, ucid, as: String)
-
- video_array = video.to_a
- args = arg_array(video_array)
+ views: views,
+ })
# We don't include the 'premiere_timestamp' here because channel pages don't include them,
# meaning the above timestamp is always null
- db.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = db.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, views = $10", args: video_array)
-
- # Update all users affected by insert
- if emails.empty?
- values = "'{}'"
- else
- values = "VALUES #{emails.map { |email| %((E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}')) }.join(",")}"
- end
+ live_now = $8, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
- db.exec("UPDATE users SET feed_needs_update = true WHERE email = ANY(#{values})")
+ db.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
if pull_all_videos
@@ -293,38 +285,24 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
ids = [] of String
loop do
- url = produce_channel_videos_url(ucid, page, auto_generated: auto_generated)
- response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
-
- if json["content_html"]? && !json["content_html"].as_s.empty?
- document = XML.parse_html(json["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
- else
- break
- end
-
- nodeset = nodeset.not_nil!
-
- if auto_generated
- videos = extract_videos(nodeset)
- else
- videos = extract_videos(nodeset, ucid, author)
- end
-
- count = nodeset.size
- videos = videos.map { |video| ChannelVideo.new(
- id: video.id,
- title: video.title,
- published: video.published,
- updated: Time.utc,
- ucid: video.ucid,
- author: video.author,
- length_seconds: video.length_seconds,
- live_now: video.live_now,
+ response = get_channel_videos_response(ucid, page, auto_generated: auto_generated)
+ initial_data = JSON.parse(response.body).as_a.find &.["response"]?
+ raise "Could not extract JSON" if !initial_data
+ videos = extract_videos(initial_data.as_h, author, ucid)
+
+ count = videos.size
+ videos = videos.map { |video| ChannelVideo.new({
+ id: video.id,
+ title: video.title,
+ published: video.published,
+ updated: Time.utc,
+ ucid: video.ucid,
+ author: video.author,
+ length_seconds: video.length_seconds,
+ live_now: video.live_now,
premiere_timestamp: video.premiere_timestamp,
- views: video.views
- ) }
+ views: video.views,
+ }) }
videos.each do |video|
ids << video.id
@@ -332,75 +310,42 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
# We are notified of Red videos elsewhere (PubSub), which includes a correct published date,
# so since they don't provide a published date here we can safely ignore them.
if Time.utc - video.published > 1.minute
- emails = db.query_all("UPDATE users SET notifications = notifications || $1 \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications) RETURNING email",
- video.id, video.published, video.ucid, as: String)
-
- video_array = video.to_a
- args = arg_array(video_array)
-
- # We don't update the 'premire_timestamp' here because channel pages don't include them
- db.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = db.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, views = $10", args: video_array)
-
- # Update all users affected by insert
- if emails.empty?
- values = "'{}'"
- else
- values = "VALUES #{emails.map { |email| %((E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}')) }.join(",")}"
- end
+ live_now = $8, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
- db.exec("UPDATE users SET feed_needs_update = true WHERE email = ANY(#{values})")
+ db.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
end
- if count < 25
- break
- end
-
+ break if count < 25
page += 1
end
-
- # When a video is deleted from a channel, we find and remove it here
- db.exec("DELETE FROM channel_videos * WHERE NOT id = ANY ('{#{ids.map { |id| %("#{id}") }.join(",")}}') AND ucid = $1", ucid)
end
- channel = InvidiousChannel.new(ucid, author, Time.utc, false, nil)
+ channel = InvidiousChannel.new({
+ id: ucid,
+ author: author,
+ updated: Time.utc,
+ deleted: false,
+ subscribed: nil,
+ })
return channel
end
def fetch_channel_playlists(ucid, author, auto_generated, continuation, sort_by)
- if continuation
+ if continuation || auto_generated
url = produce_channel_playlists_url(ucid, continuation, sort_by, auto_generated)
response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
- if json["load_more_widget_html"].as_s.empty?
- continuation = nil
- else
- continuation = XML.parse_html(json["load_more_widget_html"].as_s)
- continuation = continuation.xpath_node(%q(//button[@data-uix-load-more-href]))
-
- if continuation
- continuation = extract_channel_playlists_cursor(continuation["data-uix-load-more-href"], auto_generated)
- end
- end
-
- html = XML.parse_html(json["content_html"].as_s)
- nodeset = html.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
- elsif auto_generated
- url = "/channel/#{ucid}"
-
- response = YT_POOL.client &.get(url)
- html = XML.parse_html(response.body)
-
- nodeset = html.xpath_nodes(%q(//ul[@id="browse-items-primary"]/li[contains(@class, "feed-item-container")]))
+ continuation = response.body.match(/"continuation":"(?<continuation>[^"]+)"/).try &.["continuation"]?
+ initial_data = JSON.parse(response.body).as_a.find(&.["response"]?).try &.as_h
else
- url = "/channel/#{ucid}/playlists?disable_polymer=1&flow=list&view=1"
+ url = "/channel/#{ucid}/playlists?flow=list&view=1"
case sort_by
when "last", "last_added"
@@ -409,55 +354,58 @@ def fetch_channel_playlists(ucid, author, auto_generated, continuation, sort_by)
url += "&sort=da"
when "newest", "newest_created"
url += "&sort=dd"
+ else nil # Ignore
end
response = YT_POOL.client &.get(url)
- html = XML.parse_html(response.body)
-
- continuation = html.xpath_node(%q(//button[@data-uix-load-more-href]))
- if continuation
- continuation = extract_channel_playlists_cursor(continuation["data-uix-load-more-href"], auto_generated)
- end
-
- nodeset = html.xpath_nodes(%q(//ul[@id="browse-items-primary"]/li[contains(@class, "feed-item-container")]))
+ continuation = response.body.match(/"continuation":"(?<continuation>[^"]+)"/).try &.["continuation"]?
+ initial_data = extract_initial_data(response.body)
end
- if auto_generated
- items = extract_shelf_items(nodeset, ucid, author)
- else
- items = extract_items(nodeset, ucid, author)
- end
+ return [] of SearchItem, nil if !initial_data
+ items = extract_items(initial_data)
+ continuation = extract_channel_playlists_cursor(continuation, auto_generated) if continuation
return items, continuation
end
-def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = "newest")
+def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = "newest", v2 = false)
object = {
"80226972:embedded" => {
"2:string" => ucid,
"3:base64" => {
- "2:string" => "videos",
- "6:varint": 2_i64,
- "7:varint": 1_i64,
- "12:varint": 1_i64,
- "13:string": "",
- "23:varint": 0_i64,
+ "2:string" => "videos",
+ "6:varint" => 2_i64,
+ "7:varint" => 1_i64,
+ "12:varint" => 1_i64,
+ "13:string" => "",
+ "23:varint" => 0_i64,
},
},
}
- if auto_generated
- seed = Time.unix(1525757349)
- until seed >= Time.utc
- seed += 1.month
- end
- timestamp = seed - (page - 1).months
+ if !v2
+ if auto_generated
+ seed = Time.unix(1525757349)
+ until seed >= Time.utc
+ seed += 1.month
+ end
+ timestamp = seed - (page - 1).months
- object["80226972:embedded"]["3:base64"].as(Hash)["4:varint"] = 0x36_i64
- object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = "#{timestamp.to_unix}"
+ object["80226972:embedded"]["3:base64"].as(Hash)["4:varint"] = 0x36_i64
+ object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = "#{timestamp.to_unix}"
+ else
+ object["80226972:embedded"]["3:base64"].as(Hash)["4:varint"] = 0_i64
+ object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = "#{page}"
+ end
else
object["80226972:embedded"]["3:base64"].as(Hash)["4:varint"] = 0_i64
- object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = "#{page}"
+
+ object["80226972:embedded"]["3:base64"].as(Hash)["61:string"] = Base64.urlsafe_encode(Protodec::Any.from_json(Protodec::Any.cast_json({
+ "1:string" => Base64.urlsafe_encode(Protodec::Any.from_json(Protodec::Any.cast_json({
+ "1:varint" => 30_i64 * (page - 1),
+ }))),
+ })))
end
case sort_by
@@ -466,6 +414,7 @@ def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = "
object["80226972:embedded"]["3:base64"].as(Hash)["3:varint"] = 0x01_i64
when "oldest"
object["80226972:embedded"]["3:base64"].as(Hash)["3:varint"] = 0x02_i64
+ else nil # Ignore
end
object["80226972:embedded"]["3:string"] = Base64.urlsafe_encode(Protodec::Any.from_json(Protodec::Any.cast_json(object["80226972:embedded"]["3:base64"])))
@@ -484,20 +433,20 @@ def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated
"80226972:embedded" => {
"2:string" => ucid,
"3:base64" => {
- "2:string" => "playlists",
- "6:varint": 2_i64,
- "7:varint": 1_i64,
- "12:varint": 1_i64,
- "13:string": "",
- "23:varint": 0_i64,
+ "2:string" => "playlists",
+ "6:varint" => 2_i64,
+ "7:varint" => 1_i64,
+ "12:varint" => 1_i64,
+ "13:string" => "",
+ "23:varint" => 0_i64,
},
},
}
- if !auto_generated
- cursor = Base64.urlsafe_encode(cursor, false)
+ if cursor
+ cursor = Base64.urlsafe_encode(cursor, false) if !auto_generated
+ object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = cursor
end
- object["80226972:embedded"]["3:base64"].as(Hash)["15:string"] = cursor
if auto_generated
object["80226972:embedded"]["3:base64"].as(Hash)["4:varint"] = 0x32_i64
@@ -510,6 +459,7 @@ def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated
object["80226972:embedded"]["3:base64"].as(Hash)["3:varint"] = 3_i64
when "last", "last_added"
object["80226972:embedded"]["3:base64"].as(Hash)["3:varint"] = 4_i64
+ else nil # Ignore
end
end
@@ -524,14 +474,22 @@ def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated
return "/browse_ajax?continuation=#{continuation}&gl=US&hl=en"
end
-def extract_channel_playlists_cursor(url, auto_generated)
- cursor = URI.parse(url).query_params
- .try { |i| URI.decode_www_form(i["continuation"]) }
+def extract_channel_playlists_cursor(cursor, auto_generated)
+ cursor = URI.decode_www_form(cursor)
.try { |i| Base64.decode(i) }
.try { |i| IO::Memory.new(i) }
.try { |i| Protodec::Any.parse(i) }
- .try { |i| i["80226972:0:embedded"]["3:1:base64"].as_h.find { |k, v| k.starts_with?("15:") } }
- .try &.[1].as_s || ""
+ .try { |i| i["80226972:0:embedded"]["3:1:base64"].as_h.find { |k, v| k.starts_with? "15:" } }
+ .try &.[1]
+
+ if cursor.try &.as_h?
+ cursor = cursor.try { |i| Protodec::Any.cast_json(i.as_h) }
+ .try { |i| Protodec::Any.from_json(i) }
+ .try { |i| Base64.urlsafe_encode(i) }
+ .try { |i| URI.encode_www_form(i) } || ""
+ else
+ cursor = cursor.try &.as_s || ""
+ end
if !auto_generated
cursor = URI.decode_www_form(cursor)
@@ -542,13 +500,13 @@ def extract_channel_playlists_cursor(url, auto_generated)
end
# TODO: Add "sort_by"
-def fetch_channel_community(ucid, continuation, locale, config, kemal_config, format, thin_mode)
+def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=US&hl=en")
- if response.status_code == 404
+ if response.status_code != 200
response = YT_POOL.client &.get("/user/#{ucid}/community?gl=US&hl=en")
end
- if response.status_code == 404
+ if response.status_code != 200
error_message = translate(locale, "This channel does not exist.")
raise error_message
end
@@ -569,16 +527,8 @@ def fetch_channel_community(ucid, continuation, locale, config, kemal_config, fo
headers = HTTP::Headers.new
headers["cookie"] = response.cookies.add_request_headers(headers)["cookie"]
- headers["content-type"] = "application/x-www-form-urlencoded"
-
- headers["x-client-data"] = "CIi2yQEIpbbJAQipncoBCNedygEIqKPKAQ=="
- headers["x-spf-previous"] = ""
- headers["x-spf-referer"] = ""
- headers["x-youtube-client-name"] = "1"
- headers["x-youtube-client-version"] = "2.20180719"
-
- session_token = response.body.match(/"XSRF_TOKEN":"(?<session_token>[A-Za-z0-9\_\-\=]+)"/).try &.["session_token"]? || ""
+ session_token = response.body.match(/"XSRF_TOKEN":"(?<session_token>[^"]+)"/).try &.["session_token"]? || ""
post_req = {
session_token: session_token,
}
@@ -616,17 +566,9 @@ def fetch_channel_community(ucid, continuation, locale, config, kemal_config, fo
post = post["backstagePostThreadRenderer"]?.try &.["post"]["backstagePostRenderer"]? ||
post["commentThreadRenderer"]?.try &.["comment"]["commentRenderer"]?
- if !post
- next
- end
-
- if !post["contentText"]?
- content_html = ""
- else
- content_html = post["contentText"]["simpleText"]?.try &.as_s.rchop('\ufeff').try { |block| HTML.escape(block) }.to_s ||
- content_to_comment_html(post["contentText"]["runs"].as_a).try &.to_s || ""
- end
+ next if !post
+ content_html = post["contentText"]?.try { |t| parse_content(t) } || ""
author = post["authorText"]?.try &.["simpleText"]? || ""
json.object do
@@ -695,7 +637,7 @@ def fetch_channel_community(ucid, continuation, locale, config, kemal_config, fo
json.field "title", attachment["title"]["simpleText"].as_s
json.field "videoId", video_id
json.field "videoThumbnails" do
- generate_thumbnails(json, video_id, config, kemal_config)
+ generate_thumbnails(json, video_id)
end
json.field "lengthSeconds", decode_length_seconds(attachment["lengthText"]["simpleText"].as_s)
@@ -797,7 +739,7 @@ def produce_channel_community_continuation(ucid, cursor)
object = {
"80226972:embedded" => {
"2:string" => ucid,
- "3:string" => cursor,
+ "3:string" => cursor || "",
},
}
@@ -833,153 +775,173 @@ def extract_channel_community_cursor(continuation)
cursor
end
+INITDATA_PREQUERY = "window[\"ytInitialData\"] = {"
+
def get_about_info(ucid, locale)
- about = YT_POOL.client &.get("/channel/#{ucid}/about?disable_polymer=1&gl=US&hl=en")
- if about.status_code == 404
- about = YT_POOL.client &.get("/user/#{ucid}/about?disable_polymer=1&gl=US&hl=en")
+ about = YT_POOL.client &.get("/channel/#{ucid}/about?gl=US&hl=en")
+ if about.status_code != 200
+ about = YT_POOL.client &.get("/user/#{ucid}/about?gl=US&hl=en")
end
if md = about.headers["location"]?.try &.match(/\/channel\/(?<ucid>UC[a-zA-Z0-9_-]{22})/)
raise ChannelRedirect.new(channel_id: md["ucid"])
end
- about = XML.parse_html(about.body)
-
- if about.xpath_node(%q(//div[contains(@class, "channel-empty-message")]))
+ if about.status_code != 200
error_message = translate(locale, "This channel does not exist.")
raise error_message
end
- if about.xpath_node(%q(//span[contains(@class,"qualified-channel-title-text")]/a)).try &.content.empty?
+ initdata_pre = about.body.index(INITDATA_PREQUERY)
+ initdata_post = initdata_pre.nil? ? nil : about.body.index("};", initdata_pre)
+ if initdata_post.nil?
+ about = XML.parse_html(about.body)
error_message = about.xpath_node(%q(//div[@class="yt-alert-content"])).try &.content.strip
error_message ||= translate(locale, "Could not get channel info.")
raise error_message
end
+ initdata_pre = initdata_pre.not_nil! + INITDATA_PREQUERY.size - 1
- author = about.xpath_node(%q(//span[contains(@class,"qualified-channel-title-text")]/a)).not_nil!.content
- author_url = about.xpath_node(%q(//span[contains(@class,"qualified-channel-title-text")]/a)).not_nil!["href"]
- author_thumbnail = about.xpath_node(%q(//img[@class="channel-header-profile-image"])).not_nil!["src"]
+ initdata = JSON.parse(about.body[initdata_pre, initdata_post - initdata_pre + 1])
+ about = XML.parse_html(about.body)
+
+ if about.xpath_node(%q(//div[contains(@class, "channel-empty-message")]))
+ error_message = translate(locale, "This channel does not exist.")
+ raise error_message
+ end
+
+ author = about.xpath_node(%q(//meta[@name="title"])).not_nil!["content"]
+ author_url = about.xpath_node(%q(//link[@rel="canonical"])).not_nil!["href"]
+ author_thumbnail = about.xpath_node(%q(//link[@rel="image_src"])).not_nil!["href"]
ucid = about.xpath_node(%q(//meta[@itemprop="channelId"])).not_nil!["content"]
- banner = about.xpath_node(%q(//div[@id="gh-banner"]/style)).not_nil!.content
- banner = "https:" + banner.match(/background-image: url\((?<url>[^)]+)\)/).not_nil!["url"]
+ # Raises a KeyError on failure.
+ banners = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["banner"]?.try &.["thumbnails"]?
+ banner = banners.try &.[-1]?.try &.["url"].as_s?
- if banner.includes? "channels/c4/default_banner"
- banner = nil
- end
+ # if banner.includes? "channels/c4/default_banner"
+ # banner = nil
+ # end
- description_html = about.xpath_node(%q(//div[contains(@class,"about-description")])).try &.to_s ||
- %(<div class="about-description branded-page-box-padding"><pre></pre></div>)
+ description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || ""
+ description_html = HTML.escape(description).gsub("\n", "<br>")
paid = about.xpath_node(%q(//meta[@itemprop="paid"])).not_nil!["content"] == "True"
is_family_friendly = about.xpath_node(%q(//meta[@itemprop="isFamilyFriendly"])).not_nil!["content"] == "True"
allowed_regions = about.xpath_node(%q(//meta[@itemprop="regionsAllowed"])).not_nil!["content"].split(",")
- related_channels = about.xpath_nodes(%q(//div[contains(@class, "branded-page-related-channels")]/ul/li))
- related_channels = related_channels.map do |node|
- related_id = node["data-external-id"]?
- related_id ||= ""
+ related_channels = initdata["contents"]["twoColumnBrowseResultsRenderer"]
+ .["secondaryContents"]?.try &.["browseSecondaryContentsRenderer"]["contents"][0]?
+ .try &.["verticalChannelSectionRenderer"]?.try &.["items"]?.try &.as_a.map do |node|
+ renderer = node["miniChannelRenderer"]?
+ related_id = renderer.try &.["channelId"]?.try &.as_s?
+ related_id ||= ""
- anchor = node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
- related_title = anchor.try &.["title"]
- related_title ||= ""
+ related_title = renderer.try &.["title"]?.try &.["simpleText"]?.try &.as_s?
+ related_title ||= ""
- related_author_url = anchor.try &.["href"]
- related_author_url ||= ""
-
- related_author_thumbnail = node.xpath_node(%q(.//img)).try &.["data-thumb"]
- related_author_thumbnail ||= ""
-
- AboutRelatedChannel.new(
- ucid: related_id,
- author: related_title,
- author_url: related_author_url,
- author_thumbnail: related_author_thumbnail,
- )
- end
+ related_author_url = renderer.try &.["navigationEndpoint"]?.try &.["commandMetadata"]?.try &.["webCommandMetadata"]?
+ .try &.["url"]?.try &.as_s?
+ related_author_url ||= ""
- joined = about.xpath_node(%q(//span[contains(., "Joined")]))
- .try &.content.try { |text| Time.parse(text, "Joined %b %-d, %Y", Time::Location.local) } || Time.unix(0)
+ related_author_thumbnails = renderer.try &.["thumbnail"]?.try &.["thumbnails"]?.try &.as_a?
+ related_author_thumbnails ||= [] of JSON::Any
- total_views = about.xpath_node(%q(//span[contains(., "views")]/b))
- .try &.content.try &.gsub(/\D/, "").to_i64? || 0_i64
+ related_author_thumbnail = ""
+ if related_author_thumbnails.size > 0
+ related_author_thumbnail = related_author_thumbnails[-1]["url"]?.try &.as_s?
+ related_author_thumbnail ||= ""
+ end
- sub_count = about.xpath_node(%q(.//span[contains(@class, "subscriber-count")]))
- .try &.["title"].try { |text| short_text_to_number(text) } || 0
+ AboutRelatedChannel.new({
+ ucid: related_id,
+ author: related_title,
+ author_url: related_author_url,
+ author_thumbnail: related_author_thumbnail,
+ })
+ end
+ related_channels ||= [] of AboutRelatedChannel
- # Auto-generated channels
- # https://support.google.com/youtube/answer/2579942
+ total_views = 0_i64
+ joined = Time.unix(0)
+ tabs = [] of String
auto_generated = false
- if about.xpath_node(%q(//ul[@class="about-custom-links"]/li/a[@title="Auto-generated by YouTube"])) ||
- about.xpath_node(%q(//span[@class="qualified-channel-title-badge"]/span[@title="Auto-generated by YouTube"]))
- auto_generated = true
- end
- tabs = about.xpath_nodes(%q(//ul[@id="channel-navigation-menu"]/li/a/span)).map { |node| node.content.downcase }
-
- AboutChannel.new(
- ucid: ucid,
- author: author,
- auto_generated: auto_generated,
- author_url: author_url,
- author_thumbnail: author_thumbnail,
- banner: banner,
- description_html: description_html,
- paid: paid,
- total_views: total_views,
- sub_count: sub_count,
- joined: joined,
+ tabs_json = initdata["contents"]["twoColumnBrowseResultsRenderer"]["tabs"]?.try &.as_a?
+ if !tabs_json.nil?
+ # Retrieve information from the tabs array. The index we are looking for varies between channels.
+ tabs_json.each do |node|
+ # Try to find the about section which is located in only one of the tabs.
+ channel_about_meta = node["tabRenderer"]?.try &.["content"]?.try &.["sectionListRenderer"]?
+ .try &.["contents"]?.try &.[0]?.try &.["itemSectionRenderer"]?.try &.["contents"]?
+ .try &.[0]?.try &.["channelAboutFullMetadataRenderer"]?
+
+ if !channel_about_meta.nil?
+ total_views = channel_about_meta["viewCountText"]?.try &.["simpleText"]?.try &.as_s.gsub(/\D/, "").to_i64? || 0_i64
+
+ # The joined text is split to several sub strings. The reduce joins those strings before parsing the date.
+ joined = channel_about_meta["joinedDateText"]?.try &.["runs"]?.try &.as_a.reduce("") { |acc, node| acc + node["text"].as_s }
+ .try { |text| Time.parse(text, "Joined %b %-d, %Y", Time::Location.local) } || Time.unix(0)
+
+ # Auto-generated channels
+ # https://support.google.com/youtube/answer/2579942
+ # For auto-generated channels, channel_about_meta only has ["description"]["simpleText"] and ["primaryLinks"][0]["title"]["simpleText"]
+ if (channel_about_meta["primaryLinks"]?.try &.size || 0) == 1 && (channel_about_meta["primaryLinks"][0]?) &&
+ (channel_about_meta["primaryLinks"][0]["title"]?.try &.["simpleText"]?.try &.as_s? || "") == "Auto-generated by YouTube"
+ auto_generated = true
+ end
+ end
+ end
+ tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map { |node| node["tabRenderer"]["title"].as_s.downcase }
+ end
+
+ sub_count = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s?
+ .try { |text| short_text_to_number(text.split(" ")[0]) } || 0
+
+ AboutChannel.new({
+ ucid: ucid,
+ author: author,
+ auto_generated: auto_generated,
+ author_url: author_url,
+ author_thumbnail: author_thumbnail,
+ banner: banner,
+ description_html: description_html,
+ paid: paid,
+ total_views: total_views,
+ sub_count: sub_count,
+ joined: joined,
is_family_friendly: is_family_friendly,
- allowed_regions: allowed_regions,
- related_channels: related_channels,
- tabs: tabs
- )
+ allowed_regions: allowed_regions,
+ related_channels: related_channels,
+ tabs: tabs,
+ })
+end
+
+def get_channel_videos_response(ucid, page = 1, auto_generated = nil, sort_by = "newest")
+ url = produce_channel_videos_url(ucid, page, auto_generated: auto_generated, sort_by: sort_by, v2: true)
+ return YT_POOL.client &.get(url)
end
def get_60_videos(ucid, author, page, auto_generated, sort_by = "newest")
- count = 0
videos = [] of SearchVideo
2.times do |i|
- url = produce_channel_videos_url(ucid, page * 2 + (i - 1), auto_generated: auto_generated, sort_by: sort_by)
- response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
-
- if json["content_html"]? && !json["content_html"].as_s.empty?
- document = XML.parse_html(json["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
-
- if !json["load_more_widget_html"]?.try &.as_s.empty?
- count += 30
- end
-
- if auto_generated
- videos += extract_videos(nodeset)
- else
- videos += extract_videos(nodeset, ucid, author)
- end
- else
- break
- end
+ response = get_channel_videos_response(ucid, page * 2 + (i - 1), auto_generated: auto_generated, sort_by: sort_by)
+ initial_data = JSON.parse(response.body).as_a.find &.["response"]?
+ break if !initial_data
+ videos.concat extract_videos(initial_data.as_h, author, ucid)
end
- return videos, count
+ return videos.size, videos
end
def get_latest_videos(ucid)
- videos = [] of SearchVideo
-
- url = produce_channel_videos_url(ucid, 0)
- response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
-
- if json["content_html"]? && !json["content_html"].as_s.empty?
- document = XML.parse_html(json["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
-
- videos = extract_videos(nodeset, ucid)
- end
+ response = get_channel_videos_response(ucid, 1)
+ initial_data = JSON.parse(response.body).as_a.find &.["response"]?
+ return [] of SearchVideo if !initial_data
+ author = initial_data["response"]?.try &.["metadata"]?.try &.["channelMetadataRenderer"]?.try &.["title"]?.try &.as_s
+ items = extract_videos(initial_data.as_h, author, ucid)
- return videos
+ return items
end
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr
index 2d7bc1cf..407cef78 100644
--- a/src/invidious/comments.cr
+++ b/src/invidious/comments.cr
@@ -1,11 +1,23 @@
class RedditThing
- JSON.mapping({
- kind: String,
- data: RedditComment | RedditLink | RedditMore | RedditListing,
- })
+ include JSON::Serializable
+
+ property kind : String
+ property data : RedditComment | RedditLink | RedditMore | RedditListing
end
class RedditComment
+ include JSON::Serializable
+
+ property author : String
+ property body_html : String
+ property replies : RedditThing | String
+ property score : Int32
+ property depth : Int32
+ property permalink : String
+
+ @[JSON::Field(converter: RedditComment::TimeConverter)]
+ property created_utc : Time
+
module TimeConverter
def self.from_json(value : JSON::PullParser) : Time
Time.unix(value.read_float.to_i)
@@ -15,51 +27,38 @@ class RedditComment
json.number(value.to_unix)
end
end
-
- JSON.mapping({
- author: String,
- body_html: String,
- replies: RedditThing | String,
- score: Int32,
- depth: Int32,
- permalink: String,
- created_utc: {
- type: Time,
- converter: RedditComment::TimeConverter,
- },
- })
end
struct RedditLink
- JSON.mapping({
- author: String,
- score: Int32,
- subreddit: String,
- num_comments: Int32,
- id: String,
- permalink: String,
- title: String,
- })
+ include JSON::Serializable
+
+ property author : String
+ property score : Int32
+ property subreddit : String
+ property num_comments : Int32
+ property id : String
+ property permalink : String
+ property title : String
end
struct RedditMore
- JSON.mapping({
- children: Array(String),
- count: Int32,
- depth: Int32,
- })
+ include JSON::Serializable
+
+ property children : Array(String)
+ property count : Int32
+ property depth : Int32
end
class RedditListing
- JSON.mapping({
- children: Array(RedditThing),
- modhash: String,
- })
+ include JSON::Serializable
+
+ property children : Array(RedditThing)
+ property modhash : String
end
def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, sort_by = "top")
video = get_video(id, db, region: region)
- session_token = video.info["session_token"]?
+ session_token = video.session_token
case cursor
when nil, ""
@@ -85,17 +84,9 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so
session_token: session_token,
}
- headers = HTTP::Headers.new
-
- headers["content-type"] = "application/x-www-form-urlencoded"
- headers["cookie"] = video.info["cookie"]
-
- headers["x-client-data"] = "CIi2yQEIpbbJAQipncoBCNedygEIqKPKAQ=="
- headers["x-spf-previous"] = "https://www.youtube.com/watch?v=#{id}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999"
- headers["x-spf-referer"] = "https://www.youtube.com/watch?v=#{id}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999"
-
- headers["x-youtube-client-name"] = "1"
- headers["x-youtube-client-version"] = "2.20180719"
+ headers = HTTP::Headers{
+ "cookie" => video.cookie,
+ }
response = YT_POOL.client(region, &.post("/comment_service_ajax?action_get_comments=1&hl=en&gl=US", headers, form: post_req))
response = JSON.parse(response.body)
@@ -150,8 +141,7 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so
node_comment = node["commentRenderer"]
end
- content_html = node_comment["contentText"]["simpleText"]?.try &.as_s.rchop('\ufeff').try { |block| HTML.escape(block) }.to_s ||
- content_to_comment_html(node_comment["contentText"]["runs"].as_a).try &.to_s || ""
+ content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || ""
author = node_comment["authorText"]?.try &.["simpleText"]? || ""
json.field "author", author
@@ -294,7 +284,7 @@ def template_youtube_comments(comments, locale, thin_mode)
<div class="pure-u-23-24">
<p>
<a href="javascript:void(0)" data-continuation="#{child["replies"]["continuation"]}"
- onclick="get_youtube_replies(this)">#{translate(locale, "View `x` replies", number_with_separator(child["replies"]["replyCount"]))}</a>
+ data-onclick="get_youtube_replies">#{translate(locale, "View `x` replies", number_with_separator(child["replies"]["replyCount"]))}</a>
</p>
</div>
</div>
@@ -347,7 +337,7 @@ def template_youtube_comments(comments, locale, thin_mode)
END_HTML
else
html << <<-END_HTML
- <iframe id='ivplayer' type='text/html' style='position:absolute;width:100%;height:100%;left:0;top:0' src='/embed/#{attachment["videoId"]?}?autoplay=0' frameborder='0'></iframe>
+ <iframe id='ivplayer' style='position:absolute;width:100%;height:100%;left:0;top:0' src='/embed/#{attachment["videoId"]?}?autoplay=0' style='border:none;'></iframe>
END_HTML
end
@@ -356,6 +346,7 @@ def template_youtube_comments(comments, locale, thin_mode)
</div>
</div>
END_HTML
+ else nil # Ignore
end
end
@@ -413,7 +404,7 @@ def template_youtube_comments(comments, locale, thin_mode)
<div class="pure-u-1">
<p>
<a href="javascript:void(0)" data-continuation="#{comments["continuation"]}"
- onclick="get_youtube_replies(this, true)">#{translate(locale, "Load more")}</a>
+ data-onclick="get_youtube_replies" data-load-more>#{translate(locale, "Load more")}</a>
</p>
</div>
</div>
@@ -451,7 +442,7 @@ def template_reddit_comments(root, locale)
html << <<-END_HTML
<p>
- <a href="javascript:void(0)" onclick="toggle_parent(this)">[ - ]</a>
+ <a href="javascript:void(0)" data-onclick="toggle_parent">[ - ]</a>
<b><a href="https://www.reddit.com/user/#{child.author}">#{child.author}</a></b>
#{translate(locale, "`x` points", number_with_separator(child.score))}
<span title="#{child.created_utc.to_s(translate(locale, "%a %B %-d %T %Y UTC"))}">#{translate(locale, "`x` ago", recode_date(child.created_utc, locale))}</span>
@@ -522,6 +513,11 @@ def fill_links(html, scheme, host)
return html.to_xml(options: XML::SaveOptions::NO_DECL)
end
+def parse_content(content : JSON::Any) : String
+ content["simpleText"]?.try &.as_s.rchop('\ufeff').try { |b| HTML.escape(b) }.to_s ||
+ content["runs"]?.try &.as_a.try { |r| content_to_comment_html(r).try &.to_s } || ""
+end
+
def content_to_comment_html(content)
comment_html = content.map do |run|
text = HTML.escape(run["text"].as_s)
@@ -556,7 +552,7 @@ def content_to_comment_html(content)
video_id = watch_endpoint["videoId"].as_s
if length_seconds
- text = %(<a href="javascript:void(0)" onclick="player.currentTime(#{length_seconds})">#{text}</a>)
+ text = %(<a href="javascript:void(0)" data-onclick="jump_to_time" data-jump-time="#{length_seconds}">#{text}</a>)
else
text = %(<a href="/watch?v=#{video_id}">#{text}</a>)
end
@@ -609,6 +605,8 @@ def produce_comment_continuation(video_id, cursor = "", sort_by = "top")
object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
when "new", "newest"
object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 1_i64
+ else # top
+ object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
end
continuation = object.try { |i| Protodec::Any.cast_json(object) }
diff --git a/src/invidious/helpers/handlers.cr b/src/invidious/helpers/handlers.cr
index 456618cf..045b6701 100644
--- a/src/invidious/helpers/handlers.cr
+++ b/src/invidious/helpers/handlers.cr
@@ -61,7 +61,7 @@ class Kemal::ExceptionHandler
end
class FilteredCompressHandler < Kemal::Handler
- exclude ["/videoplayback", "/videoplayback/*", "/vi/*", "/ggpht/*", "/api/v1/auth/notifications"]
+ exclude ["/videoplayback", "/videoplayback/*", "/vi/*", "/sb/*", "/ggpht/*", "/api/v1/auth/notifications"]
exclude ["/api/v1/auth/notifications", "/data_control"], "POST"
def call(env)
@@ -74,10 +74,10 @@ class FilteredCompressHandler < Kemal::Handler
if request_headers.includes_word?("Accept-Encoding", "gzip")
env.response.headers["Content-Encoding"] = "gzip"
- env.response.output = Gzip::Writer.new(env.response.output, sync_close: true)
+ env.response.output = Compress::Gzip::Writer.new(env.response.output, sync_close: true)
elsif request_headers.includes_word?("Accept-Encoding", "deflate")
env.response.headers["Content-Encoding"] = "deflate"
- env.response.output = Flate::Writer.new(env.response.output, sync_close: true)
+ env.response.output = Compress::Deflate::Writer.new(env.response.output, sync_close: true)
end
call_next env
@@ -212,29 +212,3 @@ class DenyFrame < Kemal::Handler
call_next env
end
end
-
-# Temp fixes for https://github.com/crystal-lang/crystal/issues/7383
-class HTTP::UnknownLengthContent
- def read_byte
- ensure_send_continue
- if @io.is_a?(OpenSSL::SSL::Socket::Client)
- return if @io.as(OpenSSL::SSL::Socket::Client).@in_buffer_rem.empty?
- end
- @io.read_byte
- end
-end
-
-class HTTP::Client
- private def handle_response(response)
- if @socket.is_a?(OpenSSL::SSL::Socket::Client) && @host.ends_with?("googlevideo.com")
- close unless response.keep_alive? || @socket.as(OpenSSL::SSL::Socket::Client).@in_buffer_rem.empty?
-
- if @socket.as(OpenSSL::SSL::Socket::Client).@in_buffer_rem.empty?
- @socket = nil
- end
- else
- close unless response.keep_alive?
- end
- response
- end
-end
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 2341d3be..62c24f3e 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -1,217 +1,100 @@
require "./macros"
struct Nonce
- db_mapping({
- nonce: String,
- expire: Time,
- })
+ include DB::Serializable
+
+ property nonce : String
+ property expire : Time
end
struct SessionId
- db_mapping({
- id: String,
- email: String,
- issued: String,
- })
+ include DB::Serializable
+
+ property id : String
+ property email : String
+ property issued : String
end
struct Annotation
- db_mapping({
- id: String,
- annotations: String,
- })
+ include DB::Serializable
+
+ property id : String
+ property annotations : String
end
struct ConfigPreferences
- module StringToArray
- def self.to_json(value : Array(String), json : JSON::Builder)
- json.array do
- value.each do |element|
- json.string element
- end
- end
- end
-
- def self.from_json(value : JSON::PullParser) : Array(String)
- begin
- result = [] of String
- value.read_array do
- result << HTML.escape(value.read_string[0, 100])
- end
- rescue ex
- result = [HTML.escape(value.read_string[0, 100]), ""]
- end
-
- result
- end
-
- def self.to_yaml(value : Array(String), yaml : YAML::Nodes::Builder)
- yaml.sequence do
- value.each do |element|
- yaml.scalar element
- end
- end
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Array(String)
- begin
- unless node.is_a?(YAML::Nodes::Sequence)
- node.raise "Expected sequence, not #{node.class}"
- end
-
- result = [] of String
- node.nodes.each do |item|
- unless item.is_a?(YAML::Nodes::Scalar)
- node.raise "Expected scalar, not #{item.class}"
- end
-
- result << HTML.escape(item.value[0, 100])
- end
- rescue ex
- if node.is_a?(YAML::Nodes::Scalar)
- result = [HTML.escape(node.value[0, 100]), ""]
- else
- result = ["", ""]
- end
- end
-
- result
- end
- end
-
- module BoolToString
- def self.to_json(value : String, json : JSON::Builder)
- json.string value
- end
-
- def self.from_json(value : JSON::PullParser) : String
- begin
- result = value.read_string
-
- if result.empty?
- CONFIG.default_user_preferences.dark_mode
- else
- result
- end
- rescue ex
- if value.read_bool
- "dark"
- else
- "light"
- end
- end
- end
-
- def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
- yaml.scalar value
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
- unless node.is_a?(YAML::Nodes::Scalar)
- node.raise "Expected scalar, not #{node.class}"
- end
-
- case node.value
- when "true"
- "dark"
- when "false"
- "light"
- when ""
- CONFIG.default_user_preferences.dark_mode
- else
- node.value
- end
- end
+ include YAML::Serializable
+
+ property annotations : Bool = false
+ property annotations_subscribed : Bool = false
+ property autoplay : Bool = false
+ property captions : Array(String) = ["", "", ""]
+ property comments : Array(String) = ["youtube", ""]
+ property continue : Bool = false
+ property continue_autoplay : Bool = true
+ property dark_mode : String = ""
+ property latest_only : Bool = false
+ property listen : Bool = false
+ property local : Bool = false
+ property locale : String = "en-US"
+ property max_results : Int32 = 40
+ property notifications_only : Bool = false
+ property player_style : String = "invidious"
+ property quality : String = "hd720"
+ property default_home : String = "Popular"
+ property feed_menu : Array(String) = ["Popular", "Trending", "Subscriptions", "Playlists"]
+ property related_videos : Bool = true
+ property sort : String = "published"
+ property speed : Float32 = 1.0_f32
+ property thin_mode : Bool = false
+ property unseen_only : Bool = false
+ property video_loop : Bool = false
+ property volume : Int32 = 100
+
+ def to_tuple
+ {% begin %}
+ {
+ {{*@type.instance_vars.map { |var| "#{var.name}: #{var.name}".id }}}
+ }
+ {% end %}
end
-
- yaml_mapping({
- annotations: {type: Bool, default: false},
- annotations_subscribed: {type: Bool, default: false},
- autoplay: {type: Bool, default: false},
- captions: {type: Array(String), default: ["", "", ""], converter: StringToArray},
- comments: {type: Array(String), default: ["youtube", ""], converter: StringToArray},
- continue: {type: Bool, default: false},
- continue_autoplay: {type: Bool, default: true},
- dark_mode: {type: String, default: "", converter: BoolToString},
- latest_only: {type: Bool, default: false},
- listen: {type: Bool, default: false},
- local: {type: Bool, default: false},
- locale: {type: String, default: "en-US"},
- max_results: {type: Int32, default: 40},
- notifications_only: {type: Bool, default: false},
- player_style: {type: String, default: "invidious"},
- quality: {type: String, default: "hd720"},
- default_home: {type: String, default: "Popular"},
- feed_menu: {type: Array(String), default: ["Popular", "Trending", "Subscriptions", "Playlists"]},
- related_videos: {type: Bool, default: true},
- sort: {type: String, default: "published"},
- speed: {type: Float32, default: 1.0_f32},
- thin_mode: {type: Bool, default: false},
- unseen_only: {type: Bool, default: false},
- video_loop: {type: Bool, default: false},
- volume: {type: Int32, default: 100},
- })
end
struct Config
- module ConfigPreferencesConverter
- def self.to_yaml(value : Preferences, yaml : YAML::Nodes::Builder)
- value.to_yaml(yaml)
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Preferences
- Preferences.new(*ConfigPreferences.new(ctx, node).to_tuple)
- end
- end
-
- module FamilyConverter
- def self.to_yaml(value : Socket::Family, yaml : YAML::Nodes::Builder)
- case value
- when Socket::Family::UNSPEC
- yaml.scalar nil
- when Socket::Family::INET
- yaml.scalar "ipv4"
- when Socket::Family::INET6
- yaml.scalar "ipv6"
- end
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Socket::Family
- if node.is_a?(YAML::Nodes::Scalar)
- case node.value.downcase
- when "ipv4"
- Socket::Family::INET
- when "ipv6"
- Socket::Family::INET6
- else
- Socket::Family::UNSPEC
- end
- else
- node.raise "Expected scalar, not #{node.class}"
- end
- end
- end
-
- module StringToCookies
- def self.to_yaml(value : HTTP::Cookies, yaml : YAML::Nodes::Builder)
- (value.map { |c| "#{c.name}=#{c.value}" }).join("; ").to_yaml(yaml)
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : HTTP::Cookies
- unless node.is_a?(YAML::Nodes::Scalar)
- node.raise "Expected scalar, not #{node.class}"
- end
-
- cookies = HTTP::Cookies.new
- node.value.split(";").each do |cookie|
- next if cookie.strip.empty?
- name, value = cookie.split("=", 2)
- cookies << HTTP::Cookie.new(name.strip, value.strip)
- end
-
- cookies
- end
- end
+ include YAML::Serializable
+
+ property channel_threads : Int32 # Number of threads to use for crawling videos from channels (for updating subscriptions)
+ property feed_threads : Int32 # Number of threads to use for updating feeds
+ property db : DBConfig # Database configuration
+ property full_refresh : Bool # Used for crawling channels: threads should check all videos uploaded by a channel
+ property https_only : Bool? # Used to tell Invidious it is behind a proxy, so links to resources should be https://
+ property hmac_key : String? # HMAC signing key for CSRF tokens and verifying pubsub subscriptions
+ property domain : String? # Domain to be used for links to resources on the site where an absolute URL is required
+ property use_pubsub_feeds : Bool | Int32 = false # Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
+ property captcha_enabled : Bool = true
+ property login_enabled : Bool = true
+ property registration_enabled : Bool = true
+ property statistics_enabled : Bool = false
+ property admins : Array(String) = [] of String
+ property external_port : Int32? = nil
+ property default_user_preferences : ConfigPreferences = ConfigPreferences.from_yaml("")
+ property dmca_content : Array(String) = [] of String # For compliance with DMCA, disables download widget using list of video IDs
+ property check_tables : Bool = false # Check table integrity, automatically try to add any missing columns, create tables, etc.
+ property cache_annotations : Bool = false # Cache annotations requested from IA, will not cache empty annotations or annotations that only contain cards
+ property banner : String? = nil # Optional banner to be displayed along top of page for announcements, etc.
+ property hsts : Bool? = true # Enables 'Strict-Transport-Security'. Ensure that `domain` and all subdomains are served securely
+ property disable_proxy : Bool? | Array(String)? = false # Disable proxying server-wide: options: 'dash', 'livestreams', 'downloads', 'local'
+
+ @[YAML::Field(converter: Preferences::FamilyConverter)]
+ property force_resolve : Socket::Family = Socket::Family::UNSPEC # Connect to YouTube over 'ipv6', 'ipv4'. Will sometimes resolve fix issues with rate-limiting (see https://github.com/ytdl-org/youtube-dl/issues/21729)
+ property port : Int32 = 3000 # Port to listen for connections (overrided by command line argument)
+ property host_binding : String = "0.0.0.0" # Host to bind (overrided by command line argument)
+ property pool_size : Int32 = 100 # Pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool of `pool_size`)
+ property admin_email : String = "omarroth@protonmail.com" # Email for bug reports
+
+ @[YAML::Field(converter: Preferences::StringToCookies)]
+ property cookies : HTTP::Cookies = HTTP::Cookies.new # Saved cookies in "name1=value1; name2=value2..." format
+ property captcha_key : String? = nil # Key for Anti-Captcha
def disabled?(option)
case disabled = CONFIG.disable_proxy
@@ -223,77 +106,20 @@ struct Config
else
return false
end
+ else
+ return false
end
end
-
- YAML.mapping({
- channel_threads: Int32, # Number of threads to use for crawling videos from channels (for updating subscriptions)
- feed_threads: Int32, # Number of threads to use for updating feeds
- db: DBConfig, # Database configuration
- full_refresh: Bool, # Used for crawling channels: threads should check all videos uploaded by a channel
- https_only: Bool?, # Used to tell Invidious it is behind a proxy, so links to resources should be https://
- hmac_key: String?, # HMAC signing key for CSRF tokens and verifying pubsub subscriptions
- domain: String?, # Domain to be used for links to resources on the site where an absolute URL is required
- use_pubsub_feeds: {type: Bool | Int32, default: false}, # Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
- top_enabled: {type: Bool, default: true},
- captcha_enabled: {type: Bool, default: true},
- login_enabled: {type: Bool, default: true},
- registration_enabled: {type: Bool, default: true},
- statistics_enabled: {type: Bool, default: false},
- admins: {type: Array(String), default: [] of String},
- external_port: {type: Int32?, default: nil},
- default_user_preferences: {type: Preferences,
- default: Preferences.new(*ConfigPreferences.from_yaml("").to_tuple),
- converter: ConfigPreferencesConverter,
- },
- dmca_content: {type: Array(String), default: [] of String}, # For compliance with DMCA, disables download widget using list of video IDs
- check_tables: {type: Bool, default: false}, # Check table integrity, automatically try to add any missing columns, create tables, etc.
- cache_annotations: {type: Bool, default: false}, # Cache annotations requested from IA, will not cache empty annotations or annotations that only contain cards
- banner: {type: String?, default: nil}, # Optional banner to be displayed along top of page for announcements, etc.
- hsts: {type: Bool?, default: true}, # Enables 'Strict-Transport-Security'. Ensure that `domain` and all subdomains are served securely
- disable_proxy: {type: Bool? | Array(String)?, default: false}, # Disable proxying server-wide: options: 'dash', 'livestreams', 'downloads', 'local'
- force_resolve: {type: Socket::Family, default: Socket::Family::UNSPEC, converter: FamilyConverter}, # Connect to YouTube over 'ipv6', 'ipv4'. Will sometimes resolve fix issues with rate-limiting (see https://github.com/ytdl-org/youtube-dl/issues/21729)
- port: {type: Int32, default: 3000}, # Port to listen for connections (overrided by command line argument)
- host_binding: {type: String, default: "0.0.0.0"}, # Host to bind (overrided by command line argument)
- pool_size: {type: Int32, default: 100}, # Pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool of `pool_size`)
- admin_email: {type: String, default: "omarroth@protonmail.com"}, # Email for bug reports
- cookies: {type: HTTP::Cookies, default: HTTP::Cookies.new, converter: StringToCookies}, # Saved cookies in "name1=value1; name2=value2..." format
- captcha_key: {type: String?, default: nil}, # Key for Anti-Captcha
- })
end
struct DBConfig
- yaml_mapping({
- user: String,
- password: String,
- host: String,
- port: Int32,
- dbname: String,
- })
-end
+ include YAML::Serializable
-def rank_videos(db, n)
- top = [] of {Float64, String}
-
- db.query("SELECT id, wilson_score, published FROM videos WHERE views > 5000 ORDER BY published DESC LIMIT 1000") do |rs|
- rs.each do
- id = rs.read(String)
- wilson_score = rs.read(Float64)
- published = rs.read(Time)
-
- # Exponential decay, older videos tend to rank lower
- temperature = wilson_score * Math.exp(-0.000005*((Time.utc - published).total_minutes))
- top << {temperature, id}
- end
- end
-
- top.sort!
-
- # Make hottest come first
- top.reverse!
- top = top.map { |a, b| b }
-
- return top[0..n - 1]
+ property user : String
+ property password : String
+ property host : String
+ property port : Int32
+ property dbname : String
end
def login_req(f_req)
@@ -334,293 +160,179 @@ def html_to_content(description_html : String)
return description
end
-def extract_videos(nodeset, ucid = nil, author_name = nil)
- videos = extract_items(nodeset, ucid, author_name)
- videos.select { |item| item.is_a?(SearchVideo) }.map { |video| video.as(SearchVideo) }
+def extract_videos(initial_data : Hash(String, JSON::Any), author_fallback : String? = nil, author_id_fallback : String? = nil)
+ extract_items(initial_data, author_fallback, author_id_fallback).select(&.is_a?(SearchVideo)).map(&.as(SearchVideo))
end
-def extract_items(nodeset, ucid = nil, author_name = nil)
- # TODO: Make this a 'common', so it makes more sense to be used here
- items = [] of SearchItem
-
- nodeset.each do |node|
- anchor = node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
- if !anchor
- next
- end
- title = anchor.content.strip
- id = anchor["href"]
-
- if anchor["href"].starts_with? "https://www.googleadservices.com"
- next
- end
-
- author_id = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-byline")]/a)).try &.["href"].split("/")[-1] || ucid || ""
- author = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-byline")]/a)).try &.content.strip || author_name || ""
- description_html = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-description")])).try &.to_s || ""
-
- tile = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-tile")]))
- if !tile
- next
- end
-
- case tile["class"]
- when .includes? "yt-lockup-playlist"
- plid = HTTP::Params.parse(URI.parse(id).query.not_nil!)["list"]
-
- anchor = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-meta")]/a))
-
- if !anchor
- anchor = node.xpath_node(%q(.//ul[@class="yt-lockup-meta-info"]/li/a))
- end
-
- video_count = node.xpath_node(%q(.//span[@class="formatted-video-count-label"]/b)) ||
- node.xpath_node(%q(.//span[@class="formatted-video-count-label"]))
- if video_count
- video_count = video_count.content
-
- if video_count == "50+"
- author = "YouTube"
- author_id = "UC-9-kyTW8ZkZNDHQJ6FgpwQ"
- end
-
- video_count = video_count.gsub(/\D/, "").to_i?
- end
- video_count ||= 0
-
- videos = [] of SearchPlaylistVideo
- node.xpath_nodes(%q(.//*[contains(@class, "yt-lockup-playlist-items")]/li)).each do |video|
- anchor = video.xpath_node(%q(.//a))
- if anchor
- video_title = anchor.content.strip
- id = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)["v"]
- end
- video_title ||= ""
- id ||= ""
-
- anchor = video.xpath_node(%q(.//span/span))
- if anchor
- length_seconds = decode_length_seconds(anchor.content)
- end
- length_seconds ||= 0
-
- videos << SearchPlaylistVideo.new(
- video_title,
- id,
- length_seconds
- )
- end
-
- playlist_thumbnail = node.xpath_node(%q(.//span/img)).try &.["data-thumb"]?
- playlist_thumbnail ||= node.xpath_node(%q(.//span/img)).try &.["src"]
-
- items << SearchPlaylist.new(
- title: title,
- id: plid,
- author: author,
- ucid: author_id,
- video_count: video_count,
- videos: videos,
- thumbnail: playlist_thumbnail
- )
- when .includes? "yt-lockup-channel"
- author = title.strip
-
- ucid = node.xpath_node(%q(.//button[contains(@class, "yt-uix-subscription-button")])).try &.["data-channel-external-id"]?
- ucid ||= id.split("/")[-1]
-
- author_thumbnail = node.xpath_node(%q(.//div/span/img)).try &.["data-thumb"]?
- author_thumbnail ||= node.xpath_node(%q(.//div/span/img)).try &.["src"]
- if author_thumbnail
- author_thumbnail = URI.parse(author_thumbnail)
- author_thumbnail.scheme = "https"
- author_thumbnail = author_thumbnail.to_s
- end
-
- author_thumbnail ||= ""
-
- subscriber_count = node.xpath_node(%q(.//span[contains(@class, "subscriber-count")]))
- .try &.["title"].try { |text| short_text_to_number(text) } || 0
-
- video_count = node.xpath_node(%q(.//ul[@class="yt-lockup-meta-info"]/li)).try &.content.split(" ")[0].gsub(/\D/, "").to_i?
-
- items << SearchChannel.new(
- author: author,
- ucid: ucid,
- author_thumbnail: author_thumbnail,
- subscriber_count: subscriber_count,
- video_count: video_count || 0,
- description_html: description_html,
- auto_generated: video_count ? false : true,
- )
- else
- id = id.lchop("/watch?v=")
-
- metadata = node.xpath_node(%q(.//div[contains(@class,"yt-lockup-meta")]/ul))
-
- published = metadata.try &.xpath_node(%q(.//li[contains(text(), " ago")])).try { |node| decode_date(node.content.sub(/^[a-zA-Z]+ /, "")) }
- published ||= metadata.try &.xpath_node(%q(.//span[@data-timestamp])).try { |node| Time.unix(node["data-timestamp"].to_i64) }
- published ||= Time.utc
-
- view_count = metadata.try &.xpath_node(%q(.//li[contains(text(), " views")])).try &.content.gsub(/\D/, "").to_i64?
- view_count ||= 0_i64
-
- length_seconds = node.xpath_node(%q(.//span[@class="video-time"])).try { |node| decode_length_seconds(node.content) }
- length_seconds ||= -1
-
- live_now = node.xpath_node(%q(.//span[contains(@class, "yt-badge-live")])) ? true : false
- premium = node.xpath_node(%q(.//span[text()="Premium"])) ? true : false
-
- if !premium || node.xpath_node(%q(.//span[contains(text(), "Free episode")]))
- paid = false
- else
+def extract_item(item : JSON::Any, author_fallback : String? = nil, author_id_fallback : String? = nil)
+ if i = (item["videoRenderer"]? || item["gridVideoRenderer"]?)
+ video_id = i["videoId"].as_s
+ title = i["title"].try { |t| t["simpleText"]?.try &.as_s || t["runs"]?.try &.as_a.map(&.["text"].as_s).join("") } || ""
+
+ author_info = i["ownerText"]?.try &.["runs"].as_a[0]?
+ author = author_info.try &.["text"].as_s || author_fallback || ""
+ author_id = author_info.try &.["navigationEndpoint"]?.try &.["browseEndpoint"]["browseId"].as_s || author_id_fallback || ""
+
+ published = i["publishedTimeText"]?.try &.["simpleText"]?.try { |t| decode_date(t.as_s) } || Time.local
+ view_count = i["viewCountText"]?.try &.["simpleText"]?.try &.as_s.gsub(/\D+/, "").to_i64? || 0_i64
+ description_html = i["descriptionSnippet"]?.try { |t| parse_content(t) } || ""
+ length_seconds = i["lengthText"]?.try &.["simpleText"]?.try &.as_s.try { |t| decode_length_seconds(t) } ||
+ i["thumbnailOverlays"]?.try &.as_a.find(&.["thumbnailOverlayTimeStatusRenderer"]?).try &.["thumbnailOverlayTimeStatusRenderer"]?
+ .try &.["text"]?.try &.["simpleText"]?.try &.as_s.try { |t| decode_length_seconds(t) } || 0
+
+ live_now = false
+ paid = false
+ premium = false
+
+ premiere_timestamp = i["upcomingEventData"]?.try &.["startTime"]?.try { |t| Time.unix(t.as_s.to_i64) }
+
+ i["badges"]?.try &.as_a.each do |badge|
+ b = badge["metadataBadgeRenderer"]
+ case b["label"].as_s
+ when "LIVE NOW"
+ live_now = true
+ when "New", "4K", "CC"
+ # TODO
+ when "Premium"
paid = true
- end
- premiere_timestamp = node.xpath_node(%q(.//ul[@class="yt-lockup-meta-info"]/li/span[@class="localized-date"])).try &.["data-timestamp"]?.try &.to_i64
- if premiere_timestamp
- premiere_timestamp = Time.unix(premiere_timestamp)
+ # TODO: Potentially available as i["topStandaloneBadge"]["metadataBadgeRenderer"]
+ premium = true
+ else nil # Ignore
end
-
- items << SearchVideo.new(
- title: title,
- id: id,
- author: author,
- ucid: author_id,
- published: published,
- views: view_count,
- description_html: description_html,
- length_seconds: length_seconds,
- live_now: live_now,
- paid: paid,
- premium: premium,
- premiere_timestamp: premiere_timestamp
- )
end
- end
- return items
+ SearchVideo.new({
+ title: title,
+ id: video_id,
+ author: author,
+ ucid: author_id,
+ published: published,
+ views: view_count,
+ description_html: description_html,
+ length_seconds: length_seconds,
+ live_now: live_now,
+ paid: paid,
+ premium: premium,
+ premiere_timestamp: premiere_timestamp,
+ })
+ elsif i = item["channelRenderer"]?
+ author = i["title"]["simpleText"]?.try &.as_s || author_fallback || ""
+ author_id = i["channelId"]?.try &.as_s || author_id_fallback || ""
+
+ author_thumbnail = i["thumbnail"]["thumbnails"]?.try &.as_a[0]?.try { |u| "https:#{u["url"]}" } || ""
+ subscriber_count = i["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s.try { |s| short_text_to_number(s.split(" ")[0]) } || 0
+
+ auto_generated = false
+ auto_generated = true if !i["videoCountText"]?
+ video_count = i["videoCountText"]?.try &.["runs"].as_a[0]?.try &.["text"].as_s.gsub(/\D/, "").to_i || 0
+ description_html = i["descriptionSnippet"]?.try { |t| parse_content(t) } || ""
+
+ SearchChannel.new({
+ author: author,
+ ucid: author_id,
+ author_thumbnail: author_thumbnail,
+ subscriber_count: subscriber_count,
+ video_count: video_count,
+ description_html: description_html,
+ auto_generated: auto_generated,
+ })
+ elsif i = item["gridPlaylistRenderer"]?
+ title = i["title"]["runs"].as_a[0]?.try &.["text"].as_s || ""
+ plid = i["playlistId"]?.try &.as_s || ""
+
+ video_count = i["videoCountText"]["runs"].as_a[0]?.try &.["text"].as_s.gsub(/\D/, "").to_i || 0
+ playlist_thumbnail = i["thumbnail"]["thumbnails"][0]?.try &.["url"]?.try &.as_s || ""
+
+ SearchPlaylist.new({
+ title: title,
+ id: plid,
+ author: author_fallback || "",
+ ucid: author_id_fallback || "",
+ video_count: video_count,
+ videos: [] of SearchPlaylistVideo,
+ thumbnail: playlist_thumbnail,
+ })
+ elsif i = item["playlistRenderer"]?
+ title = i["title"]["simpleText"]?.try &.as_s || ""
+ plid = i["playlistId"]?.try &.as_s || ""
+
+ video_count = i["videoCount"]?.try &.as_s.to_i || 0
+ playlist_thumbnail = i["thumbnails"].as_a[0]?.try &.["thumbnails"]?.try &.as_a[0]?.try &.["url"].as_s || ""
+
+ author_info = i["shortBylineText"]?.try &.["runs"].as_a[0]?
+ author = author_info.try &.["text"].as_s || author_fallback || ""
+ author_id = author_info.try &.["navigationEndpoint"]?.try &.["browseEndpoint"]["browseId"].as_s || author_id_fallback || ""
+
+ videos = i["videos"]?.try &.as_a.map do |v|
+ v = v["childVideoRenderer"]
+ v_title = v["title"]["simpleText"]?.try &.as_s || ""
+ v_id = v["videoId"]?.try &.as_s || ""
+ v_length_seconds = v["lengthText"]?.try &.["simpleText"]?.try { |t| decode_length_seconds(t.as_s) } || 0
+ SearchPlaylistVideo.new({
+ title: v_title,
+ id: v_id,
+ length_seconds: v_length_seconds,
+ })
+ end || [] of SearchPlaylistVideo
+
+ # TODO: i["publishedTimeText"]?
+
+ SearchPlaylist.new({
+ title: title,
+ id: plid,
+ author: author,
+ ucid: author_id,
+ video_count: video_count,
+ videos: videos,
+ thumbnail: playlist_thumbnail,
+ })
+ elsif i = item["radioRenderer"]? # Mix
+ # TODO
+ elsif i = item["showRenderer"]? # Show
+ # TODO
+ elsif i = item["shelfRenderer"]?
+ elsif i = item["horizontalCardListRenderer"]?
+ elsif i = item["searchPyvRenderer"]? # Ad
+ end
end
-def extract_shelf_items(nodeset, ucid = nil, author_name = nil)
- items = [] of SearchPlaylist
-
- nodeset.each do |shelf|
- shelf_anchor = shelf.xpath_node(%q(.//h2[contains(@class, "branded-page-module-title")]))
- next if !shelf_anchor
-
- title = shelf_anchor.xpath_node(%q(.//span[contains(@class, "branded-page-module-title-text")])).try &.content.strip
- title ||= ""
-
- id = shelf_anchor.xpath_node(%q(.//a)).try &.["href"]
- next if !id
-
- shelf_is_playlist = false
- videos = [] of SearchPlaylistVideo
-
- shelf.xpath_nodes(%q(.//ul[contains(@class, "yt-uix-shelfslider-list") or contains(@class, "expanded-shelf-content-list")]/li)).each do |child_node|
- type = child_node.xpath_node(%q(./div))
- if !type
- next
- end
-
- case type["class"]
- when .includes? "yt-lockup-video"
- shelf_is_playlist = true
-
- anchor = child_node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
- if anchor
- video_title = anchor.content.strip
- video_id = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)["v"]
- end
- video_title ||= ""
- video_id ||= ""
-
- anchor = child_node.xpath_node(%q(.//span[@class="video-time"]))
- if anchor
- length_seconds = decode_length_seconds(anchor.content)
- end
- length_seconds ||= 0
-
- videos << SearchPlaylistVideo.new(
- video_title,
- video_id,
- length_seconds
- )
- when .includes? "yt-lockup-playlist"
- anchor = child_node.xpath_node(%q(.//h3[contains(@class, "yt-lockup-title")]/a))
- if anchor
- playlist_title = anchor.content.strip
- params = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)
- plid = params["list"]
- end
- playlist_title ||= ""
- plid ||= ""
-
- playlist_thumbnail = child_node.xpath_node(%q(.//span/img)).try &.["data-thumb"]?
- playlist_thumbnail ||= child_node.xpath_node(%q(.//span/img)).try &.["src"]
-
- video_count = child_node.xpath_node(%q(.//span[@class="formatted-video-count-label"]/b)) ||
- child_node.xpath_node(%q(.//span[@class="formatted-video-count-label"]))
- if video_count
- video_count = video_count.content.gsub(/\D/, "").to_i?
- end
- video_count ||= 50
-
- videos = [] of SearchPlaylistVideo
- child_node.xpath_nodes(%q(.//*[contains(@class, "yt-lockup-playlist-items")]/li)).each do |video|
- anchor = video.xpath_node(%q(.//a))
- if anchor
- video_title = anchor.content.strip
- id = HTTP::Params.parse(URI.parse(anchor["href"]).query.not_nil!)["v"]
- end
- video_title ||= ""
- id ||= ""
-
- anchor = video.xpath_node(%q(.//span/span))
- if anchor
- length_seconds = decode_length_seconds(anchor.content)
- end
- length_seconds ||= 0
-
- videos << SearchPlaylistVideo.new(
- video_title,
- id,
- length_seconds
- )
- end
-
- items << SearchPlaylist.new(
- title: playlist_title,
- id: plid,
- author: author_name,
- ucid: ucid,
- video_count: video_count,
- videos: videos,
- thumbnail: playlist_thumbnail
- )
- end
- end
+def extract_items(initial_data : Hash(String, JSON::Any), author_fallback : String? = nil, author_id_fallback : String? = nil)
+ items = [] of SearchItem
- if shelf_is_playlist
- plid = HTTP::Params.parse(URI.parse(id).query.not_nil!)["list"]
-
- items << SearchPlaylist.new(
- title: title,
- id: plid,
- author: author_name,
- ucid: ucid,
- video_count: videos.size,
- videos: videos,
- thumbnail: "https://i.ytimg.com/vi/#{videos[0].id}/mqdefault.jpg"
- )
- end
+ channel_v2_response = initial_data
+ .try &.["response"]?
+ .try &.["continuationContents"]?
+ .try &.["gridContinuation"]?
+ .try &.["items"]?
+
+ if channel_v2_response
+ channel_v2_response.try &.as_a.each { |item|
+ extract_item(item, author_fallback, author_id_fallback)
+ .try { |t| items << t }
+ }
+ else
+ initial_data.try { |t| t["contents"]? || t["response"]? }
+ .try { |t| t["twoColumnBrowseResultsRenderer"]?.try &.["tabs"].as_a.select(&.["tabRenderer"]?.try &.["selected"].as_bool)[0]?.try &.["tabRenderer"]["content"] ||
+ t["twoColumnSearchResultsRenderer"]?.try &.["primaryContents"] ||
+ t["continuationContents"]? }
+ .try { |t| t["sectionListRenderer"]? || t["sectionListContinuation"]? }
+ .try &.["contents"].as_a
+ .each { |c| c.try &.["itemSectionRenderer"]?.try &.["contents"].as_a
+ .try { |t| t[0]?.try &.["shelfRenderer"]?.try &.["content"]["expandedShelfContentsRenderer"]?.try &.["items"].as_a ||
+ t[0]?.try &.["gridRenderer"]?.try &.["items"].as_a || t }
+ .each { |item|
+ extract_item(item, author_fallback, author_id_fallback)
+ .try { |t| items << t }
+ } }
end
- return items
+ items
end
def check_enum(db, logger, enum_name, struct_type = nil)
+ return # TODO
+
if !db.query_one?("SELECT true FROM pg_type WHERE typname = $1", enum_name, as: Bool)
logger.puts("CREATE TYPE #{enum_name}")
@@ -642,18 +354,14 @@ def check_table(db, logger, table_name, struct_type = nil)
end
end
- if !struct_type
- return
- end
+ return if !struct_type
- struct_array = struct_type.to_type_tuple
+ struct_array = struct_type.type_array
column_array = get_column_array(db, table_name)
column_types = File.read("config/sql/#{table_name}.sql").match(/CREATE TABLE public\.#{table_name}\n\((?<types>[\d\D]*?)\);/)
- .try &.["types"].split(",").map { |line| line.strip }
+ .try &.["types"].split(",").map { |line| line.strip }.reject &.starts_with?("CONSTRAINT")
- if !column_types
- return
- end
+ return if !column_types
struct_array.each_with_index do |name, i|
if name != column_array[i]?
@@ -704,6 +412,15 @@ def check_table(db, logger, table_name, struct_type = nil)
end
end
end
+
+ return if column_array.size <= struct_array.size
+
+ column_array.each do |column|
+ if !struct_array.includes? column
+ logger.puts("ALTER TABLE #{table_name} DROP COLUMN #{column} CASCADE")
+ db.exec("ALTER TABLE #{table_name} DROP COLUMN #{column} CASCADE")
+ end
+ end
end
class PG::ResultSet
@@ -732,9 +449,7 @@ def cache_annotation(db, id, annotations)
body = XML.parse(annotations)
nodeset = body.xpath_nodes(%q(/document/annotations/annotation))
- if nodeset == 0
- return
- end
+ return if nodeset == 0
has_legacy_annotations = false
nodeset.each do |node|
@@ -744,13 +459,10 @@ def cache_annotation(db, id, annotations)
end
end
- if has_legacy_annotations
- # TODO: Update on conflict?
- db.exec("INSERT INTO annotations VALUES ($1, $2) ON CONFLICT DO NOTHING", id, annotations)
- end
+ db.exec("INSERT INTO annotations VALUES ($1, $2) ON CONFLICT DO NOTHING", id, annotations) if has_legacy_annotations
end
-def create_notification_stream(env, config, kemal_config, decrypt_function, topics, connection_channel)
+def create_notification_stream(env, topics, connection_channel)
connection = Channel(PQ::Notification).new(8)
connection_channel.send({true, connection})
@@ -765,12 +477,12 @@ def create_notification_stream(env, config, kemal_config, decrypt_function, topi
loop do
time_span = [0, 0, 0, 0]
time_span[rand(4)] = rand(30) + 5
- published = Time.utc - Time::Span.new(time_span[0], time_span[1], time_span[2], time_span[3])
+ published = Time.utc - Time::Span.new(days: time_span[0], hours: time_span[1], minutes: time_span[2], seconds: time_span[3])
video_id = TEST_IDS[rand(TEST_IDS.size)]
video = get_video(video_id, PG_DB)
video.published = published
- response = JSON.parse(video.to_json(locale, config, kemal_config, decrypt_function))
+ response = JSON.parse(video.to_json(locale))
if fields_text = env.params.query["fields"]?
begin
@@ -804,7 +516,7 @@ def create_notification_stream(env, config, kemal_config, decrypt_function, topi
when .match(/UC[A-Za-z0-9_-]{22}/)
PG_DB.query_all("SELECT * FROM channel_videos WHERE ucid = $1 AND published > $2 ORDER BY published DESC LIMIT 15",
topic, Time.unix(since.not_nil!), as: ChannelVideo).each do |video|
- response = JSON.parse(video.to_json(locale, config, Kemal.config))
+ response = JSON.parse(video.to_json(locale))
if fields_text = env.params.query["fields"]?
begin
@@ -846,7 +558,7 @@ def create_notification_stream(env, config, kemal_config, decrypt_function, topi
video = get_video(video_id, PG_DB)
video.published = Time.unix(published)
- response = JSON.parse(video.to_json(locale, config, Kemal.config, decrypt_function))
+ response = JSON.parse(video.to_json(locale))
if fields_text = env.params.query["fields"]?
begin
@@ -884,26 +596,46 @@ def create_notification_stream(env, config, kemal_config, decrypt_function, topi
end
end
-def extract_initial_data(body)
- initial_data = body.match(/window\["ytInitialData"\] = (?<info>.*?);\n/).try &.["info"] || "{}"
+def extract_initial_data(body) : Hash(String, JSON::Any)
+ initial_data = body.match(/(window\["ytInitialData"\]|var\s+ytInitialData)\s*=\s*(?<info>.*?);+\s*\n/).try &.["info"] || "{}"
if initial_data.starts_with?("JSON.parse(\"")
- return JSON.parse(JSON.parse(%({"initial_data":"#{initial_data[12..-3]}"}))["initial_data"].as_s)
+ return JSON.parse(JSON.parse(%({"initial_data":"#{initial_data[12..-3]}"}))["initial_data"].as_s).as_h
else
- return JSON.parse(initial_data)
+ return JSON.parse(initial_data).as_h
end
end
def proxy_file(response, env)
if response.headers.includes_word?("Content-Encoding", "gzip")
- Gzip::Writer.open(env.response) do |deflate|
- response.pipe(deflate)
+ Compress::Gzip::Writer.open(env.response) do |deflate|
+ IO.copy response.body_io, deflate
end
elsif response.headers.includes_word?("Content-Encoding", "deflate")
- Flate::Writer.open(env.response) do |deflate|
- response.pipe(deflate)
+ Compress::Deflate::Writer.open(env.response) do |deflate|
+ IO.copy response.body_io, deflate
end
else
- response.pipe(env.response)
+ IO.copy response.body_io, env.response
+ end
+end
+
+# See https://github.com/kemalcr/kemal/pull/576
+class HTTP::Server::Response::Output
+ def close
+ return if closed?
+
+ unless response.wrote_headers?
+ response.content_length = @out_count
+ end
+
+ ensure_headers_written
+
+ super
+
+ if @chunked
+ @io << "0\r\n\r\n"
+ @io.flush
+ end
end
end
diff --git a/src/invidious/helpers/i18n.cr b/src/invidious/helpers/i18n.cr
index 4c9bb2d6..0faa2e32 100644
--- a/src/invidious/helpers/i18n.cr
+++ b/src/invidious/helpers/i18n.cr
@@ -24,6 +24,8 @@ def translate(locale : Hash(String, JSON::Any) | Nil, translation : String, text
if !locale[translation].as_s.empty?
translation = locale[translation].as_s
end
+ else
+ raise "Invalid translation #{translation}"
end
end
diff --git a/src/invidious/helpers/jobs.cr b/src/invidious/helpers/jobs.cr
deleted file mode 100644
index d304a27e..00000000
--- a/src/invidious/helpers/jobs.cr
+++ /dev/null
@@ -1,318 +0,0 @@
-def refresh_channels(db, logger, config)
- max_channel = Channel(Int32).new
-
- spawn do
- max_threads = max_channel.receive
- active_threads = 0
- active_channel = Channel(Bool).new
-
- loop do
- db.query("SELECT id FROM channels ORDER BY updated") do |rs|
- rs.each do
- id = rs.read(String)
-
- if active_threads >= max_threads
- if active_channel.receive
- active_threads -= 1
- end
- end
-
- active_threads += 1
- spawn do
- begin
- channel = fetch_channel(id, db, config.full_refresh)
-
- db.exec("UPDATE channels SET updated = $1, author = $2, deleted = false WHERE id = $3", Time.utc, channel.author, id)
- rescue ex
- if ex.message == "Deleted or invalid channel"
- db.exec("UPDATE channels SET updated = $1, deleted = true WHERE id = $2", Time.utc, id)
- end
- logger.puts("#{id} : #{ex.message}")
- end
-
- active_channel.send(true)
- end
- end
- end
-
- sleep 1.minute
- Fiber.yield
- end
- end
-
- max_channel.send(config.channel_threads)
-end
-
-def refresh_feeds(db, logger, config)
- max_channel = Channel(Int32).new
- spawn do
- max_threads = max_channel.receive
- active_threads = 0
- active_channel = Channel(Bool).new
-
- loop do
- db.query("SELECT email FROM users WHERE feed_needs_update = true OR feed_needs_update IS NULL") do |rs|
- rs.each do
- email = rs.read(String)
- view_name = "subscriptions_#{sha256(email)}"
-
- if active_threads >= max_threads
- if active_channel.receive
- active_threads -= 1
- end
- end
-
- active_threads += 1
- spawn do
- begin
- # Drop outdated views
- column_array = get_column_array(db, view_name)
- ChannelVideo.to_type_tuple.each_with_index do |name, i|
- if name != column_array[i]?
- logger.puts("DROP MATERIALIZED VIEW #{view_name}")
- db.exec("DROP MATERIALIZED VIEW #{view_name}")
- raise "view does not exist"
- end
- end
-
- if !db.query_one("SELECT pg_get_viewdef('#{view_name}')", as: String).includes? "WHERE ((cv.ucid = ANY (u.subscriptions))"
- logger.puts("Materialized view #{view_name} is out-of-date, recreating...")
- db.exec("DROP MATERIALIZED VIEW #{view_name}")
- end
-
- db.exec("REFRESH MATERIALIZED VIEW #{view_name}")
- db.exec("UPDATE users SET feed_needs_update = false WHERE email = $1", email)
- rescue ex
- # Rename old views
- begin
- legacy_view_name = "subscriptions_#{sha256(email)[0..7]}"
-
- db.exec("SELECT * FROM #{legacy_view_name} LIMIT 0")
- logger.puts("RENAME MATERIALIZED VIEW #{legacy_view_name}")
- db.exec("ALTER MATERIALIZED VIEW #{legacy_view_name} RENAME TO #{view_name}")
- rescue ex
- begin
- # While iterating through, we may have an email stored from a deleted account
- if db.query_one?("SELECT true FROM users WHERE email = $1", email, as: Bool)
- logger.puts("CREATE #{view_name}")
- db.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(email)}")
- db.exec("UPDATE users SET feed_needs_update = false WHERE email = $1", email)
- end
- rescue ex
- logger.puts("REFRESH #{email} : #{ex.message}")
- end
- end
- end
-
- active_channel.send(true)
- end
- end
- end
-
- sleep 5.seconds
- Fiber.yield
- end
- end
-
- max_channel.send(config.feed_threads)
-end
-
-def subscribe_to_feeds(db, logger, key, config)
- if config.use_pubsub_feeds
- case config.use_pubsub_feeds
- when Bool
- max_threads = config.use_pubsub_feeds.as(Bool).to_unsafe
- when Int32
- max_threads = config.use_pubsub_feeds.as(Int32)
- end
- max_channel = Channel(Int32).new
-
- client_pool = HTTPPool.new(PUBSUB_URL, capacity: max_threads, timeout: 0.05)
-
- spawn do
- max_threads = max_channel.receive
- active_threads = 0
- active_channel = Channel(Bool).new
-
- loop do
- db.query_all("SELECT id FROM channels WHERE CURRENT_TIMESTAMP - subscribed > interval '4 days' OR subscribed IS NULL") do |rs|
- rs.each do
- ucid = rs.read(String)
-
- if active_threads >= max_threads.as(Int32)
- if active_channel.receive
- active_threads -= 1
- end
- end
-
- active_threads += 1
-
- spawn do
- begin
- response = subscribe_pubsub(ucid, key, config, client_pool)
-
- if response.status_code >= 400
- logger.puts("#{ucid} : #{response.body}")
- end
- rescue ex
- logger.puts("#{ucid} : #{ex.message}")
- end
-
- active_channel.send(true)
- end
- end
- end
-
- sleep 1.minute
- Fiber.yield
- end
- end
-
- max_channel.send(max_threads.as(Int32))
- end
-end
-
-def pull_top_videos(config, db)
- loop do
- begin
- top = rank_videos(db, 40)
- rescue ex
- sleep 1.minute
- Fiber.yield
-
- next
- end
-
- if top.size == 0
- sleep 1.minute
- Fiber.yield
-
- next
- end
-
- videos = [] of Video
-
- top.each do |id|
- begin
- videos << get_video(id, db)
- rescue ex
- next
- end
- end
-
- yield videos
-
- sleep 1.minute
- Fiber.yield
- end
-end
-
-def pull_popular_videos(db)
- loop do
- videos = db.query_all("SELECT DISTINCT ON (ucid) * FROM channel_videos WHERE ucid IN \
- (SELECT channel FROM (SELECT UNNEST(subscriptions) AS channel FROM users) AS d \
- GROUP BY channel ORDER BY COUNT(channel) DESC LIMIT 40) \
- ORDER BY ucid, published DESC", as: ChannelVideo).sort_by { |video| video.published }.reverse
-
- yield videos
-
- sleep 1.minute
- Fiber.yield
- end
-end
-
-def update_decrypt_function
- loop do
- begin
- decrypt_function = fetch_decrypt_function
- yield decrypt_function
- rescue ex
- next
- ensure
- sleep 1.minute
- Fiber.yield
- end
- end
-end
-
-def bypass_captcha(captcha_key, logger)
- loop do
- begin
- response = YT_POOL.client &.get("/watch?v=CvFH_6DNRCY&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999")
- if response.body.includes?("To continue with your YouTube experience, please fill out the form below.")
- html = XML.parse_html(response.body)
- form = html.xpath_node(%(//form[@action="/das_captcha"])).not_nil!
- site_key = form.xpath_node(%(.//div[@class="g-recaptcha"])).try &.["data-sitekey"]
-
- inputs = {} of String => String
- form.xpath_nodes(%(.//input[@name])).map do |node|
- inputs[node["name"]] = node["value"]
- end
-
- headers = response.cookies.add_request_headers(HTTP::Headers.new)
-
- response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/createTask", body: {
- "clientKey" => CONFIG.captcha_key,
- "task" => {
- "type" => "NoCaptchaTaskProxyless",
- # "type" => "NoCaptchaTask",
- "websiteURL" => "https://www.youtube.com/watch?v=CvFH_6DNRCY&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999",
- "websiteKey" => site_key,
- # "proxyType" => "http",
- # "proxyAddress" => CONFIG.proxy_address,
- # "proxyPort" => CONFIG.proxy_port,
- # "proxyLogin" => CONFIG.proxy_user,
- # "proxyPassword" => CONFIG.proxy_pass,
- # "userAgent" => "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
- },
- }.to_json).body)
-
- if response["error"]?
- raise response["error"].as_s
- end
-
- task_id = response["taskId"].as_i
-
- loop do
- sleep 10.seconds
-
- response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/getTaskResult", body: {
- "clientKey" => CONFIG.captcha_key,
- "taskId" => task_id,
- }.to_json).body)
-
- if response["status"]?.try &.== "ready"
- break
- elsif response["errorId"]?.try &.as_i != 0
- raise response["errorDescription"].as_s
- end
- end
-
- inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
- response = YT_POOL.client &.post("/das_captcha", headers, form: inputs)
-
- yield response.cookies.select { |cookie| cookie.name != "PREF" }
- end
- rescue ex
- logger.puts("Exception: #{ex.message}")
- ensure
- sleep 1.minute
- Fiber.yield
- end
- end
-end
-
-def find_working_proxies(regions)
- loop do
- regions.each do |region|
- proxies = get_proxies(region).first(20)
- proxies = proxies.map { |proxy| {ip: proxy[:ip], port: proxy[:port]} }
- # proxies = filter_proxies(proxies)
-
- yield region, proxies
- end
-
- sleep 1.minute
- Fiber.yield
- end
-end
diff --git a/src/invidious/helpers/macros.cr b/src/invidious/helpers/macros.cr
index ddfb9f8e..8b74bc86 100644
--- a/src/invidious/helpers/macros.cr
+++ b/src/invidious/helpers/macros.cr
@@ -1,43 +1,51 @@
-macro db_mapping(mapping)
- def initialize({{*mapping.keys.map { |id| "@#{id}".id }}})
+module DB::Serializable
+ macro included
+ {% verbatim do %}
+ macro finished
+ def self.type_array
+ \{{ @type.instance_vars
+ .reject { |var| var.annotation(::DB::Field) && var.annotation(::DB::Field)[:ignore] }
+ .map { |name| name.stringify }
+ }}
+ end
+
+ def initialize(tuple)
+ \{% for var in @type.instance_vars %}
+ \{% ann = var.annotation(::DB::Field) %}
+ \{% if ann && ann[:ignore] %}
+ \{% else %}
+ @\{{var.name}} = tuple[:\{{var.name.id}}]
+ \{% end %}
+ \{% end %}
+ end
+
+ def to_a
+ \{{ @type.instance_vars
+ .reject { |var| var.annotation(::DB::Field) && var.annotation(::DB::Field)[:ignore] }
+ .map { |name| name }
+ }}
+ end
+ end
+ {% end %}
end
-
- def to_a
- return [ {{*mapping.keys.map { |id| "@#{id}".id }}} ]
- end
-
- def self.to_type_tuple
- return { {{*mapping.keys.map { |id| "#{id}" }}} }
- end
-
- DB.mapping( {{mapping}} )
-end
-
-macro json_mapping(mapping)
- def initialize({{*mapping.keys.map { |id| "@#{id}".id }}})
- end
-
- def to_a
- return [ {{*mapping.keys.map { |id| "@#{id}".id }}} ]
- end
-
- patched_json_mapping( {{mapping}} )
- YAML.mapping( {{mapping}} )
end
-macro yaml_mapping(mapping)
- def initialize({{*mapping.keys.map { |id| "@#{id}".id }}})
- end
-
- def to_a
- return [ {{*mapping.keys.map { |id| "@#{id}".id }}} ]
- end
-
- def to_tuple
- return { {{*mapping.keys.map { |id| "@#{id}".id }}} }
+module JSON::Serializable
+ macro included
+ {% verbatim do %}
+ macro finished
+ def initialize(tuple)
+ \{% for var in @type.instance_vars %}
+ \{% ann = var.annotation(::JSON::Field) %}
+ \{% if ann && ann[:ignore] %}
+ \{% else %}
+ @\{{var.name}} = tuple[:\{{var.name.id}}]
+ \{% end %}
+ \{% end %}
+ end
+ end
+ {% end %}
end
-
- YAML.mapping({{mapping}})
end
macro templated(filename, template = "template")
diff --git a/src/invidious/helpers/patch_mapping.cr b/src/invidious/helpers/patch_mapping.cr
deleted file mode 100644
index 19bd8ca1..00000000
--- a/src/invidious/helpers/patch_mapping.cr
+++ /dev/null
@@ -1,166 +0,0 @@
-# Overloads https://github.com/crystal-lang/crystal/blob/0.28.0/src/json/from_json.cr#L24
-def Object.from_json(string_or_io, default) : self
- parser = JSON::PullParser.new(string_or_io)
- new parser, default
-end
-
-# Adds configurable 'default'
-macro patched_json_mapping(_properties_, strict = false)
- {% for key, value in _properties_ %}
- {% _properties_[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %}
- {% end %}
-
- {% for key, value in _properties_ %}
- {% _properties_[key][:key_id] = key.id.gsub(/\?$/, "") %}
- {% end %}
-
- {% for key, value in _properties_ %}
- @{{value[:key_id]}} : {{value[:type]}}{{ (value[:nilable] ? "?" : "").id }}
-
- {% if value[:setter] == nil ? true : value[:setter] %}
- def {{value[:key_id]}}=(_{{value[:key_id]}} : {{value[:type]}}{{ (value[:nilable] ? "?" : "").id }})
- @{{value[:key_id]}} = _{{value[:key_id]}}
- end
- {% end %}
-
- {% if value[:getter] == nil ? true : value[:getter] %}
- def {{key.id}} : {{value[:type]}}{{ (value[:nilable] ? "?" : "").id }}
- @{{value[:key_id]}}
- end
- {% end %}
-
- {% if value[:presence] %}
- @{{value[:key_id]}}_present : Bool = false
-
- def {{value[:key_id]}}_present?
- @{{value[:key_id]}}_present
- end
- {% end %}
- {% end %}
-
- def initialize(%pull : ::JSON::PullParser, default = nil)
- {% for key, value in _properties_ %}
- %var{key.id} = nil
- %found{key.id} = false
- {% end %}
-
- %location = %pull.location
- begin
- %pull.read_begin_object
- rescue exc : ::JSON::ParseException
- raise ::JSON::MappingError.new(exc.message, self.class.to_s, nil, *%location, exc)
- end
- until %pull.kind.end_object?
- %key_location = %pull.location
- key = %pull.read_object_key
- case key
- {% for key, value in _properties_ %}
- when {{value[:key] || value[:key_id].stringify}}
- %found{key.id} = true
- begin
- %var{key.id} =
- {% if value[:nilable] || value[:default] != nil %} %pull.read_null_or { {% end %}
-
- {% if value[:root] %}
- %pull.on_key!({{value[:root]}}) do
- {% end %}
-
- {% if value[:converter] %}
- {{value[:converter]}}.from_json(%pull)
- {% elsif value[:type].is_a?(Path) || value[:type].is_a?(Generic) %}
- {{value[:type]}}.new(%pull)
- {% else %}
- ::Union({{value[:type]}}).new(%pull)
- {% end %}
-
- {% if value[:root] %}
- end
- {% end %}
-
- {% if value[:nilable] || value[:default] != nil %} } {% end %}
- rescue exc : ::JSON::ParseException
- raise ::JSON::MappingError.new(exc.message, self.class.to_s, {{value[:key] || value[:key_id].stringify}}, *%key_location, exc)
- end
- {% end %}
- else
- {% if strict %}
- raise ::JSON::MappingError.new("Unknown JSON attribute: #{key}", self.class.to_s, nil, *%key_location, nil)
- {% else %}
- %pull.skip
- {% end %}
- end
- end
- %pull.read_next
-
- {% for key, value in _properties_ %}
- {% unless value[:nilable] || value[:default] != nil %}
- if %var{key.id}.nil? && !%found{key.id} && !::Union({{value[:type]}}).nilable?
- raise ::JSON::MappingError.new("Missing JSON attribute: {{(value[:key] || value[:key_id]).id}}", self.class.to_s, nil, *%location, nil)
- end
- {% end %}
-
- {% if value[:nilable] %}
- {% if value[:default] != nil %}
- @{{value[:key_id]}} = %found{key.id} ? %var{key.id} : (default.responds_to?(:{{value[:key_id]}}) ? default.{{value[:key_id]}} : {{value[:default]}})
- {% else %}
- @{{value[:key_id]}} = %var{key.id}
- {% end %}
- {% elsif value[:default] != nil %}
- @{{value[:key_id]}} = %var{key.id}.nil? ? (default.responds_to?(:{{value[:key_id]}}) ? default.{{value[:key_id]}} : {{value[:default]}}) : %var{key.id}
- {% else %}
- @{{value[:key_id]}} = (%var{key.id}).as({{value[:type]}})
- {% end %}
-
- {% if value[:presence] %}
- @{{value[:key_id]}}_present = %found{key.id}
- {% end %}
- {% end %}
- end
-
- def to_json(json : ::JSON::Builder)
- json.object do
- {% for key, value in _properties_ %}
- _{{value[:key_id]}} = @{{value[:key_id]}}
-
- {% unless value[:emit_null] %}
- unless _{{value[:key_id]}}.nil?
- {% end %}
-
- json.field({{value[:key] || value[:key_id].stringify}}) do
- {% if value[:root] %}
- {% if value[:emit_null] %}
- if _{{value[:key_id]}}.nil?
- nil.to_json(json)
- else
- {% end %}
-
- json.object do
- json.field({{value[:root]}}) do
- {% end %}
-
- {% if value[:converter] %}
- if _{{value[:key_id]}}
- {{ value[:converter] }}.to_json(_{{value[:key_id]}}, json)
- else
- nil.to_json(json)
- end
- {% else %}
- _{{value[:key_id]}}.to_json(json)
- {% end %}
-
- {% if value[:root] %}
- {% if value[:emit_null] %}
- end
- {% end %}
- end
- end
- {% end %}
- end
-
- {% unless value[:emit_null] %}
- end
- {% end %}
- {% end %}
- end
- end
-end
diff --git a/src/invidious/helpers/signatures.cr b/src/invidious/helpers/signatures.cr
index 1d238576..f811500f 100644
--- a/src/invidious/helpers/signatures.cr
+++ b/src/invidious/helpers/signatures.cr
@@ -1,69 +1,53 @@
+alias SigProc = Proc(Array(String), Int32, Array(String))
+
def fetch_decrypt_function(id = "CvFH_6DNRCY")
- document = YT_POOL.client &.get("/watch?v=#{id}&gl=US&hl=en&disable_polymer=1").body
- url = document.match(/src="(?<url>\/yts\/jsbin\/player_ias-.{9}\/en_US\/base.js)"/).not_nil!["url"]
+ document = YT_POOL.client &.get("/watch?v=#{id}&gl=US&hl=en").body
+ url = document.match(/src="(?<url>\/s\/player\/[^\/]+\/player_ias[^\/]+\/en_US\/base.js)"/).not_nil!["url"]
player = YT_POOL.client &.get(url).body
- function_name = player.match(/^(?<name>[^=]+)=function\(a\){a=a\.split\(""\)/m).not_nil!["name"]
- function_body = player.match(/^#{Regex.escape(function_name)}=function\(a\){(?<body>[^}]+)}/m).not_nil!["body"]
+ function_name = player.match(/^(?<name>[^=]+)=function\(\w\){\w=\w\.split\(""\);[^\. ]+\.[^( ]+/m).not_nil!["name"]
+ function_body = player.match(/^#{Regex.escape(function_name)}=function\(\w\){(?<body>[^}]+)}/m).not_nil!["body"]
function_body = function_body.split(";")[1..-2]
var_name = function_body[0][0, 2]
var_body = player.delete("\n").match(/var #{Regex.escape(var_name)}={(?<body>(.*?))};/).not_nil!["body"]
- operations = {} of String => String
+ operations = {} of String => SigProc
var_body.split("},").each do |operation|
op_name = operation.match(/^[^:]+/).not_nil![0]
op_body = operation.match(/\{[^}]+/).not_nil![0]
case op_body
when "{a.reverse()"
- operations[op_name] = "a"
+ operations[op_name] = ->(a : Array(String), b : Int32) { a.reverse }
when "{a.splice(0,b)"
- operations[op_name] = "b"
+ operations[op_name] = ->(a : Array(String), b : Int32) { a.delete_at(0..(b - 1)); a }
else
- operations[op_name] = "c"
+ operations[op_name] = ->(a : Array(String), b : Int32) { c = a[0]; a[0] = a[b % a.size]; a[b % a.size] = c; a }
end
end
- decrypt_function = [] of {name: String, value: Int32}
+ decrypt_function = [] of {SigProc, Int32}
function_body.each do |function|
function = function.lchop(var_name).delete("[].")
op_name = function.match(/[^\(]+/).not_nil![0]
- value = function.match(/\(a,(?<value>[\d]+)\)/).not_nil!["value"].to_i
+ value = function.match(/\(\w,(?<value>[\d]+)\)/).not_nil!["value"].to_i
- decrypt_function << {name: operations[op_name], value: value}
+ decrypt_function << {operations[op_name], value}
end
return decrypt_function
end
-def decrypt_signature(fmt, code)
- if !fmt["s"]?
- return ""
- end
-
- a = fmt["s"]
- a = a.split("")
+def decrypt_signature(fmt : Hash(String, JSON::Any))
+ return "" if !fmt["s"]? || !fmt["sp"]?
- code.each do |item|
- case item[:name]
- when "a"
- a.reverse!
- when "b"
- a.delete_at(0..(item[:value] - 1))
- when "c"
- a = splice(a, item[:value])
- end
+ sp = fmt["sp"].as_s
+ sig = fmt["s"].as_s.split("")
+ DECRYPT_FUNCTION.each do |proc, value|
+ sig = proc.call(sig, value)
end
- signature = a.join("")
- return "&#{fmt["sp"]?}=#{signature}"
-end
-
-def splice(a, b)
- c = a[0]
- a[0] = a[b % a.size]
- a[b % a.size] = c
- return a
+ return "&#{sp}=#{sig.join("")}"
end
diff --git a/src/invidious/helpers/static_file_handler.cr b/src/invidious/helpers/static_file_handler.cr
index 20d92b9c..be9d36ab 100644
--- a/src/invidious/helpers/static_file_handler.cr
+++ b/src/invidious/helpers/static_file_handler.cr
@@ -81,12 +81,12 @@ def send_file(env : HTTP::Server::Context, file_path : String, data : Slice(UInt
condition = config.is_a?(Hash) && config["gzip"]? == true && filesize > minsize && Kemal::Utils.zip_types(file_path)
if condition && request_headers.includes_word?("Accept-Encoding", "gzip")
env.response.headers["Content-Encoding"] = "gzip"
- Gzip::Writer.open(env.response) do |deflate|
+ Compress::Gzip::Writer.open(env.response) do |deflate|
IO.copy(file, deflate)
end
elsif condition && request_headers.includes_word?("Accept-Encoding", "deflate")
env.response.headers["Content-Encoding"] = "deflate"
- Flate::Writer.open(env.response) do |deflate|
+ Compress::Deflate::Writer.open(env.response) do |deflate|
IO.copy(file, deflate)
end
else
diff --git a/src/invidious/helpers/tokens.cr b/src/invidious/helpers/tokens.cr
index 30f7d4f4..39aae367 100644
--- a/src/invidious/helpers/tokens.cr
+++ b/src/invidious/helpers/tokens.cr
@@ -1,3 +1,5 @@
+require "crypto/subtle"
+
def generate_token(email, scopes, expire, key, db)
session = "v1:#{Base64.urlsafe_encode(Random::Secure.random_bytes(32))}"
PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", session, email, Time.utc)
@@ -41,15 +43,10 @@ def sign_token(key, hash)
string_to_sign = [] of String
hash.each do |key, value|
- if key == "signature"
- next
- end
+ next if key == "signature"
- if value.is_a?(JSON::Any)
- case value
- when .as_a?
- value = value.as_a.map { |item| item.as_s }
- end
+ if value.is_a?(JSON::Any) && value.as_a?
+ value = value.as_a.map { |i| i.as_s }
end
case value
@@ -76,32 +73,31 @@ def validate_request(token, session, request, key, db, locale = nil)
raise translate(locale, "Hidden field \"token\" is a required field")
end
- if token["signature"] != sign_token(key, token)
- raise translate(locale, "Invalid signature")
+ expire = token["expire"]?.try &.as_i
+ if expire.try &.< Time.utc.to_unix
+ raise translate(locale, "Token is expired, please try again")
end
if token["session"] != session
raise translate(locale, "Erroneous token")
end
- if token["nonce"]? && (nonce = db.query_one?("SELECT * FROM nonces WHERE nonce = $1", token["nonce"], as: {String, Time}))
- if nonce[1] > Time.utc
- db.exec("UPDATE nonces SET expire = $1 WHERE nonce = $2", Time.utc(1990, 1, 1), nonce[0])
- else
- raise translate(locale, "Erroneous token")
- end
- end
-
scopes = token["scopes"].as_a.map { |v| v.as_s }
scope = "#{request.method}:#{request.path.lchop("/api/v1/auth/").lstrip("/")}"
-
if !scopes_include_scope(scopes, scope)
raise translate(locale, "Invalid scope")
end
- expire = token["expire"]?.try &.as_i
- if expire.try &.< Time.utc.to_unix
- raise translate(locale, "Token is expired, please try again")
+ if !Crypto::Subtle.constant_time_compare(token["signature"].to_s, sign_token(key, token))
+ raise translate(locale, "Invalid signature")
+ end
+
+ if token["nonce"]? && (nonce = db.query_one?("SELECT * FROM nonces WHERE nonce = $1", token["nonce"], as: {String, Time}))
+ if nonce[1] > Time.utc
+ db.exec("UPDATE nonces SET expire = $1 WHERE nonce = $2", Time.utc(1990, 1, 1), nonce[0])
+ else
+ raise translate(locale, "Erroneous token")
+ end
end
return {scopes, expire, token["signature"].as_s}
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index 8c5ce7a0..a51f15ce 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -2,20 +2,23 @@ require "lsquic"
require "pool/connection"
def add_yt_headers(request)
- request.headers["x-youtube-client-name"] ||= "1"
- request.headers["x-youtube-client-version"] ||= "1.20180719"
request.headers["user-agent"] ||= "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"
request.headers["accept-charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
request.headers["accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.headers["accept-language"] ||= "en-us,en;q=0.5"
- request.headers["cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}"
+ return if request.resource.starts_with? "/sorry/index"
+ request.headers["x-youtube-client-name"] ||= "1"
+ request.headers["x-youtube-client-version"] ||= "2.20200609"
+ if !CONFIG.cookies.empty?
+ request.headers["cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}"
+ end
end
-struct HTTPPool
+struct QUICPool
property! url : URI
property! capacity : Int32
property! timeout : Float64
- property pool : ConnectionPool(HTTPClient)
+ property pool : ConnectionPool(QUIC::Client)
def initialize(url : URI, @capacity = 5, @timeout = 5.0)
@url = url
@@ -23,87 +26,35 @@ struct HTTPPool
end
def client(region = nil, &block)
- conn = pool.checkout
-
- begin
- if region
- PROXY_LIST[region]?.try &.sample(40).each do |proxy|
- begin
- proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
- conn.set_proxy(proxy)
- break
- rescue ex
- end
- end
- end
-
+ if region
+ conn = make_client(url, region)
response = yield conn
-
- if region
- conn.unset_proxy
+ else
+ conn = pool.checkout
+ begin
+ response = yield conn
+ rescue ex
+ conn.close
+ conn = QUIC::Client.new(url)
+ conn.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::INET
+ conn.family = Socket::Family::INET if conn.family == Socket::Family::UNSPEC
+ conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
+ response = yield conn
+ ensure
+ pool.checkin(conn)
end
-
- response
- rescue ex
- conn = HTTPClient.new(url)
- conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- conn.family = (url.host == "www.youtube.com" || url.host == "suggestqueries.google.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC
- conn.read_timeout = 10.seconds
- conn.connect_timeout = 10.seconds
- yield conn
- ensure
- pool.checkin(conn)
end
- end
-
- private def build_pool
- ConnectionPool(HTTPClient).new(capacity: capacity, timeout: timeout) do
- client = HTTPClient.new(url)
- client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- client.family = (url.host == "www.youtube.com" || url.host == "suggestqueries.google.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC
- client.read_timeout = 10.seconds
- client.connect_timeout = 10.seconds
- client
- end
- end
-end
-struct QUICPool
- property! url : URI
- property! capacity : Int32
- property! timeout : Float64
-
- def initialize(url : URI, @capacity = 5, @timeout = 5.0)
- @url = url
+ response
end
- def client(region = nil, &block)
- begin
- if region
- client = HTTPClient.new(url)
- client.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- client.read_timeout = 10.seconds
- client.connect_timeout = 10.seconds
-
- PROXY_LIST[region]?.try &.sample(40).each do |proxy|
- begin
- proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
- client.set_proxy(proxy)
- break
- rescue ex
- end
- end
-
- yield client
- else
- conn = QUIC::Client.new(url)
- conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- yield conn
- end
- rescue ex
+ private def build_pool
+ ConnectionPool(QUIC::Client).new(capacity: capacity, timeout: timeout) do
conn = QUIC::Client.new(url)
+ conn.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::INET
+ conn.family = Socket::Family::INET if conn.family == Socket::Family::UNSPEC
conn.before_request { |r| add_yt_headers(r) } if url.host == "www.youtube.com"
- yield conn
+ conn
end
end
end
@@ -129,7 +80,8 @@ def elapsed_text(elapsed)
end
def make_client(url : URI, region = nil)
- client = HTTPClient.new(url)
+ # TODO: Migrate any applicable endpoints to QUIC
+ client = HTTPClient.new(url, OpenSSL::SSL::Context::Client.insecure)
client.family = (url.host == "www.youtube.com") ? CONFIG.force_resolve : Socket::Family::UNSPEC
client.read_timeout = 10.seconds
client.connect_timeout = 10.seconds
@@ -151,7 +103,7 @@ end
def decode_length_seconds(string)
length_seconds = string.gsub(/[^0-9:]/, "").split(":").map &.to_i
length_seconds = [0] * (3 - length_seconds.size) + length_seconds
- length_seconds = Time::Span.new(length_seconds[0], length_seconds[1], length_seconds[2])
+ length_seconds = Time::Span.new hours: length_seconds[0], minutes: length_seconds[1], seconds: length_seconds[2]
length_seconds = length_seconds.total_seconds.to_i
return length_seconds
@@ -213,6 +165,7 @@ def decode_date(string : String)
return Time.utc
when "yesterday"
return Time.utc - 1.day
+ else nil # Continue
end
# String matches format "20 hours ago", "4 months ago"...
@@ -367,7 +320,7 @@ def get_referer(env, fallback = "/", unroll = true)
end
referer = referer.full_path
- referer = "/" + referer.lstrip("\/\\")
+ referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\")
if referer == env.request.path
referer = fallback
@@ -376,50 +329,13 @@ def get_referer(env, fallback = "/", unroll = true)
return referer
end
-struct VarInt
- def self.from_io(io : IO, format = IO::ByteFormat::NetworkEndian) : Int32
- result = 0_u32
- num_read = 0
-
- loop do
- byte = io.read_byte
- raise "Invalid VarInt" if !byte
- value = byte & 0x7f
-
- result |= value.to_u32 << (7 * num_read)
- num_read += 1
-
- break if byte & 0x80 == 0
- raise "Invalid VarInt" if num_read > 5
- end
-
- result.to_i32
- end
-
- def self.to_io(io : IO, value : Int32)
- io.write_byte 0x00 if value == 0x00
- value = value.to_u32
-
- while value != 0
- byte = (value & 0x7f).to_u8
- value >>= 7
-
- if value != 0
- byte |= 0x80
- end
-
- io.write_byte byte
- end
- end
-end
-
def sha256(text)
digest = OpenSSL::Digest.new("SHA256")
digest << text
- return digest.hexdigest
+ return digest.final.hexstring
end
-def subscribe_pubsub(topic, key, config, client_pool)
+def subscribe_pubsub(topic, key, config)
case topic
when .match(/^UC[A-Za-z0-9_-]{22}$/)
topic = "channel_id=#{topic}"
@@ -435,10 +351,8 @@ def subscribe_pubsub(topic, key, config, client_pool)
nonce = Random::Secure.hex(4)
signature = "#{time}:#{nonce}"
- host_url = make_host_url(config, Kemal.config)
-
body = {
- "hub.callback" => "#{host_url}/feed/webhook/v1:#{time}:#{nonce}:#{OpenSSL::HMAC.hexdigest(:sha1, key, signature)}",
+ "hub.callback" => "#{HOST_URL}/feed/webhook/v1:#{time}:#{nonce}:#{OpenSSL::HMAC.hexdigest(:sha1, key, signature)}",
"hub.topic" => "https://www.youtube.com/xml/feeds/videos.xml?#{topic}",
"hub.verify" => "async",
"hub.mode" => "subscribe",
@@ -446,7 +360,7 @@ def subscribe_pubsub(topic, key, config, client_pool)
"hub.secret" => key.to_s,
}
- return client_pool.client &.post("/subscribe", form: body)
+ return make_client(PUBSUB_URL).post("/subscribe", form: body)
end
def parse_range(range)
diff --git a/src/invidious/jobs.cr b/src/invidious/jobs.cr
new file mode 100644
index 00000000..ec0cad64
--- /dev/null
+++ b/src/invidious/jobs.cr
@@ -0,0 +1,13 @@
+module Invidious::Jobs
+ JOBS = [] of BaseJob
+
+ def self.register(job : BaseJob)
+ JOBS << job
+ end
+
+ def self.start_all
+ JOBS.each do |job|
+ spawn { job.begin }
+ end
+ end
+end
diff --git a/src/invidious/jobs/base_job.cr b/src/invidious/jobs/base_job.cr
new file mode 100644
index 00000000..47e75864
--- /dev/null
+++ b/src/invidious/jobs/base_job.cr
@@ -0,0 +1,3 @@
+abstract class Invidious::Jobs::BaseJob
+ abstract def begin
+end
diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr
new file mode 100644
index 00000000..8b69e01a
--- /dev/null
+++ b/src/invidious/jobs/bypass_captcha_job.cr
@@ -0,0 +1,131 @@
+class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
+ private getter logger : Invidious::LogHandler
+ private getter config : Config
+
+ def initialize(@logger, @config)
+ end
+
+ def begin
+ loop do
+ begin
+ {"/watch?v=jNQXAC9IVRw&gl=US&hl=en&has_verified=1&bpctr=9999999999", produce_channel_videos_url(ucid: "UC4QobU6STFB0P71PMvOGN5A")}.each do |path|
+ response = YT_POOL.client &.get(path)
+ if response.body.includes?("To continue with your YouTube experience, please fill out the form below.")
+ html = XML.parse_html(response.body)
+ form = html.xpath_node(%(//form[@action="/das_captcha"])).not_nil!
+ site_key = form.xpath_node(%(.//div[@id="recaptcha"])).try &.["data-sitekey"]
+ s_value = form.xpath_node(%(.//div[@id="recaptcha"])).try &.["data-s"]
+
+ inputs = {} of String => String
+ form.xpath_nodes(%(.//input[@name])).map do |node|
+ inputs[node["name"]] = node["value"]
+ end
+
+ headers = response.cookies.add_request_headers(HTTP::Headers.new)
+
+ response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/createTask", body: {
+ "clientKey" => config.captcha_key,
+ "task" => {
+ "type" => "NoCaptchaTaskProxyless",
+ "websiteURL" => "https://www.youtube.com#{path}",
+ "websiteKey" => site_key,
+ "recaptchaDataSValue" => s_value,
+ },
+ }.to_json).body)
+
+ raise response["error"].as_s if response["error"]?
+ task_id = response["taskId"].as_i
+
+ loop do
+ sleep 10.seconds
+
+ response = JSON.parse(HTTP::Client.post("https://api.anti-captcha.com/getTaskResult", body: {
+ "clientKey" => config.captcha_key,
+ "taskId" => task_id,
+ }.to_json).body)
+
+ if response["status"]?.try &.== "ready"
+ break
+ elsif response["errorId"]?.try &.as_i != 0
+ raise response["errorDescription"].as_s
+ end
+ end
+
+ inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
+ headers["Cookies"] = response["solution"]["cookies"].as_h?.try &.map { |k, v| "#{k}=#{v}" }.join("; ") || ""
+ response = YT_POOL.client &.post("/das_captcha", headers, form: inputs)
+
+ response.cookies
+ .select { |cookie| cookie.name != "PREF" }
+ .each { |cookie| config.cookies << cookie }
+
+ # Persist cookies between runs
+ File.write("config/config.yml", config.to_yaml)
+ elsif response.headers["Location"]?.try &.includes?("/sorry/index")
+ location = response.headers["Location"].try { |u| URI.parse(u) }
+ headers = HTTP::Headers{":authority" => location.host.not_nil!}
+ response = YT_POOL.client &.get(location.full_path, headers)
+
+ html = XML.parse_html(response.body)
+ form = html.xpath_node(%(//form[@action="index"])).not_nil!
+ site_key = form.xpath_node(%(.//div[@id="recaptcha"])).try &.["data-sitekey"]
+ s_value = form.xpath_node(%(.//div[@id="recaptcha"])).try &.["data-s"]
+
+ inputs = {} of String => String
+ form.xpath_nodes(%(.//input[@name])).map do |node|
+ inputs[node["name"]] = node["value"]
+ end
+
+ captcha_client = HTTPClient.new(URI.parse("https://api.anti-captcha.com"))
+ captcha_client.family = config.force_resolve || Socket::Family::INET
+ response = JSON.parse(captcha_client.post("/createTask", body: {
+ "clientKey" => config.captcha_key,
+ "task" => {
+ "type" => "NoCaptchaTaskProxyless",
+ "websiteURL" => location.to_s,
+ "websiteKey" => site_key,
+ "recaptchaDataSValue" => s_value,
+ },
+ }.to_json).body)
+
+ raise response["error"].as_s if response["error"]?
+ task_id = response["taskId"].as_i
+
+ loop do
+ sleep 10.seconds
+
+ response = JSON.parse(captcha_client.post("/getTaskResult", body: {
+ "clientKey" => config.captcha_key,
+ "taskId" => task_id,
+ }.to_json).body)
+
+ if response["status"]?.try &.== "ready"
+ break
+ elsif response["errorId"]?.try &.as_i != 0
+ raise response["errorDescription"].as_s
+ end
+ end
+
+ inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
+ headers["Cookies"] = response["solution"]["cookies"].as_h?.try &.map { |k, v| "#{k}=#{v}" }.join("; ") || ""
+ response = YT_POOL.client &.post("/sorry/index", headers: headers, form: inputs)
+ headers = HTTP::Headers{
+ "Cookie" => URI.parse(response.headers["location"]).query_params["google_abuse"].split(";")[0],
+ }
+ cookies = HTTP::Cookies.from_headers(headers)
+
+ cookies.each { |cookie| config.cookies << cookie }
+
+ # Persist cookies between runs
+ File.write("config/config.yml", config.to_yaml)
+ end
+ end
+ rescue ex
+ logger.puts("Exception: #{ex.message}")
+ ensure
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+ end
+end
diff --git a/src/invidious/jobs/notification_job.cr b/src/invidious/jobs/notification_job.cr
new file mode 100644
index 00000000..2f525e08
--- /dev/null
+++ b/src/invidious/jobs/notification_job.cr
@@ -0,0 +1,24 @@
+class Invidious::Jobs::NotificationJob < Invidious::Jobs::BaseJob
+ private getter connection_channel : Channel({Bool, Channel(PQ::Notification)})
+ private getter pg_url : URI
+
+ def initialize(@connection_channel, @pg_url)
+ end
+
+ def begin
+ connections = [] of Channel(PQ::Notification)
+
+ PG.connect_listen(pg_url, "notifications") { |event| connections.each(&.send(event)) }
+
+ loop do
+ action, connection = connection_channel.receive
+
+ case action
+ when true
+ connections << connection
+ when false
+ connections.delete(connection)
+ end
+ end
+ end
+end
diff --git a/src/invidious/jobs/pull_popular_videos_job.cr b/src/invidious/jobs/pull_popular_videos_job.cr
new file mode 100644
index 00000000..7a8ab84e
--- /dev/null
+++ b/src/invidious/jobs/pull_popular_videos_job.cr
@@ -0,0 +1,27 @@
+class Invidious::Jobs::PullPopularVideosJob < Invidious::Jobs::BaseJob
+ QUERY = <<-SQL
+ SELECT DISTINCT ON (ucid) *
+ FROM channel_videos
+ WHERE ucid IN (SELECT channel FROM (SELECT UNNEST(subscriptions) AS channel FROM users) AS d
+ GROUP BY channel ORDER BY COUNT(channel) DESC LIMIT 40)
+ ORDER BY ucid, published DESC
+ SQL
+ POPULAR_VIDEOS = Atomic.new([] of ChannelVideo)
+ private getter db : DB::Database
+
+ def initialize(@db)
+ end
+
+ def begin
+ loop do
+ videos = db.query_all(QUERY, as: ChannelVideo)
+ .sort_by(&.published)
+ .reverse
+
+ POPULAR_VIDEOS.set(videos)
+
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+end
diff --git a/src/invidious/jobs/refresh_channels_job.cr b/src/invidious/jobs/refresh_channels_job.cr
new file mode 100644
index 00000000..75fc474d
--- /dev/null
+++ b/src/invidious/jobs/refresh_channels_job.cr
@@ -0,0 +1,59 @@
+class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
+ private getter db : DB::Database
+ private getter logger : Invidious::LogHandler
+ private getter config : Config
+
+ def initialize(@db, @logger, @config)
+ end
+
+ def begin
+ max_threads = config.channel_threads
+ lim_threads = max_threads
+ active_threads = 0
+ active_channel = Channel(Bool).new
+ backoff = 1.seconds
+
+ loop do
+ db.query("SELECT id FROM channels ORDER BY updated") do |rs|
+ rs.each do
+ id = rs.read(String)
+
+ if active_threads >= lim_threads
+ if active_channel.receive
+ active_threads -= 1
+ end
+ end
+
+ active_threads += 1
+ spawn do
+ begin
+ channel = fetch_channel(id, db, config.full_refresh)
+
+ lim_threads = max_threads
+ db.exec("UPDATE channels SET updated = $1, author = $2, deleted = false WHERE id = $3", Time.utc, channel.author, id)
+ rescue ex
+ logger.puts("#{id} : #{ex.message}")
+ if ex.message == "Deleted or invalid channel"
+ db.exec("UPDATE channels SET updated = $1, deleted = true WHERE id = $2", Time.utc, id)
+ else
+ lim_threads = 1
+ logger.puts("#{id} : backing off for #{backoff}s")
+ sleep backoff
+ if backoff < 1.days
+ backoff += backoff
+ else
+ backoff = 1.days
+ end
+ end
+ end
+
+ active_channel.send(true)
+ end
+ end
+ end
+
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+end
diff --git a/src/invidious/jobs/refresh_feeds_job.cr b/src/invidious/jobs/refresh_feeds_job.cr
new file mode 100644
index 00000000..eebdf0f3
--- /dev/null
+++ b/src/invidious/jobs/refresh_feeds_job.cr
@@ -0,0 +1,77 @@
+class Invidious::Jobs::RefreshFeedsJob < Invidious::Jobs::BaseJob
+ private getter db : DB::Database
+ private getter logger : Invidious::LogHandler
+ private getter config : Config
+
+ def initialize(@db, @logger, @config)
+ end
+
+ def begin
+ max_threads = config.feed_threads
+ active_threads = 0
+ active_channel = Channel(Bool).new
+
+ loop do
+ db.query("SELECT email FROM users WHERE feed_needs_update = true OR feed_needs_update IS NULL") do |rs|
+ rs.each do
+ email = rs.read(String)
+ view_name = "subscriptions_#{sha256(email)}"
+
+ if active_threads >= max_threads
+ if active_channel.receive
+ active_threads -= 1
+ end
+ end
+
+ active_threads += 1
+ spawn do
+ begin
+ # Drop outdated views
+ column_array = get_column_array(db, view_name)
+ ChannelVideo.type_array.each_with_index do |name, i|
+ if name != column_array[i]?
+ logger.puts("DROP MATERIALIZED VIEW #{view_name}")
+ db.exec("DROP MATERIALIZED VIEW #{view_name}")
+ raise "view does not exist"
+ end
+ end
+
+ if !db.query_one("SELECT pg_get_viewdef('#{view_name}')", as: String).includes? "WHERE ((cv.ucid = ANY (u.subscriptions))"
+ logger.puts("Materialized view #{view_name} is out-of-date, recreating...")
+ db.exec("DROP MATERIALIZED VIEW #{view_name}")
+ end
+
+ db.exec("REFRESH MATERIALIZED VIEW #{view_name}")
+ db.exec("UPDATE users SET feed_needs_update = false WHERE email = $1", email)
+ rescue ex
+ # Rename old views
+ begin
+ legacy_view_name = "subscriptions_#{sha256(email)[0..7]}"
+
+ db.exec("SELECT * FROM #{legacy_view_name} LIMIT 0")
+ logger.puts("RENAME MATERIALIZED VIEW #{legacy_view_name}")
+ db.exec("ALTER MATERIALIZED VIEW #{legacy_view_name} RENAME TO #{view_name}")
+ rescue ex
+ begin
+ # While iterating through, we may have an email stored from a deleted account
+ if db.query_one?("SELECT true FROM users WHERE email = $1", email, as: Bool)
+ logger.puts("CREATE #{view_name}")
+ db.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(email)}")
+ db.exec("UPDATE users SET feed_needs_update = false WHERE email = $1", email)
+ end
+ rescue ex
+ logger.puts("REFRESH #{email} : #{ex.message}")
+ end
+ end
+ end
+
+ active_channel.send(true)
+ end
+ end
+ end
+
+ sleep 5.seconds
+ Fiber.yield
+ end
+ end
+end
diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr
new file mode 100644
index 00000000..021671be
--- /dev/null
+++ b/src/invidious/jobs/statistics_refresh_job.cr
@@ -0,0 +1,59 @@
+class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob
+ STATISTICS = {
+ "version" => "2.0",
+ "software" => {
+ "name" => "invidious",
+ "version" => "",
+ "branch" => "",
+ },
+ "openRegistrations" => true,
+ "usage" => {
+ "users" => {
+ "total" => 0_i64,
+ "activeHalfyear" => 0_i64,
+ "activeMonth" => 0_i64,
+ },
+ },
+ "metadata" => {
+ "updatedAt" => Time.utc.to_unix,
+ "lastChannelRefreshedAt" => 0_i64,
+ },
+ }
+
+ private getter db : DB::Database
+ private getter config : Config
+
+ def initialize(@db, @config, @software_config : Hash(String, String))
+ end
+
+ def begin
+ load_initial_stats
+
+ loop do
+ refresh_stats
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+
+ # should only be called once at the very beginning
+ private def load_initial_stats
+ STATISTICS["software"] = {
+ "name" => @software_config["name"],
+ "version" => @software_config["version"],
+ "branch" => @software_config["branch"],
+ }
+ STATISTICS["openRegistration"] = config.registration_enabled
+ end
+
+ private def refresh_stats
+ users = STATISTICS.dig("usage", "users").as(Hash(String, Int64))
+ users["total"] = db.query_one("SELECT count(*) FROM users", as: Int64)
+ users["activeHalfyear"] = db.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '6 months'", as: Int64)
+ users["activeMonth"] = db.query_one("SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '1 month'", as: Int64)
+ STATISTICS["metadata"] = {
+ "updatedAt" => Time.utc.to_unix,
+ "lastChannelRefreshedAt" => db.query_one?("SELECT updated FROM channels ORDER BY updated DESC LIMIT 1", as: Time).try &.to_unix || 0_i64,
+ }
+ end
+end
diff --git a/src/invidious/jobs/subscribe_to_feeds_job.cr b/src/invidious/jobs/subscribe_to_feeds_job.cr
new file mode 100644
index 00000000..3d3b2218
--- /dev/null
+++ b/src/invidious/jobs/subscribe_to_feeds_job.cr
@@ -0,0 +1,52 @@
+class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob
+ private getter db : DB::Database
+ private getter logger : Invidious::LogHandler
+ private getter hmac_key : String
+ private getter config : Config
+
+ def initialize(@db, @logger, @config, @hmac_key)
+ end
+
+ def begin
+ max_threads = 1
+ if config.use_pubsub_feeds.is_a?(Int32)
+ max_threads = config.use_pubsub_feeds.as(Int32)
+ end
+
+ active_threads = 0
+ active_channel = Channel(Bool).new
+
+ loop do
+ db.query_all("SELECT id FROM channels WHERE CURRENT_TIMESTAMP - subscribed > interval '4 days' OR subscribed IS NULL") do |rs|
+ rs.each do
+ ucid = rs.read(String)
+
+ if active_threads >= max_threads.as(Int32)
+ if active_channel.receive
+ active_threads -= 1
+ end
+ end
+
+ active_threads += 1
+
+ spawn do
+ begin
+ response = subscribe_pubsub(ucid, hmac_key, config)
+
+ if response.status_code >= 400
+ logger.puts("#{ucid} : #{response.body}")
+ end
+ rescue ex
+ logger.puts("#{ucid} : #{ex.message}")
+ end
+
+ active_channel.send(true)
+ end
+ end
+ end
+
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+end
diff --git a/src/invidious/jobs/update_decrypt_function_job.cr b/src/invidious/jobs/update_decrypt_function_job.cr
new file mode 100644
index 00000000..5332c672
--- /dev/null
+++ b/src/invidious/jobs/update_decrypt_function_job.cr
@@ -0,0 +1,19 @@
+class Invidious::Jobs::UpdateDecryptFunctionJob < Invidious::Jobs::BaseJob
+ DECRYPT_FUNCTION = [] of {SigProc, Int32}
+
+ def begin
+ loop do
+ begin
+ decrypt_function = fetch_decrypt_function
+ DECRYPT_FUNCTION.clear
+ decrypt_function.each { |df| DECRYPT_FUNCTION << df }
+ rescue ex
+ # TODO: Log error
+ next
+ ensure
+ sleep 1.minute
+ Fiber.yield
+ end
+ end
+ end
+end
diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr
index 04a37b87..c69eb0c4 100644
--- a/src/invidious/mixes.cr
+++ b/src/invidious/mixes.cr
@@ -1,32 +1,32 @@
struct MixVideo
- db_mapping({
- title: String,
- id: String,
- author: String,
- ucid: String,
- length_seconds: Int32,
- index: Int32,
- rdid: String,
- })
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property ucid : String
+ property length_seconds : Int32
+ property index : Int32
+ property rdid : String
end
struct Mix
- db_mapping({
- title: String,
- id: String,
- videos: Array(MixVideo),
- })
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property videos : Array(MixVideo)
end
def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
headers = HTTP::Headers.new
- headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
if cookies
headers = cookies.add_request_headers(headers)
end
- response = YT_POOL.client &.get("/watch?v=#{video_id}&list=#{rdid}&gl=US&hl=en&has_verified=1&bpctr=9999999999", headers)
+ video_id = "CvFH_6DNRCY" if rdid.starts_with? "OLAK5uy_"
+ response = YT_POOL.client &.get("/watch?v=#{video_id}&list=#{rdid}&gl=US&hl=en", headers)
initial_data = extract_initial_data(response.body)
if !initial_data["contents"]["twoColumnWatchNextResults"]["playlist"]?
@@ -49,23 +49,22 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
id = item["videoId"].as_s
title = item["title"]?.try &.["simpleText"].as_s
- if !title
- next
- end
+ next if !title
+
author = item["longBylineText"]["runs"][0]["text"].as_s
ucid = item["longBylineText"]["runs"][0]["navigationEndpoint"]["browseEndpoint"]["browseId"].as_s
length_seconds = decode_length_seconds(item["lengthText"]["simpleText"].as_s)
index = item["navigationEndpoint"]["watchEndpoint"]["index"].as_i
- videos << MixVideo.new(
- title,
- id,
- author,
- ucid,
- length_seconds,
- index,
- rdid
- )
+ videos << MixVideo.new({
+ title: title,
+ id: id,
+ author: author,
+ ucid: ucid,
+ length_seconds: length_seconds,
+ index: index,
+ rdid: rdid,
+ })
end
if !cookies
@@ -75,7 +74,11 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
videos.uniq! { |video| video.id }
videos = videos.first(50)
- return Mix.new(mix_title, rdid, videos)
+ return Mix.new({
+ title: mix_title,
+ id: rdid,
+ videos: videos,
+ })
end
def template_mix(mix)
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index 9c8afd3c..c984a12a 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -1,26 +1,38 @@
struct PlaylistVideo
- def to_xml(host_url, auto_generated, xml : XML::Builder)
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property ucid : String
+ property length_seconds : Int32
+ property published : Time
+ property plid : String
+ property index : Int64
+ property live_now : Bool
+
+ def to_xml(auto_generated, xml : XML::Builder)
xml.element("entry") do
xml.element("id") { xml.text "yt:video:#{self.id}" }
xml.element("yt:videoId") { xml.text self.id }
xml.element("yt:channelId") { xml.text self.ucid }
xml.element("title") { xml.text self.title }
- xml.element("link", rel: "alternate", href: "#{host_url}/watch?v=#{self.id}")
+ xml.element("link", rel: "alternate", href: "#{HOST_URL}/watch?v=#{self.id}")
xml.element("author") do
if auto_generated
xml.element("name") { xml.text self.author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{self.ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" }
else
xml.element("name") { xml.text author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{ucid}" }
end
end
xml.element("content", type: "xhtml") do
xml.element("div", xmlns: "http://www.w3.org/1999/xhtml") do
- xml.element("a", href: "#{host_url}/watch?v=#{self.id}") do
- xml.element("img", src: "#{host_url}/vi/#{self.id}/mqdefault.jpg")
+ xml.element("a", href: "#{HOST_URL}/watch?v=#{self.id}") do
+ xml.element("img", src: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg")
end
end
end
@@ -29,23 +41,23 @@ struct PlaylistVideo
xml.element("media:group") do
xml.element("media:title") { xml.text self.title }
- xml.element("media:thumbnail", url: "#{host_url}/vi/#{self.id}/mqdefault.jpg",
+ xml.element("media:thumbnail", url: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg",
width: "320", height: "180")
end
end
end
- def to_xml(host_url, auto_generated, xml : XML::Builder? = nil)
+ def to_xml(auto_generated, xml : XML::Builder? = nil)
if xml
- to_xml(host_url, auto_generated, xml)
+ to_xml(auto_generated, xml)
else
XML.build do |json|
- to_xml(host_url, auto_generated, xml)
+ to_xml(auto_generated, xml)
end
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder, index : Int32?)
+ def to_json(locale, json : JSON::Builder, index : Int32?)
json.object do
json.field "title", self.title
json.field "videoId", self.id
@@ -55,7 +67,7 @@ struct PlaylistVideo
json.field "authorUrl", "/channel/#{self.ucid}"
json.field "videoThumbnails" do
- generate_thumbnails(json, self.id, config, kemal_config)
+ generate_thumbnails(json, self.id)
end
if index
@@ -69,31 +81,32 @@ struct PlaylistVideo
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder? = nil, index : Int32? = nil)
+ def to_json(locale, json : JSON::Builder? = nil, index : Int32? = nil)
if json
- to_json(locale, config, kemal_config, json, index: index)
+ to_json(locale, json, index: index)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, json, index: index)
+ to_json(locale, json, index: index)
end
end
end
-
- db_mapping({
- title: String,
- id: String,
- author: String,
- ucid: String,
- length_seconds: Int32,
- published: Time,
- plid: String,
- index: Int64,
- live_now: Bool,
- })
end
struct Playlist
- def to_json(offset, locale, config, kemal_config, json : JSON::Builder, continuation : String? = nil)
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property author_thumbnail : String
+ property ucid : String
+ property description : String
+ property video_count : Int32
+ property views : Int64
+ property updated : Time
+ property thumbnail : String?
+
+ def to_json(offset, locale, json : JSON::Builder, continuation : String? = nil)
json.object do
json.field "type", "playlist"
json.field "title", self.title
@@ -118,7 +131,7 @@ struct Playlist
end
end
- json.field "description", html_to_content(self.description_html)
+ json.field "description", self.description
json.field "descriptionHtml", self.description_html
json.field "videoCount", self.video_count
@@ -130,39 +143,30 @@ struct Playlist
json.array do
videos = get_playlist_videos(PG_DB, self, offset: offset, locale: locale, continuation: continuation)
videos.each_with_index do |video, index|
- video.to_json(locale, config, Kemal.config, json)
+ video.to_json(locale, json)
end
end
end
end
end
- def to_json(offset, locale, config, kemal_config, json : JSON::Builder? = nil, continuation : String? = nil)
+ def to_json(offset, locale, json : JSON::Builder? = nil, continuation : String? = nil)
if json
- to_json(offset, locale, config, kemal_config, json, continuation: continuation)
+ to_json(offset, locale, json, continuation: continuation)
else
JSON.build do |json|
- to_json(offset, locale, config, kemal_config, json, continuation: continuation)
+ to_json(offset, locale, json, continuation: continuation)
end
end
end
- db_mapping({
- title: String,
- id: String,
- author: String,
- author_thumbnail: String,
- ucid: String,
- description_html: String,
- video_count: Int32,
- views: Int64,
- updated: Time,
- thumbnail: String?,
- })
-
def privacy
PlaylistPrivacy::Public
end
+
+ def description_html
+ HTML.escape(self.description).gsub("\n", "<br>")
+ end
end
enum PlaylistPrivacy
@@ -172,7 +176,30 @@ enum PlaylistPrivacy
end
struct InvidiousPlaylist
- def to_json(offset, locale, config, kemal_config, json : JSON::Builder, continuation : String? = nil)
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property description : String = ""
+ property video_count : Int32
+ property created : Time
+ property updated : Time
+
+ @[DB::Field(converter: InvidiousPlaylist::PlaylistPrivacyConverter)]
+ property privacy : PlaylistPrivacy = PlaylistPrivacy::Private
+ property index : Array(Int64)
+
+ @[DB::Field(ignore: true)]
+ property thumbnail_id : String?
+
+ module PlaylistPrivacyConverter
+ def self.from_rs(rs)
+ return PlaylistPrivacy.parse(String.new(rs.read(Slice(UInt8))))
+ end
+ end
+
+ def to_json(offset, locale, json : JSON::Builder, continuation : String? = nil)
json.object do
json.field "type", "invidiousPlaylist"
json.field "title", self.title
@@ -195,43 +222,23 @@ struct InvidiousPlaylist
json.array do
videos = get_playlist_videos(PG_DB, self, offset: offset, locale: locale, continuation: continuation)
videos.each_with_index do |video, index|
- video.to_json(locale, config, Kemal.config, json, offset + index)
+ video.to_json(locale, json, offset + index)
end
end
end
end
end
- def to_json(offset, locale, config, kemal_config, json : JSON::Builder? = nil, continuation : String? = nil)
+ def to_json(offset, locale, json : JSON::Builder? = nil, continuation : String? = nil)
if json
- to_json(offset, locale, config, kemal_config, json, continuation: continuation)
+ to_json(offset, locale, json, continuation: continuation)
else
JSON.build do |json|
- to_json(offset, locale, config, kemal_config, json, continuation: continuation)
+ to_json(offset, locale, json, continuation: continuation)
end
end
end
- property thumbnail_id
-
- module PlaylistPrivacyConverter
- def self.from_rs(rs)
- return PlaylistPrivacy.parse(String.new(rs.read(Slice(UInt8))))
- end
- end
-
- db_mapping({
- title: String,
- id: String,
- author: String,
- description: {type: String, default: ""},
- video_count: Int32,
- created: Time,
- updated: Time,
- privacy: {type: PlaylistPrivacy, default: PlaylistPrivacy::Private, converter: PlaylistPrivacyConverter},
- index: Array(Int64),
- })
-
def thumbnail
@thumbnail_id ||= PG_DB.query_one?("SELECT id FROM playlist_videos WHERE plid = $1 ORDER BY array_position($2, index) LIMIT 1", self.id, self.index, as: String) || "-----------"
"/vi/#{@thumbnail_id}/mqdefault.jpg"
@@ -257,17 +264,17 @@ end
def create_playlist(db, title, privacy, user)
plid = "IVPL#{Random::Secure.urlsafe_base64(24)[0, 31]}"
- playlist = InvidiousPlaylist.new(
- title: title.byte_slice(0, 150),
- id: plid,
- author: user.email,
+ playlist = InvidiousPlaylist.new({
+ title: title.byte_slice(0, 150),
+ id: plid,
+ author: user.email,
description: "", # Max 5000 characters
video_count: 0,
- created: Time.utc,
- updated: Time.utc,
- privacy: privacy,
- index: [] of Int64,
- )
+ created: Time.utc,
+ updated: Time.utc,
+ privacy: privacy,
+ index: [] of Int64,
+ })
playlist_array = playlist.to_a
args = arg_array(playlist_array)
@@ -277,50 +284,25 @@ def create_playlist(db, title, privacy, user)
return playlist
end
-def extract_playlist(plid, nodeset, index)
- videos = [] of PlaylistVideo
-
- nodeset.each_with_index do |video, offset|
- anchor = video.xpath_node(%q(.//td[@class="pl-video-title"]))
- if !anchor
- next
- end
-
- title = anchor.xpath_node(%q(.//a)).not_nil!.content.strip(" \n")
- id = anchor.xpath_node(%q(.//a)).not_nil!["href"].lchop("/watch?v=")[0, 11]
-
- anchor = anchor.xpath_node(%q(.//div[@class="pl-video-owner"]/a))
- if anchor
- author = anchor.content
- ucid = anchor["href"].split("/")[2]
- else
- author = ""
- ucid = ""
- end
+def subscribe_playlist(db, user, playlist)
+ playlist = InvidiousPlaylist.new({
+ title: playlist.title.byte_slice(0, 150),
+ id: playlist.id,
+ author: user.email,
+ description: "", # Max 5000 characters
+ video_count: playlist.video_count,
+ created: Time.utc,
+ updated: playlist.updated,
+ privacy: PlaylistPrivacy::Private,
+ index: [] of Int64,
+ })
- anchor = video.xpath_node(%q(.//td[@class="pl-video-time"]/div/div[1]))
- if anchor && !anchor.content.empty?
- length_seconds = decode_length_seconds(anchor.content)
- live_now = false
- else
- length_seconds = 0
- live_now = true
- end
+ playlist_array = playlist.to_a
+ args = arg_array(playlist_array)
- videos << PlaylistVideo.new(
- title: title,
- id: id,
- author: author,
- ucid: ucid,
- length_seconds: length_seconds,
- published: Time.utc,
- plid: plid,
- index: (index + offset).to_i64,
- live_now: live_now
- )
- end
+ db.exec("INSERT INTO playlists VALUES (#{args})", args: playlist_array)
- return videos
+ return playlist
end
def produce_playlist_url(id, index)
@@ -368,58 +350,64 @@ def fetch_playlist(plid, locale)
plid = "UU#{plid.lchop("UC")}"
end
- response = YT_POOL.client &.get("/playlist?list=#{plid}&hl=en&disable_polymer=1")
+ response = YT_POOL.client &.get("/playlist?list=#{plid}&hl=en")
if response.status_code != 200
- raise translate(locale, "Not a playlist.")
+ if response.headers["location"]?.try &.includes? "/sorry/index"
+ raise "Could not extract playlist info. Instance is likely blocked."
+ else
+ raise translate(locale, "Not a playlist.")
+ end
end
- body = response.body.gsub(/<button[^>]+><span[^>]+>\s*less\s*<img[^>]+>\n<\/span><\/button>/, "")
- document = XML.parse_html(body)
+ initial_data = extract_initial_data(response.body)
+ playlist_info = initial_data["sidebar"]?.try &.["playlistSidebarRenderer"]?.try &.["items"]?.try &.[0]["playlistSidebarPrimaryInfoRenderer"]?
- title = document.xpath_node(%q(//h1[@class="pl-header-title"]))
- if !title
- raise translate(locale, "Playlist does not exist.")
- end
- title = title.content.strip(" \n")
+ raise "Could not extract playlist info" if !playlist_info
+ title = playlist_info["title"]?.try &.["runs"][0]?.try &.["text"]?.try &.as_s || ""
- description_html = document.xpath_node(%q(//span[@class="pl-header-description-text"]/div/div[1])).try &.to_s ||
- document.xpath_node(%q(//span[@class="pl-header-description-text"])).try &.to_s || ""
+ desc_item = playlist_info["description"]?
+ description = desc_item.try &.["runs"]?.try &.as_a.map(&.["text"].as_s).join("") || desc_item.try &.["simpleText"]?.try &.as_s || ""
- playlist_thumbnail = document.xpath_node(%q(//div[@class="pl-header-thumb"]/img)).try &.["data-thumb"]? ||
- document.xpath_node(%q(//div[@class="pl-header-thumb"]/img)).try &.["src"]
+ thumbnail = playlist_info["thumbnailRenderer"]?.try &.["playlistVideoThumbnailRenderer"]?
+ .try &.["thumbnail"]["thumbnails"][0]["url"]?.try &.as_s
- # YouTube allows anonymous playlists, so most of this can be empty or optional
- anchor = document.xpath_node(%q(//ul[@class="pl-header-details"]))
- author = anchor.try &.xpath_node(%q(.//li[1]/a)).try &.content
- author ||= ""
- author_thumbnail = document.xpath_node(%q(//img[@class="channel-header-profile-image"])).try &.["src"]
- author_thumbnail ||= ""
- ucid = anchor.try &.xpath_node(%q(.//li[1]/a)).try &.["href"].split("/")[-1]
- ucid ||= ""
+ views = 0_i64
+ updated = Time.utc
+ video_count = 0
+ playlist_info["stats"]?.try &.as_a.each do |stat|
+ text = stat["runs"]?.try &.as_a.map(&.["text"].as_s).join("") || stat["simpleText"]?.try &.as_s
+ next if !text
- video_count = anchor.try &.xpath_node(%q(.//li[2])).try &.content.gsub(/\D/, "").to_i?
- video_count ||= 0
+ if text.includes? "video"
+ video_count = text.gsub(/\D/, "").to_i? || 0
+ elsif text.includes? "view"
+ views = text.gsub(/\D/, "").to_i64? || 0_i64
+ else
+ updated = decode_date(text.lchop("Last updated on ").lchop("Updated "))
+ end
+ end
- views = anchor.try &.xpath_node(%q(.//li[3])).try &.content.gsub(/\D/, "").to_i64?
- views ||= 0_i64
+ author_info = initial_data["sidebar"]?.try &.["playlistSidebarRenderer"]?.try &.["items"]?.try &.[1]["playlistSidebarSecondaryInfoRenderer"]?
+ .try &.["videoOwner"]["videoOwnerRenderer"]?
- updated = anchor.try &.xpath_node(%q(.//li[4])).try &.content.lchop("Last updated on ").lchop("Updated ").try { |date| decode_date(date) }
- updated ||= Time.utc
+ raise "Could not extract author info" if !author_info
- playlist = Playlist.new(
- title: title,
- id: plid,
- author: author,
- author_thumbnail: author_thumbnail,
- ucid: ucid,
- description_html: description_html,
- video_count: video_count,
- views: views,
- updated: updated,
- thumbnail: playlist_thumbnail,
- )
+ author_thumbnail = author_info["thumbnail"]["thumbnails"][0]["url"]?.try &.as_s || ""
+ author = author_info["title"]["runs"][0]["text"]?.try &.as_s || ""
+ ucid = author_info["title"]["runs"][0]["navigationEndpoint"]["browseEndpoint"]["browseId"]?.try &.as_s || ""
- return playlist
+ return Playlist.new({
+ title: title,
+ id: plid,
+ author: author,
+ author_thumbnail: author_thumbnail,
+ ucid: ucid,
+ description: description,
+ video_count: video_count,
+ views: views,
+ updated: updated,
+ thumbnail: thumbnail,
+ })
end
def get_playlist_videos(db, playlist, offset, locale = nil, continuation = nil)
@@ -437,35 +425,26 @@ end
def fetch_playlist_videos(plid, video_count, offset = 0, locale = nil, continuation = nil)
if continuation
- html = YT_POOL.client &.get("/watch?v=#{continuation}&list=#{plid}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999")
- html = XML.parse_html(html.body)
-
- index = html.xpath_node(%q(//span[@id="playlist-current-index"])).try &.content.to_i?.try &.- 1
- offset = index || offset
+ response = YT_POOL.client &.get("/watch?v=#{continuation}&list=#{plid}&gl=US&hl=en")
+ initial_data = extract_initial_data(response.body)
+ offset = initial_data["currentVideoEndpoint"]?.try &.["watchEndpoint"]?.try &.["index"]?.try &.as_i64 || offset
end
if video_count > 100
url = produce_playlist_url(plid, offset)
response = YT_POOL.client &.get(url)
- response = JSON.parse(response.body)
- if !response["content_html"]? || response["content_html"].as_s.empty?
- raise translate(locale, "Empty playlist")
- end
-
- document = XML.parse_html(response["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(.//tr[contains(@class, "pl-video")]))
- videos = extract_playlist(plid, nodeset, offset)
+ initial_data = JSON.parse(response.body).as_a.find(&.as_h.["response"]?).try &.as_h
elsif offset > 100
return [] of PlaylistVideo
else # Extract first page of videos
- response = YT_POOL.client &.get("/playlist?list=#{plid}&gl=US&hl=en&disable_polymer=1")
- document = XML.parse_html(response.body)
- nodeset = document.xpath_nodes(%q(.//tr[contains(@class, "pl-video")]))
-
- videos = extract_playlist(plid, nodeset, 0)
+ response = YT_POOL.client &.get("/playlist?list=#{plid}&gl=US&hl=en")
+ initial_data = extract_initial_data(response.body)
end
+ return [] of PlaylistVideo if !initial_data
+ videos = extract_playlist_videos(initial_data)
+
until videos.empty? || videos[0].index == offset
videos.shift
end
@@ -473,6 +452,45 @@ def fetch_playlist_videos(plid, video_count, offset = 0, locale = nil, continuat
return videos
end
+def extract_playlist_videos(initial_data : Hash(String, JSON::Any))
+ videos = [] of PlaylistVideo
+
+ (initial_data["contents"]?.try &.["twoColumnBrowseResultsRenderer"]["tabs"].as_a.select(&.["tabRenderer"]["selected"]?.try &.as_bool)[0]["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]["contents"][0]["playlistVideoListRenderer"]["contents"].as_a ||
+ initial_data["response"]?.try &.["continuationContents"]["playlistVideoListContinuation"]["contents"].as_a).try &.each do |item|
+ if i = item["playlistVideoRenderer"]?
+ video_id = i["navigationEndpoint"]["watchEndpoint"]["videoId"].as_s
+ plid = i["navigationEndpoint"]["watchEndpoint"]["playlistId"].as_s
+ index = i["navigationEndpoint"]["watchEndpoint"]["index"].as_i64
+
+ thumbnail = i["thumbnail"]["thumbnails"][0]["url"].as_s
+ title = i["title"].try { |t| t["simpleText"]? || t["runs"]?.try &.[0]["text"]? }.try &.as_s || ""
+ author = i["shortBylineText"]?.try &.["runs"][0]["text"].as_s || ""
+ ucid = i["shortBylineText"]?.try &.["runs"][0]["navigationEndpoint"]["browseEndpoint"]["browseId"].as_s || ""
+ length_seconds = i["lengthSeconds"]?.try &.as_s.to_i
+ live = false
+
+ if !length_seconds
+ live = true
+ length_seconds = 0
+ end
+
+ videos << PlaylistVideo.new({
+ title: title,
+ id: video_id,
+ author: author,
+ ucid: ucid,
+ length_seconds: length_seconds,
+ published: Time.utc,
+ plid: plid,
+ live_now: live,
+ index: index,
+ })
+ end
+ end
+
+ return videos
+end
+
def template_playlist(playlist)
html = <<-END_HTML
<h3>
diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr
new file mode 100644
index 00000000..c6e6667e
--- /dev/null
+++ b/src/invidious/routes/base_route.cr
@@ -0,0 +1,9 @@
+abstract class Invidious::Routes::BaseRoute
+ private getter config : Config
+ private getter logger : Invidious::LogHandler
+
+ def initialize(@config, @logger)
+ end
+
+ abstract def handle(env)
+end
diff --git a/src/invidious/routes/embed/index.cr b/src/invidious/routes/embed/index.cr
new file mode 100644
index 00000000..79c91d86
--- /dev/null
+++ b/src/invidious/routes/embed/index.cr
@@ -0,0 +1,27 @@
+class Invidious::Routes::Embed::Index < Invidious::Routes::BaseRoute
+ def handle(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+
+ if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
+ begin
+ playlist = get_playlist(PG_DB, plid, locale: locale)
+ offset = env.params.query["index"]?.try &.to_i? || 0
+ videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
+ rescue ex
+ error_message = ex.message
+ env.response.status_code = 500
+ return templated "error"
+ end
+
+ url = "/embed/#{videos[0].id}?#{env.params.query}"
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query}"
+ end
+ else
+ url = "/"
+ end
+
+ env.redirect url
+ end
+end
diff --git a/src/invidious/routes/embed/show.cr b/src/invidious/routes/embed/show.cr
new file mode 100644
index 00000000..23c2b86f
--- /dev/null
+++ b/src/invidious/routes/embed/show.cr
@@ -0,0 +1,174 @@
+class Invidious::Routes::Embed::Show < Invidious::Routes::BaseRoute
+ def handle(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ id = env.params.url["id"]
+
+ plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
+ continuation = process_continuation(PG_DB, env.params.query, plid, id)
+
+ if md = env.params.query["playlist"]?
+ .try &.match(/[a-zA-Z0-9_-]{11}(,[a-zA-Z0-9_-]{11})*/)
+ video_series = md[0].split(",")
+ env.params.query.delete("playlist")
+ end
+
+ preferences = env.get("preferences").as(Preferences)
+
+ if id.includes?("%20") || id.includes?("+") || env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
+ id = env.params.url["id"].gsub("%20", "").delete("+")
+
+ url = "/embed/#{id}"
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query.to_s.gsub("%20", "").delete("+")}"
+ end
+
+ return env.redirect url
+ end
+
+ # YouTube embed supports `videoseries` with either `list=PLID`
+ # or `playlist=VIDEO_ID,VIDEO_ID`
+ case id
+ when "videoseries"
+ url = ""
+
+ if plid
+ begin
+ playlist = get_playlist(PG_DB, plid, locale: locale)
+ offset = env.params.query["index"]?.try &.to_i? || 0
+ videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
+ rescue ex
+ error_message = ex.message
+ env.response.status_code = 500
+ return templated "error"
+ end
+
+ url = "/embed/#{videos[0].id}"
+ elsif video_series
+ url = "/embed/#{video_series.shift}"
+ env.params.query["playlist"] = video_series.join(",")
+ else
+ return env.redirect "/"
+ end
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query}"
+ end
+
+ return env.redirect url
+ when "live_stream"
+ response = YT_POOL.client &.get("/embed/live_stream?channel=#{env.params.query["channel"]? || ""}")
+ video_id = response.body.match(/"video_id":"(?<video_id>[a-zA-Z0-9_-]{11})"/).try &.["video_id"]
+
+ env.params.query.delete_all("channel")
+
+ if !video_id || video_id == "live_stream"
+ error_message = "Video is unavailable."
+ return templated "error"
+ end
+
+ url = "/embed/#{video_id}"
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query}"
+ end
+
+ return env.redirect url
+ when id.size > 11
+ url = "/embed/#{id[0, 11]}"
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query}"
+ end
+
+ return env.redirect url
+ else nil # Continue
+ end
+
+ params = process_video_params(env.params.query, preferences)
+
+ user = env.get?("user").try &.as(User)
+ if user
+ subscriptions = user.subscriptions
+ watched = user.watched
+ notifications = user.notifications
+ end
+ subscriptions ||= [] of String
+
+ begin
+ video = get_video(id, PG_DB, region: params.region)
+ rescue ex : VideoRedirect
+ return env.redirect env.request.resource.gsub(id, ex.video_id)
+ rescue ex
+ error_message = ex.message
+ env.response.status_code = 500
+ return templated "error"
+ end
+
+ if preferences.annotations_subscribed &&
+ subscriptions.includes?(video.ucid) &&
+ (env.params.query["iv_load_policy"]? || "1") == "1"
+ params.annotations = true
+ end
+
+ # if watched && !watched.includes? id
+ # PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.as(User).email)
+ # end
+
+ if notifications && notifications.includes? id
+ PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
+ env.get("user").as(User).notifications.delete(id)
+ notifications.delete(id)
+ end
+
+ fmt_stream = video.fmt_stream
+ adaptive_fmts = video.adaptive_fmts
+
+ if params.local
+ fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ end
+
+ video_streams = video.video_streams
+ audio_streams = video.audio_streams
+
+ if audio_streams.empty? && !video.live_now
+ if params.quality == "dash"
+ env.params.query.delete_all("quality")
+ return env.redirect "/embed/#{id}?#{env.params.query}"
+ elsif params.listen
+ env.params.query.delete_all("listen")
+ env.params.query["listen"] = "0"
+ return env.redirect "/embed/#{id}?#{env.params.query}"
+ end
+ end
+
+ captions = video.captions
+
+ preferred_captions = captions.select { |caption|
+ params.preferred_captions.includes?(caption.name.simpleText) ||
+ params.preferred_captions.includes?(caption.languageCode.split("-")[0])
+ }
+ preferred_captions.sort_by! { |caption|
+ (params.preferred_captions.index(caption.name.simpleText) ||
+ params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
+ }
+ captions = captions - preferred_captions
+
+ aspect_ratio = nil
+
+ thumbnail = "/vi/#{video.id}/maxres.jpg"
+
+ if params.raw
+ url = fmt_stream[0]["url"].as_s
+
+ fmt_stream.each do |fmt|
+ url = fmt["url"].as_s if fmt["quality"].as_s == params.quality
+ end
+
+ return env.redirect url
+ end
+
+ rendered "embed"
+ end
+end
diff --git a/src/invidious/routes/home.cr b/src/invidious/routes/home.cr
new file mode 100644
index 00000000..9b1bf61b
--- /dev/null
+++ b/src/invidious/routes/home.cr
@@ -0,0 +1,34 @@
+class Invidious::Routes::Home < Invidious::Routes::BaseRoute
+ def handle(env)
+ preferences = env.get("preferences").as(Preferences)
+ locale = LOCALES[preferences.locale]?
+ user = env.get? "user"
+
+ case preferences.default_home
+ when ""
+ templated "empty"
+ when "Popular"
+ templated "popular"
+ when "Trending"
+ env.redirect "/feed/trending"
+ when "Subscriptions"
+ if user
+ env.redirect "/feed/subscriptions"
+ else
+ templated "popular"
+ end
+ when "Playlists"
+ if user
+ env.redirect "/view_all_playlists"
+ else
+ templated "popular"
+ end
+ else
+ templated "empty"
+ end
+ end
+
+ private def popular_videos
+ Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
+ end
+end
diff --git a/src/invidious/routes/licenses.cr b/src/invidious/routes/licenses.cr
new file mode 100644
index 00000000..38fde7bb
--- /dev/null
+++ b/src/invidious/routes/licenses.cr
@@ -0,0 +1,6 @@
+class Invidious::Routes::Licenses < Invidious::Routes::BaseRoute
+ def handle(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ rendered "licenses"
+ end
+end
diff --git a/src/invidious/routes/privacy.cr b/src/invidious/routes/privacy.cr
new file mode 100644
index 00000000..4565c94c
--- /dev/null
+++ b/src/invidious/routes/privacy.cr
@@ -0,0 +1,6 @@
+class Invidious::Routes::Privacy < Invidious::Routes::BaseRoute
+ def handle(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ templated "privacy"
+ end
+end
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
new file mode 100644
index 00000000..4eee7793
--- /dev/null
+++ b/src/invidious/routes/watch.cr
@@ -0,0 +1,186 @@
+class Invidious::Routes::Watch < Invidious::Routes::BaseRoute
+ def handle(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ region = env.params.query["region"]?
+
+ if env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
+ url = "/watch?" + env.params.query.to_s.gsub("%20", "").delete("+")
+ return env.redirect url
+ end
+
+ if env.params.query["v"]?
+ id = env.params.query["v"]
+
+ if env.params.query["v"].empty?
+ error_message = "Invalid parameters."
+ env.response.status_code = 400
+ return templated "error"
+ end
+
+ if id.size > 11
+ url = "/watch?v=#{id[0, 11]}"
+ env.params.query.delete_all("v")
+ if env.params.query.size > 0
+ url += "&#{env.params.query}"
+ end
+
+ return env.redirect url
+ end
+ else
+ return env.redirect "/"
+ end
+
+ plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
+ continuation = process_continuation(PG_DB, env.params.query, plid, id)
+
+ nojs = env.params.query["nojs"]?
+
+ nojs ||= "0"
+ nojs = nojs == "1"
+
+ preferences = env.get("preferences").as(Preferences)
+
+ user = env.get?("user").try &.as(User)
+ if user
+ subscriptions = user.subscriptions
+ watched = user.watched
+ notifications = user.notifications
+ end
+ subscriptions ||= [] of String
+
+ params = process_video_params(env.params.query, preferences)
+ env.params.query.delete_all("listen")
+
+ begin
+ video = get_video(id, PG_DB, region: params.region)
+ rescue ex : VideoRedirect
+ return env.redirect env.request.resource.gsub(id, ex.video_id)
+ rescue ex
+ error_message = ex.message
+ env.response.status_code = 500
+ logger.puts("#{id} : #{ex.message}")
+ return templated "error"
+ end
+
+ if preferences.annotations_subscribed &&
+ subscriptions.includes?(video.ucid) &&
+ (env.params.query["iv_load_policy"]? || "1") == "1"
+ params.annotations = true
+ end
+ env.params.query.delete_all("iv_load_policy")
+
+ if watched && !watched.includes? id
+ PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.as(User).email)
+ end
+
+ if notifications && notifications.includes? id
+ PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
+ env.get("user").as(User).notifications.delete(id)
+ notifications.delete(id)
+ end
+
+ if nojs
+ if preferences
+ source = preferences.comments[0]
+ if source.empty?
+ source = preferences.comments[1]
+ end
+
+ if source == "youtube"
+ begin
+ comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
+ rescue ex
+ if preferences.comments[1] == "reddit"
+ comments, reddit_thread = fetch_reddit_comments(id)
+ comment_html = template_reddit_comments(comments, locale)
+
+ comment_html = fill_links(comment_html, "https", "www.reddit.com")
+ comment_html = replace_links(comment_html)
+ end
+ end
+ elsif source == "reddit"
+ begin
+ comments, reddit_thread = fetch_reddit_comments(id)
+ comment_html = template_reddit_comments(comments, locale)
+
+ comment_html = fill_links(comment_html, "https", "www.reddit.com")
+ comment_html = replace_links(comment_html)
+ rescue ex
+ if preferences.comments[1] == "youtube"
+ comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
+ end
+ end
+ end
+ else
+ comment_html = JSON.parse(fetch_youtube_comments(id, PG_DB, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]
+ end
+
+ comment_html ||= ""
+ end
+
+ fmt_stream = video.fmt_stream
+ adaptive_fmts = video.adaptive_fmts
+
+ if params.local
+ fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ end
+
+ video_streams = video.video_streams
+ audio_streams = video.audio_streams
+
+ # Older videos may not have audio sources available.
+ # We redirect here so they're not unplayable
+ if audio_streams.empty? && !video.live_now
+ if params.quality == "dash"
+ env.params.query.delete_all("quality")
+ env.params.query["quality"] = "medium"
+ return env.redirect "/watch?#{env.params.query}"
+ elsif params.listen
+ env.params.query.delete_all("listen")
+ env.params.query["listen"] = "0"
+ return env.redirect "/watch?#{env.params.query}"
+ end
+ end
+
+ captions = video.captions
+
+ preferred_captions = captions.select { |caption|
+ params.preferred_captions.includes?(caption.name.simpleText) ||
+ params.preferred_captions.includes?(caption.languageCode.split("-")[0])
+ }
+ preferred_captions.sort_by! { |caption|
+ (params.preferred_captions.index(caption.name.simpleText) ||
+ params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
+ }
+ captions = captions - preferred_captions
+
+ aspect_ratio = "16:9"
+
+ thumbnail = "/vi/#{video.id}/maxres.jpg"
+
+ if params.raw
+ if params.listen
+ url = audio_streams[0]["url"].as_s
+
+ audio_streams.each do |fmt|
+ if fmt["bitrate"].as_i == params.quality.rchop("k").to_i
+ url = fmt["url"].as_s
+ end
+ end
+ else
+ url = fmt_stream[0]["url"].as_s
+
+ fmt_stream.each do |fmt|
+ if fmt["quality"].as_s == params.quality
+ url = fmt["url"].as_s
+ end
+ end
+ end
+
+ return env.redirect url
+ end
+
+ templated "watch"
+ end
+end
diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr
new file mode 100644
index 00000000..c09dda38
--- /dev/null
+++ b/src/invidious/routing.cr
@@ -0,0 +1,8 @@
+module Invidious::Routing
+ macro get(path, controller)
+ get {{ path }} do |env|
+ controller_instance = {{ controller }}.new(config, logger)
+ controller_instance.handle(env)
+ end
+ end
+end
diff --git a/src/invidious/search.cr b/src/invidious/search.cr
index 92996f75..85fd024a 100644
--- a/src/invidious/search.cr
+++ b/src/invidious/search.cr
@@ -1,5 +1,20 @@
struct SearchVideo
- def to_xml(host_url, auto_generated, query_params, xml : XML::Builder)
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property ucid : String
+ property published : Time
+ property views : Int64
+ property description_html : String
+ property length_seconds : Int32
+ property live_now : Bool
+ property paid : Bool
+ property premium : Bool
+ property premiere_timestamp : Time?
+
+ def to_xml(auto_generated, query_params, xml : XML::Builder)
query_params["v"] = self.id
xml.element("entry") do
@@ -7,22 +22,22 @@ struct SearchVideo
xml.element("yt:videoId") { xml.text self.id }
xml.element("yt:channelId") { xml.text self.ucid }
xml.element("title") { xml.text self.title }
- xml.element("link", rel: "alternate", href: "#{host_url}/watch?#{query_params}")
+ xml.element("link", rel: "alternate", href: "#{HOST_URL}/watch?#{query_params}")
xml.element("author") do
if auto_generated
xml.element("name") { xml.text self.author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{self.ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" }
else
xml.element("name") { xml.text author }
- xml.element("uri") { xml.text "#{host_url}/channel/#{ucid}" }
+ xml.element("uri") { xml.text "#{HOST_URL}/channel/#{ucid}" }
end
end
xml.element("content", type: "xhtml") do
xml.element("div", xmlns: "http://www.w3.org/1999/xhtml") do
- xml.element("a", href: "#{host_url}/watch?#{query_params}") do
- xml.element("img", src: "#{host_url}/vi/#{self.id}/mqdefault.jpg")
+ xml.element("a", href: "#{HOST_URL}/watch?#{query_params}") do
+ xml.element("img", src: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg")
end
xml.element("p", style: "word-break:break-word;white-space:pre-wrap") { xml.text html_to_content(self.description_html) }
@@ -33,7 +48,7 @@ struct SearchVideo
xml.element("media:group") do
xml.element("media:title") { xml.text self.title }
- xml.element("media:thumbnail", url: "#{host_url}/vi/#{self.id}/mqdefault.jpg",
+ xml.element("media:thumbnail", url: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg",
width: "320", height: "180")
xml.element("media:description") { xml.text html_to_content(self.description_html) }
end
@@ -44,17 +59,17 @@ struct SearchVideo
end
end
- def to_xml(host_url, auto_generated, query_params, xml : XML::Builder | Nil = nil)
+ def to_xml(auto_generated, query_params, xml : XML::Builder | Nil = nil)
if xml
- to_xml(host_url, auto_generated, query_params, xml)
+ to_xml(HOST_URL, auto_generated, query_params, xml)
else
XML.build do |json|
- to_xml(host_url, auto_generated, query_params, xml)
+ to_xml(HOST_URL, auto_generated, query_params, xml)
end
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder)
+ def to_json(locale, json : JSON::Builder)
json.object do
json.field "type", "video"
json.field "title", self.title
@@ -65,7 +80,7 @@ struct SearchVideo
json.field "authorUrl", "/channel/#{self.ucid}"
json.field "videoThumbnails" do
- generate_thumbnails(json, self.id, config, kemal_config)
+ generate_thumbnails(json, self.id)
end
json.field "description", html_to_content(self.description_html)
@@ -78,45 +93,49 @@ struct SearchVideo
json.field "liveNow", self.live_now
json.field "paid", self.paid
json.field "premium", self.premium
+ json.field "isUpcoming", self.is_upcoming
+
+ if self.premiere_timestamp
+ json.field "premiereTimestamp", self.premiere_timestamp.try &.to_unix
+ end
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder | Nil = nil)
+ def to_json(locale, json : JSON::Builder | Nil = nil)
if json
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
end
end
end
- db_mapping({
- title: String,
- id: String,
- author: String,
- ucid: String,
- published: Time,
- views: Int64,
- description_html: String,
- length_seconds: Int32,
- live_now: Bool,
- paid: Bool,
- premium: Bool,
- premiere_timestamp: Time?,
- })
+ def is_upcoming
+ premiere_timestamp ? true : false
+ end
end
struct SearchPlaylistVideo
- db_mapping({
- title: String,
- id: String,
- length_seconds: Int32,
- })
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property length_seconds : Int32
end
struct SearchPlaylist
- def to_json(locale, config, kemal_config, json : JSON::Builder)
+ include DB::Serializable
+
+ property title : String
+ property id : String
+ property author : String
+ property ucid : String
+ property video_count : Int32
+ property videos : Array(SearchPlaylistVideo)
+ property thumbnail : String?
+
+ def to_json(locale, json : JSON::Builder)
json.object do
json.field "type", "playlist"
json.field "title", self.title
@@ -137,7 +156,7 @@ struct SearchPlaylist
json.field "lengthSeconds", video.length_seconds
json.field "videoThumbnails" do
- generate_thumbnails(json, video.id, config, Kemal.config)
+ generate_thumbnails(json, video.id)
end
end
end
@@ -146,29 +165,29 @@ struct SearchPlaylist
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder | Nil = nil)
+ def to_json(locale, json : JSON::Builder | Nil = nil)
if json
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
end
end
end
-
- db_mapping({
- title: String,
- id: String,
- author: String,
- ucid: String,
- video_count: Int32,
- videos: Array(SearchPlaylistVideo),
- thumbnail: String?,
- })
end
struct SearchChannel
- def to_json(locale, config, kemal_config, json : JSON::Builder)
+ include DB::Serializable
+
+ property author : String
+ property ucid : String
+ property author_thumbnail : String
+ property subscriber_count : Int32
+ property video_count : Int32
+ property description_html : String
+ property auto_generated : Bool
+
+ def to_json(locale, json : JSON::Builder)
json.object do
json.field "type", "channel"
json.field "author", self.author
@@ -198,85 +217,50 @@ struct SearchChannel
end
end
- def to_json(locale, config, kemal_config, json : JSON::Builder | Nil = nil)
+ def to_json(locale, json : JSON::Builder | Nil = nil)
if json
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, json)
+ to_json(locale, json)
end
end
end
-
- db_mapping({
- author: String,
- ucid: String,
- author_thumbnail: String,
- subscriber_count: Int32,
- video_count: Int32,
- description_html: String,
- auto_generated: Bool,
- })
end
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist
def channel_search(query, page, channel)
- response = YT_POOL.client &.get("/channel/#{channel}?disable_polymer=1&hl=en&gl=US")
- document = XML.parse_html(response.body)
- canonical = document.xpath_node(%q(//link[@rel="canonical"]))
-
- if !canonical
- response = YT_POOL.client &.get("/c/#{channel}?disable_polymer=1&hl=en&gl=US")
- document = XML.parse_html(response.body)
- canonical = document.xpath_node(%q(//link[@rel="canonical"]))
- end
+ response = YT_POOL.client &.get("/channel/#{channel}?hl=en&gl=US")
+ response = YT_POOL.client &.get("/user/#{channel}?hl=en&gl=US") if response.headers["location"]?
+ response = YT_POOL.client &.get("/c/#{channel}?hl=en&gl=US") if response.headers["location"]?
- if !canonical
- response = YT_POOL.client &.get("/user/#{channel}?disable_polymer=1&hl=en&gl=US")
- document = XML.parse_html(response.body)
- canonical = document.xpath_node(%q(//link[@rel="canonical"]))
- end
+ ucid = response.body.match(/\\"channelId\\":\\"(?<ucid>[^\\]+)\\"/).try &.["ucid"]?
- if !canonical
- return 0, [] of SearchItem
- end
-
- ucid = canonical["href"].split("/")[-1]
+ return 0, [] of SearchItem if !ucid
url = produce_channel_search_url(ucid, query, page)
response = YT_POOL.client &.get(url)
- json = JSON.parse(response.body)
-
- if json["content_html"]? && !json["content_html"].as_s.empty?
- document = XML.parse_html(json["content_html"].as_s)
- nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
-
- count = nodeset.size
- items = extract_items(nodeset)
- else
- count = 0
- items = [] of SearchItem
- end
+ initial_data = JSON.parse(response.body).as_a.find &.["response"]?
+ return 0, [] of SearchItem if !initial_data
+ author = initial_data["response"]?.try &.["metadata"]?.try &.["channelMetadataRenderer"]?.try &.["title"]?.try &.as_s
+ items = extract_items(initial_data.as_h, author, ucid)
- return count, items
+ return items.size, items
end
def search(query, page = 1, search_params = produce_search_params(content_type: "all"), region = nil)
- if query.empty?
- return {0, [] of SearchItem}
- end
+ return 0, [] of SearchItem if query.empty?
- html = YT_POOL.client(region, &.get("/results?q=#{URI.encode_www_form(query)}&page=#{page}&sp=#{search_params}&hl=en&disable_polymer=1").body)
- if html.empty?
- return {0, [] of SearchItem}
- end
+ body = YT_POOL.client(region, &.get("/results?q=#{URI.encode_www_form(query)}&page=#{page}&sp=#{search_params}&hl=en").body)
+ return 0, [] of SearchItem if body.empty?
+
+ initial_data = extract_initial_data(body)
+ items = extract_items(initial_data)
- html = XML.parse_html(html)
- nodeset = html.xpath_nodes(%q(//ol[@class="item-section"]/li))
- items = extract_items(nodeset)
+ # initial_data["estimatedResults"]?.try &.as_s.to_i64
- return {nodeset.size, items}
+ return items.size, items
end
def produce_search_params(sort : String = "relevance", date : String = "", content_type : String = "",
@@ -310,6 +294,7 @@ def produce_search_params(sort : String = "relevance", date : String = "", conte
object["2:embedded"].as(Hash)["1:varint"] = 4_i64
when "year"
object["2:embedded"].as(Hash)["1:varint"] = 5_i64
+ else nil # Ignore
end
case content_type
@@ -334,6 +319,7 @@ def produce_search_params(sort : String = "relevance", date : String = "", conte
object["2:embedded"].as(Hash)["3:varint"] = 1_i64
when "long"
object["2:embedded"].as(Hash)["3:varint"] = 2_i64
+ else nil # Ignore
end
features.each do |feature|
@@ -358,6 +344,7 @@ def produce_search_params(sort : String = "relevance", date : String = "", conte
object["2:embedded"].as(Hash)["23:varint"] = 1_i64
when "hdr"
object["2:embedded"].as(Hash)["25:varint"] = 1_i64
+ else nil # Ignore
end
end
@@ -379,12 +366,9 @@ def produce_channel_search_url(ucid, query, page)
"2:string" => ucid,
"3:base64" => {
"2:string" => "search",
- "6:varint" => 2_i64,
"7:varint" => 1_i64,
- "12:varint" => 1_i64,
- "13:string" => "",
- "23:varint" => 0_i64,
"15:string" => "#{page}",
+ "23:varint" => 0_i64,
},
"11:string" => query,
},
diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr
index 3a9c6935..8d078387 100644
--- a/src/invidious/trending.cr
+++ b/src/invidious/trending.cr
@@ -1,7 +1,4 @@
def fetch_trending(trending_type, region, locale)
- headers = HTTP::Headers.new
- headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
-
region ||= "US"
region = region.upcase
@@ -11,7 +8,7 @@ def fetch_trending(trending_type, region, locale)
if trending_type && trending_type != "Default"
trending_type = trending_type.downcase.capitalize
- response = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en", headers).body
+ response = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body
initial_data = extract_initial_data(response)
@@ -21,51 +18,28 @@ def fetch_trending(trending_type, region, locale)
if url
url["channelListSubMenuAvatarRenderer"]["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"]
url = url["channelListSubMenuAvatarRenderer"]["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"].as_s
- url += "&disable_polymer=1&gl=#{region}&hl=en"
+ url = "#{url}&gl=#{region}&hl=en"
trending = YT_POOL.client &.get(url).body
plid = extract_plid(url)
else
- trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en&disable_polymer=1").body
+ trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body
end
else
- trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en&disable_polymer=1").body
+ trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body
end
- trending = XML.parse_html(trending)
- nodeset = trending.xpath_nodes(%q(//ul/li[@class="expanded-shelf-content-item-wrapper"]))
- trending = extract_videos(nodeset)
+ initial_data = extract_initial_data(trending)
+ trending = extract_videos(initial_data)
return {trending, plid}
end
def extract_plid(url)
- wrapper = HTTP::Params.parse(URI.parse(url).query.not_nil!)["bp"]
-
- wrapper = URI.decode_www_form(wrapper)
- wrapper = Base64.decode(wrapper)
-
- # 0xe2 0x02 0x2e
- wrapper += 3
-
- # 0x0a
- wrapper += 1
-
- # Looks like "/m/[a-z0-9]{5}", not sure what it does here
-
- item_size = wrapper[0]
- wrapper += 1
- item = wrapper[0, item_size]
- wrapper += item.size
-
- # 0x12
- wrapper += 1
-
- plid_size = wrapper[0]
- wrapper += 1
- plid = wrapper[0, plid_size]
- wrapper += plid.size
-
- plid = String.new(plid)
-
- return plid
+ return url.try { |i| URI.parse(i).query }
+ .try { |i| HTTP::Params.parse(i)["bp"] }
+ .try { |i| URI.decode_www_form(i) }
+ .try { |i| Base64.decode(i) }
+ .try { |i| IO::Memory.new(i) }
+ .try { |i| Protodec::Any.parse(i) }
+ .try &.["44:0:embedded"]?.try &.["2:1:string"]?.try &.as_s
end
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index afb100f2..46bf8865 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -4,6 +4,20 @@ require "crypto/bcrypt/password"
MATERIALIZED_VIEW_SQL = ->(email : String) { "SELECT cv.* FROM channel_videos cv WHERE EXISTS (SELECT subscriptions FROM users u WHERE cv.ucid = ANY (u.subscriptions) AND u.email = E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}') ORDER BY published DESC" }
struct User
+ include DB::Serializable
+
+ property updated : Time
+ property notifications : Array(String)
+ property subscriptions : Array(String)
+ property email : String
+
+ @[DB::Field(converter: User::PreferencesConverter)]
+ property preferences : Preferences
+ property password : String?
+ property token : String
+ property watched : Array(String)
+ property feed_needs_update : Bool?
+
module PreferencesConverter
def self.from_rs(rs)
begin
@@ -13,31 +27,78 @@ struct User
end
end
end
-
- db_mapping({
- updated: Time,
- notifications: Array(String),
- subscriptions: Array(String),
- email: String,
- preferences: {
- type: Preferences,
- converter: PreferencesConverter,
- },
- password: String?,
- token: String,
- watched: Array(String),
- feed_needs_update: Bool?,
- })
end
struct Preferences
- module ProcessString
+ include JSON::Serializable
+ include YAML::Serializable
+
+ property annotations : Bool = CONFIG.default_user_preferences.annotations
+ property annotations_subscribed : Bool = CONFIG.default_user_preferences.annotations_subscribed
+ property autoplay : Bool = CONFIG.default_user_preferences.autoplay
+
+ @[JSON::Field(converter: Preferences::StringToArray)]
+ @[YAML::Field(converter: Preferences::StringToArray)]
+ property captions : Array(String) = CONFIG.default_user_preferences.captions
+
+ @[JSON::Field(converter: Preferences::StringToArray)]
+ @[YAML::Field(converter: Preferences::StringToArray)]
+ property comments : Array(String) = CONFIG.default_user_preferences.comments
+ property continue : Bool = CONFIG.default_user_preferences.continue
+ property continue_autoplay : Bool = CONFIG.default_user_preferences.continue_autoplay
+
+ @[JSON::Field(converter: Preferences::BoolToString)]
+ @[YAML::Field(converter: Preferences::BoolToString)]
+ property dark_mode : String = CONFIG.default_user_preferences.dark_mode
+ property latest_only : Bool = CONFIG.default_user_preferences.latest_only
+ property listen : Bool = CONFIG.default_user_preferences.listen
+ property local : Bool = CONFIG.default_user_preferences.local
+
+ @[JSON::Field(converter: Preferences::ProcessString)]
+ property locale : String = CONFIG.default_user_preferences.locale
+
+ @[JSON::Field(converter: Preferences::ClampInt)]
+ property max_results : Int32 = CONFIG.default_user_preferences.max_results
+ property notifications_only : Bool = CONFIG.default_user_preferences.notifications_only
+
+ @[JSON::Field(converter: Preferences::ProcessString)]
+ property player_style : String = CONFIG.default_user_preferences.player_style
+
+ @[JSON::Field(converter: Preferences::ProcessString)]
+ property quality : String = CONFIG.default_user_preferences.quality
+ property default_home : String = CONFIG.default_user_preferences.default_home
+ property feed_menu : Array(String) = CONFIG.default_user_preferences.feed_menu
+ property related_videos : Bool = CONFIG.default_user_preferences.related_videos
+
+ @[JSON::Field(converter: Preferences::ProcessString)]
+ property sort : String = CONFIG.default_user_preferences.sort
+ property speed : Float32 = CONFIG.default_user_preferences.speed
+ property thin_mode : Bool = CONFIG.default_user_preferences.thin_mode
+ property unseen_only : Bool = CONFIG.default_user_preferences.unseen_only
+ property video_loop : Bool = CONFIG.default_user_preferences.video_loop
+ property volume : Int32 = CONFIG.default_user_preferences.volume
+
+ module BoolToString
def self.to_json(value : String, json : JSON::Builder)
json.string value
end
def self.from_json(value : JSON::PullParser) : String
- HTML.escape(value.read_string[0, 100])
+ begin
+ result = value.read_string
+
+ if result.empty?
+ CONFIG.default_user_preferences.dark_mode
+ else
+ result
+ end
+ rescue ex
+ if value.read_bool
+ "dark"
+ else
+ "light"
+ end
+ end
end
def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
@@ -45,7 +106,20 @@ struct Preferences
end
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
- HTML.escape(node.value[0, 100])
+ unless node.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected scalar, not #{node.class}"
+ end
+
+ case node.value
+ when "true"
+ "dark"
+ when "false"
+ "light"
+ when ""
+ CONFIG.default_user_preferences.dark_mode
+ else
+ node.value
+ end
end
end
@@ -67,33 +141,130 @@ struct Preferences
end
end
- json_mapping({
- annotations: {type: Bool, default: CONFIG.default_user_preferences.annotations},
- annotations_subscribed: {type: Bool, default: CONFIG.default_user_preferences.annotations_subscribed},
- autoplay: {type: Bool, default: CONFIG.default_user_preferences.autoplay},
- captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: ConfigPreferences::StringToArray},
- comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: ConfigPreferences::StringToArray},
- continue: {type: Bool, default: CONFIG.default_user_preferences.continue},
- continue_autoplay: {type: Bool, default: CONFIG.default_user_preferences.continue_autoplay},
- dark_mode: {type: String, default: CONFIG.default_user_preferences.dark_mode, converter: ConfigPreferences::BoolToString},
- latest_only: {type: Bool, default: CONFIG.default_user_preferences.latest_only},
- listen: {type: Bool, default: CONFIG.default_user_preferences.listen},
- local: {type: Bool, default: CONFIG.default_user_preferences.local},
- locale: {type: String, default: CONFIG.default_user_preferences.locale, converter: ProcessString},
- max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results, converter: ClampInt},
- notifications_only: {type: Bool, default: CONFIG.default_user_preferences.notifications_only},
- player_style: {type: String, default: CONFIG.default_user_preferences.player_style, converter: ProcessString},
- quality: {type: String, default: CONFIG.default_user_preferences.quality, converter: ProcessString},
- default_home: {type: String, default: CONFIG.default_user_preferences.default_home},
- feed_menu: {type: Array(String), default: CONFIG.default_user_preferences.feed_menu},
- related_videos: {type: Bool, default: CONFIG.default_user_preferences.related_videos},
- sort: {type: String, default: CONFIG.default_user_preferences.sort, converter: ProcessString},
- speed: {type: Float32, default: CONFIG.default_user_preferences.speed},
- thin_mode: {type: Bool, default: CONFIG.default_user_preferences.thin_mode},
- unseen_only: {type: Bool, default: CONFIG.default_user_preferences.unseen_only},
- video_loop: {type: Bool, default: CONFIG.default_user_preferences.video_loop},
- volume: {type: Int32, default: CONFIG.default_user_preferences.volume},
- })
+ module FamilyConverter
+ def self.to_yaml(value : Socket::Family, yaml : YAML::Nodes::Builder)
+ case value
+ when Socket::Family::UNSPEC
+ yaml.scalar nil
+ when Socket::Family::INET
+ yaml.scalar "ipv4"
+ when Socket::Family::INET6
+ yaml.scalar "ipv6"
+ when Socket::Family::UNIX
+ raise "Invalid socket family #{value}"
+ end
+ end
+
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Socket::Family
+ if node.is_a?(YAML::Nodes::Scalar)
+ case node.value.downcase
+ when "ipv4"
+ Socket::Family::INET
+ when "ipv6"
+ Socket::Family::INET6
+ else
+ Socket::Family::UNSPEC
+ end
+ else
+ node.raise "Expected scalar, not #{node.class}"
+ end
+ end
+ end
+
+ module ProcessString
+ def self.to_json(value : String, json : JSON::Builder)
+ json.string value
+ end
+
+ def self.from_json(value : JSON::PullParser) : String
+ HTML.escape(value.read_string[0, 100])
+ end
+
+ def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
+ yaml.scalar value
+ end
+
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
+ HTML.escape(node.value[0, 100])
+ end
+ end
+
+ module StringToArray
+ def self.to_json(value : Array(String), json : JSON::Builder)
+ json.array do
+ value.each do |element|
+ json.string element
+ end
+ end
+ end
+
+ def self.from_json(value : JSON::PullParser) : Array(String)
+ begin
+ result = [] of String
+ value.read_array do
+ result << HTML.escape(value.read_string[0, 100])
+ end
+ rescue ex
+ result = [HTML.escape(value.read_string[0, 100]), ""]
+ end
+
+ result
+ end
+
+ def self.to_yaml(value : Array(String), yaml : YAML::Nodes::Builder)
+ yaml.sequence do
+ value.each do |element|
+ yaml.scalar element
+ end
+ end
+ end
+
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Array(String)
+ begin
+ unless node.is_a?(YAML::Nodes::Sequence)
+ node.raise "Expected sequence, not #{node.class}"
+ end
+
+ result = [] of String
+ node.nodes.each do |item|
+ unless item.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected scalar, not #{item.class}"
+ end
+
+ result << HTML.escape(item.value[0, 100])
+ end
+ rescue ex
+ if node.is_a?(YAML::Nodes::Scalar)
+ result = [HTML.escape(node.value[0, 100]), ""]
+ else
+ result = ["", ""]
+ end
+ end
+
+ result
+ end
+ end
+
+ module StringToCookies
+ def self.to_yaml(value : HTTP::Cookies, yaml : YAML::Nodes::Builder)
+ (value.map { |c| "#{c.name}=#{c.value}" }).join("; ").to_yaml(yaml)
+ end
+
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : HTTP::Cookies
+ unless node.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected scalar, not #{node.class}"
+ end
+
+ cookies = HTTP::Cookies.new
+ node.value.split(";").each do |cookie|
+ next if cookie.strip.empty?
+ name, value = cookie.split("=", 2)
+ cookies << HTTP::Cookie.new(name.strip, value.strip)
+ end
+
+ cookies
+ end
+ end
end
def get_user(sid, headers, db, refresh = true)
@@ -103,8 +274,7 @@ def get_user(sid, headers, db, refresh = true)
if refresh && Time.utc - user.updated > 1.minute
user, sid = fetch_user(sid, headers, db)
user_array = user.to_a
-
- user_array[4] = user_array[4].to_json
+ user_array[4] = user_array[4].to_json # User preferences
args = arg_array(user_array)
db.exec("INSERT INTO users VALUES (#{args}) \
@@ -122,8 +292,7 @@ def get_user(sid, headers, db, refresh = true)
else
user, sid = fetch_user(sid, headers, db)
user_array = user.to_a
-
- user_array[4] = user_array[4].to_json
+ user_array[4] = user_array[4].to_json # User preferences
args = arg_array(user.to_a)
db.exec("INSERT INTO users VALUES (#{args}) \
@@ -166,7 +335,17 @@ def fetch_user(sid, headers, db)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new(Time.utc, [] of String, channels, email, CONFIG.default_user_preferences, nil, token, [] of String, true)
+ user = User.new({
+ updated: Time.utc,
+ notifications: [] of String,
+ subscriptions: channels,
+ email: email,
+ preferences: Preferences.new(CONFIG.default_user_preferences.to_tuple),
+ password: nil,
+ token: token,
+ watched: [] of String,
+ feed_needs_update: true,
+ })
return user, sid
end
@@ -174,7 +353,17 @@ def create_user(sid, email, password)
password = Crypto::Bcrypt::Password.create(password, cost: 10)
token = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
- user = User.new(Time.utc, [] of String, [] of String, email, CONFIG.default_user_preferences, password.to_s, token, [] of String, true)
+ user = User.new({
+ updated: Time.utc,
+ notifications: [] of String,
+ subscriptions: [] of String,
+ email: email,
+ preferences: Preferences.new(CONFIG.default_user_preferences.to_tuple),
+ password: password.to_s,
+ token: token,
+ watched: [] of String,
+ feed_needs_update: true,
+ })
return user, sid
end
@@ -267,7 +456,7 @@ def subscribe_ajax(channel_id, action, env_headers)
end
headers = cookies.add_request_headers(headers)
- if match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[A-Za-z0-9\_\-\=]+)"/)
+ if match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[^"]+)"/)
session_token = match["session_token"]
headers["content-type"] = "application/x-www-form-urlencoded"
@@ -281,48 +470,6 @@ def subscribe_ajax(channel_id, action, env_headers)
end
end
-# TODO: Playlist stub, sync with YouTube for Google accounts
-# def playlist_ajax(video_ids, source_playlist_id, name, privacy, action, env_headers)
-# headers = HTTP::Headers.new
-# headers["Cookie"] = env_headers["Cookie"]
-#
-# html = YT_POOL.client &.get("/view_all_playlists?disable_polymer=1", headers)
-#
-# cookies = HTTP::Cookies.from_headers(headers)
-# html.cookies.each do |cookie|
-# if {"VISITOR_INFO1_LIVE", "YSC", "SIDCC"}.includes? cookie.name
-# if cookies[cookie.name]?
-# cookies[cookie.name] = cookie
-# else
-# cookies << cookie
-# end
-# end
-# end
-# headers = cookies.add_request_headers(headers)
-#
-# if match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[A-Za-z0-9\_\-\=]+)"/)
-# session_token = match["session_token"]
-#
-# headers["content-type"] = "application/x-www-form-urlencoded"
-#
-# post_req = {
-# video_ids: [] of String,
-# source_playlist_id: "",
-# n: name,
-# p: privacy,
-# session_token: session_token,
-# }
-# post_url = "/playlist_ajax?#{action}=1"
-#
-# response = client.post(post_url, headers, form: post_req)
-# if response.status_code == 200
-# return JSON.parse(response.body)["result"]["playlistId"].as_s
-# else
-# return nil
-# end
-# end
-# end
-
def get_subscription_feed(db, user, max_results = 40, page = 1)
limit = max_results.clamp(0, MAX_ITEMS_PER_PAGE)
offset = (page - 1) * limit
@@ -350,6 +497,7 @@ def get_subscription_feed(db, user, max_results = 40, page = 1)
notifications.sort_by! { |video| video.author }
when "channel name - reverse"
notifications.sort_by! { |video| video.author }.reverse!
+ else nil # Ignore
end
else
if user.preferences.latest_only
@@ -398,6 +546,7 @@ def get_subscription_feed(db, user, max_results = 40, page = 1)
videos.sort_by! { |video| video.author }
when "channel name - reverse"
videos.sort_by! { |video| video.author }.reverse!
+ else nil # Ignore
end
notifications = PG_DB.query_one("SELECT notifications FROM users WHERE email = $1", user.email, as: Array(String))
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index e9aee092..8e314fe0 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -222,53 +222,73 @@ VIDEO_FORMATS = {
}
struct VideoPreferences
- json_mapping({
- annotations: Bool,
- autoplay: Bool,
- comments: Array(String),
- continue: Bool,
- continue_autoplay: Bool,
- controls: Bool,
- listen: Bool,
- local: Bool,
- preferred_captions: Array(String),
- player_style: String,
- quality: String,
- raw: Bool,
- region: String?,
- related_videos: Bool,
- speed: (Float32 | Float64),
- video_end: (Float64 | Int32),
- video_loop: Bool,
- video_start: (Float64 | Int32),
- volume: Int32,
- })
+ include JSON::Serializable
+
+ property annotations : Bool
+ property autoplay : Bool
+ property comments : Array(String)
+ property continue : Bool
+ property continue_autoplay : Bool
+ property controls : Bool
+ property listen : Bool
+ property local : Bool
+ property preferred_captions : Array(String)
+ property player_style : String
+ property quality : String
+ property raw : Bool
+ property region : String?
+ property related_videos : Bool
+ property speed : Float32 | Float64
+ property video_end : Float64 | Int32
+ property video_loop : Bool
+ property video_start : Float64 | Int32
+ property volume : Int32
end
struct Video
- property player_json : JSON::Any?
- property recommended_json : JSON::Any?
+ include DB::Serializable
+
+ property id : String
+
+ @[DB::Field(converter: Video::JSONConverter)]
+ property info : Hash(String, JSON::Any)
+ property updated : Time
+
+ @[DB::Field(ignore: true)]
+ property captions : Array(Caption)?
+
+ @[DB::Field(ignore: true)]
+ property adaptive_fmts : Array(Hash(String, JSON::Any))?
+
+ @[DB::Field(ignore: true)]
+ property fmt_stream : Array(Hash(String, JSON::Any))?
+
+ @[DB::Field(ignore: true)]
+ property description : String?
- module HTTPParamConverter
+ module JSONConverter
def self.from_rs(rs)
- HTTP::Params.parse(rs.read(String))
+ JSON.parse(rs.read(String)).as_h
end
end
- def to_json(locale, config, kemal_config, decrypt_function, json : JSON::Builder)
+ def to_json(locale, json : JSON::Builder)
json.object do
json.field "type", "video"
json.field "title", self.title
json.field "videoId", self.id
+
+ json.field "error", info["reason"] if info["reason"]?
+
json.field "videoThumbnails" do
- generate_thumbnails(json, self.id, config, kemal_config)
+ generate_thumbnails(json, self.id)
end
json.field "storyboards" do
- generate_storyboards(json, self.id, self.storyboards, config, kemal_config)
+ generate_storyboards(json, self.id, self.storyboards)
end
- json.field "description", html_to_content(self.description_html)
+ json.field "description", self.description
json.field "descriptionHtml", self.description_html
json.field "published", self.published.to_unix
json.field "publishedText", translate(locale, "`x` ago", recode_date(self.published, locale))
@@ -307,43 +327,39 @@ struct Video
json.field "lengthSeconds", self.length_seconds
json.field "allowRatings", self.allow_ratings
- json.field "rating", self.info["avg_rating"].to_f32
+ json.field "rating", self.average_rating
json.field "isListed", self.is_listed
json.field "liveNow", self.live_now
json.field "isUpcoming", self.is_upcoming
if self.premiere_timestamp
- json.field "premiereTimestamp", self.premiere_timestamp.not_nil!.to_unix
+ json.field "premiereTimestamp", self.premiere_timestamp.try &.to_unix
end
- if player_response["streamingData"]?.try &.["hlsManifestUrl"]?
- host_url = make_host_url(config, kemal_config)
-
- hlsvp = player_response["streamingData"]["hlsManifestUrl"].as_s
- hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", host_url)
-
+ if hlsvp = self.hls_manifest_url
+ hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", HOST_URL)
json.field "hlsUrl", hlsvp
end
- json.field "dashUrl", "#{make_host_url(config, kemal_config)}/api/manifest/dash/id/#{id}"
+ json.field "dashUrl", "#{HOST_URL}/api/manifest/dash/id/#{id}"
json.field "adaptiveFormats" do
json.array do
- self.adaptive_fmts(decrypt_function).each do |fmt|
+ self.adaptive_fmts.each do |fmt|
json.object do
- json.field "index", fmt["index"]
- json.field "bitrate", fmt["bitrate"]
- json.field "init", fmt["init"]
+ json.field "index", "#{fmt["indexRange"]["start"]}-#{fmt["indexRange"]["end"]}"
+ json.field "bitrate", fmt["bitrate"].as_i.to_s
+ json.field "init", "#{fmt["initRange"]["start"]}-#{fmt["initRange"]["end"]}"
json.field "url", fmt["url"]
- json.field "itag", fmt["itag"]
- json.field "type", fmt["type"]
- json.field "clen", fmt["clen"]
- json.field "lmt", fmt["lmt"]
- json.field "projectionType", fmt["projection_type"]
+ json.field "itag", fmt["itag"].as_i.to_s
+ json.field "type", fmt["mimeType"]
+ json.field "clen", fmt["contentLength"]
+ json.field "lmt", fmt["lastModified"]
+ json.field "projectionType", fmt["projectionType"]
fmt_info = itag_to_metadata?(fmt["itag"])
if fmt_info
- fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.to_i || 30
+ fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.as_i || 30
json.field "fps", fps
json.field "container", fmt_info["ext"]
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
@@ -369,16 +385,16 @@ struct Video
json.field "formatStreams" do
json.array do
- self.fmt_stream(decrypt_function).each do |fmt|
+ self.fmt_stream.each do |fmt|
json.object do
json.field "url", fmt["url"]
- json.field "itag", fmt["itag"]
- json.field "type", fmt["type"]
+ json.field "itag", fmt["itag"].as_i.to_s
+ json.field "type", fmt["mimeType"]
json.field "quality", fmt["quality"]
fmt_info = itag_to_metadata?(fmt["itag"])
if fmt_info
- fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.to_i || 30
+ fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.as_i || 30
json.field "fps", fps
json.field "container", fmt_info["ext"]
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
@@ -416,15 +432,13 @@ struct Video
json.field "recommendedVideos" do
json.array do
- self.info["rvs"]?.try &.split(",").each do |rv|
- rv = HTTP::Params.parse(rv)
-
+ self.related_videos.each do |rv|
if rv["id"]?
json.object do
json.field "videoId", rv["id"]
json.field "title", rv["title"]
json.field "videoThumbnails" do
- generate_thumbnails(json, rv["id"], config, kemal_config)
+ generate_thumbnails(json, rv["id"])
end
json.field "author", rv["author"]
@@ -437,7 +451,7 @@ struct Video
qualities.each do |quality|
json.object do
- json.field "url", rv["author_thumbnail"].gsub(/s\d+-/, "s#{quality}-")
+ json.field "url", rv["author_thumbnail"]?.try &.gsub(/s\d+-/, "s#{quality}-")
json.field "width", quality
json.field "height", quality
end
@@ -446,9 +460,9 @@ struct Video
end
end
- json.field "lengthSeconds", rv["length_seconds"].to_i
- json.field "viewCountText", rv["short_view_count_text"]
- json.field "viewCount", rv["view_count"]?.try &.to_i64
+ json.field "lengthSeconds", rv["length_seconds"]?.try &.to_i
+ json.field "viewCountText", rv["short_view_count_text"]?
+ json.field "viewCount", rv["view_count"]?.try &.empty? ? nil : rv["view_count"].to_i64
end
end
end
@@ -457,269 +471,164 @@ struct Video
end
end
- def to_json(locale, config, kemal_config, decrypt_function, json : JSON::Builder | Nil = nil)
+ def to_json(locale, json : JSON::Builder | Nil = nil)
if json
- to_json(locale, config, kemal_config, decrypt_function, json)
+ to_json(locale, json)
else
JSON.build do |json|
- to_json(locale, config, kemal_config, decrypt_function, json)
+ to_json(locale, json)
end
end
end
- # `description_html` is stored in DB as `description`, which can be
- # quite confusing. Since it currently isn't very practical to rename
- # it, we instead define a getter and setter here.
- def description_html
- self.description
+ def title
+ info["videoDetails"]["title"]?.try &.as_s || ""
end
- def description_html=(other : String)
- self.description = other
+ def ucid
+ info["videoDetails"]["channelId"]?.try &.as_s || ""
end
- def allow_ratings
- allow_ratings = player_response["videoDetails"]?.try &.["allowRatings"]?.try &.as_bool
-
- if allow_ratings.nil?
- return true
- end
+ def author
+ info["videoDetails"]["author"]?.try &.as_s || ""
+ end
- return allow_ratings
+ def length_seconds : Int32
+ info["microformat"]?.try &.["playerMicroformatRenderer"]?.try &.["lengthSeconds"]?.try &.as_s.to_i ||
+ info["videoDetails"]["lengthSeconds"]?.try &.as_s.to_i || 0
end
- def live_now
- live_now = player_response["videoDetails"]?.try &.["isLive"]?.try &.as_bool
+ def views : Int64
+ info["videoDetails"]["viewCount"]?.try &.as_s.to_i64 || 0_i64
+ end
- if live_now.nil?
- return false
- end
+ def likes : Int64
+ info["likes"]?.try &.as_i64 || 0_i64
+ end
- return live_now
+ def dislikes : Int64
+ info["dislikes"]?.try &.as_i64 || 0_i64
end
- def is_listed
- is_listed = player_response["videoDetails"]?.try &.["isCrawlable"]?.try &.as_bool
+ def average_rating : Float64
+ # (likes / (likes + dislikes) * 4 + 1)
+ info["videoDetails"]["averageRating"]?.try { |t| t.as_f? || t.as_i64?.try &.to_f64 }.try &.round(4) || 0.0
+ end
- if is_listed.nil?
- return true
- end
+ def published : Time
+ info["microformat"]?.try &.["playerMicroformatRenderer"]?.try &.["publishDate"]?.try { |t| Time.parse(t.as_s, "%Y-%m-%d", Time::Location.local) } || Time.local
+ end
- return is_listed
+ def published=(other : Time)
+ info["microformat"].as_h["playerMicroformatRenderer"].as_h["publishDate"] = JSON::Any.new(other.to_s("%Y-%m-%d"))
end
- def is_upcoming
- is_upcoming = player_response["videoDetails"]?.try &.["isUpcoming"]?.try &.as_bool
+ def cookie
+ info["cookie"]?.try &.as_h.map { |k, v| "#{k}=#{v}" }.join("; ") || ""
+ end
- if is_upcoming.nil?
- return false
- end
+ def allow_ratings
+ r = info["videoDetails"]["allowRatings"]?.try &.as_bool
+ r.nil? ? false : r
+ end
- return is_upcoming
+ def live_now
+ info["videoDetails"]["isLiveContent"]?.try &.as_bool || false
end
- def premiere_timestamp
- if self.is_upcoming
- premiere_timestamp = player_response["playabilityStatus"]?
- .try &.["liveStreamability"]?
- .try &.["liveStreamabilityRenderer"]?
- .try &.["offlineSlate"]?
- .try &.["liveStreamOfflineSlateRenderer"]?
- .try &.["scheduledStartTime"]?.try &.as_s.to_i64
- end
+ def is_listed
+ info["videoDetails"]["isCrawlable"]?.try &.as_bool || false
+ end
- if premiere_timestamp
- premiere_timestamp = Time.unix(premiere_timestamp)
- end
+ def is_upcoming
+ info["videoDetails"]["isUpcoming"]?.try &.as_bool || false
+ end
- return premiere_timestamp
+ def premiere_timestamp : Time?
+ info["microformat"]?.try &.["playerMicroformatRenderer"]?
+ .try &.["liveBroadcastDetails"]?.try &.["startTimestamp"]?.try { |t| Time.parse_rfc3339(t.as_s) }
end
def keywords
- keywords = player_response["videoDetails"]?.try &.["keywords"]?.try &.as_a
- keywords ||= [] of String
-
- return keywords
+ info["videoDetails"]["keywords"]?.try &.as_a.map &.as_s || [] of String
end
- def fmt_stream(decrypt_function)
- streams = [] of HTTP::Params
-
- if fmt_streams = player_response["streamingData"]?.try &.["formats"]?
- fmt_streams.as_a.each do |fmt_stream|
- if !fmt_stream.as_h?
- next
- end
-
- fmt = {} of String => String
-
- fmt["lmt"] = fmt_stream["lastModified"]?.try &.as_s || "0"
- fmt["projection_type"] = "1"
- fmt["type"] = fmt_stream["mimeType"].as_s
- fmt["clen"] = fmt_stream["contentLength"]?.try &.as_s || "0"
- fmt["bitrate"] = fmt_stream["bitrate"]?.try &.as_i.to_s || "0"
- fmt["itag"] = fmt_stream["itag"].as_i.to_s
- if fmt_stream["url"]?
- fmt["url"] = fmt_stream["url"].as_s
- end
- if fmt_stream["cipher"]?
- HTTP::Params.parse(fmt_stream["cipher"].as_s).each do |key, value|
- fmt[key] = value
- end
- end
- fmt["quality"] = fmt_stream["quality"].as_s
-
- if fmt_stream["width"]?
- fmt["size"] = "#{fmt_stream["width"]}x#{fmt_stream["height"]}"
- fmt["height"] = fmt_stream["height"].as_i.to_s
- end
+ def related_videos
+ info["relatedVideos"]?.try &.as_a.map { |h| h.as_h.transform_values &.as_s } || [] of Hash(String, String)
+ end
- if fmt_stream["fps"]?
- fmt["fps"] = fmt_stream["fps"].as_i.to_s
- end
+ def allowed_regions
+ info["microformat"]?.try &.["playerMicroformatRenderer"]?
+ .try &.["availableCountries"]?.try &.as_a.map &.as_s || [] of String
+ end
- if fmt_stream["qualityLabel"]?
- fmt["quality_label"] = fmt_stream["qualityLabel"].as_s
- end
+ def author_thumbnail : String
+ info["authorThumbnail"]?.try &.as_s || ""
+ end
- params = HTTP::Params.new
- fmt.each do |key, value|
- params[key] = value
- end
+ def sub_count_text : String
+ info["subCountText"]?.try &.as_s || "-"
+ end
- streams << params
- end
+ def fmt_stream
+ return @fmt_stream.as(Array(Hash(String, JSON::Any))) if @fmt_stream
- streams.sort_by! { |stream| stream["height"].to_i }.reverse!
- elsif fmt_stream = self.info["url_encoded_fmt_stream_map"]?
- fmt_stream.split(",").each do |string|
- if !string.empty?
- streams << HTTP::Params.parse(string)
+ fmt_stream = info["streamingData"]?.try &.["formats"]?.try &.as_a.map &.as_h || [] of Hash(String, JSON::Any)
+ fmt_stream.each do |fmt|
+ if s = (fmt["cipher"]? || fmt["signatureCipher"]?).try { |h| HTTP::Params.parse(h.as_s) }
+ s.each do |k, v|
+ fmt[k] = JSON::Any.new(v)
end
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}#{decrypt_signature(fmt)}")
end
- end
-
- streams.each { |s| s.add("label", "#{s["quality"]} - #{s["type"].split(";")[0].split("/")[1]}") }
- streams = streams.uniq { |s| s["label"] }
-
- if self.info["region"]?
- streams.each do |fmt|
- fmt["url"] += "&region=" + self.info["region"]
- end
- end
- streams.each do |fmt|
- fmt["url"] += "&host=" + (URI.parse(fmt["url"]).host || "")
- fmt["url"] += decrypt_signature(fmt, decrypt_function)
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}&host=#{URI.parse(fmt["url"].as_s).host}")
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}&region=#{self.info["region"]}") if self.info["region"]?
end
-
- return streams
+ fmt_stream.sort_by! { |f| f["width"]?.try &.as_i || 0 }
+ @fmt_stream = fmt_stream
+ return @fmt_stream.as(Array(Hash(String, JSON::Any)))
end
- def adaptive_fmts(decrypt_function)
- adaptive_fmts = [] of HTTP::Params
-
- if fmts = player_response["streamingData"]?.try &.["adaptiveFormats"]?
- fmts.as_a.each do |adaptive_fmt|
- if !adaptive_fmt.as_h?
- next
- end
-
- fmt = {} of String => String
-
- if init = adaptive_fmt["initRange"]?
- fmt["init"] = "#{init["start"]}-#{init["end"]}"
- end
- fmt["init"] ||= "0-0"
-
- fmt["lmt"] = adaptive_fmt["lastModified"]?.try &.as_s || "0"
- fmt["projection_type"] = "1"
- fmt["type"] = adaptive_fmt["mimeType"].as_s
- fmt["clen"] = adaptive_fmt["contentLength"]?.try &.as_s || "0"
- fmt["bitrate"] = adaptive_fmt["bitrate"]?.try &.as_i.to_s || "0"
- fmt["itag"] = adaptive_fmt["itag"].as_i.to_s
- if adaptive_fmt["url"]?
- fmt["url"] = adaptive_fmt["url"].as_s
- end
- if adaptive_fmt["cipher"]?
- HTTP::Params.parse(adaptive_fmt["cipher"].as_s).each do |key, value|
- fmt[key] = value
- end
- end
- if index = adaptive_fmt["indexRange"]?
- fmt["index"] = "#{index["start"]}-#{index["end"]}"
- end
- fmt["index"] ||= "0-0"
-
- if adaptive_fmt["width"]?
- fmt["size"] = "#{adaptive_fmt["width"]}x#{adaptive_fmt["height"]}"
- end
-
- if adaptive_fmt["fps"]?
- fmt["fps"] = adaptive_fmt["fps"].as_i.to_s
- end
-
- if adaptive_fmt["qualityLabel"]?
- fmt["quality_label"] = adaptive_fmt["qualityLabel"].as_s
- end
-
- params = HTTP::Params.new
- fmt.each do |key, value|
- params[key] = value
+ def adaptive_fmts
+ return @adaptive_fmts.as(Array(Hash(String, JSON::Any))) if @adaptive_fmts
+ fmt_stream = info["streamingData"]?.try &.["adaptiveFormats"]?.try &.as_a.map &.as_h || [] of Hash(String, JSON::Any)
+ fmt_stream.each do |fmt|
+ if s = (fmt["cipher"]? || fmt["signatureCipher"]?).try { |h| HTTP::Params.parse(h.as_s) }
+ s.each do |k, v|
+ fmt[k] = JSON::Any.new(v)
end
-
- adaptive_fmts << params
- end
- elsif fmts = self.info["adaptive_fmts"]?
- fmts.split(",") do |string|
- adaptive_fmts << HTTP::Params.parse(string)
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}#{decrypt_signature(fmt)}")
end
- end
- if self.info["region"]?
- adaptive_fmts.each do |fmt|
- fmt["url"] += "&region=" + self.info["region"]
- end
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}&host=#{URI.parse(fmt["url"].as_s).host}")
+ fmt["url"] = JSON::Any.new("#{fmt["url"]}&region=#{self.info["region"]}") if self.info["region"]?
end
-
- adaptive_fmts.each do |fmt|
- fmt["url"] += "&host=" + (URI.parse(fmt["url"]).host || "")
- fmt["url"] += decrypt_signature(fmt, decrypt_function)
- end
-
- return adaptive_fmts
+ # See https://github.com/TeamNewPipe/NewPipe/issues/2415
+ # Some streams are segmented by URL `sq/` rather than index, for now we just filter them out
+ fmt_stream.reject! { |f| !f["indexRange"]? }
+ fmt_stream.sort_by! { |f| f["width"]?.try &.as_i || 0 }
+ @adaptive_fmts = fmt_stream
+ return @adaptive_fmts.as(Array(Hash(String, JSON::Any)))
end
- def video_streams(adaptive_fmts)
- video_streams = adaptive_fmts.select { |s| s["type"].starts_with? "video" }
-
- return video_streams
+ def video_streams
+ adaptive_fmts.select &.["mimeType"]?.try &.as_s.starts_with?("video")
end
- def audio_streams(adaptive_fmts)
- audio_streams = adaptive_fmts.select { |s| s["type"].starts_with? "audio" }
- audio_streams.sort_by! { |s| s["bitrate"].to_i }.reverse!
- audio_streams.each do |stream|
- stream["bitrate"] = (stream["bitrate"].to_f64/1000).to_i.to_s
- end
-
- return audio_streams
- end
-
- def player_response
- @player_json = JSON.parse(@info["player_response"]) if !@player_json
- @player_json.not_nil!
+ def audio_streams
+ adaptive_fmts.select &.["mimeType"]?.try &.as_s.starts_with?("audio")
end
def storyboards
- storyboards = player_response["storyboards"]?
+ storyboards = info["storyboards"]?
.try &.as_h
.try &.["playerStoryboardSpecRenderer"]?
.try &.["spec"]?
.try &.as_s.split("|")
if !storyboards
- if storyboard = player_response["storyboards"]?
+ if storyboard = info["storyboards"]?
.try &.as_h
.try &.["playerLiveStoryboardSpecRenderer"]?
.try &.["spec"]?
@@ -747,9 +656,7 @@ struct Video
storyboard_height: Int32,
storyboard_count: Int32)
- if !storyboards
- return items
- end
+ return items if !storyboards
url = URI.parse(storyboards.shift)
params = HTTP::Params.parse(url.query || "")
@@ -783,220 +690,169 @@ struct Video
end
def paid
- reason = player_response["playabilityStatus"]?.try &.["reason"]?
+ reason = info["playabilityStatus"]?.try &.["reason"]?
paid = reason == "This video requires payment to watch." ? true : false
-
- return paid
+ paid
end
def premium
- if info["premium"]?
- self.info["premium"] == "true"
- else
- false
+ keywords.includes? "YouTube Red"
+ end
+
+ def captions : Array(Caption)
+ return @captions.as(Array(Caption)) if @captions
+ captions = info["captions"]?.try &.["playerCaptionsTracklistRenderer"]?.try &.["captionTracks"]?.try &.as_a.map do |caption|
+ caption = Caption.from_json(caption.to_json)
+ caption.name.simpleText = caption.name.simpleText.split(" - ")[0]
+ caption
end
+ captions ||= [] of Caption
+ @captions = captions
+ return @captions.as(Array(Caption))
end
- def captions
- captions = [] of Caption
- if player_response["captions"]?
- caption_list = player_response["captions"]["playerCaptionsTracklistRenderer"]["captionTracks"]?.try &.as_a
- caption_list ||= [] of JSON::Any
+ def description
+ description = info["microformat"]?.try &.["playerMicroformatRenderer"]?
+ .try &.["description"]?.try &.["simpleText"]?.try &.as_s || ""
+ end
- caption_list.each do |caption|
- caption = Caption.from_json(caption.to_json)
- caption.name.simpleText = caption.name.simpleText.split(" - ")[0]
- captions << caption
- end
- end
+ # TODO
+ def description=(value : String)
+ @description = value
+ end
- return captions
+ def description_html
+ info["descriptionHtml"]?.try &.as_s || "<p></p>"
end
- def short_description
- short_description = self.description_html.gsub(/(<br>)|(<br\/>|"|\n)/, {
- "<br>": " ",
- "<br/>": " ",
- "\"": "&quot;",
- "\n": " ",
- })
- short_description = XML.parse_html(short_description).content[0..200].strip(" ")
-
- if short_description.empty?
- short_description = " "
- end
+ def description_html=(value : String)
+ info["descriptionHtml"] = JSON::Any.new(value)
+ end
- return short_description
- end
-
- def length_seconds
- player_response["videoDetails"]["lengthSeconds"].as_s.to_i
- end
-
- db_mapping({
- id: String,
- info: {
- type: HTTP::Params,
- default: HTTP::Params.parse(""),
- converter: Video::HTTPParamConverter,
- },
- updated: Time,
- title: String,
- views: Int64,
- likes: Int32,
- dislikes: Int32,
- wilson_score: Float64,
- published: Time,
- description: String,
- language: String?,
- author: String,
- ucid: String,
- allowed_regions: Array(String),
- is_family_friendly: Bool,
- genre: String,
- genre_url: String,
- license: String,
- sub_count_text: String,
- author_thumbnail: String,
- })
-end
+ def short_description
+ info["shortDescription"]?.try &.as_s? || ""
+ end
-struct Caption
- json_mapping({
- name: CaptionName,
- baseUrl: String,
- languageCode: String,
- })
-end
+ def hls_manifest_url : String?
+ info["streamingData"]?.try &.["hlsManifestUrl"]?.try &.as_s
+ end
-struct CaptionName
- json_mapping({
- simpleText: String,
- })
-end
+ def dash_manifest_url
+ info["streamingData"]?.try &.["dashManifestUrl"]?.try &.as_s
+ end
-class VideoRedirect < Exception
- property video_id : String
+ def genre : String
+ info["genre"]?.try &.as_s || ""
+ end
- def initialize(@video_id)
+ def genre_url : String?
+ info["genreUcid"]? ? "/channel/#{info["genreUcid"]}" : nil
end
-end
-def get_video(id, db, refresh = true, region = nil, force_refresh = false)
- if (video = db.query_one?("SELECT * FROM videos WHERE id = $1", id, as: Video)) && !region
- # If record was last updated over 10 minutes ago, or video has since premiered,
- # refresh (expire param in response lasts for 6 hours)
- if (refresh &&
- (Time.utc - video.updated > 10.minutes) ||
- (video.premiere_timestamp && video.premiere_timestamp.as(Time) < Time.utc)) ||
- force_refresh
- begin
- video = fetch_video(id, region)
- video_array = video.to_a
+ def license : String?
+ info["license"]?.try &.as_s
+ end
- args = arg_array(video_array[1..-1], 2)
+ def is_family_friendly : Bool
+ info["microformat"]?.try &.["playerMicroformatRenderer"]["isFamilySafe"]?.try &.as_bool || false
+ end
- db.exec("UPDATE videos SET (info,updated,title,views,likes,dislikes,wilson_score,\
- published,description,language,author,ucid,allowed_regions,is_family_friendly,\
- genre,genre_url,license,sub_count_text,author_thumbnail)\
- = (#{args}) WHERE id = $1", args: video_array)
- rescue ex
- db.exec("DELETE FROM videos * WHERE id = $1", id)
- raise ex
- end
- end
- else
- video = fetch_video(id, region)
- video_array = video.to_a
+ def wilson_score : Float64
+ ci_lower_bound(likes, likes + dislikes).round(4)
+ end
- args = arg_array(video_array)
+ def engagement : Float64
+ ((likes + dislikes) / views).round(4)
+ end
- if !region
- db.exec("INSERT INTO videos VALUES (#{args}) ON CONFLICT (id) DO NOTHING", args: video_array)
- end
+ def reason : String?
+ info["reason"]?.try &.as_s
end
- return video
+ def session_token : String?
+ info["sessionToken"]?.try &.as_s?
+ end
end
-def extract_recommended(recommended_videos)
- rvs = [] of HTTP::Params
+struct CaptionName
+ include JSON::Serializable
- recommended_videos.try &.each do |compact_renderer|
- if compact_renderer["compactRadioRenderer"]? || compact_renderer["compactPlaylistRenderer"]?
- # TODO
- elsif video_renderer = compact_renderer["compactVideoRenderer"]?
- recommended_video = HTTP::Params.new
- recommended_video["id"] = video_renderer["videoId"].as_s
- recommended_video["title"] = video_renderer["title"]["simpleText"].as_s
+ property simpleText : String
+end
- next if !video_renderer["shortBylineText"]?
+struct Caption
+ include JSON::Serializable
- recommended_video["author"] = video_renderer["shortBylineText"]["runs"].as_a[0]["text"].as_s
- recommended_video["ucid"] = video_renderer["shortBylineText"]["runs"].as_a[0]["navigationEndpoint"]["browseEndpoint"]["browseId"].as_s
- recommended_video["author_thumbnail"] = video_renderer["channelThumbnail"]["thumbnails"][0]["url"].as_s
+ property name : CaptionName
+ property baseUrl : String
+ property languageCode : String
+end
- if view_count = video_renderer["viewCountText"]?.try { |field| field["simpleText"]?.try &.as_s || field["runs"][0]?.try &.["text"].as_s }.try &.delete(", views watching").to_i64?.try &.to_s
- recommended_video["view_count"] = view_count
- recommended_video["short_view_count_text"] = "#{number_to_short_text(view_count.to_i64)} views"
- end
- recommended_video["length_seconds"] = decode_length_seconds(video_renderer["lengthText"]?.try &.["simpleText"]?.try &.as_s || "0:00").to_s
+class VideoRedirect < Exception
+ property video_id : String
- rvs << recommended_video
- end
+ def initialize(@video_id)
end
-
- rvs
end
-def extract_polymer_config(body, html)
- params = HTTP::Params.new
-
- params["session_token"] = body.match(/"XSRF_TOKEN":"(?<session_token>[A-Za-z0-9\_\-\=]+)"/).try &.["session_token"] || ""
-
- html_info = JSON.parse(body.match(/ytplayer\.config = (?<info>.*?);ytplayer\.load/).try &.["info"] || "{}").try &.["args"]?.try &.as_h
+def parse_related(r : JSON::Any) : JSON::Any?
+ # TODO: r["endScreenPlaylistRenderer"], etc.
+ return if !r["endScreenVideoRenderer"]?
+ r = r["endScreenVideoRenderer"].as_h
+
+ return if !r["lengthInSeconds"]?
+
+ rv = {} of String => JSON::Any
+ rv["author"] = r["shortBylineText"]["runs"][0]?.try &.["text"] || JSON::Any.new("")
+ rv["ucid"] = r["shortBylineText"]["runs"][0]?.try &.["navigationEndpoint"]["browseEndpoint"]["browseId"] || JSON::Any.new("")
+ rv["author_url"] = JSON::Any.new("/channel/#{rv["ucid"]}")
+ rv["length_seconds"] = JSON::Any.new(r["lengthInSeconds"].as_i.to_s)
+ rv["title"] = r["title"]["simpleText"]
+ rv["short_view_count_text"] = JSON::Any.new(r["shortViewCountText"]?.try &.["simpleText"]?.try &.as_s || "")
+ rv["view_count"] = JSON::Any.new(r["title"]["accessibility"]?.try &.["accessibilityData"]["label"].as_s.match(/(?<views>[1-9](\d+,?)*) views/).try &.["views"].gsub(/\D/, "") || "")
+ rv["id"] = r["videoId"]
+ JSON::Any.new(rv)
+end
- if html_info
- html_info.each do |key, value|
- params[key] = value.to_s
- end
+def extract_polymer_config(body)
+ params = {} of String => JSON::Any
+ player_response = body.match(/window\["ytInitialPlayerResponse"\]\s*=\s*(?<info>.*?);\n/)
+ .try { |r| JSON.parse(r["info"]).as_h }
+
+ if body.includes?("To continue with your YouTube experience, please fill out the form below.") ||
+ body.includes?("https://www.google.com/sorry/index")
+ params["reason"] = JSON::Any.new("Could not extract video info. Instance is likely blocked.")
+ elsif !player_response
+ params["reason"] = JSON::Any.new("Video unavailable.")
+ elsif player_response["playabilityStatus"]?.try &.["status"]?.try &.as_s != "OK"
+ reason = player_response["playabilityStatus"]["errorScreen"]?.try &.["playerErrorMessageRenderer"]?.try &.["subreason"]?.try { |s| s["simpleText"]?.try &.as_s || s["runs"].as_a.map { |r| r["text"] }.join("") } ||
+ player_response["playabilityStatus"]["reason"].as_s
+ params["reason"] = JSON::Any.new(reason)
end
- initial_data = extract_initial_data(body)
+ params["sessionToken"] = JSON::Any.new(body.match(/"XSRF_TOKEN":"(?<session_token>[^"]+)"/).try &.["session_token"]?)
+ params["shortDescription"] = JSON::Any.new(body.match(/"og:description" content="(?<description>[^"]+)"/).try &.["description"]?)
- primary_results = initial_data["contents"]?
- .try &.["twoColumnWatchNextResults"]?
- .try &.["results"]?
- .try &.["results"]?
- .try &.["contents"]?
+ return params if !player_response
- comment_continuation = primary_results.try &.as_a.select { |object| object["itemSectionRenderer"]? }[0]?
- .try &.["itemSectionRenderer"]?
- .try &.["continuations"]?
- .try &.[0]?
- .try &.["nextContinuationData"]?
-
- params["ctoken"] = comment_continuation.try &.["continuation"]?.try &.as_s || ""
- params["itct"] = comment_continuation.try &.["clickTrackingParams"]?.try &.as_s || ""
-
- rvs = initial_data["contents"]?
- .try &.["twoColumnWatchNextResults"]?
- .try &.["secondaryResults"]?
- .try &.["secondaryResults"]?
- .try &.["results"]?
- .try &.as_a
+ {"captions", "microformat", "playabilityStatus", "storyboards", "videoDetails"}.each do |f|
+ params[f] = player_response[f] if player_response[f]?
+ end
- params["rvs"] = extract_recommended(rvs).join(",")
+ yt_initial_data = body.match(/(window\["ytInitialData"\]|var\s+ytInitialData)\s*=\s*(?<info>.*?);\s*\n/)
+ .try { |r| JSON.parse(r["info"]).as_h }
- # TODO: Watching now
- params["views"] = primary_results.try &.as_a.select { |object| object["videoPrimaryInfoRenderer"]? }[0]?
- .try &.["videoPrimaryInfoRenderer"]?
- .try &.["viewCount"]?
- .try &.["videoViewCountRenderer"]?
- .try &.["viewCount"]?
- .try &.["simpleText"]?
- .try &.as_s.gsub(/\D/, "").to_i64.to_s || "0"
+ params["relatedVideos"] = yt_initial_data.try &.["playerOverlays"]?.try &.["playerOverlayRenderer"]?
+ .try &.["endScreen"]?.try &.["watchNextEndScreenRenderer"]?.try &.["results"]?.try &.as_a.compact_map { |r|
+ parse_related r
+ }.try { |a| JSON::Any.new(a) } || yt_initial_data.try &.["webWatchNextResponseExtensionData"]?.try &.["relatedVideoArgs"]?
+ .try &.as_s.split(",").map { |r|
+ r = HTTP::Params.parse(r).to_h
+ JSON::Any.new(Hash.zip(r.keys, r.values.map { |v| JSON::Any.new(v) }))
+ }.try { |a| JSON::Any.new(a) } || JSON::Any.new([] of JSON::Any)
+ primary_results = yt_initial_data.try &.["contents"]?.try &.["twoColumnWatchNextResults"]?.try &.["results"]?
+ .try &.["results"]?.try &.["contents"]?
sentiment_bar = primary_results.try &.as_a.select { |object| object["videoPrimaryInfoRenderer"]? }[0]?
.try &.["videoPrimaryInfoRenderer"]?
.try &.["sentimentBar"]?
@@ -1004,34 +860,13 @@ def extract_polymer_config(body, html)
.try &.["tooltip"]?
.try &.as_s
- likes, dislikes = sentiment_bar.try &.split(" / ").map { |a| a.delete(", ").to_i32 }[0, 2] || {0, 0}
+ likes, dislikes = sentiment_bar.try &.split(" / ", 2).map &.gsub(/\D/, "").to_i64 || {0_i64, 0_i64}
+ params["likes"] = JSON::Any.new(likes)
+ params["dislikes"] = JSON::Any.new(dislikes)
- params["likes"] = "#{likes}"
- params["dislikes"] = "#{dislikes}"
-
- published = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]?
- .try &.["videoSecondaryInfoRenderer"]?
- .try &.["dateText"]?
- .try &.["simpleText"]?
- .try &.as_s.split(" ")[-3..-1].join(" ")
-
- if published
- params["published"] = Time.parse(published, "%b %-d, %Y", Time::Location.local).to_unix.to_s
- else
- params["published"] = Time.utc(1990, 1, 1).to_unix.to_s
- end
-
- params["description_html"] = "<p></p>"
-
- description_html = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]?
- .try &.["videoSecondaryInfoRenderer"]?
- .try &.["description"]?
- .try &.["runs"]?
- .try &.as_a
-
- if description_html
- params["description_html"] = content_to_comment_html(description_html)
- end
+ params["descriptionHtml"] = JSON::Any.new(primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]?
+ .try &.["videoSecondaryInfoRenderer"]?.try &.["description"]?.try &.["runs"]?
+ .try &.as_a.try { |t| content_to_comment_html(t).gsub("\n", "<br/>") } || "<p></p>")
metadata = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]?
.try &.["videoSecondaryInfoRenderer"]?
@@ -1040,9 +875,8 @@ def extract_polymer_config(body, html)
.try &.["rows"]?
.try &.as_a
- params["genre"] = ""
- params["genre_ucid"] = ""
- params["license"] = ""
+ params["genre"] = params["microformat"]?.try &.["playerMicroformatRenderer"]?.try &.["category"]? || JSON::Any.new("")
+ params["genreUrl"] = JSON::Any.new(nil)
metadata.try &.each do |row|
title = row["metadataRowRenderer"]?.try &.["title"]?.try &.["simpleText"]?.try &.as_s
@@ -1054,219 +888,130 @@ def extract_polymer_config(body, html)
contents = contents.try &.["runs"]?
.try &.as_a[0]?
- params["genre"] = contents.try &.["text"]?
- .try &.as_s || ""
- params["genre_ucid"] = contents.try &.["navigationEndpoint"]?
- .try &.["browseEndpoint"]?
- .try &.["browseId"]?.try &.as_s || ""
+ params["genre"] = JSON::Any.new(contents.try &.["text"]?.try &.as_s || "")
+ params["genreUcid"] = JSON::Any.new(contents.try &.["navigationEndpoint"]?.try &.["browseEndpoint"]?
+ .try &.["browseId"]?.try &.as_s || "")
elsif title.try &.== "License"
contents = contents.try &.["runs"]?
.try &.as_a[0]?
- params["license"] = contents.try &.["text"]?
- .try &.as_s || ""
+ params["license"] = JSON::Any.new(contents.try &.["text"]?.try &.as_s || "")
elsif title.try &.== "Licensed to YouTube by"
- params["license"] = contents.try &.["simpleText"]?
- .try &.as_s || ""
+ params["license"] = JSON::Any.new(contents.try &.["simpleText"]?.try &.as_s || "")
end
end
author_info = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]?
- .try &.["videoSecondaryInfoRenderer"]?
- .try &.["owner"]?
- .try &.["videoOwnerRenderer"]?
+ .try &.["videoSecondaryInfoRenderer"]?.try &.["owner"]?.try &.["videoOwnerRenderer"]?
- params["author_thumbnail"] = author_info.try &.["thumbnail"]?
- .try &.["thumbnails"]?
- .try &.as_a[0]?
- .try &.["url"]?
- .try &.as_s || ""
+ params["authorThumbnail"] = JSON::Any.new(author_info.try &.["thumbnail"]?
+ .try &.["thumbnails"]?.try &.as_a[0]?.try &.["url"]?
+ .try &.as_s || "")
- params["sub_count_text"] = author_info.try &.["subscriberCountText"]?
- .try &.["simpleText"]?
- .try &.as_s.gsub(/\D/, "") || "0"
+ params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]?
+ .try { |t| t["simpleText"]? || t["runs"]?.try &.[0]?.try &.["text"]? }.try &.as_s.split(" ", 2)[0] || "-")
- return params
-end
+ initial_data = body.match(/ytplayer\.config\s*=\s*(?<info>.*?);ytplayer\.web_player_context_config/)
+ .try { |r| JSON.parse(r["info"]) }.try &.["args"]["player_response"]?
+ .try &.as_s?.try &.try { |r| JSON.parse(r).as_h }
-def extract_player_config(body, html)
- params = HTTP::Params.new
+ return params if !initial_data
- if md = body.match(/'XSRF_TOKEN': "(?<session_token>[A-Za-z0-9\_\-\=]+)"/)
- params["session_token"] = md["session_token"]
+ {"playabilityStatus", "streamingData"}.each do |f|
+ params[f] = initial_data[f] if initial_data[f]?
end
- if md = body.match(/'RELATED_PLAYER_ARGS': (?<json>.*?),\n/)
- recommended_json = JSON.parse(md["json"])
- rvs_params = recommended_json["rvs"].as_s.split(",").map { |params| HTTP::Params.parse(params) }
-
- if watch_next_response = recommended_json["watch_next_response"]?
- watch_next_json = JSON.parse(watch_next_response.as_s)
- rvs = watch_next_json["contents"]?
- .try &.["twoColumnWatchNextResults"]?
- .try &.["secondaryResults"]?
- .try &.["secondaryResults"]?
- .try &.["results"]?
- .try &.as_a
-
- rvs = extract_recommended(rvs).compact_map do |rv|
- if !rv["short_view_count_text"]?
- rv_params = rvs_params.select { |rv_params| rv_params["id"]? == (rv["id"]? || "") }[0]?
+ params
+end
- if rv_params.try &.["short_view_count_text"]?
- rv["short_view_count_text"] = rv_params.not_nil!["short_view_count_text"]
- rv
- else
- nil
- end
- else
- rv
- end
+def get_video(id, db, refresh = true, region = nil, force_refresh = false)
+ if (video = db.query_one?("SELECT * FROM videos WHERE id = $1", id, as: Video)) && !region
+ # If record was last updated over 10 minutes ago, or video has since premiered,
+ # refresh (expire param in response lasts for 6 hours)
+ if (refresh &&
+ (Time.utc - video.updated > 10.minutes) ||
+ (video.premiere_timestamp.try &.< Time.utc)) ||
+ force_refresh
+ begin
+ video = fetch_video(id, region)
+ db.exec("UPDATE videos SET (id, info, updated) = ($1, $2, $3) WHERE id = $1", video.id, video.info.to_json, video.updated)
+ rescue ex
+ db.exec("DELETE FROM videos * WHERE id = $1", id)
+ raise ex
end
- params["rvs"] = (rvs.map &.to_s).join(",")
- end
- end
-
- html_info = body.match(/ytplayer\.config = (?<info>.*?);ytplayer\.load/).try &.["info"]
-
- if html_info
- JSON.parse(html_info)["args"].as_h.each do |key, value|
- params[key] = value.to_s
end
else
- error_message = html.xpath_node(%q(//h1[@id="unavailable-message"]))
- if error_message
- params["reason"] = error_message.content.strip
- elsif body.includes?("To continue with your YouTube experience, please fill out the form below.") ||
- body.includes?("https://www.google.com/sorry/index")
- params["reason"] = "Could not extract video info. Instance is likely blocked."
- else
- params["reason"] = "Video unavailable."
+ video = fetch_video(id, region)
+ if !region
+ db.exec("INSERT INTO videos VALUES ($1, $2, $3) ON CONFLICT (id) DO NOTHING", video.id, video.info.to_json, video.updated)
end
end
- return params
+ return video
end
def fetch_video(id, region)
- response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999"))
+ response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&has_verified=1&bpctr=9999999999"))
if md = response.headers["location"]?.try &.match(/v=(?<id>[a-zA-Z0-9_-]{11})/)
raise VideoRedirect.new(video_id: md["id"])
end
- html = XML.parse_html(response.body)
- info = extract_player_config(response.body, html)
- info["cookie"] = response.cookies.to_h.map { |name, cookie| "#{name}=#{cookie.value}" }.join("; ")
-
- allowed_regions = html.xpath_node(%q(//meta[@itemprop="regionsAllowed"])).try &.["content"].split(",")
- if !allowed_regions || allowed_regions == [""]
- allowed_regions = [] of String
- end
+ info = extract_polymer_config(response.body)
+ info["cookie"] = JSON::Any.new(response.cookies.to_h.transform_values { |v| JSON::Any.new(v.value) })
+ allowed_regions = info["microformat"]?.try &.["playerMicroformatRenderer"]["availableCountries"]?.try &.as_a.map &.as_s || [] of String
# Check for region-blocks
- if info["reason"]? && info["reason"].includes?("your country")
+ if info["reason"]?.try &.as_s.includes?("your country")
bypass_regions = PROXY_LIST.keys & allowed_regions
if !bypass_regions.empty?
region = bypass_regions[rand(bypass_regions.size)]
- response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999"))
-
- html = XML.parse_html(response.body)
- info = extract_player_config(response.body, html)
+ response = YT_POOL.client(region, &.get("/watch?v=#{id}&gl=US&hl=en&has_verified=1&bpctr=9999999999"))
- info["region"] = region if region
- info["cookie"] = response.cookies.to_h.map { |name, cookie| "#{name}=#{cookie.value}" }.join("; ")
+ region_info = extract_polymer_config(response.body)
+ region_info["region"] = JSON::Any.new(region) if region
+ region_info["cookie"] = JSON::Any.new(response.cookies.to_h.transform_values { |v| JSON::Any.new(v.value) })
+ info = region_info if !region_info["reason"]?
end
end
# Try to pull streams from embed URL
if info["reason"]?
embed_page = YT_POOL.client &.get("/embed/#{id}").body
- sts = embed_page.match(/"sts"\s*:\s*(?<sts>\d+)/).try &.["sts"]?
- sts ||= ""
- embed_info = HTTP::Params.parse(YT_POOL.client &.get("/get_video_info?video_id=#{id}&eurl=https://youtube.googleapis.com/v/#{id}&gl=US&hl=en&disable_polymer=1&sts=#{sts}").body)
+ sts = embed_page.match(/"sts"\s*:\s*(?<sts>\d+)/).try &.["sts"]? || ""
+ embed_info = HTTP::Params.parse(YT_POOL.client &.get("/get_video_info?html5=1&video_id=#{id}&eurl=https://youtube.googleapis.com/v/#{id}&gl=US&hl=en&sts=#{sts}").body)
- if !embed_info["reason"]?
- embed_info.each do |key, value|
- info[key] = value.to_s
+ if embed_info["player_response"]?
+ player_response = JSON.parse(embed_info["player_response"])
+ {"captions", "microformat", "playabilityStatus", "streamingData", "videoDetails", "storyboards"}.each do |f|
+ info[f] = player_response[f] if player_response[f]?
end
- else
- raise info["reason"]
end
- end
- if info["reason"]? && !info["player_response"]?
- raise info["reason"]
- end
+ initial_data = JSON.parse(embed_info["watch_next_response"]) if embed_info["watch_next_response"]?
- player_json = JSON.parse(info["player_response"])
- if reason = player_json["playabilityStatus"]?.try &.["reason"]?.try &.as_s
- raise reason
+ info["relatedVideos"] = initial_data.try &.["playerOverlays"]?.try &.["playerOverlayRenderer"]?
+ .try &.["endScreen"]?.try &.["watchNextEndScreenRenderer"]?.try &.["results"]?.try &.as_a.compact_map { |r|
+ parse_related r
+ }.try { |a| JSON::Any.new(a) } || embed_info["rvs"]?.try &.split(",").map { |r|
+ r = HTTP::Params.parse(r).to_h
+ JSON::Any.new(Hash.zip(r.keys, r.values.map { |v| JSON::Any.new(v) }))
+ }.try { |a| JSON::Any.new(a) } || JSON::Any.new([] of JSON::Any)
end
- title = player_json["videoDetails"]["title"].as_s
- author = player_json["videoDetails"]["author"]?.try &.as_s || ""
- ucid = player_json["videoDetails"]["channelId"]?.try &.as_s || ""
-
- info["premium"] = html.xpath_node(%q(.//span[text()="Premium"])) ? "true" : "false"
-
- views = html.xpath_node(%q(//meta[@itemprop="interactionCount"]))
- .try &.["content"].to_i64? || 0_i64
+ raise info["reason"]?.try &.as_s || "" if !info["videoDetails"]?
- likes = html.xpath_node(%q(//button[@title="I like this"]/span))
- .try &.content.delete(",").try &.to_i? || 0
-
- dislikes = html.xpath_node(%q(//button[@title="I dislike this"]/span))
- .try &.content.delete(",").try &.to_i? || 0
-
- avg_rating = (likes.to_f/(likes.to_f + dislikes.to_f) * 4 + 1)
- avg_rating = avg_rating.nan? ? 0.0 : avg_rating
- info["avg_rating"] = "#{avg_rating}"
-
- description_html = html.xpath_node(%q(//p[@id="eow-description"])).try &.to_xml(options: XML::SaveOptions::NO_DECL) || "<p></p>"
- wilson_score = ci_lower_bound(likes, likes + dislikes)
-
- published = html.xpath_node(%q(//meta[@itemprop="datePublished"])).try &.["content"]
- published ||= Time.utc.to_s("%Y-%m-%d")
- published = Time.parse(published, "%Y-%m-%d", Time::Location.local)
-
- is_family_friendly = html.xpath_node(%q(//meta[@itemprop="isFamilyFriendly"])).try &.["content"] == "True"
- is_family_friendly ||= true
-
- genre = html.xpath_node(%q(//meta[@itemprop="genre"])).try &.["content"]
- genre ||= ""
-
- genre_url = html.xpath_node(%(//ul[contains(@class, "watch-info-tag-list")]/li/a[text()="#{genre}"])).try &.["href"]?
- genre_url ||= ""
-
- # YouTube provides invalid URLs for some genres, so we fix that here
- case genre
- when "Comedy"
- genre_url = "/channel/UCQZ43c4dAA9eXCQuXWu9aTw"
- when "Education"
- genre_url = "/channel/UCdxpofrI-dO6oYfsqHDHphw"
- when "Gaming"
- genre_url = "/channel/UCOpNcN46UbXVtpKMrmU4Abg"
- when "Movies"
- genre_url = "/channel/UClgRkhTL3_hImCAmdLfDE4g"
- when "Nonprofits & Activism"
- genre_url = "/channel/UCfFyYRYslvuhwMDnx6KjUvw"
- when "Trailers"
- genre_url = "/channel/UClgRkhTL3_hImCAmdLfDE4g"
- end
-
- license = html.xpath_node(%q(//h4[contains(text(),"License")]/parent::*/ul/li)).try &.content || ""
- sub_count_text = html.xpath_node(%q(//span[contains(@class, "subscriber-count")])).try &.["title"]? || "0"
- author_thumbnail = html.xpath_node(%(//span[@class="yt-thumb-clip"]/img)).try &.["data-thumb"]?.try &.gsub(/^\/\//, "https://") || ""
-
- video = Video.new(id, info, Time.utc, title, views, likes, dislikes, wilson_score, published, description_html,
- nil, author, ucid, allowed_regions, is_family_friendly, genre, genre_url, license, sub_count_text, author_thumbnail)
+ video = Video.new({
+ id: id,
+ info: info,
+ updated: Time.utc,
+ })
return video
end
-def itag_to_metadata?(itag : String)
- return VIDEO_FORMATS[itag]?
+def itag_to_metadata?(itag : JSON::Any)
+ return VIDEO_FORMATS[itag.to_s]?
end
def process_continuation(db, query, plid, id)
@@ -1368,34 +1113,34 @@ def process_video_params(query, preferences)
controls ||= 1
controls = controls >= 1
- params = VideoPreferences.new(
- annotations: annotations,
- autoplay: autoplay,
- comments: comments,
- continue: continue,
- continue_autoplay: continue_autoplay,
- controls: controls,
- listen: listen,
- local: local,
- player_style: player_style,
+ params = VideoPreferences.new({
+ annotations: annotations,
+ autoplay: autoplay,
+ comments: comments,
+ continue: continue,
+ continue_autoplay: continue_autoplay,
+ controls: controls,
+ listen: listen,
+ local: local,
+ player_style: player_style,
preferred_captions: preferred_captions,
- quality: quality,
- raw: raw,
- region: region,
- related_videos: related_videos,
- speed: speed,
- video_end: video_end,
- video_loop: video_loop,
- video_start: video_start,
- volume: volume,
- )
+ quality: quality,
+ raw: raw,
+ region: region,
+ related_videos: related_videos,
+ speed: speed,
+ video_end: video_end,
+ video_loop: video_loop,
+ video_start: video_start,
+ volume: volume,
+ })
return params
end
-def build_thumbnails(id, config, kemal_config)
+def build_thumbnails(id)
return {
- {name: "maxres", host: "#{make_host_url(config, kemal_config)}", url: "maxres", height: 720, width: 1280},
+ {name: "maxres", host: "#{HOST_URL}", url: "maxres", height: 720, width: 1280},
{name: "maxresdefault", host: "https://i.ytimg.com", url: "maxresdefault", height: 720, width: 1280},
{name: "sddefault", host: "https://i.ytimg.com", url: "sddefault", height: 480, width: 640},
{name: "high", host: "https://i.ytimg.com", url: "hqdefault", height: 360, width: 480},
@@ -1407,9 +1152,9 @@ def build_thumbnails(id, config, kemal_config)
}
end
-def generate_thumbnails(json, id, config, kemal_config)
+def generate_thumbnails(json, id)
json.array do
- build_thumbnails(id, config, kemal_config).each do |thumbnail|
+ build_thumbnails(id).each do |thumbnail|
json.object do
json.field "quality", thumbnail[:name]
json.field "url", "#{thumbnail[:host]}/vi/#{id}/#{thumbnail["url"]}.jpg"
@@ -1420,7 +1165,7 @@ def generate_thumbnails(json, id, config, kemal_config)
end
end
-def generate_storyboards(json, id, storyboards, config, kemal_config)
+def generate_storyboards(json, id, storyboards)
json.array do
storyboards.each do |storyboard|
json.object do
diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr
index f1899faa..09eacbc8 100644
--- a/src/invidious/views/add_playlist_items.ecr
+++ b/src/invidious/views/add_playlist_items.ecr
@@ -20,12 +20,14 @@
<div class="pure-u-1 pure-u-lg-1-5"></div>
</div>
-<script>
-var playlist_data = {
- csrf_token: '<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>',
-}
+<script id="playlist_data" type="application/json">
+<%=
+{
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "")
+}.to_pretty_json
+%>
</script>
-<script src="/js/playlist_widget.js"></script>
+<script src="/js/playlist_widget.js?v=<%= ASSET_COMMIT %>"></script>
<div class="pure-g">
<% videos.each_slice(4) do |slice| %>
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr
index b5eb46ea..caa0ad0e 100644
--- a/src/invidious/views/channel.ecr
+++ b/src/invidious/views/channel.ecr
@@ -28,7 +28,7 @@
</div>
<div class="h-box">
- <p><span style="white-space:pre-wrap"><%= XML.parse_html(channel.description_html).xpath_node(%q(.//pre)).try &.content %></span></p>
+ <p><span style="white-space:pre-wrap"><%= channel.description_html %></span></p>
</div>
<div class="h-box">
@@ -92,7 +92,7 @@
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %>
- <a href="/channel/<%= channel.ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
+ <a href="/channel/<%= channel.ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Previous page") %>
</a>
<% end %>
@@ -100,7 +100,7 @@
<div class="pure-u-1 pure-u-lg-3-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count == 60 %>
- <a href="/channel/<%= channel.ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
+ <a href="/channel/<%= channel.ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr
index 218cc2d4..69724390 100644
--- a/src/invidious/views/community.ecr
+++ b/src/invidious/views/community.ecr
@@ -71,14 +71,16 @@
</div>
<% end %>
-<script>
-var community_data = {
- ucid: '<%= channel.ucid %>',
- youtube_comments_text: '<%= HTML.escape(translate(locale, "View YouTube comments")) %>',
- comments_text: '<%= HTML.escape(translate(locale, "View `x` comments", "{commentCount}")) %>',
- hide_replies_text: '<%= HTML.escape(translate(locale, "Hide replies")) %>',
- show_replies_text: '<%= HTML.escape(translate(locale, "Show replies")) %>',
- preferences: <%= env.get("preferences").as(Preferences).to_json %>,
-}
+<script id="community_data" type="application/json">
+<%=
+{
+ "ucid" => channel.ucid,
+ "youtube_comments_text" => HTML.escape(translate(locale, "View YouTube comments")),
+ "comments_text" => HTML.escape(translate(locale, "View `x` comments", "{commentCount}")),
+ "hide_replies_text" => HTML.escape(translate(locale, "Hide replies")),
+ "show_replies_text" => HTML.escape(translate(locale, "Show replies")),
+ "preferences" => env.get("preferences").as(Preferences)
+}.to_pretty_json
+%>
</script>
<script src="/js/community.js?v=<%= ASSET_COMMIT %>"></script>
diff --git a/src/invidious/views/components/feed_menu.ecr b/src/invidious/views/components/feed_menu.ecr
index f72db2da..3dbeaf37 100644
--- a/src/invidious/views/components/feed_menu.ecr
+++ b/src/invidious/views/components/feed_menu.ecr
@@ -1,19 +1,11 @@
-<div class="h-box pure-g">
- <div class="pure-u-1 pure-u-md-1-4"></div>
- <div class="pure-u-1 pure-u-md-1-2">
- <div class="pure-g">
- <% feed_menu = env.get("preferences").as(Preferences).feed_menu.dup %>
- <% if !env.get?("user") %>
- <% feed_menu.reject! {|item| {"Subscriptions", "Playlists"}.includes? item} %>
- <% end %>
- <% feed_menu.each do |feed| %>
- <div class="pure-u-1-2 pure-u-md-1-<%= feed_menu.size %>">
- <a href="/feed/<%= feed.downcase %>" class="pure-menu-heading" style="text-align:center">
- <%= translate(locale, feed) %>
- </a>
- </div>
- <% end %>
- </div>
- </div>
- <div class="pure-u-1 pure-u-md-1-4"></div>
+<div class="feed-menu">
+ <% feed_menu = env.get("preferences").as(Preferences).feed_menu.dup %>
+ <% if !env.get?("user") %>
+ <% feed_menu.reject! {|item| {"Subscriptions", "Playlists"}.includes? item} %>
+ <% end %>
+ <% feed_menu.each do |feed| %>
+ <a href="/feed/<%= feed.downcase %>" class="feed-menu-item pure-menu-heading">
+ <%= translate(locale, feed) %>
+ </a>
+ <% end %>
</div>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr
index f7b9cce6..0c19fc1b 100644
--- a/src/invidious/views/components/item.ecr
+++ b/src/invidious/views/components/item.ecr
@@ -44,7 +44,7 @@
<% end %>
</div>
<% end %>
- <p><%= item.title %></p>
+ <p><%= HTML.escape(item.title) %></p>
</a>
<p>
<b>
@@ -57,10 +57,10 @@
<div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
<% if plid = env.get?("remove_playlist_items") %>
- <form onsubmit="return false" action="/playlist_ajax?action_remove_video=1&set_video_id=<%= item.index %>&playlist_id=<%= plid %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/playlist_ajax?action_remove_video=1&set_video_id=<%= item.index %>&playlist_id=<%= plid %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
- <a onclick="remove_playlist_item(this)" data-index="<%= item.index %>" data-plid="<%= plid %>" href="javascript:void(0)">
+ <a data-onclick="remove_playlist_item" data-index="<%= item.index %>" data-plid="<%= plid %>" href="javascript:void(0)">
<button type="submit" style="all:unset">
<i class="icon ion-md-trash"></i>
</button>
@@ -76,7 +76,7 @@
<% end %>
</div>
<% end %>
- <p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p>
+ <p><a href="/watch?v=<%= item.id %>"><%= HTML.escape(item.title) %></a></p>
</a>
<p>
<b>
@@ -85,7 +85,7 @@
</p>
<h5 class="pure-g">
- <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.utc %>
+ <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp.try &.> Time.utc %>
<div class="pure-u-2-3"><%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.utc).ago, locale)) %></div>
<% elsif Time.utc - item.published > 1.minute %>
<div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
@@ -103,13 +103,12 @@
<div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
<% if env.get? "show_watched" %>
- <form onsubmit="return false" action="/watch_ajax?action_mark_watched=1&id=<%= item.id %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/watch_ajax?action_mark_watched=1&id=<%= item.id %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
- <a onclick="mark_watched(this)" data-id="<%= item.id %>" href="javascript:void(0)">
+ <a data-onclick="mark_watched" data-id="<%= item.id %>" href="javascript:void(0)">
<button type="submit" style="all:unset">
- <i onmouseenter='this.setAttribute("class", "icon ion-ios-eye-off")'
- onmouseleave='this.setAttribute("class", "icon ion-ios-eye")'
+ <i data-mouse="switch_classes" data-switch-classes="ion-ios-eye-off,ion-ios-eye"
class="icon ion-ios-eye">
</i>
</button>
@@ -117,10 +116,10 @@
</p>
</form>
<% elsif plid = env.get? "add_playlist_items" %>
- <form onsubmit="return false" action="/playlist_ajax?action_add_video=1&video_id=<%= item.id %>&playlist_id=<%= plid %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/playlist_ajax?action_add_video=1&video_id=<%= item.id %>&playlist_id=<%= plid %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
- <a onclick="add_playlist_item(this)" data-id="<%= item.id %>" data-plid="<%= plid %>" href="javascript:void(0)">
+ <a data-onclick="add_playlist_item" data-id="<%= item.id %>" data-plid="<%= plid %>" href="javascript:void(0)">
<button type="submit" style="all:unset">
<i class="icon ion-md-add"></i>
</button>
@@ -137,7 +136,7 @@
</div>
</a>
<% end %>
- <p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p>
+ <p><a href="/watch?v=<%= item.id %>"><%= HTML.escape(item.title) %></a></p>
<p>
<b>
<a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
@@ -145,7 +144,7 @@
</p>
<h5 class="pure-g">
- <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.utc %>
+ <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp.try &.> Time.utc %>
<div class="pure-u-2-3"><%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.utc).ago, locale)) %></div>
<% elsif Time.utc - item.published > 1.minute %>
<div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr
index ba6311cb..0e6664fa 100644
--- a/src/invidious/views/components/player.ecr
+++ b/src/invidious/views/components/player.ecr
@@ -1,28 +1,25 @@
-<video style="outline:none;width:100%;background-color:#000" playsinline poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>"
- id="player" class="video-js player-style-<%= params.player_style %>"
- onmouseenter='this["data-title"]=this["title"];this["title"]=""'
- onmouseleave='this["title"]=this["data-title"];this["data-title"]=""'
- oncontextmenu='this["title"]=this["data-title"]'
+<video style="outline:none;width:100%;background-color:#000" playsinline poster="<%= thumbnail %>"
+ id="player" class="on-video_player video-js player-style-<%= params.player_style %>"
<% if params.autoplay %>autoplay<% end %>
<% if params.video_loop %>loop<% end %>
<% if params.controls %>controls<% end %>>
- <% if hlsvp && !CONFIG.disabled?("livestreams") %>
- <source src="<%= hlsvp %>?local=true" type="application/x-mpegURL" label="livestream">
+ <% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %>
+ <source src="<%= URI.parse(hlsvp).full_path %>?local=true" type="application/x-mpegURL" label="livestream">
<% else %>
<% if params.listen %>
<% audio_streams.each_with_index do |fmt, i| %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= i == 0 ? true : false %>">
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= i == 0 ? true : false %>">
<% end %>
<% else %>
<% if params.quality == "dash" %>
- <source src="/api/manifest/dash/id/<%= video.id %>?local=true" type='application/dash+xml' label="dash">
+ <source src="/api/manifest/dash/id/<%= video.id %>?local=true&unique_res=1" type='application/dash+xml' label="dash">
<% end %>
<% fmt_stream.each_with_index do |fmt, i| %>
<% if params.quality %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= params.quality == fmt["label"].split(" - ")[0] %>">
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["quality"] %>" selected="<%= params.quality == fmt["quality"] %>">
<% else %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= i == 0 ? true : false %>">
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["quality"] %>" selected="<%= i == 0 ? true : false %>">
<% end %>
<% end %>
<% end %>
@@ -39,12 +36,14 @@
<% end %>
</video>
-<script>
-var player_data = {
- aspect_ratio: '<%= aspect_ratio %>',
- title: "<%= video.title.dump_unquoted %>",
- description: "<%= HTML.escape(video.short_description) %>",
- thumbnail: "<%= thumbnail %>"
-}
+<script id="player_data" type="application/json">
+<%=
+{
+ "aspect_ratio" => aspect_ratio,
+ "title" => video.title,
+ "description" => HTML.escape(video.short_description),
+ "thumbnail" => thumbnail
+}.to_pretty_json
+%>
</script>
<script src="/js/player.js?v=<%= ASSET_COMMIT %>"></script>
diff --git a/src/invidious/views/components/player_sources.ecr b/src/invidious/views/components/player_sources.ecr
index d950e0da..d02f82d2 100644
--- a/src/invidious/views/components/player_sources.ecr
+++ b/src/invidious/views/components/player_sources.ecr
@@ -3,6 +3,8 @@
<link rel="stylesheet" href="/css/videojs.markers.min.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-share.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-vtt-thumbnails.css?v=<%= ASSET_COMMIT %>">
+<link rel="stylesheet" href="/css/videojs-vtt-thumbnails-fix.css?v=<%= ASSET_COMMIT %>">
+<script src="/js/global.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/video.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-contrib-quality-levels.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-http-source-selector.min.js?v=<%= ASSET_COMMIT %>"></script>
diff --git a/src/invidious/views/components/subscribe_widget.ecr b/src/invidious/views/components/subscribe_widget.ecr
index 471e6c1c..ac2fbf1d 100644
--- a/src/invidious/views/components/subscribe_widget.ecr
+++ b/src/invidious/views/components/subscribe_widget.ecr
@@ -19,15 +19,17 @@
</p>
<% end %>
- <script>
- var subscribe_data = {
- ucid: '<%= ucid %>',
- author: '<%= HTML.escape(author) %>',
- sub_count_text: '<%= HTML.escape(sub_count_text) %>',
- csrf_token: '<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>',
- subscribe_text: '<%= HTML.escape(translate(locale, "Subscribe")) %>',
- unsubscribe_text: '<%= HTML.escape(translate(locale, "Unsubscribe")) %>'
- }
+ <script id="subscribe_data" type="application/json">
+ <%=
+ {
+ "ucid" => ucid,
+ "author" => HTML.escape(author),
+ "sub_count_text" => HTML.escape(sub_count_text),
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || ""),
+ "subscribe_text" => HTML.escape(translate(locale, "Subscribe")),
+ "unsubscribe_text" => HTML.escape(translate(locale, "Unsubscribe"))
+ }.to_pretty_json
+ %>
</script>
<script src="/js/subscribe_widget.js?v=<%= ASSET_COMMIT %>"></script>
<% else %>
diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr
index 6c06bf2e..48dbc55f 100644
--- a/src/invidious/views/embed.ecr
+++ b/src/invidious/views/embed.ecr
@@ -10,33 +10,24 @@
<script src="/js/videojs-overlay.min.js?v=<%= ASSET_COMMIT %>"></script>
<link rel="stylesheet" href="/css/default.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/darktheme.css?v=<%= ASSET_COMMIT %>">
+ <link rel="stylesheet" href="/css/embed.css?v=<%= ASSET_COMMIT %>">
<title><%= HTML.escape(video.title) %> - Invidious</title>
- <style>
- #player {
- position: fixed;
- right: 0;
- bottom: 0;
- min-width: 100%;
- min-height: 100%;
- width: auto;
- height: auto;
- z-index: -100;
- }
- </style>
</head>
<body>
-<script>
-var video_data = {
- id: '<%= video.id %>',
- index: '<%= continuation %>',
- plid: '<%= plid %>',
- length_seconds: '<%= video.length_seconds.to_f %>',
- video_series: <%= video_series.to_json %>,
- params: <%= params.to_json %>,
- preferences: <%= preferences.to_json %>,
- premiere_timestamp: <%= video.premiere_timestamp.try &.to_unix || "null" %>
-}
+<script id="video_data" type="application/json">
+<%=
+{
+ "id" => video.id,
+ "index" => continuation,
+ "plid" => plid,
+ "length_seconds" => video.length_seconds.to_f,
+ "video_series" => video_series,
+ "params" => params,
+ "preferences" => preferences,
+ "premiere_timestamp" => video.premiere_timestamp.try &.to_unix
+}.to_pretty_json
+%>
</script>
<%= rendered "components/player" %>
diff --git a/src/invidious/views/history.ecr b/src/invidious/views/history.ecr
index 7d7ded2c..fe8c70b9 100644
--- a/src/invidious/views/history.ecr
+++ b/src/invidious/views/history.ecr
@@ -18,10 +18,12 @@
</div>
</div>
-<script>
-var watched_data = {
- csrf_token: '<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>',
-}
+<script id="watched_data" type="application/json">
+<%=
+{
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "")
+}.to_pretty_json
+%>
</script>
<script src="/js/watched_widget.js"></script>
@@ -34,10 +36,10 @@ var watched_data = {
<% if !env.get("preferences").as(Preferences).thin_mode %>
<div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item %>/mqdefault.jpg"/>
- <form onsubmit="return false" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
- <a onclick="mark_unwatched(this)" data-id="<%= item %>" href="javascript:void(0)">
+ <a data-onclick="mark_unwatched" data-id="<%= item %>" href="javascript:void(0)">
<button type="submit" style="all:unset">
<i class="icon ion-md-trash"></i>
</button>
diff --git a/src/invidious/views/login.ecr b/src/invidious/views/login.ecr
index 59fa90e5..b6e8117b 100644
--- a/src/invidious/views/login.ecr
+++ b/src/invidious/views/login.ecr
@@ -22,7 +22,43 @@
<hr>
<% case account_type when %>
- <% when "invidious" %>
+ <% when "google" %>
+ <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=google" method="post">
+ <fieldset>
+ <% if email %>
+ <input name="email" type="hidden" value="<%= email %>">
+ <% else %>
+ <label for="email"><%= translate(locale, "E-mail") %> :</label>
+ <input required class="pure-input-1" name="email" type="email" placeholder="<%= translate(locale, "E-mail") %>">
+ <% end %>
+
+ <% if password %>
+ <input name="password" type="hidden" value="<%= HTML.escape(password) %>">
+ <% else %>
+ <label for="password"><%= translate(locale, "Password") %> :</label>
+ <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
+ <% end %>
+
+ <% if prompt %>
+ <label for="tfa"><%= translate(locale, prompt) %> :</label>
+ <input required class="pure-input-1" name="tfa" type="text" placeholder="<%= translate(locale, prompt) %>">
+ <% end %>
+
+ <% if tfa %>
+ <input type="hidden" name="tfa" value="<%= tfa %>">
+ <% end %>
+
+ <% if captcha %>
+ <img style="width:50%" src="/Captcha?v=2&ctoken=<%= captcha[:tokens][0] %>"/>
+ <input type="hidden" name="token" value="<%= captcha[:tokens][0] %>">
+ <label for="answer"><%= translate(locale, "Answer") %> :</label>
+ <input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
+ <% end %>
+
+ <button type="submit" class="pure-button pure-button-primary"><%= translate(locale, "Sign In") %></button>
+ </fieldset>
+ </form>
+ <% else # "invidious" %>
<form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=invidious" method="post">
<fieldset>
<% if email %>
@@ -50,7 +86,7 @@
<input type="hidden" name="captcha_type" value="image">
<label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
<input type="text" name="answer" type="text" placeholder="h:mm:ss">
- <% when "text" %>
+ <% else # "text" %>
<% captcha = captcha.not_nil! %>
<% captcha[:tokens].each_with_index do |token, i| %>
<input type="hidden" name="token[<%= i %>]" value="<%= URI.encode_www_form(token) %>">
@@ -71,7 +107,7 @@
<%= translate(locale, "Text CAPTCHA") %>
</button>
</label>
- <% when "text" %>
+ <% else # "text" %>
<label>
<button type="submit" name="change_type" class="pure-button pure-button-primary" value="image">
<%= translate(locale, "Image CAPTCHA") %>
@@ -85,42 +121,6 @@
<% end %>
</fieldset>
</form>
- <% when "google" %>
- <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=google" method="post">
- <fieldset>
- <% if email %>
- <input name="email" type="hidden" value="<%= email %>">
- <% else %>
- <label for="email"><%= translate(locale, "E-mail") %> :</label>
- <input required class="pure-input-1" name="email" type="email" placeholder="<%= translate(locale, "E-mail") %>">
- <% end %>
-
- <% if password %>
- <input name="password" type="hidden" value="<%= HTML.escape(password) %>">
- <% else %>
- <label for="password"><%= translate(locale, "Password") %> :</label>
- <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
- <% end %>
-
- <% if prompt %>
- <label for="tfa"><%= translate(locale, prompt) %> :</label>
- <input required class="pure-input-1" name="tfa" type="text" placeholder="<%= translate(locale, prompt) %>">
- <% end %>
-
- <% if tfa %>
- <input type="hidden" name="tfa" value="<%= tfa %>">
- <% end %>
-
- <% if captcha %>
- <img style="width:50%" src="/Captcha?v=2&ctoken=<%= captcha[:tokens][0] %>"/>
- <input type="hidden" name="token" value="<%= captcha[:tokens][0] %>">
- <label for="answer"><%= translate(locale, "Answer") %> :</label>
- <input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
- <% end %>
-
- <button type="submit" class="pure-button pure-button-primary"><%= translate(locale, "Sign In") %></button>
- </fieldset>
- </form>
<% end %>
</div>
</div>
diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr
index cb643aaa..bb721c3a 100644
--- a/src/invidious/views/playlist.ecr
+++ b/src/invidious/views/playlist.ecr
@@ -45,6 +45,12 @@
<% if playlist.is_a?(InvidiousPlaylist) && playlist.author == user.try &.email %>
<div class="pure-u-1-3"><a href="/edit_playlist?list=<%= plid %>"><i class="icon ion-md-create"></i></a></div>
<div class="pure-u-1-3"><a href="/delete_playlist?list=<%= plid %>"><i class="icon ion-md-trash"></i></a></div>
+ <% else %>
+ <% if PG_DB.query_one?("SELECT id FROM playlists WHERE id = $1", playlist.id, as: String).nil? %>
+ <div class="pure-u-1-3"><a href="/subscribe_playlist?list=<%= plid %>"><i class="icon ion-md-add"></i></a></div>
+ <% else %>
+ <div class="pure-u-1-3"><a href="/delete_playlist?list=<%= plid %>"><i class="icon ion-md-trash"></i></a></div>
+ <% end %>
<% end %>
<div class="pure-u-1-3"><a href="/feed/playlist/<%= plid %>"><i class="icon ion-logo-rss"></i></a></div>
</div>
@@ -69,12 +75,14 @@
</div>
<% if playlist.is_a?(InvidiousPlaylist) && playlist.author == user.try &.email %>
-<script>
-var playlist_data = {
- csrf_token: '<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>',
-}
+<script id="playlist_data" type="application/json">
+<%=
+{
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "")
+}.to_pretty_json
+%>
</script>
-<script src="/js/playlist_widget.js"></script>
+<script src="/js/playlist_widget.js?v=<%= ASSET_COMMIT %>"></script>
<% end %>
<div class="pure-g">
diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr
index a32192b5..0c48be96 100644
--- a/src/invidious/views/playlists.ecr
+++ b/src/invidious/views/playlists.ecr
@@ -90,7 +90,7 @@
<div class="pure-u-1 pure-u-md-4-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if continuation %>
- <a href="/channel/<%= channel.ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= sort_by %><% end %>">
+ <a href="/channel/<%= channel.ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 17e5804e..fb5bd44b 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -2,12 +2,6 @@
<title><%= translate(locale, "Preferences") %> - Invidious</title>
<% end %>
-<script>
-function update_value(element) {
- document.getElementById('volume-value').innerText = element.value;
-}
-</script>
-
<div class="h-box">
<form class="pure-form pure-form-aligned" action="/preferences?referer=<%= URI.encode_www_form(referer) %>" method="post">
<fieldset>
@@ -65,7 +59,7 @@ function update_value(element) {
<div class="pure-control-group">
<label for="volume"><%= translate(locale, "Player volume: ") %></label>
- <input name="volume" id="volume" oninput="update_value(this);" type="range" min="0" max="100" step="5" value="<%= preferences.volume %>">
+ <input name="volume" id="volume" data-onrange="update_volume_value" type="range" min="0" max="100" step="5" value="<%= preferences.volume %>">
<span class="pure-form-message-inline" id="volume-value"><%= preferences.volume %></span>
</div>
@@ -205,7 +199,7 @@ function update_value(element) {
<% # Web notifications are only supported over HTTPS %>
<% if Kemal.config.ssl || config.https_only %>
<div class="pure-control-group">
- <a href="#" onclick="Notification.requestPermission()"><%= translate(locale, "Enable web notifications") %></a>
+ <a href="#" data-onclick="notification_requestPermission"><%= translate(locale, "Enable web notifications") %></a>
</div>
<% end %>
<% end %>
@@ -234,11 +228,6 @@ function update_value(element) {
</div>
<div class="pure-control-group">
- <label for="top_enabled"><%= translate(locale, "Top enabled: ") %></label>
- <input name="top_enabled" id="top_enabled" type="checkbox" <% if config.top_enabled %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
<label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled: ") %></label>
<input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>>
</div>
diff --git a/src/invidious/views/subscription_manager.ecr b/src/invidious/views/subscription_manager.ecr
index 43d14b37..6cddcd6c 100644
--- a/src/invidious/views/subscription_manager.ecr
+++ b/src/invidious/views/subscription_manager.ecr
@@ -37,9 +37,9 @@
<div class="pure-u-2-5"></div>
<div class="pure-u-1-5" style="text-align:right">
<h3 style="padding-right:0.5em">
- <form onsubmit="return false" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= channel.id %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= channel.id %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
- <a onclick="remove_subscription(this)" data-ucid="<%= channel.id %>" href="#">
+ <a data-onclick="remove_subscription" data-ucid="<%= channel.id %>" href="#">
<input style="all:unset" type="submit" value="<%= translate(locale, "unsubscribe") %>">
</a>
</form>
@@ -52,32 +52,3 @@
<% end %>
</div>
<% end %>
-
-<script>
-function remove_subscription(target) {
- var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
- row.style.display = 'none';
- var count = document.getElementById('count');
- count.innerText = count.innerText - 1;
-
- var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
- '&referer=<%= env.get("current_page") %>' +
- '&c=' + target.getAttribute('data-ucid');
- var xhr = new XMLHttpRequest();
- xhr.responseType = 'json';
- xhr.timeout = 10000;
- xhr.open('POST', url, true);
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status != 200) {
- count.innerText = parseInt(count.innerText) + 1;
- row.style.display = '';
- }
- }
- }
-
- xhr.send('csrf_token=<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>');
-}
-</script>
diff --git a/src/invidious/views/subscriptions.ecr b/src/invidious/views/subscriptions.ecr
index ee31d241..af1d4fbc 100644
--- a/src/invidious/views/subscriptions.ecr
+++ b/src/invidious/views/subscriptions.ecr
@@ -45,10 +45,12 @@
<hr>
</div>
-<script>
-var watched_data = {
- csrf_token: '<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>',
-}
+<script id="watched_data" type="application/json">
+<%=
+{
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "")
+}.to_pretty_json
+%>
</script>
<script src="/js/watched_widget.js"></script>
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index b7cf2dcb..61cf5c3a 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -111,7 +111,7 @@
<div class="footer">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3">
- <a href="https://github.com/omarroth/invidious">
+ <a href="https://github.com/iv-org/invidious">
<%= translate(locale, "Released under the AGPLv3 by Omar Roth.") %>
</a>
</div>
@@ -140,23 +140,24 @@
</div>
<div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-github"></i>
- <%= translate(locale, "Current version: ") %> <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %>
- <i class="icon ion-logo-github"></i>
- <%= CURRENT_BRANCH %>
+ <%= translate(locale, "Current version: ") %> <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %> @ <%= CURRENT_BRANCH %>
</div>
</div>
</div>
</div>
<div class="pure-u-1 pure-u-md-2-24"></div>
</div>
+ <script src="/js/handlers.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/themes.js?v=<%= ASSET_COMMIT %>"></script>
<% if env.get? "user" %>
<script src="/js/sse.js?v=<%= ASSET_COMMIT %>"></script>
- <script>
- var notification_data = {
- upload_text: '<%= HTML.escape(translate(locale, "`x` uploaded a video")) %>',
- live_upload_text: '<%= HTML.escape(translate(locale, "`x` is live")) %>',
- }
+ <script id="notification_data" type="application/json">
+ <%=
+ {
+ "upload_text" => HTML.escape(translate(locale, "`x` uploaded a video")),
+ "live_upload_text" => HTML.escape(translate(locale, "`x` is live"))
+ }.to_pretty_json
+ %>
</script>
<script src="/js/notifications.js?v=<%= ASSET_COMMIT %>"></script>
<% end %>
diff --git a/src/invidious/views/token_manager.ecr b/src/invidious/views/token_manager.ecr
index b626d99c..e48aec2f 100644
--- a/src/invidious/views/token_manager.ecr
+++ b/src/invidious/views/token_manager.ecr
@@ -29,9 +29,9 @@
</div>
<div class="pure-u-1-5" style="text-align:right">
<h3 style="padding-right:0.5em">
- <form onsubmit="return false" action="/token_ajax?action_revoke_token=1&session=<%= token[:session] %>&referer=<%= env.get("current_page") %>" method="post">
+ <form data-onsubmit="return_false" action="/token_ajax?action_revoke_token=1&session=<%= token[:session] %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
- <a onclick="revoke_token(this)" data-session="<%= token[:session] %>" href="#">
+ <a data-onclick="revoke_token" data-session="<%= token[:session] %>" href="#">
<input style="all:unset" type="submit" value="<%= translate(locale, "revoke") %>">
</a>
</form>
@@ -44,32 +44,3 @@
<% end %>
</div>
<% end %>
-
-<script>
-function revoke_token(target) {
- var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
- row.style.display = 'none';
- var count = document.getElementById('count');
- count.innerText = count.innerText - 1;
-
- var url = '/token_ajax?action_revoke_token=1&redirect=false' +
- '&referer=<%= env.get("current_page") %>' +
- '&session=' + target.getAttribute('data-session');
- var xhr = new XMLHttpRequest();
- xhr.responseType = 'json';
- xhr.timeout = 10000;
- xhr.open('POST', url, true);
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status != 200) {
- count.innerText = parseInt(count.innerText) + 1;
- row.style.display = '';
- }
- }
- }
-
- xhr.send('csrf_token=<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>');
-}
-</script>
diff --git a/src/invidious/views/top.ecr b/src/invidious/views/top.ecr
deleted file mode 100644
index f5db3aaa..00000000
--- a/src/invidious/views/top.ecr
+++ /dev/null
@@ -1,20 +0,0 @@
-<% content_for "header" do %>
-<meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>">
-<title>
- <% if env.get("preferences").as(Preferences).default_home != "Top" %>
- <%= translate(locale, "Top") %> - Invidious
- <% else %>
- Invidious
- <% end %>
-</title>
-<% end %>
-
-<%= rendered "components/feed_menu" %>
-
-<div class="pure-g">
- <% top_videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
- <% end %>
-</div>
diff --git a/src/invidious/views/view_all_playlists.ecr b/src/invidious/views/view_all_playlists.ecr
index 0fa7a325..5ec6aa31 100644
--- a/src/invidious/views/view_all_playlists.ecr
+++ b/src/invidious/views/view_all_playlists.ecr
@@ -6,7 +6,7 @@
<div class="pure-g h-box">
<div class="pure-u-2-3">
- <h3><%= translate(locale, "`x` playlists", %(<span id="count">#{items.size}</span>)) %></h3>
+ <h3><%= translate(locale, "`x` created playlists", %(<span id="count">#{items_created.size}</span>)) %></h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
@@ -16,7 +16,21 @@
</div>
<div class="pure-g">
- <% items.each_slice(4) do |slice| %>
+ <% items_created.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
+</div>
+
+<div class="pure-g h-box">
+ <div class="pure-u-1">
+ <h3><%= translate(locale, "`x` saved playlists", %(<span id="count">#{items_saved.size}</span>)) %></h3>
+ </div>
+</div>
+
+<div class="pure-g">
+ <% items_saved.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index df61abc5..9a1e6c32 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -3,47 +3,49 @@
<meta name="description" content="<%= HTML.escape(video.short_description) %>">
<meta name="keywords" content="<%= video.keywords.join(",") %>">
<meta property="og:site_name" content="Invidious">
-<meta property="og:url" content="<%= host_url %>/watch?v=<%= video.id %>">
+<meta property="og:url" content="<%= HOST_URL %>/watch?v=<%= video.id %>">
<meta property="og:title" content="<%= HTML.escape(video.title) %>">
<meta property="og:image" content="/vi/<%= video.id %>/maxres.jpg">
-<meta property="og:description" content="<%= HTML.escape(video.short_description) %>">
+<meta property="og:description" content="<%= video.short_description %>">
<meta property="og:type" content="video.other">
-<meta property="og:video:url" content="<%= host_url %>/embed/<%= video.id %>">
-<meta property="og:video:secure_url" content="<%= host_url %>/embed/<%= video.id %>">
+<meta property="og:video:url" content="<%= HOST_URL %>/embed/<%= video.id %>">
+<meta property="og:video:secure_url" content="<%= HOST_URL %>/embed/<%= video.id %>">
<meta property="og:video:type" content="text/html">
<meta property="og:video:width" content="1280">
<meta property="og:video:height" content="720">
<meta name="twitter:card" content="player">
<meta name="twitter:site" content="@omarroth1">
-<meta name="twitter:url" content="<%= host_url %>/watch?v=<%= video.id %>">
+<meta name="twitter:url" content="<%= HOST_URL %>/watch?v=<%= video.id %>">
<meta name="twitter:title" content="<%= HTML.escape(video.title) %>">
-<meta name="twitter:description" content="<%= HTML.escape(video.short_description) %>">
-<meta name="twitter:image" content="<%= host_url %>/vi/<%= video.id %>/maxres.jpg">
-<meta name="twitter:player" content="<%= host_url %>/embed/<%= video.id %>">
+<meta name="twitter:description" content="<%= video.short_description %>">
+<meta name="twitter:image" content="<%= HOST_URL %>/vi/<%= video.id %>/maxres.jpg">
+<meta name="twitter:player" content="<%= HOST_URL %>/embed/<%= video.id %>">
<meta name="twitter:player:width" content="1280">
<meta name="twitter:player:height" content="720">
<%= rendered "components/player_sources" %>
<title><%= HTML.escape(video.title) %> - Invidious</title>
<% end %>
-<script>
-var video_data = {
- id: '<%= video.id %>',
- index: '<%= continuation %>',
- plid: '<%= plid %>',
- length_seconds: <%= video.length_seconds.to_f %>,
- play_next: <%= !rvs.empty? && !plid && params.continue %>,
- next_video: '<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>',
- youtube_comments_text: '<%= HTML.escape(translate(locale, "View YouTube comments")) %>',
- reddit_comments_text: '<%= HTML.escape(translate(locale, "View Reddit comments")) %>',
- reddit_permalink_text: '<%= HTML.escape(translate(locale, "View more comments on Reddit")) %>',
- comments_text: '<%= HTML.escape(translate(locale, "View `x` comments", "{commentCount}")) %>',
- hide_replies_text: '<%= HTML.escape(translate(locale, "Hide replies")) %>',
- show_replies_text: '<%= HTML.escape(translate(locale, "Show replies")) %>',
- params: <%= params.to_json %>,
- preferences: <%= preferences.to_json %>,
- premiere_timestamp: <%= video.premiere_timestamp.try &.to_unix || "null" %>
-}
+<script id="video_data" type="application/json">
+<%=
+{
+ "id" => video.id,
+ "index" => continuation,
+ "plid" => plid,
+ "length_seconds" => video.length_seconds.to_f,
+ "play_next" => !video.related_videos.empty? && !plid && params.continue,
+ "next_video" => video.related_videos.select { |rv| rv["id"]? }[0]?.try &.["id"],
+ "youtube_comments_text" => HTML.escape(translate(locale, "View YouTube comments")),
+ "reddit_comments_text" => HTML.escape(translate(locale, "View Reddit comments")),
+ "reddit_permalink_text" => HTML.escape(translate(locale, "View more comments on Reddit")),
+ "comments_text" => HTML.escape(translate(locale, "View `x` comments", "{commentCount}")),
+ "hide_replies_text" => HTML.escape(translate(locale, "Hide replies")),
+ "show_replies_text" => HTML.escape(translate(locale, "Show replies")),
+ "params" => params,
+ "preferences" => preferences,
+ "premiere_timestamp" => video.premiere_timestamp.try &.to_unix
+}.to_pretty_json
+%>
</script>
<div id="player-container" class="h-box">
@@ -70,13 +72,13 @@ var video_data = {
</h3>
<% end %>
- <% if !reason.empty? %>
+ <% if video.reason %>
<h3>
- <%= reason %>
+ <%= video.reason %>
</h3>
- <% elsif video.premiere_timestamp %>
+ <% elsif video.premiere_timestamp.try &.> Time.utc %>
<h3>
- <%= translate(locale, "Premieres in `x`", recode_date((video.premiere_timestamp.as(Time) - Time.utc).ago, locale)) %>
+ <%= video.premiere_timestamp.try { |t| translate(locale, "Premieres in `x`", recode_date((t - Time.utc).ago, locale)) } %>
</h3>
<% end %>
</div>
@@ -84,10 +86,10 @@ var video_data = {
<div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-5">
<div class="h-box">
- <span>
+ <span id="watch-on-youtube">
<a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a>
</span>
- <p>
+ <p id="annotations">
<% if params.annotations %>
<a href="/watch?<%= env.params.query %>&iv_load_policy=3">
<%= translate(locale, "Hide annotations") %>
@@ -99,26 +101,54 @@ var video_data = {
<% end %>
</p>
+ <% if user %>
+ <% playlists = PG_DB.query_all("SELECT id,title FROM playlists WHERE author = $1 AND id LIKE 'IV%'", user.email, as: {String, String}) %>
+ <% if !playlists.empty? %>
+ <form data-onsubmit="return_false" class="pure-form pure-form-stacked" action="/playlist_ajax" method="post">
+ <div class="pure-control-group">
+ <label for="playlist_id"><%= translate(locale, "Add to playlist: ") %></label>
+ <select style="width:100%" name="playlist_id" id="playlist_id">
+ <% playlists.each do |plid, title| %>
+ <option data-plid="<%= plid %>" value="<%= plid %>"><%= title %></option>
+ <% end %>
+ </select>
+ </div>
+
+ <button data-onclick="add_playlist_video" data-id="<%= video.id %>" type="submit" class="pure-button pure-button-primary">
+ <b><%= translate(locale, "Add to playlist") %></b>
+ </button>
+ </form>
+ <script id="playlist_data" type="application/json">
+ <%=
+ {
+ "csrf_token" => URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "")
+ }.to_pretty_json
+ %>
+ </script>
+ <script src="/js/playlist_widget.js?v=<%= Time.utc.to_unix_ms %>"></script>
+ <% end %>
+ <% end %>
+
<% if CONFIG.dmca_content.includes?(video.id) || CONFIG.disabled?("downloads") %>
- <p><%= translate(locale, "Download is disabled.") %></p>
+ <p id="download"><%= translate(locale, "Download is disabled.") %></p>
<% else %>
<form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank">
<div class="pure-control-group">
<label for="download_widget"><%= translate(locale, "Download as: ") %></label>
<select style="width:100%" name="download_widget" id="download_widget">
<% fmt_stream.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %>
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["mimeType"].as_s.split(";")[0].split("/")[1] %>"}'>
+ <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["mimeType"].as_s.split(";")[0] %>
</option>
<% end %>
<% video_streams.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["mimeType"].as_s.split(";")[0].split("/")[1] %>"}'>
+ <%= option["qualityLabel"] %> - <%= option["mimeType"].as_s.split(";")[0] %> @ <%= option["fps"] %>fps - video only
</option>
<% end %>
<% audio_streams.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.encode_www_form(video.title) %>-<%= video.id %>.<%= option["mimeType"].as_s.split(";")[0].split("/")[1] %>"}'>
+ <%= option["mimeType"].as_s.split(";")[0] %> @ <%= option["bitrate"]?.try &.as_i./ 1000 %>k - audio only
</option>
<% end %>
<% captions.each do |caption| %>
@@ -135,23 +165,23 @@ var video_data = {
</form>
<% end %>
- <p><i class="icon ion-ios-eye"></i> <%= number_with_separator(video.views) %></p>
- <p><i class="icon ion-ios-thumbs-up"></i> <%= number_with_separator(video.likes) %></p>
- <p><i class="icon ion-ios-thumbs-down"></i> <%= number_with_separator(video.dislikes) %></p>
+ <p id="views"><i class="icon ion-ios-eye"></i> <%= number_with_separator(video.views) %></p>
+ <p id="likes"><i class="icon ion-ios-thumbs-up"></i> <%= number_with_separator(video.likes) %></p>
+ <p id="dislikes"><i class="icon ion-ios-thumbs-down"></i> <%= number_with_separator(video.dislikes) %></p>
<p id="genre"><%= translate(locale, "Genre: ") %>
- <% if video.genre_url.empty? %>
+ <% if !video.genre_url %>
<%= video.genre %>
<% else %>
<a href="<%= video.genre_url %>"><%= video.genre %></a>
<% end %>
</p>
- <% if !video.license.empty? %>
+ <% if video.license %>
<p id="license"><%= translate(locale, "License: ") %><%= video.license %></p>
<% end %>
<p id="family_friendly"><%= translate(locale, "Family friendly? ") %><%= translate_bool(locale, video.is_family_friendly) %></p>
- <p id="wilson"><%= translate(locale, "Wilson score: ") %><%= video.wilson_score.round(4) %></p>
- <p id="rating"><%= translate(locale, "Rating: ") %><%= rating.round(4) %> / 5</p>
- <p id="engagement"><%= translate(locale, "Engagement: ") %><%= engagement.round(2) %>%</p>
+ <p id="wilson"><%= translate(locale, "Wilson score: ") %><%= video.wilson_score %></p>
+ <p id="rating"><%= translate(locale, "Rating: ") %><%= video.average_rating %> / 5</p>
+ <p id="engagement"><%= translate(locale, "Engagement: ") %><%= video.engagement %>%</p>
<% if video.allowed_regions.size != REGIONS.size %>
<p id="allowed_regions">
<% if video.allowed_regions.size < REGIONS.size // 2 %>
@@ -168,8 +198,10 @@ var video_data = {
<div class="h-box">
<a href="/channel/<%= video.ucid %>" style="display:block;width:fit-content;width:-moz-fit-content">
<div class="channel-profile">
- <img src="/ggpht<%= URI.parse(video.author_thumbnail).full_path %>">
- <span><%= video.author %></span>
+ <% if !video.author_thumbnail.empty? %>
+ <img src="/ggpht<%= URI.parse(video.author_thumbnail).full_path %>">
+ <% end %>
+ <span id="channel-name"><%= video.author %></span>
</div>
</a>
@@ -178,9 +210,9 @@ var video_data = {
<% sub_count_text = video.sub_count_text %>
<%= rendered "components/subscribe_widget" %>
- <p>
- <% if video.premiere_timestamp %>
- <b><%= translate(locale, "Premieres `x`", video.premiere_timestamp.not_nil!.to_s("%B %-d, %R UTC")) %></b>
+ <p id="published-date">
+ <% if video.premiere_timestamp.try &.> Time.utc %>
+ <b><%= video.premiere_timestamp.try { |t| translate(locale, "Premieres `x`", t.to_s("%B %-d, %R UTC")) } %></b>
<% else %>
<b><%= translate(locale, "Shared `x`", video.published.to_s("%B %-d, %Y")) %></b>
<% end %>
@@ -214,7 +246,7 @@ var video_data = {
<% if params.related_videos %>
<div class="h-box">
- <% if !rvs.empty? %>
+ <% if !video.related_videos.empty? %>
<div <% if plid %>style="display:none"<% end %>>
<div class="pure-control-group">
<label for="continue"><%= translate(locale, "Play next by default: ") %></label>
@@ -224,7 +256,7 @@ var video_data = {
</div>
<% end %>
- <% rvs.each do |rv| %>
+ <% video.related_videos.each do |rv| %>
<% if rv["id"]? %>
<a href="/watch?v=<%= rv["id"] %>">
<% if !env.get("preferences").as(Preferences).thin_mode %>
@@ -237,15 +269,17 @@ var video_data = {
<h5 class="pure-g">
<div class="pure-u-14-24">
<% if rv["ucid"]? %>
- <b style="width:100%"><a href="/channel/<%= rv["ucid"] %>"><%= rv["author"] %></a></b>
+ <b style="width:100%"><a href="/channel/<%= rv["ucid"] %>"><%= rv["author"]? %></a></b>
<% else %>
- <b style="width:100%"><%= rv["author"] %></b>
+ <b style="width:100%"><%= rv["author"]? %></b>
<% end %>
</div>
<div class="pure-u-10-24" style="text-align:right">
<% if views = rv["short_view_count_text"]?.try &.delete(", views watching") %>
- <b class="width:100%"><%= translate(locale, "`x` views", views) %></b>
+ <% if !views.empty? %>
+ <b class="width:100%"><%= translate(locale, "`x` views", views) %></b>
+ <% end %>
<% end %>
</div>
</h5>