diff --git a/admin/presets/tests/generator/lib.php b/admin/presets/tests/generator/lib.php index b5a385c752a1..8d6ffc9385de 100644 --- a/admin/presets/tests/generator/lib.php +++ b/admin/presets/tests/generator/lib.php @@ -227,7 +227,6 @@ private function add_to_config_log(string $name, string $oldvalue, string $value public function access_protected($object, string $property) { $reflection = new ReflectionClass($object); $property = $reflection->getProperty($property); - $property->setAccessible(true); return $property->getValue($object); } @@ -244,7 +243,6 @@ public function get_admin_preset_setting(string $category, string $settingname): // Set method accessibility. $method = new ReflectionMethod(manager::class, 'get_setting'); - $method->setAccessible(true); // Get the proper adminpresets_setting instance. $settingpage = $adminroot->locate($category); diff --git a/admin/settings/plugins.php b/admin/settings/plugins.php index 33ddda707519..43909fba3469 100644 --- a/admin/settings/plugins.php +++ b/admin/settings/plugins.php @@ -135,6 +135,18 @@ $temp->add($setting); $ADMIN->add('authsettings', $temp); + // Toggle password visiblity icon. + $temp->add(new admin_setting_configselect('loginpasswordtoggle', + new lang_string('auth_loginpasswordtoggle', 'auth'), + new lang_string('auth_loginpasswordtoggle_desc', 'auth'), + TOGGLE_SENSITIVE_SMALL_SCREENS_ONLY, + [ + TOGGLE_SENSITIVE_DISABLED => get_string('disabled', 'admin'), + TOGGLE_SENSITIVE_ENABLED => get_string('enabled', 'admin'), + TOGGLE_SENSITIVE_SMALL_SCREENS_ONLY => get_string('smallscreensonly', 'admin'), + ], + )); + $temp = new admin_externalpage('authtestsettings', get_string('testsettings', 'core_auth'), new moodle_url("/auth/test_settings.php"), 'moodle/site:config', true); $ADMIN->add('authsettings', $temp); diff --git a/admin/tool/dataprivacy/tests/expired_contexts_test.php b/admin/tool/dataprivacy/tests/expired_contexts_test.php index abd8d997d6d6..ae50fbf2510b 100644 --- a/admin/tool/dataprivacy/tests/expired_contexts_test.php +++ b/admin/tool/dataprivacy/tests/expired_contexts_test.php @@ -2079,7 +2079,6 @@ public function test_progress_tracer_default() { $rc = new \ReflectionClass(\tool_dataprivacy\expired_contexts_manager::class); $rcm = $rc->getMethod('get_progress'); - $rcm->setAccessible(true); $this->assertInstanceOf(\text_progress_trace::class, $rcm->invoke($manager)); } @@ -2094,7 +2093,6 @@ public function test_progress_tracer_set() { $rc = new \ReflectionClass(\tool_dataprivacy\expired_contexts_manager::class); $rcm = $rc->getMethod('get_progress'); - $rcm->setAccessible(true); $this->assertSame($mytrace, $rcm->invoke($manager)); } diff --git a/admin/tool/dataprivacy/tests/filtered_userlist_test.php b/admin/tool/dataprivacy/tests/filtered_userlist_test.php index 7d71da163707..4146e0ec7845 100644 --- a/admin/tool/dataprivacy/tests/filtered_userlist_test.php +++ b/admin/tool/dataprivacy/tests/filtered_userlist_test.php @@ -41,7 +41,6 @@ public function test_apply_expired_contexts_filters(array $initial, array $expir $rc = new \ReflectionClass(\tool_dataprivacy\filtered_userlist::class); $rcm = $rc->getMethod('set_userids'); - $rcm->setAccessible(true); $rcm->invoke($userlist, $initial); diff --git a/admin/tool/langimport/tests/locale_test.php b/admin/tool/langimport/tests/locale_test.php index f2f121525adc..dbe51337b75d 100644 --- a/admin/tool/langimport/tests/locale_test.php +++ b/admin/tool/langimport/tests/locale_test.php @@ -84,7 +84,6 @@ public function test_set_locale(string $set, string $ret) { $loc = new locale(); $rc = new \ReflectionClass(locale::class); $rm = $rc->getMethod('set_locale'); - $rm->setAccessible(true); // Capture current locale for later restore (funnily, using the set_locale() method itself. $originallocale = $rm->invokeArgs($loc, [LC_ALL, 0]); diff --git a/admin/tool/licensemanager/tests/manager_test.php b/admin/tool/licensemanager/tests/manager_test.php index 2b9763c4ed49..3fdc0dcbf1a7 100644 --- a/admin/tool/licensemanager/tests/manager_test.php +++ b/admin/tool/licensemanager/tests/manager_test.php @@ -70,7 +70,6 @@ public function test_edit_existing_license() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'edit'); - $method->setAccessible(true); // Allow accessing of private method. $method->invoke($manager, \tool_licensemanager\manager::ACTION_UPDATE, $testlicense->shortname); // Should not create a new license when updating an existing license. @@ -90,7 +89,6 @@ public function test_edit_license_not_exists() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'edit'); - $method->setAccessible(true); // Allow accessing of private method. // Attempt to update a license that doesn't exist. $formdata = [ @@ -111,7 +109,6 @@ public function test_edit_license_no_shortname() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'edit'); - $method->setAccessible(true); // Allow accessing of private method. // Attempt to update a license without passing license shortname. $formdata = [ @@ -148,7 +145,6 @@ public function test_edit_create_license() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'edit'); - $method->setAccessible(true); // Allow accessing of private method. $method->invoke($manager, \tool_licensemanager\manager::ACTION_CREATE, $formdata['shortname']); // Should create a new license in database. @@ -180,7 +176,6 @@ public function test_change_license_order() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod('\tool_licensemanager\manager', 'change_license_order'); - $method->setAccessible(true); // Allow accessing of private method. $method->invoke($manager, \tool_licensemanager\manager::ACTION_MOVE_UP, 'cc-nc-4.0'); $licenseorder = array_keys(license_manager::get_licenses()); diff --git a/admin/tool/mfa/factor/email/tests/factor_test.php b/admin/tool/mfa/factor/email/tests/factor_test.php index e0923555e70f..55a45585eda3 100644 --- a/admin/tool/mfa/factor/email/tests/factor_test.php +++ b/admin/tool/mfa/factor/email/tests/factor_test.php @@ -39,7 +39,6 @@ public function test_check_verification_code() { $emailfactorclass = new \factor_email\factor('email'); $rc = new \ReflectionClass($emailfactorclass::class); $rcm = $rc->getMethod('check_verification_code'); - $rcm->setAccessible(true); // Assigned email to be used in getting the email factor. $USER->email = 'user@mail.com'; @@ -76,7 +75,6 @@ public function test_check_verification_code() { // Cleans up email records once MFA passed. $rcm = $rc->getMethod('post_pass_state'); - $rcm->setAccessible(true); $rcm->invoke($emailfactorclass); // Check if the email records have been deleted. diff --git a/admin/tool/mfa/factor/sms/tests/factor_test.php b/admin/tool/mfa/factor/sms/tests/factor_test.php index 978916fc1b43..49e3e9a33139 100644 --- a/admin/tool/mfa/factor/sms/tests/factor_test.php +++ b/admin/tool/mfa/factor/sms/tests/factor_test.php @@ -154,7 +154,6 @@ public function test_check_verification_code(): void { // Check verification code. $rcm = $rc->getMethod('check_verification_code'); - $rcm->setAccessible(true); $this->assertTrue($rcm->invoke($smsfactor, $secretcode)); // Test that calling the revoke on the generic type revokes all. diff --git a/admin/tool/mfa/factor/token/tests/factor_test.php b/admin/tool/mfa/factor/token/tests/factor_test.php index 3a0b1450c66e..62c63cd92dd6 100644 --- a/admin/tool/mfa/factor/token/tests/factor_test.php +++ b/admin/tool/mfa/factor/token/tests/factor_test.php @@ -50,7 +50,6 @@ public function test_calculate_expiry_time_in_general() { set_config('expireovernight', 0, 'factor_token'); $method = new \ReflectionMethod($this->factor, 'calculate_expiry_time'); - $method->setAccessible(true); // Test that non-overnight timestamps are just exactly as configured. // We don't need to care about 0 or negative ints, they will just make the cookie expire immediately. @@ -95,7 +94,6 @@ public function test_calculate_expiry_time_in_general() { public function test_calculate_expiry_time_for_overnight_expiry_with_one_day_expiry($timestamp) { // Setup configuration. $method = new \ReflectionMethod($this->factor, 'calculate_expiry_time'); - $method->setAccessible(true); set_config('expireovernight', 1, 'factor_token'); set_config('expiry', DAYSECS, 'factor_token'); @@ -144,7 +142,6 @@ public function test_calculate_expiry_time_for_overnight_expiry_with_one_day_exp public function test_calculate_expiry_time_for_overnight_expiry_with_two_day_expiry($timestamp) { // Setup configuration. $method = new \ReflectionMethod($this->factor, 'calculate_expiry_time'); - $method->setAccessible(true); set_config('expireovernight', 1, 'factor_token'); set_config('expiry', 2 * DAYSECS, 'factor_token'); @@ -195,7 +192,6 @@ public function test_calculate_expiry_time_for_overnight_expiry_with_two_day_exp public function test_calculate_expiry_time_for_overnight_expiry_with_three_hour_expiry($timestamp) { // Setup configuration. $method = new \ReflectionMethod($this->factor, 'calculate_expiry_time'); - $method->setAccessible(true); set_config('expireovernight', 1, 'factor_token'); set_config('expiry', 3 * HOURSECS, 'factor_token'); @@ -240,7 +236,6 @@ public function test_calculate_expiry_time_for_overnight_expiry_with_three_hour_ public function test_calculate_expiry_time_for_overnight_expiry_with_an_hour_expiry($timestamp) { // Setup configuration. $method = new \ReflectionMethod($this->factor, 'calculate_expiry_time'); - $method->setAccessible(true); set_config('expireovernight', 1, 'factor_token'); set_config('expiry', HOURSECS, 'factor_token'); diff --git a/admin/tool/mfa/tests/secret_manager_test.php b/admin/tool/mfa/tests/secret_manager_test.php index b9b293f52ee8..d426dfe0b8f2 100644 --- a/admin/tool/mfa/tests/secret_manager_test.php +++ b/admin/tool/mfa/tests/secret_manager_test.php @@ -42,7 +42,6 @@ public function test_create_secret() { // Mutate the sessionid using reflection. $reflectedsessionid = new \ReflectionProperty($secman, 'sessionid'); - $reflectedsessionid->setAccessible(true); $reflectedsessionid->setValue($secman, 'fakesession'); $sec1 = $secman->create_secret(1800, false); @@ -97,7 +96,6 @@ public function test_add_secret_to_db() { // Let's make stuff public using reflection. $reflectedscanner = new \ReflectionClass($secman); $reflectedmethod = $reflectedscanner->getMethod('add_secret_to_db'); - $reflectedmethod->setAccessible(true); // Now add a secret and confirm it creates the correct record. $reflectedmethod->invoke($secman, 'code', 1800); @@ -164,7 +162,6 @@ public function test_validate_secret() { // Session locked code from the same session id. // Mutate the sessionid using reflection. $reflectedsessionid = new \ReflectionProperty($secman, 'sessionid'); - $reflectedsessionid->setAccessible(true); $reflectedsessionid->setValue($secman, 'fakesession'); $secret = $secman->create_secret(1800, true); @@ -227,7 +224,6 @@ public function test_has_active_secret() { $reflectedscanner = new \ReflectionClass($secman); $reflectedmethod = $reflectedscanner->getMethod('has_active_secret'); - $reflectedmethod->setAccessible(true); // DB secrets. $this->assertFalse($reflectedmethod->invoke($secman)); @@ -244,7 +240,6 @@ public function test_has_active_secret() { // Now check a secret with session involvement. // Mutate the sessionid using reflection. $reflectedsessionid = new \ReflectionProperty($secman, 'sessionid'); - $reflectedsessionid->setAccessible(true); $reflectedsessionid->setValue($secman, 'fakesession'); $this->assertFalse($reflectedmethod->invoke($secman, true)); diff --git a/admin/tool/mobile/classes/local/hooks/output/standard_head_html_prepend.php b/admin/tool/mobile/classes/local/hook/output/before_standard_head_html_generation.php similarity index 86% rename from admin/tool/mobile/classes/local/hooks/output/standard_head_html_prepend.php rename to admin/tool/mobile/classes/local/hook/output/before_standard_head_html_generation.php index f349ea392606..7d4ddbb4dcc3 100644 --- a/admin/tool/mobile/classes/local/hooks/output/standard_head_html_prepend.php +++ b/admin/tool/mobile/classes/local/hook/output/before_standard_head_html_generation.php @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -namespace tool_mobile\local\hooks\output; +namespace tool_mobile\local\hook\output; /** * Allows plugins to add any elements to the page html tag @@ -23,14 +23,13 @@ * @copyright 2023 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class standard_head_html_prepend { - +class before_standard_head_html_generation { /** * Callback to add head elements. * - * @param \core\hook\output\standard_head_html_prepend $hook + * @param \core\hook\output\before_standard_head_html_generation $hook */ - public static function callback(\core\hook\output\standard_head_html_prepend $hook): void { + public static function callback(\core\hook\output\before_standard_head_html_generation $hook): void { global $CFG, $PAGE; // Smart App Banners meta tag is only displayed if mobile services are enabled and configured. if (!empty($CFG->enablemobilewebservice)) { @@ -45,7 +44,7 @@ public static function callback(\core\hook\output\standard_head_html_prepend $ho if (!empty($mobilesettings->androidappid)) { $mobilemanifesturl = "$CFG->wwwroot/$CFG->admin/tool/mobile/mobile.webmanifest.php"; - $hook->add_html(''); + $hook->add_html(''); } } } diff --git a/admin/tool/mobile/db/hooks.php b/admin/tool/mobile/db/hooks.php index 60e2d927e8c8..91b54ffc7a5f 100644 --- a/admin/tool/mobile/db/hooks.php +++ b/admin/tool/mobile/db/hooks.php @@ -26,8 +26,8 @@ $callbacks = [ [ - 'hook' => core\hook\output\standard_head_html_prepend::class, - 'callback' => 'tool_mobile\local\hooks\output\standard_head_html_prepend::callback', + 'hook' => core\hook\output\before_standard_head_html_generation::class, + 'callback' => 'tool_mobile\local\hook\output\before_standard_head_html_generation::callback', 'priority' => 0, ], ]; diff --git a/admin/tool/mobile/version.php b/admin/tool/mobile/version.php index 7f18ff304820..adf67504ef0d 100644 --- a/admin/tool/mobile/version.php +++ b/admin/tool/mobile/version.php @@ -23,7 +23,7 @@ */ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2023100900; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2024022600; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2023100400; // Requires this Moodle version. $plugin->component = 'tool_mobile'; // Full name of the plugin (used for diagnostics). $plugin->dependencies = [ diff --git a/admin/tool/usertours/classes/cache.php b/admin/tool/usertours/classes/cache.php index 28f5eb34e10d..a053fc5fd11f 100644 --- a/admin/tool/usertours/classes/cache.php +++ b/admin/tool/usertours/classes/cache.php @@ -14,21 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Cache manager. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; -defined('MOODLE_INTERNAL') || die(); - /** * Cache manager. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -97,7 +88,7 @@ public static function get_matching_tourdata(\moodle_url $targetmatch) { } $target = $targetmatch->out_as_local_url(); - return array_filter($tours, function($tour) use ($possiblematches, $target) { + return array_filter($tours, function ($tour) use ($possiblematches, $target) { if (in_array($tour->pathmatch, $possiblematches)) { return true; } diff --git a/admin/tool/usertours/classes/configuration.php b/admin/tool/usertours/classes/configuration.php index ae63554eb30e..2f18c29be7b7 100644 --- a/admin/tool/usertours/classes/configuration.php +++ b/admin/tool/usertours/classes/configuration.php @@ -14,26 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Step configuration detail class. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; -defined('MOODLE_INTERNAL') || die(); - /** * Step configuration detail class. * - * @copyright 2016 Andrew Nicols + * @package tool_usertours + * @copyright 2024 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class configuration { - /** * @var TOURDEFAULT */ @@ -60,7 +50,7 @@ public static function get_defaultable_keys() { * @return mixed */ public static function get_default_value($key) { - switch($key) { + switch ($key) { case 'placement': return 'bottom'; case 'orphan': @@ -77,7 +67,7 @@ public static function get_default_value($key) { * @return mixed */ public static function get_step_default_value($key) { - switch($key) { + switch ($key) { case 'placement': case 'orphan': case 'backdrop': @@ -94,10 +84,10 @@ public static function get_step_default_value($key) { */ public static function get_placement_options($default = null) { $values = [ - 'top' => get_string('above', 'tool_usertours'), - 'bottom' => get_string('below', 'tool_usertours'), - 'left' => get_string('left', 'tool_usertours'), - 'right' => get_string('right', 'tool_usertours'), + 'top' => get_string('above', 'tool_usertours'), + 'bottom' => get_string('below', 'tool_usertours'), + 'left' => get_string('left', 'tool_usertours'), + 'right' => get_string('right', 'tool_usertours'), ]; if ($default === null) { @@ -114,5 +104,4 @@ public static function get_placement_options($default = null) { return $values; } - } diff --git a/admin/tool/usertours/classes/event/step_shown.php b/admin/tool/usertours/classes/event/step_shown.php index 3537b61f7b7a..72ff3b4a6d52 100644 --- a/admin/tool/usertours/classes/event/step_shown.php +++ b/admin/tool/usertours/classes/event/step_shown.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The tool_usertours step_shown event. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\event; -defined('MOODLE_INTERNAL') || die(); - /** * The tool_usertours step_shown event. * @@ -41,7 +31,6 @@ * } */ class step_shown extends \core\event\base { - /** * Init method. */ diff --git a/admin/tool/usertours/classes/event/tour_ended.php b/admin/tool/usertours/classes/event/tour_ended.php index 945d1e4eeb92..6853dd4a8605 100644 --- a/admin/tool/usertours/classes/event/tour_ended.php +++ b/admin/tool/usertours/classes/event/tour_ended.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The tool_usertours tour_ended event. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\event; -defined('MOODLE_INTERNAL') || die(); - /** * The tool_usertours tour_ended event. * @@ -41,7 +31,6 @@ * } */ class tour_ended extends \core\event\base { - /** * Init method. */ diff --git a/admin/tool/usertours/classes/event/tour_reset.php b/admin/tool/usertours/classes/event/tour_reset.php index bd9e60d02c22..660f35f5db12 100644 --- a/admin/tool/usertours/classes/event/tour_reset.php +++ b/admin/tool/usertours/classes/event/tour_reset.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The tool_usertours tour_reset event. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\event; -defined('MOODLE_INTERNAL') || die(); - /** * The tool_usertours tour_reset event. * @@ -41,7 +31,6 @@ * } */ class tour_reset extends \core\event\base { - /** * Init method. */ diff --git a/admin/tool/usertours/classes/event/tour_started.php b/admin/tool/usertours/classes/event/tour_started.php index 915cb586de37..d44114f051c2 100644 --- a/admin/tool/usertours/classes/event/tour_started.php +++ b/admin/tool/usertours/classes/event/tour_started.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The tool_usertours tour_started event. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\event; -defined('MOODLE_INTERNAL') || die(); - /** * The tool_usertours tour_started event. * @@ -41,7 +31,6 @@ * } */ class tour_started extends \core\event\base { - /** * Init method. */ diff --git a/admin/tool/usertours/classes/external/tour.php b/admin/tool/usertours/classes/external/tour.php index 649becb5de8d..9ecad8e43ac2 100644 --- a/admin/tool/usertours/classes/external/tour.php +++ b/admin/tool/usertours/classes/external/tour.php @@ -43,10 +43,10 @@ public static function fetch_and_start_tour($tourid, $context, $pageurl) { global $PAGE; $params = self::validate_parameters(self::fetch_and_start_tour_parameters(), [ - 'tourid' => $tourid, - 'context' => $context, - 'pageurl' => $pageurl, - ]); + 'tourid' => $tourid, + 'context' => $context, + 'pageurl' => $pageurl, + ]); $context = \context_helper::instance_by_id($params['context']); self::validate_context($context); @@ -60,8 +60,8 @@ public static function fetch_and_start_tour($tourid, $context, $pageurl) { \tool_usertours\event\tour_started::create([ 'contextid' => $context->id, - 'objectid' => $tour->get_id(), - 'other' => [ + 'objectid' => $tour->get_id(), + 'other' => [ 'pageurl' => $params['pageurl'], ], ])->trigger(); @@ -78,9 +78,9 @@ public static function fetch_and_start_tour($tourid, $context, $pageurl) { */ public static function fetch_and_start_tour_parameters() { return new external_function_parameters([ - 'tourid' => new external_value(PARAM_INT, 'Tour ID'), - 'context' => new external_value(PARAM_INT, 'Context ID'), - 'pageurl' => new external_value(PARAM_URL, 'Page URL'), + 'tourid' => new external_value(PARAM_INT, 'Tour ID'), + 'context' => new external_value(PARAM_INT, 'Context ID'), + 'pageurl' => new external_value(PARAM_URL, 'Page URL'), ]); } @@ -91,12 +91,12 @@ public static function fetch_and_start_tour_parameters() { */ public static function fetch_and_start_tour_returns() { return new external_single_structure([ - 'tourconfig' => new external_single_structure([ - 'name' => new external_value(PARAM_RAW, 'Tour Name'), - 'steps' => new external_multiple_structure(self::step_structure_returns()), - 'endtourlabel' => new external_value(PARAM_RAW, 'Label of the end tour button'), + 'tourconfig' => new external_single_structure([ + 'name' => new external_value(PARAM_RAW, 'Tour Name'), + 'steps' => new external_multiple_structure(self::step_structure_returns()), + 'endtourlabel' => new external_value(PARAM_RAW, 'Label of the end tour button'), 'displaystepnumbers' => new external_value(PARAM_BOOL, 'display step number'), - ], 'Tour config', VALUE_OPTIONAL) + ], 'Tour config', VALUE_OPTIONAL), ]); } @@ -110,10 +110,10 @@ public static function fetch_and_start_tour_returns() { */ public static function reset_tour($tourid, $context, $pageurl) { $params = self::validate_parameters(self::reset_tour_parameters(), [ - 'tourid' => $tourid, - 'context' => $context, - 'pageurl' => $pageurl, - ]); + 'tourid' => $tourid, + 'context' => $context, + 'pageurl' => $pageurl, + ]); $context = \context_helper::instance_by_id($params['context']); self::validate_context($context); @@ -130,9 +130,9 @@ public static function reset_tour($tourid, $context, $pageurl) { \tool_usertours\event\tour_reset::create([ 'contextid' => $context->id, - 'objectid' => $params['tourid'], - 'other' => [ - 'pageurl' => $params['pageurl'], + 'objectid' => $params['tourid'], + 'other' => [ + 'pageurl' => $params['pageurl'], ], ])->trigger(); break; @@ -149,9 +149,9 @@ public static function reset_tour($tourid, $context, $pageurl) { */ public static function reset_tour_parameters() { return new external_function_parameters([ - 'tourid' => new external_value(PARAM_INT, 'Tour ID'), - 'context' => new external_value(PARAM_INT, 'Context ID'), - 'pageurl' => new external_value(PARAM_URL, 'Current page location'), + 'tourid' => new external_value(PARAM_INT, 'Tour ID'), + 'context' => new external_value(PARAM_INT, 'Context ID'), + 'pageurl' => new external_value(PARAM_URL, 'Current page location'), ]); } @@ -162,7 +162,7 @@ public static function reset_tour_parameters() { */ public static function reset_tour_returns() { return new external_single_structure([ - 'startTour' => new external_value(PARAM_INT, 'Tour ID', VALUE_OPTIONAL), + 'startTour' => new external_value(PARAM_INT, 'Tour ID', VALUE_OPTIONAL), ]); } @@ -178,25 +178,26 @@ public static function reset_tour_returns() { */ public static function complete_tour($tourid, $context, $pageurl, $stepid, $stepindex) { $params = self::validate_parameters(self::complete_tour_parameters(), [ - 'tourid' => $tourid, - 'context' => $context, - 'pageurl' => $pageurl, - 'stepid' => $stepid, - 'stepindex' => $stepindex, - ]); + 'tourid' => $tourid, + 'context' => $context, + 'pageurl' => $pageurl, + 'stepid' => $stepid, + 'stepindex' => $stepindex, + ]); $context = \context_helper::instance_by_id($params['context']); self::validate_context($context); $tour = tourinstance::instance($params['tourid']); + $tour->mark_user_completed(); \tool_usertours\event\tour_ended::create([ 'contextid' => $context->id, - 'objectid' => $params['tourid'], - 'other' => [ - 'pageurl' => $params['pageurl'], - 'stepid' => $params['stepid'], + 'objectid' => $params['tourid'], + 'other' => [ + 'pageurl' => $params['pageurl'], + 'stepid' => $params['stepid'], 'stepindex' => $params['stepindex'], ], ])->trigger(); @@ -211,10 +212,10 @@ public static function complete_tour($tourid, $context, $pageurl, $stepid, $step */ public static function complete_tour_parameters() { return new external_function_parameters([ - 'tourid' => new external_value(PARAM_INT, 'Tour ID'), - 'context' => new external_value(PARAM_INT, 'Context ID'), - 'pageurl' => new external_value(PARAM_LOCALURL, 'Page URL'), - 'stepid' => new external_value(PARAM_INT, 'Step ID'), + 'tourid' => new external_value(PARAM_INT, 'Tour ID'), + 'context' => new external_value(PARAM_INT, 'Context ID'), + 'pageurl' => new external_value(PARAM_LOCALURL, 'Page URL'), + 'stepid' => new external_value(PARAM_INT, 'Step ID'), 'stepindex' => new external_value(PARAM_INT, 'Step Number'), ]); } @@ -240,12 +241,12 @@ public static function complete_tour_returns() { */ public static function step_shown($tourid, $context, $pageurl, $stepid, $stepindex) { $params = self::validate_parameters(self::step_shown_parameters(), [ - 'tourid' => $tourid, - 'context' => $context, - 'pageurl' => $pageurl, - 'stepid' => $stepid, - 'stepindex' => $stepindex, - ]); + 'tourid' => $tourid, + 'context' => $context, + 'pageurl' => $pageurl, + 'stepid' => $stepid, + 'stepindex' => $stepindex, + ]); $context = \context_helper::instance_by_id($params['context']); self::validate_context($context); @@ -257,11 +258,11 @@ public static function step_shown($tourid, $context, $pageurl, $stepid, $stepind \tool_usertours\event\step_shown::create([ 'contextid' => $context->id, - 'objectid' => $params['stepid'], + 'objectid' => $params['stepid'], - 'other' => [ - 'pageurl' => $params['pageurl'], - 'tourid' => $params['tourid'], + 'other' => [ + 'pageurl' => $params['pageurl'], + 'tourid' => $params['tourid'], 'stepindex' => $params['stepindex'], ], ])->trigger(); @@ -276,10 +277,10 @@ public static function step_shown($tourid, $context, $pageurl, $stepid, $stepind */ public static function step_shown_parameters() { return new external_function_parameters([ - 'tourid' => new external_value(PARAM_INT, 'Tour ID'), - 'context' => new external_value(PARAM_INT, 'Context ID'), - 'pageurl' => new external_value(PARAM_URL, 'Page URL'), - 'stepid' => new external_value(PARAM_INT, 'Step ID'), + 'tourid' => new external_value(PARAM_INT, 'Tour ID'), + 'context' => new external_value(PARAM_INT, 'Context ID'), + 'pageurl' => new external_value(PARAM_URL, 'Page URL'), + 'stepid' => new external_value(PARAM_INT, 'Step ID'), 'stepindex' => new external_value(PARAM_INT, 'Step Number'), ]); } @@ -300,24 +301,47 @@ public static function step_shown_returns() { */ public static function step_structure_returns() { return new external_single_structure([ - 'title' => new external_value(PARAM_RAW, - 'Step Title'), - 'content' => new external_value(PARAM_RAW, - 'Step Content'), - 'element' => new external_value(PARAM_TEXT, - 'Step Target'), - 'placement' => new external_value(PARAM_TEXT, - 'Step Placement'), - 'delay' => new external_value(PARAM_INT, - 'Delay before showing the step (ms)', VALUE_OPTIONAL), - 'backdrop' => new external_value(PARAM_BOOL, - 'Whether a backdrop should be used', VALUE_OPTIONAL), - 'reflex' => new external_value(PARAM_BOOL, - 'Whether to move to the next step when the target element is clicked', VALUE_OPTIONAL), - 'orphan' => new external_value(PARAM_BOOL, - 'Whether to display the step even if it could not be found', VALUE_OPTIONAL), - 'stepid' => new external_value(PARAM_INT, - 'The actual ID of the step', VALUE_OPTIONAL), + 'title' => new external_value( + PARAM_RAW, + 'Step Title' + ), + 'content' => new external_value( + PARAM_RAW, + 'Step Content' + ), + 'element' => new external_value( + PARAM_TEXT, + 'Step Target' + ), + 'placement' => new external_value( + PARAM_TEXT, + 'Step Placement' + ), + 'delay' => new external_value( + PARAM_INT, + 'Delay before showing the step (ms)', + VALUE_OPTIONAL + ), + 'backdrop' => new external_value( + PARAM_BOOL, + 'Whether a backdrop should be used', + VALUE_OPTIONAL + ), + 'reflex' => new external_value( + PARAM_BOOL, + 'Whether to move to the next step when the target element is clicked', + VALUE_OPTIONAL + ), + 'orphan' => new external_value( + PARAM_BOOL, + 'Whether to display the step even if it could not be found', + VALUE_OPTIONAL + ), + 'stepid' => new external_value( + PARAM_INT, + 'The actual ID of the step', + VALUE_OPTIONAL + ), ]); } } diff --git a/admin/tool/usertours/classes/helper.php b/admin/tool/usertours/classes/helper.php index 6c2befa697a9..8327dbd0ed44 100644 --- a/admin/tool/usertours/classes/helper.php +++ b/admin/tool/usertours/classes/helper.php @@ -14,29 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Tour helper. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; use core\output\inplace_editable; -use tool_usertours\local\clientside_filter\clientside_filter; - -defined('MOODLE_INTERNAL') || die(); /** * Tour helper. * * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @package tool_usertours */ class helper { - /** * @var MOVE_UP */ @@ -158,10 +147,10 @@ public static function get_view_tour_link($tourid) { */ public static function get_reset_tour_for_all_link($tourid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ - 'id' => $tourid, - 'action' => manager::ACTION_RESETFORALL, - 'sesskey' => sesskey(), - ]); + 'id' => $tourid, + 'action' => manager::ACTION_RESETFORALL, + 'sesskey' => sesskey(), + ]); } /** @@ -204,9 +193,9 @@ public static function get_import_tour_link() { */ public static function get_export_tour_link($tourid) { $link = new \moodle_url('/admin/tool/usertours/configure.php', [ - 'action' => manager::ACTION_EXPORTTOUR, - 'id' => $tourid, - ]); + 'action' => manager::ACTION_EXPORTTOUR, + 'id' => $tourid, + ]); return $link; } @@ -219,8 +208,8 @@ public static function get_export_tour_link($tourid) { */ public static function get_duplicate_tour_link($tourid) { $link = new \moodle_url('/admin/tool/usertours/configure.php', [ - 'action' => manager::ACTION_DUPLICATETOUR, - 'id' => $tourid, + 'action' => manager::ACTION_DUPLICATETOUR, + 'id' => $tourid, ]); return $link; @@ -234,10 +223,10 @@ public static function get_duplicate_tour_link($tourid) { */ public static function get_delete_tour_link($tourid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ - 'id' => $tourid, - 'action' => manager::ACTION_DELETETOUR, - 'sesskey' => sesskey(), - ]); + 'id' => $tourid, + 'action' => manager::ACTION_DELETETOUR, + 'sesskey' => sesskey(), + ]); } /** @@ -262,18 +251,17 @@ public static function get_list_tour_link() { * @param array $options Display options. * @return string */ - public static function format_icon_link($url, $icon, $alt, $iconcomponent = 'moodle', $options = array()) { + public static function format_icon_link($url, $icon, $alt, $iconcomponent = 'moodle', $options = []) { global $OUTPUT; return $OUTPUT->action_icon( - $url, - new \pix_icon($icon, $alt, $iconcomponent, [ - 'title' => $alt, - ]), - null, - $options - ); - + $url, + new \pix_icon($icon, $alt, $iconcomponent, [ + 'title' => $alt, + ]), + null, + $options + ); } /** @@ -282,7 +270,7 @@ public static function format_icon_link($url, $icon, $alt, $iconcomponent = 'moo * @param array $options Display options. * @return string */ - public static function get_filler_icon($options = array()) { + public static function get_filler_icon($options = []) { global $OUTPUT; return \html_writer::span( @@ -299,10 +287,10 @@ public static function get_filler_icon($options = array()) { */ public static function get_delete_step_link($stepid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ - 'action' => manager::ACTION_DELETESTEP, - 'id' => $stepid, - 'sesskey' => sesskey(), - ]); + 'action' => manager::ACTION_DELETESTEP, + 'id' => $stepid, + 'sesskey' => sesskey(), + ]); } /** @@ -314,16 +302,16 @@ public static function get_delete_step_link($stepid) { public static function render_tourname_inplace_editable(tour $tour): inplace_editable { $name = format_text(static::get_string_from_input($tour->get_name()), FORMAT_HTML); return new inplace_editable( - 'tool_usertours', - 'tourname', - $tour->get_id(), - true, - \html_writer::link( - $tour->get_view_link(), - $name - ), - $tour->get_name() - ); + 'tool_usertours', + 'tourname', + $tour->get_id(), + true, + \html_writer::link( + $tour->get_view_link(), + $name + ), + $tour->get_name() + ); } /** @@ -335,13 +323,13 @@ public static function render_tourname_inplace_editable(tour $tour): inplace_edi public static function render_tourdescription_inplace_editable(tour $tour): inplace_editable { $description = format_text(static::get_string_from_input($tour->get_description()), FORMAT_HTML); return new inplace_editable( - 'tool_usertours', - 'tourdescription', - $tour->get_id(), - true, - $description, - $tour->get_description() - ); + 'tool_usertours', + 'tourdescription', + $tour->get_id(), + true, + $description, + $tour->get_description() + ); } /** @@ -364,15 +352,15 @@ public static function render_tourenabled_inplace_editable(tour $tour): inplace_ } $editable = new inplace_editable( - 'tool_usertours', - 'tourenabled', - $tour->get_id(), - true, - $OUTPUT->pix_icon($icon, $alt, 'moodle', [ - 'title' => $alt, - ]), - $value - ); + 'tool_usertours', + 'tourenabled', + $tour->get_id(), + true, + $OUTPUT->pix_icon($icon, $alt, 'moodle', [ + 'title' => $alt, + ]), + $value + ); $editable->set_type_toggle(); return $editable; @@ -388,16 +376,16 @@ public static function render_stepname_inplace_editable(step $step): inplace_edi $title = format_text(static::get_string_from_input($step->get_title()), FORMAT_HTML); return new inplace_editable( - 'tool_usertours', - 'stepname', - $step->get_id(), - true, - \html_writer::link( - $step->get_edit_link(), - $title - ), - $step->get_title() - ); + 'tool_usertours', + 'stepname', + $step->get_id(), + true, + \html_writer::link( + $step->get_edit_link(), + $title + ), + $step->get_title() + ); } /** @@ -408,7 +396,7 @@ public static function render_stepname_inplace_editable(step $step): inplace_edi public static function get_tours() { global $DB; - $tours = $DB->get_records('tool_usertours_tours', array(), 'sortorder ASC'); + $tours = $DB->get_records('tool_usertours_tours', [], 'sortorder ASC'); $return = []; foreach ($tours as $tour) { $return[$tour->id] = tour::load_from_record($tour); @@ -435,7 +423,7 @@ public static function get_tour($tourid) { public static function get_tour_from_sortorder($sortorder) { global $DB; - $tour = $DB->get_record('tool_usertours_tours', array('sortorder' => $sortorder)); + $tour = $DB->get_record('tool_usertours_tours', ['sortorder' => $sortorder]); return tour::load_from_record($tour); } @@ -460,7 +448,7 @@ public static function reset_tour_sortorder() { $index = 0; foreach ($tours as $tour) { if ($tour->sortorder != $index) { - $DB->set_field('tool_usertours_tours', 'sortorder', $index, array('id' => $tour->id)); + $DB->set_field('tool_usertours_tours', 'sortorder', $index, ['id' => $tour->id]); } $index++; } @@ -508,7 +496,7 @@ public static function get_step($stepid) { public static function get_step_from_sortorder($tourid, $sortorder) { global $DB; - $step = $DB->get_record('tool_usertours_steps', array('tourid' => $tourid, 'sortorder' => $sortorder)); + $step = $DB->get_record('tool_usertours_steps', ['tourid' => $tourid, 'sortorder' => $sortorder]); return step::load_from_record($step); } @@ -538,11 +526,11 @@ public static function bootstrap() { if ($tours) { $filters = static::get_all_clientside_filters(); - $tourdetails = array_map(function($tour) use ($filters) { + $tourdetails = array_map(function ($tour) use ($filters) { return [ - 'tourId' => $tour->get_id(), - 'startTour' => $tour->should_show_for_user(), - 'filtervalues' => $tour->get_client_filter_values($filters), + 'tourId' => $tour->get_id(), + 'startTour' => $tour->should_show_for_user(), + 'filtervalues' => $tour->get_client_filter_values($filters), ]; }, $tours); @@ -552,8 +540,8 @@ public static function bootstrap() { } $PAGE->requires->js_call_amd('tool_usertours/usertours', 'init', [ - $tourdetails, - $filternames, + $tourdetails, + $filternames, ]); } } @@ -567,7 +555,7 @@ public static function get_all_filters() { $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\filter'); $filters = array_keys($filters); - $filters = array_filter($filters, function($filterclass) { + $filters = array_filter($filters, function ($filterclass) { $rc = new \ReflectionClass($filterclass); return $rc->isInstantiable(); }); @@ -586,7 +574,7 @@ public static function get_all_clientside_filters() { $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\clientside_filter'); $filters = array_keys($filters); - $filters = array_filter($filters, function($filterclass) { + $filters = array_filter($filters, function ($filterclass) { $rc = new \ReflectionClass($filterclass); return $rc->isInstantiable(); }); diff --git a/admin/tool/usertours/classes/local/clientside_filter/clientside_filter.php b/admin/tool/usertours/classes/local/clientside_filter/clientside_filter.php index 6fa403ac57a0..ed394f29be63 100644 --- a/admin/tool/usertours/classes/local/clientside_filter/clientside_filter.php +++ b/admin/tool/usertours/classes/local/clientside_filter/clientside_filter.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Clientside filter base. - * - * @package tool_usertours - * @copyright 2020 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\clientside_filter; -defined('MOODLE_INTERNAL') || die(); - use stdClass; use tool_usertours\local\filter\base; use tool_usertours\tour; @@ -33,6 +23,7 @@ /** * Clientside filter base. * + * @package tool_usertours * @copyright 2020 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -46,10 +37,10 @@ abstract class clientside_filter extends base { public static function get_client_side_values(tour $tour): stdClass { $data = (object) []; - if (is_a(static::class, clientside_filter::class, true)) { + if (is_a(static::class, self::class, true)) { $data->filterdata = $tour->get_filter_values(static::get_filter_name()); } return $data; } -} \ No newline at end of file +} diff --git a/admin/tool/usertours/classes/local/clientside_filter/cssselector.php b/admin/tool/usertours/classes/local/clientside_filter/cssselector.php index e6d6c2d778eb..ef30c5895928 100644 --- a/admin/tool/usertours/classes/local/clientside_filter/cssselector.php +++ b/admin/tool/usertours/classes/local/clientside_filter/cssselector.php @@ -14,13 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Selector filter. - * - * @package tool_usertours - * @copyright 2020 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ namespace tool_usertours\local\clientside_filter; use stdClass; @@ -29,6 +22,7 @@ /** * Course filter. * + * @package tool_usertours * @copyright 2020 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -107,7 +101,7 @@ public static function get_client_side_values(tour $tour): stdClass { // Filter values might not exist for tours that were created before this filter existed. if (!$filtervalues) { - return new stdClass; + return new stdClass(); } return (object) $filtervalues; diff --git a/admin/tool/usertours/classes/local/filter/accessdate.php b/admin/tool/usertours/classes/local/filter/accessdate.php index 26fecd4b8c7e..7ca30008d65e 100644 --- a/admin/tool/usertours/classes/local/filter/accessdate.php +++ b/admin/tool/usertours/classes/local/filter/accessdate.php @@ -13,29 +13,19 @@ // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . - -/** - * Access Date filter. - * - * @package tool_usertours - * @copyright 2019 Tom Dickman - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use context; use tool_usertours\tour; /** * Access date filter. Used to determine if USER should see a tour based on a particular access date. * + * @package tool_usertours * @copyright 2019 Tom Dickman * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class accessdate extends base { - /** * Access date filtering constant for setting base date as account creation date. */ @@ -74,12 +64,11 @@ public static function get_filter_name() { */ public static function get_filter_options() { - return array( + return [ self::FILTER_ACCOUNT_CREATION => get_string('filter_date_account_creation', 'tool_usertours'), self::FILTER_FIRST_LOGIN => get_string('filter_date_first_login', 'tool_usertours'), self::FILTER_LAST_LOGIN => get_string('filter_date_last_login', 'tool_usertours'), - ); - + ]; } /** @@ -96,8 +85,14 @@ public static function add_filter_to_form(\MoodleQuickForm &$mform) { $range = "{$key}_range"; $enabled = "{$key}_enabled"; - $mform->addElement('advcheckbox', $enabled, get_string($key, 'tool_usertours'), - get_string('filter_accessdate_enabled', 'tool_usertours'), null, array(0, 1)); + $mform->addElement( + 'advcheckbox', + $enabled, + get_string($key, 'tool_usertours'), + get_string('filter_accessdate_enabled', 'tool_usertours'), + null, + [0, 1] + ); $mform->addHelpButton($enabled, $enabled, 'tool_usertours'); $mform->addElement('select', $key, ' ', self::get_filter_options()); @@ -110,7 +105,6 @@ public static function add_filter_to_form(\MoodleQuickForm &$mform) { ]); $mform->setDefault($range, 90 * DAYSECS); $mform->hideIf($range, $enabled, 'notchecked'); - } /** @@ -224,4 +218,4 @@ public static function filter_matches(tour $tour, context $context) { } return $result; } -} \ No newline at end of file +} diff --git a/admin/tool/usertours/classes/local/filter/base.php b/admin/tool/usertours/classes/local/filter/base.php index ff1de4442a97..fc73c58dedda 100644 --- a/admin/tool/usertours/classes/local/filter/base.php +++ b/admin/tool/usertours/classes/local/filter/base.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Filter base. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Filter base. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/filter/category.php b/admin/tool/usertours/classes/local/filter/category.php index 0b1f119853d9..fd5566d998c0 100644 --- a/admin/tool/usertours/classes/local/filter/category.php +++ b/admin/tool/usertours/classes/local/filter/category.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Category filter. - * - * @package tool_usertours - * @copyright 2017 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Category filter. * + * @package tool_usertours * @copyright 2017 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/filter/course.php b/admin/tool/usertours/classes/local/filter/course.php index 32fb21ddb5da..a440bc0598c7 100644 --- a/admin/tool/usertours/classes/local/filter/course.php +++ b/admin/tool/usertours/classes/local/filter/course.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Course filter. - * - * @package tool_usertours - * @copyright 2017 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Course filter. * + * @package tool_usertours * @copyright 2017 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/filter/courseformat.php b/admin/tool/usertours/classes/local/filter/courseformat.php index 95e2b7c86132..de2ca1435237 100644 --- a/admin/tool/usertours/classes/local/filter/courseformat.php +++ b/admin/tool/usertours/classes/local/filter/courseformat.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Course format filter. - * - * @package tool_usertours - * @copyright 2017 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Course format filter. * + * @package tool_usertours * @copyright 2017 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/filter/role.php b/admin/tool/usertours/classes/local/filter/role.php index a64ee83585c2..e3c67ebe5a23 100644 --- a/admin/tool/usertours/classes/local/filter/role.php +++ b/admin/tool/usertours/classes/local/filter/role.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Theme filter. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Theme filter. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -106,7 +97,7 @@ public static function filter_matches(tour $tour, context $context) { } // Use a request cache to save on DB queries. - // We may be checking multiple tours and they'll all be for the same userid, and contextid + // We may be checking multiple tours and they'll all be for the same userid, and contextid. $cache = \cache::make_from_params(\cache_store::MODE_REQUEST, 'tool_usertours', 'filter_role'); // Get all of the roles used in this context, including special roles such as user, and frontpageuser. diff --git a/admin/tool/usertours/classes/local/filter/theme.php b/admin/tool/usertours/classes/local/filter/theme.php index 786684c9c13f..e041d172cc37 100644 --- a/admin/tool/usertours/classes/local/filter/theme.php +++ b/admin/tool/usertours/classes/local/filter/theme.php @@ -14,24 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Theme filter. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\filter; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour; use context; /** * Theme filter. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/forms/editstep.php b/admin/tool/usertours/classes/local/forms/editstep.php index b9418e75e225..8c586101f33a 100644 --- a/admin/tool/usertours/classes/local/forms/editstep.php +++ b/admin/tool/usertours/classes/local/forms/editstep.php @@ -98,7 +98,7 @@ public function definition() { // Content type. $typeoptions = [ static::CONTENTTYPE_LANGSTRING => get_string('content_type_langstring', 'tool_usertours'), - static::CONTENTTYPE_MANUAL => get_string('content_type_manual', 'tool_usertours') + static::CONTENTTYPE_MANUAL => get_string('content_type_manual', 'tool_usertours'), ]; $mform->addElement('select', 'contenttype', get_string('content_type', 'tool_usertours'), $typeoptions); $mform->addHelpButton('contenttype', 'content_type', 'tool_usertours'); @@ -114,7 +114,7 @@ public function definition() { 'maxbytes' => $CFG->maxbytes, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'changeformat' => 1, - 'trusttext' => true + 'trusttext' => true, ]; $objs = $mform->createElement('editor', 'content', get_string('content', 'tool_usertours'), null, $editoroptions); // TODO: MDL-68540 We need to add the editor to a group element because editor element will not work with hideIf. diff --git a/admin/tool/usertours/classes/local/forms/edittour.php b/admin/tool/usertours/classes/local/forms/edittour.php index 80409b1aa783..cf6f50402cd9 100644 --- a/admin/tool/usertours/classes/local/forms/edittour.php +++ b/admin/tool/usertours/classes/local/forms/edittour.php @@ -28,7 +28,8 @@ require_once($CFG->libdir . '/formslib.php'); -use \tool_usertours\helper; +use tool_usertours\helper; +use tool_usertours\tour; /** * Form for editing tours. @@ -88,6 +89,17 @@ public function definition() { $mform->addElement('checkbox', 'displaystepnumbers', get_string('displaystepnumbers', 'tool_usertours')); $mform->addHelpButton('displaystepnumbers', 'displaystepnumbers', 'tool_usertours'); + $mform->addElement( + 'select', + 'showtourwhen', + get_string('showtourwhen', 'tool_usertours'), + [ + tour::SHOW_TOUR_UNTIL_COMPLETE => get_string('showtouruntilcomplete', 'tool_usertours'), + tour::SHOW_TOUR_ON_EACH_PAGE_VISIT => get_string('showtoureachtime', 'tool_usertours'), + ] + ); + $mform->setDefault('showtourwhen', tour::SHOW_TOUR_UNTIL_COMPLETE); + // Configuration. $this->tour->add_config_to_form($mform); diff --git a/admin/tool/usertours/classes/local/table/step_list.php b/admin/tool/usertours/classes/local/table/step_list.php index c774c6e63f6f..87937d7b0e11 100644 --- a/admin/tool/usertours/classes/local/table/step_list.php +++ b/admin/tool/usertours/classes/local/table/step_list.php @@ -39,7 +39,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class step_list extends \flexible_table { - /** * @var int $tourid The id of the tour. */ @@ -54,25 +53,25 @@ public function __construct($tourid) { parent::__construct('steps'); $this->tourid = $tourid; - $baseurl = new \moodle_url('/tool/usertours/configure.php', array( + $baseurl = new \moodle_url('/tool/usertours/configure.php', [ 'id' => $tourid, - )); + ]); $this->define_baseurl($baseurl); // Column definition. - $this->define_columns(array( + $this->define_columns([ 'title', 'content', 'target', 'actions', - )); + ]); - $this->define_headers(array( - get_string('title', 'tool_usertours'), + $this->define_headers([ + get_string('title', 'tool_usertours'), get_string('content', 'tool_usertours'), - get_string('target', 'tool_usertours'), + get_string('target', 'tool_usertours'), get_string('actions', 'tool_usertours'), - )); + ]); $this->set_attribute('class', 'admintable generaltable steptable'); $this->setup(); @@ -98,8 +97,14 @@ protected function col_title(step $step) { protected function col_content(step $step) { $content = $step->get_content(); $systemcontext = \context_system::instance(); - $content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $systemcontext->id, - 'tool_usertours', 'stepcontent', $step->get_id()); + $content = file_rewrite_pluginfile_urls( + $content, + 'pluginfile.php', + $systemcontext->id, + 'tool_usertours', + 'stepcontent', + $step->get_id() + ); $content = helper::get_string_from_input($content); $content = step::get_step_image_from_input($content); @@ -135,8 +140,11 @@ protected function col_actions(step $step) { if ($step->is_last_step()) { $actions[] = helper::get_filler_icon(); } else { - $actions[] = helper::format_icon_link($step->get_movedown_link(), 't/down', - get_string('movestepdown', 'tool_usertours')); + $actions[] = helper::format_icon_link( + $step->get_movedown_link(), + 't/down', + get_string('movestepdown', 'tool_usertours') + ); } $actions[] = helper::format_icon_link($step->get_edit_link(), 't/edit', get_string('edit')); diff --git a/admin/tool/usertours/classes/local/table/tour_list.php b/admin/tool/usertours/classes/local/table/tour_list.php index 0ea20a13dbc4..dd5298cd8d1c 100644 --- a/admin/tool/usertours/classes/local/table/tour_list.php +++ b/admin/tool/usertours/classes/local/table/tour_list.php @@ -38,7 +38,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tour_list extends \flexible_table { - /** @var int The count of all tours. */ protected int $tourcount = 0; @@ -52,21 +51,21 @@ public function __construct() { $this->define_baseurl($baseurl); // Column definition. - $this->define_columns(array( + $this->define_columns([ 'name', 'description', 'appliesto', 'enabled', 'actions', - )); + ]); - $this->define_headers(array( + $this->define_headers([ get_string('name', 'tool_usertours'), get_string('description', 'tool_usertours'), get_string('appliesto', 'tool_usertours'), get_string('enabled', 'tool_usertours'), get_string('actions', 'tool_usertours'), - )); + ]); $this->set_attribute('class', 'admintable generaltable'); $this->setup(); @@ -129,22 +128,32 @@ protected function col_actions(tour $tour) { if ($tour->is_first_tour()) { $actions[] = helper::get_filler_icon(); } else { - $actions[] = helper::format_icon_link($tour->get_moveup_link(), 't/up', - get_string('movetourup', 'tool_usertours')); + $actions[] = helper::format_icon_link( + $tour->get_moveup_link(), + 't/up', + get_string('movetourup', 'tool_usertours') + ); } if ($tour->is_last_tour($this->tourcount)) { $actions[] = helper::get_filler_icon(); } else { - $actions[] = helper::format_icon_link($tour->get_movedown_link(), 't/down', - get_string('movetourdown', 'tool_usertours')); + $actions[] = helper::format_icon_link( + $tour->get_movedown_link(), + 't/down', + get_string('movetourdown', 'tool_usertours') + ); } $actions[] = helper::format_icon_link($tour->get_view_link(), 't/viewdetails', get_string('view')); $actions[] = helper::format_icon_link($tour->get_edit_link(), 't/edit', get_string('edit')); $actions[] = helper::format_icon_link($tour->get_duplicate_link(), 't/copy', get_string('duplicate')); - $actions[] = helper::format_icon_link($tour->get_export_link(), 't/export', - get_string('exporttour', 'tool_usertours'), 'tool_usertours'); + $actions[] = helper::format_icon_link( + $tour->get_export_link(), + 't/export', + get_string('exporttour', 'tool_usertours'), + 'tool_usertours' + ); $actions[] = helper::format_icon_link($tour->get_delete_link(), 't/delete', get_string('delete'), null, [ 'data-action' => 'delete', 'data-id' => $tour->get_id(), diff --git a/admin/tool/usertours/classes/local/target/base.php b/admin/tool/usertours/classes/local/target/base.php index 663e5bf03b68..e3b829bfb049 100644 --- a/admin/tool/usertours/classes/local/target/base.php +++ b/admin/tool/usertours/classes/local/target/base.php @@ -14,23 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Target base. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\target; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\step; /** * Target base. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/local/target/block.php b/admin/tool/usertours/classes/local/target/block.php index 095e9018c4c9..06071c7d5cb9 100644 --- a/admin/tool/usertours/classes/local/target/block.php +++ b/admin/tool/usertours/classes/local/target/block.php @@ -14,28 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Block target. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\target; -defined('MOODLE_INTERNAL') || die(); - -use tool_usertours\step; - /** * Block target. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class block extends base { - /** * Convert the target value to a valid CSS selector for use in the * output configuration. @@ -101,8 +89,12 @@ public static function add_config_to_form(\MoodleQuickForm $mform) { * @param MoodleQuickForm $mform The form to add configuration to. */ public static function add_disabled_constraints_to_form(\MoodleQuickForm $mform) { - $mform->hideIf('targetvalue_block', 'targettype', 'noteq', - \tool_usertours\target::get_target_constant_for_class(self::class)); + $mform->hideIf( + 'targetvalue_block', + 'targettype', + 'noteq', + \tool_usertours\target::get_target_constant_for_class(self::class) + ); } /** diff --git a/admin/tool/usertours/classes/local/target/selector.php b/admin/tool/usertours/classes/local/target/selector.php index b0cc92682f03..16057c0e04c7 100644 --- a/admin/tool/usertours/classes/local/target/selector.php +++ b/admin/tool/usertours/classes/local/target/selector.php @@ -14,28 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Selector target. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\target; -defined('MOODLE_INTERNAL') || die(); - -use tool_usertours\step; - /** * Selector target. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class selector extends base { - /** * Convert the target value to a valid CSS selector for use in the * output configuration. @@ -91,8 +79,12 @@ public static function add_config_to_form(\MoodleQuickForm $mform) { * @param MoodleQuickForm $mform The form to add configuration to. */ public static function add_disabled_constraints_to_form(\MoodleQuickForm $mform) { - $mform->hideIf('targetvalue_selector', 'targettype', 'noteq', - \tool_usertours\target::get_target_constant_for_class(self::class)); + $mform->hideIf( + 'targetvalue_selector', + 'targettype', + 'noteq', + \tool_usertours\target::get_target_constant_for_class(self::class) + ); } /** diff --git a/admin/tool/usertours/classes/local/target/unattached.php b/admin/tool/usertours/classes/local/target/unattached.php index 316fdea4b853..0c5303687100 100644 --- a/admin/tool/usertours/classes/local/target/unattached.php +++ b/admin/tool/usertours/classes/local/target/unattached.php @@ -14,23 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * A step designed to be orphaned. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\local\target; -defined('MOODLE_INTERNAL') || die(); - -use tool_usertours\step; - /** * A step designed to be orphaned. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/manager.php b/admin/tool/usertours/classes/manager.php index ab207e6ce5c8..cd9c22ebfeed 100644 --- a/admin/tool/usertours/classes/manager.php +++ b/admin/tool/usertours/classes/manager.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Tour manager. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\local\forms; use tool_usertours\local\table; use core\notification; @@ -33,11 +23,11 @@ /** * Tour manager. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class manager { - /** * @var ACTION_LISTTOURS The action to get the list of tours. */ @@ -163,7 +153,7 @@ public function execute($action) { $PAGE->set_primary_active_tab('siteadminnode'); // Add the main content. - switch($action) { + switch ($action) { case self::ACTION_NEWTOUR: case self::ACTION_EDITTOUR: $this->edit_tour(optional_param('id', null, PARAM_INT)); @@ -356,7 +346,6 @@ protected function edit_tour($id = null) { if ($id) { $tour = tour::instance($id); $PAGE->navbar->add(helper::get_string_from_input($tour->get_name()), $tour->get_edit_link()); - } else { $tour = new tour(); $PAGE->navbar->add(get_string('newtour', 'tool_usertours'), $tour->get_edit_link()); @@ -374,6 +363,7 @@ protected function edit_tour($id = null) { $tour->set_enabled(!empty($data->enabled)); $tour->set_endtourlabel($data->endtourlabel); $tour->set_display_step_numbers(!empty($data->displaystepnumbers)); + $tour->set_showtourwhen($data->showtourwhen); foreach (configuration::get_defaultable_keys() as $key) { $tour->set_config($key, $data->$key); @@ -403,6 +393,7 @@ protected function edit_tour($id = null) { foreach (helper::get_all_filters() as $filterclass) { $filterclass::prepare_filter_values_for_form($tour, $data); } + $form->set_data($data); } @@ -568,7 +559,7 @@ protected function show_hide_tour($tourid, $visibility) { require_sesskey(); - $tour = $DB->get_record('tool_usertours_tours', array('id' => $tourid)); + $tour = $DB->get_record('tool_usertours_tours', ['id' => $tourid]); $tour->enabled = $visibility; $DB->update_record('tool_usertours_tours', $tour); @@ -784,9 +775,10 @@ protected function move_tour($id) { */ protected static function _move_tour(tour $tour, $direction) { // We can't move the first tour higher, nor the last tour any lower. - if (($tour->is_first_tour() && $direction == helper::MOVE_UP) || - ($tour->is_last_tour() && $direction == helper::MOVE_DOWN)) { - + if ( + ($tour->is_first_tour() && $direction == helper::MOVE_UP) || + ($tour->is_last_tour() && $direction == helper::MOVE_DOWN) + ) { return; } diff --git a/admin/tool/usertours/classes/output/renderer.php b/admin/tool/usertours/classes/output/renderer.php index 27c1ae37901c..6c9ed28f8ba4 100644 --- a/admin/tool/usertours/classes/output/renderer.php +++ b/admin/tool/usertours/classes/output/renderer.php @@ -14,21 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Renderer. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\output; -defined('MOODLE_INTERNAL') || die(); - /** * Renderer. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/admin/tool/usertours/classes/output/step.php b/admin/tool/usertours/classes/output/step.php index a3f5f81a0240..a85a0a5664ab 100644 --- a/admin/tool/usertours/classes/output/step.php +++ b/admin/tool/usertours/classes/output/step.php @@ -38,7 +38,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class step implements \renderable { - /** * @var The step instance. */ @@ -65,8 +64,14 @@ public function export_for_template(\renderer_base $output) { $content = $step->get_content(); $systemcontext = \context_system::instance(); - $content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $systemcontext->id, - 'tool_usertours', 'stepcontent', $step->get_id()); + $content = file_rewrite_pluginfile_urls( + $content, + 'pluginfile.php', + $systemcontext->id, + 'tool_usertours', + 'stepcontent', + $step->get_id() + ); $content = helper::get_string_from_input($content); $content = $step::get_step_image_from_input($content); @@ -74,17 +79,17 @@ public function export_for_template(\renderer_base $output) { $result = (object) [ 'stepid' => $step->get_id(), 'title' => \core_external\util::format_text( - helper::get_string_from_input($step->get_title()), - FORMAT_HTML, - $PAGE->context->id, - 'tool_usertours' - )[0], + helper::get_string_from_input($step->get_title()), + FORMAT_HTML, + $PAGE->context->id, + 'tool_usertours' + )[0], 'content' => \core_external\util::format_text( - $content, - $step->get_contentformat(), - $PAGE->context->id, - 'tool_usertours' - )[0], + $content, + $step->get_contentformat(), + $PAGE->context->id, + 'tool_usertours' + )[0], 'element' => $step->get_target()->convert_to_css(), ]; diff --git a/admin/tool/usertours/classes/output/tour.php b/admin/tool/usertours/classes/output/tour.php index 6e933fb7cc43..d232e44d1636 100644 --- a/admin/tool/usertours/classes/output/tour.php +++ b/admin/tool/usertours/classes/output/tour.php @@ -14,28 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Tour renderable. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\output; -defined('MOODLE_INTERNAL') || die(); - use tool_usertours\tour as toursource; /** * Tour renderable. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tour implements \renderable { - /** * @var The tour instance. */ diff --git a/admin/tool/usertours/classes/privacy/provider.php b/admin/tool/usertours/classes/privacy/provider.php index db71ee9a1a98..c65b204860fa 100644 --- a/admin/tool/usertours/classes/privacy/provider.php +++ b/admin/tool/usertours/classes/privacy/provider.php @@ -14,25 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Privacy Subsystem implementation for tool_usertours. - * - * @package tool_usertours - * @copyright 2018 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours\privacy; -use \core_privacy\local\request\writer; -use \core_privacy\local\metadata\collection; -use \core_privacy\local\request\transform; - -defined('MOODLE_INTERNAL') || die(); +use core_privacy\local\request\writer; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; /** * Implementation of the privacy subsystem plugin provider for the user tours feature. * + * @package tool_usertours * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -41,9 +32,7 @@ class provider implements \core_privacy\local\metadata\provider, // This plugin has some sitewide user preferences to export. - \core_privacy\local\request\user_preference_provider -{ - + \core_privacy\local\request\user_preference_provider { /** * Returns meta data about this system. * diff --git a/admin/tool/usertours/classes/step.php b/admin/tool/usertours/classes/step.php index 95715e177adf..485bc081536e 100644 --- a/admin/tool/usertours/classes/step.php +++ b/admin/tool/usertours/classes/step.php @@ -14,29 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Step class. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; use context_system; use stdClass; -defined('MOODLE_INTERNAL') || die(); - /** * Step class. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class step { - /** * @var int $id The id of the step. */ @@ -137,7 +127,7 @@ protected function fetch($id) { global $DB; return $this->reload_from_record( - $DB->get_record('tool_usertours_steps', array('id' => $id)) + $DB->get_record('tool_usertours_steps', ['id' => $id]) ); } @@ -414,7 +404,7 @@ public function get_movedown_link() { */ public function get_config($key = null, $default = null) { if ($this->config === null) { - $this->config = (object) array(); + $this->config = (object) []; } if ($key === null) { @@ -448,7 +438,7 @@ public function get_config($key = null, $default = null) { */ public function set_config($key, $value) { if ($this->config === null) { - $this->config = (object) array(); + $this->config = (object) []; } if ($value === null) { @@ -497,7 +487,7 @@ protected function embed_files(): array { 'name' => $file->get_filename(), 'path' => $file->get_filepath(), 'content' => base64_encode($file->get_content()), - 'encode' => 'base64' + 'encode' => 'base64', ]; } @@ -635,7 +625,7 @@ public function remove() { return; } - $DB->delete_records('tool_usertours_steps', array('id' => $this->id)); + $DB->delete_records('tool_usertours_steps', ['id' => $this->id]); $this->get_tour()->reset_step_sortorder(); // Notify of a change to the step configuration. @@ -817,15 +807,19 @@ public static function get_step_image_from_input(string $content): string { return $content; } - $content = preg_replace_callback('%@@PIXICON::(?P([^::]*))::(?P([^@@]*))@@%', - function(array $matches) { + $content = preg_replace_callback( + '%@@PIXICON::(?P([^::]*))::(?P([^@@]*))@@%', + function (array $matches) { global $OUTPUT; $component = $matches['component']; if ($component == 'moodle') { $component = 'core'; } - return \html_writer::img($OUTPUT->image_url($matches['identifier'], $component)->out(false), '', - ['class' => 'img-fluid']); + return \html_writer::img( + $OUTPUT->image_url($matches['identifier'], $component)->out(false), + '', + ['class' => 'img-fluid'] + ); }, $content ); diff --git a/admin/tool/usertours/classes/target.php b/admin/tool/usertours/classes/target.php index f65c2caa0e29..9299ca5180cd 100644 --- a/admin/tool/usertours/classes/target.php +++ b/admin/tool/usertours/classes/target.php @@ -14,26 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Target class. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; -defined('MOODLE_INTERNAL') || die(); - /** * Target class. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class target { - /** * @var TARGET_SELECTOR The target is a CSS selector. */ diff --git a/admin/tool/usertours/classes/tour.php b/admin/tool/usertours/classes/tour.php index c51f9e85f0de..61001c5745d1 100644 --- a/admin/tool/usertours/classes/tour.php +++ b/admin/tool/usertours/classes/tour.php @@ -14,28 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Tour class. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; -use tool_usertours\local\clientside_filter\clientside_filter; - -defined('MOODLE_INTERNAL') || die(); - /** * Tour class. * + * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tour { - /** * The tour is currently disabled * @@ -64,6 +52,12 @@ class tour { */ const TOUR_REQUESTED_BY_USER = 'tool_usertours_tour_reset_time_'; + /** @var int Whether to show the tour only until it has been marked complete */ + const SHOW_TOUR_UNTIL_COMPLETE = 1; + + /** @var int Whether to show the tour every time a page matches */ + const SHOW_TOUR_ON_EACH_PAGE_VISIT = 2; + /** * @var $id The tour ID. */ @@ -157,7 +151,7 @@ protected function fetch($id) { global $DB; return $this->reload_from_record( - $DB->get_record('tool_usertours_tours', array('id' => $id), '*', MUST_EXIST) + $DB->get_record('tool_usertours_tours', ['id' => $id], '*', MUST_EXIST) ); } @@ -424,7 +418,7 @@ public function get_delete_link() { * @return object */ public function to_record() { - return (object) array( + return (object) [ 'id' => $this->id, 'name' => $this->name, 'description' => $this->description, @@ -434,7 +428,7 @@ public function to_record() { 'endtourlabel' => $this->endtourlabel, 'configdata' => json_encode($this->config), 'displaystepnumbers' => $this->displaystepnumbers, - ); + ]; } /** @@ -519,7 +513,7 @@ public function get_movedown_link() { */ public function get_config($key = null, $default = null) { if ($this->config === null) { - $this->config = (object) array(); + $this->config = (object) []; } if ($key === null) { return $this->config; @@ -545,7 +539,7 @@ public function get_config($key = null, $default = null) { */ public function set_config($key, $value) { if ($this->config === null) { - $this->config = (object) array(); + $this->config = (object) []; } $this->config->$key = $value; $this->dirty = true; @@ -602,7 +596,7 @@ public function remove() { } // Remove the configuration for the tour. - $DB->delete_records('tool_usertours_tours', array('id' => $this->id)); + $DB->delete_records('tool_usertours_tours', ['id' => $this->id]); helper::reset_tour_sortorder(); $this->remove_user_preferences(); @@ -617,11 +611,11 @@ public function remove() { */ public function reset_step_sortorder() { global $DB; - $steps = $DB->get_records('tool_usertours_steps', array('tourid' => $this->id), 'sortorder ASC', 'id'); + $steps = $DB->get_records('tool_usertours_steps', ['tourid' => $this->id], 'sortorder ASC', 'id'); $index = 0; foreach ($steps as $step) { - $DB->set_field('tool_usertours_steps', 'sortorder', $index, array('id' => $step->id)); + $DB->set_field('tool_usertours_steps', 'sortorder', $index, ['id' => $step->id]); $index++; } @@ -653,6 +647,11 @@ public function should_show_for_user() { return false; } + if ($this->get_showtourwhen() === self::SHOW_TOUR_ON_EACH_PAGE_VISIT) { + // The tour should be shown on every page visit. + return true; + } + if ($tourcompletiondate = get_user_preferences(self::TOUR_LAST_COMPLETED_BY_USER . $this->get_id(), null)) { if ($tourresetdate = get_user_preferences(self::TOUR_REQUESTED_BY_USER . $this->get_id(), null)) { if ($tourresetdate >= $tourcompletiondate) { @@ -775,6 +774,7 @@ protected function add_config_field_to_form(\MoodleQuickForm &$mform, $key) { */ public function prepare_data_for_form() { $data = $this->to_record(); + $data->showtourwhen = $this->get_showtourwhen(); foreach (configuration::get_defaultable_keys() as $key) { $data->$key = $this->get_config($key, configuration::get_default_value($key)); } @@ -872,4 +872,29 @@ public function set_display_step_numbers(bool $value): tour { public function get_display_step_numbers(): bool { return $this->displaystepnumbers; } + + /** + * Set the value for the when to show the tour. + * + * @see self::SHOW_TOUR_UNTIL_COMPLETE + * @see self::SHOW_TOUR_ON_EACH_PAGE_VISIT + * + * @param int $value + * @return self + */ + public function set_showtourwhen(int $value): tour { + return $this->set_config('showtourwhen', $value); + } + + /** + * When to show the tour. + * + * @see self::SHOW_TOUR_UNTIL_COMPLETE + * @see self::SHOW_TOUR_ON_EACH_PAGE_VISIT + * + * @return int + */ + public function get_showtourwhen(): int { + return $this->get_config('showtourwhen', self::SHOW_TOUR_UNTIL_COMPLETE); + } } diff --git a/admin/tool/usertours/configure.php b/admin/tool/usertours/configure.php index cb7bc9832182..5ff066b18e93 100644 --- a/admin/tool/usertours/configure.php +++ b/admin/tool/usertours/configure.php @@ -31,5 +31,5 @@ $PAGE->set_context(context_system::instance()); $pluginmanager->execute( - $action - ); + $action +); diff --git a/admin/tool/usertours/db/access.php b/admin/tool/usertours/db/access.php index 1e8e6b927c90..4dd38c2245d8 100644 --- a/admin/tool/usertours/db/access.php +++ b/admin/tool/usertours/db/access.php @@ -24,13 +24,13 @@ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( +$capabilities = [ 'tool/usertours:managetours' => [ 'captype' => 'write', 'riskbitmask' => RISK_XSS, 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => [ 'manager' => CAP_ALLOW, - ] + ], ], -); +]; diff --git a/admin/tool/usertours/db/caches.php b/admin/tool/usertours/db/caches.php index 3ae3c8fb4c7d..28e384656994 100644 --- a/admin/tool/usertours/db/caches.php +++ b/admin/tool/usertours/db/caches.php @@ -24,19 +24,19 @@ defined('MOODLE_INTERNAL') || die(); -$definitions = array( - 'tourdata' => array( +$definitions = [ + 'tourdata' => [ 'mode' => cache_store::MODE_APPLICATION, 'simplekeys' => true, 'simpledata' => true, 'staticacceleration' => true, 'staticaccelerationsize' => 1, - ), - 'stepdata' => array( + ], + 'stepdata' => [ 'mode' => cache_store::MODE_APPLICATION, 'simplekeys' => true, 'simpledata' => true, 'staticacceleration' => true, 'staticaccelerationsize' => 1, - ), -); + ], +]; diff --git a/admin/tool/usertours/db/services.php b/admin/tool/usertours/db/services.php index 38e65eaa5a52..9b47633c5d67 100644 --- a/admin/tool/usertours/db/services.php +++ b/admin/tool/usertours/db/services.php @@ -24,40 +24,40 @@ defined('MOODLE_INTERNAL') || die(); -$functions = array( - 'tool_usertours_fetch_and_start_tour' => array( +$functions = [ + 'tool_usertours_fetch_and_start_tour' => [ 'classname' => 'tool_usertours\external\tour', 'methodname' => 'fetch_and_start_tour', 'description' => 'Fetch the specified tour', 'type' => 'read', 'capabilities' => '', 'ajax' => true, - ), + ], - 'tool_usertours_step_shown' => array( + 'tool_usertours_step_shown' => [ 'classname' => 'tool_usertours\external\tour', 'methodname' => 'step_shown', 'description' => 'Mark the specified step as completed for the current user', 'type' => 'write', 'capabilities' => '', 'ajax' => true, - ), + ], - 'tool_usertours_complete_tour' => array( + 'tool_usertours_complete_tour' => [ 'classname' => 'tool_usertours\external\tour', 'methodname' => 'complete_tour', 'description' => 'Mark the specified tour as completed for the current user', 'type' => 'write', 'capabilities' => '', 'ajax' => true, - ), + ], - 'tool_usertours_reset_tour' => array( + 'tool_usertours_reset_tour' => [ 'classname' => 'tool_usertours\external\tour', 'methodname' => 'reset_tour', 'description' => 'Remove the specified tour', 'type' => 'write', 'capabilities' => '', 'ajax' => true, - ), -); + ], +]; diff --git a/admin/tool/usertours/lang/en/tool_usertours.php b/admin/tool/usertours/lang/en/tool_usertours.php index 0672417b728a..815806de4a9a 100644 --- a/admin/tool/usertours/lang/en/tool_usertours.php +++ b/admin/tool/usertours/lang/en/tool_usertours.php @@ -36,6 +36,9 @@ Alternatively, a language string ID may be entered in the format identifier,component (with no brackets or space after the comma).'; $string['displaystepnumbers'] = 'Display step numbers'; $string['displaystepnumbers_help'] = 'Whether to display a step number count e.g. 1/4, 2/4 etc. to indicate the length of the user tour.'; +$string['showtourwhen'] = 'Show tour'; +$string['showtoureachtime'] = 'each time a filter matches it'; +$string['showtouruntilcomplete'] = 'until it has been closed'; $string['confirmstepremovalquestion'] = 'Are you sure that you wish to remove this step?'; $string['confirmstepremovaltitle'] = 'Confirm step removal'; $string['confirmtourremovalquestion'] = 'Are you sure that you wish to remove this tour?'; diff --git a/admin/tool/usertours/tests/accessdate_filter_test.php b/admin/tool/usertours/tests/accessdate_filter_test.php index 52b44c3c31b4..1458ee14763c 100644 --- a/admin/tool/usertours/tests/accessdate_filter_test.php +++ b/admin/tool/usertours/tests/accessdate_filter_test.php @@ -24,9 +24,9 @@ * @package tool_usertours * @copyright 2019 Tom Dickman * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\local\filter\accessdate */ class accessdate_filter_test extends \advanced_testcase { - public function setUp(): void { $this->resetAfterTest(true); } @@ -36,7 +36,7 @@ public function setUp(): void { * * @return array */ - public function filter_matches_provider() { + public static function filter_matches_provider(): array { return [ 'No config set; Matches' => [ [], @@ -45,61 +45,61 @@ public function filter_matches_provider() { ], 'Filter is not enabled; Match' => [ ['filter_accessdate' => accessdate::FILTER_ACCOUNT_CREATION, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 0], + 'filter_accessdate_enabled' => 0, ], ['timecreated' => time() - (89 * DAYSECS)], true, ], 'Filter is not enabled (tour would not be displayed if it was); Match' => [ ['filter_accessdate' => accessdate::FILTER_ACCOUNT_CREATION, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 0], + 'filter_accessdate_enabled' => 0, ], ['timecreated' => time() - (91 * DAYSECS)], true, ], 'Inside range of account creation date; Match' => [ ['filter_accessdate' => accessdate::FILTER_ACCOUNT_CREATION, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['timecreated' => time() - (89 * DAYSECS)], true, ], 'Outside range of account creation date; No match' => [ ['filter_accessdate' => accessdate::FILTER_ACCOUNT_CREATION, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['timecreated' => time() - (91 * DAYSECS)], false, ], 'Inside range of first login date; Match' => [ ['filter_accessdate' => accessdate::FILTER_FIRST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['firstaccess' => time() - (89 * DAYSECS)], true, ], 'Outside range of first login date; No match' => [ ['filter_accessdate' => accessdate::FILTER_FIRST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['firstaccess' => time() - (91 * DAYSECS)], false, ], 'Inside range of last login date; Match' => [ ['filter_accessdate' => accessdate::FILTER_LAST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['lastlogin' => time() - (89 * DAYSECS)], true, ], 'Outside range of last login date; No match' => [ ['filter_accessdate' => accessdate::FILTER_LAST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['lastlogin' => time() - (91 * DAYSECS)], false, ], 'User has never logged in, but tour should be visible; Match' => [ ['filter_accessdate' => accessdate::FILTER_LAST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['lastlogin' => 0, 'timecreated' => time() - (89 * DAYSECS)], true, ], 'User has never logged in, and tour should not be visible; No match' => [ ['filter_accessdate' => accessdate::FILTER_LAST_LOGIN, 'filter_accessdate_range' => 90 * DAYSECS, - 'filter_accessdate_enabled' => 1], + 'filter_accessdate_enabled' => 1, ], ['lastlogin' => 0, 'timecreated' => time() - (91 * DAYSECS)], false, ], @@ -115,7 +115,7 @@ public function filter_matches_provider() { * @param array $userstate any user state required for test. * @param bool $expected result expected. */ - public function test_filter_matches($filtervalues, $userstate, $expected) { + public function test_filter_matches($filtervalues, $userstate, $expected): void { $course = $this->getDataGenerator()->create_course(); $context = \context_course::instance($course->id); @@ -127,5 +127,4 @@ public function test_filter_matches($filtervalues, $userstate, $expected) { $this->assertEquals($expected, accessdate::filter_matches($tour, $context)); } - } diff --git a/admin/tool/usertours/tests/behat/behat_tool_usertours.php b/admin/tool/usertours/tests/behat/behat_tool_usertours.php index ef00bd2f7a01..797f5b5142a9 100644 --- a/admin/tool/usertours/tests/behat/behat_tool_usertours.php +++ b/admin/tool/usertours/tests/behat/behat_tool_usertours.php @@ -25,7 +25,7 @@ require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php'); -use Behat\Gherkin\Node\TableNode as TableNode; +use Behat\Gherkin\Node\TableNode; /** * User tour related steps definitions. * @@ -35,7 +35,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class behat_tool_usertours extends behat_base { - /** * Add a new user tour. * @@ -90,8 +89,9 @@ public function i_add_steps_to_the_tour(TableNode $table) { * @Given /^I open the User tour settings page$/ */ public function i_open_the_user_tour_settings_page() { - $this->execute('behat_navigation::i_navigate_to_in_site_administration', - get_string('appearance', 'admin') . ' > ' . + $this->execute( + 'behat_navigation::i_navigate_to_in_site_administration', + get_string('appearance', 'admin') . ' > ' . get_string('usertours', 'tool_usertours') ); } diff --git a/admin/tool/usertours/tests/behat/tour_prevents_completion.feature b/admin/tool/usertours/tests/behat/tour_prevents_completion.feature new file mode 100644 index 000000000000..0b2e687be9f5 --- /dev/null +++ b/admin/tool/usertours/tests/behat/tour_prevents_completion.feature @@ -0,0 +1,29 @@ +@tool @tool_usertours +Feature: Prevent yours from being marked as complete + In order to impart key information + As an administrator + I can prevent a user tour from being marked as complete + + Background: + Given I log in as "admin" + And I add a new user tour with: + | Name | First tour | + | Description | My first tour | + | Apply to URL match | FRONTPAGE | + | Tour is enabled | 1 | + | Show with backdrop | 1 | + # 2 = tour::SHOW_TOUR_ON_EACH_PAGE_VISIT + | Show tour | 2 | + And I add steps to the "First tour" tour: + | targettype | Title | id_content | Content type | + | Display in middle of page | Welcome | Welcome tour. | Manual | + + @javascript + Scenario: Ending the tour should not mark it as complete + # Changing the window viewport to mobile so we will have the footer section. + Given I am on site homepage + And I should see "Welcome" + And I press "Got it" + And I should not see "Welcome" + When I am on site homepage + Then I should see "Welcome" diff --git a/admin/tool/usertours/tests/cache_test.php b/admin/tool/usertours/tests/cache_test.php index 27f96008d12a..54cadfaf578a 100644 --- a/admin/tool/usertours/tests/cache_test.php +++ b/admin/tool/usertours/tests/cache_test.php @@ -27,6 +27,7 @@ * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\cache */ class cache_test extends \advanced_testcase { // There are shared helpers for these tests in the helper trait. @@ -35,7 +36,7 @@ class cache_test extends \advanced_testcase { /** * Test that get_enabled_tourdata does not return disabled tours. */ - public function test_get_enabled_tourdata_disabled() { + public function test_get_enabled_tourdata_disabled(): void { $this->resetAfterTest(); $tour = $this->helper_create_tour((object)['enabled' => false]); @@ -48,7 +49,7 @@ public function test_get_enabled_tourdata_disabled() { /** * Test that get_enabled_tourdata does not return an enabled but empty tour. */ - public function test_get_enabled_tourdata_enabled_no_steps() { + public function test_get_enabled_tourdata_enabled_no_steps(): void { $this->resetAfterTest(); $this->helper_create_tour(); @@ -60,7 +61,7 @@ public function test_get_enabled_tourdata_enabled_no_steps() { /** * Test that get_enabled_tourdata returns a tour with steps. */ - public function test_get_enabled_tourdata_enabled() { + public function test_get_enabled_tourdata_enabled(): void { $this->resetAfterTest(); // Create two tours. Only the second has steps. @@ -79,7 +80,7 @@ public function test_get_enabled_tourdata_enabled() { /** * Test that get_enabled_tourdata returns tours in the correct sortorder */ - public function test_get_enabled_tourdata_enabled_sortorder() { + public function test_get_enabled_tourdata_enabled_sortorder(): void { $this->resetAfterTest(); $tour1 = $this->helper_create_tour(); @@ -100,7 +101,7 @@ public function test_get_enabled_tourdata_enabled_sortorder() { /** * Test that caching prevents additional DB reads. */ - public function test_get_enabled_tourdata_single_fetch() { + public function test_get_enabled_tourdata_single_fetch(): void { global $DB; $this->resetAfterTest(); @@ -118,7 +119,6 @@ public function test_get_enabled_tourdata_single_fetch() { // No subsequent reads for any further calls. $matches = \tool_usertours\cache::get_enabled_tourdata(); $this->assertEquals(1, $DB->perf_get_reads() - $startreads); - } /** @@ -126,31 +126,31 @@ public function test_get_enabled_tourdata_single_fetch() { * * @return array */ - public function get_matching_tourdata_provider() { + public static function get_matching_tourdata_provider(): array { $tourconfigs = [ (object) [ 'name' => 'my_exact_1', - 'pathmatch' => '/my/view.php' + 'pathmatch' => '/my/view.php', ], (object) [ 'name' => 'my_failed_regex', - 'pathmatch' => '/my/*.php' + 'pathmatch' => '/my/*.php', ], (object) [ 'name' => 'my_glob_1', - 'pathmatch' => '/my/%' + 'pathmatch' => '/my/%', ], (object) [ 'name' => 'my_glob_2', - 'pathmatch' => '/my/%' + 'pathmatch' => '/my/%', ], (object) [ 'name' => 'frontpage_only', - 'pathmatch' => 'FRONTPAGE' + 'pathmatch' => 'FRONTPAGE', ], (object) [ 'name' => 'frontpage_match', - 'pathmatch' => '/?%' + 'pathmatch' => '/?%', ], ]; @@ -186,7 +186,7 @@ public function get_matching_tourdata_provider() { * @param string $targetmatch The match to be tested * @param array $expected An array containing the ordered names of the expected tours */ - public function test_get_matching_tourdata($tourconfigs, $targetmatch, $expected) { + public function test_get_matching_tourdata($tourconfigs, $targetmatch, $expected): void { $this->resetAfterTest(); foreach ($tourconfigs as $tourconfig) { $tour = $this->helper_create_tour($tourconfig); @@ -205,7 +205,7 @@ public function test_get_matching_tourdata($tourconfigs, $targetmatch, $expected /** * Test that notify_tour_change clears the cache. */ - public function test_notify_tour_change() { + public function test_notify_tour_change(): void { global $DB; $this->resetAfterTest(); @@ -236,7 +236,7 @@ public function test_notify_tour_change() { /** * Test that get_stepdata returns an empty array when no steps were found. */ - public function test_get_stepdata_no_steps() { + public function test_get_stepdata_no_steps(): void { $this->resetAfterTest(); $tour = $this->helper_create_tour((object)['enabled' => false]); @@ -249,7 +249,7 @@ public function test_get_stepdata_no_steps() { /** * Test that get_stepdata returns an empty array when no steps were found. */ - public function test_get_stepdata_correct_tour() { + public function test_get_stepdata_correct_tour(): void { $this->resetAfterTest(); $tour1 = $this->helper_create_tour((object)['enabled' => false]); @@ -274,7 +274,7 @@ public function test_get_stepdata_correct_tour() { * This is very difficult to determine because the act of changing the * order will likely change the DB natural sorting. */ - public function test_get_stepdata_ordered_steps() { + public function test_get_stepdata_ordered_steps(): void { $this->resetAfterTest(); $tour = $this->helper_create_tour((object)['enabled' => false]); @@ -290,7 +290,7 @@ public function test_get_stepdata_ordered_steps() { $this->assertCount(4, $data); // Re-order the steps. - usort($steps, function($a, $b) { + usort($steps, function ($a, $b) { return ($a->get_sortorder() < $b->get_sortorder()) ? -1 : 1; }); @@ -303,7 +303,7 @@ public function test_get_stepdata_ordered_steps() { /** * Test that caching prevents additional DB reads. */ - public function test_get_stepdata_single_fetch() { + public function test_get_stepdata_single_fetch(): void { global $DB; $this->resetAfterTest(); @@ -324,7 +324,7 @@ public function test_get_stepdata_single_fetch() { /** * Test that notify_step_change clears the cache. */ - public function test_notify_step_change() { + public function test_notify_step_change(): void { global $DB; $this->resetAfterTest(); diff --git a/admin/tool/usertours/tests/helper_test.php b/admin/tool/usertours/tests/helper_test.php index f6c574b30776..3a2f1cdad262 100644 --- a/admin/tool/usertours/tests/helper_test.php +++ b/admin/tool/usertours/tests/helper_test.php @@ -14,35 +14,25 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Tests for helper. - * - * @package tool_usertours - * @copyright 2022 Huong Nguyen - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace tool_usertours; use advanced_testcase; -defined('MOODLE_INTERNAL') || die(); - /** * Tests for helper. * * @package tool_usertours * @copyright 2022 Huong Nguyen * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\helper */ class helper_test extends advanced_testcase { - /** * Data Provider for get_string_from_input. * * @return array */ - public function get_string_from_input_provider(): array { + public static function get_string_from_input_provider(): array { return [ 'Text' => [ 'example', @@ -78,7 +68,7 @@ public function get_string_from_input_provider(): array { * @param string $string The string to test * @param string $expected The expected result */ - public function test_get_string_from_input($string, $expected) { + public function test_get_string_from_input($string, $expected): void { $this->assertEquals($expected, helper::get_string_from_input($string)); } } diff --git a/admin/tool/usertours/tests/helper_trait.php b/admin/tool/usertours/tests/helper_trait.php index c3638a1d41bf..988ace5abcd4 100644 --- a/admin/tool/usertours/tests/helper_trait.php +++ b/admin/tool/usertours/tests/helper_trait.php @@ -14,16 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Helpers for unit tests. - * - * @package tool_usertours - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - /** * Helpers for unit tests. * @@ -47,7 +37,7 @@ public function helper_create_tour(\stdClass $tourconfig = null, $persist = true 'name' => '', 'description' => '', 'configdata' => '', - 'displaystepnumbers' => true + 'displaystepnumbers' => true, ]; if ($tourconfig === null) { diff --git a/admin/tool/usertours/tests/manager_test.php b/admin/tool/usertours/tests/manager_test.php index 17751f0aa745..924ba268e85f 100644 --- a/admin/tool/usertours/tests/manager_test.php +++ b/admin/tool/usertours/tests/manager_test.php @@ -28,6 +28,7 @@ * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\manager */ class manager_test extends \advanced_testcase { // There are shared helpers for these tests in the helper trait. @@ -74,28 +75,28 @@ public function mock_database() { * * @return array */ - public function sesskey_required_provider() { + public static function sesskey_required_provider(): array { $tourid = rand(1, 100); $stepid = rand(1, 100); return [ - 'Tour removal' => [ - 'delete_tour', - [$tourid], - ], - 'Step removal' => [ - 'delete_step', - [$stepid], - ], - 'Tour visibility' => [ - 'show_hide_tour', - [$tourid, true], - ], - 'Move step' => [ - 'move_step', - [$stepid], - ], - ]; + 'Tour removal' => [ + 'delete_tour', + [$tourid], + ], + 'Step removal' => [ + 'delete_step', + [$stepid], + ], + 'Tour visibility' => [ + 'show_hide_tour', + [$tourid, true], + ], + 'Move step' => [ + 'move_step', + [$stepid], + ], + ]; } /** @@ -105,12 +106,11 @@ public function sesskey_required_provider() { * @param string $function The function to test * @param array $arguments The arguments to pass with it */ - public function test_sesskey_required($function, $arguments) { + public function test_sesskey_required($function, $arguments): void { $manager = new \tool_usertours\manager(); $rc = new \ReflectionClass('\tool_usertours\manager'); $rcm = $rc->getMethod($function); - $rcm->setAccessible(true); $this->expectException('moodle_exception'); $rcm->invokeArgs($manager, $arguments); @@ -121,7 +121,7 @@ public function test_sesskey_required($function, $arguments) { * * @return array */ - public function move_tour_provider() { + public static function move_tour_provider(): array { $alltours = [ ['name' => 'Tour 1'], ['name' => 'Tour 2'], @@ -167,7 +167,7 @@ public function move_tour_provider() { * @param int $expectedsortorder * @return void */ - public function test_move_tour($alltours, $movetourname, $direction, $expectedsortorder) { + public function test_move_tour($alltours, $movetourname, $direction, $expectedsortorder): void { global $DB; $this->resetAfterTest(); @@ -186,7 +186,6 @@ public function test_move_tour($alltours, $movetourname, $direction, $expectedso // Call protected method via reflection. $class = new \ReflectionClass(\tool_usertours\manager::class); $method = $class->getMethod('_move_tour'); - $method->setAccessible(true); $method->invokeArgs(null, [$tour, $direction]); // Assert expected sortorder. @@ -198,114 +197,115 @@ public function test_move_tour($alltours, $movetourname, $direction, $expectedso * * @return array */ - public function get_matching_tours_provider() { + public static function get_matching_tours_provider(): array { global $CFG; $alltours = [ [ - 'pathmatch' => '/my/%', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/my/%', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/my/%', - 'enabled' => true, - 'name' => 'My tour enabled', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/my/%', + 'enabled' => true, + 'name' => 'My tour enabled', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/my/%', - 'enabled' => true, - 'name' => 'My tour enabled 2', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/my/%', + 'enabled' => true, + 'name' => 'My tour enabled 2', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/my/%', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/my/%', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%foo=bar', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%foo=bar', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%foo=bar', - 'enabled' => true, - 'name' => 'course tour with additional params enabled', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%foo=bar', + 'enabled' => true, + 'name' => 'course tour with additional params enabled', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%foo=bar', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%foo=bar', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%', - 'enabled' => true, - 'name' => 'course tour enabled', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%', + 'enabled' => true, + 'name' => 'course tour enabled', + 'description' => '', + 'configdata' => '', + ], [ - 'pathmatch' => '/course/?id=%', - 'enabled' => false, - 'name' => 'Failure', - 'description' => '', - 'configdata' => '', - ], + 'pathmatch' => '/course/?id=%', + 'enabled' => false, + 'name' => 'Failure', + 'description' => '', + 'configdata' => '', + ], ]; - return [ - 'No matches found' => [ - $alltours, - $CFG->wwwroot . '/some/invalid/value', - [], - ], - 'Never return a disabled tour' => [ - $alltours, - $CFG->wwwroot . '/my/index.php', - ['My tour enabled', 'My tour enabled 2'], - ], - 'My not course' => [ - $alltours, - $CFG->wwwroot . '/my/index.php', - ['My tour enabled', 'My tour enabled 2'], - ], - 'My with params' => [ - $alltours, - $CFG->wwwroot . '/my/index.php?id=42', - ['My tour enabled', 'My tour enabled 2'], - ], - 'Course with params' => [ - $alltours, - $CFG->wwwroot . '/course/?id=42', - ['course tour enabled'], - ], - 'Course with params and trailing content' => [ - $alltours, - $CFG->wwwroot . '/course/?id=42&foo=bar', - ['course tour with additional params enabled', 'course tour enabled'], - ], - ]; + return + [ + 'No matches found' => [ + $alltours, + $CFG->wwwroot . '/some/invalid/value', + [], + ], + 'Never return a disabled tour' => [ + $alltours, + $CFG->wwwroot . '/my/index.php', + ['My tour enabled', 'My tour enabled 2'], + ], + 'My not course' => [ + $alltours, + $CFG->wwwroot . '/my/index.php', + ['My tour enabled', 'My tour enabled 2'], + ], + 'My with params' => [ + $alltours, + $CFG->wwwroot . '/my/index.php?id=42', + ['My tour enabled', 'My tour enabled 2'], + ], + 'Course with params' => [ + $alltours, + $CFG->wwwroot . '/course/?id=42', + ['course tour enabled'], + ], + 'Course with params and trailing content' => [ + $alltours, + $CFG->wwwroot . '/course/?id=42&foo=bar', + ['course tour with additional params enabled', 'course tour enabled'], + ], + ]; } /** @@ -316,7 +316,7 @@ public function get_matching_tours_provider() { * @param string $url The URL to test. * @param array $expected List of names of the expected matching tours. */ - public function test_get_matching_tours(array $alltours, string $url, array $expected) { + public function test_get_matching_tours(array $alltours, string $url, array $expected): void { $this->resetAfterTest(); $this->setGuestUser(); @@ -336,7 +336,7 @@ public function test_get_matching_tours(array $alltours, string $url, array $exp /** * Test that no matching tours are returned if there is pending site policy agreement. */ - public function test_get_matching_tours_for_user_without_site_policy_agreed() { + public function test_get_matching_tours_for_user_without_site_policy_agreed(): void { global $CFG; $this->resetAfterTest(); diff --git a/admin/tool/usertours/tests/privacy/provider_test.php b/admin/tool/usertours/tests/privacy/provider_test.php index 907feb483524..e63ace554d3c 100644 --- a/admin/tool/usertours/tests/privacy/provider_test.php +++ b/admin/tool/usertours/tests/privacy/provider_test.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Unit tests for the tool_usertours implementation of the privacy API. - * - * @package tool_usertours - * @category test - * @copyright 2018 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ namespace tool_usertours\privacy; -defined('MOODLE_INTERNAL') || die(); - use core_privacy\local\metadata\collection; use core_privacy\local\request\writer; use tool_usertours\tour; @@ -34,11 +24,13 @@ /** * Unit tests for the tool_usertours implementation of the privacy API. * + * @package tool_usertours + * @category test * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\privacy\provider */ class provider_test extends \core_privacy\tests\provider_testcase { - /** * Helper method for creating a tour * @@ -56,7 +48,7 @@ protected function create_test_tour(): tour { /** * Ensure that get_metadata exports valid content. */ - public function test_get_metadata() { + public function test_get_metadata(): void { $items = new collection('tool_usertours'); $result = provider::get_metadata($items); $this->assertSame($items, $result); @@ -66,7 +58,7 @@ public function test_get_metadata() { /** * Ensure that export_user_preferences returns no data if the user has completed no tours. */ - public function test_export_user_preferences_no_pref() { + public function test_export_user_preferences_no_pref(): void { $user = \core_user::get_user_by_username('admin'); provider::export_user_preferences($user->id); @@ -78,7 +70,7 @@ public function test_export_user_preferences_no_pref() { /** * Ensure that export_user_preferences returns request completion data. */ - public function test_export_user_preferences_completed() { + public function test_export_user_preferences_completed(): void { global $DB; $this->resetAfterTest(); @@ -101,7 +93,7 @@ public function test_export_user_preferences_completed() { /** * Ensure that export_user_preferences returns request completion data. */ - public function test_export_user_preferences_requested() { + public function test_export_user_preferences_requested(): void { global $DB; $this->resetAfterTest(); @@ -149,14 +141,16 @@ public function test_export_user_preferences_correct_user(): void { $this->assertCount(1, $prefs); // We should have received back the "completed tour" preference of the test user. - $this->assertStringStartsWith('You last marked the "' . $tour->get_name() . '" user tour as completed on', - reset($prefs)->description); + $this->assertStringStartsWith( + 'You last marked the "' . $tour->get_name() . '" user tour as completed on', + reset($prefs)->description + ); } /** * Ensure that export_user_preferences excludes deleted tours. */ - public function test_export_user_preferences_deleted_tour() { + public function test_export_user_preferences_deleted_tour(): void { global $DB; $this->resetAfterTest(); diff --git a/admin/tool/usertours/tests/role_filter_test.php b/admin/tool/usertours/tests/role_filter_test.php index 20ee1be96298..ceff72fb39ba 100644 --- a/admin/tool/usertours/tests/role_filter_test.php +++ b/admin/tool/usertours/tests/role_filter_test.php @@ -22,9 +22,9 @@ * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\local\filter\role */ class role_filter_test extends \advanced_testcase { - /** * @var $course Test course */ @@ -72,7 +72,7 @@ public function setUp(): void { /** * Test the filter_matches function when any is set. */ - public function test_filter_matches_any() { + public function test_filter_matches_any(): void { $context = \context_course::instance($this->course->id); // Note: No need to persist this tour. @@ -93,7 +93,7 @@ public function test_filter_matches_any() { /** * Test the filter_matches function when one role is set. */ - public function test_filter_matches_single_role() { + public function test_filter_matches_single_role(): void { $context = \context_course::instance($this->course->id); $roles = [ @@ -122,7 +122,7 @@ public function test_filter_matches_single_role() { /** * Test the filter_matches function when multiple roles are set. */ - public function test_filter_matches_multiple_role() { + public function test_filter_matches_multiple_role(): void { $context = \context_course::instance($this->course->id); $roles = [ @@ -152,7 +152,7 @@ public function test_filter_matches_multiple_role() { /** * Test the filter_matches function when one user has multiple roles. */ - public function test_filter_matches_multiple_role_one_user() { + public function test_filter_matches_multiple_role_one_user(): void { $context = \context_course::instance($this->course->id); $roles = [ @@ -184,7 +184,7 @@ public function test_filter_matches_multiple_role_one_user() { /** * Test the filter_matches function when it is targetted at an admin. */ - public function test_filter_matches_multiple_role_only_admin() { + public function test_filter_matches_multiple_role_only_admin(): void { $context = \context_course::instance($this->course->id); $roles = [ @@ -212,7 +212,7 @@ public function test_filter_matches_multiple_role_only_admin() { /** * Test the filter_matches function when multiple roles are set, including an admin user. */ - public function test_filter_matches_multiple_role_including_admin() { + public function test_filter_matches_multiple_role_including_admin(): void { $context = \context_course::instance($this->course->id); $roles = [ @@ -243,7 +243,7 @@ public function test_filter_matches_multiple_role_including_admin() { /** * Test the filter_matches function when an admin user has multiple roles. */ - public function test_filter_matches_multiple_role_admin_user() { + public function test_filter_matches_multiple_role_admin_user(): void { global $USER; $context = \context_course::instance($this->course->id); @@ -266,7 +266,7 @@ public function test_filter_matches_multiple_role_admin_user() { /** * Test that the get_filter_options function does not include the guest roles. */ - public function test_get_filter_options_no_guest_roles() { + public function test_get_filter_options_no_guest_roles(): void { create_role('Test Role', 'testrole', 'This is a test role', 'guest'); $allroles = role_get_names(null, ROLENAME_ALIAS); diff --git a/admin/tool/usertours/tests/step_test.php b/admin/tool/usertours/tests/step_test.php index 434908e01d53..8ba2cafa2faf 100644 --- a/admin/tool/usertours/tests/step_test.php +++ b/admin/tool/usertours/tests/step_test.php @@ -27,9 +27,9 @@ * @package tool_usertours * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\step */ class step_test extends \advanced_testcase { - /** * @var moodle_database */ @@ -62,8 +62,7 @@ public function mock_database() { global $DB; $DB = $this->getMockBuilder('moodle_database') - ->getMock() - ; + ->getMock(); return $DB; } @@ -73,64 +72,61 @@ public function mock_database() { * * @return array */ - public function dirty_value_provider() { - return [ + public static function dirty_value_provider(): array { + return + [ 'tourid' => [ - 'tourid', - [1], - ], + 'tourid', + [1], + ], 'title' => [ - 'title', - ['Lorem'], - ], + 'title', + ['Lorem'], + ], 'content' => [ - 'content', - ['Lorem'], - ], + 'content', + ['Lorem'], + ], 'targettype' => [ - 'targettype', - ['Lorem'], - ], + 'targettype', + ['Lorem'], + ], 'targetvalue' => [ - 'targetvalue', - ['Lorem'], - ], + 'targetvalue', + ['Lorem'], + ], 'sortorder' => [ - 'sortorder', - [1], - ], + 'sortorder', + [1], + ], 'config' => [ - 'config', - ['key', 'value'], - ], + 'config', + ['key', 'value'], + ], ]; } /** * Test the fetch function. */ - public function test_fetch() { + public function test_fetch(): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods(['reload_from_record']) - ->getMock() - ; + ->getMock(); $idretval = rand(1, 100); $DB = $this->mock_database(); $DB->method('get_record') - ->willReturn($idretval) - ; + ->willReturn($idretval); $retval = rand(1, 100); $step->expects($this->once()) ->method('reload_from_record') ->with($this->equalTo($idretval)) - ->wilLReturn($retval) - ; + ->wilLReturn($retval); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcm = $rc->getMethod('fetch'); - $rcm->setAccessible(true); $id = rand(1, 100); $this->assertEquals($retval, $rcm->invoke($step, 'fetch', $id)); @@ -143,14 +139,13 @@ public function test_fetch() { * @param string $name The key to update * @param string $value The value to set */ - public function test_dirty_values($name, $value) { + public function test_dirty_values($name, $value): void { $step = new \tool_usertours\step(); $method = 'set_' . $name; call_user_func_array([$step, $method], $value); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $this->assertTrue($rcp->getValue($step)); } @@ -160,12 +155,12 @@ public function test_dirty_values($name, $value) { * * @return array */ - public function step_sortorder_provider() { + public static function step_sortorder_provider(): array { return [ - [0, 5, true, false], - [1, 5, false, false], - [4, 5, false, true], - ]; + [0, 5, true, false], + [1, 5, false, false], + [4, 5, false, true], + ]; } /** @@ -177,15 +172,14 @@ public function step_sortorder_provider() { * @param bool $isfirst Whether this is the first step * @param bool $islast Whether this is the last step */ - public function test_is_first_step($sortorder, $count, $isfirst, $islast) { + public function test_is_first_step($sortorder, $count, $isfirst, $islast): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods(['get_sortorder']) ->getMock(); $step->expects($this->once()) ->method('get_sortorder') - ->willReturn($sortorder) - ; + ->willReturn($sortorder); $this->assertEquals($isfirst, $step->is_first_step()); } @@ -199,7 +193,7 @@ public function test_is_first_step($sortorder, $count, $isfirst, $islast) { * @param bool $isfirst Whether this is the first step * @param bool $islast Whether this is the last step */ - public function test_is_last_step($sortorder, $count, $isfirst, $islast) { + public function test_is_last_step($sortorder, $count, $isfirst, $islast): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods(['get_sortorder', 'get_tour']) ->getMock(); @@ -210,18 +204,15 @@ public function test_is_last_step($sortorder, $count, $isfirst, $islast) { $step->expects($this->once()) ->method('get_tour') - ->willReturn($tour) - ; + ->willReturn($tour); $tour->expects($this->once()) ->method('count_steps') - ->willReturn($count) - ; + ->willReturn($count); $step->expects($this->once()) ->method('get_sortorder') - ->willReturn($sortorder) - ; + ->willReturn($sortorder); $this->assertEquals($islast, $step->is_last_step()); } @@ -229,20 +220,19 @@ public function test_is_last_step($sortorder, $count, $isfirst, $islast) { /** * Test get_config with no keys provided. */ - public function test_get_config_no_keys() { + public function test_get_config_no_keys(): void { $step = new \tool_usertours\step(); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $allvalues = (object) [ - 'some' => 'value', - 'another' => 42, - 'key' => [ - 'somethingelse', - ], - ]; + 'some' => 'value', + 'another' => 42, + 'key' => [ + 'somethingelse', + ], + ]; $rcp->setValue($step, $allvalues); @@ -254,92 +244,92 @@ public function test_get_config_no_keys() { * * @return array */ - public function get_config_provider() { + public static function get_config_provider(): array { $allvalues = (object) [ - 'some' => 'value', - 'another' => 42, - 'key' => [ - 'somethingelse', - ], - ]; + 'some' => 'value', + 'another' => 42, + 'key' => [ + 'somethingelse', + ], + ]; $tourconfig = rand(1, 100); $forcedconfig = rand(1, 100); return [ - 'No initial config' => [ - null, - null, - null, - $tourconfig, - false, - $forcedconfig, - (object) [], - ], - 'All values' => [ - $allvalues, - null, - null, - $tourconfig, - false, - $forcedconfig, - $allvalues, - ], - 'Valid string value' => [ - $allvalues, - 'some', - null, - $tourconfig, - false, - $forcedconfig, - 'value', - ], - 'Valid array value' => [ - $allvalues, - 'key', - null, - $tourconfig, - false, - $forcedconfig, - ['somethingelse'], - ], - 'Invalid value' => [ - $allvalues, - 'notavalue', - null, - $tourconfig, - false, - $forcedconfig, - $tourconfig, - ], - 'Configuration value' => [ - $allvalues, - 'placement', - null, - $tourconfig, - false, - $forcedconfig, - $tourconfig, - ], - 'Invalid value with default' => [ - $allvalues, - 'notavalue', - 'somedefault', - $tourconfig, - false, - $forcedconfig, - 'somedefault', - ], - 'Value forced at target' => [ - $allvalues, - 'somevalue', - 'somedefault', - $tourconfig, - true, - $forcedconfig, - $forcedconfig, - ], - ]; + 'No initial config' => [ + null, + null, + null, + $tourconfig, + false, + $forcedconfig, + (object) [], + ], + 'All values' => [ + $allvalues, + null, + null, + $tourconfig, + false, + $forcedconfig, + $allvalues, + ], + 'Valid string value' => [ + $allvalues, + 'some', + null, + $tourconfig, + false, + $forcedconfig, + 'value', + ], + 'Valid array value' => [ + $allvalues, + 'key', + null, + $tourconfig, + false, + $forcedconfig, + ['somethingelse'], + ], + 'Invalid value' => [ + $allvalues, + 'notavalue', + null, + $tourconfig, + false, + $forcedconfig, + $tourconfig, + ], + 'Configuration value' => [ + $allvalues, + 'placement', + null, + $tourconfig, + false, + $forcedconfig, + $tourconfig, + ], + 'Invalid value with default' => [ + $allvalues, + 'notavalue', + 'somedefault', + $tourconfig, + false, + $forcedconfig, + 'somedefault', + ], + 'Value forced at target' => [ + $allvalues, + 'somevalue', + 'somedefault', + $tourconfig, + true, + $forcedconfig, + $forcedconfig, + ], + ]; } /** @@ -354,55 +344,46 @@ public function get_config_provider() { * @param mixed $forcedvalue The example value * @param mixed $expected The expected value */ - public function test_get_config_valid_keys($values, $key, $default, $tourconfig, $isforced, $forcedvalue, $expected) { + public function test_get_config_valid_keys($values, $key, $default, $tourconfig, $isforced, $forcedvalue, $expected): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods(['get_target', 'get_targettype', 'get_tour']) ->getMock(); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $rcp->setValue($step, $values); $target = $this->getMockBuilder(\tool_usertours\local\target\base::class) ->disableOriginalConstructor() - ->getMock() - ; + ->getMock(); $target->expects($this->any()) ->method('is_setting_forced') - ->willReturn($isforced) - ; + ->willReturn($isforced); $target->expects($this->any()) ->method('get_forced_setting_value') ->with($this->equalTo($key)) - ->willReturn($forcedvalue) - ; + ->willReturn($forcedvalue); $step->expects($this->any()) ->method('get_targettype') - ->willReturn('type') - ; + ->willReturn('type'); $step->expects($this->any()) ->method('get_target') - ->willReturn($target) - ; + ->willReturn($target); $tour = $this->getMockBuilder(\tool_usertours\tour::class) - ->getMock() - ; + ->getMock(); $tour->expects($this->any()) ->method('get_config') - ->willReturn($tourconfig) - ; + ->willReturn($tourconfig); $step->expects($this->any()) ->method('get_tour') - ->willReturn($tour) - ; + ->willReturn($tour); $this->assertEquals($expected, $step->get_config($key, $default)); } @@ -410,14 +391,14 @@ public function test_get_config_valid_keys($values, $key, $default, $tourconfig, /** * Data provider for set_config. */ - public function set_config_provider() { + public static function set_config_provider(): array { $allvalues = (object) [ - 'some' => 'value', - 'another' => 42, - 'key' => [ - 'somethingelse', - ], - ]; + 'some' => 'value', + 'another' => 42, + 'key' => [ + 'somethingelse', + ], + ]; $randvalue = rand(1, 100); @@ -426,27 +407,27 @@ public function set_config_provider() { $newvalues = $allvalues; $newvalues->some = 'unset'; $provider['Unset an existing value'] = [ - $allvalues, - 'some', - null, - $newvalues, - ]; + $allvalues, + 'some', + null, + $newvalues, + ]; $newvalues = $allvalues; $newvalues->some = $randvalue; $provider['Set an existing value'] = [ - $allvalues, - 'some', - $randvalue, - $newvalues, - ]; + $allvalues, + 'some', + $randvalue, + $newvalues, + ]; $provider['Set a new value'] = [ - $allvalues, - 'newkey', - $randvalue, - (object) array_merge((array) $allvalues, ['newkey' => $randvalue]), - ]; + $allvalues, + 'newkey', + $randvalue, + (object) array_merge((array) $allvalues, ['newkey' => $randvalue]), + ]; return $provider; } @@ -460,23 +441,20 @@ public function set_config_provider() { * @param mixed $newvalue The new value to set * @param mixed $expected The expected value */ - public function test_set_config($initialvalues, $key, $newvalue, $expected) { + public function test_set_config($initialvalues, $key, $newvalue, $expected): void { $step = new \tool_usertours\step(); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $rcp->setValue($step, $initialvalues); $target = $this->getMockBuilder(\tool_usertours\local\target\base::class) ->disableOriginalConstructor() - ->getMock() - ; + ->getMock(); $target->expects($this->any()) ->method('is_setting_forced') - ->willReturn(false) - ; + ->willReturn(false); $step->set_config($key, $newvalue); @@ -486,22 +464,19 @@ public function test_set_config($initialvalues, $key, $newvalue, $expected) { /** * Ensure that non-dirty tours are not persisted. */ - public function test_persist_non_dirty() { + public function test_persist_non_dirty(): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'to_record', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'reload', + ]) + ->getMock(); $step->expects($this->never()) - ->method('to_record') - ; + ->method('to_record'); $step->expects($this->never()) - ->method('reload') - ; + ->method('reload'); $this->assertSame($step, $step->persist()); } @@ -509,45 +484,38 @@ public function test_persist_non_dirty() { /** * Ensure that new dirty steps are persisted. */ - public function test_persist_dirty_new() { + public function test_persist_dirty_new(): void { // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) ->method('insert_record') - ->willReturn(42) - ; + ->willReturn(42); // Mock the tour. $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'to_record', - 'calculate_sortorder', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'calculate_sortorder', + 'reload', + ]) + ->getMock(); $step->expects($this->once()) ->method('to_record') ->willReturn((object)['id' => 42]); - ; $step->expects($this->once()) - ->method('calculate_sortorder') - ; + ->method('calculate_sortorder'); $step->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $rcp->setValue($step, true); $tour = $this->createMock(\tool_usertours\tour::class); $rcp = $rc->getProperty('tour'); - $rcp->setAccessible(true); $rcp->setValue($step, $tour); $this->assertSame($step, $step->persist()); @@ -556,43 +524,37 @@ public function test_persist_dirty_new() { /** * Ensure that new non-dirty, forced steps are persisted. */ - public function test_persist_force_new() { + public function test_persist_force_new(): void { global $DB; // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) ->method('insert_record') - ->willReturn(42) - ; + ->willReturn(42); // Mock the tour. $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'to_record', - 'calculate_sortorder', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'calculate_sortorder', + 'reload', + ]) + ->getMock(); $step->expects($this->once()) ->method('to_record') ->willReturn((object)['id' => 42]); - ; $step->expects($this->once()) - ->method('calculate_sortorder') - ; + ->method('calculate_sortorder'); $step->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $tour = $this->createMock(\tool_usertours\tour::class); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('tour'); - $rcp->setAccessible(true); $rcp->setValue($step, $tour); $this->assertSame($step, $step->persist(true)); @@ -601,48 +563,40 @@ public function test_persist_force_new() { /** * Ensure that existing dirty steps are persisted. */ - public function test_persist_dirty_existing() { + public function test_persist_dirty_existing(): void { // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) - ->method('update_record') - ; + ->method('update_record'); // Mock the tour. $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'to_record', - 'calculate_sortorder', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'calculate_sortorder', + 'reload', + ]) + ->getMock(); $step->expects($this->once()) ->method('to_record') ->willReturn((object)['id' => 42]); - ; $step->expects($this->never()) - ->method('calculate_sortorder') - ; + ->method('calculate_sortorder'); $step->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($step, 42); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $rcp->setValue($step, true); $tour = $this->createMock(\tool_usertours\tour::class); $rcp = $rc->getProperty('tour'); - $rcp->setAccessible(true); $rcp->setValue($step, $tour); $this->assertSame($step, $step->persist()); @@ -651,46 +605,39 @@ public function test_persist_dirty_existing() { /** * Ensure that existing non-dirty, forced steps are persisted. */ - public function test_persist_force_existing() { + public function test_persist_force_existing(): void { global $DB; // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) - ->method('update_record') - ; + ->method('update_record'); // Mock the tour. $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'to_record', - 'calculate_sortorder', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'calculate_sortorder', + 'reload', + ]) + ->getMock(); $step->expects($this->once()) ->method('to_record') - ->willReturn((object)['id' => 42]); - ; + ->willReturn((object) ['id' => 42]); $step->expects($this->never()) - ->method('calculate_sortorder') - ; + ->method('calculate_sortorder'); $step->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($step, 42); $tour = $this->createMock(\tool_usertours\tour::class); $rcp = $rc->getProperty('tour'); - $rcp->setAccessible(true); $rcp->setValue($step, $tour); $this->assertSame($step, $step->persist(true)); @@ -699,17 +646,15 @@ public function test_persist_force_existing() { /** * Check that a tour which has never been persisted is removed correctly. */ - public function test_remove_non_persisted() { + public function test_remove_non_persisted(): void { $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([]) - ->getMock() - ; + ->getMock(); // Mock the database. $DB = $this->mock_database(); $DB->expects($this->never()) - ->method('delete_records') - ; + ->method('delete_records'); $this->assertNull($step->remove()); } @@ -717,42 +662,36 @@ public function test_remove_non_persisted() { /** * Check that a tour which has been persisted is removed correctly. */ - public function test_remove_persisted() { + public function test_remove_persisted(): void { $id = rand(1, 100); $tour = $this->getMockBuilder(\tool_usertours\tour::class) ->onlyMethods([ - 'reset_step_sortorder', - ]) - ->getMock() - ; + 'reset_step_sortorder', + ]) + ->getMock(); $tour->expects($this->once()) - ->method('reset_step_sortorder') - ; + ->method('reset_step_sortorder'); $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'get_tour', - ]) - ->getMock() - ; + 'get_tour', + ]) + ->getMock(); $step->expects($this->once()) ->method('get_tour') - ->willReturn($tour) - ; + ->willReturn($tour); // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) ->method('delete_records') - ->with($this->equalTo('tool_usertours_steps'), $this->equalTo(['id' => $id])) - ; + ->with($this->equalTo('tool_usertours_steps'), $this->equalTo(['id' => $id])); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($step, $id); $this->assertEquals($id, $step->get_id()); @@ -764,37 +703,37 @@ public function test_remove_persisted() { * * @return array */ - public function getter_provider() { + public static function getter_provider(): array { return [ - 'id' => [ - 'id', - rand(1, 100), - ], - 'tourid' => [ - 'tourid', - rand(1, 100), - ], - 'title' => [ - 'title', - 'Lorem', - ], - 'content' => [ - 'content', - 'Lorem', - ], - 'targettype' => [ - 'targettype', - 'Lorem', - ], - 'targetvalue' => [ - 'targetvalue', - 'Lorem', - ], - 'sortorder' => [ - 'sortorder', - rand(1, 100), - ], - ]; + 'id' => [ + 'id', + rand(1, 100), + ], + 'tourid' => [ + 'tourid', + rand(1, 100), + ], + 'title' => [ + 'title', + 'Lorem', + ], + 'content' => [ + 'content', + 'Lorem', + ], + 'targettype' => [ + 'targettype', + 'Lorem', + ], + 'targetvalue' => [ + 'targetvalue', + 'Lorem', + ], + 'sortorder' => [ + 'sortorder', + rand(1, 100), + ], + ]; } /** @@ -804,13 +743,12 @@ public function getter_provider() { * @param string $key The key to test * @param mixed $value The expected value */ - public function test_getters($key, $value) { + public function test_getters($key, $value): void { $step = new \tool_usertours\step(); $rc = new \ReflectionClass(\tool_usertours\step::class); $rcp = $rc->getProperty($key); - $rcp->setAccessible(true); $rcp->setValue($step, $value); $getter = 'get_' . $key; @@ -821,7 +759,7 @@ public function test_getters($key, $value) { /** * Ensure that the get_step_image_from_input function replace PIXICON placeholder with the correct images correctly. */ - public function test_get_step_image_from_input() { + public function test_get_step_image_from_input(): void { // Test step content with single image. $stepcontent = '@@PIXICON::tour/tour_mycourses::tool_usertours@@
Test'; $stepcontent = \tool_usertours\step::get_step_image_from_input($stepcontent); @@ -832,7 +770,8 @@ public function test_get_step_image_from_input() { $this->assertStringNotContainsString('PIXICON', $stepcontent); // Test step content with multiple images. - $stepcontent = '@@PIXICON::tour/tour_mycourses::tool_usertours@@
Test
@@PIXICON::tour/tour_myhomepage::tool_usertours@@'; + $stepcontent = + '@@PIXICON::tour/tour_mycourses::tool_usertours@@
Test
@@PIXICON::tour/tour_myhomepage::tool_usertours@@'; $stepcontent = \tool_usertours\step::get_step_image_from_input($stepcontent); // If the format is correct, PIXICON placeholder will be replaced with the img tag. $this->assertStringStartsWith(' * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\local\filter\theme */ class theme_filter_test extends \advanced_testcase { - /** * Data Provider for filter_matches function. * * @return array */ - public function filter_matches_provider() { + public static function filter_matches_provider(): array { return [ 'No config set; Matches' => [ null, @@ -73,7 +73,7 @@ public function filter_matches_provider() { * @param string $currenttheme The name of the current theme * @param boolean $expected Whether the tour is expected to match */ - public function test_filter_matches($filtervalues, $currenttheme, $expected) { + public function test_filter_matches($filtervalues, $currenttheme, $expected): void { global $PAGE; $filtername = \tool_usertours\local\filter\theme::class; diff --git a/admin/tool/usertours/tests/tour_test.php b/admin/tool/usertours/tests/tour_test.php index f7955dd94e45..e32df99a1f81 100644 --- a/admin/tool/usertours/tests/tour_test.php +++ b/admin/tool/usertours/tests/tour_test.php @@ -16,25 +16,25 @@ namespace tool_usertours; -defined('MOODLE_INTERNAL') || die(); - -global $CFG; -require_once($CFG->libdir . '/formslib.php'); - /** * Tests for tour. * * @package tool_usertours * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_usertours\tour */ class tour_test extends \advanced_testcase { - /** * @var moodle_database */ protected $db; + public static function setUpBeforeClass(): void { + global $CFG; + require_once($CFG->libdir . '/formslib.php'); + } + /** * Setup to store the DB reference. */ @@ -62,8 +62,7 @@ public function mock_database() { global $DB; $DB = $this->getMockBuilder(\moodle_database::class) - ->getMock() - ; + ->getMock(); return $DB; } @@ -73,33 +72,37 @@ public function mock_database() { * * @return array */ - public function dirty_value_provider() { + public static function dirty_value_provider(): array { return [ - 'name' => [ - 'name', - ['Lorem'], - ], - 'description' => [ - 'description', - ['Lorem'], - ], - 'pathmatch' => [ - 'pathmatch', - ['Lorem'], - ], - 'enabled' => [ - 'enabled', - ['Lorem'], - ], - 'sortorder' => [ - 'sortorder', - [1], - ], - 'config' => [ - 'config', - ['key', 'value'], - ], - ]; + 'name' => [ + 'name', + ['Lorem'], + ], + 'description' => [ + 'description', + ['Lorem'], + ], + 'pathmatch' => [ + 'pathmatch', + ['Lorem'], + ], + 'enabled' => [ + 'enabled', + ['Lorem'], + ], + 'sortorder' => [ + 'sortorder', + [1], + ], + 'config' => [ + 'config', + ['key', 'value'], + ], + 'showtourwhen' => [ + 'showtourwhen', + [0], + ], + ]; } /** @@ -109,14 +112,13 @@ public function dirty_value_provider() { * @param string $name The name of the key being tested * @param mixed $value The value being set */ - public function test_dirty_values($name, $value) { + public function test_dirty_values($name, $value): void { $tour = new \tool_usertours\tour(); $method = 'set_' . $name; call_user_func_array([$tour, $method], $value); $rc = new \ReflectionClass(\tool_usertours\tour::class); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $this->assertTrue($rcp->getValue($tour)); } @@ -126,37 +128,37 @@ public function test_dirty_values($name, $value) { * * @return array */ - public function getter_provider() { + public static function getter_provider(): array { return [ - 'id' => [ - 'id', - rand(1, 100), - ], - 'name' => [ - 'name', - 'Lorem', - ], - 'description' => [ - 'description', - 'Lorem', - ], - 'pathmatch' => [ - 'pathmatch', - 'Lorem', - ], - 'enabled' => [ - 'enabled', - 'Lorem', - ], - 'sortorder' => [ - 'sortorder', - rand(1, 100), - ], - 'config' => [ - 'config', - ['key', 'value'], - ], - ]; + 'id' => [ + 'id', + rand(1, 100), + ], + 'name' => [ + 'name', + 'Lorem', + ], + 'description' => [ + 'description', + 'Lorem', + ], + 'pathmatch' => [ + 'pathmatch', + 'Lorem', + ], + 'enabled' => [ + 'enabled', + 'Lorem', + ], + 'sortorder' => [ + 'sortorder', + rand(1, 100), + ], + 'config' => [ + 'config', + ['key', 'value'], + ], + ]; } /** @@ -166,13 +168,12 @@ public function getter_provider() { * @param string $key The name of the key being tested * @param mixed $value The value being set */ - public function test_getters($key, $value) { + public function test_getters($key, $value): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty($key); - $rcp->setAccessible(true); $rcp->setValue($tour, $value); $getter = 'get_' . $key; @@ -183,15 +184,13 @@ public function test_getters($key, $value) { /** * Ensure that non-dirty tours are not persisted. */ - public function test_persist_non_dirty() { + public function test_persist_non_dirty(): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods(['to_record']) - ->getMock() - ; + ->getMock(); $tour->expects($this->never()) - ->method('to_record') - ; + ->method('to_record'); $this->assertSame($tour, $tour->persist()); } @@ -199,134 +198,114 @@ public function test_persist_non_dirty() { /** * Ensure that new dirty tours are persisted. */ - public function test_persist_dirty_new() { + public function test_persist_dirty_new(): void { // Mock the database. $DB = $this->mock_database(); $DB->expects($this->never()) - ->method('update_record') - ; + ->method('update_record'); $id = rand(1, 100); $DB->expects($this->once()) ->method('insert_record') - ->willReturn($id) - ; + ->willReturn($id); // Mock the tour. $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'to_record', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'reload', + ]) + ->getMock(); $tour->expects($this->once()) - ->method('to_record') - ; + ->method('to_record'); $tour->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $rcp->setValue($tour, true); $this->assertSame($tour, $tour->persist()); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $this->assertEquals($id, $rcp->getValue($tour)); } /** * Ensure that non-dirty, forced tours are persisted. */ - public function test_persist_force_new() { + public function test_persist_force_new(): void { global $DB; // Mock the database. $DB = $this->mock_database(); $DB->expects($this->never()) - ->method('update_record') - ; + ->method('update_record'); $id = rand(1, 100); $DB->expects($this->once()) ->method('insert_record') - ->willReturn($id) - ; + ->willReturn($id); // Mock the tour. $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'to_record', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'reload', + ]) + ->getMock(); $tour->expects($this->once()) - ->method('to_record') - ; + ->method('to_record'); $tour->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $this->assertSame($tour, $tour->persist(true)); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $this->assertEquals($id, $rcp->getValue($tour)); } /** * Ensure that dirty tours are persisted. */ - public function test_persist_dirty_existing() { + public function test_persist_dirty_existing(): void { // Mock the database. $DB = $this->mock_database(); $DB->expects($this->once()) ->method('update_record') - ->willReturn($this->returnSelf()) - ; + ->willReturn($this->returnSelf()); $DB->expects($this->never()) - ->method('insert_record') - ; + ->method('insert_record'); // Mock the tour. $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'to_record', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'reload', + ]) + ->getMock(); $tour->expects($this->once()) - ->method('to_record') - ; + ->method('to_record'); $tour->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($tour, 42); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $rcp->setValue($tour, true); $this->assertSame($tour, $tour->persist()); @@ -335,7 +314,7 @@ public function test_persist_dirty_existing() { /** * Ensure that non-dirty, forced tours are persisted. */ - public function test_persist_force() { + public function test_persist_force(): void { global $DB; // Mock the database. @@ -343,38 +322,31 @@ public function test_persist_force() { $DB->expects($this->once()) ->method('update_record') - ->willReturn($this->returnSelf()) - ; + ->willReturn($this->returnSelf()); $DB->expects($this->never()) - ->method('insert_record') - ; + ->method('insert_record'); // Mock the tour. $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'to_record', - 'reload', - ]) - ->getMock() - ; + 'to_record', + 'reload', + ]) + ->getMock(); $tour->expects($this->once()) - ->method('to_record') - ; + ->method('to_record'); $tour->expects($this->once()) - ->method('reload') - ; + ->method('reload'); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($tour, 42); $rcp = $rc->getProperty('dirty'); - $rcp->setAccessible(true); $rcp->setValue($tour, true); $this->assertSame($tour, $tour->persist(true)); @@ -383,42 +355,40 @@ public function test_persist_force() { /** * Test setting config. */ - public function test_set_config() { + public function test_set_config(): void { $tour = new \tool_usertours\tour(); $tour->set_config('key', 'value'); $tour->set_config('another', [ - 'foo' => 'bar', - ]); + 'foo' => 'bar', + ]); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $this->assertEquals((object) [ - 'key' => 'value', - 'another' => [ - 'foo' => 'bar', - ], - ], $rcp->getValue($tour)); + 'key' => 'value', + 'another' => [ + 'foo' => 'bar', + ], + ], $rcp->getValue($tour)); } /** * Test get_config with no keys provided. */ - public function test_get_config_no_keys() { + public function test_get_config_no_keys(): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $allvalues = (object) [ - 'some' => 'value', - 'another' => 42, - 'key' => [ - 'somethingelse', - ], - ]; + 'some' => 'value', + 'another' => 42, + 'key' => [ + 'somethingelse', + ], + ]; $rcp->setValue($tour, $allvalues); @@ -430,59 +400,59 @@ public function test_get_config_no_keys() { * * @return array */ - public function get_config_provider() { + public static function get_config_provider(): array { $allvalues = (object) [ - 'some' => 'value', - 'another' => 42, - 'key' => [ - 'somethingelse', - ], - ]; + 'some' => 'value', + 'another' => 42, + 'key' => [ + 'somethingelse', + ], + ]; return [ - 'No nitial config' => [ - null, - null, - null, - (object) [], - ], - 'All values' => [ - $allvalues, - null, - null, - $allvalues, - ], - 'Valid string value' => [ - $allvalues, - 'some', - null, - 'value', - ], - 'Valid array value' => [ - $allvalues, - 'key', - null, - ['somethingelse'], - ], - 'Invalid value' => [ - $allvalues, - 'notavalue', - null, - null, - ], - 'Configuration value' => [ - $allvalues, - 'placement', - null, - \tool_usertours\configuration::get_default_value('placement'), - ], - 'Invalid value with default' => [ - $allvalues, - 'notavalue', - 'somedefault', - 'somedefault', - ], - ]; + 'No nitial config' => [ + null, + null, + null, + (object) [], + ], + 'All values' => [ + $allvalues, + null, + null, + $allvalues, + ], + 'Valid string value' => [ + $allvalues, + 'some', + null, + 'value', + ], + 'Valid array value' => [ + $allvalues, + 'key', + null, + ['somethingelse'], + ], + 'Invalid value' => [ + $allvalues, + 'notavalue', + null, + null, + ], + 'Configuration value' => [ + $allvalues, + 'placement', + null, + \tool_usertours\configuration::get_default_value('placement'), + ], + 'Invalid value with default' => [ + $allvalues, + 'notavalue', + 'somedefault', + 'somedefault', + ], + ]; } /** @@ -494,12 +464,11 @@ public function get_config_provider() { * @param mixed $default The default value * @param mixed $expected The expected value */ - public function test_get_config_valid_keys($values, $key, $default, $expected) { + public function test_get_config_valid_keys($values, $key, $default, $expected): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('config'); - $rcp->setAccessible(true); $rcp->setValue($tour, $values); $this->assertEquals($expected, $tour->get_config($key, $default)); @@ -508,23 +477,20 @@ public function test_get_config_valid_keys($values, $key, $default, $expected) { /** * Check that a tour which has never been persisted is removed correctly. */ - public function test_remove_non_persisted() { + public function test_remove_non_persisted(): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_steps', - ]) - ->getMock() - ; + 'get_steps', + ]) + ->getMock(); $tour->expects($this->never()) - ->method('get_steps') - ; + ->method('get_steps'); // Mock the database. $DB = $this->mock_database(); $DB->expects($this->never()) - ->method('delete_records') - ; + ->method('delete_records'); $this->assertNull($tour->remove()); } @@ -532,32 +498,28 @@ public function test_remove_non_persisted() { /** * Check that a tour which has been persisted is removed correctly. */ - public function test_remove_persisted() { + public function test_remove_persisted(): void { $id = rand(1, 100); $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_steps', - ]) - ->getMock() - ; + 'get_steps', + ]) + ->getMock(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('id'); - $rcp->setAccessible(true); $rcp->setValue($tour, $id); $step = $this->getMockBuilder(\tool_usertours\step::class) ->onlyMethods([ - 'remove', - ]) - ->getMock() - ; + 'remove', + ]) + ->getMock(); $tour->expects($this->once()) ->method('get_steps') - ->willReturn([$step]) - ; + ->willReturn([$step]); // Mock the database. $DB = $this->mock_database(); @@ -569,14 +531,12 @@ public function test_remove_persisted() { [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_LAST_COMPLETED_BY_USER . $id])], [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_REQUESTED_BY_USER . $id])] ) - ->willReturn(null) - ; + ->willReturn(null); $DB->expects($this->once()) ->method('get_records') ->with($this->equalTo('tool_usertours_tours'), $this->equalTo(null)) - ->willReturn([]) - ; + ->willReturn([]); $this->assertNull($tour->remove()); } @@ -584,7 +544,7 @@ public function test_remove_persisted() { /** * Teset that sortorder is reset according to sortorder with values from 0. */ - public function test_reset_step_sortorder() { + public function test_reset_step_sortorder(): void { $tour = new \tool_usertours\tour(); $mockdata = []; @@ -598,12 +558,10 @@ public function test_reset_step_sortorder() { $DB = $this->mock_database(); $DB->expects($this->once()) ->method('get_records') - ->willReturn($mockdata) - ; + ->willReturn($mockdata); $setfield = $DB->expects($this->exactly(5)) - ->method('set_field') - ; + ->method('set_field'); call_user_func_array([$setfield, 'withConsecutive'], $expectations); $tour->reset_step_sortorder(); @@ -612,7 +570,7 @@ public function test_reset_step_sortorder() { /** * Test that a disabled tour should never be shown to users. */ - public function test_should_show_for_user_disabled() { + public function test_should_show_for_user_disabled(): void { $tour = new \tool_usertours\tour(); $tour->set_enabled(false); @@ -624,40 +582,54 @@ public function test_should_show_for_user_disabled() { * * @return array */ - public function should_show_for_user_provider() { + public static function should_show_for_user_provider(): array { $time = time(); return [ - 'Not seen by user at all' => [ - null, - null, - null, - true, - ], - 'Completed by user before majorupdatetime' => [ - $time - DAYSECS, - null, - $time, - true, - ], - 'Completed by user since majorupdatetime' => [ - $time, - null, - $time - DAYSECS, - false, - ], - 'Requested by user before current completion' => [ - $time, - $time - DAYSECS, - null, - false, - ], - 'Requested by user since completion' => [ - $time - DAYSECS, - $time, - null, - true, - ], - ]; + 'Not seen by user at all' => [ + null, + null, + null, + [], + true, + ], + 'Completed by user before majorupdatetime' => [ + $time - DAYSECS, + null, + $time, + [], + true, + ], + 'Completed by user since majorupdatetime' => [ + $time, + null, + $time - DAYSECS, + [], + false, + ], + 'Requested by user before current completion' => [ + $time, + $time - DAYSECS, + $time - MINSECS, + [], + false, + ], + 'Requested by user since completion' => [ + $time - DAYSECS, + $time, + 'null', + [], + true, + ], + 'Tour will show on each load' => [ + $time, + $time - DAYSECS, + null, + [ + 'showtourwhen' => tour::SHOW_TOUR_ON_EACH_PAGE_VISIT, + ], + true, + ], + ]; } /** @@ -667,30 +639,37 @@ public function should_show_for_user_provider() { * @param mixed $completiondate The user's completion date for this tour * @param mixed $requesteddate The user's last requested date for this tour * @param mixed $updateddate The date this tour was last updated + * @param mixed $config The tour config to apply * @param string $expectation The expected tour key */ - public function test_should_show_for_user($completiondate, $requesteddate, $updateddate, $expectation) { + public function test_should_show_for_user( + $completiondate, + $requesteddate, + $updateddate, + $config, + $expectation, + ): void { // Uses user preferences so we must be in a user context. $this->resetAfterTest(); $this->setAdminUser(); $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_id', - 'get_config', - 'is_enabled', - ]) - ->getMock() - ; + 'get_id', + 'is_enabled', + ]) + ->getMock(); $tour->method('is_enabled') - ->willReturn(true) - ; + ->willReturn(true); + + foreach ($config as $key => $value) { + $tour->set_config($key, $value); + } $id = rand(1, 100); $tour->method('get_id') - ->willReturn($id) - ; + ->willReturn($id); if ($completiondate !== null) { set_user_preference(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER . $id, $completiondate); @@ -701,10 +680,7 @@ public function test_should_show_for_user($completiondate, $requesteddate, $upda } if ($updateddate !== null) { - $tour->expects($this->once()) - ->method('get_config') - ->willReturn($updateddate) - ; + $tour->set_config('majorupdatetime', $updateddate); } $this->assertEquals($expectation, $tour->should_show_for_user()); @@ -715,44 +691,47 @@ public function test_should_show_for_user($completiondate, $requesteddate, $upda * * @return array */ - public function get_tour_key_provider() { + public static function get_tour_key_provider(): array { $id = rand(1, 100); $time = time(); return [ 'No initial values' => [ - $id, - [null, $time], - $this->greaterThanOrEqual($time), - true, - null, - sprintf('tool_usertours_\d_%d_%s', $id, $time), - ], + $id, + [null, $time], + static::logicalOr( + new \PHPUnit\Framework\Constraint\IsEqual($time), + new \PHPUnit\Framework\Constraint\GreaterThan($time), + ), + true, + null, + sprintf('tool_usertours_\d_%d_%s', $id, $time), + ], 'Initial tour time, no user pref' => [ - $id, - [$time], - null, - false, - null, - sprintf('tool_usertours_\d_%d_%s', $id, $time), - ], + $id, + [$time], + null, + false, + null, + sprintf('tool_usertours_\d_%d_%s', $id, $time), + ], 'Initial tour time, with user reset lower' => [ - $id, - [$time], - null, - false, - $time - DAYSECS, - sprintf('tool_usertours_\d_%d_%s', $id, $time), - ], + $id, + [$time], + null, + false, + $time - DAYSECS, + sprintf('tool_usertours_\d_%d_%s', $id, $time), + ], 'Initial tour time, with user reset higher' => [ - $id, - [$time], - null, - false, - $time + DAYSECS, - sprintf('tool_usertours_\d_%d_%s', $id, $time + DAYSECS), - ], + $id, + [$time], + null, + false, + $time + DAYSECS, + sprintf('tool_usertours_\d_%d_%s', $id, $time + DAYSECS), + ], ]; } @@ -767,83 +746,74 @@ public function get_tour_key_provider() { * @param mixed $userpref The value to set for the user preference * @param string $expectation The expected tour key */ - public function test_get_tour_key($id, $getconfig, $setconfig, $willpersist, $userpref, $expectation) { + public function test_get_tour_key($id, $getconfig, $setconfig, $willpersist, $userpref, $expectation): void { // Uses user preferences so we must be in a user context. $this->resetAfterTest(); $this->setAdminUser(); $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_config', - 'set_config', - 'get_id', - 'persist', - ]) - ->getMock() - ; + 'get_config', + 'set_config', + 'get_id', + 'persist', + ]) + ->getMock(); if ($getconfig) { $tour->expects($this->exactly(count($getconfig))) ->method('get_config') - ->will(call_user_func_array([$this, 'onConsecutiveCalls'], $getconfig)) - ; + ->will(call_user_func_array([$this, 'onConsecutiveCalls'], $getconfig)); } if ($setconfig) { $tour->expects($this->once()) ->method('set_config') ->with($this->equalTo('majorupdatetime'), $setconfig) - ->will($this->returnSelf()) - ; + ->will($this->returnSelf()); } else { $tour->expects($this->never()) - ->method('set_config') - ; + ->method('set_config'); } if ($willpersist) { $tour->expects($this->once()) - ->method('persist') - ; + ->method('persist'); } else { $tour->expects($this->never()) - ->method('persist') - ; + ->method('persist'); } $tour->expects($this->any()) ->method('get_id') - ->willReturn($id) - ; + ->willReturn($id); if ($userpref !== null) { set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $userpref); } $this->assertMatchesRegularExpression( - '/' . $expectation . '/', - $tour->get_tour_key() - ); + '/' . $expectation . '/', + $tour->get_tour_key() + ); } /** * Ensure that the request_user_reset function sets an appropriate value for the tour. */ - public function test_requested_user_reset() { + public function test_requested_user_reset(): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_id', - ]) - ->getMock() - ; + 'get_id', + ]) + ->getMock(); $id = rand(1, 100); $time = time(); $tour->expects($this->once()) ->method('get_id') - ->willReturn($id) - ; + ->willReturn($id); $tour->request_user_reset(); @@ -853,21 +823,19 @@ public function test_requested_user_reset() { /** * Ensure that the request_user_reset function sets an appropriate value for the tour. */ - public function test_mark_user_completed() { + public function test_mark_user_completed(): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods([ - 'get_id', - ]) - ->getMock() - ; + 'get_id', + ]) + ->getMock(); $id = rand(1, 100); $time = time(); $tour->expects($this->once()) ->method('get_id') - ->willReturn($id) - ; + ->willReturn($id); $tour->mark_user_completed(); @@ -879,34 +847,34 @@ public function test_mark_user_completed() { * * @return array */ - public function sortorder_first_last_provider() { + public static function sortorder_first_last_provider(): array { $topcount = rand(10, 100); return [ - 'Only tour => first + last' => [ - 0, - true, - 1, - true, - ], - 'First tour of many' => [ - 0, - true, - $topcount, - false, - ], - 'Last tour of many' => [ - $topcount - 1, - false, - $topcount, - true, - ], - 'Middle tour of many' => [ - 5, - false, - $topcount, - false, - ], - ]; + 'Only tour => first + last' => [ + 0, + true, + 1, + true, + ], + 'First tour of many' => [ + 0, + true, + $topcount, + false, + ], + 'Last tour of many' => [ + $topcount - 1, + false, + $topcount, + true, + ], + 'Middle tour of many' => [ + 5, + false, + $topcount, + false, + ], + ]; } /** @@ -918,12 +886,11 @@ public function sortorder_first_last_provider() { * @param int $total The number of tours * @param bool $islast Whether this is the last tour */ - public function test_is_first_tour($sortorder, $isfirst, $total, $islast) { + public function test_is_first_tour($sortorder, $isfirst, $total, $islast): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('sortorder'); - $rcp->setAccessible(true); $rcp->setValue($tour, $sortorder); $this->assertEquals($isfirst, $tour->is_first_tour()); @@ -938,20 +905,18 @@ public function test_is_first_tour($sortorder, $isfirst, $total, $islast) { * @param int $total The number of tours * @param bool $islast Whether this is the last tour */ - public function test_is_last_tour_calculated($sortorder, $isfirst, $total, $islast) { + public function test_is_last_tour_calculated($sortorder, $isfirst, $total, $islast): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('sortorder'); - $rcp->setAccessible(true); $rcp->setValue($tour, $sortorder); // The total will be calculated. $DB = $this->mock_database(); $DB->expects($this->once()) ->method('count_records') - ->willReturn($total) - ; + ->willReturn($total); $this->assertEquals($islast, $tour->is_last_tour()); } @@ -964,12 +929,11 @@ public function test_is_last_tour_calculated($sortorder, $isfirst, $total, $isla * @param int $total The number of tours * @param bool $islast Whether this is the last tour */ - public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast) { + public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast): void { $tour = new \tool_usertours\tour(); $rc = new \ReflectionClass(tour::class); $rcp = $rc->getProperty('sortorder'); - $rcp->setAccessible(true); $rcp->setValue($tour, $sortorder); // The total is provided. @@ -977,8 +941,7 @@ public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast $DB = $this->mock_database(); $DB->expects($this->never()) ->method('count_records') - ->willReturn(0) - ; + ->willReturn(0); $this->assertEquals($islast, $tour->is_last_tour($total)); } @@ -987,7 +950,7 @@ public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast * * @return array */ - public function get_filter_values_provider() { + public static function get_filter_values_provider(): array { $cheese = ['cheddar', 'boursin', 'mozzarella']; $horses = ['coolie', 'dakota', 'leo', 'twiggy']; return [ @@ -1013,7 +976,7 @@ public function get_filter_values_provider() { 'Some config for several filters' => [ [ 'horses' => $horses, - 'cheese' => $cheese + 'cheese' => $cheese, ], 'horses', $horses, @@ -1029,7 +992,7 @@ public function get_filter_values_provider() { * @param string $filtername The name of the filter being tested * @param array $expectedvalues The expected result */ - public function test_get_filter_values($fullconfig, $filtername, $expectedvalues) { + public function test_get_filter_values($fullconfig, $filtername, $expectedvalues): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods(['get_config']) ->getMock(); @@ -1046,7 +1009,7 @@ public function test_get_filter_values($fullconfig, $filtername, $expectedvalues * * @return array */ - public function set_filter_values_provider() { + public static function set_filter_values_provider(): array { $cheese = ['cheddar', 'boursin', 'mozzarella']; $horses = ['coolie', 'dakota', 'leo', 'twiggy']; @@ -1087,7 +1050,7 @@ public function set_filter_values_provider() { * @param array $newvalues The new values to store * @param array $expectedvalues The combined values */ - public function test_set_filter_values_merge($currentvalues, $filtername, $newvalues, $expectedvalues) { + public function test_set_filter_values_merge($currentvalues, $filtername, $newvalues, $expectedvalues): void { $tour = $this->getMockBuilder(tour::class) ->onlyMethods(['get_config', 'set_config']) ->getMock(); diff --git a/analytics/tests/community_of_inquiry_activities_completed_by.php b/analytics/tests/community_of_inquiry_activities_completed_by.php index cb76f02d8dbf..c8b4df5fa4db 100644 --- a/analytics/tests/community_of_inquiry_activities_completed_by.php +++ b/analytics/tests/community_of_inquiry_activities_completed_by.php @@ -78,7 +78,6 @@ public function test_get_activities_with_availability($availabilitylevel) { )); $method = new ReflectionMethod($availabilityinfo, 'set_in_database'); - $method->setAccessible(true); $method->invoke($availabilityinfo, json_encode($structure)); $this->setUser($stu1); @@ -339,11 +338,9 @@ private function instantiate_indicator($modulename, \core_analytics\course $cour $class = new ReflectionClass($indicator); $property = $class->getProperty('course'); - $property->setAccessible(true); $property->setValue($indicator, $course); $method = new ReflectionMethod($indicator, 'get_activities'); - $method->setAccessible(true); return array($indicator, $method); } diff --git a/analytics/tests/model_test.php b/analytics/tests/model_test.php index 884ef3e610d1..b2a621379a0b 100644 --- a/analytics/tests/model_test.php +++ b/analytics/tests/model_test.php @@ -427,7 +427,6 @@ public function test_export_config() { $modelconfig = new \core_analytics\model_config($this->model); $method = new \ReflectionMethod('\\core_analytics\\model_config', 'export_model_data'); - $method->setAccessible(true); $modeldata = $method->invoke($modelconfig); diff --git a/auth/classes/output/login.php b/auth/classes/output/login.php index 3800cb72ecc2..6854234c0d4b 100644 --- a/auth/classes/output/login.php +++ b/auth/classes/output/login.php @@ -75,6 +75,10 @@ class login implements renderable, templatable { public $maintenance; /** @var string ReCaptcha element HTML. */ public $recaptcha; + /** @var bool Toggle the password visibility icon. */ + public $togglepassword; + /** @var bool Toggle the password visibility icon for small screens only. */ + public $smallscreensonly; /** * Constructor. @@ -130,6 +134,11 @@ public function __construct(array $authsequence, $username = '') { require_once($CFG->libdir . '/recaptchalib_v2.php'); $this->recaptcha = recaptcha_get_challenge_html(RECAPTCHA_API_URL, $CFG->recaptchapublickey); } + + // Toggle password visibility icon. + $this->togglepassword = get_config('core', 'loginpasswordtoggle') == TOGGLE_SENSITIVE_ENABLED || + get_config('core', 'loginpasswordtoggle') == TOGGLE_SENSITIVE_SMALL_SCREENS_ONLY; + $this->smallscreensonly = get_config('core', 'loginpasswordtoggle') == TOGGLE_SENSITIVE_SMALL_SCREENS_ONLY; } /** @@ -175,6 +184,8 @@ public function export_for_template(renderer_base $output) { $data->maintenance = format_text($this->maintenance, FORMAT_MOODLE); $data->languagemenu = $this->languagemenu; $data->recaptcha = $this->recaptcha; + $data->togglepassword = $this->togglepassword; + $data->smallscreensonly = $this->smallscreensonly; return $data; } diff --git a/auth/tests/behat/loginform.feature b/auth/tests/behat/loginform.feature index a87301d421a7..cc4c01338e7c 100644 --- a/auth/tests/behat/loginform.feature +++ b/auth/tests/behat/loginform.feature @@ -101,3 +101,21 @@ Feature: Test if the login form provides the correct feedback And I press "Log in" And I press the tab key Then the focused element is "Username" "field" + + Scenario: Display the password visibility toggle icon + Given the following config values are set as admin: + | loginpasswordtoggle | 1 | + When I follow "Log in" + Then "Toggle sensitive" "button" should be visible + And the following config values are set as admin: + | loginpasswordtoggle | 0 | + And I reload the page + And "Toggle sensitive" "button" should not be visible + + Scenario: Display the password visibility toggle icon for small screens only + Given the following config values are set as admin: + | loginpasswordtoggle | 2 | + When I follow "Log in" + Then "Toggle sensitive" "button" should not be visible + And I change the viewport size to "mobile" + And "Toggle sensitive" "button" should be visible diff --git a/backup/moodle2/tests/backup_stepslib_test.php b/backup/moodle2/tests/backup_stepslib_test.php index 46dc1347cb1c..d06ec5ae69fd 100644 --- a/backup/moodle2/tests/backup_stepslib_test.php +++ b/backup/moodle2/tests/backup_stepslib_test.php @@ -74,7 +74,6 @@ public function test_backup_section_structure_step(): void { $reflection = new \ReflectionClass($step); $method = $reflection->getMethod('define_structure'); - $method->setAccessible(true); $structure = $method->invoke($step); $elements = $structure->get_final_elements(); diff --git a/backup/moodle2/tests/restore_gradebook_structure_step_test.php b/backup/moodle2/tests/restore_gradebook_structure_step_test.php index 2b47e14c80fd..a541f383cb7e 100644 --- a/backup/moodle2/tests/restore_gradebook_structure_step_test.php +++ b/backup/moodle2/tests/restore_gradebook_structure_step_test.php @@ -77,7 +77,6 @@ public function test_rewrite_step_backup_file_for_legacy_freeze($source, $expect $rc = new \ReflectionClass('\restore_gradebook_structure_step'); $rcm = $rc->getMethod('rewrite_step_backup_file_for_legacy_freeze'); - $rcm->setAccessible(true); $rcm->invoke($restore, $filepath); // Check the result. diff --git a/backup/tests/automated_backup_test.php b/backup/tests/automated_backup_test.php index 26831d2ab43f..42fdd102374b 100644 --- a/backup/tests/automated_backup_test.php +++ b/backup/tests/automated_backup_test.php @@ -116,11 +116,9 @@ public function test_automated_backup_skipped_run() { $classobject = $this->backupcronautomatedhelper->return_this(); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses'); - $method->setAccessible(true); // Allow accessing of private method. $courses = $method->invoke($classobject); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups'); - $method->setAccessible(true); // Allow accessing of private method. $emailpending = $method->invokeArgs($classobject, [$courses, $admin]); $this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not scheduled for backup until/'); @@ -145,7 +143,6 @@ public function test_automated_backup_push_run() { $classobject = $this->backupcronautomatedhelper->return_this(); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses'); - $method->setAccessible(true); // Allow accessing of private method. $courses = $method->invoke($classobject); // Create this backup course. @@ -161,7 +158,6 @@ public function test_automated_backup_push_run() { $DB->update_record('backup_courses', $backupcourse); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups'); - $method->setAccessible(true); // Allow accessing of private method. $emailpending = $method->invokeArgs($classobject, [$courses, $admin]); $this->assertTrue($emailpending); @@ -204,7 +200,6 @@ public function test_should_skip_invisible_course() { $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time()); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup'); - $method->setAccessible(true); // Allow accessing of private method. $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]); $this->assertTrue($skipped); @@ -239,7 +234,6 @@ public function test_should_skip_not_modified_course_in_days() { $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time()); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup'); - $method->setAccessible(true); // Allow accessing of private method. $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]); $this->assertTrue($skipped); @@ -274,7 +268,6 @@ public function test_should_skip_not_modified_course_since_prev() { $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time()); $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup'); - $method->setAccessible(true); // Allow accessing of private method. $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]); $this->assertTrue($skipped); @@ -298,7 +291,6 @@ public function test_task_complete_when_courseid_is_missing() { // Create a backup task. $method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task'); - $method->setAccessible(true); // Allow accessing of private method. $method->invokeArgs($classobject, [$backupcourse, $admin]); // Delete course for this test. @@ -331,7 +323,6 @@ public function test_task_complete_when_backup_course_is_missing() { // Create a backup task. $method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task'); - $method->setAccessible(true); // Allow accessing of private method. $method->invokeArgs($classobject, [$backupcourse, $admin]); // Delete backup course for this test. diff --git a/backup/util/dbops/tests/restore_dbops_test.php b/backup/util/dbops/tests/restore_dbops_test.php index 325c01a4adbd..2be84704e080 100644 --- a/backup/util/dbops/tests/restore_dbops_test.php +++ b/backup/util/dbops/tests/restore_dbops_test.php @@ -351,7 +351,6 @@ public function test_precheck_user($dbuser, $backupuser, $samesite, $outcome) { $dbuser = $DB->get_record('user', ['id' => $dbuser->id]); $method = (new \ReflectionClass('restore_dbops'))->getMethod('precheck_user'); - $method->setAccessible(true); $result = $method->invoke(null, $backupuser, $samesite, $siteid); if (is_bool($result)) { diff --git a/backup/util/helper/tests/restore_log_rule_test.php b/backup/util/helper/tests/restore_log_rule_test.php index 58c0cfc6ffae..83c004ffc1b6 100644 --- a/backup/util/helper/tests/restore_log_rule_test.php +++ b/backup/util/helper/tests/restore_log_rule_test.php @@ -62,11 +62,9 @@ public function test_build_regexp() { $class = new \ReflectionClass('restore_log_rule'); $method = $class->getMethod('extract_tokens'); - $method->setAccessible(true); $tokens = $method->invoke($lr, $original); $method = $class->getMethod('build_regexp'); - $method->setAccessible(true); $this->assertSame($expectation, $method->invoke($lr, $original, $tokens)); } } diff --git a/badges/tests/badgeslib_test.php b/badges/tests/badgeslib_test.php index df569b1cd4c7..555e2d8a7042 100644 --- a/badges/tests/badgeslib_test.php +++ b/badges/tests/badgeslib_test.php @@ -912,7 +912,6 @@ public function test_core_badges_myprofile_navigation() { core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course); $reflector = new ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('localbadges', $nodes->getValue($tree)); } @@ -935,7 +934,6 @@ public function test_core_badges_myprofile_navigation_badges_disabled() { core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $course); $reflector = new ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('localbadges', $nodes->getValue($tree)); } @@ -954,7 +952,6 @@ public function test_core_badges_myprofile_navigation_with_course_badge() { core_badges_myprofile_navigation($tree, $this->user, $iscurrentuser, $this->course); $reflector = new ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('localbadges', $nodes->getValue($tree)); } diff --git a/badges/tests/behat/delete_awarded_badge.feature b/badges/tests/behat/delete_awarded_badge.feature index 8d917144a519..39ae200b387d 100644 --- a/badges/tests/behat/delete_awarded_badge.feature +++ b/badges/tests/behat/delete_awarded_badge.feature @@ -34,8 +34,7 @@ Feature: Delete course badge already awarded # Navigate to Manage Badges page in order to delete the badge And I navigate to "Badges > Manage badges" in current page administration # Delete the badge - And I open the action menu in "" "table_row" - And I choose "Delete" in the open action menu + And I press "Delete" action in the "" report row And I press "" And I am on the "Course 1" "enrolled users" page And I click on "Student 1" "link" diff --git a/badges/tests/behat/manage_badges.feature b/badges/tests/behat/manage_badges.feature index c06fabc29ce9..d9b6b0055c94 100644 --- a/badges/tests/behat/manage_badges.feature +++ b/badges/tests/behat/manage_badges.feature @@ -54,16 +54,14 @@ Feature: Manage badges And I set the field "Manager" to "1" And I press "Save" And I navigate to "Badges > Manage badges" in site administration - And I open the action menu in "Badge #1" "table_row" - And I choose "Enable access" in the open action menu + And I press "Enable access" action in the "Badge #1" report row And I should see "Changes in badge access" And I press "Continue" And I should see "Access to the badges was successfully enabled" Then the following should exist in the "reportbuilder-table" table: | Name | Badge status | | Badge #1 | Available | - And I open the action menu in "Badge #1" "table_row" - And I choose "Disable access" in the open action menu + And I press "Disable access" action in the "Badge #1" report row And I should see "Access to the badges was successfully disabled" And the following should exist in the "reportbuilder-table" table: | Name | Badge status | @@ -78,14 +76,12 @@ Feature: Manage badges And I set the field "Manager" to "1" And I press "Save" And I navigate to "Badges > Manage badges" in site administration - And I open the action menu in "Badge #1" "table_row" - And I choose "Enable access" in the open action menu + And I press "Enable access" action in the "Badge #1" report row And I press "Continue" - And I open the action menu in "Badge #1" "table_row" - And I choose "Award badge" in the open action menu + And I press "Award badge" action in the "Badge #1" report row And I set the field "potentialrecipients[]" to "Admin User (moodle@example.com)" And I press "Award badge" And I navigate to "Badges > Manage badges" in site administration - And the following should exist in the "reportbuilder-table" table: + Then the following should exist in the "reportbuilder-table" table: | Name | Badge status | Recipients | | Badge #1 | Available | 1 | diff --git a/badges/tests/behat/view_badge.feature b/badges/tests/behat/view_badge.feature index 1f7795b3b9bd..2a82efa3efa0 100644 --- a/badges/tests/behat/view_badge.feature +++ b/badges/tests/behat/view_badge.feature @@ -38,8 +38,7 @@ Feature: Display badges And I navigate to "Badges > Manage badges" in site administration And I follow "Testing system badge" And I select "Recipients (1)" from the "jump" singleselect - And I open the action menu in "Student 1" "table_row" - And I choose "View issued badge" in the open action menu + And I press "View issued badge" action in the "Student 1" report row Then I should see "Awarded to Student 1" And I should see "This badge has to be awarded by a user with the following role:" And I should not see "Expired" @@ -64,8 +63,7 @@ Feature: Display badges And I navigate to "Badges > Manage badges" in site administration And I follow "Testing system badge" And I select "Recipients (1)" from the "jump" singleselect - And I open the action menu in "Student 1" "table_row" - And I choose "View issued badge" in the open action menu + And I press "View issued badge" action in the "Student 1" report row Then I should see "Awarded to Student 1" And I should see "Complete ALL of the listed requirements." And I should see "This badge has to be awarded by a user with the following role:" @@ -86,8 +84,7 @@ Feature: Display badges And I press "Continue" # Check badge details are displayed. And I select "Recipients (2)" from the "jump" singleselect - And I open the action menu in "Student 1" "table_row" - And I choose "View issued badge" in the open action menu + And I press "View issued badge" action in the "Student 1" report row Then I should see "Awarded to Student 1" And I should see "Complete ANY of the listed requirements." And I should see "This badge has to be awarded by a user with the following role:" @@ -115,8 +112,7 @@ Feature: Display badges And I navigate to "Badges > Manage badges" in site administration And I follow "Testing system badge" And I select "Recipients (1)" from the "jump" singleselect - And I open the action menu in "Student 1" "table_row" - And I choose "View issued badge" in the open action menu + And I press "View issued badge" action in the "Student 1" report row Then I should see "Expires" And I should not see "Expired" @@ -140,7 +136,6 @@ Feature: Display badges And I navigate to "Badges > Manage badges" in site administration And I follow "Testing system badge" And I select "Recipients (1)" from the "jump" singleselect - And I open the action menu in "Student 1" "table_row" - And I choose "View issued badge" in the open action menu + And I press "View issued badge" action in the "Student 1" report row Then I should see "Expired" And I should not see "Expires" diff --git a/badges/tests/output/manage_badge_action_bar_test.php b/badges/tests/output/manage_badge_action_bar_test.php index 0979f5e8c303..b93a3c7d2eda 100644 --- a/badges/tests/output/manage_badge_action_bar_test.php +++ b/badges/tests/output/manage_badge_action_bar_test.php @@ -134,7 +134,6 @@ public function test_generate_badge_navigation(string $role, array $expected) { $rc = new \ReflectionClass(manage_badge_action_bar::class); $rcm = $rc->getMethod('generate_badge_navigation'); - $rcm->setAccessible(true); $content = $rcm->invoke($actionbar); $this->assertEquals($expected, array_values($content)); } diff --git a/blocks/accessreview/tests/accessibility_review_test.php b/blocks/accessreview/tests/accessibility_review_test.php index 00f74ad458ca..8388fd31e95f 100644 --- a/blocks/accessreview/tests/accessibility_review_test.php +++ b/blocks/accessreview/tests/accessibility_review_test.php @@ -39,7 +39,6 @@ public static function setUpBeforeClass(): void { public function test_get_toggle_link() { $rc = new ReflectionClass(block_accessreview::class); $rm = $rc->getMethod('get_toggle_link'); - $rm->setAccessible(true); $block = new block_accessreview(); $output = $rm->invoke($block); @@ -60,7 +59,6 @@ public function test_get_download_link() { $rc = new ReflectionClass(block_accessreview::class); $rm = $rc->getMethod('get_download_link'); - $rm->setAccessible(true); $block = new block_accessreview(); $this->setUser($user1); @@ -86,7 +84,6 @@ public function test_get_report_link() { $rc = new ReflectionClass(block_accessreview::class); $rm = $rc->getMethod('get_report_link'); - $rm->setAccessible(true); $block = new block_accessreview(); $this->setUser($user1); diff --git a/blocks/myoverview/classes/output/main.php b/blocks/myoverview/classes/output/main.php index e9bb671e376c..abe98d9e2091 100644 --- a/blocks/myoverview/classes/output/main.php +++ b/blocks/myoverview/classes/output/main.php @@ -363,7 +363,14 @@ public function get_customfield_values_for_export() { if (!$this->displaygroupingcustomfield) { return []; } - $fieldid = $DB->get_field('customfield_field', 'id', ['shortname' => $this->customfiltergrouping]); + + // Get the relevant customfield ID within the core_course/course component/area. + $fieldid = $DB->get_field_sql(" + SELECT f.id + FROM {customfield_field} f + JOIN {customfield_category} c ON c.id = f.categoryid + WHERE f.shortname = :shortname AND c.component = 'core_course' AND c.area = 'course' + ", ['shortname' => $this->customfiltergrouping]); if (!$fieldid) { return []; } diff --git a/blog/tests/lib_test.php b/blog/tests/lib_test.php index 345e9d2936e8..0eb80f70e9b7 100644 --- a/blog/tests/lib_test.php +++ b/blog/tests/lib_test.php @@ -175,7 +175,6 @@ public function test_core_blog_myprofile_navigation() { core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course); $reflector = new \ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('blogs', $nodes->getValue($tree)); } @@ -197,7 +196,6 @@ public function test_core_blog_myprofile_navigation_as_guest() { core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course); $reflector = new \ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('blogs', $nodes->getValue($tree)); } @@ -220,7 +218,6 @@ public function test_core_blog_myprofile_navigation_blogs_disabled() { core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course); $reflector = new \ReflectionObject($tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('blogs', $nodes->getValue($tree)); } diff --git a/cache/stores/redis/lib.php b/cache/stores/redis/lib.php index 3b3229302bb9..16a8d25d8f49 100644 --- a/cache/stores/redis/lib.php +++ b/cache/stores/redis/lib.php @@ -851,7 +851,6 @@ public static function initialise_test_instance(cache_definition $definition) { if (!empty($config->test_ttl)) { $definition = clone $definition; $property = (new ReflectionClass($definition))->getProperty('ttl'); - $property->setAccessible(true); $property->setValue($definition, 999); } $cache = new cachestore_redis('Redis test', $configuration); diff --git a/cache/tests/cache_test.php b/cache/tests/cache_test.php index ac6df7fe274c..a080816856c3 100644 --- a/cache/tests/cache_test.php +++ b/cache/tests/cache_test.php @@ -2332,11 +2332,8 @@ public function test_application_locking_multiple_layers_failures(): void { // We need to get the individual stores so as to set up the right behaviour here. $ref = new \ReflectionClass('\cache'); $definitionprop = $ref->getProperty('definition'); - $definitionprop->setAccessible(true); $storeprop = $ref->getProperty('store'); - $storeprop->setAccessible(true); $loaderprop = $ref->getProperty('loader'); - $loaderprop->setAccessible(true); $definition = $definitionprop->getValue($cache); $localstore = $storeprop->getValue($cache); @@ -2346,7 +2343,6 @@ public function test_application_locking_multiple_layers_failures(): void { // Set the lock waiting time to 1 second so it doesn't take forever to run the test. $ref = new \ReflectionClass('\cachestore_file'); $lockwaitprop = $ref->getProperty('lockwait'); - $lockwaitprop->setAccessible(true); $lockwaitprop->setValue($localstore, 1); $lockwaitprop->setValue($sharedstore, 1); diff --git a/calendar/amd/build/calendar_threemonth.min.js b/calendar/amd/build/calendar_threemonth.min.js deleted file mode 100644 index 93cae7033aaf..000000000000 --- a/calendar/amd/build/calendar_threemonth.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * This module handles display of multiple mini calendars in a view, and - * movement through them. - * - * @deprecated since 4.0 MDL-72810. - * @todo MDL-73117 This will be deleted in Moodle 4.4. - * @module core_calendar/calendar_threemonth - * @copyright 2017 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define("core_calendar/calendar_threemonth",["jquery","core/notification","core_calendar/selectors","core_calendar/events","core/templates","core_calendar/view_manager"],(function($,Notification,CalendarSelectors,CalendarEvents,Templates,CalendarViewManager){return{init:function(root){!function(root){$("body").on([CalendarEvents.monthChanged,CalendarEvents.dayChanged].join(" "),(function(e,year,month,courseId,categoryId){root.queue((function(next){return processRequest(e,year,month,courseId,categoryId).then((function(){return next()})).fail(Notification.exception)}))}));var processRequest=function(e,year,month,courseId,categoryId){var newParent=root.find('[data-year="'+year+'"][data-month="'+month+'"]').closest(CalendarSelectors.calendarPeriods.month),allMonths=root.find(CalendarSelectors.calendarPeriods.month),previousMonth=$(allMonths[0]),nextMonth=$(allMonths[2]),placeHolder=$("");placeHolder.attr("data-template","core_calendar/threemonth_month"),placeHolder.attr("data-includenavigation",!1),placeHolder.attr("data-mini",!0);var requestYear,requestMonth,oldMonth,placeHolderContainer=$("
");if(placeHolderContainer.hide(),placeHolderContainer.append(placeHolder),newParent.is(previousMonth))placeHolderContainer.insertBefore(previousMonth),requestYear=previousMonth.data("previousYear"),requestMonth=previousMonth.data("previousMonth"),oldMonth=nextMonth;else{if(!newParent.is(nextMonth))return $.Deferred().resolve();placeHolderContainer.insertAfter(nextMonth),requestYear=nextMonth.data("nextYear"),requestMonth=nextMonth.data("nextMonth"),oldMonth=previousMonth}return CalendarViewManager.refreshMonthContent(placeHolder,requestYear,requestMonth,courseId,categoryId,placeHolder).then((function(){var slideUpPromise=$.Deferred(),slideDownPromise=$.Deferred();return oldMonth.slideUp("fast",(function(){$(this).remove(),slideUpPromise.resolve()})),placeHolderContainer.slideDown("fast",(function(){slideDownPromise.resolve()})),$.when(slideUpPromise,slideDownPromise)}))};root.on("click",CalendarSelectors.links.miniDayLink,(function(e){var miniDayLink=$(e.target),year=miniDayLink.data("year"),month=miniDayLink.data("month"),day=miniDayLink.text(),courseId=miniDayLink.data("courseid"),categoryId=miniDayLink.data("categoryid"),calendarRoot=$("body").find(CalendarSelectors.calendarMain);CalendarViewManager.refreshDayContent(calendarRoot,year,month,day,courseId,categoryId,calendarRoot.find('[id^="calendar-"][data-template^="core_calendar/"]'),"core_calendar/calendar_day"),e.preventDefault(),CalendarViewManager.updateUrl("?view=day")}))}(root=$(root))}}})); - -//# sourceMappingURL=calendar_threemonth.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/calendar_threemonth.min.js.map b/calendar/amd/build/calendar_threemonth.min.js.map deleted file mode 100644 index fc4a2155b072..000000000000 --- a/calendar/amd/build/calendar_threemonth.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"calendar_threemonth.min.js","sources":["../src/calendar_threemonth.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * This module handles display of multiple mini calendars in a view, and\n * movement through them.\n *\n * @deprecated since 4.0 MDL-72810.\n * @todo MDL-73117 This will be deleted in Moodle 4.4.\n * @module core_calendar/calendar_threemonth\n * @copyright 2017 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/notification',\n 'core_calendar/selectors',\n 'core_calendar/events',\n 'core/templates',\n 'core_calendar/view_manager',\n],\nfunction(\n $,\n Notification,\n CalendarSelectors,\n CalendarEvents,\n Templates,\n CalendarViewManager\n) {\n\n /**\n * Listen to and handle any calendar events fired by the calendar UI.\n *\n * @method registerCalendarEventListeners\n * @param {object} root The calendar root element\n */\n var registerCalendarEventListeners = function(root) {\n var body = $('body');\n body.on([CalendarEvents.monthChanged, CalendarEvents.dayChanged].join(' '), function(e, year, month, courseId, categoryId) {\n // We have to use a queue here because the calling code is decoupled from these listeners.\n // It's possible for the event to be called multiple times before one call is fully resolved.\n root.queue(function(next) {\n return processRequest(e, year, month, courseId, categoryId)\n .then(function() {\n return next();\n })\n .fail(Notification.exception)\n ;\n });\n });\n\n var processRequest = function(e, year, month, courseId, categoryId) {\n var newCurrentMonth = root.find('[data-year=\"' + year + '\"][data-month=\"' + month + '\"]');\n var newParent = newCurrentMonth.closest(CalendarSelectors.calendarPeriods.month);\n var allMonths = root.find(CalendarSelectors.calendarPeriods.month);\n\n var previousMonth = $(allMonths[0]);\n var nextMonth = $(allMonths[2]);\n\n var placeHolder = $('');\n placeHolder.attr('data-template', 'core_calendar/threemonth_month');\n placeHolder.attr('data-includenavigation', false);\n placeHolder.attr('data-mini', true);\n var placeHolderContainer = $('
');\n placeHolderContainer.hide();\n placeHolderContainer.append(placeHolder);\n\n var requestYear;\n var requestMonth;\n var oldMonth;\n\n if (newParent.is(previousMonth)) {\n // Fetch the new previous month.\n placeHolderContainer.insertBefore(previousMonth);\n\n requestYear = previousMonth.data('previousYear');\n requestMonth = previousMonth.data('previousMonth');\n oldMonth = nextMonth;\n } else if (newParent.is(nextMonth)) {\n // Fetch the new next month.\n placeHolderContainer.insertAfter(nextMonth);\n requestYear = nextMonth.data('nextYear');\n requestMonth = nextMonth.data('nextMonth');\n oldMonth = previousMonth;\n } else {\n return $.Deferred().resolve();\n }\n\n return CalendarViewManager.refreshMonthContent(\n placeHolder,\n requestYear,\n requestMonth,\n courseId,\n categoryId,\n placeHolder\n )\n .then(function() {\n var slideUpPromise = $.Deferred();\n var slideDownPromise = $.Deferred();\n oldMonth.slideUp('fast', function() {\n $(this).remove();\n slideUpPromise.resolve();\n });\n placeHolderContainer.slideDown('fast', function() {\n slideDownPromise.resolve();\n });\n\n return $.when(slideUpPromise, slideDownPromise);\n });\n };\n\n // Listen for a click on the day link in the three month block to load the day view.\n root.on('click', CalendarSelectors.links.miniDayLink, function(e) {\n\n var miniDayLink = $(e.target);\n var year = miniDayLink.data('year'),\n month = miniDayLink.data('month'),\n day = miniDayLink.text(),\n courseId = miniDayLink.data('courseid'),\n categoryId = miniDayLink.data('categoryid'),\n calendarRoot = $('body').find(CalendarSelectors.calendarMain);\n CalendarViewManager.refreshDayContent(calendarRoot, year, month, day, courseId, categoryId,\n calendarRoot.find('[id^=\"calendar-\"][data-template^=\"core_calendar/\"]'), 'core_calendar/calendar_day');\n e.preventDefault();\n CalendarViewManager.updateUrl('?view=day');\n });\n };\n\n return {\n init: function(root) {\n root = $(root);\n\n registerCalendarEventListeners(root);\n }\n };\n});\n"],"names":["define","$","Notification","CalendarSelectors","CalendarEvents","Templates","CalendarViewManager","init","root","on","monthChanged","dayChanged","join","e","year","month","courseId","categoryId","queue","next","processRequest","then","fail","exception","newParent","find","closest","calendarPeriods","allMonths","previousMonth","nextMonth","placeHolder","attr","requestYear","requestMonth","oldMonth","placeHolderContainer","hide","append","is","insertBefore","data","Deferred","resolve","insertAfter","refreshMonthContent","slideUpPromise","slideDownPromise","slideUp","this","remove","slideDown","when","links","miniDayLink","target","day","text","calendarRoot","calendarMain","refreshDayContent","preventDefault","updateUrl","registerCalendarEventListeners"],"mappings":";;;;;;;;;;AAyBAA,2CAAO,CACH,SACA,oBACA,0BACA,uBACA,iBACA,+BAEJ,SACIC,EACAC,aACAC,kBACAC,eACAC,UACAC,2BAqGO,CACHC,KAAM,SAASC,OA7FkB,SAASA,MAC/BP,EAAE,QACRQ,GAAG,CAACL,eAAeM,aAAcN,eAAeO,YAAYC,KAAK,MAAM,SAASC,EAAGC,KAAMC,MAAOC,SAAUC,YAG3GT,KAAKU,OAAM,SAASC,aACTC,eAAeP,EAAGC,KAAMC,MAAOC,SAAUC,YAC/CI,MAAK,kBACKF,UAEVG,KAAKpB,aAAaqB,qBAKvBH,eAAiB,SAASP,EAAGC,KAAMC,MAAOC,SAAUC,gBAEhDO,UADkBhB,KAAKiB,KAAK,eAAiBX,KAAO,kBAAoBC,MAAQ,MACpDW,QAAQvB,kBAAkBwB,gBAAgBZ,OACtEa,UAAYpB,KAAKiB,KAAKtB,kBAAkBwB,gBAAgBZ,OAExDc,cAAgB5B,EAAE2B,UAAU,IAC5BE,UAAY7B,EAAE2B,UAAU,IAExBG,YAAc9B,EAAE,UACpB8B,YAAYC,KAAK,gBAAiB,kCAClCD,YAAYC,KAAK,0BAA0B,GAC3CD,YAAYC,KAAK,aAAa,OAK1BC,YACAC,aACAC,SANAC,qBAAuBnC,EAAE,YAC7BmC,qBAAqBC,OACrBD,qBAAqBE,OAAOP,aAMxBP,UAAUe,GAAGV,eAEbO,qBAAqBI,aAAaX,eAElCI,YAAcJ,cAAcY,KAAK,gBACjCP,aAAeL,cAAcY,KAAK,iBAClCN,SAAWL,cACR,CAAA,IAAIN,UAAUe,GAAGT,kBAOb7B,EAAEyC,WAAWC,UALpBP,qBAAqBQ,YAAYd,WACjCG,YAAcH,UAAUW,KAAK,YAC7BP,aAAeJ,UAAUW,KAAK,aAC9BN,SAAWN,qBAKRvB,oBAAoBuC,oBACvBd,YACAE,YACAC,aACAlB,SACAC,WACAc,aAEHV,MAAK,eACEyB,eAAiB7C,EAAEyC,WACnBK,iBAAmB9C,EAAEyC,kBACzBP,SAASa,QAAQ,QAAQ,WACrB/C,EAAEgD,MAAMC,SACRJ,eAAeH,aAEnBP,qBAAqBe,UAAU,QAAQ,WACnCJ,iBAAiBJ,aAGd1C,EAAEmD,KAAKN,eAAgBC,sBAKtCvC,KAAKC,GAAG,QAASN,kBAAkBkD,MAAMC,aAAa,SAASzC,OAEnDyC,YAAcrD,EAAEY,EAAE0C,QAClBzC,KAAOwC,YAAYb,KAAK,QACxB1B,MAAQuC,YAAYb,KAAK,SACzBe,IAAMF,YAAYG,OAClBzC,SAAWsC,YAAYb,KAAK,YAC5BxB,WAAaqC,YAAYb,KAAK,cAC9BiB,aAAezD,EAAE,QAAQwB,KAAKtB,kBAAkBwD,cACpDrD,oBAAoBsD,kBAAkBF,aAAc5C,KAAMC,MAAOyC,IAAKxC,SAAUC,WAC5EyC,aAAajC,KAAK,sDAAuD,8BAC7EZ,EAAEgD,iBACFvD,oBAAoBwD,UAAU,gBAQlCC,CAFAvD,KAAOP,EAAEO"} \ No newline at end of file diff --git a/calendar/amd/src/calendar_threemonth.js b/calendar/amd/src/calendar_threemonth.js deleted file mode 100644 index 576f6c10bc58..000000000000 --- a/calendar/amd/src/calendar_threemonth.js +++ /dev/null @@ -1,148 +0,0 @@ -// This file is part of Moodle - http://moodle.org/ -// -// Moodle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Moodle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Moodle. If not, see . - -/** - * This module handles display of multiple mini calendars in a view, and - * movement through them. - * - * @deprecated since 4.0 MDL-72810. - * @todo MDL-73117 This will be deleted in Moodle 4.4. - * @module core_calendar/calendar_threemonth - * @copyright 2017 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define([ - 'jquery', - 'core/notification', - 'core_calendar/selectors', - 'core_calendar/events', - 'core/templates', - 'core_calendar/view_manager', -], -function( - $, - Notification, - CalendarSelectors, - CalendarEvents, - Templates, - CalendarViewManager -) { - - /** - * Listen to and handle any calendar events fired by the calendar UI. - * - * @method registerCalendarEventListeners - * @param {object} root The calendar root element - */ - var registerCalendarEventListeners = function(root) { - var body = $('body'); - body.on([CalendarEvents.monthChanged, CalendarEvents.dayChanged].join(' '), function(e, year, month, courseId, categoryId) { - // We have to use a queue here because the calling code is decoupled from these listeners. - // It's possible for the event to be called multiple times before one call is fully resolved. - root.queue(function(next) { - return processRequest(e, year, month, courseId, categoryId) - .then(function() { - return next(); - }) - .fail(Notification.exception) - ; - }); - }); - - var processRequest = function(e, year, month, courseId, categoryId) { - var newCurrentMonth = root.find('[data-year="' + year + '"][data-month="' + month + '"]'); - var newParent = newCurrentMonth.closest(CalendarSelectors.calendarPeriods.month); - var allMonths = root.find(CalendarSelectors.calendarPeriods.month); - - var previousMonth = $(allMonths[0]); - var nextMonth = $(allMonths[2]); - - var placeHolder = $(''); - placeHolder.attr('data-template', 'core_calendar/threemonth_month'); - placeHolder.attr('data-includenavigation', false); - placeHolder.attr('data-mini', true); - var placeHolderContainer = $('
'); - placeHolderContainer.hide(); - placeHolderContainer.append(placeHolder); - - var requestYear; - var requestMonth; - var oldMonth; - - if (newParent.is(previousMonth)) { - // Fetch the new previous month. - placeHolderContainer.insertBefore(previousMonth); - - requestYear = previousMonth.data('previousYear'); - requestMonth = previousMonth.data('previousMonth'); - oldMonth = nextMonth; - } else if (newParent.is(nextMonth)) { - // Fetch the new next month. - placeHolderContainer.insertAfter(nextMonth); - requestYear = nextMonth.data('nextYear'); - requestMonth = nextMonth.data('nextMonth'); - oldMonth = previousMonth; - } else { - return $.Deferred().resolve(); - } - - return CalendarViewManager.refreshMonthContent( - placeHolder, - requestYear, - requestMonth, - courseId, - categoryId, - placeHolder - ) - .then(function() { - var slideUpPromise = $.Deferred(); - var slideDownPromise = $.Deferred(); - oldMonth.slideUp('fast', function() { - $(this).remove(); - slideUpPromise.resolve(); - }); - placeHolderContainer.slideDown('fast', function() { - slideDownPromise.resolve(); - }); - - return $.when(slideUpPromise, slideDownPromise); - }); - }; - - // Listen for a click on the day link in the three month block to load the day view. - root.on('click', CalendarSelectors.links.miniDayLink, function(e) { - - var miniDayLink = $(e.target); - var year = miniDayLink.data('year'), - month = miniDayLink.data('month'), - day = miniDayLink.text(), - courseId = miniDayLink.data('courseid'), - categoryId = miniDayLink.data('categoryid'), - calendarRoot = $('body').find(CalendarSelectors.calendarMain); - CalendarViewManager.refreshDayContent(calendarRoot, year, month, day, courseId, categoryId, - calendarRoot.find('[id^="calendar-"][data-template^="core_calendar/"]'), 'core_calendar/calendar_day'); - e.preventDefault(); - CalendarViewManager.updateUrl('?view=day'); - }); - }; - - return { - init: function(root) { - root = $(root); - - registerCalendarEventListeners(root); - } - }; -}); diff --git a/calendar/renderer.php b/calendar/renderer.php index b6c867835574..5134fa007fa5 100644 --- a/calendar/renderer.php +++ b/calendar/renderer.php @@ -51,63 +51,10 @@ public function complete_layout() { } /** - * Produces the content for the three months block (pretend block) - * - * This includes the previous month, the current month, and the next month - * * @deprecated since 4.0 MDL-72810. - * @todo MDL-73117 This will be deleted in Moodle 4.4. - * - * @param calendar_information $calendar - * @return string */ - public function fake_block_threemonths(calendar_information $calendar) { - debugging('This method is no longer used as the three month calendar block has been removed', DEBUG_DEVELOPER); - - // Get the calendar type we are using. - $calendartype = \core_calendar\type_factory::get_calendar_instance(); - $time = $calendartype->timestamp_to_date_array($calendar->time); - - $current = $calendar->time; - $prevmonthyear = $calendartype->get_prev_month($time['year'], $time['mon']); - $prev = $calendartype->convert_to_timestamp( - $prevmonthyear[1], - $prevmonthyear[0], - 1 - ); - $nextmonthyear = $calendartype->get_next_month($time['year'], $time['mon']); - $next = $calendartype->convert_to_timestamp( - $nextmonthyear[1], - $nextmonthyear[0], - 1 - ); - - $content = ''; - - // Previous. - $calendar->set_time($prev); - list($previousmonth, ) = calendar_get_view($calendar, 'minithree', false, true); - - // Current month. - $calendar->set_time($current); - list($currentmonth, ) = calendar_get_view($calendar, 'minithree', false, true); - - // Next month. - $calendar->set_time($next); - list($nextmonth, ) = calendar_get_view($calendar, 'minithree', false, true); - - // Reset the time back. - $calendar->set_time($current); - - $data = (object) [ - 'previousmonth' => $previousmonth, - 'currentmonth' => $currentmonth, - 'nextmonth' => $nextmonth, - ]; - - $template = 'core_calendar/calendar_threemonth'; - $content .= $this->render_from_template($template, $data); - return $content; + public function fake_block_threemonths() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); } /** diff --git a/calendar/templates/calendar_threemonth.mustache b/calendar/templates/calendar_threemonth.mustache deleted file mode 100644 index 5fc66f7eb47c..000000000000 --- a/calendar/templates/calendar_threemonth.mustache +++ /dev/null @@ -1,52 +0,0 @@ -{{! - This file is part of Moodle - http://moodle.org/ - - Moodle is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Moodle is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Moodle. If not, see . -}} -{{! - @template core_calendar/calendar_threemonth - - @deprecated since 4.0 MDL-72810. - @todo MDL-73117 This will be deleted in Moodle 4.4. - - Calendar view to show three months as a block. - - The purpose of this template is to render a set of three months of calendar_mini in a block. - - Classes required for JS: - * none - - Data attributes required for JS: - * none - - Example context (json): - { - } -}} -
- {{#previousmonth}} - {{> core_calendar/threemonth_month}} - {{/previousmonth}} - {{#currentmonth}} - {{> core_calendar/threemonth_month}} - {{/currentmonth}} - {{#nextmonth}} - {{> core_calendar/threemonth_month}} - {{/nextmonth}} -
-{{#js}} -require(['jquery', 'core_calendar/calendar_threemonth'], function($, CalendarThreeMonth) { - CalendarThreeMonth.init($("#calendar-multi-{{uniqid}}")); -}); -{{/js}} diff --git a/calendar/tests/behat/behat_calendar.php b/calendar/tests/behat/behat_calendar.php index fc53c18233ca..3065ae8fd468 100644 --- a/calendar/tests/behat/behat_calendar.php +++ b/calendar/tests/behat/behat_calendar.php @@ -122,16 +122,6 @@ public function i_hover_over_today_in_mini_calendar_block(): void { $this->i_hover_over_day_of_this_month_in_mini_calendar_block($todaysday); } - /** - * Hover over today in the calendar. - * - * @Given /^I hover over today in the calendar$/ - */ - public function i_hover_over_today_in_the_calendar() { - $todaysday = date('j'); - return $this->i_hover_over_day_of_this_month_in_calendar($todaysday); - } - /** * Navigate to a specific month in the calendar. * diff --git a/calendar/tests/behat/behat_calendar_deprecated.php b/calendar/tests/behat/behat_calendar_deprecated.php new file mode 100644 index 000000000000..0fc1a08838b5 --- /dev/null +++ b/calendar/tests/behat/behat_calendar_deprecated.php @@ -0,0 +1,59 @@ +. + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../lib/behat/behat_deprecated_base.php'); + +/** + * Steps definitions that are now deprecated and will be removed in the next releases. + * + * This file only contains the steps that previously were in the behat_*.php files in the SAME DIRECTORY. + * When deprecating steps from other components or plugins, create a behat_COMPONENT_deprecated.php + * file in the same directory where the steps were defined. + * + * @package core_calendar + * @category test + * @copyright 2024 Mathew May + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_calendar_deprecated extends behat_deprecated_base { + /** + * Hover over today in the calendar. + * + * @Given /^I hover over today in the calendar$/ + * + * @deprecated since 4.4 MDL-73117. + * @TODO MDL-79721: This will be deleted in Moodle 4.8. + */ + public function i_hover_over_today_in_the_calendar() { + $this->deprecated_message('behat_calendar::i_hover_over_today_in_the_calendar'); + $todaysday = date('j'); + + $summarytitle = userdate(time(), get_string('strftimemonthyear')); + // The current month table. + $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]"; + + // Strings for the class cell match. + $cellclasses = "contains(concat(' ', normalize-space(@class), ' '), ' day ')"; + $daycontains = "text()[contains(concat(' ', normalize-space(.), ' '), ' {$todaysday} ')]"; + $daycell = "td[{$cellclasses}]"; + $dayofmonth = "a[{$daycontains}]"; + + $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth; + $this->execute("behat_general::i_hover", [$xpath, "xpath_element"]); + } +} diff --git a/calendar/tests/calendar_event_exporter_test.php b/calendar/tests/calendar_event_exporter_test.php index 055309216466..e092c4689b30 100644 --- a/calendar/tests/calendar_event_exporter_test.php +++ b/calendar/tests/calendar_event_exporter_test.php @@ -80,7 +80,6 @@ public function test_get_timestamp_min_limit($starttime, $min, $expected) { ->getMock(); $reflector = new \ReflectionClass($class); $method = $reflector->getMethod('get_timestamp_min_limit'); - $method->setAccessible(true); $result = $method->invoke($mock, $starttime, $min); $this->assertEquals($expected, $result['mindaytimestamp']); @@ -137,7 +136,6 @@ public function test_get_timestamp_max_limit($starttime, $max, $expected) { ->getMock(); $reflector = new \ReflectionClass($class); $method = $reflector->getMethod('get_timestamp_max_limit'); - $method->setAccessible(true); $result = $method->invoke($mock, $starttime, $max); $this->assertEquals($expected, $result['maxdaytimestamp']); diff --git a/calendar/tests/rrule_manager_test.php b/calendar/tests/rrule_manager_test.php index ed9a3c119943..12b625a27a83 100644 --- a/calendar/tests/rrule_manager_test.php +++ b/calendar/tests/rrule_manager_test.php @@ -124,7 +124,6 @@ public function test_parse_rrule() { $reflectionclass = new \ReflectionClass($mang); foreach ($props as $prop => $expectedval) { $rcprop = $reflectionclass->getProperty($prop); - $rcprop->setAccessible(true); $this->assertEquals($expectedval, $rcprop->getValue($mang)); } } diff --git a/calendar/upgrade.txt b/calendar/upgrade.txt index 89855aa40937..28f627b4144e 100644 --- a/calendar/upgrade.txt +++ b/calendar/upgrade.txt @@ -5,6 +5,15 @@ information provided here is intended especially for developers. * The following previously deprecated methods have been removed and can no longer be used: - `calendar_process_subscription_row` - `calendar_import_icalendar_events` + - `fake_block_threemonths` + - `i_click_day_of_this_month_in_calendar` + - `i_hover_over_today_in_the_calendar` +* The following previously deprecated files have been removed and can no longer be used: + - `calendar_threemonth.js` + - `calendar_threemonth.mustache` + - `threemonth_month.mustache` +* The following have been deprecated: + - Behat step definition `i_hover_over_today_in_the_calendar` * The event_exporter_base class now returns a field called "branded" indicating whether the module is branded or not. All the external functions using the exporter will now return the new field: - core_calendar_get_action_events_by_course diff --git a/communication/provider/matrix/tests/local/command_test.php b/communication/provider/matrix/tests/local/command_test.php index c255f26ed639..8e540b784101 100644 --- a/communication/provider/matrix/tests/local/command_test.php +++ b/communication/provider/matrix/tests/local/command_test.php @@ -281,7 +281,6 @@ public function test_query_parameters( ); $execute = new ReflectionMethod($instance, 'execute'); - $execute->setAccessible(true); $execute->invoke($instance, $command); } diff --git a/communication/provider/matrix/tests/matrix_client_test.php b/communication/provider/matrix/tests/matrix_client_test.php index 00680e242adc..a3e8c8950868 100644 --- a/communication/provider/matrix/tests/matrix_client_test.php +++ b/communication/provider/matrix/tests/matrix_client_test.php @@ -447,7 +447,6 @@ public function test_command_is_executed(): void { $rc = new \ReflectionClass($instance); $rcm = $rc->getMethod('execute'); - $rcm->setAccessible(true); $result = $rcm->invoke($instance, $command); $this->assertEquals(200, $result->getStatusCode()); diff --git a/completion/completion_completion.php b/completion/completion_completion.php index 54adf228420d..47bd4c003f9f 100644 --- a/completion/completion_completion.php +++ b/completion/completion_completion.php @@ -179,8 +179,10 @@ public function mark_complete($timecomplete = null) { // Notify user. $course = get_course($data->course); $messagesubject = get_string('coursecompleted', 'completion'); + $options = new stdClass(); + $options->context = context_course::instance($course->id); $a = [ - 'coursename' => get_course_display_name_for_list($course), + 'coursename' => format_string(get_course_display_name_for_list($course), true, $options), 'courselink' => (string) new moodle_url('/course/view.php', array('id' => $course->id)), ]; $messagebody = get_string('coursecompletedmessage', 'completion', $a); diff --git a/contentbank/tests/contentbank_test.php b/contentbank/tests/contentbank_test.php index 88a08ed07a9a..6291c2ae70e5 100644 --- a/contentbank/tests/contentbank_test.php +++ b/contentbank/tests/contentbank_test.php @@ -568,7 +568,6 @@ public function test_get_contenttypes_with_capability_feature(array $contenttype // Replace protected singletoninstance reference (core_plugin_manager property) with mock object. $ref = new \ReflectionProperty(\core_plugin_manager::class, 'singletoninstance'); - $ref->setAccessible(true); $ref->setValue(null, $pluginmanager); // Return values of get_plugins_of_type method. @@ -592,7 +591,6 @@ public function test_get_contenttypes_with_capability_feature(array $contenttype // Get access to private property enabledcontenttypes. $rc = new \ReflectionClass(\core_contentbank\contentbank::class); $rcp = $rc->getProperty('enabledcontenttypes'); - $rcp->setAccessible(true); foreach ($contenttypesenabled as $contenttypename) { $plugins["\\contenttype_$contenttypename\\contenttype"] = $contenttypename; diff --git a/course/format/tests/local/baseactions_test.php b/course/format/tests/local/baseactions_test.php index 65bc80d9732f..19d05e14332d 100644 --- a/course/format/tests/local/baseactions_test.php +++ b/course/format/tests/local/baseactions_test.php @@ -45,7 +45,6 @@ public static function setUpBeforeClass(): void { private function get_base_reflection_method(baseactions $baseinstance, string $methodname): ReflectionMethod { $reflectionclass = new \reflectionclass($baseinstance); $method = $reflectionclass->getMethod($methodname); - $method->setAccessible(true); return $method; } diff --git a/course/tests/category_hooks_test.php b/course/tests/category_hooks_test.php index 21a73bd91639..b68de7a7eebe 100644 --- a/course/tests/category_hooks_test.php +++ b/course/tests/category_hooks_test.php @@ -72,7 +72,6 @@ public function get_mock_category(\core_course_category $category, string $callb // This is used to overcome private constructor. $reflected = new \ReflectionClass(\core_course_category::class); $constructor = $reflected->getConstructor(); - $constructor->setAccessible(true); $constructor->invoke($mockcategory, $category->get_db_record()); return $mockcategory; diff --git a/course/tests/course_image_cache_test.php b/course/tests/course_image_cache_test.php index c3fffd79c21c..59b697a5b97a 100644 --- a/course/tests/course_image_cache_test.php +++ b/course/tests/course_image_cache_test.php @@ -98,7 +98,6 @@ public function test_getting_data_if_course_is_not_exist() { public function test_get_image_url_from_overview_files_return_null_if_no_summary_files_in_the_course() { $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files'); $cache = course_image::get_instance_for_cache(new cache_definition()); - $method->setAccessible(true); // Create course without files. $course = $this->getDataGenerator()->create_course(); @@ -111,7 +110,6 @@ public function test_get_image_url_from_overview_files_return_null_if_no_summary public function test_get_image_url_from_overview_files_returns_null_if_no_summary_images_in_the_course() { $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files'); $cache = course_image::get_instance_for_cache(new cache_definition()); - $method->setAccessible(true); // Create course without image files. $draftid2 = $this->fill_draft_area(['filename2.zip' => 'Test file contents2']); @@ -125,7 +123,6 @@ public function test_get_image_url_from_overview_files_returns_null_if_no_summar public function test_get_image_url_from_overview_files_returns_url_if_there_is_a_summary_image() { $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files'); $cache = course_image::get_instance_for_cache(new cache_definition()); - $method->setAccessible(true); // Create course without one image. $draftid1 = $this->fill_draft_area(['filename1.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg')]); @@ -140,7 +137,6 @@ public function test_get_image_url_from_overview_files_returns_url_if_there_is_a public function test_get_image_url_from_overview_files_returns_url_of_the_first_image_if_there_are_many_summary_images() { $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files'); $cache = course_image::get_instance_for_cache(new cache_definition()); - $method->setAccessible(true); // Create course with two image files. $draftid1 = $this->fill_draft_area([ @@ -159,7 +155,6 @@ public function test_get_image_url_from_overview_files_returns_url_of_the_first_ public function test_get_image_url_from_overview_files_returns_url_of_the_first_image_if_there_are_many_summary_files() { $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files'); $cache = course_image::get_instance_for_cache(new cache_definition()); - $method->setAccessible(true); // Create course with two image files and one zip file. $draftid1 = $this->fill_draft_area([ diff --git a/course/tests/targets_test.php b/course/tests/targets_test.php index 9e2e72b9823c..6dc0ad89a5dd 100644 --- a/course/tests/targets_test.php +++ b/course/tests/targets_test.php @@ -413,7 +413,6 @@ public function test_core_target_course_completion_samples($coursestart, $course $class = new \ReflectionClass('\core\analytics\analyser\student_enrolments'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $target->add_sample_data($samplesdata); @@ -448,7 +447,6 @@ public function test_core_target_course_completion_active_during_analysis_time($ $class = new \ReflectionClass('\core\analytics\analyser\student_enrolments'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $target->add_sample_data($samplesdata); @@ -456,7 +454,6 @@ public function test_core_target_course_completion_active_during_analysis_time($ $reftarget = new \ReflectionObject($target); $refmethod = $reftarget->getMethod('calculate_sample'); - $refmethod->setAccessible(true); if ($nullcalculation) { $this->assertNull($refmethod->invoke($target, $sampleid, $analysable, $starttime, $endtime)); @@ -532,7 +529,6 @@ public function test_core_target_course_competencies_calculate() { $class = new \ReflectionClass('\core\analytics\analyser\student_enrolments'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $target->add_sample_data($samplesdata); @@ -540,7 +536,6 @@ public function test_core_target_course_competencies_calculate() { $class = new \ReflectionClass('\core_course\analytics\target\course_competencies'); $method = $class->getMethod('calculate_sample'); - $method->setAccessible(true); // Method calculate_sample() returns 1 when the user has not achieved all the competencies assigned to the course. $this->assertEquals(1, $method->invoke($target, $sampleid, $analysable)); @@ -630,14 +625,12 @@ public function test_core_target_course_gradetopass_calculate() { $class = new \ReflectionClass('\core\analytics\analyser\student_enrolments'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $target->add_sample_data($samplesdata); $class = new \ReflectionClass('\core_course\analytics\target\course_gradetopass'); $method = $class->getMethod('calculate_sample'); - $method->setAccessible(true); // Verify all the expectations are fulfilled. foreach ($sampleids as $sampleid => $key) { diff --git a/customfield/tests/generator/lib.php b/customfield/tests/generator/lib.php index eae8490154f0..6da6bf30f828 100644 --- a/customfield/tests/generator/lib.php +++ b/customfield/tests/generator/lib.php @@ -156,7 +156,6 @@ public function add_instance_data(field_controller $field, int $instanceid, $val $rc = new ReflectionClass(get_class($data)); $rcm = $rc->getMethod('get_form_element_name'); - $rcm->setAccessible(true); $formelementname = $rcm->invokeArgs($data, []); $record = (object)[$formelementname => $value]; $data->instance_form_save($record); diff --git a/enrol/ldap/tests/ldap_test.php b/enrol/ldap/tests/ldap_test.php index c918b19f0293..7f93d763593f 100644 --- a/enrol/ldap/tests/ldap_test.php +++ b/enrol/ldap/tests/ldap_test.php @@ -513,7 +513,6 @@ public function test_objectclass_fetch($usertype, $expected) { // Use reflection to sneak a look at the plugin. $rc = new \ReflectionClass('enrol_ldap_plugin'); $rcp = $rc->getProperty('userobjectclass'); - $rcp->setAccessible(true); // Fetch the current userobjectclass value. $value = $rcp->getValue($instance); diff --git a/enrol/lti/tests/helper_test.php b/enrol/lti/tests/helper_test.php index 90fc6c09e14f..a3553183415c 100644 --- a/enrol/lti/tests/helper_test.php +++ b/enrol/lti/tests/helper_test.php @@ -477,7 +477,6 @@ public function set_xpath_provider() { public function test_set_xpath($parameters, $expected) { $helper = new \ReflectionClass('enrol_lti\\helper'); $function = $helper->getMethod('set_xpath'); - $function->setAccessible(true); $document = new \DOMDocument(); $document->load(realpath(__DIR__ . '/fixtures/input.xml')); @@ -502,7 +501,6 @@ public function test_set_xpath_incorrect_xpath() { ]; $helper = new \ReflectionClass('enrol_lti\\helper'); $function = $helper->getMethod('set_xpath'); - $function->setAccessible(true); $document = new \DOMDocument(); $document->load(realpath(__DIR__ . '/fixtures/input.xml')); diff --git a/files/tests/converter_test.php b/files/tests/converter_test.php index d54d4b171aeb..ae766c8856cd 100644 --- a/files/tests/converter_test.php +++ b/files/tests/converter_test.php @@ -223,7 +223,6 @@ public function test_get_document_converter_classes_no_plugins() { $converter->method('get_enabled_plugins')->willReturn([]); $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes'); - $method->setAccessible(true); $result = $method->invokeArgs($converter, ['docx', 'pdf']); $this->assertEmpty($result); } @@ -238,7 +237,6 @@ public function test_get_document_converter_classes_plugin_class_not_found() { ]); $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes'); - $method->setAccessible(true); $result = $method->invokeArgs($converter, ['docx', 'pdf']); $this->assertEmpty($result); } @@ -257,7 +255,6 @@ public function test_get_document_converter_classes_plugin_class_requirements_no ]); $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes'); - $method->setAccessible(true); $result = $method->invokeArgs($converter, ['docx', 'pdf']); $this->assertEmpty($result); } @@ -276,7 +273,6 @@ public function test_get_document_converter_classes_plugin_class_met_not_support ]); $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes'); - $method->setAccessible(true); $result = $method->invokeArgs($converter, ['docx', 'pdf']); $this->assertEmpty($result); } @@ -296,7 +292,6 @@ public function test_get_document_converter_classes_plugin_class_met_and_support ]); $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes'); - $method->setAccessible(true); $result = $method->invokeArgs($converter, ['docx', 'pdf']); $this->assertCount(1, $result); $this->assertNotFalse(array_search($classname, $result)); @@ -681,7 +676,6 @@ public function test_start_conversion_two_supported() { */ public function test_get_next_converter_no_converters() { $rcm = new \ReflectionMethod(converter::class, 'get_next_converter'); - $rcm->setAccessible(true); $converter = new \core_files\converter(); $result = $rcm->invoke($converter, [], null); @@ -694,7 +688,6 @@ public function test_get_next_converter_no_converters() { */ public function test_get_next_converter_only_converters() { $rcm = new \ReflectionMethod(converter::class, 'get_next_converter'); - $rcm->setAccessible(true); $converter = new converter(); $result = $rcm->invoke($converter, ['example'], 'example'); @@ -707,7 +700,6 @@ public function test_get_next_converter_only_converters() { */ public function test_get_next_converter_last_converters() { $rcm = new \ReflectionMethod(converter::class, 'get_next_converter'); - $rcm->setAccessible(true); $converter = new converter(); $result = $rcm->invoke($converter, ['foo', 'example'], 'example'); @@ -720,7 +712,6 @@ public function test_get_next_converter_last_converters() { */ public function test_get_next_converter_middle_converters() { $rcm = new \ReflectionMethod(converter::class, 'get_next_converter'); - $rcm->setAccessible(true); $converter = new converter(); $result = $rcm->invoke($converter, ['foo', 'bar', 'baz', 'example'], 'bar'); @@ -733,7 +724,6 @@ public function test_get_next_converter_middle_converters() { */ public function test_get_next_converter_first() { $rcm = new \ReflectionMethod(converter::class, 'get_next_converter'); - $rcm->setAccessible(true); $converter = new converter(); $result = $rcm->invoke($converter, ['foo', 'bar', 'baz', 'example']); diff --git a/grade/report/user/tests/lib_test.php b/grade/report/user/tests/lib_test.php index c27caa4c02f7..59bb6dc5fe6c 100644 --- a/grade/report/user/tests/lib_test.php +++ b/grade/report/user/tests/lib_test.php @@ -69,7 +69,6 @@ public function test_gradereport_user_myprofile_navigation() { gradereport_user_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('grade', $nodes->getValue($this->tree)); } @@ -84,7 +83,6 @@ public function test_gradereport_user_myprofile_navigation_without_permission() gradereport_user_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('grade', $nodes->getValue($this->tree)); } } diff --git a/h5p/tests/editor_test.php b/h5p/tests/editor_test.php index 74fe952b91f8..d2f1fc763813 100644 --- a/h5p/tests/editor_test.php +++ b/h5p/tests/editor_test.php @@ -113,7 +113,6 @@ public function test_set_content() { // Call the method. We need the id of the new H5P content. $rc = new \ReflectionClass(player::class); $rcp = $rc->getProperty('h5pid'); - $rcp->setAccessible(true); $h5pid = $rcp->getValue($h5pplayer); $editor = new editor(); @@ -122,7 +121,6 @@ public function test_set_content() { // Check we get the H5P content. $rc = new \ReflectionClass(editor::class); $rcp = $rc->getProperty('oldcontent'); - $rcp->setAccessible(true); $oldcontent = $rcp->getValue($editor); $core = (new factory)->get_core(); @@ -130,7 +128,6 @@ public function test_set_content() { // Check we get the file of the H5P content. $rcp = $rc->getProperty('oldfile'); - $rcp->setAccessible(true); $oldfile = $rcp->getValue($editor); $this->assertSame($file->get_contenthash(), $oldfile->get_contenthash()); @@ -154,7 +151,6 @@ public function test_set_library() { // Check that the library has the right value. $rc = new \ReflectionClass(editor::class); $rcp = $rc->getProperty('library'); - $rcp->setAccessible(true); $actual = $rcp->getValue($editor); $this->assertSame($library, $actual); @@ -171,7 +167,6 @@ public function test_set_library() { ]; $rcp = $rc->getProperty('filearea'); - $rcp->setAccessible(true); $actual = $rcp->getValue($editor); $this->assertEquals($expected, $actual); @@ -198,8 +193,6 @@ public function test_add_editor_to_form() { $rc = new \ReflectionClass(page_requirements_manager::class); $rcp = $rc->getProperty('cssurls'); $rcp2 = $rc->getProperty('jsincludes'); - $rcp->setAccessible(true); - $rcp2->setAccessible(true); $actualcss = array_keys($rcp->getValue($PAGE->requires)); $actualjs = array_keys($rcp2->getValue($PAGE->requires)['head']); $cachebuster = helper::get_cache_buster(); diff --git a/h5p/tests/file_storage_test.php b/h5p/tests/file_storage_test.php index cbf0ee5a13eb..a1f9b5c290a5 100644 --- a/h5p/tests/file_storage_test.php +++ b/h5p/tests/file_storage_test.php @@ -69,11 +69,9 @@ protected function setUp(): void { // Get value of protected properties. $h5p_fs_rc = new \ReflectionClass(file_storage::class); $h5p_file_storage_context = $h5p_fs_rc->getProperty('context'); - $h5p_file_storage_context->setAccessible(true); $this->h5p_fs_context = $h5p_file_storage_context->getValue($this->h5p_file_storage); $h5p_file_storage_fs = $h5p_fs_rc->getProperty('fs'); - $h5p_file_storage_fs->setAccessible(true); $this->h5p_fs_fs = $h5p_file_storage_fs->getValue($this->h5p_file_storage); } @@ -625,7 +623,6 @@ public function test_get_file(): void { // Set get_file method accessibility. $method = new ReflectionMethod(file_storage::class, 'get_file'); - $method->setAccessible(true); $contentfile = $method->invoke(new file_storage(), file_storage::CONTENT_FILEAREA, $h5pcontentid, $file); @@ -668,7 +665,6 @@ public function test_move_file(): void { // Set get_file method accessibility. $method = new ReflectionMethod(file_storage::class, 'move_file'); - $method->setAccessible(true); $method->invoke(new file_storage(), $file, $h5pcontentid); diff --git a/h5p/tests/generator/lib.php b/h5p/tests/generator/lib.php index 3bfefc0df85f..79edfec2e12e 100644 --- a/h5p/tests/generator/lib.php +++ b/h5p/tests/generator/lib.php @@ -554,7 +554,6 @@ public function create_export_file(string $filename, int $contextid, // Call the method. We need the id of the new H5P content. $rc = new \ReflectionClass(player::class); $rcp = $rc->getProperty('h5pid'); - $rcp->setAccessible(true); $h5pid = $rcp->getValue($h5pplayer); // Get the info export file. diff --git a/lang/en/admin.php b/lang/en/admin.php index 9f7ea6d93f49..624f5604f053 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -1314,6 +1314,7 @@ $string['sixtyfourbitswarning'] = 'It has been detected that your site is not using a 64-bit PHP version. It is recommended that you upgrade your site to ensure future compatibility.'; $string['slasharguments'] = 'Use slash arguments'; $string['slashargumentswarning'] = 'It is recommended that the use of slash arguments is enabled. In future it will be required. For more details, see the documentation Using slash arguments.'; +$string['smallscreensonly'] = 'Small screens only'; $string['smtp'] = 'SMTP'; $string['smtpauthtype'] = 'SMTP Auth Type'; $string['smtpdetail'] = 'Simple Mail Transfer Protocol (SMTP) settings for sending email.'; diff --git a/lang/en/auth.php b/lang/en/auth.php index c73816c063c1..2a42ae444a10 100644 --- a/lang/en/auth.php +++ b/lang/en/auth.php @@ -41,6 +41,8 @@ $string['auth_changingemailaddress'] = 'You have requested a change of email address, from {$a->oldemail} to {$a->newemail}. For security reasons, we are sending you an email message at the new address to confirm that it belongs to you. Your email address will be updated as soon as you open the URL sent to you in that message.'; $string['authinstructions'] = 'Leave this blank for the default login instructions to be displayed on the login page. If you want to provide custom login instructions, enter them here.'; $string['auth_invalidnewemailkey'] = 'Error: if you are trying to confirm a change of email address, you may have made a mistake in copying the URL we sent you by email. Please copy the address and try again.'; +$string['auth_loginpasswordtoggle'] = 'Password visibility toggle'; +$string['auth_loginpasswordtoggle_desc'] = 'Add an icon to the password field on the login screen that allows users to show or hide their entered password.'; $string['auth_loginrecaptcha'] = 'Enable reCAPTCHA for login'; $string['auth_loginrecaptcha_desc'] = 'Add a visual/audio confirmation form element to the login page. This reduces the risk of unwarranted login attempts. See Google reCAPTCHA for more details. '; $string['auth_multiplehosts'] = 'Multiple hosts OR addresses can be specified (eg host1.com;host2.com;host3.com) or (eg xxx.xxx.xxx.xxx;xxx.xxx.xxx.xxx)'; diff --git a/lang/en/courseformat.php b/lang/en/courseformat.php index c6d44e39964d..b6135aaeb065 100644 --- a/lang/en/courseformat.php +++ b/lang/en/courseformat.php @@ -47,6 +47,7 @@ $string['cm_show_feedback'] = '{$a->name} is now shown.'; $string['cm_show_feedback_batch'] = 'The selected {$a->count} activities are now shown.'; $string['cm_stealth_feedback'] = '{$a->name} is now available but not shown on the course page.'; +$string['cm_stealth_feedback_batch'] = 'The selected {$a->count} activities are now available but not shown on the course page.'; $string['cm_visiblegroups_feedback'] = '{$a->name} group mode changed to Visible groups.'; $string['cmavailability'] = 'Activity availability'; $string['cmdelete_info'] = 'This will delete {$a->name} and any user data it contains.'; diff --git a/lang/en/form.php b/lang/en/form.php index 440997cb63ee..0ddade386d02 100644 --- a/lang/en/form.php +++ b/lang/en/form.php @@ -87,5 +87,6 @@ $string['time'] = 'Time'; $string['timeunit'] = 'Time unit'; $string['timing'] = 'Timing'; +$string['togglesensitive'] = 'Toggle sensitive'; $string['unmaskpassword'] = 'Unmask'; $string['year'] = 'Year'; diff --git a/lib/amd/build/togglesensitive.min.js b/lib/amd/build/togglesensitive.min.js new file mode 100644 index 000000000000..7a14a4543d42 --- /dev/null +++ b/lib/amd/build/togglesensitive.min.js @@ -0,0 +1,10 @@ +define("core/togglesensitive",["exports","core/pagehelpers","core/templates","core/pending","core/prefetch","core/notification","core_form/events"],(function(_exports,_pagehelpers,_templates,_pending,_prefetch,_notification,_events){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +/** + * JS module for toggling the sensitive input visibility (e.g. passwords, keys). + * + * @module core/togglesensitive + * @copyright 2023 David Woloszyn + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_pending=_interopRequireDefault(_pending),_prefetch=_interopRequireDefault(_prefetch),_notification=_interopRequireDefault(_notification);const SELECTORS_BUTTON=".toggle-sensitive-btn",PIX_EYE="t/hide",PIX_EYE_SLASH="t/show";let sensitiveElementId,smallScreensOnly;_exports.init=function(elementId){let isSmallScreensOnly=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const sensitiveInput=document.getElementById(elementId);null!==sensitiveInput&&(sensitiveElementId=elementId,smallScreensOnly=isSmallScreensOnly,_prefetch.default.prefetchTemplate("core/form_input_toggle_sensitive"),renderSensitiveToggle(sensitiveInput),registerListenerEvents())};const renderSensitiveToggle=sensitiveInput=>{_templates.default.render("core/form_input_toggle_sensitive",{smallscreensonly:smallScreensOnly,sensitiveinput:sensitiveInput.outerHTML}).then((html=>{sensitiveInput.outerHTML=html,(0,_events.notifyFieldStructureChanged)(sensitiveInput.id)})).catch(_notification.default.exception)},registerListenerEvents=()=>{document.addEventListener("click",handleButtonInteraction),smallScreensOnly&&window.addEventListener("resize",handleScreenResizing)},handleButtonInteraction=event=>{const toggleButton=event.target.closest(SELECTORS_BUTTON);if(toggleButton){const sensitiveInput=document.getElementById(sensitiveElementId);sensitiveInput&&toggleSensitiveVisibility(sensitiveInput,toggleButton)}},handleScreenResizing=()=>{if(!(0,_pagehelpers.isExtraSmall)()){const sensitiveInput=document.getElementById(sensitiveElementId);if(sensitiveInput){const toggleButton=sensitiveInput.parentNode.querySelector(SELECTORS_BUTTON);toggleButton&&toggleSensitiveVisibility(sensitiveInput,toggleButton,!0)}}},toggleSensitiveVisibility=function(sensitiveInput,toggleButton){let force=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const pendingPromise=new _pending.default("core/togglesensitive:toggle");let type,icon;!0===force?(type="password",icon=PIX_EYE):(type="password"===sensitiveInput.getAttribute("type")?"text":"password",icon="password"===sensitiveInput.getAttribute("type")?PIX_EYE_SLASH:PIX_EYE),sensitiveInput.setAttribute("type",type),_templates.default.renderPix(icon,"core").then((icon=>{toggleButton.innerHTML=icon,pendingPromise.resolve()})).catch(_notification.default.exception)}})); + +//# sourceMappingURL=togglesensitive.min.js.map \ No newline at end of file diff --git a/lib/amd/build/togglesensitive.min.js.map b/lib/amd/build/togglesensitive.min.js.map new file mode 100644 index 000000000000..dfedebd5e21c --- /dev/null +++ b/lib/amd/build/togglesensitive.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"togglesensitive.min.js","sources":["../src/togglesensitive.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JS module for toggling the sensitive input visibility (e.g. passwords, keys).\n *\n * @module core/togglesensitive\n * @copyright 2023 David Woloszyn \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {isExtraSmall} from 'core/pagehelpers';\nimport Templates from 'core/templates';\nimport Pending from 'core/pending';\nimport Prefetch from 'core/prefetch';\nimport Notification from 'core/notification';\nimport {notifyFieldStructureChanged} from 'core_form/events';\n\nconst SELECTORS = {\n BUTTON: '.toggle-sensitive-btn',\n ICON: '.toggle-sensitive-btn .icon',\n};\n\nconst PIX = {\n EYE: 't/hide',\n EYE_SLASH: 't/show',\n};\n\nlet sensitiveElementId;\nlet smallScreensOnly;\n\n/**\n * Entrypoint of the js.\n *\n * @method init\n * @param {String} elementId Form button element.\n * @param {boolean} isSmallScreensOnly Is this for small screens only?\n */\nexport const init = (elementId, isSmallScreensOnly = false) => {\n const sensitiveInput = document.getElementById(elementId);\n if (sensitiveInput === null) {\n // Exit early if invalid element id passed.\n return;\n }\n sensitiveElementId = elementId;\n smallScreensOnly = isSmallScreensOnly;\n Prefetch.prefetchTemplate('core/form_input_toggle_sensitive');\n // Render the sensitive input with a toggle button.\n renderSensitiveToggle(sensitiveInput);\n // Register event listeners.\n registerListenerEvents();\n};\n\n/**\n * Render the new input html with toggle button and update the incoming html.\n *\n * @method renderSensitiveToggle\n * @param {HTMLElement} sensitiveInput HTML element for the sensitive input.\n */\nconst renderSensitiveToggle = (sensitiveInput) => {\n Templates.render(\n 'core/form_input_toggle_sensitive',\n {\n smallscreensonly: smallScreensOnly,\n sensitiveinput: sensitiveInput.outerHTML,\n }\n ).then((html) => {\n sensitiveInput.outerHTML = html;\n // Dispatch the event indicating the sensitive input has changed.\n notifyFieldStructureChanged(sensitiveInput.id);\n return;\n }).catch(Notification.exception);\n};\n\n/**\n * Register event listeners.\n *\n * @method registerListenerEvents\n */\nconst registerListenerEvents = () => {\n // Toggle the sensitive input visibility when interacting with the toggle button.\n document.addEventListener('click', handleButtonInteraction);\n // For small screens only, hide all sensitive inputs when the screen is enlarged.\n if (smallScreensOnly) {\n window.addEventListener('resize', handleScreenResizing);\n }\n};\n\n/**\n * Handle events trigger by interacting with the toggle button.\n *\n * @method handleButtonInteraction\n * @param {Event} event The button event.\n */\nconst handleButtonInteraction = (event) => {\n const toggleButton = event.target.closest(SELECTORS.BUTTON);\n if (toggleButton) {\n const sensitiveInput = document.getElementById(sensitiveElementId);\n if (sensitiveInput) {\n toggleSensitiveVisibility(sensitiveInput, toggleButton);\n }\n }\n};\n\n/**\n * Handle events trigger by resizing the screen.\n *\n * @method handleScreenResizing\n */\nconst handleScreenResizing = () => {\n if (!isExtraSmall()) {\n const sensitiveInput = document.getElementById(sensitiveElementId);\n if (sensitiveInput) {\n const toggleButton = sensitiveInput.parentNode.querySelector(SELECTORS.BUTTON);\n if (toggleButton) {\n toggleSensitiveVisibility(sensitiveInput, toggleButton, true);\n }\n }\n }\n};\n\n/**\n * Toggle the sensitive input visibility and its associated icon.\n *\n * @method toggleSensitiveVisibility\n * @param {HTMLInputElement} sensitiveInput The sensitive input element.\n * @param {HTMLElement} toggleButton The toggle button.\n * @param {boolean} force Force the input back to password type.\n */\nconst toggleSensitiveVisibility = (sensitiveInput, toggleButton, force = false) => {\n const pendingPromise = new Pending('core/togglesensitive:toggle');\n let type;\n let icon;\n if (force === true) {\n type = 'password';\n icon = PIX.EYE;\n } else {\n type = sensitiveInput.getAttribute('type') === 'password' ? 'text' : 'password';\n icon = sensitiveInput.getAttribute('type') === 'password' ? PIX.EYE_SLASH : PIX.EYE;\n }\n sensitiveInput.setAttribute('type', type);\n Templates.renderPix(icon, 'core').then((icon) => {\n toggleButton.innerHTML = icon;\n pendingPromise.resolve();\n return;\n }).catch(Notification.exception);\n};\n"],"names":["SELECTORS","PIX","sensitiveElementId","smallScreensOnly","elementId","isSmallScreensOnly","sensitiveInput","document","getElementById","prefetchTemplate","renderSensitiveToggle","registerListenerEvents","render","smallscreensonly","sensitiveinput","outerHTML","then","html","id","catch","Notification","exception","addEventListener","handleButtonInteraction","window","handleScreenResizing","event","toggleButton","target","closest","toggleSensitiveVisibility","parentNode","querySelector","force","pendingPromise","Pending","type","icon","getAttribute","setAttribute","renderPix","innerHTML","resolve"],"mappings":";;;;;;;gRA8BMA,iBACM,wBAINC,QACG,SADHA,cAES,aAGXC,mBACAC,+BASgB,SAACC,eAAWC,iFACtBC,eAAiBC,SAASC,eAAeJ,WACxB,OAAnBE,iBAIJJ,mBAAqBE,UACrBD,iBAAmBE,qCACVI,iBAAiB,oCAE1BC,sBAAsBJ,gBAEtBK,iCASED,sBAAyBJ,oCACjBM,OACN,mCACA,CACIC,iBAAkBV,iBAClBW,eAAgBR,eAAeS,YAErCC,MAAMC,OACJX,eAAeS,UAAYE,6CAECX,eAAeY,OAE5CC,MAAMC,sBAAaC,YAQpBV,uBAAyB,KAE3BJ,SAASe,iBAAiB,QAASC,yBAE/BpB,kBACAqB,OAAOF,iBAAiB,SAAUG,uBAUpCF,wBAA2BG,cACvBC,aAAeD,MAAME,OAAOC,QAAQ7B,qBACtC2B,aAAc,OACRrB,eAAiBC,SAASC,eAAeN,oBAC3CI,gBACAwB,0BAA0BxB,eAAgBqB,gBAUhDF,qBAAuB,UACpB,+BAAgB,OACXnB,eAAiBC,SAASC,eAAeN,uBAC3CI,eAAgB,OACVqB,aAAerB,eAAeyB,WAAWC,cAAchC,kBACzD2B,cACAG,0BAA0BxB,eAAgBqB,cAAc,MAclEG,0BAA4B,SAACxB,eAAgBqB,kBAAcM,oEACvDC,eAAiB,IAAIC,iBAAQ,mCAC/BC,KACAC,MACU,IAAVJ,OACAG,KAAO,WACPC,KAAOpC,UAEPmC,KAA+C,aAAxC9B,eAAegC,aAAa,QAAyB,OAAS,WACrED,KAA+C,aAAxC/B,eAAegC,aAAa,QAAyBrC,cAAgBA,SAEhFK,eAAeiC,aAAa,OAAQH,yBAC1BI,UAAUH,KAAM,QAAQrB,MAAMqB,OACpCV,aAAac,UAAYJ,KACzBH,eAAeQ,aAEhBvB,MAAMC,sBAAaC"} \ No newline at end of file diff --git a/lib/amd/src/togglesensitive.js b/lib/amd/src/togglesensitive.js new file mode 100644 index 000000000000..19d2bf03783e --- /dev/null +++ b/lib/amd/src/togglesensitive.js @@ -0,0 +1,159 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * JS module for toggling the sensitive input visibility (e.g. passwords, keys). + * + * @module core/togglesensitive + * @copyright 2023 David Woloszyn + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +import {isExtraSmall} from 'core/pagehelpers'; +import Templates from 'core/templates'; +import Pending from 'core/pending'; +import Prefetch from 'core/prefetch'; +import Notification from 'core/notification'; +import {notifyFieldStructureChanged} from 'core_form/events'; + +const SELECTORS = { + BUTTON: '.toggle-sensitive-btn', + ICON: '.toggle-sensitive-btn .icon', +}; + +const PIX = { + EYE: 't/hide', + EYE_SLASH: 't/show', +}; + +let sensitiveElementId; +let smallScreensOnly; + +/** + * Entrypoint of the js. + * + * @method init + * @param {String} elementId Form button element. + * @param {boolean} isSmallScreensOnly Is this for small screens only? + */ +export const init = (elementId, isSmallScreensOnly = false) => { + const sensitiveInput = document.getElementById(elementId); + if (sensitiveInput === null) { + // Exit early if invalid element id passed. + return; + } + sensitiveElementId = elementId; + smallScreensOnly = isSmallScreensOnly; + Prefetch.prefetchTemplate('core/form_input_toggle_sensitive'); + // Render the sensitive input with a toggle button. + renderSensitiveToggle(sensitiveInput); + // Register event listeners. + registerListenerEvents(); +}; + +/** + * Render the new input html with toggle button and update the incoming html. + * + * @method renderSensitiveToggle + * @param {HTMLElement} sensitiveInput HTML element for the sensitive input. + */ +const renderSensitiveToggle = (sensitiveInput) => { + Templates.render( + 'core/form_input_toggle_sensitive', + { + smallscreensonly: smallScreensOnly, + sensitiveinput: sensitiveInput.outerHTML, + } + ).then((html) => { + sensitiveInput.outerHTML = html; + // Dispatch the event indicating the sensitive input has changed. + notifyFieldStructureChanged(sensitiveInput.id); + return; + }).catch(Notification.exception); +}; + +/** + * Register event listeners. + * + * @method registerListenerEvents + */ +const registerListenerEvents = () => { + // Toggle the sensitive input visibility when interacting with the toggle button. + document.addEventListener('click', handleButtonInteraction); + // For small screens only, hide all sensitive inputs when the screen is enlarged. + if (smallScreensOnly) { + window.addEventListener('resize', handleScreenResizing); + } +}; + +/** + * Handle events trigger by interacting with the toggle button. + * + * @method handleButtonInteraction + * @param {Event} event The button event. + */ +const handleButtonInteraction = (event) => { + const toggleButton = event.target.closest(SELECTORS.BUTTON); + if (toggleButton) { + const sensitiveInput = document.getElementById(sensitiveElementId); + if (sensitiveInput) { + toggleSensitiveVisibility(sensitiveInput, toggleButton); + } + } +}; + +/** + * Handle events trigger by resizing the screen. + * + * @method handleScreenResizing + */ +const handleScreenResizing = () => { + if (!isExtraSmall()) { + const sensitiveInput = document.getElementById(sensitiveElementId); + if (sensitiveInput) { + const toggleButton = sensitiveInput.parentNode.querySelector(SELECTORS.BUTTON); + if (toggleButton) { + toggleSensitiveVisibility(sensitiveInput, toggleButton, true); + } + } + } +}; + +/** + * Toggle the sensitive input visibility and its associated icon. + * + * @method toggleSensitiveVisibility + * @param {HTMLInputElement} sensitiveInput The sensitive input element. + * @param {HTMLElement} toggleButton The toggle button. + * @param {boolean} force Force the input back to password type. + */ +const toggleSensitiveVisibility = (sensitiveInput, toggleButton, force = false) => { + const pendingPromise = new Pending('core/togglesensitive:toggle'); + let type; + let icon; + if (force === true) { + type = 'password'; + icon = PIX.EYE; + } else { + type = sensitiveInput.getAttribute('type') === 'password' ? 'text' : 'password'; + icon = sensitiveInput.getAttribute('type') === 'password' ? PIX.EYE_SLASH : PIX.EYE; + } + sensitiveInput.setAttribute('type', type); + Templates.renderPix(icon, 'core').then((icon) => { + toggleButton.innerHTML = icon; + pendingPromise.resolve(); + return; + }).catch(Notification.exception); +}; diff --git a/lib/behat/classes/named_selector.php b/lib/behat/classes/named_selector.php index e683ffcf2913..b390b7590942 100644 --- a/lib/behat/classes/named_selector.php +++ b/lib/behat/classes/named_selector.php @@ -58,7 +58,6 @@ public function register_component_selector(string $component, behat_component_n // This is due to an API limitation in Mink. $rc = new \ReflectionClass(\Behat\Mink\Selector\NamedSelector::class); $r = $rc->getProperty('replacements'); - $r->setAccessible(true); $replacements = $r->getValue($this); $selectorxpath = strtr($selector->get_combined_xpath(), $replacements); @@ -77,7 +76,6 @@ public function register_replacement(string $component, behat_component_named_re // This is due to an API limitation in Mink. $rc = new \ReflectionClass(\Behat\Mink\Selector\NamedSelector::class); $r = $rc->getProperty('replacements'); - $r->setAccessible(true); $existing = $r->getValue($this); $from = $replacement->get_from($component); diff --git a/lib/classes/deprecated.php b/lib/classes/attribute/deprecated.php similarity index 79% rename from lib/classes/deprecated.php rename to lib/classes/attribute/deprecated.php index deb278abe94b..c68317bdf397 100644 --- a/lib/classes/deprecated.php +++ b/lib/classes/attribute/deprecated.php @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -namespace core; - -use Attribute; +namespace core\attribute; /** * Attribute to describe a deprecated item. @@ -25,7 +23,7 @@ * @copyright 2023 Andrew Lyons * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -#[Attribute] +#[\Attribute] class deprecated { /** * A deprecated item. @@ -34,20 +32,25 @@ class deprecated { * * Note: The mere presence of the attribute does not do anything. It must be checked by some part of the code. * - * @param mixed $descriptor A brief descriptor of the thing that was deprecated. + * @param null|string $replacement Any replacement for the deprecated thing * @param null|string $since When it was deprecated * @param null|string $reason Why it was deprecated - * @param null|string $replacement Any replacement for the deprecated thing * @param null|string $mdl Link to the Moodle Tracker issue for more information + * @param bool $final Whether this is a final deprecation + * @param bool $emit Whether to emit a deprecation warning */ public function __construct( - public readonly mixed $descriptor, + public readonly ?string $replacement, public readonly ?string $since = null, public readonly ?string $reason = null, - public readonly ?string $replacement = null, public readonly ?string $mdl = null, public readonly bool $final = false, public readonly bool $emit = true, ) { + if ($replacement === null && $reason === null && $mdl === null) { + throw new \coding_exception( + 'A deprecated item which is not deprecated must provide a reason, or an issue number.', + ); + } } } diff --git a/lib/classes/attribute/deprecated_with_reference.php b/lib/classes/attribute/deprecated_with_reference.php new file mode 100644 index 000000000000..751cd8f111ec --- /dev/null +++ b/lib/classes/attribute/deprecated_with_reference.php @@ -0,0 +1,58 @@ +. + +namespace core\attribute; + +/** + * Attribute to describe a deprecated item which contains a reference to the owning feature. + * + * @package core + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class deprecated_with_reference extends deprecated { + /** + * A deprecated item which also includes a reference to the owning feature. + * + * This attribute is not expected to be used more generally. It is an internal feature. + * + * @param string $owner The code which owns the usage + * @param null|string $replacement Any replacement for the deprecated thing + * @param null|string $since When it was deprecated + * @param null|string $reason Why it was deprecated + * @param null|string $mdl Link to the Moodle Tracker issue for more information + * @param bool $final Whether this is a final deprecation + * @param bool $emit Whether to emit a deprecation warning + */ + public function __construct( + public readonly string $owner, + ?string $replacement, + ?string $since, + ?string $reason, + ?string $mdl, + bool $final, + bool $emit, + ) { + parent::__construct( + replacement: $replacement, + since: $since, + reason: $reason, + mdl: $mdl, + final: $final, + emit: $emit, + ); + } +} diff --git a/lib/classes/deprecation.php b/lib/classes/deprecation.php index b71fd502d9b6..e11b12058ac3 100644 --- a/lib/classes/deprecation.php +++ b/lib/classes/deprecation.php @@ -16,6 +16,9 @@ namespace core; +use core\attribute\deprecated; +use core\attribute\deprecated_with_reference; + /** * Deprecation utility. * @@ -42,17 +45,14 @@ public static function from(array|string|object $reference): ?deprecated { return self::from(explode('::', $reference)); } - if (class_exists($reference)) { + if (class_exists($reference) || interface_exists($reference) || trait_exists($reference)) { // The reference looks to be a class name. return self::from([$reference]); } if (function_exists($reference)) { // The reference looks to be a global function. - $ref = new \ReflectionFunction($reference); - if ($attributes = $ref->getAttributes(deprecated::class)) { - return $attributes[0]->newInstance(); - } + return self::get_attribute(new \ReflectionFunction($reference), $reference); } return null; @@ -75,14 +75,45 @@ public static function from(array|string|object $reference): ?deprecated { return self::from_reflected_object($rc, $reference[1] ?? null); } - if (is_string($reference[0]) && class_exists($reference[0])) { - $rc = new \ReflectionClass($reference[0]); - return self::from_reflected_object($rc, $reference[1] ?? null); + if (is_string($reference[0])) { + if (class_exists($reference[0]) || interface_exists($reference[0]) || trait_exists($reference[0])) { + $rc = new \ReflectionClass($reference[0]); + return self::from_reflected_object($rc, $reference[1] ?? null); + } } // The reference is an array, but it's not an object or a class that currently exists. return null; } + + // The reference is none of the above. + return null; + } + + /** + * Get a deprecation attribute from a reflector. + * + * @param \Reflector $ref The reflector + * @param string $owner A descriptor of the owner of the thing that is deprecated + * @return null|deprecated_with_reference + */ + protected static function get_attribute( + \Reflector $ref, + string $owner, + ): ?deprecated_with_reference { + if ($attributes = $ref->getAttributes(deprecated::class)) { + $attribute = $attributes[0]->newInstance(); + return new deprecated_with_reference( + owner: $owner, + replacement: $attribute->replacement, + since: $attribute->since, + reason: $attribute->reason, + mdl: $attribute->mdl, + final: $attribute->final, + emit: $attribute->emit, + ); + } + return null; } /** @@ -107,47 +138,59 @@ public static function emit_deprecation_if_present(array|string|object $referenc } /** - * Fetch a deprecation attribute from a reflected object. + * Fetch a referenced deprecation attribute from a reflected object. * * @param \ReflectionClass $rc The reflected object * @param null|string $name The name of the thing to check for deprecation - * @return null|deprecated + * @return null|deprecated_with_reference */ protected static function from_reflected_object( \ReflectionClass $rc, ?string $name, - ): ?deprecated { - if ($name === null) { - // No name specified. This may be a deprecated class. - if ($attributes = $rc->getAttributes(deprecated::class)) { - return $attributes[0]->newInstance(); + ): ?deprecated_with_reference { + // Check if the class itself is deprecated first. + $classattribute = self::get_attribute($rc, $rc->name); + if ($classattribute || $name === null) { + return $classattribute; + } + + // Check for any deprecated interfaces. + foreach ($rc->getInterfaces() as $interface) { + if ($attribute = self::get_attribute($interface, $interface->name)) { + return $attribute; + } + } + + // And any deprecated traits. + foreach ($rc->getTraits() as $trait) { + if ($attribute = self::get_attribute($trait, $trait->name)) { + return $attribute; } - return null; } if ($rc->hasConstant($name)) { // This class has a constant with the specified name. // Note: This also applies to enums. - $ref = $rc->getReflectionConstant($name); - if ($attributes = $ref->getAttributes(deprecated::class)) { - return $attributes[0]->newInstance(); - } + return self::get_attribute( + $rc->getReflectionConstant($name), + "{$rc->name}::{$name}", + ); } if ($rc->hasMethod($name)) { // This class has a method with the specified name. - $ref = $rc->getMethod($name); - if ($attributes = $ref->getAttributes(deprecated::class)) { - return $attributes[0]->newInstance(); - } + return self::get_attribute( + $rc->getMethod($name), + "{$rc->name}::{$name}", + ); } if ($rc->hasProperty($name)) { // This class has a property with the specified name. - $ref = $rc->getProperty($name); - if ($attributes = $ref->getAttributes(deprecated::class)) { - return $attributes[0]->newInstance(); - } + return self::get_attribute( + $rc->getProperty($name), + "{$rc->name}::{$name}", + ); } return null; @@ -157,10 +200,19 @@ protected static function from_reflected_object( * Get a string describing the deprecation. * * @param deprecated $attribute + * @param string $owner * @return string */ - public static function get_deprecation_string(deprecated $attribute): string { - $output = "Deprecation: {$attribute->descriptor} has been deprecated"; + public static function get_deprecation_string( + deprecated $attribute, + ): string { + $output = "Deprecation:"; + + if ($attribute instanceof deprecated_with_reference) { + $output .= " {$attribute->owner}"; + } + $output .= " has been deprecated"; + if ($attribute->since) { $output .= " since {$attribute->since}"; } @@ -187,7 +239,9 @@ public static function get_deprecation_string(deprecated $attribute): string { * * @param deprecated $attribute */ - public static function emit_deprecation_notice(deprecated $attribute): void { + protected static function emit_deprecation_notice( + deprecated $attribute, + ): void { if (!$attribute->emit) { return; } diff --git a/lib/classes/hook/output/standard_head_html_prepend.php b/lib/classes/hook/output/before_standard_head_html_generation.php similarity index 82% rename from lib/classes/hook/output/standard_head_html_prepend.php rename to lib/classes/hook/output/before_standard_head_html_generation.php index 5a4ac7d0c567..4a2e99ac9b40 100644 --- a/lib/classes/hook/output/standard_head_html_prepend.php +++ b/lib/classes/hook/output/before_standard_head_html_generation.php @@ -26,19 +26,25 @@ #[\core\attribute\tags('output')] #[\core\attribute\label('Allows plugins to add any elements to the page <head> html tag.')] #[\core\attribute\hook\replaces_callbacks('before_standard_html_head')] -class standard_head_html_prepend { - /** @var string $output Stores results from callbacks */ - private $output = ''; +final class before_standard_head_html_generation { + public function __construct( + /** @var \renderer_base The core_renderer instance used for the generation */ + public readonly \renderer_base $renderer, + private string $output = '', + ) { + } /** * Plugins implementing callback can add any HTML to the page. * * Must be a string containing valid html head content * - * @param string $output + * @param null|string $output */ - public function add_html(string $output): void { - $this->output .= $output; + public function add_html(?string $output): void { + if ($output) { + $this->output .= $output; + } } /** diff --git a/lib/classes/param.php b/lib/classes/param.php index 359ffc37b293..9c817ff4f5b2 100644 --- a/lib/classes/param.php +++ b/lib/classes/param.php @@ -18,6 +18,7 @@ use coding_exception; use core_text; +use core\attribute\deprecated; use core\ip_utils; use invalid_parameter_exception; use moodle_exception; @@ -222,9 +223,9 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::CLEAN', + replacement: 'a more specific type of parameter', since: '2.0', - reason: 'Please use a more specific type of parameter', + reason: 'The CLEAN param type is too generic to perform satisfactory validation', emit: false, )] case CLEAN = 'clean'; @@ -234,7 +235,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::INTEGER', + replacement: 'param::INT', since: '2.0', reason: 'Alias for INT', final: true, @@ -246,7 +247,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::NUMBER', + replacement: 'param::FLOAT', since: '2.0', reason: 'Alias for FLOAT', final: true, @@ -259,7 +260,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::ACTION', + replacement: 'param::ALPHANUMEXT', since: '2.0', reason: 'Alias for PARAM_ALPHANUMEXT', final: true, @@ -272,7 +273,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::FORMAT', + replacement: 'param::ALPHANUMEXT', since: '2.0', reason: 'Alias for PARAM_ALPHANUMEXT', final: true, @@ -284,7 +285,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::MULTILANG', + replacement: 'param::TEXT', since: '2.0', reason: 'Alias for PARAM_TEXT', final: true, @@ -303,7 +304,7 @@ enum param: string { * @deprecated since 2.0 */ #[deprecated( - 'param::CLEANFILE', + replacement: 'param::FILE', since: '2.0', reason: 'Alias for PARAM_FILE', )] diff --git a/lib/classes/scss.php b/lib/classes/scss.php index 31d73536eb1b..301a7d65cddc 100644 --- a/lib/classes/scss.php +++ b/lib/classes/scss.php @@ -164,7 +164,6 @@ protected function compileChild($child, \ScssPhp\ScssPhp\Formatter\OutputBlock $ // We need to find the import path relative to the directory of the currently processed file. $currentdirectory = new ReflectionProperty(\ScssPhp\ScssPhp\Compiler::class, 'currentDirectory'); - $currentdirectory->setAccessible(true); if ($path = $this->findImport($path, $currentdirectory->getValue($this))) { if ($this->is_valid_file($path)) { diff --git a/lib/db/services.php b/lib/db/services.php index 672509c38b34..1886f7de5976 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1706,13 +1706,6 @@ 'capabilities' => 'moodle/question:flag', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), - 'core_question_submit_tags_form' => array( - 'classname' => 'core_question_external', - 'methodname' => 'submit_tags_form', - 'description' => 'Update the question tags.', - 'type' => 'write', - 'ajax' => true, - ), 'core_question_get_random_question_summaries' => array( 'classname' => 'core_question_external', 'methodname' => 'get_random_question_summaries', diff --git a/lib/ddl/tests/ddl_test.php b/lib/ddl/tests/ddl_test.php index 3dd3d07f22ac..85456aec28ef 100644 --- a/lib/ddl/tests/ddl_test.php +++ b/lib/ddl/tests/ddl_test.php @@ -1885,7 +1885,6 @@ public function test_leftover_temp_tables_cache() { $rc = new \ReflectionClass('moodle_database'); $rcm = $rc->getMethod('get_temp_tables_cache'); - $rcm->setAccessible(true); $metacachetemp = $rcm->invokeArgs($DB, []); // Data of test_table0 should be removed from the cache. @@ -1896,7 +1895,6 @@ public function test_leftover_temp_tables_cache() { $rc = new \ReflectionClass('moodle_database'); $rcm = $rc->getMethod('get_metacache'); - $rcm->setAccessible(true); $metacache = $rcm->invokeArgs($DB, []); // Data of test_table2 should be intact. diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 1f29fd436699..409a16a41878 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -3125,3 +3125,94 @@ function random_bytes_emulate($length) { ); return random_bytes($length); } + +/** + * @deprecated since Moodle 4.0 + */ +function question_preview_url() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 + */ +function question_preview_popup_params() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 + */ +function question_hash() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71573 + */ +function question_make_export_url() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 + */ +function question_get_export_single_question_url() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function question_remove_stale_questions_from_category() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function flatten_category_tree() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function add_indented_names() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function question_category_select_menu() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function get_categories_for_contexts() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function question_category_options() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function question_add_context_in_key() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} + +/** + * @deprecated since Moodle 4.0 MDL-71585 + */ +function question_fix_top_names() { + throw new coding_exception(__FUNCTION__ . '() has been removed.'); +} diff --git a/lib/dml/tests/dml_mysqli_read_slave_test.php b/lib/dml/tests/dml_mysqli_read_slave_test.php index 7c797ebff4f3..681fca72d114 100644 --- a/lib/dml/tests/dml_mysqli_read_slave_test.php +++ b/lib/dml/tests/dml_mysqli_read_slave_test.php @@ -117,7 +117,6 @@ public function test_aux_readonly(): void { $rc = new \ReflectionClass(\mysqli_native_moodle_database::class); $rcm = $rc->getMethod('insert_chunk_size'); - $rcm->setAccessible(true); $rcm->invoke($db2); $this->assertGreaterThan($reads, $reads = $db2->perf_get_reads()); $this->assertGreaterThan($readsprimary, $readsprimary = $reads - $db2->perf_get_reads_slave()); diff --git a/lib/dml/tests/dml_test.php b/lib/dml/tests/dml_test.php index 46fa06f032c9..653f158c3295 100644 --- a/lib/dml/tests/dml_test.php +++ b/lib/dml/tests/dml_test.php @@ -500,7 +500,7 @@ public function test_add_sql_debugging() { $out = $fixture->four($sql); $expected = <<invoke() +-- line 64 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to ReflectionMethod->invoke() EOD; $this->assertEquals($this->unix_to_os_dirsep($expected), $out); @@ -508,8 +508,8 @@ public function test_add_sql_debugging() { $out = $fixture->four($sql); $expected = <<invoke() --- line 74 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->one() +-- line 64 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to ReflectionMethod->invoke() +-- line 73 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->one() EOD; $this->assertEquals($this->unix_to_os_dirsep($expected), $out); @@ -517,10 +517,10 @@ public function test_add_sql_debugging() { $out = $fixture->four($sql); $expected = <<invoke() --- line 74 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->one() --- line 83 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->two() --- line 92 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->three() +-- line 64 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to ReflectionMethod->invoke() +-- line 73 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->one() +-- line 82 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->two() +-- line 91 of /lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php: call to test_dml_sql_debugging_fixture->three() -- line 517 of /lib/dml/tests/dml_test.php: call to test_dml_sql_debugging_fixture->four() EOD; $this->assertEquals($this->unix_to_os_dirsep($expected), $out); @@ -6371,7 +6371,6 @@ public function test_get_server_info_dbfamily_mysql() { $this->assertTrue(empty($cfg->dboptions['versionfromdb'])); $rc = new \ReflectionClass(\mysqli_native_moodle_database::class); $rcm = $rc->getMethod('should_db_version_be_read_from_db'); - $rcm->setAccessible(true); $this->assertFalse($rcm->invokeArgs($DB, [])); ['description' => $description, 'version' => $version] = $DB->get_server_info(); diff --git a/lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php b/lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php index 2aba9dead4c7..c29268c0e093 100644 --- a/lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php +++ b/lib/dml/tests/fixtures/test_dml_sql_debugging_fixture.php @@ -61,7 +61,6 @@ public function get_mock() { */ public function one(string $sql) { $method = new \ReflectionMethod($this->db, 'add_sql_debugging'); - $method->setAccessible(true); return $method->invoke($this->db, $sql); } diff --git a/lib/dml/tests/fixtures/test_moodle_read_slave_trait.php b/lib/dml/tests/fixtures/test_moodle_read_slave_trait.php index 07d21d8ae885..6826c3d93625 100644 --- a/lib/dml/tests/fixtures/test_moodle_read_slave_trait.php +++ b/lib/dml/tests/fixtures/test_moodle_read_slave_trait.php @@ -53,7 +53,6 @@ public function __construct($external = false) { $this->prefix = 'test_'; // Default, not to leave empty. $rcp = new ReflectionProperty(parent::class, 'wantreadslave'); - $rcp->setAccessible(true); $rcp->setValue($this, true); $this->dbhwrite = $rw; diff --git a/lib/dml/tests/mysqli_native_moodle_database_test.php b/lib/dml/tests/mysqli_native_moodle_database_test.php index d40c5646d27e..dd17338224ab 100644 --- a/lib/dml/tests/mysqli_native_moodle_database_test.php +++ b/lib/dml/tests/mysqli_native_moodle_database_test.php @@ -70,7 +70,6 @@ public function new_connection(?bool $compress = false, ?string $ssl = null): my $reflector = new ReflectionClass($db2); $rp = $reflector->getProperty('mysqli'); - $rp->setAccessible(true); return $rp->getValue($db2); } diff --git a/lib/dml/tests/pgsql_native_moodle_database_test.php b/lib/dml/tests/pgsql_native_moodle_database_test.php index 5e3986035b6b..3e0a32e55464 100644 --- a/lib/dml/tests/pgsql_native_moodle_database_test.php +++ b/lib/dml/tests/pgsql_native_moodle_database_test.php @@ -89,7 +89,6 @@ private function get_current_index(): int { global $DB; $reflector = new ReflectionClass($DB); $property = $reflector->getProperty('inorequaluniqueindex'); - $property->setAccessible(true); return (int) $property->getValue($DB); } @@ -390,7 +389,6 @@ public function new_connection($ssl) { $reflector = new ReflectionClass($db2); $rp = $reflector->getProperty('pgsql'); - $rp->setAccessible(true); return $rp->getValue($db2); } diff --git a/lib/dml/tests/sqlsrv_native_moodle_database_test.php b/lib/dml/tests/sqlsrv_native_moodle_database_test.php index 9e0f34b9f7ea..0d4800a6e470 100644 --- a/lib/dml/tests/sqlsrv_native_moodle_database_test.php +++ b/lib/dml/tests/sqlsrv_native_moodle_database_test.php @@ -125,10 +125,8 @@ public function test_add_no_lock_to_temp_tables($input, $expected) { $reflector = new \ReflectionObject($sqlsrv); $method = $reflector->getMethod('add_no_lock_to_temp_tables'); - $method->setAccessible(true); $temptablesproperty = $reflector->getProperty('temptables'); - $temptablesproperty->setAccessible(true); $temptables = new temptables_tester(); $temptablesproperty->setValue($sqlsrv, $temptables); @@ -252,7 +250,6 @@ public function test_has_query_order_by(string $sql, string $expectedmainquery, // The has_query_order_by static method is protected. Use Reflection to call the method. $method = new \ReflectionMethod('sqlsrv_native_moodle_database', 'has_query_order_by'); - $method->setAccessible(true); $result = $method->invoke(null, $sql); $this->assertSame($expectedresult, $result); } diff --git a/lib/editor/atto/plugins/html/thirdpartylibs.xml b/lib/editor/atto/plugins/html/thirdpartylibs.xml index 6baba0ca1fb1..ceb826cbf70f 100644 --- a/lib/editor/atto/plugins/html/thirdpartylibs.xml +++ b/lib/editor/atto/plugins/html/thirdpartylibs.xml @@ -12,7 +12,7 @@ yui/src/beautify jsbeautify Beautify HTML code in Atto. - 1.14.7 + 1.15.1 MIT https://github.com/beautify-web/js-beautify diff --git a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-debug.js b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-debug.js index 6ebc08992d70..4bd9ce1b0259 100644 --- a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-debug.js +++ b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-debug.js @@ -77,7 +77,7 @@ Y.namespace('M.atto_html').beautify = exports; } } space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()", - NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) + NOTE: This option is overridden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" | any of the former + ",preserve-inline" put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. @@ -928,7 +928,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) { - if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { + if (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.SEMICOLON]) && !this._flags.inline_frame) { this.print_newline(); } else { this._output.space_before_token = true; @@ -1054,7 +1054,9 @@ Beautifier.prototype.handle_word = function(current_token) { } if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { - if (!this.start_of_object_property()) { + if (!this.start_of_object_property() && !( + // start of object property is different for numeric values with +/- prefix operators + in_array(this._flags.last_token.text, ['+', '-']) && this._last_last_text === ':' && this._flags.parent.mode === MODE.ObjectLiteral)) { this.allow_wrap_or_preserved_newline(current_token); } } @@ -1335,6 +1337,12 @@ Beautifier.prototype.handle_operator = function(current_token) { return; } + if (in_array(current_token.text, ['-', '+']) && this.start_of_object_property()) { + // numeric value with +/- symbol in front as a property + this.print_token(current_token); + return; + } + // Allow line wrapping between operators when operator_position is // set to before or preserve if (this._flags.last_token.type === TOKEN.OPERATOR && in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)) { @@ -2161,12 +2169,13 @@ var nonASCIIidentifierChars = "\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u0 //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; -var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; +var unicodeEscapeOrCodePoint = "\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}"; +var identifierStart = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; +var identifierChars = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; exports.identifier = new RegExp(identifierStart + identifierChars, 'g'); exports.identifierStart = new RegExp(identifierStart); -exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); +exports.identifierMatch = new RegExp("(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line @@ -2355,10 +2364,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -2654,6 +2663,7 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_non_javascript(c); token = token || this._read_string(c); + token = token || this._read_pair(c, this._input.peek(1)); // Issue #2062 hack for record type '#{' token = token || this._read_word(previous_token); token = token || this._read_singles(c); token = token || this._read_comment(c); @@ -2712,6 +2722,19 @@ Tokenizer.prototype._read_singles = function(c) { return token; }; +Tokenizer.prototype._read_pair = function(c, d) { + var token = null; + if (c === '#' && d === '{') { + token = this._create_token(TOKEN.START_BLOCK, c + d); + } + + if (token) { + this._input.next(); + this._input.next(); + } + return token; +}; + Tokenizer.prototype._read_punctuation = function() { var resulting_string = this.__patterns.punct.read(); @@ -2957,6 +2980,9 @@ function unescape_string(s) { matched = input_scan.match(/x([0-9A-Fa-f]{2})/g); } else if (input_scan.peek() === 'u') { matched = input_scan.match(/u([0-9A-Fa-f]{4})/g); + if (!matched) { + matched = input_scan.match(/u\{([0-9A-Fa-f]+)\}/g); + } } else { out += '\\'; if (input_scan.hasNext()) { @@ -2980,7 +3006,9 @@ function unescape_string(s) { } else if (escaped >= 0x00 && escaped < 0x20) { // leave 0x00...0x1f escaped out += '\\' + matched[0]; - continue; + } else if (escaped > 0x10FFFF) { + // If the escape sequence is out of bounds, keep the original sequence and continue conversion + out += '\\' + matched[0]; } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) { // single-quote, apostrophe, backslash - escape these out += '\\' + String.fromCharCode(escaped); @@ -3803,7 +3831,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil @@ -4609,10 +4638,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -5115,18 +5144,18 @@ function Beautifier(source_text, options) { // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule this.NESTED_AT_RULE = { - "@page": true, - "@font-face": true, - "@keyframes": true, + "page": true, + "font-face": true, + "keyframes": true, // also in CONDITIONAL_GROUP_RULE below - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.CONDITIONAL_GROUP_RULE = { - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.NON_SEMICOLON_NEWLINE_PROPERTY = [ "grid-template-areas", @@ -5254,8 +5283,7 @@ Beautifier.prototype.beautify = function() { // label { content: blue } var insidePropertyValue = false; var enteringConditionalGroup = false; - var insideAtExtend = false; - var insideAtImport = false; + var insideNonNestedAtRule = false; var insideScssMap = false; var topCharacter = this._ch; var insideNonSemiColonValues = false; @@ -5310,10 +5338,30 @@ Beautifier.prototype.beautify = function() { // Ensures any new lines following the comment are preserved this.eatWhitespace(true); - } else if (this._ch === '@' || this._ch === '$') { + } else if (this._ch === '$') { + this.preserveSingleSpace(isAfterSpace); + + this.print_string(this._ch); + + // strip trailing space, if present, for hash property checks + var variable = this._input.peekUntilAfter(/[: ,;{}()[\]\/='"]/g); + + if (variable.match(/[ :]$/)) { + // we have a variable or pseudo-class, add it and insert one space before continuing + variable = this.eatString(": ").replace(/\s+$/, ''); + this.print_string(variable); + this._output.space_before_token = true; + } + + // might be sass variable + if (parenLevel === 0 && variable.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); + } + } else if (this._ch === '@') { this.preserveSingleSpace(isAfterSpace); - // deal with less propery mixins @{...} + // deal with less property mixins @{...} if (this._input.peek() === '{') { this.print_string(this._ch + this.eatString('}')); } else { @@ -5324,29 +5372,26 @@ Beautifier.prototype.beautify = function() { if (variableOrRule.match(/[ :]$/)) { // we have a variable or pseudo-class, add it and insert one space before continuing - variableOrRule = this.eatString(": ").replace(/\s$/, ''); + variableOrRule = this.eatString(": ").replace(/\s+$/, ''); this.print_string(variableOrRule); this._output.space_before_token = true; } - variableOrRule = variableOrRule.replace(/\s$/, ''); - - if (variableOrRule === 'extend') { - insideAtExtend = true; - } else if (variableOrRule === 'import') { - insideAtImport = true; - } + // might be less variable + if (parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); - // might be a nesting at-rule - if (variableOrRule in this.NESTED_AT_RULE) { + // might be a nesting at-rule + } else if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; if (variableOrRule in this.CONDITIONAL_GROUP_RULE) { enteringConditionalGroup = true; } - // might be less variable - } else if (!insideRule && parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { - insidePropertyValue = true; - this.indent(); + + // might be a non-nested at-rule + } else if (parenLevel === 0 && !insidePropertyValue) { + insideNonNestedAtRule = true; } } } else if (this._ch === '#' && this._input.peek() === '{') { @@ -5358,6 +5403,9 @@ Beautifier.prototype.beautify = function() { this.outdent(); } + // non nested at rule becomes nested + insideNonNestedAtRule = false; + // when entering conditional groups, only rulesets are allowed if (enteringConditionalGroup) { enteringConditionalGroup = false; @@ -5398,8 +5446,7 @@ Beautifier.prototype.beautify = function() { if (previous_ch === '{') { this._output.trim(true); } - insideAtImport = false; - insideAtExtend = false; + if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -5433,9 +5480,10 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideNonNestedAtRule && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query + this.print_string(':'); if (!insidePropertyValue) { insidePropertyValue = true; @@ -5472,8 +5520,7 @@ Beautifier.prototype.beautify = function() { this.outdent(); insidePropertyValue = false; } - insideAtExtend = false; - insideAtImport = false; + insideNonNestedAtRule = false; this.print_string(this._ch); this.eatWhitespace(true); @@ -5538,7 +5585,7 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) { + if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideNonNestedAtRule) { this._output.add_new_line(); } else { this._output.space_before_token = true; @@ -6353,10 +6400,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -7229,7 +7276,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil @@ -7572,6 +7620,13 @@ Printer.prototype.indent = function() { this.indent_level++; }; +Printer.prototype.deindent = function() { + if (this.indent_level > 0) { + this.indent_level--; + this._output.set_indent(this.indent_level, this.alignment_size); + } +}; + Printer.prototype.get_full_indent = function(level) { level = this.indent_level + (level || 0); if (level < 1) { @@ -7757,15 +7812,19 @@ Beautifier.prototype.beautify = function() { while (raw_token.type !== TOKEN.EOF) { if (raw_token.type === TOKEN.TAG_OPEN || raw_token.type === TOKEN.COMMENT) { - parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token); + parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token, tokens); last_tag_token = parser_token; } else if ((raw_token.type === TOKEN.ATTRIBUTE || raw_token.type === TOKEN.EQUALS || raw_token.type === TOKEN.VALUE) || (raw_token.type === TOKEN.TEXT && !last_tag_token.tag_complete)) { - parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, tokens); + parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, last_token); } else if (raw_token.type === TOKEN.TAG_CLOSE) { parser_token = this._handle_tag_close(printer, raw_token, last_tag_token); } else if (raw_token.type === TOKEN.TEXT) { parser_token = this._handle_text(printer, raw_token, last_tag_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_OPEN) { + parser_token = this._handle_control_flow_open(printer, raw_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_CLOSE) { + parser_token = this._handle_control_flow_close(printer, raw_token); } else { // This should never happen, but if it does. Print the raw token printer.add_raw_token(raw_token); @@ -7780,6 +7839,38 @@ Beautifier.prototype.beautify = function() { return sweet_code; }; +Beautifier.prototype._handle_control_flow_open = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + printer.indent(); + return parser_token; +}; + +Beautifier.prototype._handle_control_flow_close = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + + printer.deindent(); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + return parser_token; +}; + Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_token) { var parser_token = { text: raw_token.text, @@ -7818,7 +7909,7 @@ Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_t return parser_token; }; -Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, tokens) { +Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, last_token) { var wrapped = last_tag_token.has_wrapped_attrs; var parser_token = { text: raw_token.text, @@ -7839,7 +7930,6 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ } else { if (raw_token.type === TOKEN.ATTRIBUTE) { printer.set_space_before_token(true); - last_tag_token.attr_count += 1; } else if (raw_token.type === TOKEN.EQUALS) { //no space before = printer.set_space_before_token(false); } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value @@ -7852,29 +7942,15 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ wrapped = wrapped || raw_token.newlines !== 0; } - - if (this._is_wrap_attributes_force) { - var force_attr_wrap = last_tag_token.attr_count > 1; - if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) { - var is_only_attribute = true; - var peek_index = 0; - var peek_token; - do { - peek_token = tokens.peek(peek_index); - if (peek_token.type === TOKEN.ATTRIBUTE) { - is_only_attribute = false; - break; - } - peek_index += 1; - } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE); - - force_attr_wrap = !is_only_attribute; - } - - if (force_attr_wrap) { - printer.print_newline(false); - wrapped = true; - } + // Wrap for 'force' options, and if the number of attributes is at least that specified in 'wrap_attributes_min_attrs': + // 1. always wrap the second and beyond attributes + // 2. wrap the first attribute only if 'force-expand-multiline' is specified + if (this._is_wrap_attributes_force && + last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && + (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond + this._is_wrap_attributes_force_expand_multiline)) { + printer.print_newline(false); + wrapped = true; } } printer.print_token(raw_token); @@ -8003,12 +8079,12 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, } }; -Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token) { +Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token, tokens) { var parser_token = this._get_tag_open_token(raw_token); if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) && !last_tag_token.is_empty_element && - raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf(' tag special case: -var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; +var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']; Beautifier.prototype._do_optional_end_element = function(parser_token) { @@ -8249,7 +8338,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) { } else if (parser_token.tag_name === 'li') { // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. - result = result || this._tag_stack.try_pop('li', ['ol', 'ul']); + result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element. @@ -8388,6 +8477,7 @@ function Options(options) { this.indent_handlebars = this._get_boolean('indent_handlebars', true); this.wrap_attributes = this._get_selection('wrap_attributes', ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple', 'preserve', 'preserve-aligned']); + this.wrap_attributes_min_attrs = this._get_number('wrap_attributes_min_attrs', 2); this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size); this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']); @@ -8405,6 +8495,7 @@ function Options(options) { // obsolete inline tags 'acronym', 'big', 'strike', 'tt' ]); + this.inline_custom_elements = this._get_boolean('inline_custom_elements', true); this.void_elements = this._get_array('void_elements', [ // HTLM void elements - aka self-closing tags - aka singletons // https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements @@ -8479,6 +8570,8 @@ var Pattern = (__webpack_require__(12).Pattern); var TOKEN = { TAG_OPEN: 'TK_TAG_OPEN', TAG_CLOSE: 'TK_TAG_CLOSE', + CONTROL_FLOW_OPEN: 'TK_CONTROL_FLOW_OPEN', + CONTROL_FLOW_CLOSE: 'TK_CONTROL_FLOW_CLOSE', ATTRIBUTE: 'TK_ATTRIBUTE', EQUALS: 'TK_EQUALS', VALUE: 'TK_VALUE', @@ -8503,11 +8596,13 @@ var Tokenizer = function(input_string, options) { this.__patterns = { word: templatable_reader.until(/[\n\r\t <]/), + word_control_flow_close_excluded: templatable_reader.until(/[\n\r\t <}]/), single_quote: templatable_reader.until_after(/'/), double_quote: templatable_reader.until_after(/"/), attribute: templatable_reader.until(/[\n\r\t =>]|\/>/), element_name: templatable_reader.until(/[\n\r\t >\/]/), + angular_control_flow_start: pattern_reader.matching(/\@[a-zA-Z]+[^({]*[({]/), handlebars_comment: pattern_reader.starting_with(/{{!--/).until_after(/--}}/), handlebars: pattern_reader.starting_with(/{{/).until_after(/}}/), handlebars_open: pattern_reader.until(/[\n\r\t }]/), @@ -8521,6 +8616,7 @@ var Tokenizer = function(input_string, options) { if (this._options.indent_handlebars) { this.__patterns.word = this.__patterns.word.exclude('handlebars'); + this.__patterns.word_control_flow_close_excluded = this.__patterns.word_control_flow_close_excluded.exclude('handlebars'); } this._unformatted_content_delimiter = null; @@ -8539,14 +8635,16 @@ Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:fal }; Tokenizer.prototype._is_opening = function(current_token) { - return current_token.type === TOKEN.TAG_OPEN; + return current_token.type === TOKEN.TAG_OPEN || current_token.type === TOKEN.CONTROL_FLOW_OPEN; }; Tokenizer.prototype._is_closing = function(current_token, open_token) { - return current_token.type === TOKEN.TAG_CLOSE && + return (current_token.type === TOKEN.TAG_CLOSE && (open_token && ( ((current_token.text === '>' || current_token.text === '/>') && open_token.text[0] === '<') || - (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))); + (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))) + ) || (current_token.type === TOKEN.CONTROL_FLOW_CLOSE && + (current_token.text === '}' && open_token.text.endsWith('{'))); }; Tokenizer.prototype._reset = function() { @@ -8565,8 +8663,9 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_open_handlebars(c, open_token); token = token || this._read_attribute(c, previous_token, open_token); token = token || this._read_close(c, open_token); + token = token || this._read_control_flows(c, open_token); token = token || this._read_raw_content(c, previous_token, open_token); - token = token || this._read_content_word(c); + token = token || this._read_content_word(c, open_token); token = token || this._read_comment_or_cdata(c); token = token || this._read_processing(c); token = token || this._read_open(c, open_token); @@ -8631,7 +8730,7 @@ Tokenizer.prototype._read_processing = function(c) { // jshint unused:false Tokenizer.prototype._read_open = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (c === '<') { resulting_string = this._input.next(); @@ -8648,7 +8747,7 @@ Tokenizer.prototype._read_open = function(c, open_token) { Tokenizer.prototype._read_open_handlebars = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') { if (this._input.peek(2) === '!') { resulting_string = this.__patterns.handlebars_comment.read(); @@ -8663,11 +8762,48 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) { return token; }; +Tokenizer.prototype._read_control_flows = function(c, open_token) { + var resulting_string = ''; + var token = null; + // Only check for control flows if angular templating is set AND indenting is set + if (!this._options.templating.includes('angular') || !this._options.indent_handlebars) { + return token; + } + + if (c === '@') { + resulting_string = this.__patterns.angular_control_flow_start.read(); + if (resulting_string === '') { + return token; + } + + var opening_parentheses_count = resulting_string.endsWith('(') ? 1 : 0; + var closing_parentheses_count = 0; + // The opening brace of the control flow is where the number of opening and closing parentheses equal + // e.g. @if({value: true} !== null) { + while (!(resulting_string.endsWith('{') && opening_parentheses_count === closing_parentheses_count)) { + var next_char = this._input.next(); + if (next_char === null) { + break; + } else if (next_char === '(') { + opening_parentheses_count++; + } else if (next_char === ')') { + closing_parentheses_count++; + } + resulting_string += next_char; + } + token = this._create_token(TOKEN.CONTROL_FLOW_OPEN, resulting_string); + } else if (c === '}' && open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) { + resulting_string = this._input.next(); + token = this._create_token(TOKEN.CONTROL_FLOW_CLOSE, resulting_string); + } + return token; +}; + Tokenizer.prototype._read_close = function(c, open_token) { var resulting_string = null; var token = null; - if (open_token) { + if (open_token && open_token.type === TOKEN.TAG_OPEN) { if (open_token.text[0] === '<' && (c === '>' || (c === '/' && this._input.peek(1) === '>'))) { resulting_string = this._input.next(); if (c === '/') { // for close tag "/>" @@ -8754,7 +8890,7 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) return null; }; -Tokenizer.prototype._read_content_word = function(c) { +Tokenizer.prototype._read_content_word = function(c, open_token) { var resulting_string = ''; if (this._options.unformatted_content_delimiter) { if (c === this._options.unformatted_content_delimiter[0]) { @@ -8763,7 +8899,7 @@ Tokenizer.prototype._read_content_word = function(c) { } if (!resulting_string) { - resulting_string = this.__patterns.word.read(); + resulting_string = (open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) ? this.__patterns.word_control_flow_close_excluded.read() : this.__patterns.word.read(); } if (resulting_string) { return this._create_token(TOKEN.TEXT, resulting_string); diff --git a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-min.js b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-min.js index c16731212cc9..9f2d6e07a8b6 100644 --- a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-min.js +++ b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify-min.js @@ -1,24 +1,25 @@ -YUI.add("moodle-atto_html-beautify",function(t,e){var s,a,u,n,i,_,r={};t.namespace("M.atto_html").beautify=r,function(){"use strict";var t,n=[function(t,e,n){var i=n(1).Beautifier,_=n(5).Options;t.exports=function(t,e){return new i(t,e).beautify()},t.exports.defaultOptions=function(){return new _}},function(n,_,t){var d,f,g,o,h,s,a,r,b,m,y,w=t(2).Output,k=t(3).Token,x=t(4),v=t(5).Options,E=t(7).Tokenizer,O=t(7).line_starters,T=t(7).positionable_operators,p=t(7).TOKEN;function l(t,e){return-1!==e.indexOf(t)}function i(t,e){return t&&t.type===p.RESERVED&&t.text===e}function c(t,e){return t&&t.type===p.RESERVED&&l(t.text,e)}function R(t,e){e.multiline_frame||e.mode===r||e.mode===b||t.remove_indent(e.start_line_index)}function u(t){return t===a}function A(t){return l(t,[m,r,b])}function e(t,e){e=e||{},this._source_text=t||"",this._output=null,this._tokens=null,this._last_last_text=null,this._flags=null,this._previous_flags=null,this._flag_store=null,this._options=new v(e)}d=["case","return","do","if","throw","else","await","break","continue","async"],f=function(t){for(var e={},n=0;nn&&(n=t.line_indent_level)),{mode:e,parent:t,last_token:t?t.last_token:new k(p.START_BLOCK,""),last_word:t?t.last_word:"",declaration_statement:!1,declaration_assignment:!1,multiline_frame:!1,inline_frame:!1,if_block:!1,else_block:!1,class_start_block:!1,do_block:!1,do_while:!1,import_block:!1,in_case_statement:!1,in_case:!1,case_body:!1,case_block:!1,indentation_level:n,alignment:0,line_indent_level:t?t.line_indent_level:n,start_line_index:this._output.get_line_number(),ternary_depth:0}},e.prototype._reset=function(t){var e=t.match(/^[\t ]*/)[0];return this._last_last_text="",this._output=new w(this._options,e),this._output.raw=this._options.test_output_raw,this._flag_store=[],this.set_mode(o),e=new E(t,this._options),this._tokens=e.tokenize(),t},e.prototype.beautify=function(){var t,e,n;if(this._options.disabled)return this._source_text;for(t=this._reset(this._source_text),e=this._options.eol,"auto"===this._options.eol&&(e="\n",t&&x.lineBreak.test(t||"")&&(e=t.match(x.lineBreak)[0])),n=this._tokens.next();n;)this.handle_token(n),this._last_last_text=this._flags.last_token.text,this._flags.last_token=n,n=this._tokens.next();return this._output.get_code(e)},e.prototype.handle_token=function(t,e){t.type===p.START_EXPR?this.handle_start_expr(t):t.type===p.END_EXPR?this.handle_end_expr(t):t.type===p.START_BLOCK?this.handle_start_block(t):t.type===p.END_BLOCK?this.handle_end_block(t):t.type===p.WORD||t.type===p.RESERVED?this.handle_word(t):t.type===p.SEMICOLON?this.handle_semicolon(t):t.type===p.STRING?this.handle_string(t):t.type===p.EQUALS?this.handle_equals(t):t.type===p.OPERATOR?this.handle_operator(t):t.type===p.COMMA?this.handle_comma(t):t.type===p.BLOCK_COMMENT?this.handle_block_comment(t,e):t.type===p.COMMENT?this.handle_comment(t,e):t.type===p.DOT?this.handle_dot(t):t.type===p.EOF?this.handle_eof(t):(t.type,p.UNKNOWN,this.handle_unknown(t,e))},e.prototype.handle_whitespace_and_comments=function(t,e){var n,i,_,s=t.newlines,a=this._options.keep_array_indentation&&u(this._flags.mode);if(t.comments_before)for(n=t.comments_before.next();n;)this.handle_whitespace_and_comments(n,e),this.handle_token(n,e),n=t.comments_before.next();if(a)for(i=0;ithis._options.max_preserve_newlines&&(s=this._options.max_preserve_newlines),this._options.preserve_newlines&&1this._flags.parent.indentation_level)&&(--this._flags.indentation_level,this._output.set_indent(this._flags.indentation_level,this._flags.alignment))},e.prototype.set_mode=function(t){this._flags?(this._flag_store.push(this._flags),this._previous_flags=this._flags):this._previous_flags=this.create_flags(null,t),this._flags=this.create_flags(this._previous_flags,t),this._output.set_indent(this._flags.indentation_level,this._flags.alignment)},e.prototype.restore_mode=function(){0"!==this._flags.last_token.text)&&(l(this._flags.last_token.type,[p.EQUALS,p.START_EXPR,p.COMMA,p.OPERATOR])||c(this._flags.last_token,["return","throw","import","default"]))?this.set_mode(s):this.set_mode(o),this._flags.last_token&&c(this._flags.last_token.previous,["class","extends"])&&(this._flags.class_start_block=!0),n=(e=!n.comments_before&&"}"===n.text)&&"function"===this._flags.last_word&&this._flags.last_token.type===p.END_EXPR,this._options.brace_preserve_inline){i=0,this._flags.inline_frame=!(_=null);do{if((_=this._tokens.peek((i+=1)-1)).newlines){this._flags.inline_frame=!1;break}}while(_.type!==p.EOF&&(_.type!==p.END_BLOCK||_.opened!==t))}("expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines)&&!this._flags.inline_frame?this._flags.last_token.type!==p.OPERATOR&&(n||this._flags.last_token.type===p.EQUALS||c(this._flags.last_token,d)&&"else"!==this._flags.last_token.text)?this._output.space_before_token=!0:this.print_newline(!1,!0):(!u(this._previous_flags.mode)||this._flags.last_token.type!==p.START_EXPR&&this._flags.last_token.type!==p.COMMA||(this._flags.last_token.type!==p.COMMA&&!this._options.space_in_paren||(this._output.space_before_token=!0),(this._flags.last_token.type===p.COMMA||this._flags.last_token.type===p.START_EXPR&&this._flags.inline_frame)&&(this.allow_wrap_or_preserved_newline(t),this._previous_flags.multiline_frame=this._previous_flags.multiline_frame||this._flags.multiline_frame,this._flags.multiline_frame=!1)),this._flags.last_token.type!==p.OPERATOR&&this._flags.last_token.type!==p.START_EXPR&&(this._flags.last_token.type!==p.START_BLOCK||this._flags.inline_frame?this._output.space_before_token=!0:this.print_newline())),this.print_token(t),this.indent(),e||this._options.brace_preserve_inline&&this._flags.inline_frame||this.print_newline()},e.prototype.handle_end_block=function(t){for(this.handle_whitespace_and_comments(t);this._flags.mode===h;)this.restore_mode();var e=this._flags.last_token.type===p.START_BLOCK;this._flags.inline_frame&&!e?this._output.space_before_token=!0:"expand"===this._options.brace_style?e||this.print_newline():e||(u(this._flags.mode)&&this._options.keep_array_indentation?(this._options.keep_array_indentation=!1,this.print_newline(),this._options.keep_array_indentation=!0):this.print_newline()),this.restore_mode(),this.print_token(t)},e.prototype.handle_word=function(t){var e;if(t.type===p.RESERVED&&(l(t.text,["set","get"])&&this._flags.mode!==s||"import"===t.text&&l(this._tokens.peek().text,["(","."])||l(t.text,["as","from"])&&!this._flags.import_block||this._flags.mode===s&&":"===this._tokens.peek().text)&&(t.type=p.WORD),this.start_of_statement(t)?c(this._flags.last_token,["var","let","const"])&&t.type===p.WORD&&(this._flags.declaration_statement=!0):!t.newlines||A(this._flags.mode)||this._flags.last_token.type===p.OPERATOR&&"--"!==this._flags.last_token.text&&"++"!==this._flags.last_token.text||this._flags.last_token.type===p.EQUALS||!this._options.preserve_newlines&&c(this._flags.last_token,["var","let","const","set","get"])?this.handle_whitespace_and_comments(t):(this.handle_whitespace_and_comments(t),this.print_newline()),this._flags.do_block&&!this._flags.do_while){if(i(t,"while"))return this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0,void(this._flags.do_while=!0);this.print_newline(),this._flags.do_block=!1}if(this._flags.if_block)if(!this._flags.else_block&&i(t,"else"))this._flags.else_block=!0;else{for(;this._flags.mode===h;)this.restore_mode();this._flags.if_block=!1,this._flags.else_block=!1}return this._flags.in_case_statement&&c(t,["case","default"])?(this.print_newline(),this._flags.case_block||!this._flags.case_body&&!this._options.jslint_happy||this.deindent(),this._flags.case_body=!1,this.print_token(t),void(this._flags.in_case=!0)):(this._flags.last_token.type!==p.COMMA&&this._flags.last_token.type!==p.START_EXPR&&this._flags.last_token.type!==p.EQUALS&&this._flags.last_token.type!==p.OPERATOR||this.start_of_object_property()||this.allow_wrap_or_preserved_newline(t),i(t,"function")?((l(this._flags.last_token.text,["}",";"])||this._output.just_added_newline()&&!l(this._flags.last_token.text,["(","[","{",":","=",","])&&this._flags.last_token.type!==p.OPERATOR)&&(this._output.just_added_blankline()||t.comments_before||(this.print_newline(),this.print_newline(!0))),this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD?c(this._flags.last_token,["get","set","new","export"])||c(this._flags.last_token,y)||i(this._flags.last_token,"default")&&"export"===this._last_last_text||"declare"===this._flags.last_token.text?this._output.space_before_token=!0:this.print_newline():this._flags.last_token.type===p.OPERATOR||"="===this._flags.last_token.text?this._output.space_before_token=!0:!this._flags.multiline_frame&&(A(this._flags.mode)||u(this._flags.mode))||this.print_newline(),this.print_token(t),void(this._flags.last_word=t.text)):(e="NONE",this._flags.last_token.type===p.END_BLOCK?this._previous_flags.inline_frame?e="SPACE":!c(t,["else","catch","finally","from"])||"expand"===this._options.brace_style||"end-expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines?e="NEWLINE":(e="SPACE",this._output.space_before_token=!0):this._flags.last_token.type===p.SEMICOLON&&this._flags.mode===o?e="NEWLINE":this._flags.last_token.type===p.SEMICOLON&&A(this._flags.mode)?e="SPACE":this._flags.last_token.type===p.STRING?e="NEWLINE":this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD||"*"===this._flags.last_token.text&&(l(this._last_last_text,["function","yield"])||this._flags.mode===s&&l(this._last_last_text,["{",","]) -)?e="SPACE":this._flags.last_token.type===p.START_BLOCK?e=this._flags.inline_frame?"SPACE":"NEWLINE":this._flags.last_token.type===p.END_EXPR&&(this._output.space_before_token=!0,e="NEWLINE"),c(t,O)&&")"!==this._flags.last_token.text&&(e=this._flags.inline_frame||"else"===this._flags.last_token.text||"export"===this._flags.last_token.text?"SPACE":"NEWLINE"),c(t,["else","catch","finally"])?(this._flags.last_token.type!==p.END_BLOCK||this._previous_flags.mode!==o||"expand"===this._options.brace_style||"end-expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines)&&!this._flags.inline_frame?this.print_newline():(this._output.trim(!0),"}"!==this._output.current_line.last()&&this.print_newline(),this._output.space_before_token=!0):"NEWLINE"===e?c(this._flags.last_token,d)||"declare"===this._flags.last_token.text&&c(t,["var","let","const"])?this._output.space_before_token=!0:this._flags.last_token.type!==p.END_EXPR?this._flags.last_token.type===p.START_EXPR&&c(t,["var","let","const"])||":"===this._flags.last_token.text||(i(t,"if")&&i(t.previous,"else")?this._output.space_before_token=!0:this.print_newline()):c(t,O)&&")"!==this._flags.last_token.text&&this.print_newline():this._flags.multiline_frame&&u(this._flags.mode)&&","===this._flags.last_token.text&&"}"===this._last_last_text?this.print_newline():"SPACE"===e&&(this._output.space_before_token=!0),!t.previous||t.previous.type!==p.WORD&&t.previous.type!==p.RESERVED||(this._output.space_before_token=!0),this.print_token(t),this._flags.last_word=t.text,void(t.type===p.RESERVED&&("do"===t.text?this._flags.do_block=!0:"if"===t.text?this._flags.if_block=!0:"import"===t.text?this._flags.import_block=!0:this._flags.import_block&&i(t,"from")&&(this._flags.import_block=!1)))))},e.prototype.handle_semicolon=function(t){this.start_of_statement(t)?this._output.space_before_token=!1:this.handle_whitespace_and_comments(t);for(var e=this._tokens.peek();!(this._flags.mode!==h||this._flags.if_block&&i(e,"else")||this._flags.do_block);)this.restore_mode();this._flags.import_block&&(this._flags.import_block=!1),this.print_token(t)},e.prototype.handle_string=function(t){t.text.startsWith("`")&&0===t.newlines&&""===t.whitespace_before&&(")"===t.previous.text||this._flags.last_token.type===p.WORD)||(this.start_of_statement(t)?this._output.space_before_token=!0:(this.handle_whitespace_and_comments(t),this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD||this._flags.inline_frame?this._output.space_before_token=!0:this._flags.last_token.type===p.COMMA||this._flags.last_token.type===p.START_EXPR||this._flags.last_token.type===p.EQUALS||this._flags.last_token.type===p.OPERATOR?this.start_of_object_property()||this.allow_wrap_or_preserved_newline(t):!t.text.startsWith("`")||this._flags.last_token.type!==p.END_EXPR||"]"!==t.previous.text&&")"!==t.previous.text||0!==t.newlines?this.print_newline():this._output.space_before_token=!0)),this.print_token(t)},e.prototype.handle_equals=function(t){this.start_of_statement(t)||this.handle_whitespace_and_comments(t),this._flags.declaration_statement&&(this._flags.declaration_assignment=!0),this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0},e.prototype.handle_comma=function(t){this.handle_whitespace_and_comments(t,!0),this.print_token(t),this._output.space_before_token=!0,this._flags.declaration_statement?(A(this._flags.parent.mode)&&(this._flags.declaration_assignment=!1),this._flags.declaration_assignment?(this._flags.declaration_assignment=!1,this.print_newline(!1,!0)):this._options.comma_first&&this.allow_wrap_or_preserved_newline(t)):this._flags.mode===s||this._flags.mode===h&&this._flags.parent.mode===s?(this._flags.mode===h&&this.restore_mode(),this._flags.inline_frame||this.print_newline()):this._options.comma_first&&this.allow_wrap_or_preserved_newline(t)},e.prototype.handle_operator=function(t){var e,n,i,_,s,a,u="*"===t.text&&(c(this._flags.last_token,["function","yield"])||l(this._flags.last_token.type,[p.START_BLOCK,p.COMMA,p.END_BLOCK,p.SEMICOLON])),r=l(t.text,["-","+"])&&(l(this._flags.last_token.type,[p.START_BLOCK,p.START_EXPR,p.EQUALS,p.OPERATOR])||l(this._flags.last_token.text,O)||","===this._flags.last_token.text);if(this.start_of_statement(t)||this.handle_whitespace_and_comments(t,!u),"*"!==t.text||this._flags.last_token.type!==p.DOT)if("::"!==t.text){if(this._flags.last_token.type===p.OPERATOR&&l(this._options.operator_position,g)&&this.allow_wrap_or_preserved_newline(t),":"===t.text&&this._flags.in_case)return this.print_token(t),this._flags.in_case=!1,this._flags.case_body=!0,void(this._tokens.peek().type!==p.START_BLOCK?(this.indent(),this.print_newline(),this._flags.case_block=!1):(this._flags.case_block=!0,this._output.space_before_token=!0));if(a=!(n=e=!0),":"===t.text?0===this._flags.ternary_depth?e=!1:(--this._flags.ternary_depth,a=!0):"?"===t.text&&(this._flags.ternary_depth+=1),!r&&!u&&this._options.preserve_newlines&&l(t.text,T))switch(_=(i=":"===t.text)&&a,s=i&&!a,this._options.operator_position){case f.before_newline:return this._output.space_before_token=!s,this.print_token(t),i&&!_||this.allow_wrap_or_preserved_newline(t),void(this._output.space_before_token=!0);case f.after_newline:return this._output.space_before_token=!0,!i||_?this._tokens.peek().newlines?this.print_newline(!1,!0):this.allow_wrap_or_preserved_newline(t):this._output.space_before_token=!1,this.print_token(t),void(this._output.space_before_token=!0);case f.preserve_newline:return s||this.allow_wrap_or_preserved_newline(t),e=!(this._output.just_added_newline()||s),this._output.space_before_token=e,this.print_token(t),void(this._output.space_before_token=!0)}u?(this.allow_wrap_or_preserved_newline(t),e=!1,n=(a=this._tokens.peek())&&l(a.type,[p.WORD,p.RESERVED])):"..."===t.text?(this.allow_wrap_or_preserved_newline(t),e=this._flags.last_token.type===p.START_BLOCK,n=!1):(l(t.text,["--","++","!","~"])||r)&&( -this._flags.last_token.type!==p.COMMA&&this._flags.last_token.type!==p.START_EXPR||this.allow_wrap_or_preserved_newline(t),n=e=!1,!t.newlines||"--"!==t.text&&"++"!==t.text&&"~"!==t.text||((u=c(this._flags.last_token,d)&&t.newlines)&&(this._previous_flags.if_block||this._previous_flags.else_block)&&this.restore_mode(),this.print_newline(u,!0)),";"===this._flags.last_token.text&&A(this._flags.mode)&&(e=!0),this._flags.last_token.type===p.RESERVED?e=!0:this._flags.last_token.type===p.END_EXPR?e=!("]"===this._flags.last_token.text&&("--"===t.text||"++"===t.text)):this._flags.last_token.type===p.OPERATOR&&(e=l(t.text,["--","-","++","+"])&&l(this._flags.last_token.text,["--","-","++","+"]),l(t.text,["+","-"])&&l(this._flags.last_token.text,["--","++"])&&(n=!0)),(this._flags.mode!==o||this._flags.inline_frame)&&this._flags.mode!==h||"{"!==this._flags.last_token.text&&";"!==this._flags.last_token.text||this.print_newline()),this._output.space_before_token=this._output.space_before_token||e,this.print_token(t),this._output.space_before_token=n}else this.print_token(t);else this.print_token(t)},e.prototype.handle_block_comment=function(t,e){return this._output.raw?(this._output.add_raw_token(t),void(t.directives&&"end"===t.directives.preserve&&(this._output.raw=this._options.test_output_raw))):t.directives?(this.print_newline(!1,e),this.print_token(t),"start"===t.directives.preserve&&(this._output.raw=!0),void this.print_newline(!1,!0)):void(x.newline.test(t.text)||t.newlines?this.print_block_commment(t,e):(this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0))},e.prototype.print_block_commment=function(t,e){var n,i,_,s=function(t){for(var e=[],n=(t=t.replace(x.allLineBreaks,"\n")).indexOf("\n");-1!==n;)e.push(t.substring(0,n)),n=(t=t.substring(n+1)).indexOf("\n");return t.length&&e.push(t),e}(t.text),a=t.whitespace_before,u=a.length;if(this.print_newline(!1,e),this.print_token_line_indentation(t),this._output.add_token(s[0]),this.print_newline(!1,e),1this.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&(this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice(this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count, -this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty()?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g,"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0),1n&&(n=t.line_indent_level)),{mode:e,parent:t,last_token:t?t.last_token:new k(p.START_BLOCK,""),last_word:t?t.last_word:"",declaration_statement:!1,declaration_assignment:!1,multiline_frame:!1,inline_frame:!1,if_block:!1,else_block:!1,class_start_block:!1,do_block:!1,do_while:!1,import_block:!1,in_case_statement:!1,in_case:!1,case_body:!1,case_block:!1,indentation_level:n,alignment:0,line_indent_level:t?t.line_indent_level:n,start_line_index:this._output.get_line_number(),ternary_depth:0}},e.prototype._reset=function(t){var e=t.match(/^[\t ]*/)[0];return this._last_last_text="",this._output=new w(this._options,e),this._output.raw=this._options.test_output_raw,this._flag_store=[],this.set_mode(o),e=new E(t,this._options),this._tokens=e.tokenize(),t},e.prototype.beautify=function(){var t,e,n;if(this._options.disabled)return this._source_text;for(t=this._reset(this._source_text),e=this._options.eol,"auto"===this._options.eol&&(e="\n",t&&x.lineBreak.test(t||"")&&(e=t.match(x.lineBreak)[0])),n=this._tokens.next();n;)this.handle_token(n),this._last_last_text=this._flags.last_token.text,this._flags.last_token=n,n=this._tokens.next();return this._output.get_code(e)},e.prototype.handle_token=function(t,e){t.type===p.START_EXPR?this.handle_start_expr(t):t.type===p.END_EXPR?this.handle_end_expr(t):t.type===p.START_BLOCK?this.handle_start_block(t):t.type===p.END_BLOCK?this.handle_end_block(t):t.type===p.WORD||t.type===p.RESERVED?this.handle_word(t):t.type===p.SEMICOLON?this.handle_semicolon(t):t.type===p.STRING?this.handle_string(t):t.type===p.EQUALS?this.handle_equals(t):t.type===p.OPERATOR?this.handle_operator(t):t.type===p.COMMA?this.handle_comma(t):t.type===p.BLOCK_COMMENT?this.handle_block_comment(t,e):t.type===p.COMMENT?this.handle_comment(t,e):t.type===p.DOT?this.handle_dot(t):t.type===p.EOF?this.handle_eof(t):(t.type,p.UNKNOWN,this.handle_unknown(t,e))},e.prototype.handle_whitespace_and_comments=function(t,e){var n,i,_,s=t.newlines,a=this._options.keep_array_indentation&&r(this._flags.mode);if(t.comments_before)for(n=t.comments_before.next();n;)this.handle_whitespace_and_comments(n,e),this.handle_token(n,e),n=t.comments_before.next();if(a)for(i=0;ithis._options.max_preserve_newlines&&(s=this._options.max_preserve_newlines),this._options.preserve_newlines&&1this._flags.parent.indentation_level)&&(--this._flags.indentation_level,this._output.set_indent(this._flags.indentation_level,this._flags.alignment))},e.prototype.set_mode=function(t){this._flags?(this._flag_store.push(this._flags),this._previous_flags=this._flags):this._previous_flags=this.create_flags(null,t),this._flags=this.create_flags(this._previous_flags,t),this._output.set_indent(this._flags.indentation_level,this._flags.alignment)},e.prototype.restore_mode=function(){0"!==this._flags.last_token.text)&&(l(this._flags.last_token.type,[p.EQUALS,p.START_EXPR,p.COMMA,p.OPERATOR])||c(this._flags.last_token,["return","throw","import","default"]))?this.set_mode(s):this.set_mode(o),this._flags.last_token&&c(this._flags.last_token.previous,["class","extends"])&&(this._flags.class_start_block=!0),n=(e=!n.comments_before&&"}"===n.text)&&"function"===this._flags.last_word&&this._flags.last_token.type===p.END_EXPR,this._options.brace_preserve_inline){i=0,this._flags.inline_frame=!(_=null);do{if((_=this._tokens.peek((i+=1)-1)).newlines){this._flags.inline_frame=!1;break}}while(_.type!==p.EOF&&(_.type!==p.END_BLOCK||_.opened!==t))}("expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines)&&!this._flags.inline_frame?this._flags.last_token.type!==p.OPERATOR&&(n||this._flags.last_token.type===p.EQUALS||c(this._flags.last_token,d)&&"else"!==this._flags.last_token.text)?this._output.space_before_token=!0:this.print_newline(!1,!0):(!r(this._previous_flags.mode)||this._flags.last_token.type!==p.START_EXPR&&this._flags.last_token.type!==p.COMMA||(this._flags.last_token.type!==p.COMMA&&!this._options.space_in_paren||(this._output.space_before_token=!0),(this._flags.last_token.type===p.COMMA||this._flags.last_token.type===p.START_EXPR&&this._flags.inline_frame)&&(this.allow_wrap_or_preserved_newline(t),this._previous_flags.multiline_frame=this._previous_flags.multiline_frame||this._flags.multiline_frame,this._flags.multiline_frame=!1)),this._flags.last_token.type!==p.OPERATOR&&this._flags.last_token.type!==p.START_EXPR&&(l(this._flags.last_token.type,[p.START_BLOCK,p.SEMICOLON])&&!this._flags.inline_frame?this.print_newline():this._output.space_before_token=!0)),this.print_token(t),this.indent(),e||this._options.brace_preserve_inline&&this._flags.inline_frame||this.print_newline()},e.prototype.handle_end_block=function(t){for(this.handle_whitespace_and_comments(t);this._flags.mode===h;)this.restore_mode();var e=this._flags.last_token.type===p.START_BLOCK;this._flags.inline_frame&&!e?this._output.space_before_token=!0:"expand"===this._options.brace_style?e||this.print_newline():e||(r(this._flags.mode)&&this._options.keep_array_indentation?(this._options.keep_array_indentation=!1,this.print_newline(),this._options.keep_array_indentation=!0):this.print_newline()),this.restore_mode(),this.print_token(t)},e.prototype.handle_word=function(t){var e;if(t.type===p.RESERVED&&(l(t.text,["set","get"])&&this._flags.mode!==s||"import"===t.text&&l(this._tokens.peek().text,["(","."])||l(t.text,["as","from"])&&!this._flags.import_block||this._flags.mode===s&&":"===this._tokens.peek().text)&&(t.type=p.WORD),this.start_of_statement(t)?c(this._flags.last_token,["var","let","const"])&&t.type===p.WORD&&(this._flags.declaration_statement=!0):!t.newlines||A(this._flags.mode)||this._flags.last_token.type===p.OPERATOR&&"--"!==this._flags.last_token.text&&"++"!==this._flags.last_token.text||this._flags.last_token.type===p.EQUALS||!this._options.preserve_newlines&&c(this._flags.last_token,["var","let","const","set","get"])?this.handle_whitespace_and_comments(t):(this.handle_whitespace_and_comments(t),this.print_newline()),this._flags.do_block&&!this._flags.do_while){if(i(t,"while"))return this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0,void(this._flags.do_while=!0);this.print_newline(),this._flags.do_block=!1}if(this._flags.if_block)if(!this._flags.else_block&&i(t,"else"))this._flags.else_block=!0;else{for(;this._flags.mode===h;)this.restore_mode();this._flags.if_block=!1,this._flags.else_block=!1}return this._flags.in_case_statement&&c(t,["case","default"])?(this.print_newline(),this._flags.case_block||!this._flags.case_body&&!this._options.jslint_happy||this.deindent(),this._flags.case_body=!1,this.print_token(t),void(this._flags.in_case=!0)):(this._flags.last_token.type!==p.COMMA&&this._flags.last_token.type!==p.START_EXPR&&this._flags.last_token.type!==p.EQUALS&&this._flags.last_token.type!==p.OPERATOR||this.start_of_object_property()||l(this._flags.last_token.text,["+","-"])&&":"===this._last_last_text&&this._flags.parent.mode===s||this.allow_wrap_or_preserved_newline(t),i(t,"function")?((l(this._flags.last_token.text,["}",";"])||this._output.just_added_newline()&&!l(this._flags.last_token.text,["(","[","{",":","=",","])&&this._flags.last_token.type!==p.OPERATOR)&&(this._output.just_added_blankline()||t.comments_before||(this.print_newline(),this.print_newline(!0))),this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD?c(this._flags.last_token,["get","set","new","export"])||c(this._flags.last_token,y)||i(this._flags.last_token,"default")&&"export"===this._last_last_text||"declare"===this._flags.last_token.text?this._output.space_before_token=!0:this.print_newline():this._flags.last_token.type===p.OPERATOR||"="===this._flags.last_token.text?this._output.space_before_token=!0:!this._flags.multiline_frame&&(A(this._flags.mode)||r(this._flags.mode))||this.print_newline(),this.print_token(t),void(this._flags.last_word=t.text)):(e="NONE",this._flags.last_token.type===p.END_BLOCK?this._previous_flags.inline_frame?e="SPACE":!c(t,["else","catch","finally","from"])||"expand"===this._options.brace_style||"end-expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines?e="NEWLINE":(e="SPACE",this._output.space_before_token=!0):this._flags.last_token.type===p.SEMICOLON&&this._flags.mode===o?e="NEWLINE":this._flags.last_token.type===p.SEMICOLON&&A(this._flags.mode)?e="SPACE":this._flags.last_token.type===p.STRING?e="NEWLINE":this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD||"*"===this._flags.last_token.text&&(l( +this._last_last_text,["function","yield"])||this._flags.mode===s&&l(this._last_last_text,["{",","]))?e="SPACE":this._flags.last_token.type===p.START_BLOCK?e=this._flags.inline_frame?"SPACE":"NEWLINE":this._flags.last_token.type===p.END_EXPR&&(this._output.space_before_token=!0,e="NEWLINE"),c(t,O)&&")"!==this._flags.last_token.text&&(e=this._flags.inline_frame||"else"===this._flags.last_token.text||"export"===this._flags.last_token.text?"SPACE":"NEWLINE"),c(t,["else","catch","finally"])?(this._flags.last_token.type!==p.END_BLOCK||this._previous_flags.mode!==o||"expand"===this._options.brace_style||"end-expand"===this._options.brace_style||"none"===this._options.brace_style&&t.newlines)&&!this._flags.inline_frame?this.print_newline():(this._output.trim(!0),"}"!==this._output.current_line.last()&&this.print_newline(),this._output.space_before_token=!0):"NEWLINE"===e?c(this._flags.last_token,d)||"declare"===this._flags.last_token.text&&c(t,["var","let","const"])?this._output.space_before_token=!0:this._flags.last_token.type!==p.END_EXPR?this._flags.last_token.type===p.START_EXPR&&c(t,["var","let","const"])||":"===this._flags.last_token.text||(i(t,"if")&&i(t.previous,"else")?this._output.space_before_token=!0:this.print_newline()):c(t,O)&&")"!==this._flags.last_token.text&&this.print_newline():this._flags.multiline_frame&&r(this._flags.mode)&&","===this._flags.last_token.text&&"}"===this._last_last_text?this.print_newline():"SPACE"===e&&(this._output.space_before_token=!0),!t.previous||t.previous.type!==p.WORD&&t.previous.type!==p.RESERVED||(this._output.space_before_token=!0),this.print_token(t),this._flags.last_word=t.text,void(t.type===p.RESERVED&&("do"===t.text?this._flags.do_block=!0:"if"===t.text?this._flags.if_block=!0:"import"===t.text?this._flags.import_block=!0:this._flags.import_block&&i(t,"from")&&(this._flags.import_block=!1)))))},e.prototype.handle_semicolon=function(t){this.start_of_statement(t)?this._output.space_before_token=!1:this.handle_whitespace_and_comments(t);for(var e=this._tokens.peek();!(this._flags.mode!==h||this._flags.if_block&&i(e,"else")||this._flags.do_block);)this.restore_mode();this._flags.import_block&&(this._flags.import_block=!1),this.print_token(t)},e.prototype.handle_string=function(t){t.text.startsWith("`")&&0===t.newlines&&""===t.whitespace_before&&(")"===t.previous.text||this._flags.last_token.type===p.WORD)||(this.start_of_statement(t)?this._output.space_before_token=!0:(this.handle_whitespace_and_comments(t),this._flags.last_token.type===p.RESERVED||this._flags.last_token.type===p.WORD||this._flags.inline_frame?this._output.space_before_token=!0:this._flags.last_token.type===p.COMMA||this._flags.last_token.type===p.START_EXPR||this._flags.last_token.type===p.EQUALS||this._flags.last_token.type===p.OPERATOR?this.start_of_object_property()||this.allow_wrap_or_preserved_newline(t):!t.text.startsWith("`")||this._flags.last_token.type!==p.END_EXPR||"]"!==t.previous.text&&")"!==t.previous.text||0!==t.newlines?this.print_newline():this._output.space_before_token=!0)),this.print_token(t)},e.prototype.handle_equals=function(t){this.start_of_statement(t)||this.handle_whitespace_and_comments(t),this._flags.declaration_statement&&(this._flags.declaration_assignment=!0),this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0},e.prototype.handle_comma=function(t){this.handle_whitespace_and_comments(t,!0),this.print_token(t),this._output.space_before_token=!0,this._flags.declaration_statement?(A(this._flags.parent.mode)&&(this._flags.declaration_assignment=!1),this._flags.declaration_assignment?(this._flags.declaration_assignment=!1,this.print_newline(!1,!0)):this._options.comma_first&&this.allow_wrap_or_preserved_newline(t)):this._flags.mode===s||this._flags.mode===h&&this._flags.parent.mode===s?(this._flags.mode===h&&this.restore_mode(),this._flags.inline_frame||this.print_newline()):this._options.comma_first&&this.allow_wrap_or_preserved_newline(t)},e.prototype.handle_operator=function(t){var e,n,i,_,s,a,r="*"===t.text&&(c(this._flags.last_token,["function","yield"])||l(this._flags.last_token.type,[p.START_BLOCK,p.COMMA,p.END_BLOCK,p.SEMICOLON])),u=l(t.text,["-","+"])&&(l(this._flags.last_token.type,[p.START_BLOCK,p.START_EXPR,p.EQUALS,p.OPERATOR])||l(this._flags.last_token.text,O)||","===this._flags.last_token.text);if(this.start_of_statement(t)||this.handle_whitespace_and_comments(t,!r),"*"!==t.text||this._flags.last_token.type!==p.DOT)if("::"!==t.text)if(l(t.text,["-","+"])&&this.start_of_object_property())this.print_token(t);else{if(this._flags.last_token.type===p.OPERATOR&&l(this._options.operator_position,g)&&this.allow_wrap_or_preserved_newline(t),":"===t.text&&this._flags.in_case)return this.print_token(t),this._flags.in_case=!1,this._flags.case_body=!0,void(this._tokens.peek().type!==p.START_BLOCK?(this.indent(),this.print_newline(),this._flags.case_block=!1):(this._flags.case_block=!0,this._output.space_before_token=!0));if(a=!(n=e=!0),":"===t.text?0===this._flags.ternary_depth?e=!1:(--this._flags.ternary_depth,a=!0):"?"===t.text&&(this._flags.ternary_depth+=1),!u&&!r&&this._options.preserve_newlines&&l(t.text,T))switch(_=(i=":"===t.text)&&a,s=i&&!a,this._options.operator_position){case f.before_newline:return this._output.space_before_token=!s,this.print_token(t),i&&!_||this.allow_wrap_or_preserved_newline(t),void(this._output.space_before_token=!0);case f.after_newline:return this._output.space_before_token=!0,!i||_?this._tokens.peek().newlines?this.print_newline(!1,!0):this.allow_wrap_or_preserved_newline(t):this._output.space_before_token=!1,this.print_token(t),void(this._output.space_before_token=!0);case f.preserve_newline:return s||this.allow_wrap_or_preserved_newline(t),e=!(this._output.just_added_newline()||s),this._output.space_before_token=e,this.print_token(t),void(this._output.space_before_token=!0)}r?(this.allow_wrap_or_preserved_newline(t),e=!1,n=(a=this._tokens.peek())&&l(a.type,[p.WORD,p.RESERVED]) +):"..."===t.text?(this.allow_wrap_or_preserved_newline(t),e=this._flags.last_token.type===p.START_BLOCK,n=!1):(l(t.text,["--","++","!","~"])||u)&&(this._flags.last_token.type!==p.COMMA&&this._flags.last_token.type!==p.START_EXPR||this.allow_wrap_or_preserved_newline(t),n=e=!1,!t.newlines||"--"!==t.text&&"++"!==t.text&&"~"!==t.text||((r=c(this._flags.last_token,d)&&t.newlines)&&(this._previous_flags.if_block||this._previous_flags.else_block)&&this.restore_mode(),this.print_newline(r,!0)),";"===this._flags.last_token.text&&A(this._flags.mode)&&(e=!0),this._flags.last_token.type===p.RESERVED?e=!0:this._flags.last_token.type===p.END_EXPR?e=!("]"===this._flags.last_token.text&&("--"===t.text||"++"===t.text)):this._flags.last_token.type===p.OPERATOR&&(e=l(t.text,["--","-","++","+"])&&l(this._flags.last_token.text,["--","-","++","+"]),l(t.text,["+","-"])&&l(this._flags.last_token.text,["--","++"])&&(n=!0)),(this._flags.mode!==o||this._flags.inline_frame)&&this._flags.mode!==h||"{"!==this._flags.last_token.text&&";"!==this._flags.last_token.text||this.print_newline()),this._output.space_before_token=this._output.space_before_token||e,this.print_token(t),this._output.space_before_token=n}else this.print_token(t);else this.print_token(t)},e.prototype.handle_block_comment=function(t,e){return this._output.raw?(this._output.add_raw_token(t),void(t.directives&&"end"===t.directives.preserve&&(this._output.raw=this._options.test_output_raw))):t.directives?(this.print_newline(!1,e),this.print_token(t),"start"===t.directives.preserve&&(this._output.raw=!0),void this.print_newline(!1,!0)):void(x.newline.test(t.text)||t.newlines?this.print_block_commment(t,e):(this._output.space_before_token=!0,this.print_token(t),this._output.space_before_token=!0))},e.prototype.print_block_commment=function(t,e){var n,i,_,s=function(t){for(var e=[],n=(t=t.replace(x.allLineBreaks,"\n")).indexOf("\n");-1!==n;)e.push(t.substring(0,n)),n=(t=t.substring(n+1)).indexOf("\n");return t.length&&e.push(t),e}(t.text),a=t.whitespace_before,r=a.length;if(this.print_newline(!1,e),this.print_token_line_indentation(t),this._output.add_token(s[0]),this.print_newline(!1,e),1this.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&(this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice( +this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count,this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty()?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g,"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0),1>> === !== &&= ??= ||= << && >= ** != == <= >> || ?? |> < / - + > : & % ? ^ | *".split(" "),s=(s="\\?\\.(?!\\d) "+(s=(s=">>>= ... >>= <<= === >>> !== **= &&= ??= ||= => ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> = ! ? > < : / ^ - + * & % ~ |").replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"))).replace(/ /g,"|"),c=new RegExp(s),s=(a="continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export".split(",")).concat(["do","in","of","else","get","set","new","catch","finally","typeof","yield","async","await","from","as","class","extends"]),d=new RegExp("^(?:"+s.join("|")+")$"),((s=function(t,e){ -g.call(this,t,e),this._patterns.whitespace=this._patterns.whitespace.matching(/\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff/.source,/\u2028\u2029/.source),t=new b(this._input),e=new m(this._input).read_options(this._options),this.__patterns={template:e,identifier:e.starting_with(h.identifier).matching(h.identifierMatch),number:t.matching(n),punct:t.matching(c),comment:t.starting_with(/\/\//).until(/[\n\r\u2028\u2029]/),block_comment:t.starting_with(/\/\*/).until_after(/\*\//),html_comment_start:t.matching(//),include:t.starting_with(/#include/).until_after(h.lineBreak),shebang:t.starting_with(/#!/).until_after(h.lineBreak),xml:t.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[^}]+?}|!\[CDATA\[[^\]]*?\]\]|)(\s*{[^}]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{([^{}]|{[^}]+?})+?}))*\s*(\/?)\s*>/),single_quote:e.until(/['\\\n\r\u2028\u2029]/),double_quote:e.until(/["\\\n\r\u2028\u2029]/),template_text:e.until(/[`\\$]/),template_expression:e.until(/[`}\\]/)}}).prototype=new g)._is_comment=function(t){return t.type===o.COMMENT||t.type===o.BLOCK_COMMENT||t.type===o.UNKNOWN},s.prototype._is_opening=function(t){return t.type===o.START_BLOCK||t.type===o.START_EXPR},s.prototype._is_closing=function(t,e){return(t.type===o.END_BLOCK||t.type===o.END_EXPR)&&e&&("]"===t.text&&"["===e.text||")"===t.text&&"("===e.text||"}"===t.text&&"{"===e.text)},s.prototype._reset=function(){_=!1},s.prototype._get_next_token=function(t,e){var n;return this._readWhitespace(),null===(n=this._input.peek())?this._create_token(o.EOF,""):this._read_non_javascript(n)||this._read_string(n)||this._read_word(t)||this._read_singles(n)||this._read_comment(n)||this._read_regexp(n,t)||this._read_xml(n,t)||this._read_punctuation()||this._create_token(o.UNKNOWN,this._input.next())},s.prototype._read_word=function(t){var e=this.__patterns.identifier.read();return""!==e?(e=e.replace(h.allLineBreaks,"\n"),t.type!==o.DOT&&(t.type!==o.RESERVED||"set"!==t.text&&"get"!==t.text)&&d.test(e)?"in"!==e&&"of"!==e||t.type!==o.WORD&&t.type!==o.STRING?this._create_token(o.RESERVED,e):this._create_token(o.OPERATOR,e):this._create_token(o.WORD,e)):""!==(e=this.__patterns.number.read())?this._create_token(o.WORD,e):void 0},s.prototype._read_singles=function(t){var e=null;return"("===t||"["===t?e=this._create_token(o.START_EXPR,t):")"===t||"]"===t?e=this._create_token(o.END_EXPR,t):"{"===t?e=this._create_token(o.START_BLOCK,t):"}"===t?e=this._create_token(o.END_BLOCK,t):";"===t?e=this._create_token(o.SEMICOLON,t):"."===t&&l.test(this._input.peek(1))?e=this._create_token(o.DOT,t):","===t&&(e=this._create_token(o.COMMA,t)),e&&this._input.next(),e},s.prototype._read_punctuation=function(){var t=this.__patterns.punct.read();if(""!==t)return"="===t?this._create_token(o.EQUALS,t):"?."===t?this._create_token(o.DOT,t):this._create_token(o.OPERATOR,t)},s.prototype._read_non_javascript=function(t){var e,n="";if("#"===t){if(this._is_first_token()&&(n=this.__patterns.shebang.read()))return this._create_token(o.UNKNOWN,n.trim()+"\n");if(n=this.__patterns.include.read())return this._create_token(o.UNKNOWN,n.trim()+"\n");if(t=this._input.next(),e="#",this._input.hasNext()&&this._input.testChar(p)){for(;e+=t=this._input.next(),this._input.hasNext()&&"#"!==t&&"="!==t;);return"#"===t||("["===this._input.peek()&&"]"===this._input.peek(1)?(e+="[]",this._input.next(),this._input.next()):"{"===this._input.peek()&&"}"===this._input.peek(1)&&(e+="{}",this._input.next(),this._input.next())),this._create_token(o.WORD,e)}this._input.back()}else if("<"===t&&this._is_first_token()){if(n=this.__patterns.html_comment_start.read()){for(;this._input.hasNext()&&!this._input.testChar(h.newline);)n+=this._input.next();return _=!0,this._create_token(o.COMMENT,n)}}else if(_&&"-"===t&&(n=this.__patterns.html_comment_end.read()))return _=!1,this._create_token(o.COMMENT,n);return null},s.prototype._read_comment=function(t){var e,n=null;return"/"===t&&(t="","*"===this._input.peek(1)?(t=this.__patterns.block_comment.read(),(e=i.get_directives(t))&&"start"===e.ignore&&(t+=i.readIgnored(this._input)),t=t.replace(h.allLineBreaks,"\n"),(n=this._create_token(o.BLOCK_COMMENT,t)).directives=e):"/"===this._input.peek(1)&&(t=this.__patterns.comment.read(),n=this._create_token(o.COMMENT,t))),n},s.prototype._read_string=function(t){var e;return"`"===t||"'"===t||'"'===t?(e=this._input.next(),this.has_char_escapes=!1,e+="`"===t?this._read_string_recursive("`",!0,"${"):this._read_string_recursive(t),this.has_char_escapes&&this._options.unescape_strings&&(e=function(t){var e="",n=0,i=new f(t),_=null;for(;i.hasNext();)if((_=i.match(/([\s]|[^\\]|\\\\)+/g))&&(e+=_[0]),"\\"===i.peek()){if(i.next(),"x"===i.peek())_=i.match(/x([0-9A-Fa-f]{2})/g);else{if("u"!==i.peek()){e+="\\",i.hasNext()&&(e+=i.next());continue}_=i.match(/u([0-9A-Fa-f]{4})/g)}if(!_)return t;if(126<(n=parseInt(_[1],16))&&n<=255&&0===_[0].indexOf("x"))return t;e+=0<=n&&n<32?"\\"+_[0]:34===n||39===n||92===n?"\\"+String.fromCharCode(n):String.fromCharCode(n)}return e}(e)),this._input.peek()===t&&(e+=this._input.next()),e=e.replace(h.allLineBreaks,"\n"),this._create_token(o.STRING,e)):null},s.prototype._allow_regexp_or_xml=function(t){return t.type===o.RESERVED&&u(t.text,["return","case","throw","else","do","typeof","yield"])||t.type===o.END_EXPR&&")"===t.text&&t.opened.previous.type===o.RESERVED&&u(t.opened.previous.text,["if","while","for"])||u(t.type,[o.COMMENT,o.START_EXPR,o.START_BLOCK,o.START,o.END_BLOCK,o.OPERATOR,o.EQUALS,o.EOF,o.SEMICOLON,o.COMMA])},s.prototype._read_regexp=function(t,e){var n,i,_;if("/"===t&&this._allow_regexp_or_xml(e)){for(n=this._input.next(),_=i=!1;this._input.hasNext()&&(i||_||this._input.peek()!==t)&&!this._input.testChar(h.newline);)n+=this._input.peek(),i?i=!1:(i="\\"===this._input.peek(),"["===this._input.peek()?_=!0:"]"===this._input.peek()&&(_=!1)),this._input.next();return this._input.peek()===t&&(n=(n+=this._input.next())+this._input.read( -h.identifier)),this._create_token(o.STRING,n)}return null},s.prototype._read_xml=function(t,e){var n,i,_,s,a,u,r;if(this._options.e4x&&"<"===t&&this._allow_regexp_or_xml(e)&&(n="",i=this.__patterns.xml.read_match())){for(s=0===(_=i[2].replace(/^{\s+/,"{").replace(/\s+}$/,"}")).indexOf("{"),a=0;i&&(u=!!i[1],r=i[2],!(!!i[i.length-1]||"![CDATA["===r.slice(0,8))&&(r===_||s&&r.replace(/^{\s+/,"{").replace(/\s+}$/,"}"))&&(u?--a:++a),n+=i[0],!(a<=0));)i=this.__patterns.xml.read_match();return i||(n+=this._input.match(/[\s\S]*/g)[0]),n=n.replace(h.allLineBreaks,"\n"),this._create_token(o.STRING,n)}return null},s.prototype._read_string_recursive=function(t,e,n){var i,_,s,a;for("'"===t?_=this.__patterns.single_quote:'"'===t?_=this.__patterns.double_quote:"`"===t?_=this.__patterns.template_text:"}"===t&&(_=this.__patterns.template_expression),s=_.read(),a="";this._input.hasNext();){if((a=this._input.next())===t||!e&&h.newline.test(a)){this._input.back();break}"\\"===a&&this._input.hasNext()?("x"===(i=this._input.peek())||"u"===i?this.has_char_escapes=!0:"\r"===i&&"\n"===this._input.peek(1)&&this._input.next(),a+=this._input.next()):n&&("${"===n&&"$"===a&&"{"===this._input.peek()&&(a+=this._input.next()),n===a&&(a+="`"===t?this._read_string_recursive("}",e,"`"):this._read_string_recursive("`",e,"${"),this._input.hasNext()&&(a+=this._input.next()))),s+=a+=_.read()}return s},t.exports.Tokenizer=s,t.exports.TOKEN=o,t.exports.positionable_operators=e.slice(),t.exports.line_starters=a.slice()},function(t){var i=RegExp.prototype.hasOwnProperty("sticky");function e(t){this.__input=t||"",this.__input_length=this.__input.length,this.__position=0}e.prototype.restart=function(){this.__position=0},e.prototype.back=function(){0=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},function(t,e,n){var i=n(8).InputScanner,s=n(3).Token,a=n(10).TokenStream,_=n(11).WhitespacePattern,u={START:"TK_START",RAW:"TK_RAW",EOF:"TK_EOF"},n=function(t,e){this._input=new i(t),this._options=e||{},this.__tokens=null,this._patterns={},this._patterns.whitespace=new _(this._input)};n.prototype.tokenize=function(){var t,e,n,i,_;for(this._input.restart(),this.__tokens=new a,this._reset(),e=new s(u.START,""),n=null,i=[],_=new a;e.type!==u.EOF;){for(t=this._get_next_token(e,n);this._is_comment(t);)_.add(t),t=this._get_next_token(e,n);_.isEmpty()||(t.comments_before=_,_=new a),t.parent=n,this._is_opening(t)?(i.push(n),n=t):n&&this._is_closing(t,n)&&((t.opened=n).closed=t,n=i.pop(),t.parent=n),(t.previous=e).next=t,this.__tokens.add(t),e=t}return this.__tokens},n.prototype._is_first_token=function(){return this.__tokens.isEmpty()},n.prototype._reset=function(){},n.prototype._get_next_token=function(t,e){this._readWhitespace();var n=this._input.read(/.+/g);return n?this._create_token(u.RAW,n):this._create_token(u.EOF,"")},n.prototype._is_comment=function(t){return!1},n.prototype._is_opening=function(t){return!1},n.prototype._is_closing=function(t,e){return!1},n.prototype._create_token=function(t,e){return new s(t,e,this._patterns.whitespace.newline_count,this._patterns.whitespace.whitespace_before_token)},n.prototype._readWhitespace=function(){return this._patterns.whitespace.read()},t.exports.Tokenizer=n,t.exports.TOKEN=u},function(t){function e(t){this.__tokens=[],this.__tokens_length=this.__tokens.length,this.__position=0,this.__parent_token=t}e.prototype.restart=function(){this.__position=0},e.prototype.isEmpty=function(){return 0===this.__tokens_length},e.prototype.hasNext=function(){return this.__position/),erb:e.starting_with(/<%[^%]/).until_after(/[^%]%>/),django:e.starting_with(/{%/).until_after(/%}/),django_value:e.starting_with(/{{/).until_after(/}}/),django_comment:e.starting_with(/{#/).until_after(/#}/),smarty:e.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),smarty_comment:e.starting_with(/{\*/).until_after(/\*}/),smarty_literal:e.starting_with(/{literal}/).until_after(/{\/literal}/)}}(s.prototype=new i)._create=function(){return new s(this._input,this)},s.prototype._update=function(){this.__set_templated_pattern()},s.prototype.disable=function(t){var e=this._create();return e._disabled[t]=!0,e._update(),e},s.prototype.read_options=function(t){var e,n=this._create();for(e in _)n._disabled[e]=-1===t.templating.indexOf(e);return n._update(),n},s.prototype.exclude=function(t){var e=this._create();return e._excluded[t]=!0,e._update(),e},s.prototype.read=function(){for(var t="",t=this._match_pattern?this._input.read(this._starting_pattern):this._input.read(this._starting_pattern,this.__template_pattern),e=this._read_template();e;)this._match_pattern?e+=this._input.read(this._match_pattern):e+=this._input.readUntil(this.__template_pattern),t+=e,e=this._read_template();return this._until_after&&(t+=this._input.readUntilAfter(this._until_pattern)),t},s.prototype.__set_templated_pattern=function(){var t=[];this._disabled.php||t.push(this.__patterns.php._starting_pattern.source),this._disabled.handlebars||t.push(this.__patterns.handlebars._starting_pattern.source),this._disabled.erb||t.push(this.__patterns.erb._starting_pattern.source),this._disabled.django||(t.push(this.__patterns.django._starting_pattern.source),t.push(this.__patterns.django_value._starting_pattern.source),t.push(this.__patterns.django_comment._starting_pattern.source)),this._disabled.smarty||t.push(this.__patterns.smarty._starting_pattern.source),this._until_pattern&&t.push(this._until_pattern.source),this.__template_pattern=this._input.get_regexp("(?:"+t.join("|")+")")},s.prototype._read_template=function(){var t,e="",n=this._input.peek();return"<"===n?(t=this._input.peek(1),this._disabled.php||this._excluded.php||"?"!==t||(e=e||this.__patterns.php.read()),this._disabled.erb||this._excluded.erb||"%"!==t||(e=e||this.__patterns.erb.read())):"{"===n&&(this._disabled.handlebars||this._excluded.handlebars||(e=(e=(e=e||this.__patterns.handlebars_comment.read())||this.__patterns.handlebars_unescaped.read())||this.__patterns.handlebars.read()),this._disabled.django||(this._excluded.django||this._excluded.handlebars||(e=e||this.__patterns.django_value.read()), -this._excluded.django||(e=(e=e||this.__patterns.django_comment.read())||this.__patterns.django.read())),this._disabled.smarty||this._disabled.django&&this._disabled.handlebars&&(e=(e=(e=e||this.__patterns.smarty_comment.read())||this.__patterns.smarty_literal.read())||this.__patterns.smarty.read())),e},t.exports.TemplatablePattern=s}],i={};t=function _(t){var e=i[t];return e!==undefined||(e=i[t]={exports:{}},n[t](e,e.exports,_)),e.exports}(0),s=t}(),t=s,void 0!==r?r.js_beautify=t:"undefined"!=typeof window?window.js_beautify=t:"undefined"!=typeof global&&(global.js_beautify=t),function(){"use strict";var t,n=[,,function(t){function _(t){this.__parent=t,this.__character_count=0,this.__indent_count=-1,this.__alignment_count=0,this.__wrap_point_index=0,this.__wrap_point_character_count=0,this.__wrap_point_indent_count=-1,this.__wrap_point_alignment_count=0,this.__items=[]}function n(t,e){this.__cache=[""],this.__indent_size=t.indent_size,this.__indent_string=t.indent_char,t.indent_with_tabs||(this.__indent_string=new Array(t.indent_size+1).join(t.indent_char)),e=e||"",0this.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&(this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice(this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count,this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty()?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g,"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0), -1=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},,,,,function(t){function e(t,e){t="string"==typeof t?t:t.source,e="string"==typeof e?e:e.source,this.__directives_block_pattern=new RegExp(t+/ beautify( \w+[:]\w+)+ /.source+e,"g"),this.__directive_pattern=/ (\w+)[:](\w+)/g,this.__directives_end_ignore_pattern=new RegExp(t+/\sbeautify\signore:end\s/.source+e,"g")}e.prototype.get_directives=function(t){var e,n;if(!t.match(this.__directives_block_pattern))return null;for(e={},this.__directive_pattern.lastIndex=0,n=this.__directive_pattern.exec(t);n;)e[n[1]]=n[2],n=this.__directive_pattern.exec(t);return e},e.prototype.readIgnored=function(t){return t.readUntilAfter(this.__directives_end_ignore_pattern)},t.exports.Directives=e},,function(t,e,n){var i=n(16).Beautifier,_=n(17).Options;t.exports=function(t,e){return new i(t,e).beautify()},t.exports.defaultOptions=function(){return new _}},function(t,_,e){var n=e(17).Options,b=e(2).Output,m=e(8).InputScanner,e=e(13).Directives,y=new e(/\/\*/,/\*\//),w=/\r\n|[\r\n]/,k=/\r\n|[\r\n]/g,x=/\s/,v=/(?:\s|\n)+/g,E=/\/\*(?:[\s\S]*?)((?:\*\/)|$)/g,O=/\/\/(?:[^\n\r\u2028\u2029]*)/g;function i(t,e){this._source_text=t||"",this._options=new n(e),this._ch=null,this._input=null,this.NESTED_AT_RULE={"@page":!0,"@font-face":!0,"@keyframes":!0,"@media":!0,"@supports":!0,"@document":!0},this.CONDITIONAL_GROUP_RULE={"@media":!0,"@supports":!0,"@document":!0},this.NON_SEMICOLON_NEWLINE_PROPERTY=["grid-template-areas","grid-template"]}i.prototype.eatString=function(t){var e="";for(this._ch=this._input.next();this._ch;){if(e+=this._ch,"\\"===this._ch)e+=this._input.next();else if(-1!==t.indexOf(this._ch)||"\n"===this._ch)break;this._ch=this._input.next()}return e},i.prototype.eatWhitespace=function(t){for(var e=x.test(this._input.peek()),n=0;x.test(this._input.peek());)this._ch=this._input.next(),t&&"\n"===this._ch&&(0===n||n=this._nestedLevel):this._indentLevel>=this._nestedLevel-1,this._options.newline_between_rules&&n&&this._output.previous_line&&"{"!==this._output.previous_line.item(-1)&&this._output.ensure_empty_line_above("/",","),this._output.space_before_token=!0,"expand"===this._options.brace_style?(this._output.add_new_line(),this.print_string(this._ch),this.indent(),this._output.set_indent(this._indentLevel)):("("===u?this._output.space_before_token=!1:","!==u&&this.indent(),this.print_string(this._ch)),this.eatWhitespace(!0),this._output.add_new_line();else if("}"===this._ch)this.outdent(),this._output.add_new_line(),"{"===u&&this._output.trim(!0),s=l=!1,i&&(this.outdent(),i=!1),this.print_string(this._ch),n=!1,this._nestedLevel&&this._nestedLevel--,this.eatWhitespace(!0),this._output.add_new_line(),this._options.newline_between_rules&&!this._output.just_added_blankline()&&"}"!==this._input.peek()&&this._output.add_new_line(!0),")"===this._input.peek()&&(this._output.trim(!0),"expand"===this._options.brace_style&&this._output.add_new_line(!0));else if(":"===this._ch){for(g=0;g"!==this._ch&&"+"!==this._ch&&"~"!==this._ch||i||0!==e?"]"===this._ch?this.print_string(this._ch):"["===this._ch?(this.preserveSingleSpace(a),this.print_string(this._ch)):"="===this._ch?(this.eatWhitespace(),this.print_string("="),x.test(this._ch)&&(this._ch="")):"!"!==this._ch||this._input.lookBack("\\")?(this.preserveSingleSpace('"'===u||"'"===u||a),this.print_string(this._ch),!this._output.just_added_newline()&&"\n"===this._input.peek()&&f&&this._output.add_new_line()):(this._output.space_before_token=!0,this.print_string(this._ch)):this._options.space_around_combinator?(this._output.space_before_token=!0,this.print_string(this._ch),this._output.space_before_token=!0):(this.print_string(this._ch),this.eatWhitespace(),this._ch&&x.test(this._ch)&&(this._ch=""))}return this._output.get_code(h)},t.exports.Beautifier=i},function(t,e,n){var i=n(6).Options;function _(t){var e,n;for(i.call(this,t,"css"),this.selector_separator_newline=this._get_boolean("selector_separator_newline",!0),this.newline_between_rules=this._get_boolean("newline_between_rules",!0),t=this._get_boolean("space_around_selector_separator"),this.space_around_combinator=this._get_boolean("space_around_combinator")||t,e=this._get_selection_list("brace_style",["collapse","expand","end-expand","none","preserve-inline"]),this.brace_style="collapse",n=0;nthis.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&(this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice(this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count,this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty( -)?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g,"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0),1=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},function(t,e,n){var i=n(8).InputScanner,s=n(3).Token,a=n(10).TokenStream,_=n(11).WhitespacePattern,u={START:"TK_START",RAW:"TK_RAW",EOF:"TK_EOF"},n=function(t,e){this._input=new i(t),this._options=e||{},this.__tokens=null,this._patterns={},this._patterns.whitespace=new _(this._input)};n.prototype.tokenize=function(){var t,e,n,i,_;for(this._input.restart(),this.__tokens=new a,this._reset(),e=new s(u.START,""),n=null,i=[],_=new a;e.type!==u.EOF;){for(t=this._get_next_token(e,n);this._is_comment(t);)_.add(t),t=this._get_next_token(e,n);_.isEmpty()||(t.comments_before=_,_=new a),t.parent=n,this._is_opening(t)?(i.push(n),n=t):n&&this._is_closing(t,n)&&((t.opened=n).closed=t,n=i.pop(),t.parent=n),(t.previous=e).next=t,this.__tokens.add(t),e=t}return this.__tokens},n.prototype._is_first_token=function(){return this.__tokens.isEmpty()},n.prototype._reset=function(){},n.prototype._get_next_token=function(t,e){this._readWhitespace();var n=this._input.read(/.+/g);return n?this._create_token(u.RAW,n):this._create_token(u.EOF,"")},n.prototype._is_comment=function(t){return!1},n.prototype._is_opening=function(t){return!1},n.prototype._is_closing=function(t,e){return!1},n.prototype._create_token=function(t,e){return new s(t,e,this._patterns.whitespace.newline_count,this._patterns.whitespace.whitespace_before_token)},n.prototype._readWhitespace=function(){return this._patterns.whitespace.read()},t.exports.Tokenizer=n,t.exports.TOKEN=u},function(t){function e(t){this.__tokens=[],this.__tokens_length=this.__tokens.length,this.__position=0,this.__parent_token=t}e.prototype.restart=function(){this.__position=0},e.prototype.isEmpty=function(){return 0===this.__tokens_length},e.prototype.hasNext=function(){return this.__position/),erb:e.starting_with(/<%[^%]/).until_after(/[^%]%>/),django:e.starting_with(/{%/).until_after(/%}/),django_value:e.starting_with(/{{/).until_after(/}}/),django_comment:e.starting_with(/{#/).until_after(/#}/),smarty:e.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),smarty_comment:e.starting_with(/{\*/).until_after(/\*}/),smarty_literal:e.starting_with(/{literal}/).until_after(/{\/literal}/)}}(s.prototype=new i)._create=function(){return new s(this._input,this)},s.prototype._update=function(){this.__set_templated_pattern()},s.prototype.disable=function(t){var e=this._create();return e._disabled[t]=!0,e._update(),e},s.prototype.read_options=function(t){var e,n=this._create();for(e in _)n._disabled[e]=-1===t.templating.indexOf(e);return n._update(),n},s.prototype.exclude=function(t){var e=this._create();return e._excluded[t]=!0,e._update(),e},s.prototype.read=function(){for(var t="",t=this._match_pattern?this._input.read(this._starting_pattern):this._input.read(this._starting_pattern,this.__template_pattern),e=this._read_template();e;)this._match_pattern?e+=this._input.read(this._match_pattern):e+=this._input.readUntil(this.__template_pattern),t+=e,e=this._read_template();return this._until_after&&(t+=this._input.readUntilAfter(this._until_pattern)),t},s.prototype.__set_templated_pattern=function(){var t=[];this._disabled.php||t.push(this.__patterns.php._starting_pattern.source),this._disabled.handlebars||t.push(this.__patterns.handlebars._starting_pattern.source),this._disabled.erb||t.push(this.__patterns.erb._starting_pattern.source),this._disabled.django||(t.push(this.__patterns.django._starting_pattern.source),t.push(this.__patterns.django_value._starting_pattern.source),t.push(this.__patterns.django_comment._starting_pattern.source)),this._disabled.smarty||t.push(this.__patterns.smarty._starting_pattern.source),this._until_pattern&&t.push(this._until_pattern.source),this.__template_pattern=this._input.get_regexp("(?:"+t.join("|")+")")},s.prototype._read_template=function(){var t,e="",n=this._input.peek();return"<"===n?(t=this._input.peek(1),this._disabled.php||this._excluded.php||"?"!==t||(e=e||this.__patterns.php.read()),this._disabled.erb||this._excluded.erb||"%"!==t||(e=e||this.__patterns.erb.read())):"{"===n&&(this._disabled.handlebars||this._excluded.handlebars||(e=(e=(e=e||this.__patterns.handlebars_comment.read())||this.__patterns.handlebars_unescaped.read())||this.__patterns.handlebars.read()),this._disabled.django||(this._excluded.django||this._excluded.handlebars||(e=e||this.__patterns.django_value.read()),this._excluded.django||(e=(e=e||this.__patterns.django_comment.read())||this.__patterns.django.read())),this._disabled.smarty||this._disabled.django&&this._disabled.handlebars&&(e=(e=( -e=e||this.__patterns.smarty_comment.read())||this.__patterns.smarty_literal.read())||this.__patterns.smarty.read())),e},t.exports.TemplatablePattern=s},,,,function(t,e,n){var _=n(19).Beautifier,i=n(20).Options;t.exports=function(t,e,n,i){return new _(t,e,n,i).beautify()},t.exports.defaultOptions=function(){return new i}},function(e,n,t){var _,s,o,i,u,r=t(20).Options,d=t(2).Output,f=t(21).Tokenizer,h=t(21).TOKEN,g=/\r\n|[\r\n]/,b=/\r\n|[\r\n]/g,p=function(t,e){this.indent_level=0,this.alignment_size=0,this.max_preserve_newlines=t.max_preserve_newlines,this.preserve_newlines=t.preserve_newlines,this._output=new d(t,e)};function a(t,e){return-1!==e.indexOf(t)}function m(t,e,n){this.parent=t||null,this.tag=e?e.tag_name:"",this.indent_level=n||0,this.parser_token=e||null}function l(t){this._printer=t,this._current_frame=null}function c(t,e,n,i){this._source_text=t||"",e=e||{},this._js_beautify=n,this._css_beautify=i,this._tag_stack=null;t=new r(e,"html");this._options=t,this._is_wrap_attributes_force="force"===this._options.wrap_attributes.substr(0,"force".length),this._is_wrap_attributes_force_expand_multiline="force-expand-multiline"===this._options.wrap_attributes,this._is_wrap_attributes_force_aligned="force-aligned"===this._options.wrap_attributes,this._is_wrap_attributes_aligned_multiple="aligned-multiple"===this._options.wrap_attributes,this._is_wrap_attributes_preserve="preserve"===this._options.wrap_attributes.substr(0,"preserve".length),this._is_wrap_attributes_preserve_aligned="preserve-aligned"===this._options.wrap_attributes}p.prototype.current_line_has_match=function(t){return this._output.current_line.has_match(t)},p.prototype.set_space_before_token=function(t,e){this._output.space_before_token=t,this._output.non_breaking_space=e},p.prototype.set_wrap_point=function(){this._output.set_indent(this.indent_level,this.alignment_size),this._output.set_wrap_point()},p.prototype.add_raw_token=function(t){this._output.add_raw_token(t)},p.prototype.print_preserved_newlines=function(t){var e,n=0;for(t.type!==h.TEXT&&t.previous.type!==h.TEXT&&(n=t.newlines?1:0),this.preserve_newlines&&(n=t.newlines|]]>)$/.exec(i)))return void t.add_raw_token(e);s=u+n[1]+"\n",i=n[4],n[5]&&(a=u+n[5]),i=i.replace(/\n[ \t]*$/,""),(n[2]||-1!==n[3].indexOf("\n"))&&(n=n[3].match(/[ \t]+$/))&&(e.whitespace_before=n[0])}i=i&&(_?((n=function(){this.eol="\n"}).prototype=this._options.raw_options,_(u+i,new n)):u+(i=(n=e.whitespace_before)?i.replace(new RegExp("\n("+n+")?","g"),"\n"):i).replace(/\n/g,"\n"+u)),s&&(i=i?s+i+"\n"+a:s+a),t.print_newline(!1),i&&(e.text=i,e.whitespace_before="",e.newlines=0,t.add_raw_token(e),t.print_newline(!0))}},c.prototype._handle_tag_open=function(t,e,n,i){var _=this._get_tag_open_token(e);return!n.is_unformatted&&!n.is_content_unformatted||n.is_empty_element||e.type!==h.TAG_OPEN||0!==e.text.indexOf("]*)/),this.tag_check=n?n[1]:""):(n=e.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/),this.tag_check=n?n[1]:"",(e.text.startsWith("{{#>")||e.text.startsWith("{{~#>"))&&">"===this.tag_check[0]&&(">"===this.tag_check&&null!==e.next?this.tag_check=e.next.text.split(" ")[0]:this.tag_check=e.text.split(">")[1])),this.tag_check=this.tag_check.toLowerCase(),e.type===h.COMMENT&&(this.tag_complete=!0),this.is_start_tag="/"!==this.tag_check.charAt(0),this.tag_name=this.is_start_tag?this.tag_check:this.tag_check.substr(1),this.is_end_tag=!this.is_start_tag||e.closed&&"/>"===e.closed.text,t=2,"{"===this.tag_start_char&&3<=this.text.length&&"~"===this.text.charAt(2)&&(t=3),this.is_end_tag=this.is_end_tag||"{"===this.tag_start_char&&(this.text.length<3||/[^#\^]/.test(this.text.charAt(t)))):this.tag_complete=!0},c.prototype._get_tag_open_token=function(t){t=new o(this._tag_stack.get_parser_token(),t);return t.alignment_size=this._options.wrap_attributes_indent_size,t.is_end_tag=t.is_end_tag||a(t.tag_check,this._options.void_elements),t.is_empty_element=t.tag_complete||t.is_start_tag&&t.is_end_tag,t.is_unformatted=!t.tag_complete&&a(t.tag_check,this._options.unformatted),t.is_content_unformatted=!t.is_empty_element&&a(t.tag_check,this._options.content_unformatted),t.is_inline_element=a(t.tag_name,this._options.inline)||t.tag_name.includes("-")||"{"===t.tag_start_char,t},c.prototype._set_tag_position=function(t,e,n,i,_){n.is_empty_element||(n.is_end_tag?n.start_tag_token=this._tag_stack.try_pop(n.tag_name):(this._do_optional_end_element(n)&&(n.is_inline_element||t.print_newline(!1)),this._tag_stack.record_tag(n),"script"!==n.tag_name&&"style"!==n.tag_name||n.is_unformatted||n.is_content_unformatted||(n.custom_beautifier_name=s(n.tag_check,e)))),a(n.tag_check,this._options.extra_liners)&&(t.print_newline(!1),t._output.just_added_blankline()||t.print_newline(!0)),n.is_empty_element?("{"===n.tag_start_char&&"else"===n.tag_check&&(this._tag_stack.indent_to_tag(["if","unless","each"]),n.indent_content=!0,t.current_line_has_match(/{{#if/)||t.print_newline(!1)),"!--"===n.tag_name&&_.type===h.TAG_CLOSE&&i.is_end_tag&&-1===n.text.indexOf("\n")||(n.is_inline_element||n.is_unformatted||t.print_newline(!1),this._calcluate_parent_multiline(t,n))):n.is_end_tag?(e=!1,e=(e=n.start_tag_token&&n.start_tag_token.multiline_content)||!n.is_inline_element&&!(i.is_inline_element||i.is_unformatted)&&!(_.type===h.TAG_CLOSE&&n.start_tag_token===i)&&"TK_CONTENT"!==_.type,(e=n.is_content_unformatted||n.is_unformatted?!1:e)&&t.print_newline(!1)):(n.indent_content=!n.custom_beautifier_name,"<"===n.tag_start_char&&( -"html"===n.tag_name?n.indent_content=this._options.indent_inner_html:"head"===n.tag_name?n.indent_content=this._options.indent_head_inner_html:"body"===n.tag_name&&(n.indent_content=this._options.indent_body_inner_html)),n.is_inline_element||n.is_unformatted||"TK_CONTENT"===_.type&&!n.is_content_unformatted||t.print_newline(!1),this._calcluate_parent_multiline(t,n))},c.prototype._calcluate_parent_multiline=function(t,e){!e.parent||!t._output.just_added_newline()||(e.is_inline_element||e.is_unformatted)&&e.parent.is_inline_element||(e.parent.multiline_content=!0)},i=["address","article","aside","blockquote","details","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hr","main","nav","ol","p","pre","section","table","ul"],u=["a","audio","del","ins","map","noscript","video"],c.prototype._do_optional_end_element=function(t){var e,n=null;if(!t.is_empty_element&&t.is_start_tag&&t.parent)return"body"===t.tag_name?n=n||this._tag_stack.try_pop("head"):"li"===t.tag_name?n=n||this._tag_stack.try_pop("li",["ol","ul"]):"dd"===t.tag_name||"dt"===t.tag_name?n=(n=n||this._tag_stack.try_pop("dt",["dl"]))||this._tag_stack.try_pop("dd",["dl"]):"p"===t.parent.tag_name&&-1!==i.indexOf(t.tag_name)?(e=t.parent.parent)&&-1!==u.indexOf(e.tag_name)||(n=n||this._tag_stack.try_pop("p")):"rp"===t.tag_name||"rt"===t.tag_name?n=(n=n||this._tag_stack.try_pop("rt",["ruby","rtc"]))||this._tag_stack.try_pop("rp",["ruby","rtc"]):"optgroup"===t.tag_name?n=n||this._tag_stack.try_pop("optgroup",["select"]):"option"===t.tag_name?n=n||this._tag_stack.try_pop("option",["select","datalist","optgroup"]):"colgroup"===t.tag_name?n=n||this._tag_stack.try_pop("caption",["table"]):"thead"===t.tag_name?n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]):"tbody"===t.tag_name||"tfoot"===t.tag_name?n=(n=(n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]))||this._tag_stack.try_pop("thead",["table"]))||this._tag_stack.try_pop("tbody",["table"]):"tr"===t.tag_name?n=(n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]))||this._tag_stack.try_pop("tr",["table","thead","tbody","tfoot"]):"th"!==t.tag_name&&"td"!==t.tag_name||(n=(n=n||this._tag_stack.try_pop("td",["table","thead","tbody","tfoot","tr"]))||this._tag_stack.try_pop("th",["table","thead","tbody","tfoot","tr"])),t.parent=this._tag_stack.get_parser_token(),n},e.exports.Beautifier=c},function(t,e,n){var i=n(6).Options;function _(t){i.call(this,t,"html"),1===this.templating.length&&"auto"===this.templating[0]&&(this.templating=["django","erb","handlebars","php"]),this.indent_inner_html=this._get_boolean("indent_inner_html"),this.indent_body_inner_html=this._get_boolean("indent_body_inner_html",!0),this.indent_head_inner_html=this._get_boolean("indent_head_inner_html",!0),this.indent_handlebars=this._get_boolean("indent_handlebars",!0),this.wrap_attributes=this._get_selection("wrap_attributes",["auto","force","force-aligned","force-expand-multiline","aligned-multiple","preserve","preserve-aligned"]),this.wrap_attributes_indent_size=this._get_number("wrap_attributes_indent_size",this.indent_size),this.extra_liners=this._get_array("extra_liners",["head","body","/html"]),this.inline=this._get_array("inline",["a","abbr","area","audio","b","bdi","bdo","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","keygen","label","map","mark","math","meter","noscript","object","output","progress","q","ruby","s","samp","select","small","span","strong","sub","sup","svg","template","textarea","time","u","var","video","wbr","text","acronym","big","strike","tt"]),this.void_elements=this._get_array("void_elements",["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr","!doctype","?xml","basefont","isindex"]),this.unformatted=this._get_array("unformatted",[]),this.content_unformatted=this._get_array("content_unformatted",["pre","textarea"]),this.unformatted_content_delimiter=this._get_characters("unformatted_content_delimiter"),this.indent_scripts=this._get_selection("indent_scripts",["normal","keep","separate"])}_.prototype=new i,t.exports.Options=_},function(t,o,e){var n=e(9).Tokenizer,i=e(9).TOKEN,_=e(13).Directives,s=e(14).TemplatablePattern,a=e(12).Pattern,u={TAG_OPEN:"TK_TAG_OPEN",TAG_CLOSE:"TK_TAG_CLOSE",ATTRIBUTE:"TK_ATTRIBUTE",EQUALS:"TK_EQUALS",VALUE:"TK_VALUE",COMMENT:"TK_COMMENT",TEXT:"TK_TEXT",UNKNOWN:"TK_UNKNOWN",START:i.START,RAW:i.RAW,EOF:i.EOF},r=new _(/<\!--/,/-->/),e=function(t,e){n.call(this,t,e),this._current_tag_name="",t=new s(this._input).read_options(this._options),e=new a(this._input),this.__patterns={word:t.until(/[\n\r\t <]/),single_quote:t.until_after(/'/),double_quote:t.until_after(/"/),attribute:t.until(/[\n\r\t =>]|\/>/),element_name:t.until(/[\n\r\t >\/]/),handlebars_comment:e.starting_with(/{{!--/).until_after(/--}}/),handlebars:e.starting_with(/{{/).until_after(/}}/),handlebars_open:e.until(/[\n\r\t }]/),handlebars_raw_close:e.until(/}}/),comment:e.starting_with(//),cdata:e.starting_with(//),conditional_comment:e.starting_with(//),processing:e.starting_with(/<\?/).until_after(/\?>/)},this._options.indent_handlebars&&(this.__patterns.word=this.__patterns.word.exclude("handlebars")),this._unformatted_content_delimiter=null,this._options.unformatted_content_delimiter&&(t=this._input.get_literal_regexp(this._options.unformatted_content_delimiter),this.__patterns.unformatted_content_delimiter=e.matching(t).until_after(t))};(e.prototype=new n)._is_comment=function(t){return!1},e.prototype._is_opening=function(t){return t.type===u.TAG_OPEN},e.prototype._is_closing=function(t,e){return t.type===u.TAG_CLOSE&&e&&((">"===t.text||"/>"===t.text -)&&"<"===e.text[0]||"}}"===t.text&&"{"===e.text[0]&&"{"===e.text[1])},e.prototype._reset=function(){this._current_tag_name=""},e.prototype._get_next_token=function(t,e){var n;return this._readWhitespace(),null===(n=this._input.peek())?this._create_token(u.EOF,""):this._read_open_handlebars(n,e)||this._read_attribute(n,t,e)||this._read_close(n,e)||this._read_raw_content(n,t,e)||this._read_content_word(n)||this._read_comment_or_cdata(n)||this._read_processing(n)||this._read_open(n,e)||this._create_token(u.UNKNOWN,this._input.next())},e.prototype._read_comment_or_cdata=function(t){var e=null,n=null,i=null;return"<"===t&&("!"===this._input.peek(1)&&((n=this.__patterns.comment.read())?(i=r.get_directives(n))&&"start"===i.ignore&&(n+=r.readIgnored(this._input)):n=this.__patterns.cdata.read()),n&&((e=this._create_token(u.COMMENT,n)).directives=i)),e},e.prototype._read_processing=function(t){var e=null,n=null;return"<"===t&&(n="!"!==(t=this._input.peek(1))&&"?"!==t?n:(n=this.__patterns.conditional_comment.read())||this.__patterns.processing.read())&&((e=this._create_token(u.COMMENT,n)).directives=null),e},e.prototype._read_open=function(t,e){var n=null,i=null;return e||"<"===t&&(n=this._input.next(),"/"===this._input.peek()&&(n+=this._input.next()),n+=this.__patterns.element_name.read(),i=this._create_token(u.TAG_OPEN,n)),i},e.prototype._read_open_handlebars=function(t,e){var n=null,i=null;return e||this._options.indent_handlebars&&"{"===t&&"{"===this._input.peek(1)&&(i="!"===this._input.peek(2)?(n=(n=this.__patterns.handlebars_comment.read())||this.__patterns.handlebars.read(),this._create_token(u.COMMENT,n)):(n=this.__patterns.handlebars_open.read(),this._create_token(u.TAG_OPEN,n))),i},e.prototype._read_close=function(t,e){var n=null,i=null;return e&&("<"===e.text[0]&&(">"===t||"/"===t&&">"===this._input.peek(1))?(n=this._input.next(),"/"===t&&(n+=this._input.next()),i=this._create_token(u.TAG_CLOSE,n)):"{"===e.text[0]&&"}"===t&&"}"===this._input.peek(1)&&(this._input.next(),this._input.next(),i=this._create_token(u.TAG_CLOSE,"}}"))),i},e.prototype._read_attribute=function(t,e,n){var i=null;return n&&"<"===n.text[0]&&("="===t?i=this._create_token(u.EQUALS,this._input.next()):'"'===t||"'"===t?(n=this._input.next(),n+=('"'===t?this.__patterns.double_quote:this.__patterns.single_quote).read(),i=this._create_token(u.VALUE,n)):(t=this.__patterns.attribute.read())&&(i=e.type===u.EQUALS?this._create_token(u.VALUE,t):this._create_token(u.ATTRIBUTE,t))),i},e.prototype._is_content_unformatted=function(t){return-1===this._options.void_elements.indexOf(t)&&(-1!==this._options.content_unformatted.indexOf(t)||-1!==this._options.unformatted.indexOf(t))},e.prototype._read_raw_content=function(t,e,n){var i="";if(n&&"{"===n.text[0])i=this.__patterns.handlebars_raw_close.read();else if(e.type===u.TAG_CLOSE&&"<"===e.opened.text[0]&&"/"!==e.text[0])if("script"===(n=e.opened.text.substr(1).toLowerCase())||"style"===n){if(e=this._read_comment_or_cdata(t))return e.type=u.TEXT,e;i=this._input.readUntil(new RegExp("","ig"))}else this._is_content_unformatted(n)&&(i=this._input.readUntil(new RegExp("","ig")));return i?this._create_token(u.TEXT,i):null},e.prototype._read_content_word=function(t){var e="";if(e=(e=this._options.unformatted_content_delimiter&&t===this._options.unformatted_content_delimiter[0]?this.__patterns.unformatted_content_delimiter.read():e)||this.__patterns.word.read())return this._create_token(u.TEXT,e)},t.exports.Tokenizer=e,t.exports.TOKEN=u}],i={};t=function _(t){var e=i[t];return e!==undefined||(e=i[t]={exports:{}},n[t](e,e.exports,_)),e.exports}(18),u=t}(),n=u,void 0!==r?(_=i=r).html_beautify=function(t,e){return n(t,e,i.js_beautify,_.css_beautify)}:"undefined"!=typeof window?window.html_beautify=function(t,e){return n(t,e,window.js_beautify,window.css_beautify)}:"undefined"!=typeof global&&(global.html_beautify=function(t,e){return n(t,e,global.js_beautify,global.css_beautify)})},"@VERSION@"); \ No newline at end of file +_="\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u0620-\\u0649\\u0672-\\u06d3\\u06e7-\\u06e8\\u06fb-\\u06fc\\u0730-\\u074a\\u0800-\\u0814\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0840-\\u0857\\u08e4-\\u08fe\\u0900-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962-\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09d7\\u09df-\\u09e0\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2-\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b5f-\\u0b60\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62-\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2-\\u0ce3\\u0ce6-\\u0cef\\u0d02\\u0d03\\u0d46-\\u0d48\\u0d57\\u0d62-\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e34-\\u0e3a\\u0e40-\\u0e45\\u0e50-\\u0e59\\u0eb4-\\u0eb9\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f41-\\u0f47\\u0f71-\\u0f84\\u0f86-\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u1000-\\u1029\\u1040-\\u1049\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u170e-\\u1710\\u1720-\\u1730\\u1740-\\u1750\\u1772\\u1773\\u1780-\\u17b2\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u1920-\\u192b\\u1930-\\u193b\\u1951-\\u196d\\u19b0-\\u19c0\\u19c8-\\u19c9\\u19d0-\\u19d9\\u1a00-\\u1a15\\u1a20-\\u1a53\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1b46-\\u1b4b\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c00-\\u1c22\\u1c40-\\u1c49\\u1c5b-\\u1c7d\\u1cd0-\\u1cd2\\u1d00-\\u1dbe\\u1e01-\\u1f15\\u200c\\u200d\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2d81-\\u2d96\\u2de0-\\u2dff\\u3021-\\u3028\\u3099\\u309a\\ua640-\\ua66d\\ua674-\\ua67d\\ua69f\\ua6f0-\\ua6f1\\ua7f8-\\ua800\\ua806\\ua80b\\ua823-\\ua827\\ua880-\\ua881\\ua8b4-\\ua8c4\\ua8d0-\\ua8d9\\ua8f3-\\ua8f7\\ua900-\\ua909\\ua926-\\ua92d\\ua930-\\ua945\\ua980-\\ua983\\ua9b3-\\ua9c0\\uaa00-\\uaa27\\uaa40-\\uaa41\\uaa4c-\\uaa4d\\uaa50-\\uaa59\\uaa7b\\uaae0-\\uaae9\\uaaf2-\\uaaf3\\uabc0-\\uabe1\\uabec\\uabed\\uabf0-\\uabf9\\ufb20-\\ufb28\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f",s="\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}",a="(?:"+s+"|[\\x23\\x24\\x40\\x41-\\x5a\\x5f\\x61-\\x7a"+i+"])";e.identifier=new RegExp( +a+"(?:\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}|[\\x24\\x30-\\x39\\x41-\\x5a\\x5f\\x61-\\x7a\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u0620-\\u0649\\u0672-\\u06d3\\u06e7-\\u06e8\\u06fb-\\u06fc\\u0730-\\u074a\\u0800-\\u0814\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0840-\\u0857\\u08e4-\\u08fe\\u0900-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962-\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09d7\\u09df-\\u09e0\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2-\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b5f-\\u0b60\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62-\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2-\\u0ce3\\u0ce6-\\u0cef\\u0d02\\u0d03\\u0d46-\\u0d48\\u0d57\\u0d62-\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e34-\\u0e3a\\u0e40-\\u0e45\\u0e50-\\u0e59\\u0eb4-\\u0eb9\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f41-\\u0f47\\u0f71-\\u0f84\\u0f86-\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u1000-\\u1029\\u1040-\\u1049\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u170e-\\u1710\\u1720-\\u1730\\u1740-\\u1750\\u1772\\u1773\\u1780-\\u17b2\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u1920-\\u192b\\u1930-\\u193b\\u1951-\\u196d\\u19b0-\\u19c0\\u19c8-\\u19c9\\u19d0-\\u19d9\\u1a00-\\u1a15\\u1a20-\\u1a53\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1b46-\\u1b4b\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c00-\\u1c22\\u1c40-\\u1c49\\u1c5b-\\u1c7d\\u1cd0-\\u1cd2\\u1d00-\\u1dbe\\u1e01-\\u1f15\\u200c\\u200d\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2d81-\\u2d96\\u2de0-\\u2dff\\u3021-\\u3028\\u3099\\u309a\\ua640-\\ua66d\\ua674-\\ua67d\\ua69f\\ua6f0-\\ua6f1\\ua7f8-\\ua800\\ua806\\ua80b\\ua823-\\ua827\\ua880-\\ua881\\ua8b4-\\ua8c4\\ua8d0-\\ua8d9\\ua8f3-\\ua8f7\\ua900-\\ua909\\ua926-\\ua92d\\ua930-\\ua945\\ua980-\\ua983\\ua9b3-\\ua9c0\\uaa00-\\uaa27\\uaa40-\\uaa41\\uaa4c-\\uaa4d\\uaa50-\\uaa59\\uaa7b\\uaae0-\\uaae9\\uaaf2-\\uaaf3\\uabc0-\\uabe1\\uabec\\uabed\\uabf0-\\uabf9\\ufb20-\\ufb28\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f])*" +,"g"),e.identifierStart=new RegExp(a),e.identifierMatch=new RegExp("(?:"+s+"|["+n+i+_+"])+"),e.newline=/[\n\r\u2028\u2029]/,e.lineBreak=new RegExp("\r\n|"+e.newline.source),e.allLineBreaks=new RegExp(e.lineBreak.source,"g")},function(t,e,n){var i=n(6).Options,_=["before-newline","after-newline","preserve-newline"];function s(t){var e,n;for(i.call(this,t,"js"),"expand-strict"===(t=this.raw_options.brace_style||null)?this.raw_options.brace_style="expand":"collapse-preserve-inline"===t?this.raw_options.brace_style="collapse,preserve-inline":this.raw_options.braces_on_own_line!==undefined&&(this.raw_options.brace_style=this.raw_options.braces_on_own_line?"expand":"collapse"),e=this._get_selection_list("brace_style",["collapse","expand","end-expand","none","preserve-inline"]),this.brace_preserve_inline=!1,this.brace_style="collapse",n=0;n>> === !== &&= ??= ||= << && >= ** != == <= >> || ?? |> < / - + > : & % ? ^ | *".split(" "),s=(s="\\?\\.(?!\\d) "+(s=(s=">>>= ... >>= <<= === >>> !== **= &&= ??= ||= => ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> = ! ? > < : / ^ - + * & % ~ |").replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"))).replace(/ /g,"|"),c=new RegExp(s),s=(a="continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export".split(",")).concat(["do","in","of","else","get","set","new","catch","finally","typeof","yield","async","await","from","as","class","extends"]),d=new RegExp("^(?:"+s.join("|")+")$"),((s=function(t,e){g.call( +this,t,e),this._patterns.whitespace=this._patterns.whitespace.matching(/\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff/.source,/\u2028\u2029/.source),t=new b(this._input),e=new m(this._input).read_options(this._options),this.__patterns={template:e,identifier:e.starting_with(h.identifier).matching(h.identifierMatch),number:t.matching(n),punct:t.matching(c),comment:t.starting_with(/\/\//).until(/[\n\r\u2028\u2029]/),block_comment:t.starting_with(/\/\*/).until_after(/\*\//),html_comment_start:t.matching(//),include:t.starting_with(/#include/).until_after(h.lineBreak),shebang:t.starting_with(/#!/).until_after(h.lineBreak),xml:t.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[^}]+?}|!\[CDATA\[[^\]]*?\]\]|)(\s*{[^}]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{([^{}]|{[^}]+?})+?}))*\s*(\/?)\s*>/),single_quote:e.until(/['\\\n\r\u2028\u2029]/),double_quote:e.until(/["\\\n\r\u2028\u2029]/),template_text:e.until(/[`\\$]/),template_expression:e.until(/[`}\\]/)}}).prototype=new g)._is_comment=function(t){return t.type===o.COMMENT||t.type===o.BLOCK_COMMENT||t.type===o.UNKNOWN},s.prototype._is_opening=function(t){return t.type===o.START_BLOCK||t.type===o.START_EXPR},s.prototype._is_closing=function(t,e){return(t.type===o.END_BLOCK||t.type===o.END_EXPR)&&e&&("]"===t.text&&"["===e.text||")"===t.text&&"("===e.text||"}"===t.text&&"{"===e.text)},s.prototype._reset=function(){_=!1},s.prototype._get_next_token=function(t,e){var n;return this._readWhitespace(),null===(n=this._input.peek())?this._create_token(o.EOF,""):this._read_non_javascript(n)||this._read_string(n)||this._read_pair(n,this._input.peek(1))||this._read_word(t)||this._read_singles(n)||this._read_comment(n)||this._read_regexp(n,t)||this._read_xml(n,t)||this._read_punctuation()||this._create_token(o.UNKNOWN,this._input.next())},s.prototype._read_word=function(t){var e=this.__patterns.identifier.read();return""!==e?(e=e.replace(h.allLineBreaks,"\n"),t.type!==o.DOT&&(t.type!==o.RESERVED||"set"!==t.text&&"get"!==t.text)&&d.test(e)?"in"!==e&&"of"!==e||t.type!==o.WORD&&t.type!==o.STRING?this._create_token(o.RESERVED,e):this._create_token(o.OPERATOR,e):this._create_token(o.WORD,e)):""!==(e=this.__patterns.number.read())?this._create_token(o.WORD,e):void 0},s.prototype._read_singles=function(t){var e=null;return"("===t||"["===t?e=this._create_token(o.START_EXPR,t):")"===t||"]"===t?e=this._create_token(o.END_EXPR,t):"{"===t?e=this._create_token(o.START_BLOCK,t):"}"===t?e=this._create_token(o.END_BLOCK,t):";"===t?e=this._create_token(o.SEMICOLON,t):"."===t&&l.test(this._input.peek(1))?e=this._create_token(o.DOT,t):","===t&&(e=this._create_token(o.COMMA,t)),e&&this._input.next(),e},s.prototype._read_pair=function(t,e){var n=null;return(n="#"===t&&"{"===e?this._create_token(o.START_BLOCK,t+e):n)&&(this._input.next(),this._input.next()),n},s.prototype._read_punctuation=function(){var t=this.__patterns.punct.read();if(""!==t)return"="===t?this._create_token(o.EQUALS,t):"?."===t?this._create_token(o.DOT,t):this._create_token(o.OPERATOR,t)},s.prototype._read_non_javascript=function(t){var e,n="";if("#"===t){if(this._is_first_token()&&(n=this.__patterns.shebang.read()))return this._create_token(o.UNKNOWN,n.trim()+"\n");if(n=this.__patterns.include.read())return this._create_token(o.UNKNOWN,n.trim()+"\n");if(t=this._input.next(),e="#",this._input.hasNext()&&this._input.testChar(p)){for(;e+=t=this._input.next(),this._input.hasNext()&&"#"!==t&&"="!==t;);return"#"===t||("["===this._input.peek()&&"]"===this._input.peek(1)?(e+="[]",this._input.next(),this._input.next()):"{"===this._input.peek()&&"}"===this._input.peek(1)&&(e+="{}",this._input.next(),this._input.next())),this._create_token(o.WORD,e)}this._input.back()}else if("<"===t&&this._is_first_token()){if(n=this.__patterns.html_comment_start.read()){for(;this._input.hasNext()&&!this._input.testChar(h.newline);)n+=this._input.next();return _=!0,this._create_token(o.COMMENT,n)}}else if(_&&"-"===t&&(n=this.__patterns.html_comment_end.read()))return _=!1,this._create_token(o.COMMENT,n);return null},s.prototype._read_comment=function(t){var e,n=null;return"/"===t&&(t="","*"===this._input.peek(1)?(t=this.__patterns.block_comment.read(),(e=i.get_directives(t))&&"start"===e.ignore&&(t+=i.readIgnored(this._input)),t=t.replace(h.allLineBreaks,"\n"),(n=this._create_token(o.BLOCK_COMMENT,t)).directives=e):"/"===this._input.peek(1)&&(t=this.__patterns.comment.read(),n=this._create_token(o.COMMENT,t))),n},s.prototype._read_string=function(t){var e;return"`"===t||"'"===t||'"'===t?(e=this._input.next(),this.has_char_escapes=!1,e+="`"===t?this._read_string_recursive("`",!0,"${"):this._read_string_recursive(t),this.has_char_escapes&&this._options.unescape_strings&&(e=function(t){var e="",n=0,i=new f(t),_=null;for(;i.hasNext();)if((_=i.match(/([\s]|[^\\]|\\\\)+/g))&&(e+=_[0]),"\\"===i.peek()){if(i.next(),"x"===i.peek())_=i.match(/x([0-9A-Fa-f]{2})/g);else{if("u"!==i.peek()){e+="\\",i.hasNext()&&(e+=i.next());continue}_=(_=i.match(/u([0-9A-Fa-f]{4})/g))||i.match(/u\{([0-9A-Fa-f]+)\}/g)}if(!_)return t;if(126<(n=parseInt(_[1],16))&&n<=255&&0===_[0].indexOf("x"))return t;e+=0<=n&&n<32||1114111=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},function(t,e,n){var i=n(8).InputScanner,s=n(3).Token,a=n(10).TokenStream,_=n(11).WhitespacePattern,r={START:"TK_START",RAW:"TK_RAW",EOF:"TK_EOF"},n=function(t,e){this._input=new i(t),this._options=e||{},this.__tokens=null,this._patterns={},this._patterns.whitespace=new _(this._input)};n.prototype.tokenize=function(){var t,e,n,i,_;for(this._input.restart(),this.__tokens=new a,this._reset(),e=new s(r.START,""),n=null,i=[],_=new a;e.type!==r.EOF;){for(t=this._get_next_token(e,n);this._is_comment(t);)_.add(t),t=this._get_next_token(e,n);_.isEmpty()||(t.comments_before=_,_=new a),t.parent=n,this._is_opening(t)?(i.push(n),n=t):n&&this._is_closing(t,n)&&((t.opened=n).closed=t,n=i.pop(),t.parent=n),(t.previous=e).next=t,this.__tokens.add(t),e=t}return this.__tokens},n.prototype._is_first_token=function(){return this.__tokens.isEmpty()},n.prototype._reset=function(){},n.prototype._get_next_token=function(t,e){this._readWhitespace();var n=this._input.read(/.+/g);return n?this._create_token(r.RAW,n):this._create_token(r.EOF,"")},n.prototype._is_comment=function(t){return!1},n.prototype._is_opening=function(t){return!1},n.prototype._is_closing=function(t,e){return!1},n.prototype._create_token=function(t,e){return new s(t,e,this._patterns.whitespace.newline_count,this._patterns.whitespace.whitespace_before_token)},n.prototype._readWhitespace=function(){return this._patterns.whitespace.read()},t.exports.Tokenizer=n,t.exports.TOKEN=r},function(t){function e(t){this.__tokens=[],this.__tokens_length=this.__tokens.length,this.__position=0,this.__parent_token=t}e.prototype.restart=function(){this.__position=0},e.prototype.isEmpty=function(){return 0===this.__tokens_length},e.prototype.hasNext=function(){return this.__position/),erb:e.starting_with(/<%[^%]/).until_after(/[^%]%>/),django:e.starting_with(/{%/).until_after(/%}/),django_value:e.starting_with(/{{/).until_after(/}}/),django_comment:e.starting_with(/{#/).until_after(/#}/),smarty:e.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),smarty_comment:e.starting_with(/{\*/).until_after(/\*}/),smarty_literal:e.starting_with(/{literal}/).until_after(/{\/literal}/)}}(s.prototype=new i)._create=function(){return new s(this._input,this)},s.prototype._update=function(){this.__set_templated_pattern()},s.prototype.disable=function(t){var e=this._create();return e._disabled[t]=!0,e._update(),e},s.prototype.read_options=function(t){var e,n=this._create();for(e in _)n._disabled[e]=-1===t.templating.indexOf(e);return n._update(),n},s.prototype.exclude=function(t){var e=this._create();return e._excluded[t]=!0,e._update(),e},s.prototype.read=function(){for(var t="",t=this._match_pattern?this._input.read(this._starting_pattern):this._input.read(this._starting_pattern,this.__template_pattern),e=this._read_template();e;)this._match_pattern?e+=this._input.read(this._match_pattern):e+=this._input.readUntil(this.__template_pattern),t+=e,e=this._read_template();return this._until_after&&(t+=this._input.readUntilAfter(this._until_pattern)),t},s.prototype.__set_templated_pattern=function(){var t=[];this._disabled.php||t.push(this.__patterns.php._starting_pattern.source),this._disabled.handlebars||t.push(this.__patterns.handlebars._starting_pattern.source),this._disabled.erb||t.push(this.__patterns.erb._starting_pattern.source),this._disabled.django||(t.push(this.__patterns.django._starting_pattern.source),t.push(this.__patterns.django_value._starting_pattern.source),t.push(this.__patterns.django_comment._starting_pattern.source)),this._disabled.smarty||t.push(this.__patterns.smarty._starting_pattern.source),this._until_pattern&&t.push(this._until_pattern.source),this.__template_pattern=this._input.get_regexp("(?:"+t.join("|")+")")},s.prototype._read_template=function(){var t,e="",n=this._input.peek();return"<"===n?(t=this._input.peek(1),this._disabled.php||this._excluded.php||"?"!==t||(e=e||this.__patterns.php.read()),this._disabled.erb||this._excluded.erb||"%"!==t||(e=e||this.__patterns.erb.read())):"{"===n&&( +this._disabled.handlebars||this._excluded.handlebars||(e=(e=(e=e||this.__patterns.handlebars_comment.read())||this.__patterns.handlebars_unescaped.read())||this.__patterns.handlebars.read()),this._disabled.django||(this._excluded.django||this._excluded.handlebars||(e=e||this.__patterns.django_value.read()),this._excluded.django||(e=(e=e||this.__patterns.django_comment.read())||this.__patterns.django.read())),this._disabled.smarty||this._disabled.django&&this._disabled.handlebars&&(e=(e=(e=e||this.__patterns.smarty_comment.read())||this.__patterns.smarty_literal.read())||this.__patterns.smarty.read())),e},t.exports.TemplatablePattern=s}],i={};t=function _(t){var e=i[t];return e!==undefined||(e=i[t]={exports:{}},n[t](e,e.exports,_)),e.exports}(0),s=t}(),t=s,void 0!==u?u.js_beautify=t:"undefined"!=typeof window?window.js_beautify=t:"undefined"!=typeof global&&(global.js_beautify=t),function(){"use strict";var t,n=[,,function(t){function _(t){this.__parent=t,this.__character_count=0,this.__indent_count=-1,this.__alignment_count=0,this.__wrap_point_index=0,this.__wrap_point_character_count=0,this.__wrap_point_indent_count=-1,this.__wrap_point_alignment_count=0,this.__items=[]}function n(t,e){this.__cache=[""],this.__indent_size=t.indent_size,this.__indent_string=t.indent_char,t.indent_with_tabs||(this.__indent_string=new Array(t.indent_size+1).join(t.indent_char)),e=e||"",0this.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&(this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice(this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count,this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty()?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g, +"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0),1=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},,,,,function(t){function e(t,e){t="string"==typeof t?t:t.source,e="string"==typeof e?e:e.source,this.__directives_block_pattern=new RegExp(t+/ beautify( \w+[:]\w+)+ /.source+e,"g"),this.__directive_pattern=/ (\w+)[:](\w+)/g,this.__directives_end_ignore_pattern=new RegExp(t+/\sbeautify\signore:end\s/.source+e,"g")}e.prototype.get_directives=function(t){var e,n;if(!t.match(this.__directives_block_pattern))return null;for(e={},this.__directive_pattern.lastIndex=0,n=this.__directive_pattern.exec(t);n;)e[n[1]]=n[2],n=this.__directive_pattern.exec(t);return e},e.prototype.readIgnored=function(t){return t.readUntilAfter(this.__directives_end_ignore_pattern)},t.exports.Directives=e},,function(t,e,n){var i=n(16).Beautifier,_=n(17).Options;t.exports=function(t,e){return new i(t,e).beautify()},t.exports.defaultOptions=function(){return new _}},function(t,_,e){var n=e(17).Options,b=e(2).Output,m=e(8).InputScanner,e=e(13).Directives,y=new e(/\/\*/,/\*\//),w=/\r\n|[\r\n]/,k=/\r\n|[\r\n]/g,x=/\s/,v=/(?:\s|\n)+/g,E=/\/\*(?:[\s\S]*?)((?:\*\/)|$)/g,O=/\/\/(?:[^\n\r\u2028\u2029]*)/g;function i(t,e){this._source_text=t||"",this._options=new n(e),this._ch=null,this._input=null,this.NESTED_AT_RULE={page:!0,"font-face":!0,keyframes:!0,media:!0,supports:!0,document:!0},this.CONDITIONAL_GROUP_RULE={media:!0,supports:!0,document:!0},this.NON_SEMICOLON_NEWLINE_PROPERTY=["grid-template-areas","grid-template"]}i.prototype.eatString=function(t){var e="";for(this._ch=this._input.next();this._ch;){if(e+=this._ch,"\\"===this._ch)e+=this._input.next();else if(-1!==t.indexOf(this._ch)||"\n"===this._ch)break;this._ch=this._input.next()}return e},i.prototype.eatWhitespace=function(t){for(var e=x.test(this._input.peek()),n=0;x.test(this._input.peek());)this._ch=this._input.next(),t&&"\n"===this._ch&&(0===n||n=this._nestedLevel):this._indentLevel>=this._nestedLevel-1,this._options.newline_between_rules&&n&&this._output.previous_line&&"{"!==this._output.previous_line.item(-1)&&this._output.ensure_empty_line_above("/",","),this._output.space_before_token=!0,"expand"===this._options.brace_style?(this._output.add_new_line(),this.print_string(this._ch),this.indent(),this._output.set_indent(this._indentLevel)):("("===r?this._output.space_before_token=!1:","!==r&&this.indent(),this.print_string(this._ch)),this.eatWhitespace(!0),this._output.add_new_line();else if("}"===this._ch)this.outdent(),this._output.add_new_line(),"{"===r&&this._output.trim(!0),i&&(this.outdent(),i=!1),this.print_string(this._ch),n=!1,this._nestedLevel&&this._nestedLevel--,this.eatWhitespace(!0),this._output.add_new_line(), +this._options.newline_between_rules&&!this._output.just_added_blankline()&&"}"!==this._input.peek()&&this._output.add_new_line(!0),")"===this._input.peek()&&(this._output.trim(!0),"expand"===this._options.brace_style&&this._output.add_new_line(!0));else if(":"===this._ch){for(f=0;f"!==this._ch&&"+"!==this._ch&&"~"!==this._ch||i||0!==e?"]"===this._ch?this.print_string(this._ch):"["===this._ch?(this.preserveSingleSpace(a),this.print_string(this._ch)):"="===this._ch?(this.eatWhitespace(),this.print_string("="),x.test(this._ch)&&(this._ch="")):"!"!==this._ch||this._input.lookBack("\\")?(this.preserveSingleSpace('"'===r||"'"===r||a),this.print_string(this._ch),!this._output.just_added_newline()&&"\n"===this._input.peek()&&d&&this._output.add_new_line()):(this._output.space_before_token=!0,this.print_string(this._ch)):this._options.space_around_combinator?(this._output.space_before_token=!0,this.print_string(this._ch),this._output.space_before_token=!0):(this.print_string(this._ch),this.eatWhitespace(),this._ch&&x.test(this._ch)&&(this._ch=""))}return this._output.get_code(h)},t.exports.Beautifier=i},function(t,e,n){var i=n(6).Options;function _(t){var e,n;for(i.call(this,t,"css"),this.selector_separator_newline=this._get_boolean("selector_separator_newline",!0),this.newline_between_rules=this._get_boolean("newline_between_rules",!0),t=this._get_boolean("space_around_selector_separator"),this.space_around_combinator=this._get_boolean("space_around_combinator")||t,e=this._get_selection_list("brace_style",["collapse","expand","end-expand","none","preserve-inline"]),this.brace_style="collapse",n=0;nthis.__parent.wrap_line_length&&this.__wrap_point_character_count>this.__parent.next_line.__character_count},_.prototype._allow_wrap=function(){var t;return!!this._should_wrap()&&( +this.__parent.add_new_line(),(t=this.__parent.current_line).set_indent(this.__wrap_point_indent_count,this.__wrap_point_alignment_count),t.__items=this.__items.slice(this.__wrap_point_index),this.__items=this.__items.slice(0,this.__wrap_point_index),t.__character_count+=this.__character_count-this.__wrap_point_character_count,this.__character_count=this.__wrap_point_character_count," "===t.__items[0]&&(t.__items.splice(0,1),--t.__character_count),!0)},_.prototype.is_empty=function(){return 0===this.__items.length},_.prototype.last=function(){return this.is_empty()?null:this.__items[this.__items.length-1]},_.prototype.push=function(t){this.__items.push(t);var e=t.lastIndexOf("\n");-1!==e?this.__character_count=t.length-e:this.__character_count+=t.length},_.prototype.pop=function(){var t=null;return this.is_empty()||(t=this.__items.pop(),this.__character_count-=t.length),t},_.prototype._remove_indent=function(){0=this.__cache.length;)this.__add_column()},n.prototype.__add_column=function(){var t,e=this.__cache.length,n="";this.__indent_size&&e>=this.__indent_size&&(e-=(t=Math.floor(e/this.__indent_size))*this.__indent_size,n=new Array(t+1).join(this.__indent_string)),e&&(n+=new Array(e+1).join(" ")),this.__cache.push(n)},e.prototype.__add_outputline=function(){this.previous_line=this.current_line,this.current_line=this.next_line.clone_empty(),this.__lines.push(this.current_line)},e.prototype.get_line_number=function(){return this.__lines.length},e.prototype.get_indent_string=function(t,e){return this.__indent_cache.get_indent_string(t,e)},e.prototype.get_indent_size=function(t,e){return this.__indent_cache.get_indent_size(t,e)},e.prototype.is_empty=function(){return!this.previous_line&&this.current_line.is_empty()},e.prototype.add_new_line=function(t){return!(this.is_empty()||!t&&this.just_added_newline())&&(this.raw||this.__add_outputline(),!0)},e.prototype.get_code=function(t){var e;return this.trim(!0),(e=this.current_line.pop())&&("\n"===e[e.length-1]&&(e=e.replace(/\n+$/g,"")),this.current_line.push(e)),this._end_with_newline&&this.__add_outputline(),e=this.__lines.join("\n"),e="\n"!==t?e.replace(/[\n]/g,t):e},e.prototype.set_wrap_point=function(){this.current_line._set_wrap_point()},e.prototype.set_indent=function(t,e){return this.next_line.set_indent(t=t||0,e=e||0),1=t.length&&this.__input.substring(e-t.length,e).toLowerCase()===t},t.exports.InputScanner=e},function(t,e,n){var i=n(8).InputScanner,s=n(3).Token,a=n(10).TokenStream,_=n(11).WhitespacePattern,r={START:"TK_START",RAW:"TK_RAW",EOF:"TK_EOF"},n=function(t,e){this._input=new i(t),this._options=e||{},this.__tokens=null,this._patterns={},this._patterns.whitespace=new _(this._input)};n.prototype.tokenize=function(){var t,e,n,i,_;for(this._input.restart(),this.__tokens=new a,this._reset(),e=new s(r.START,""),n=null,i=[],_=new a;e.type!==r.EOF;){for(t=this._get_next_token(e,n);this._is_comment(t);)_.add(t),t=this._get_next_token(e,n);_.isEmpty()||(t.comments_before=_,_=new a),t.parent=n,this._is_opening(t)?(i.push(n),n=t):n&&this._is_closing(t,n)&&((t.opened=n).closed=t,n=i.pop(),t.parent=n),(t.previous=e).next=t,this.__tokens.add(t),e=t}return this.__tokens},n.prototype._is_first_token=function(){return this.__tokens.isEmpty()},n.prototype._reset=function(){},n.prototype._get_next_token=function(t,e){this._readWhitespace();var n=this._input.read(/.+/g);return n?this._create_token(r.RAW,n):this._create_token(r.EOF,"")},n.prototype._is_comment=function(t){return!1},n.prototype._is_opening=function(t){return!1},n.prototype._is_closing=function(t,e){return!1},n.prototype._create_token=function(t,e){return new s(t,e,this._patterns.whitespace.newline_count,this._patterns.whitespace.whitespace_before_token)},n.prototype._readWhitespace=function(){return this._patterns.whitespace.read()},t.exports.Tokenizer=n,t.exports.TOKEN=r},function(t){function e(t){this.__tokens=[],this.__tokens_length=this.__tokens.length,this.__position=0,this.__parent_token=t}e.prototype.restart=function(){this.__position=0},e.prototype.isEmpty=function(){return 0===this.__tokens_length},e.prototype.hasNext=function(){return this.__position/),erb:e.starting_with(/<%[^%]/).until_after(/[^%]%>/),django:e.starting_with(/{%/).until_after(/%}/),django_value:e.starting_with(/{{/).until_after(/}}/),django_comment:e.starting_with(/{#/).until_after(/#}/),smarty:e.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),smarty_comment:e.starting_with(/{\*/).until_after(/\*}/),smarty_literal:e.starting_with(/{literal}/).until_after(/{\/literal}/)}}(s.prototype=new i)._create=function(){return new s(this._input,this)},s.prototype._update=function(){this.__set_templated_pattern()},s.prototype.disable=function(t){var e=this._create();return e._disabled[t]=!0,e._update(),e},s.prototype.read_options=function(t){var e,n=this._create();for(e in _)n._disabled[e]=-1===t.templating.indexOf(e);return n._update(),n},s.prototype.exclude=function(t){var e=this._create();return e._excluded[t]=!0,e._update(),e},s.prototype.read=function(){for(var t="",t=this._match_pattern?this._input.read(this._starting_pattern):this._input.read(this._starting_pattern,this.__template_pattern),e=this._read_template();e;)this._match_pattern?e+=this._input.read(this._match_pattern):e+=this._input.readUntil(this.__template_pattern),t+=e,e=this._read_template();return this._until_after&&(t+=this._input.readUntilAfter(this._until_pattern)),t},s.prototype.__set_templated_pattern=function(){var t=[];this._disabled.php||t.push(this.__patterns.php._starting_pattern.source),this._disabled.handlebars||t.push(this.__patterns.handlebars._starting_pattern.source),this._disabled.erb||t.push(this.__patterns.erb._starting_pattern.source),this._disabled.django||(t.push(this.__patterns.django._starting_pattern.source),t.push(this.__patterns.django_value._starting_pattern.source),t.push(this.__patterns.django_comment._starting_pattern.source)),this._disabled.smarty||t.push(this.__patterns.smarty._starting_pattern.source),this._until_pattern&&t.push(this._until_pattern.source),this.__template_pattern=this._input.get_regexp("(?:"+t.join("|")+")")},s.prototype._read_template=function(){var t,e="",n=this._input.peek();return"<"===n?(t=this._input.peek(1),this._disabled.php||this._excluded.php||"?"!==t||(e=e||this.__patterns.php.read()), +this._disabled.erb||this._excluded.erb||"%"!==t||(e=e||this.__patterns.erb.read())):"{"===n&&(this._disabled.handlebars||this._excluded.handlebars||(e=(e=(e=e||this.__patterns.handlebars_comment.read())||this.__patterns.handlebars_unescaped.read())||this.__patterns.handlebars.read()),this._disabled.django||(this._excluded.django||this._excluded.handlebars||(e=e||this.__patterns.django_value.read()),this._excluded.django||(e=(e=e||this.__patterns.django_comment.read())||this.__patterns.django.read())),this._disabled.smarty||this._disabled.django&&this._disabled.handlebars&&(e=(e=(e=e||this.__patterns.smarty_comment.read())||this.__patterns.smarty_literal.read())||this.__patterns.smarty.read())),e},t.exports.TemplatablePattern=s},,,,function(t,e,n){var _=n(19).Beautifier,i=n(20).Options;t.exports=function(t,e,n,i){return new _(t,e,n,i).beautify()},t.exports.defaultOptions=function(){return new i}},function(e,n,t){var _,s,o,i,r,u=t(20).Options,d=t(2).Output,f=t(21).Tokenizer,h=t(21).TOKEN,g=/\r\n|[\r\n]/,b=/\r\n|[\r\n]/g,p=function(t,e){this.indent_level=0,this.alignment_size=0,this.max_preserve_newlines=t.max_preserve_newlines,this.preserve_newlines=t.preserve_newlines,this._output=new d(t,e)};function a(t,e){return-1!==e.indexOf(t)}function m(t,e,n){this.parent=t||null,this.tag=e?e.tag_name:"",this.indent_level=n||0,this.parser_token=e||null}function l(t){this._printer=t,this._current_frame=null}function c(t,e,n,i){this._source_text=t||"",e=e||{},this._js_beautify=n,this._css_beautify=i,this._tag_stack=null;t=new u(e,"html");this._options=t,this._is_wrap_attributes_force="force"===this._options.wrap_attributes.substr(0,"force".length),this._is_wrap_attributes_force_expand_multiline="force-expand-multiline"===this._options.wrap_attributes,this._is_wrap_attributes_force_aligned="force-aligned"===this._options.wrap_attributes,this._is_wrap_attributes_aligned_multiple="aligned-multiple"===this._options.wrap_attributes,this._is_wrap_attributes_preserve="preserve"===this._options.wrap_attributes.substr(0,"preserve".length),this._is_wrap_attributes_preserve_aligned="preserve-aligned"===this._options.wrap_attributes}p.prototype.current_line_has_match=function(t){return this._output.current_line.has_match(t)},p.prototype.set_space_before_token=function(t,e){this._output.space_before_token=t,this._output.non_breaking_space=e},p.prototype.set_wrap_point=function(){this._output.set_indent(this.indent_level,this.alignment_size),this._output.set_wrap_point()},p.prototype.add_raw_token=function(t){this._output.add_raw_token(t)},p.prototype.print_preserved_newlines=function(t){var e,n=0;for(t.type!==h.TEXT&&t.previous.type!==h.TEXT&&(n=t.newlines?1:0),this.preserve_newlines&&(n=t.newlines=this._options.wrap_attributes_min_attrs&&(i.type!==h.TAG_OPEN||this._is_wrap_attributes_force_expand_multiline)&&(t.print_newline(!1),_=!0)),t.print_token(e),_=_||t.previous_token_wrapped(),n.has_wrapped_attrs=_),s},c.prototype._handle_text=function(t,e,n){var i={text:e.text,type:"TK_CONTENT"};return n.custom_beautifier_name?this._print_custom_beatifier_text(t,e,n):n.is_unformatted||n.is_content_unformatted?t.add_raw_token(e):(t.traverse_whitespace(e),t.print_token(e)),i},c.prototype._print_custom_beatifier_text=function(t,e,n){var i,_,s,a,r,u=this;if(""!==e.text){if(i=e.text,r=1,a=s="","javascript"===n.custom_beautifier_name&&"function"==typeof this._js_beautify?_=this._js_beautify:"css"===n.custom_beautifier_name&&"function"==typeof this._css_beautify?_=this._css_beautify:"html"===n.custom_beautifier_name&&(_=function(t,e){return new c(t,e,u._js_beautify,u._css_beautify).beautify()}),"keep"===this._options.indent_scripts?r=0:"separate"===this._options.indent_scripts&&(r=-t.indent_level),r=t.get_full_indent(r),i=i.replace(/\n[ \t]*$/,""),"html"!==n.custom_beautifier_name&&"<"===i[0]&&i.match(/^(|]]>)$/.exec(i)))return void t.add_raw_token(e);s=r+n[1]+"\n",i=n[4],n[5]&&(a=r+n[5]),i=i.replace(/\n[ \t]*$/,""),(n[2]||-1!==n[3].indexOf("\n"))&&(n=n[3].match(/[ \t]+$/))&&(e.whitespace_before=n[0])}i=i&&(_?((n=function(){this.eol="\n"}).prototype=this._options.raw_options,_(r+i,new n)):r+(i=(n=e.whitespace_before)?i.replace(new RegExp("\n("+n+")?","g"),"\n"):i).replace(/\n/g,"\n"+r)),s&&(i=i?s+i+"\n"+a:s+a),t.print_newline(!1),i&&(e.text=i,e.whitespace_before="",e.newlines=0,t.add_raw_token(e),t.print_newline(!0))}},c.prototype._handle_tag_open=function(t,e,n,i,_){var s,a,r=this._get_tag_open_token(e);if(!n.is_unformatted&&!n.is_content_unformatted||n.is_empty_element||e.type!==h.TAG_OPEN||r.is_start_tag?(t.traverse_whitespace(e),this._set_tag_position(t,e,r,n,i),r.is_inline_element||t.set_wrap_point(),t.print_token(e)):(t.add_raw_token(e),r.start_tag_token=this._tag_stack.try_pop(r.tag_name)),r.is_start_tag&&this._is_wrap_attributes_force)for(s=0;(a=_.peek(s)).type===h.ATTRIBUTE&&(r.attr_count+=1),s+=1,a.type!==h.EOF&&a.type!==h.TAG_CLOSE;);return(this._is_wrap_attributes_force_aligned||this._is_wrap_attributes_aligned_multiple||this._is_wrap_attributes_preserve_aligned)&&(r.alignment_size=e.text.length+1),r.tag_complete||r.is_unformatted||(t.alignment_size=r.alignment_size),r},o=function(t,e){var n;this.parent=t||null,this.text="",this.type="TK_TAG_OPEN",this.tag_name="",this.is_inline_element=!1,this.is_unformatted=!1,this.is_content_unformatted=!1,this.is_empty_element=!1,this.is_start_tag=!1,this.is_end_tag=!1,this.indent_content=!1,this.multiline_content=!1,this.custom_beautifier_name=null,this.start_tag_token=null,this.attr_count=0,this.has_wrapped_attrs=!1,this.alignment_size=0,this.tag_complete=!1,this.tag_start_char="",this.tag_check="",e?(this.tag_start_char=e.text[0],this.text=e.text,"<"===this.tag_start_char?(n=e.text.match(/^<([^\s>]*)/),this.tag_check=n?n[1]:""):(n=e.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/),this.tag_check=n?n[1]:"",(e.text.startsWith("{{#>")||e.text.startsWith("{{~#>"))&&">"===this.tag_check[0]&&(">"===this.tag_check&&null!==e.next?this.tag_check=e.next.text.split(" ")[0]:this.tag_check=e.text.split(">")[1])),this.tag_check=this.tag_check.toLowerCase(),e.type===h.COMMENT&&(this.tag_complete=!0),this.is_start_tag="/"!==this.tag_check.charAt(0),this.tag_name=this.is_start_tag?this.tag_check:this.tag_check.substr(1),this.is_end_tag=!this.is_start_tag||e.closed&&"/>"===e.closed.text,t=2,"{"===this.tag_start_char&&3<=this.text.length&&"~"===this.text.charAt(2)&&(t=3),this.is_end_tag=this.is_end_tag||"{"===this.tag_start_char&&(this.text.length<3||/[^#\^]/.test(this.text.charAt(t)))):this.tag_complete=!0},c.prototype._get_tag_open_token=function(t){t=new o(this._tag_stack.get_parser_token(),t);return t.alignment_size=this._options.wrap_attributes_indent_size,t.is_end_tag=t.is_end_tag||a(t.tag_check,this._options.void_elements),t.is_empty_element=t.tag_complete||t.is_start_tag&&t.is_end_tag,t.is_unformatted=!t.tag_complete&&a(t.tag_check,this._options.unformatted),t.is_content_unformatted=!t.is_empty_element&&a( +t.tag_check,this._options.content_unformatted),t.is_inline_element=a(t.tag_name,this._options.inline)||this._options.inline_custom_elements&&t.tag_name.includes("-")||"{"===t.tag_start_char,t},c.prototype._set_tag_position=function(t,e,n,i,_){n.is_empty_element||(n.is_end_tag?n.start_tag_token=this._tag_stack.try_pop(n.tag_name):(this._do_optional_end_element(n)&&(n.is_inline_element||t.print_newline(!1)),this._tag_stack.record_tag(n),"script"!==n.tag_name&&"style"!==n.tag_name||n.is_unformatted||n.is_content_unformatted||(n.custom_beautifier_name=s(n.tag_check,e)))),a(n.tag_check,this._options.extra_liners)&&(t.print_newline(!1),t._output.just_added_blankline()||t.print_newline(!0)),n.is_empty_element?("{"===n.tag_start_char&&"else"===n.tag_check&&(this._tag_stack.indent_to_tag(["if","unless","each"]),n.indent_content=!0,t.current_line_has_match(/{{#if/)||t.print_newline(!1)),"!--"===n.tag_name&&_.type===h.TAG_CLOSE&&i.is_end_tag&&-1===n.text.indexOf("\n")||(n.is_inline_element||n.is_unformatted||t.print_newline(!1),this._calcluate_parent_multiline(t,n))):n.is_end_tag?(e=!1,e=(e=n.start_tag_token&&n.start_tag_token.multiline_content)||!n.is_inline_element&&!(i.is_inline_element||i.is_unformatted)&&!(_.type===h.TAG_CLOSE&&n.start_tag_token===i)&&"TK_CONTENT"!==_.type,(e=n.is_content_unformatted||n.is_unformatted?!1:e)&&t.print_newline(!1)):(n.indent_content=!n.custom_beautifier_name,"<"===n.tag_start_char&&("html"===n.tag_name?n.indent_content=this._options.indent_inner_html:"head"===n.tag_name?n.indent_content=this._options.indent_head_inner_html:"body"===n.tag_name&&(n.indent_content=this._options.indent_body_inner_html)),n.is_inline_element||n.is_unformatted||"TK_CONTENT"===_.type&&!n.is_content_unformatted||t.print_newline(!1),this._calcluate_parent_multiline(t,n))},c.prototype._calcluate_parent_multiline=function(t,e){!e.parent||!t._output.just_added_newline()||(e.is_inline_element||e.is_unformatted)&&e.parent.is_inline_element||(e.parent.multiline_content=!0)},i=["address","article","aside","blockquote","details","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hr","main","menu","nav","ol","p","pre","section","table","ul"],r=["a","audio","del","ins","map","noscript","video"],c.prototype._do_optional_end_element=function(t){var e,n=null;if(!t.is_empty_element&&t.is_start_tag&&t.parent)return"body"===t.tag_name?n=n||this._tag_stack.try_pop("head"):"li"===t.tag_name?n=n||this._tag_stack.try_pop("li",["ol","ul","menu"]):"dd"===t.tag_name||"dt"===t.tag_name?n=(n=n||this._tag_stack.try_pop("dt",["dl"]))||this._tag_stack.try_pop("dd",["dl"]):"p"===t.parent.tag_name&&-1!==i.indexOf(t.tag_name)?(e=t.parent.parent)&&-1!==r.indexOf(e.tag_name)||(n=n||this._tag_stack.try_pop("p")):"rp"===t.tag_name||"rt"===t.tag_name?n=(n=n||this._tag_stack.try_pop("rt",["ruby","rtc"]))||this._tag_stack.try_pop("rp",["ruby","rtc"]):"optgroup"===t.tag_name?n=n||this._tag_stack.try_pop("optgroup",["select"]):"option"===t.tag_name?n=n||this._tag_stack.try_pop("option",["select","datalist","optgroup"]):"colgroup"===t.tag_name?n=n||this._tag_stack.try_pop("caption",["table"]):"thead"===t.tag_name?n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]):"tbody"===t.tag_name||"tfoot"===t.tag_name?n=(n=(n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]))||this._tag_stack.try_pop("thead",["table"]))||this._tag_stack.try_pop("tbody",["table"]):"tr"===t.tag_name?n=(n=(n=n||this._tag_stack.try_pop("caption",["table"]))||this._tag_stack.try_pop("colgroup",["table"]))||this._tag_stack.try_pop("tr",["table","thead","tbody","tfoot"]):"th"!==t.tag_name&&"td"!==t.tag_name||(n=(n=n||this._tag_stack.try_pop("td",["table","thead","tbody","tfoot","tr"]))||this._tag_stack.try_pop("th",["table","thead","tbody","tfoot","tr"])),t.parent=this._tag_stack.get_parser_token(),n},e.exports.Beautifier=c},function(t,e,n){var i=n(6).Options;function _(t){i.call(this,t,"html"),1===this.templating.length&&"auto"===this.templating[0]&&(this.templating=["django","erb","handlebars","php"]),this.indent_inner_html=this._get_boolean("indent_inner_html"),this.indent_body_inner_html=this._get_boolean("indent_body_inner_html",!0),this.indent_head_inner_html=this._get_boolean("indent_head_inner_html",!0),this.indent_handlebars=this._get_boolean("indent_handlebars",!0),this.wrap_attributes=this._get_selection("wrap_attributes",["auto","force","force-aligned","force-expand-multiline","aligned-multiple","preserve","preserve-aligned"]),this.wrap_attributes_min_attrs=this._get_number("wrap_attributes_min_attrs",2),this.wrap_attributes_indent_size=this._get_number("wrap_attributes_indent_size",this.indent_size),this.extra_liners=this._get_array("extra_liners",["head","body","/html"]),this.inline=this._get_array("inline",["a","abbr","area","audio","b","bdi","bdo","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","keygen","label","map","mark","math","meter","noscript","object","output","progress","q","ruby","s","samp","select","small","span","strong","sub","sup","svg","template","textarea","time","u","var","video","wbr","text","acronym","big","strike","tt"]),this.inline_custom_elements=this._get_boolean("inline_custom_elements",!0),this.void_elements=this._get_array("void_elements",["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr","!doctype","?xml","basefont","isindex"]),this.unformatted=this._get_array("unformatted",[]),this.content_unformatted=this._get_array("content_unformatted",["pre","textarea"]),this.unformatted_content_delimiter=this._get_characters("unformatted_content_delimiter"),this.indent_scripts=this._get_selection("indent_scripts",["normal","keep","separate"])}_.prototype=new i,t.exports.Options=_},function(t,o,e){var n=e(9).Tokenizer,i=e(9).TOKEN,_=e(13).Directives,s=e(14 +).TemplatablePattern,a=e(12).Pattern,r={TAG_OPEN:"TK_TAG_OPEN",TAG_CLOSE:"TK_TAG_CLOSE",CONTROL_FLOW_OPEN:"TK_CONTROL_FLOW_OPEN",CONTROL_FLOW_CLOSE:"TK_CONTROL_FLOW_CLOSE",ATTRIBUTE:"TK_ATTRIBUTE",EQUALS:"TK_EQUALS",VALUE:"TK_VALUE",COMMENT:"TK_COMMENT",TEXT:"TK_TEXT",UNKNOWN:"TK_UNKNOWN",START:i.START,RAW:i.RAW,EOF:i.EOF},u=new _(/<\!--/,/-->/),e=function(t,e){n.call(this,t,e),this._current_tag_name="",t=new s(this._input).read_options(this._options),e=new a(this._input),this.__patterns={word:t.until(/[\n\r\t <]/),word_control_flow_close_excluded:t.until(/[\n\r\t <}]/),single_quote:t.until_after(/'/),double_quote:t.until_after(/"/),attribute:t.until(/[\n\r\t =>]|\/>/),element_name:t.until(/[\n\r\t >\/]/),angular_control_flow_start:e.matching(/\@[a-zA-Z]+[^({]*[({]/),handlebars_comment:e.starting_with(/{{!--/).until_after(/--}}/),handlebars:e.starting_with(/{{/).until_after(/}}/),handlebars_open:e.until(/[\n\r\t }]/),handlebars_raw_close:e.until(/}}/),comment:e.starting_with(//),cdata:e.starting_with(//),conditional_comment:e.starting_with(//),processing:e.starting_with(/<\?/).until_after(/\?>/)},this._options.indent_handlebars&&(this.__patterns.word=this.__patterns.word.exclude("handlebars"),this.__patterns.word_control_flow_close_excluded=this.__patterns.word_control_flow_close_excluded.exclude("handlebars")),this._unformatted_content_delimiter=null,this._options.unformatted_content_delimiter&&(t=this._input.get_literal_regexp(this._options.unformatted_content_delimiter),this.__patterns.unformatted_content_delimiter=e.matching(t).until_after(t))};(e.prototype=new n)._is_comment=function(t){return!1},e.prototype._is_opening=function(t){return t.type===r.TAG_OPEN||t.type===r.CONTROL_FLOW_OPEN},e.prototype._is_closing=function(t,e){return t.type===r.TAG_CLOSE&&e&&((">"===t.text||"/>"===t.text)&&"<"===e.text[0]||"}}"===t.text&&"{"===e.text[0]&&"{"===e.text[1])||t.type===r.CONTROL_FLOW_CLOSE&&"}"===t.text&&e.text.endsWith("{")},e.prototype._reset=function(){this._current_tag_name=""},e.prototype._get_next_token=function(t,e){var n;return this._readWhitespace(),null===(n=this._input.peek())?this._create_token(r.EOF,""):this._read_open_handlebars(n,e)||this._read_attribute(n,t,e)||this._read_close(n,e)||this._read_control_flows(n,e)||this._read_raw_content(n,t,e)||this._read_content_word(n,e)||this._read_comment_or_cdata(n)||this._read_processing(n)||this._read_open(n,e)||this._create_token(r.UNKNOWN,this._input.next())},e.prototype._read_comment_or_cdata=function(t){var e=null,n=null,i=null;return"<"===t&&("!"===this._input.peek(1)&&((n=this.__patterns.comment.read())?(i=u.get_directives(n))&&"start"===i.ignore&&(n+=u.readIgnored(this._input)):n=this.__patterns.cdata.read()),n&&((e=this._create_token(r.COMMENT,n)).directives=i)),e},e.prototype._read_processing=function(t){var e=null,n=null;return"<"===t&&(n="!"!==(t=this._input.peek(1))&&"?"!==t?n:(n=this.__patterns.conditional_comment.read())||this.__patterns.processing.read())&&((e=this._create_token(r.COMMENT,n)).directives=null),e},e.prototype._read_open=function(t,e){var n=null,i=null;return e&&e.type!==r.CONTROL_FLOW_OPEN||"<"===t&&(n=this._input.next(),"/"===this._input.peek()&&(n+=this._input.next()),n+=this.__patterns.element_name.read(),i=this._create_token(r.TAG_OPEN,n)),i},e.prototype._read_open_handlebars=function(t,e){var n=null,i=null;return e&&e.type!==r.CONTROL_FLOW_OPEN||this._options.indent_handlebars&&"{"===t&&"{"===this._input.peek(1)&&(i="!"===this._input.peek(2)?(n=(n=this.__patterns.handlebars_comment.read())||this.__patterns.handlebars.read(),this._create_token(r.COMMENT,n)):(n=this.__patterns.handlebars_open.read(),this._create_token(r.TAG_OPEN,n))),i},e.prototype._read_control_flows=function(t,e){var n,i,_,s="",a=null;if(!this._options.templating.includes("angular")||!this._options.indent_handlebars)return a;if("@"===t){if(""===(s=this.__patterns.angular_control_flow_start.read()))return a;for(n=s.endsWith("(")?1:0,i=0;(!s.endsWith("{")||n!==i)&&null!==(_=this._input.next());)"("===_?n++:")"===_&&i++,s+=_;a=this._create_token(r.CONTROL_FLOW_OPEN,s)}else"}"===t&&e&&e.type===r.CONTROL_FLOW_OPEN&&(s=this._input.next(),a=this._create_token(r.CONTROL_FLOW_CLOSE,s));return a},e.prototype._read_close=function(t,e){var n=null,i=null;return e&&e.type===r.TAG_OPEN&&("<"===e.text[0]&&(">"===t||"/"===t&&">"===this._input.peek(1))?(n=this._input.next(),"/"===t&&(n+=this._input.next()),i=this._create_token(r.TAG_CLOSE,n)):"{"===e.text[0]&&"}"===t&&"}"===this._input.peek(1)&&(this._input.next(),this._input.next(),i=this._create_token(r.TAG_CLOSE,"}}"))),i},e.prototype._read_attribute=function(t,e,n){var i=null;return n&&"<"===n.text[0]&&("="===t?i=this._create_token(r.EQUALS,this._input.next()):'"'===t||"'"===t?(n=this._input.next(),n+=('"'===t?this.__patterns.double_quote:this.__patterns.single_quote).read(),i=this._create_token(r.VALUE,n)):(t=this.__patterns.attribute.read())&&(i=e.type===r.EQUALS?this._create_token(r.VALUE,t):this._create_token(r.ATTRIBUTE,t))),i},e.prototype._is_content_unformatted=function(t){return-1===this._options.void_elements.indexOf(t)&&(-1!==this._options.content_unformatted.indexOf(t)||-1!==this._options.unformatted.indexOf(t))},e.prototype._read_raw_content=function(t,e,n){var i="";if(n&&"{"===n.text[0])i=this.__patterns.handlebars_raw_close.read();else if(e.type===r.TAG_CLOSE&&"<"===e.opened.text[0]&&"/"!==e.text[0])if("script"===(n=e.opened.text.substr(1).toLowerCase())||"style"===n){if(e=this._read_comment_or_cdata(t))return e.type=r.TEXT,e;i=this._input.readUntil(new RegExp("","ig"))}else this._is_content_unformatted(n)&&(i=this._input.readUntil(new RegExp("","ig")));return i?this._create_token(r.TEXT,i):null},e.prototype._read_content_word=function(t,e){var n="";if(n=( +n=this._options.unformatted_content_delimiter&&t===this._options.unformatted_content_delimiter[0]?this.__patterns.unformatted_content_delimiter.read():n)||(e&&e.type===r.CONTROL_FLOW_OPEN?this.__patterns.word_control_flow_close_excluded:this.__patterns.word).read())return this._create_token(r.TEXT,n)},t.exports.Tokenizer=e,t.exports.TOKEN=r}],i={};t=function _(t){var e=i[t];return e!==undefined||(e=i[t]={exports:{}},n[t](e,e.exports,_)),e.exports}(18),r=t}(),n=r,void 0!==u?(_=i=u).html_beautify=function(t,e){return n(t,e,i.js_beautify,_.css_beautify)}:"undefined"!=typeof window?window.html_beautify=function(t,e){return n(t,e,window.js_beautify,window.css_beautify)}:"undefined"!=typeof global&&(global.html_beautify=function(t,e){return n(t,e,global.js_beautify,global.css_beautify)})},"@VERSION@"); \ No newline at end of file diff --git a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify.js b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify.js index 6ebc08992d70..4bd9ce1b0259 100644 --- a/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify.js +++ b/lib/editor/atto/plugins/html/yui/build/moodle-atto_html-beautify/moodle-atto_html-beautify.js @@ -77,7 +77,7 @@ Y.namespace('M.atto_html').beautify = exports; } } space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()", - NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) + NOTE: This option is overridden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" | any of the former + ",preserve-inline" put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. @@ -928,7 +928,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) { - if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { + if (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.SEMICOLON]) && !this._flags.inline_frame) { this.print_newline(); } else { this._output.space_before_token = true; @@ -1054,7 +1054,9 @@ Beautifier.prototype.handle_word = function(current_token) { } if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { - if (!this.start_of_object_property()) { + if (!this.start_of_object_property() && !( + // start of object property is different for numeric values with +/- prefix operators + in_array(this._flags.last_token.text, ['+', '-']) && this._last_last_text === ':' && this._flags.parent.mode === MODE.ObjectLiteral)) { this.allow_wrap_or_preserved_newline(current_token); } } @@ -1335,6 +1337,12 @@ Beautifier.prototype.handle_operator = function(current_token) { return; } + if (in_array(current_token.text, ['-', '+']) && this.start_of_object_property()) { + // numeric value with +/- symbol in front as a property + this.print_token(current_token); + return; + } + // Allow line wrapping between operators when operator_position is // set to before or preserve if (this._flags.last_token.type === TOKEN.OPERATOR && in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)) { @@ -2161,12 +2169,13 @@ var nonASCIIidentifierChars = "\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u0 //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; -var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; +var unicodeEscapeOrCodePoint = "\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}"; +var identifierStart = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; +var identifierChars = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; exports.identifier = new RegExp(identifierStart + identifierChars, 'g'); exports.identifierStart = new RegExp(identifierStart); -exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); +exports.identifierMatch = new RegExp("(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line @@ -2355,10 +2364,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -2654,6 +2663,7 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_non_javascript(c); token = token || this._read_string(c); + token = token || this._read_pair(c, this._input.peek(1)); // Issue #2062 hack for record type '#{' token = token || this._read_word(previous_token); token = token || this._read_singles(c); token = token || this._read_comment(c); @@ -2712,6 +2722,19 @@ Tokenizer.prototype._read_singles = function(c) { return token; }; +Tokenizer.prototype._read_pair = function(c, d) { + var token = null; + if (c === '#' && d === '{') { + token = this._create_token(TOKEN.START_BLOCK, c + d); + } + + if (token) { + this._input.next(); + this._input.next(); + } + return token; +}; + Tokenizer.prototype._read_punctuation = function() { var resulting_string = this.__patterns.punct.read(); @@ -2957,6 +2980,9 @@ function unescape_string(s) { matched = input_scan.match(/x([0-9A-Fa-f]{2})/g); } else if (input_scan.peek() === 'u') { matched = input_scan.match(/u([0-9A-Fa-f]{4})/g); + if (!matched) { + matched = input_scan.match(/u\{([0-9A-Fa-f]+)\}/g); + } } else { out += '\\'; if (input_scan.hasNext()) { @@ -2980,7 +3006,9 @@ function unescape_string(s) { } else if (escaped >= 0x00 && escaped < 0x20) { // leave 0x00...0x1f escaped out += '\\' + matched[0]; - continue; + } else if (escaped > 0x10FFFF) { + // If the escape sequence is out of bounds, keep the original sequence and continue conversion + out += '\\' + matched[0]; } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) { // single-quote, apostrophe, backslash - escape these out += '\\' + String.fromCharCode(escaped); @@ -3803,7 +3831,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil @@ -4609,10 +4638,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -5115,18 +5144,18 @@ function Beautifier(source_text, options) { // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule this.NESTED_AT_RULE = { - "@page": true, - "@font-face": true, - "@keyframes": true, + "page": true, + "font-face": true, + "keyframes": true, // also in CONDITIONAL_GROUP_RULE below - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.CONDITIONAL_GROUP_RULE = { - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.NON_SEMICOLON_NEWLINE_PROPERTY = [ "grid-template-areas", @@ -5254,8 +5283,7 @@ Beautifier.prototype.beautify = function() { // label { content: blue } var insidePropertyValue = false; var enteringConditionalGroup = false; - var insideAtExtend = false; - var insideAtImport = false; + var insideNonNestedAtRule = false; var insideScssMap = false; var topCharacter = this._ch; var insideNonSemiColonValues = false; @@ -5310,10 +5338,30 @@ Beautifier.prototype.beautify = function() { // Ensures any new lines following the comment are preserved this.eatWhitespace(true); - } else if (this._ch === '@' || this._ch === '$') { + } else if (this._ch === '$') { + this.preserveSingleSpace(isAfterSpace); + + this.print_string(this._ch); + + // strip trailing space, if present, for hash property checks + var variable = this._input.peekUntilAfter(/[: ,;{}()[\]\/='"]/g); + + if (variable.match(/[ :]$/)) { + // we have a variable or pseudo-class, add it and insert one space before continuing + variable = this.eatString(": ").replace(/\s+$/, ''); + this.print_string(variable); + this._output.space_before_token = true; + } + + // might be sass variable + if (parenLevel === 0 && variable.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); + } + } else if (this._ch === '@') { this.preserveSingleSpace(isAfterSpace); - // deal with less propery mixins @{...} + // deal with less property mixins @{...} if (this._input.peek() === '{') { this.print_string(this._ch + this.eatString('}')); } else { @@ -5324,29 +5372,26 @@ Beautifier.prototype.beautify = function() { if (variableOrRule.match(/[ :]$/)) { // we have a variable or pseudo-class, add it and insert one space before continuing - variableOrRule = this.eatString(": ").replace(/\s$/, ''); + variableOrRule = this.eatString(": ").replace(/\s+$/, ''); this.print_string(variableOrRule); this._output.space_before_token = true; } - variableOrRule = variableOrRule.replace(/\s$/, ''); - - if (variableOrRule === 'extend') { - insideAtExtend = true; - } else if (variableOrRule === 'import') { - insideAtImport = true; - } + // might be less variable + if (parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); - // might be a nesting at-rule - if (variableOrRule in this.NESTED_AT_RULE) { + // might be a nesting at-rule + } else if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; if (variableOrRule in this.CONDITIONAL_GROUP_RULE) { enteringConditionalGroup = true; } - // might be less variable - } else if (!insideRule && parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { - insidePropertyValue = true; - this.indent(); + + // might be a non-nested at-rule + } else if (parenLevel === 0 && !insidePropertyValue) { + insideNonNestedAtRule = true; } } } else if (this._ch === '#' && this._input.peek() === '{') { @@ -5358,6 +5403,9 @@ Beautifier.prototype.beautify = function() { this.outdent(); } + // non nested at rule becomes nested + insideNonNestedAtRule = false; + // when entering conditional groups, only rulesets are allowed if (enteringConditionalGroup) { enteringConditionalGroup = false; @@ -5398,8 +5446,7 @@ Beautifier.prototype.beautify = function() { if (previous_ch === '{') { this._output.trim(true); } - insideAtImport = false; - insideAtExtend = false; + if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -5433,9 +5480,10 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideNonNestedAtRule && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query + this.print_string(':'); if (!insidePropertyValue) { insidePropertyValue = true; @@ -5472,8 +5520,7 @@ Beautifier.prototype.beautify = function() { this.outdent(); insidePropertyValue = false; } - insideAtExtend = false; - insideAtImport = false; + insideNonNestedAtRule = false; this.print_string(this._ch); this.eatWhitespace(true); @@ -5538,7 +5585,7 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) { + if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideNonNestedAtRule) { this._output.add_new_line(); } else { this._output.space_before_token = true; @@ -6353,10 +6400,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -7229,7 +7276,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil @@ -7572,6 +7620,13 @@ Printer.prototype.indent = function() { this.indent_level++; }; +Printer.prototype.deindent = function() { + if (this.indent_level > 0) { + this.indent_level--; + this._output.set_indent(this.indent_level, this.alignment_size); + } +}; + Printer.prototype.get_full_indent = function(level) { level = this.indent_level + (level || 0); if (level < 1) { @@ -7757,15 +7812,19 @@ Beautifier.prototype.beautify = function() { while (raw_token.type !== TOKEN.EOF) { if (raw_token.type === TOKEN.TAG_OPEN || raw_token.type === TOKEN.COMMENT) { - parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token); + parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token, tokens); last_tag_token = parser_token; } else if ((raw_token.type === TOKEN.ATTRIBUTE || raw_token.type === TOKEN.EQUALS || raw_token.type === TOKEN.VALUE) || (raw_token.type === TOKEN.TEXT && !last_tag_token.tag_complete)) { - parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, tokens); + parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, last_token); } else if (raw_token.type === TOKEN.TAG_CLOSE) { parser_token = this._handle_tag_close(printer, raw_token, last_tag_token); } else if (raw_token.type === TOKEN.TEXT) { parser_token = this._handle_text(printer, raw_token, last_tag_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_OPEN) { + parser_token = this._handle_control_flow_open(printer, raw_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_CLOSE) { + parser_token = this._handle_control_flow_close(printer, raw_token); } else { // This should never happen, but if it does. Print the raw token printer.add_raw_token(raw_token); @@ -7780,6 +7839,38 @@ Beautifier.prototype.beautify = function() { return sweet_code; }; +Beautifier.prototype._handle_control_flow_open = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + printer.indent(); + return parser_token; +}; + +Beautifier.prototype._handle_control_flow_close = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + + printer.deindent(); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + return parser_token; +}; + Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_token) { var parser_token = { text: raw_token.text, @@ -7818,7 +7909,7 @@ Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_t return parser_token; }; -Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, tokens) { +Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, last_token) { var wrapped = last_tag_token.has_wrapped_attrs; var parser_token = { text: raw_token.text, @@ -7839,7 +7930,6 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ } else { if (raw_token.type === TOKEN.ATTRIBUTE) { printer.set_space_before_token(true); - last_tag_token.attr_count += 1; } else if (raw_token.type === TOKEN.EQUALS) { //no space before = printer.set_space_before_token(false); } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value @@ -7852,29 +7942,15 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ wrapped = wrapped || raw_token.newlines !== 0; } - - if (this._is_wrap_attributes_force) { - var force_attr_wrap = last_tag_token.attr_count > 1; - if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) { - var is_only_attribute = true; - var peek_index = 0; - var peek_token; - do { - peek_token = tokens.peek(peek_index); - if (peek_token.type === TOKEN.ATTRIBUTE) { - is_only_attribute = false; - break; - } - peek_index += 1; - } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE); - - force_attr_wrap = !is_only_attribute; - } - - if (force_attr_wrap) { - printer.print_newline(false); - wrapped = true; - } + // Wrap for 'force' options, and if the number of attributes is at least that specified in 'wrap_attributes_min_attrs': + // 1. always wrap the second and beyond attributes + // 2. wrap the first attribute only if 'force-expand-multiline' is specified + if (this._is_wrap_attributes_force && + last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && + (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond + this._is_wrap_attributes_force_expand_multiline)) { + printer.print_newline(false); + wrapped = true; } } printer.print_token(raw_token); @@ -8003,12 +8079,12 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, } }; -Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token) { +Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token, tokens) { var parser_token = this._get_tag_open_token(raw_token); if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) && !last_tag_token.is_empty_element && - raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf(' tag special case: -var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; +var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']; Beautifier.prototype._do_optional_end_element = function(parser_token) { @@ -8249,7 +8338,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) { } else if (parser_token.tag_name === 'li') { // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. - result = result || this._tag_stack.try_pop('li', ['ol', 'ul']); + result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element. @@ -8388,6 +8477,7 @@ function Options(options) { this.indent_handlebars = this._get_boolean('indent_handlebars', true); this.wrap_attributes = this._get_selection('wrap_attributes', ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple', 'preserve', 'preserve-aligned']); + this.wrap_attributes_min_attrs = this._get_number('wrap_attributes_min_attrs', 2); this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size); this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']); @@ -8405,6 +8495,7 @@ function Options(options) { // obsolete inline tags 'acronym', 'big', 'strike', 'tt' ]); + this.inline_custom_elements = this._get_boolean('inline_custom_elements', true); this.void_elements = this._get_array('void_elements', [ // HTLM void elements - aka self-closing tags - aka singletons // https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements @@ -8479,6 +8570,8 @@ var Pattern = (__webpack_require__(12).Pattern); var TOKEN = { TAG_OPEN: 'TK_TAG_OPEN', TAG_CLOSE: 'TK_TAG_CLOSE', + CONTROL_FLOW_OPEN: 'TK_CONTROL_FLOW_OPEN', + CONTROL_FLOW_CLOSE: 'TK_CONTROL_FLOW_CLOSE', ATTRIBUTE: 'TK_ATTRIBUTE', EQUALS: 'TK_EQUALS', VALUE: 'TK_VALUE', @@ -8503,11 +8596,13 @@ var Tokenizer = function(input_string, options) { this.__patterns = { word: templatable_reader.until(/[\n\r\t <]/), + word_control_flow_close_excluded: templatable_reader.until(/[\n\r\t <}]/), single_quote: templatable_reader.until_after(/'/), double_quote: templatable_reader.until_after(/"/), attribute: templatable_reader.until(/[\n\r\t =>]|\/>/), element_name: templatable_reader.until(/[\n\r\t >\/]/), + angular_control_flow_start: pattern_reader.matching(/\@[a-zA-Z]+[^({]*[({]/), handlebars_comment: pattern_reader.starting_with(/{{!--/).until_after(/--}}/), handlebars: pattern_reader.starting_with(/{{/).until_after(/}}/), handlebars_open: pattern_reader.until(/[\n\r\t }]/), @@ -8521,6 +8616,7 @@ var Tokenizer = function(input_string, options) { if (this._options.indent_handlebars) { this.__patterns.word = this.__patterns.word.exclude('handlebars'); + this.__patterns.word_control_flow_close_excluded = this.__patterns.word_control_flow_close_excluded.exclude('handlebars'); } this._unformatted_content_delimiter = null; @@ -8539,14 +8635,16 @@ Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:fal }; Tokenizer.prototype._is_opening = function(current_token) { - return current_token.type === TOKEN.TAG_OPEN; + return current_token.type === TOKEN.TAG_OPEN || current_token.type === TOKEN.CONTROL_FLOW_OPEN; }; Tokenizer.prototype._is_closing = function(current_token, open_token) { - return current_token.type === TOKEN.TAG_CLOSE && + return (current_token.type === TOKEN.TAG_CLOSE && (open_token && ( ((current_token.text === '>' || current_token.text === '/>') && open_token.text[0] === '<') || - (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))); + (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))) + ) || (current_token.type === TOKEN.CONTROL_FLOW_CLOSE && + (current_token.text === '}' && open_token.text.endsWith('{'))); }; Tokenizer.prototype._reset = function() { @@ -8565,8 +8663,9 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_open_handlebars(c, open_token); token = token || this._read_attribute(c, previous_token, open_token); token = token || this._read_close(c, open_token); + token = token || this._read_control_flows(c, open_token); token = token || this._read_raw_content(c, previous_token, open_token); - token = token || this._read_content_word(c); + token = token || this._read_content_word(c, open_token); token = token || this._read_comment_or_cdata(c); token = token || this._read_processing(c); token = token || this._read_open(c, open_token); @@ -8631,7 +8730,7 @@ Tokenizer.prototype._read_processing = function(c) { // jshint unused:false Tokenizer.prototype._read_open = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (c === '<') { resulting_string = this._input.next(); @@ -8648,7 +8747,7 @@ Tokenizer.prototype._read_open = function(c, open_token) { Tokenizer.prototype._read_open_handlebars = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') { if (this._input.peek(2) === '!') { resulting_string = this.__patterns.handlebars_comment.read(); @@ -8663,11 +8762,48 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) { return token; }; +Tokenizer.prototype._read_control_flows = function(c, open_token) { + var resulting_string = ''; + var token = null; + // Only check for control flows if angular templating is set AND indenting is set + if (!this._options.templating.includes('angular') || !this._options.indent_handlebars) { + return token; + } + + if (c === '@') { + resulting_string = this.__patterns.angular_control_flow_start.read(); + if (resulting_string === '') { + return token; + } + + var opening_parentheses_count = resulting_string.endsWith('(') ? 1 : 0; + var closing_parentheses_count = 0; + // The opening brace of the control flow is where the number of opening and closing parentheses equal + // e.g. @if({value: true} !== null) { + while (!(resulting_string.endsWith('{') && opening_parentheses_count === closing_parentheses_count)) { + var next_char = this._input.next(); + if (next_char === null) { + break; + } else if (next_char === '(') { + opening_parentheses_count++; + } else if (next_char === ')') { + closing_parentheses_count++; + } + resulting_string += next_char; + } + token = this._create_token(TOKEN.CONTROL_FLOW_OPEN, resulting_string); + } else if (c === '}' && open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) { + resulting_string = this._input.next(); + token = this._create_token(TOKEN.CONTROL_FLOW_CLOSE, resulting_string); + } + return token; +}; + Tokenizer.prototype._read_close = function(c, open_token) { var resulting_string = null; var token = null; - if (open_token) { + if (open_token && open_token.type === TOKEN.TAG_OPEN) { if (open_token.text[0] === '<' && (c === '>' || (c === '/' && this._input.peek(1) === '>'))) { resulting_string = this._input.next(); if (c === '/') { // for close tag "/>" @@ -8754,7 +8890,7 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) return null; }; -Tokenizer.prototype._read_content_word = function(c) { +Tokenizer.prototype._read_content_word = function(c, open_token) { var resulting_string = ''; if (this._options.unformatted_content_delimiter) { if (c === this._options.unformatted_content_delimiter[0]) { @@ -8763,7 +8899,7 @@ Tokenizer.prototype._read_content_word = function(c) { } if (!resulting_string) { - resulting_string = this.__patterns.word.read(); + resulting_string = (open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) ? this.__patterns.word_control_flow_close_excluded.read() : this.__patterns.word.read(); } if (resulting_string) { return this._create_token(TOKEN.TEXT, resulting_string); diff --git a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-css.js b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-css.js index aa7d008bd8a4..36bc68577a63 100644 --- a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-css.js +++ b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-css.js @@ -571,10 +571,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -1077,18 +1077,18 @@ function Beautifier(source_text, options) { // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule this.NESTED_AT_RULE = { - "@page": true, - "@font-face": true, - "@keyframes": true, + "page": true, + "font-face": true, + "keyframes": true, // also in CONDITIONAL_GROUP_RULE below - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.CONDITIONAL_GROUP_RULE = { - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.NON_SEMICOLON_NEWLINE_PROPERTY = [ "grid-template-areas", @@ -1216,8 +1216,7 @@ Beautifier.prototype.beautify = function() { // label { content: blue } var insidePropertyValue = false; var enteringConditionalGroup = false; - var insideAtExtend = false; - var insideAtImport = false; + var insideNonNestedAtRule = false; var insideScssMap = false; var topCharacter = this._ch; var insideNonSemiColonValues = false; @@ -1272,10 +1271,30 @@ Beautifier.prototype.beautify = function() { // Ensures any new lines following the comment are preserved this.eatWhitespace(true); - } else if (this._ch === '@' || this._ch === '$') { + } else if (this._ch === '$') { this.preserveSingleSpace(isAfterSpace); - // deal with less propery mixins @{...} + this.print_string(this._ch); + + // strip trailing space, if present, for hash property checks + var variable = this._input.peekUntilAfter(/[: ,;{}()[\]\/='"]/g); + + if (variable.match(/[ :]$/)) { + // we have a variable or pseudo-class, add it and insert one space before continuing + variable = this.eatString(": ").replace(/\s+$/, ''); + this.print_string(variable); + this._output.space_before_token = true; + } + + // might be sass variable + if (parenLevel === 0 && variable.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); + } + } else if (this._ch === '@') { + this.preserveSingleSpace(isAfterSpace); + + // deal with less property mixins @{...} if (this._input.peek() === '{') { this.print_string(this._ch + this.eatString('}')); } else { @@ -1286,29 +1305,26 @@ Beautifier.prototype.beautify = function() { if (variableOrRule.match(/[ :]$/)) { // we have a variable or pseudo-class, add it and insert one space before continuing - variableOrRule = this.eatString(": ").replace(/\s$/, ''); + variableOrRule = this.eatString(": ").replace(/\s+$/, ''); this.print_string(variableOrRule); this._output.space_before_token = true; } - variableOrRule = variableOrRule.replace(/\s$/, ''); - - if (variableOrRule === 'extend') { - insideAtExtend = true; - } else if (variableOrRule === 'import') { - insideAtImport = true; - } + // might be less variable + if (parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); - // might be a nesting at-rule - if (variableOrRule in this.NESTED_AT_RULE) { + // might be a nesting at-rule + } else if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; if (variableOrRule in this.CONDITIONAL_GROUP_RULE) { enteringConditionalGroup = true; } - // might be less variable - } else if (!insideRule && parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { - insidePropertyValue = true; - this.indent(); + + // might be a non-nested at-rule + } else if (parenLevel === 0 && !insidePropertyValue) { + insideNonNestedAtRule = true; } } } else if (this._ch === '#' && this._input.peek() === '{') { @@ -1320,6 +1336,9 @@ Beautifier.prototype.beautify = function() { this.outdent(); } + // non nested at rule becomes nested + insideNonNestedAtRule = false; + // when entering conditional groups, only rulesets are allowed if (enteringConditionalGroup) { enteringConditionalGroup = false; @@ -1360,8 +1379,7 @@ Beautifier.prototype.beautify = function() { if (previous_ch === '{') { this._output.trim(true); } - insideAtImport = false; - insideAtExtend = false; + if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -1395,9 +1413,10 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideNonNestedAtRule && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query + this.print_string(':'); if (!insidePropertyValue) { insidePropertyValue = true; @@ -1434,8 +1453,7 @@ Beautifier.prototype.beautify = function() { this.outdent(); insidePropertyValue = false; } - insideAtExtend = false; - insideAtImport = false; + insideNonNestedAtRule = false; this.print_string(this._ch); this.eatWhitespace(true); @@ -1500,7 +1518,7 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) { + if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideNonNestedAtRule) { this._output.add_new_line(); } else { this._output.space_before_token = true; diff --git a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-html.js b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-html.js index ff60dace527c..48fa73716ab9 100644 --- a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-html.js +++ b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify-html.js @@ -640,10 +640,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -1516,7 +1516,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil @@ -1859,6 +1860,13 @@ Printer.prototype.indent = function() { this.indent_level++; }; +Printer.prototype.deindent = function() { + if (this.indent_level > 0) { + this.indent_level--; + this._output.set_indent(this.indent_level, this.alignment_size); + } +}; + Printer.prototype.get_full_indent = function(level) { level = this.indent_level + (level || 0); if (level < 1) { @@ -2044,15 +2052,19 @@ Beautifier.prototype.beautify = function() { while (raw_token.type !== TOKEN.EOF) { if (raw_token.type === TOKEN.TAG_OPEN || raw_token.type === TOKEN.COMMENT) { - parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token); + parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token, tokens); last_tag_token = parser_token; } else if ((raw_token.type === TOKEN.ATTRIBUTE || raw_token.type === TOKEN.EQUALS || raw_token.type === TOKEN.VALUE) || (raw_token.type === TOKEN.TEXT && !last_tag_token.tag_complete)) { - parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, tokens); + parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, last_token); } else if (raw_token.type === TOKEN.TAG_CLOSE) { parser_token = this._handle_tag_close(printer, raw_token, last_tag_token); } else if (raw_token.type === TOKEN.TEXT) { parser_token = this._handle_text(printer, raw_token, last_tag_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_OPEN) { + parser_token = this._handle_control_flow_open(printer, raw_token); + } else if (raw_token.type === TOKEN.CONTROL_FLOW_CLOSE) { + parser_token = this._handle_control_flow_close(printer, raw_token); } else { // This should never happen, but if it does. Print the raw token printer.add_raw_token(raw_token); @@ -2067,6 +2079,38 @@ Beautifier.prototype.beautify = function() { return sweet_code; }; +Beautifier.prototype._handle_control_flow_open = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + printer.indent(); + return parser_token; +}; + +Beautifier.prototype._handle_control_flow_close = function(printer, raw_token) { + var parser_token = { + text: raw_token.text, + type: raw_token.type + }; + + printer.deindent(); + if (raw_token.newlines) { + printer.print_preserved_newlines(raw_token); + } else { + printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true); + } + printer.print_token(raw_token); + return parser_token; +}; + Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_token) { var parser_token = { text: raw_token.text, @@ -2105,7 +2149,7 @@ Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_t return parser_token; }; -Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, tokens) { +Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, last_token) { var wrapped = last_tag_token.has_wrapped_attrs; var parser_token = { text: raw_token.text, @@ -2126,7 +2170,6 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ } else { if (raw_token.type === TOKEN.ATTRIBUTE) { printer.set_space_before_token(true); - last_tag_token.attr_count += 1; } else if (raw_token.type === TOKEN.EQUALS) { //no space before = printer.set_space_before_token(false); } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value @@ -2139,29 +2182,15 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ wrapped = wrapped || raw_token.newlines !== 0; } - - if (this._is_wrap_attributes_force) { - var force_attr_wrap = last_tag_token.attr_count > 1; - if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) { - var is_only_attribute = true; - var peek_index = 0; - var peek_token; - do { - peek_token = tokens.peek(peek_index); - if (peek_token.type === TOKEN.ATTRIBUTE) { - is_only_attribute = false; - break; - } - peek_index += 1; - } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE); - - force_attr_wrap = !is_only_attribute; - } - - if (force_attr_wrap) { - printer.print_newline(false); - wrapped = true; - } + // Wrap for 'force' options, and if the number of attributes is at least that specified in 'wrap_attributes_min_attrs': + // 1. always wrap the second and beyond attributes + // 2. wrap the first attribute only if 'force-expand-multiline' is specified + if (this._is_wrap_attributes_force && + last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && + (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond + this._is_wrap_attributes_force_expand_multiline)) { + printer.print_newline(false); + wrapped = true; } } printer.print_token(raw_token); @@ -2290,12 +2319,12 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, } }; -Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token) { +Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token, tokens) { var parser_token = this._get_tag_open_token(raw_token); if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) && !last_tag_token.is_empty_element && - raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf(' tag special case: -var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; +var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']; Beautifier.prototype._do_optional_end_element = function(parser_token) { @@ -2536,7 +2578,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) { } else if (parser_token.tag_name === 'li') { // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element. - result = result || this._tag_stack.try_pop('li', ['ol', 'ul']); + result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element. @@ -2675,6 +2717,7 @@ function Options(options) { this.indent_handlebars = this._get_boolean('indent_handlebars', true); this.wrap_attributes = this._get_selection('wrap_attributes', ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple', 'preserve', 'preserve-aligned']); + this.wrap_attributes_min_attrs = this._get_number('wrap_attributes_min_attrs', 2); this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size); this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']); @@ -2692,6 +2735,7 @@ function Options(options) { // obsolete inline tags 'acronym', 'big', 'strike', 'tt' ]); + this.inline_custom_elements = this._get_boolean('inline_custom_elements', true); this.void_elements = this._get_array('void_elements', [ // HTLM void elements - aka self-closing tags - aka singletons // https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements @@ -2766,6 +2810,8 @@ var Pattern = (__webpack_require__(12).Pattern); var TOKEN = { TAG_OPEN: 'TK_TAG_OPEN', TAG_CLOSE: 'TK_TAG_CLOSE', + CONTROL_FLOW_OPEN: 'TK_CONTROL_FLOW_OPEN', + CONTROL_FLOW_CLOSE: 'TK_CONTROL_FLOW_CLOSE', ATTRIBUTE: 'TK_ATTRIBUTE', EQUALS: 'TK_EQUALS', VALUE: 'TK_VALUE', @@ -2790,11 +2836,13 @@ var Tokenizer = function(input_string, options) { this.__patterns = { word: templatable_reader.until(/[\n\r\t <]/), + word_control_flow_close_excluded: templatable_reader.until(/[\n\r\t <}]/), single_quote: templatable_reader.until_after(/'/), double_quote: templatable_reader.until_after(/"/), attribute: templatable_reader.until(/[\n\r\t =>]|\/>/), element_name: templatable_reader.until(/[\n\r\t >\/]/), + angular_control_flow_start: pattern_reader.matching(/\@[a-zA-Z]+[^({]*[({]/), handlebars_comment: pattern_reader.starting_with(/{{!--/).until_after(/--}}/), handlebars: pattern_reader.starting_with(/{{/).until_after(/}}/), handlebars_open: pattern_reader.until(/[\n\r\t }]/), @@ -2808,6 +2856,7 @@ var Tokenizer = function(input_string, options) { if (this._options.indent_handlebars) { this.__patterns.word = this.__patterns.word.exclude('handlebars'); + this.__patterns.word_control_flow_close_excluded = this.__patterns.word_control_flow_close_excluded.exclude('handlebars'); } this._unformatted_content_delimiter = null; @@ -2826,14 +2875,16 @@ Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:fal }; Tokenizer.prototype._is_opening = function(current_token) { - return current_token.type === TOKEN.TAG_OPEN; + return current_token.type === TOKEN.TAG_OPEN || current_token.type === TOKEN.CONTROL_FLOW_OPEN; }; Tokenizer.prototype._is_closing = function(current_token, open_token) { - return current_token.type === TOKEN.TAG_CLOSE && + return (current_token.type === TOKEN.TAG_CLOSE && (open_token && ( ((current_token.text === '>' || current_token.text === '/>') && open_token.text[0] === '<') || - (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))); + (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{'))) + ) || (current_token.type === TOKEN.CONTROL_FLOW_CLOSE && + (current_token.text === '}' && open_token.text.endsWith('{'))); }; Tokenizer.prototype._reset = function() { @@ -2852,8 +2903,9 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_open_handlebars(c, open_token); token = token || this._read_attribute(c, previous_token, open_token); token = token || this._read_close(c, open_token); + token = token || this._read_control_flows(c, open_token); token = token || this._read_raw_content(c, previous_token, open_token); - token = token || this._read_content_word(c); + token = token || this._read_content_word(c, open_token); token = token || this._read_comment_or_cdata(c); token = token || this._read_processing(c); token = token || this._read_open(c, open_token); @@ -2918,7 +2970,7 @@ Tokenizer.prototype._read_processing = function(c) { // jshint unused:false Tokenizer.prototype._read_open = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (c === '<') { resulting_string = this._input.next(); @@ -2935,7 +2987,7 @@ Tokenizer.prototype._read_open = function(c, open_token) { Tokenizer.prototype._read_open_handlebars = function(c, open_token) { var resulting_string = null; var token = null; - if (!open_token) { + if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) { if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') { if (this._input.peek(2) === '!') { resulting_string = this.__patterns.handlebars_comment.read(); @@ -2950,11 +3002,48 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) { return token; }; +Tokenizer.prototype._read_control_flows = function(c, open_token) { + var resulting_string = ''; + var token = null; + // Only check for control flows if angular templating is set AND indenting is set + if (!this._options.templating.includes('angular') || !this._options.indent_handlebars) { + return token; + } + + if (c === '@') { + resulting_string = this.__patterns.angular_control_flow_start.read(); + if (resulting_string === '') { + return token; + } + + var opening_parentheses_count = resulting_string.endsWith('(') ? 1 : 0; + var closing_parentheses_count = 0; + // The opening brace of the control flow is where the number of opening and closing parentheses equal + // e.g. @if({value: true} !== null) { + while (!(resulting_string.endsWith('{') && opening_parentheses_count === closing_parentheses_count)) { + var next_char = this._input.next(); + if (next_char === null) { + break; + } else if (next_char === '(') { + opening_parentheses_count++; + } else if (next_char === ')') { + closing_parentheses_count++; + } + resulting_string += next_char; + } + token = this._create_token(TOKEN.CONTROL_FLOW_OPEN, resulting_string); + } else if (c === '}' && open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) { + resulting_string = this._input.next(); + token = this._create_token(TOKEN.CONTROL_FLOW_CLOSE, resulting_string); + } + return token; +}; + Tokenizer.prototype._read_close = function(c, open_token) { var resulting_string = null; var token = null; - if (open_token) { + if (open_token && open_token.type === TOKEN.TAG_OPEN) { if (open_token.text[0] === '<' && (c === '>' || (c === '/' && this._input.peek(1) === '>'))) { resulting_string = this._input.next(); if (c === '/') { // for close tag "/>" @@ -3041,7 +3130,7 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) return null; }; -Tokenizer.prototype._read_content_word = function(c) { +Tokenizer.prototype._read_content_word = function(c, open_token) { var resulting_string = ''; if (this._options.unformatted_content_delimiter) { if (c === this._options.unformatted_content_delimiter[0]) { @@ -3050,7 +3139,7 @@ Tokenizer.prototype._read_content_word = function(c) { } if (!resulting_string) { - resulting_string = this.__patterns.word.read(); + resulting_string = (open_token && open_token.type === TOKEN.CONTROL_FLOW_OPEN) ? this.__patterns.word_control_flow_close_excluded.read() : this.__patterns.word.read(); } if (resulting_string) { return this._create_token(TOKEN.TEXT, resulting_string); diff --git a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify.js b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify.js index d02605dca719..377364038124 100644 --- a/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify.js +++ b/lib/editor/atto/plugins/html/yui/src/beautify/js/beautify.js @@ -59,7 +59,7 @@ } } space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()", - NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) + NOTE: This option is overridden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" | any of the former + ",preserve-inline" put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. @@ -910,7 +910,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) { - if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { + if (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.SEMICOLON]) && !this._flags.inline_frame) { this.print_newline(); } else { this._output.space_before_token = true; @@ -1036,7 +1036,9 @@ Beautifier.prototype.handle_word = function(current_token) { } if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { - if (!this.start_of_object_property()) { + if (!this.start_of_object_property() && !( + // start of object property is different for numeric values with +/- prefix operators + in_array(this._flags.last_token.text, ['+', '-']) && this._last_last_text === ':' && this._flags.parent.mode === MODE.ObjectLiteral)) { this.allow_wrap_or_preserved_newline(current_token); } } @@ -1317,6 +1319,12 @@ Beautifier.prototype.handle_operator = function(current_token) { return; } + if (in_array(current_token.text, ['-', '+']) && this.start_of_object_property()) { + // numeric value with +/- symbol in front as a property + this.print_token(current_token); + return; + } + // Allow line wrapping between operators when operator_position is // set to before or preserve if (this._flags.last_token.type === TOKEN.OPERATOR && in_array(this._options.operator_position, OPERATOR_POSITION_BEFORE_OR_PRESERVE)) { @@ -2143,12 +2151,13 @@ var nonASCIIidentifierChars = "\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u0 //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; -var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; +var unicodeEscapeOrCodePoint = "\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}"; +var identifierStart = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])"; +var identifierChars = "(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*"; exports.identifier = new RegExp(identifierStart + identifierChars, 'g'); exports.identifierStart = new RegExp(identifierStart); -exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); +exports.identifierMatch = new RegExp("(?:" + unicodeEscapeOrCodePoint + "|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+"); var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line @@ -2337,10 +2346,10 @@ function Options(options, merge_child_field) { this.indent_empty_lines = this._get_boolean('indent_empty_lines'); - // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty'] - // For now, 'auto' = all off for javascript, all on for html (and inline javascript). + // valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty', 'angular'] + // For now, 'auto' = all off for javascript, all except angular on for html (and inline javascript/css). // other values ignored - this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); + this.templating = this._get_selection_list('templating', ['auto', 'none', 'angular', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']); } Options.prototype._get_array = function(name, default_value) { @@ -2636,6 +2645,7 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_non_javascript(c); token = token || this._read_string(c); + token = token || this._read_pair(c, this._input.peek(1)); // Issue #2062 hack for record type '#{' token = token || this._read_word(previous_token); token = token || this._read_singles(c); token = token || this._read_comment(c); @@ -2694,6 +2704,19 @@ Tokenizer.prototype._read_singles = function(c) { return token; }; +Tokenizer.prototype._read_pair = function(c, d) { + var token = null; + if (c === '#' && d === '{') { + token = this._create_token(TOKEN.START_BLOCK, c + d); + } + + if (token) { + this._input.next(); + this._input.next(); + } + return token; +}; + Tokenizer.prototype._read_punctuation = function() { var resulting_string = this.__patterns.punct.read(); @@ -2939,6 +2962,9 @@ function unescape_string(s) { matched = input_scan.match(/x([0-9A-Fa-f]{2})/g); } else if (input_scan.peek() === 'u') { matched = input_scan.match(/u([0-9A-Fa-f]{4})/g); + if (!matched) { + matched = input_scan.match(/u\{([0-9A-Fa-f]+)\}/g); + } } else { out += '\\'; if (input_scan.hasNext()) { @@ -2962,7 +2988,9 @@ function unescape_string(s) { } else if (escaped >= 0x00 && escaped < 0x20) { // leave 0x00...0x1f escaped out += '\\' + matched[0]; - continue; + } else if (escaped > 0x10FFFF) { + // If the escape sequence is out of bounds, keep the original sequence and continue conversion + out += '\\' + matched[0]; } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) { // single-quote, apostrophe, backslash - escape these out += '\\' + String.fromCharCode(escaped); @@ -3785,7 +3813,8 @@ var template_names = { erb: false, handlebars: false, php: false, - smarty: false + smarty: false, + angular: false }; // This lets templates appear anywhere we would do a readUntil diff --git a/lib/editor/atto/plugins/html/yui/src/beautify/readme_moodle.txt b/lib/editor/atto/plugins/html/yui/src/beautify/readme_moodle.txt index 50583795bcd4..150a51141586 100644 --- a/lib/editor/atto/plugins/html/yui/src/beautify/readme_moodle.txt +++ b/lib/editor/atto/plugins/html/yui/src/beautify/readme_moodle.txt @@ -1,7 +1,7 @@ Description of importing the js-beautify library into Moodle. * Download the latest version from https://github.com/beautify-web/js-beautify/releases -* Copy lib/beautify*.js into lib/editor/atto/plugins/html/yui/src/beautify/js +* Copy js/lib/beautify*.js into lib/editor/atto/plugins/html/yui/src/beautify/js * Copy LICENSE into lib/editor/atto/plugins/html/yui/src/beautify * Update lib/editor/atto/plugins/html/thirdpartylibs.xml * Rebuild the module diff --git a/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php b/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php index dd88bf64b8a7..78788f06e978 100644 --- a/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php +++ b/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php @@ -25,8 +25,8 @@ defined('MOODLE_INTERNAL') || die(); -$string['pluginname'] = 'Tiny premium'; +$string['pluginname'] = 'TinyMCE Premium'; $string['apikey'] = 'API key'; -$string['apikey_desc'] = 'Your Tiny premium API key requires a paid subscription. You can find your key on your Tiny Cloud account page.'; -$string['premium:accesspremium'] = 'Access Tiny Premium features'; +$string['apikey_desc'] = '

Your API key is available on your Tiny Cloud account page if you have purchased a subscription, or if you are on a free trial.

See the list of available TinyMCE Premium features for Moodle in Moodle Docs.

'; +$string['premium:accesspremium'] = 'Access TinyMCE Premium features'; $string['privacy:metadata'] = 'The Tiny premium plugin for TinyMCE does not store any personal data.'; diff --git a/lib/external/tests/external_api_test.php b/lib/external/tests/external_api_test.php index cc359cae2294..f806785b7797 100644 --- a/lib/external/tests/external_api_test.php +++ b/lib/external/tests/external_api_test.php @@ -469,7 +469,6 @@ public function test_call_external_function(): void { protected function get_context_from_params() { $rc = new \ReflectionClass(external_api::class); $method = $rc->getMethod('get_context_from_params'); - $method->setAccessible(true); return $method->invokeArgs(null, func_get_args()); } } diff --git a/lib/filestorage/tests/file_system_filedir_test.php b/lib/filestorage/tests/file_system_filedir_test.php index 2d7532f405d1..69d5bca3462e 100644 --- a/lib/filestorage/tests/file_system_filedir_test.php +++ b/lib/filestorage/tests/file_system_filedir_test.php @@ -218,7 +218,6 @@ public function test_get_remote_path_from_hash() { ->willReturn($expectedresult); $method = new \ReflectionMethod(file_system_filedir::class, 'get_remote_path_from_hash'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$contenthash]); $this->assertEquals($expectedresult, $result); @@ -294,7 +293,6 @@ public function test_get_fulldir_from_hash($hash, $hashdir) { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'get_fulldir_from_hash'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($hash)); $expectedpath = sprintf('%s/filedir/%s', $CFG->dataroot, $hashdir); @@ -326,7 +324,6 @@ public function test_get_fulldir_from_storedfile($hash, $hashdir) { $fs = new file_system_filedir(); $method = new \ReflectionMethod('file_system_filedir', 'get_fulldir_from_storedfile'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); $expectedpath = sprintf('%s/filedir/%s', $CFG->dataroot, $hashdir); @@ -345,7 +342,6 @@ public function test_get_fulldir_from_storedfile($hash, $hashdir) { */ public function test_get_contentdir_from_hash($hash, $hashdir) { $method = new \ReflectionMethod(file_system_filedir::class, 'get_contentdir_from_hash'); - $method->setAccessible(true); $fs = new file_system_filedir(); $result = $method->invokeArgs($fs, array($hash)); @@ -365,7 +361,6 @@ public function test_get_contentdir_from_hash($hash, $hashdir) { */ public function test_get_contentpath_from_hash($hash, $hashdir) { $method = new \ReflectionMethod(file_system_filedir::class, 'get_contentpath_from_hash'); - $method->setAccessible(true); $fs = new file_system_filedir(); $result = $method->invokeArgs($fs, array($hash)); @@ -389,7 +384,6 @@ public function test_get_trash_fullpath_from_hash($hash, $hashdir) { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'get_trash_fullpath_from_hash'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($hash)); $expectedpath = sprintf('%s/trashdir/%s/%s', $CFG->dataroot, $hashdir, $hash); @@ -411,7 +405,6 @@ public function test_get_trash_fulldir_from_hash($hash, $hashdir) { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'get_trash_fulldir_from_hash'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($hash)); $expectedpath = sprintf('%s/trashdir/%s', $CFG->dataroot, $hashdir); @@ -486,7 +479,6 @@ public function test_recover_file() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -526,7 +518,6 @@ public function test_recover_file_already_present() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -564,7 +555,6 @@ public function test_recover_file_size_mismatch() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -601,7 +591,6 @@ public function test_recover_file_has_mismatch() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -635,7 +624,6 @@ public function test_recover_file_alttrash() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -675,7 +663,6 @@ public function test_recover_file_contentdir_readonly() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'recover_file'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, array($file)); // Test the output. @@ -1092,7 +1079,6 @@ public function test_empty_trash() { $fs = new file_system_filedir(); $method = new \ReflectionMethod(file_system_filedir::class, 'empty_trash'); - $method->setAccessible(true); $result = $method->invoke($fs); $this->assertTrue($vfileroot->hasChild('filedir/0f/f3/' . $contenthash)); diff --git a/lib/filestorage/tests/file_system_test.php b/lib/filestorage/tests/file_system_test.php index 9a854308ed93..edd1d8d1075f 100644 --- a/lib/filestorage/tests/file_system_test.php +++ b/lib/filestorage/tests/file_system_test.php @@ -494,7 +494,6 @@ public function test_is_file_removable_empty() { $contenthash = \file_storage::hash_from_string($filecontent); $method = new \ReflectionMethod(file_system::class, 'is_file_removable'); - $method->setAccessible(true); $result = $method->invokeArgs(null, [$contenthash]); $this->assertFalse($result); } @@ -517,7 +516,6 @@ public function test_is_file_removable_in_use() { $DB->method('record_exists')->willReturn(true); $method = new \ReflectionMethod(file_system::class, 'is_file_removable'); - $method->setAccessible(true); $result = $method->invokeArgs(null, [$contenthash]); $this->assertFalse($result); @@ -541,7 +539,6 @@ public function test_is_file_removable_not_in_use() { $DB->method('record_exists')->willReturn(false); $method = new \ReflectionMethod(file_system::class, 'is_file_removable'); - $method->setAccessible(true); $result = $method->invokeArgs(null, [$contenthash]); $this->assertTrue($result); @@ -910,7 +907,6 @@ public function test_get_imageinfo_from_path() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertArrayHasKey('width', $result); @@ -932,7 +928,6 @@ public function test_get_imageinfo_from_path_no_image() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertFalse($result); @@ -949,7 +944,6 @@ public function test_get_imageinfo_from_path_svg_viewbox() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertArrayHasKey('width', $result); @@ -971,7 +965,6 @@ public function test_get_imageinfo_from_path_svg_with_width_height() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertArrayHasKey('width', $result); @@ -993,7 +986,6 @@ public function test_get_imageinfo_from_path_svg_without_attribute() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertArrayHasKey('width', $result); @@ -1015,7 +1007,6 @@ public function test_get_imageinfo_from_path_svg_invalid() { $fs = $this->get_testable_mock(); $method = new \ReflectionMethod(file_system::class, 'get_imageinfo_from_path'); - $method->setAccessible(true); $result = $method->invokeArgs($fs, [$filepath]); $this->assertFalse($result); diff --git a/lib/form/amd/build/events.min.js b/lib/form/amd/build/events.min.js index 1769f39fabae..2dcca565d70b 100644 --- a/lib/form/amd/build/events.min.js +++ b/lib/form/amd/build/events.min.js @@ -14,6 +14,6 @@ define("core_form/events",["exports","core/str","core/event_dispatcher","jquery" * window.console.log(e.target); // The form that was submitted. * window.console.log(e.detail.skipValidation); // Whether form validation was skipped. * }); - */let changesMadeString;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.types=_exports.triggerUploadStarted=_exports.triggerUploadCompleted=_exports.notifyUploadStarted=_exports.notifyUploadCompleted=_exports.notifyUploadChanged=_exports.notifyFormSubmittedByJavascript=_exports.notifyFormError=_exports.notifyFieldValidationFailure=_exports.eventTypes=void 0,_jquery=_interopRequireDefault(_jquery),_yui=_interopRequireDefault(_yui);const changesMadeCheck=e=>{e&&(e.returnValue=changesMadeString)},eventTypes={formError:"core_form/error",formSubmittedByJavascript:"core_form/submittedByJavascript",formFieldValidationFailed:"core_form/fieldValidationFailed",uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted",uploadChanged:"core_form/uploadChanged"};_exports.eventTypes=eventTypes;_exports.notifyFormError=field=>(0,_event_dispatcher.dispatchEvent)(eventTypes.formError,{},field);_exports.notifyFormSubmittedByJavascript=function(form){let skipValidation=arguments.length>1&&void 0!==arguments[1]&&arguments[1],fallbackHandled=arguments.length>2&&void 0!==arguments[2]&&arguments[2];skipValidation&&(window.skipClientValidation=!0);const customEvent=(0,_event_dispatcher.dispatchEvent)(eventTypes.formSubmittedByJavascript,{skipValidation:skipValidation,fallbackHandled:fallbackHandled},form);return skipValidation&&(window.skipClientValidation=!1),customEvent};_exports.notifyFieldValidationFailure=(field,message)=>(0,_event_dispatcher.dispatchEvent)(eventTypes.formFieldValidationFailed,{message:message},field,{cancelable:!0});const notifyUploadStarted=async elementId=>(changesMadeString=await(0,_str.getString)("changesmadereallygoaway","moodle"),window.addEventListener("beforeunload",changesMadeCheck),(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadStarted,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1}));_exports.notifyUploadStarted=notifyUploadStarted;const notifyUploadCompleted=elementId=>(window.removeEventListener("beforeunload",changesMadeCheck),(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadCompleted,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1}));_exports.notifyUploadCompleted=notifyUploadCompleted;const triggerUploadStarted=notifyUploadStarted;_exports.triggerUploadStarted=triggerUploadStarted;const triggerUploadCompleted=notifyUploadCompleted;_exports.triggerUploadCompleted=triggerUploadCompleted;_exports.types={uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted"};let legacyEventsRegistered=!1;legacyEventsRegistered||(_yui.default.use("event","moodle-core-event",(()=>{document.addEventListener(eventTypes.formError,(e=>{const element=_yui.default.one(e.target),formElement=_yui.default.one(e.target.closest("form"));_yui.default.Global.fire(M.core.globalEvents.FORM_ERROR,{formid:formElement.generateID(),elementid:element.generateID()})})),document.addEventListener(eventTypes.formSubmittedByJavascript,(e=>{if(e.detail.fallbackHandled)return;e.skipValidation&&(window.skipClientValidation=!0);const form=_yui.default.one(e.target);form.fire(M.core.event.FORM_SUBMIT_AJAX,{currentTarget:form,fallbackHandled:!0}),e.skipValidation&&(window.skipClientValidation=!1)}))})),document.addEventListener(eventTypes.formFieldValidationFailed,(e=>{const legacyEvent=_jquery.default.Event("core_form-field-validation");(0,_jquery.default)(e.target).trigger(legacyEvent,e.detail.message)})),legacyEventsRegistered=!0);_exports.notifyUploadChanged=elementId=>(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadChanged,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1})})); + */let changesMadeString;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.types=_exports.triggerUploadStarted=_exports.triggerUploadCompleted=_exports.notifyUploadStarted=_exports.notifyUploadCompleted=_exports.notifyUploadChanged=_exports.notifyFormSubmittedByJavascript=_exports.notifyFormError=_exports.notifyFieldValidationFailure=_exports.notifyFieldStructureChanged=_exports.eventTypes=void 0,_jquery=_interopRequireDefault(_jquery),_yui=_interopRequireDefault(_yui);const changesMadeCheck=e=>{e&&(e.returnValue=changesMadeString)},eventTypes={formError:"core_form/error",formSubmittedByJavascript:"core_form/submittedByJavascript",formFieldValidationFailed:"core_form/fieldValidationFailed",uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted",uploadChanged:"core_form/uploadChanged",fieldStructureChanged:"core_form/fieldStructureChanged"};_exports.eventTypes=eventTypes;_exports.notifyFormError=field=>(0,_event_dispatcher.dispatchEvent)(eventTypes.formError,{},field);_exports.notifyFormSubmittedByJavascript=function(form){let skipValidation=arguments.length>1&&void 0!==arguments[1]&&arguments[1],fallbackHandled=arguments.length>2&&void 0!==arguments[2]&&arguments[2];skipValidation&&(window.skipClientValidation=!0);const customEvent=(0,_event_dispatcher.dispatchEvent)(eventTypes.formSubmittedByJavascript,{skipValidation:skipValidation,fallbackHandled:fallbackHandled},form);return skipValidation&&(window.skipClientValidation=!1),customEvent};_exports.notifyFieldValidationFailure=(field,message)=>(0,_event_dispatcher.dispatchEvent)(eventTypes.formFieldValidationFailed,{message:message},field,{cancelable:!0});const notifyUploadStarted=async elementId=>(changesMadeString=await(0,_str.getString)("changesmadereallygoaway","moodle"),window.addEventListener("beforeunload",changesMadeCheck),(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadStarted,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1}));_exports.notifyUploadStarted=notifyUploadStarted;const notifyUploadCompleted=elementId=>(window.removeEventListener("beforeunload",changesMadeCheck),(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadCompleted,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1}));_exports.notifyUploadCompleted=notifyUploadCompleted;const triggerUploadStarted=notifyUploadStarted;_exports.triggerUploadStarted=triggerUploadStarted;const triggerUploadCompleted=notifyUploadCompleted;_exports.triggerUploadCompleted=triggerUploadCompleted;_exports.types={uploadStarted:"core_form/uploadStarted",uploadCompleted:"core_form/uploadCompleted"};let legacyEventsRegistered=!1;legacyEventsRegistered||(_yui.default.use("event","moodle-core-event",(()=>{document.addEventListener(eventTypes.formError,(e=>{const element=_yui.default.one(e.target),formElement=_yui.default.one(e.target.closest("form"));_yui.default.Global.fire(M.core.globalEvents.FORM_ERROR,{formid:formElement.generateID(),elementid:element.generateID()})})),document.addEventListener(eventTypes.formSubmittedByJavascript,(e=>{if(e.detail.fallbackHandled)return;e.skipValidation&&(window.skipClientValidation=!0);const form=_yui.default.one(e.target);form.fire(M.core.event.FORM_SUBMIT_AJAX,{currentTarget:form,fallbackHandled:!0}),e.skipValidation&&(window.skipClientValidation=!1)}))})),document.addEventListener(eventTypes.formFieldValidationFailed,(e=>{const legacyEvent=_jquery.default.Event("core_form-field-validation");(0,_jquery.default)(e.target).trigger(legacyEvent,e.detail.message)})),legacyEventsRegistered=!0);_exports.notifyUploadChanged=elementId=>(0,_event_dispatcher.dispatchEvent)(eventTypes.uploadChanged,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1});_exports.notifyFieldStructureChanged=elementId=>(0,_event_dispatcher.dispatchEvent)(eventTypes.fieldStructureChanged,{},document.getElementById(elementId),{bubbles:!0,cancellable:!1})})); //# sourceMappingURL=events.min.js.map \ No newline at end of file diff --git a/lib/form/amd/build/events.min.js.map b/lib/form/amd/build/events.min.js.map index f928286812d6..5757b431f7d2 100644 --- a/lib/form/amd/build/events.min.js.map +++ b/lib/form/amd/build/events.min.js.map @@ -1 +1 @@ -{"version":3,"file":"events.min.js","sources":["../src/events.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Javascript events for the `core_form` subsystem.\n *\n * @module core_form/events\n * @copyright 2021 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.10\n *\n * @example Example of listening to a form event.\n * import {eventTypes as formEventTypes} from 'core_form/events';\n *\n * document.addEventListener(formEventTypes.formSubmittedByJavascript, e => {\n * window.console.log(e.target); // The form that was submitted.\n * window.console.log(e.detail.skipValidation); // Whether form validation was skipped.\n * });\n */\n\nimport {getString} from 'core/str';\nimport {dispatchEvent} from 'core/event_dispatcher';\n\nlet changesMadeString;\n\n/**\n * Prevent user navigate away when upload progress still running.\n * @param {Event} e The event\n */\nconst changesMadeCheck = e => {\n if (e) {\n e.returnValue = changesMadeString;\n }\n};\n\n/**\n * Events for `core_form`.\n *\n * @constant\n * @property {String} formError See {@link event:core_form/error}\n * @property {String} formFieldValidationFailed See {@link event:core_form/fieldValidationFailed}\n * @property {String} formSubmittedByJavascript See {@link event:core_form/submittedByJavascript}\n * @property {String} uploadChanged See {@link event:core_form/uploadChanged}\n */\nexport const eventTypes = {\n /**\n * An event triggered when a form contains an error\n *\n * @event formError\n * @type {CustomEvent}\n * @property {HTMLElement} target The form field which errored\n */\n formError: 'core_form/error',\n\n /**\n * An event triggered when an mform is about to be submitted via javascript.\n *\n * @event core_form/submittedByJavascript\n * @type {CustomEvent}\n * @property {HTMLElement} target The form that was submitted\n * @property {object} detail\n * @property {boolean} detail.skipValidation Whether the form was submitted without validation (i.e. via a Cancel button)\n * @property {boolean} detail.fallbackHandled Whether the legacy YUI event has been handled\n */\n formSubmittedByJavascript: 'core_form/submittedByJavascript',\n\n /**\n * An event triggered upon form field validation failure.\n *\n * @event core_form/fieldValidationFailed\n * @type {CustomEvent}\n * @property {HTMLElement} target The field that failed validation\n * @property {object} detail\n * @property {String} detail.message The message displayed upon failure\n */\n formFieldValidationFailed: 'core_form/fieldValidationFailed',\n\n /**\n * An event triggered when an upload is started\n *\n * @event core_form/uploadStarted\n * @type {CustomEvent}\n * @property {HTMLElement} target The location where the upload began\n */\n uploadStarted: 'core_form/uploadStarted',\n\n /**\n * An event triggered when an upload completes\n *\n * @event core_form/uploadCompleted\n * @type {CustomEvent}\n * @property {HTMLElement} target The location where the upload completed\n */\n uploadCompleted: 'core_form/uploadCompleted',\n\n /**\n * An event triggered when a file upload field has been changed.\n *\n * @event core_form/uploadChanged\n * @type {CustomEvent}\n * @property {HTMLElement} target The form field which was changed\n */\n uploadChanged: 'core_form/uploadChanged',\n};\n\n// These are only imported for legacy.\nimport jQuery from 'jquery';\nimport Y from 'core/yui';\n\n/**\n * Trigger an event to indicate that a form field contained an error.\n *\n * @method notifyFormError\n * @param {HTMLElement} field The form field causing the error\n * @returns {CustomEvent}\n * @fires formError\n */\nexport const notifyFormError = field => dispatchEvent(eventTypes.formError, {}, field);\n\n/**\n * Trigger an event to indiciate that a form was submitted by Javascript.\n *\n * @method\n * @param {HTMLElement} form The form that was submitted\n * @param {Boolean} skipValidation Submit the form without validation. E.g. \"Cancel\".\n * @param {Boolean} fallbackHandled The legacy YUI event has been handled\n * @returns {CustomEvent}\n * @fires formSubmittedByJavascript\n */\nexport const notifyFormSubmittedByJavascript = (form, skipValidation = false, fallbackHandled = false) => {\n if (skipValidation) {\n window.skipClientValidation = true;\n }\n\n const customEvent = dispatchEvent(\n eventTypes.formSubmittedByJavascript,\n {\n skipValidation,\n fallbackHandled,\n },\n form\n );\n\n if (skipValidation) {\n window.skipClientValidation = false;\n }\n\n return customEvent;\n};\n\n/**\n * Trigger an event to indicate that a form field contained an error.\n *\n * @method notifyFieldValidationFailure\n * @param {HTMLElement} field The field which failed validation\n * @param {String} message The message displayed\n * @returns {CustomEvent}\n * @fires formFieldValidationFailed\n */\nexport const notifyFieldValidationFailure = (field, message) => dispatchEvent(\n eventTypes.formFieldValidationFailed,\n {\n message,\n },\n field,\n {\n cancelable: true\n }\n);\n\n/**\n * Trigger an event to indicate that an upload was started.\n *\n * @method\n * @param {String} elementId The element which was uploaded to\n * @returns {CustomEvent}\n * @fires uploadStarted\n */\nexport const notifyUploadStarted = async elementId => {\n // Add an additional check for changes made.\n changesMadeString = await getString('changesmadereallygoaway', 'moodle');\n window.addEventListener('beforeunload', changesMadeCheck);\n\n return dispatchEvent(\n eventTypes.uploadStarted,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n );\n};\n\n/**\n * Trigger an event to indicate that an upload was completed.\n *\n * @method\n * @param {String} elementId The element which was uploaded to\n * @returns {CustomEvent}\n * @fires uploadCompleted\n */\nexport const notifyUploadCompleted = elementId => {\n // Remove the additional check for changes made.\n window.removeEventListener('beforeunload', changesMadeCheck);\n\n return dispatchEvent(\n eventTypes.uploadCompleted,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n );\n};\n\n/**\n * Trigger upload start event.\n *\n * @method\n * @param {String} elementId\n * @returns {CustomEvent}\n * @fires uploadStarted\n * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadStarted notifyUploadStarted}\n */\nexport const triggerUploadStarted = notifyUploadStarted;\n\n/**\n * Trigger upload complete event.\n *\n * @method\n * @param {String} elementId\n * @returns {CustomEvent}\n * @fires uploadCompleted\n * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadCompleted notifyUploadCompleted}\n */\nexport const triggerUploadCompleted = notifyUploadCompleted;\n\n/**\n * List of the events.\n *\n * @deprecated since Moodle 4.0. See {@link module:core_form/events.eventTypes eventTypes} instead.\n **/\nexport const types = {\n uploadStarted: 'core_form/uploadStarted',\n uploadCompleted: 'core_form/uploadCompleted',\n};\n\nlet legacyEventsRegistered = false;\nif (!legacyEventsRegistered) {\n // The following event triggers are legacy and will be removed in the future.\n // The following approach provides a backwards-compatability layer for the new events.\n // Code should be updated to make use of native events.\n Y.use('event', 'moodle-core-event', () => {\n\n // Watch for the new native formError event, and trigger the legacy YUI event.\n document.addEventListener(eventTypes.formError, e => {\n const element = Y.one(e.target);\n const formElement = Y.one(e.target.closest('form'));\n\n Y.Global.fire(\n M.core.globalEvents.FORM_ERROR,\n {\n formid: formElement.generateID(),\n elementid: element.generateID(),\n }\n );\n });\n\n // Watch for the new native formSubmittedByJavascript event, and trigger the legacy YUI event.\n document.addEventListener(eventTypes.formSubmittedByJavascript, e => {\n if (e.detail.fallbackHandled) {\n // This event was originally generated by a YUI event.\n // Do not generate another as this will recurse.\n return;\n }\n\n if (e.skipValidation) {\n window.skipClientValidation = true;\n }\n\n // Trigger the legacy YUI event.\n const form = Y.one(e.target);\n form.fire(\n M.core.event.FORM_SUBMIT_AJAX,\n {\n currentTarget: form,\n fallbackHandled: true,\n }\n );\n\n if (e.skipValidation) {\n window.skipClientValidation = false;\n }\n });\n });\n\n // Watch for the new native formFieldValidationFailed event, and trigger the legacy jQuery event.\n document.addEventListener(eventTypes.formFieldValidationFailed, e => {\n // Note: The \"core_form-field-validation\" event is hard-coded in core/event.\n // This is not included to prevent cyclic module dependencies.\n const legacyEvent = jQuery.Event(\"core_form-field-validation\");\n\n jQuery(e.target).trigger(legacyEvent, e.detail.message);\n });\n\n legacyEventsRegistered = true;\n}\n\n/**\n * Trigger an event to notify the file upload field has been changed.\n *\n * @method\n * @param {string} elementId The element which was changed\n * @returns {CustomEvent}\n * @fires uploadChanged\n */\nexport const notifyUploadChanged = elementId => dispatchEvent(\n eventTypes.uploadChanged,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n);\n"],"names":["changesMadeString","changesMadeCheck","e","returnValue","eventTypes","formError","formSubmittedByJavascript","formFieldValidationFailed","uploadStarted","uploadCompleted","uploadChanged","field","form","skipValidation","fallbackHandled","window","skipClientValidation","customEvent","message","cancelable","notifyUploadStarted","async","addEventListener","document","getElementById","elementId","bubbles","cancellable","notifyUploadCompleted","removeEventListener","triggerUploadStarted","triggerUploadCompleted","legacyEventsRegistered","use","element","Y","one","target","formElement","closest","Global","fire","M","core","globalEvents","FORM_ERROR","formid","generateID","elementid","detail","event","FORM_SUBMIT_AJAX","currentTarget","legacyEvent","jQuery","Event","trigger"],"mappings":";;;;;;;;;;;;;;;;SAmCIA,mcAMEC,iBAAmBC,IACjBA,IACAA,EAAEC,YAAcH,oBAaXI,WAAa,CAQtBC,UAAW,kBAYXC,0BAA2B,kCAW3BC,0BAA2B,kCAS3BC,cAAe,0BASfC,gBAAiB,4BASjBC,cAAe,mFAeYC,QAAS,mCAAcP,WAAWC,UAAW,GAAIM,gDAYjC,SAACC,UAAMC,uEAAwBC,wEACtED,iBACAE,OAAOC,sBAAuB,SAG5BC,aAAc,mCAChBb,WAAWE,0BACX,CACIO,eAAAA,eACAC,gBAAAA,iBAEJF,aAGAC,iBACAE,OAAOC,sBAAuB,GAG3BC,mDAYiC,CAACN,MAAOO,WAAY,mCAC5Dd,WAAWG,0BACX,CACIW,QAAAA,SAEJP,MACA,CACIQ,YAAY,UAYPC,oBAAsBC,MAAAA,YAE/BrB,wBAA0B,kBAAU,0BAA2B,UAC/De,OAAOO,iBAAiB,eAAgBrB,mBAEjC,mCACHG,WAAWI,cACX,GACAe,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa,4DAaZC,sBAAwBH,YAEjCV,OAAOc,oBAAoB,eAAgB5B,mBAEpC,mCACHG,WAAWK,gBACX,GACAc,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa,gEAcZG,qBAAuBV,6EAWvBW,uBAAyBH,4FAOjB,CACjBpB,cAAe,0BACfC,gBAAiB,iCAGjBuB,wBAAyB,EACxBA,sCAICC,IAAI,QAAS,qBAAqB,KAGhCV,SAASD,iBAAiBlB,WAAWC,WAAWH,UACtCgC,QAAUC,aAAEC,IAAIlC,EAAEmC,QAClBC,YAAcH,aAAEC,IAAIlC,EAAEmC,OAAOE,QAAQ,sBAEzCC,OAAOC,KACLC,EAAEC,KAAKC,aAAaC,WACpB,CACIC,OAAQR,YAAYS,aACpBC,UAAWd,QAAQa,kBAM/BxB,SAASD,iBAAiBlB,WAAWE,2BAA2BJ,OACxDA,EAAE+C,OAAOnC,uBAMTZ,EAAEW,iBACFE,OAAOC,sBAAuB,SAI5BJ,KAAOuB,aAAEC,IAAIlC,EAAEmC,QACrBzB,KAAK6B,KACDC,EAAEC,KAAKO,MAAMC,iBACb,CACIC,cAAexC,KACfE,iBAAiB,IAIrBZ,EAAEW,iBACFE,OAAOC,sBAAuB,SAM1CO,SAASD,iBAAiBlB,WAAWG,2BAA2BL,UAGtDmD,YAAcC,gBAAOC,MAAM,kDAE1BrD,EAAEmC,QAAQmB,QAAQH,YAAanD,EAAE+C,OAAO/B,YAGnDc,wBAAyB,gCAWMP,YAAa,mCAC5CrB,WAAWM,cACX,GACAa,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa"} \ No newline at end of file +{"version":3,"file":"events.min.js","sources":["../src/events.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Javascript events for the `core_form` subsystem.\n *\n * @module core_form/events\n * @copyright 2021 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.10\n *\n * @example Example of listening to a form event.\n * import {eventTypes as formEventTypes} from 'core_form/events';\n *\n * document.addEventListener(formEventTypes.formSubmittedByJavascript, e => {\n * window.console.log(e.target); // The form that was submitted.\n * window.console.log(e.detail.skipValidation); // Whether form validation was skipped.\n * });\n */\n\nimport {getString} from 'core/str';\nimport {dispatchEvent} from 'core/event_dispatcher';\n\nlet changesMadeString;\n\n/**\n * Prevent user navigate away when upload progress still running.\n * @param {Event} e The event\n */\nconst changesMadeCheck = e => {\n if (e) {\n e.returnValue = changesMadeString;\n }\n};\n\n/**\n * Events for `core_form`.\n *\n * @constant\n * @property {String} formError See {@link event:core_form/error}\n * @property {String} formFieldValidationFailed See {@link event:core_form/fieldValidationFailed}\n * @property {String} formSubmittedByJavascript See {@link event:core_form/submittedByJavascript}\n * @property {String} uploadChanged See {@link event:core_form/uploadChanged}\n * @property {String} fieldStructureChanged See {@link event:core_form/fieldStructureChanged}\n */\nexport const eventTypes = {\n /**\n * An event triggered when a form contains an error\n *\n * @event formError\n * @type {CustomEvent}\n * @property {HTMLElement} target The form field which errored\n */\n formError: 'core_form/error',\n\n /**\n * An event triggered when an mform is about to be submitted via javascript.\n *\n * @event core_form/submittedByJavascript\n * @type {CustomEvent}\n * @property {HTMLElement} target The form that was submitted\n * @property {object} detail\n * @property {boolean} detail.skipValidation Whether the form was submitted without validation (i.e. via a Cancel button)\n * @property {boolean} detail.fallbackHandled Whether the legacy YUI event has been handled\n */\n formSubmittedByJavascript: 'core_form/submittedByJavascript',\n\n /**\n * An event triggered upon form field validation failure.\n *\n * @event core_form/fieldValidationFailed\n * @type {CustomEvent}\n * @property {HTMLElement} target The field that failed validation\n * @property {object} detail\n * @property {String} detail.message The message displayed upon failure\n */\n formFieldValidationFailed: 'core_form/fieldValidationFailed',\n\n /**\n * An event triggered when an upload is started\n *\n * @event core_form/uploadStarted\n * @type {CustomEvent}\n * @property {HTMLElement} target The location where the upload began\n */\n uploadStarted: 'core_form/uploadStarted',\n\n /**\n * An event triggered when an upload completes\n *\n * @event core_form/uploadCompleted\n * @type {CustomEvent}\n * @property {HTMLElement} target The location where the upload completed\n */\n uploadCompleted: 'core_form/uploadCompleted',\n\n /**\n * An event triggered when a file upload field has been changed.\n *\n * @event core_form/uploadChanged\n * @type {CustomEvent}\n * @property {HTMLElement} target The form field which was changed\n */\n uploadChanged: 'core_form/uploadChanged',\n\n /**\n * An event triggered when a form field structure has changed.\n *\n * @event core_form/fieldStructureChanged\n * @type {CustomEvent}\n * @property {HTMLElement} target The form field that has changed\n */\n fieldStructureChanged: 'core_form/fieldStructureChanged',\n};\n\n// These are only imported for legacy.\nimport jQuery from 'jquery';\nimport Y from 'core/yui';\n\n/**\n * Trigger an event to indicate that a form field contained an error.\n *\n * @method notifyFormError\n * @param {HTMLElement} field The form field causing the error\n * @returns {CustomEvent}\n * @fires formError\n */\nexport const notifyFormError = field => dispatchEvent(eventTypes.formError, {}, field);\n\n/**\n * Trigger an event to indiciate that a form was submitted by Javascript.\n *\n * @method\n * @param {HTMLElement} form The form that was submitted\n * @param {Boolean} skipValidation Submit the form without validation. E.g. \"Cancel\".\n * @param {Boolean} fallbackHandled The legacy YUI event has been handled\n * @returns {CustomEvent}\n * @fires formSubmittedByJavascript\n */\nexport const notifyFormSubmittedByJavascript = (form, skipValidation = false, fallbackHandled = false) => {\n if (skipValidation) {\n window.skipClientValidation = true;\n }\n\n const customEvent = dispatchEvent(\n eventTypes.formSubmittedByJavascript,\n {\n skipValidation,\n fallbackHandled,\n },\n form\n );\n\n if (skipValidation) {\n window.skipClientValidation = false;\n }\n\n return customEvent;\n};\n\n/**\n * Trigger an event to indicate that a form field contained an error.\n *\n * @method notifyFieldValidationFailure\n * @param {HTMLElement} field The field which failed validation\n * @param {String} message The message displayed\n * @returns {CustomEvent}\n * @fires formFieldValidationFailed\n */\nexport const notifyFieldValidationFailure = (field, message) => dispatchEvent(\n eventTypes.formFieldValidationFailed,\n {\n message,\n },\n field,\n {\n cancelable: true\n }\n);\n\n/**\n * Trigger an event to indicate that an upload was started.\n *\n * @method\n * @param {String} elementId The element which was uploaded to\n * @returns {CustomEvent}\n * @fires uploadStarted\n */\nexport const notifyUploadStarted = async elementId => {\n // Add an additional check for changes made.\n changesMadeString = await getString('changesmadereallygoaway', 'moodle');\n window.addEventListener('beforeunload', changesMadeCheck);\n\n return dispatchEvent(\n eventTypes.uploadStarted,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n );\n};\n\n/**\n * Trigger an event to indicate that an upload was completed.\n *\n * @method\n * @param {String} elementId The element which was uploaded to\n * @returns {CustomEvent}\n * @fires uploadCompleted\n */\nexport const notifyUploadCompleted = elementId => {\n // Remove the additional check for changes made.\n window.removeEventListener('beforeunload', changesMadeCheck);\n\n return dispatchEvent(\n eventTypes.uploadCompleted,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n );\n};\n\n/**\n * Trigger upload start event.\n *\n * @method\n * @param {String} elementId\n * @returns {CustomEvent}\n * @fires uploadStarted\n * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadStarted notifyUploadStarted}\n */\nexport const triggerUploadStarted = notifyUploadStarted;\n\n/**\n * Trigger upload complete event.\n *\n * @method\n * @param {String} elementId\n * @returns {CustomEvent}\n * @fires uploadCompleted\n * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadCompleted notifyUploadCompleted}\n */\nexport const triggerUploadCompleted = notifyUploadCompleted;\n\n/**\n * List of the events.\n *\n * @deprecated since Moodle 4.0. See {@link module:core_form/events.eventTypes eventTypes} instead.\n **/\nexport const types = {\n uploadStarted: 'core_form/uploadStarted',\n uploadCompleted: 'core_form/uploadCompleted',\n};\n\nlet legacyEventsRegistered = false;\nif (!legacyEventsRegistered) {\n // The following event triggers are legacy and will be removed in the future.\n // The following approach provides a backwards-compatability layer for the new events.\n // Code should be updated to make use of native events.\n Y.use('event', 'moodle-core-event', () => {\n\n // Watch for the new native formError event, and trigger the legacy YUI event.\n document.addEventListener(eventTypes.formError, e => {\n const element = Y.one(e.target);\n const formElement = Y.one(e.target.closest('form'));\n\n Y.Global.fire(\n M.core.globalEvents.FORM_ERROR,\n {\n formid: formElement.generateID(),\n elementid: element.generateID(),\n }\n );\n });\n\n // Watch for the new native formSubmittedByJavascript event, and trigger the legacy YUI event.\n document.addEventListener(eventTypes.formSubmittedByJavascript, e => {\n if (e.detail.fallbackHandled) {\n // This event was originally generated by a YUI event.\n // Do not generate another as this will recurse.\n return;\n }\n\n if (e.skipValidation) {\n window.skipClientValidation = true;\n }\n\n // Trigger the legacy YUI event.\n const form = Y.one(e.target);\n form.fire(\n M.core.event.FORM_SUBMIT_AJAX,\n {\n currentTarget: form,\n fallbackHandled: true,\n }\n );\n\n if (e.skipValidation) {\n window.skipClientValidation = false;\n }\n });\n });\n\n // Watch for the new native formFieldValidationFailed event, and trigger the legacy jQuery event.\n document.addEventListener(eventTypes.formFieldValidationFailed, e => {\n // Note: The \"core_form-field-validation\" event is hard-coded in core/event.\n // This is not included to prevent cyclic module dependencies.\n const legacyEvent = jQuery.Event(\"core_form-field-validation\");\n\n jQuery(e.target).trigger(legacyEvent, e.detail.message);\n });\n\n legacyEventsRegistered = true;\n}\n\n/**\n * Trigger an event to notify the file upload field has been changed.\n *\n * @method\n * @param {string} elementId The element which was changed\n * @returns {CustomEvent}\n * @fires uploadChanged\n */\nexport const notifyUploadChanged = elementId => dispatchEvent(\n eventTypes.uploadChanged,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n);\n\n/**\n * Trigger an event to notify the field structure has changed.\n *\n * @method\n * @param {string} elementId The element which was changed\n * @returns {CustomEvent}\n * @fires fieldStructureChanged\n */\nexport const notifyFieldStructureChanged = elementId => dispatchEvent(\n eventTypes.fieldStructureChanged,\n {},\n document.getElementById(elementId),\n {\n bubbles: true,\n cancellable: false,\n }\n);\n"],"names":["changesMadeString","changesMadeCheck","e","returnValue","eventTypes","formError","formSubmittedByJavascript","formFieldValidationFailed","uploadStarted","uploadCompleted","uploadChanged","fieldStructureChanged","field","form","skipValidation","fallbackHandled","window","skipClientValidation","customEvent","message","cancelable","notifyUploadStarted","async","addEventListener","document","getElementById","elementId","bubbles","cancellable","notifyUploadCompleted","removeEventListener","triggerUploadStarted","triggerUploadCompleted","legacyEventsRegistered","use","element","Y","one","target","formElement","closest","Global","fire","M","core","globalEvents","FORM_ERROR","formid","generateID","elementid","detail","event","FORM_SUBMIT_AJAX","currentTarget","legacyEvent","jQuery","Event","trigger"],"mappings":";;;;;;;;;;;;;;;;SAmCIA,weAMEC,iBAAmBC,IACjBA,IACAA,EAAEC,YAAcH,oBAcXI,WAAa,CAQtBC,UAAW,kBAYXC,0BAA2B,kCAW3BC,0BAA2B,kCAS3BC,cAAe,0BASfC,gBAAiB,4BASjBC,cAAe,0BASfC,sBAAuB,2FAeIC,QAAS,mCAAcR,WAAWC,UAAW,GAAIO,gDAYjC,SAACC,UAAMC,uEAAwBC,wEACtED,iBACAE,OAAOC,sBAAuB,SAG5BC,aAAc,mCAChBd,WAAWE,0BACX,CACIQ,eAAAA,eACAC,gBAAAA,iBAEJF,aAGAC,iBACAE,OAAOC,sBAAuB,GAG3BC,mDAYiC,CAACN,MAAOO,WAAY,mCAC5Df,WAAWG,0BACX,CACIY,QAAAA,SAEJP,MACA,CACIQ,YAAY,UAYPC,oBAAsBC,MAAAA,YAE/BtB,wBAA0B,kBAAU,0BAA2B,UAC/DgB,OAAOO,iBAAiB,eAAgBtB,mBAEjC,mCACHG,WAAWI,cACX,GACAgB,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa,4DAaZC,sBAAwBH,YAEjCV,OAAOc,oBAAoB,eAAgB7B,mBAEpC,mCACHG,WAAWK,gBACX,GACAe,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa,gEAcZG,qBAAuBV,6EAWvBW,uBAAyBH,4FAOjB,CACjBrB,cAAe,0BACfC,gBAAiB,iCAGjBwB,wBAAyB,EACxBA,sCAICC,IAAI,QAAS,qBAAqB,KAGhCV,SAASD,iBAAiBnB,WAAWC,WAAWH,UACtCiC,QAAUC,aAAEC,IAAInC,EAAEoC,QAClBC,YAAcH,aAAEC,IAAInC,EAAEoC,OAAOE,QAAQ,sBAEzCC,OAAOC,KACLC,EAAEC,KAAKC,aAAaC,WACpB,CACIC,OAAQR,YAAYS,aACpBC,UAAWd,QAAQa,kBAM/BxB,SAASD,iBAAiBnB,WAAWE,2BAA2BJ,OACxDA,EAAEgD,OAAOnC,uBAMTb,EAAEY,iBACFE,OAAOC,sBAAuB,SAI5BJ,KAAOuB,aAAEC,IAAInC,EAAEoC,QACrBzB,KAAK6B,KACDC,EAAEC,KAAKO,MAAMC,iBACb,CACIC,cAAexC,KACfE,iBAAiB,IAIrBb,EAAEY,iBACFE,OAAOC,sBAAuB,SAM1CO,SAASD,iBAAiBnB,WAAWG,2BAA2BL,UAGtDoD,YAAcC,gBAAOC,MAAM,kDAE1BtD,EAAEoC,QAAQmB,QAAQH,YAAapD,EAAEgD,OAAO/B,YAGnDc,wBAAyB,gCAWMP,YAAa,mCAC5CtB,WAAWM,cACX,GACAc,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa,yCAYsBF,YAAa,mCACpDtB,WAAWO,sBACX,GACAa,SAASC,eAAeC,WACxB,CACIC,SAAS,EACTC,aAAa"} \ No newline at end of file diff --git a/lib/form/amd/src/events.js b/lib/form/amd/src/events.js index 2cbedb241e04..b5c3b4df82da 100644 --- a/lib/form/amd/src/events.js +++ b/lib/form/amd/src/events.js @@ -53,6 +53,7 @@ const changesMadeCheck = e => { * @property {String} formFieldValidationFailed See {@link event:core_form/fieldValidationFailed} * @property {String} formSubmittedByJavascript See {@link event:core_form/submittedByJavascript} * @property {String} uploadChanged See {@link event:core_form/uploadChanged} + * @property {String} fieldStructureChanged See {@link event:core_form/fieldStructureChanged} */ export const eventTypes = { /** @@ -113,6 +114,15 @@ export const eventTypes = { * @property {HTMLElement} target The form field which was changed */ uploadChanged: 'core_form/uploadChanged', + + /** + * An event triggered when a form field structure has changed. + * + * @event core_form/fieldStructureChanged + * @type {CustomEvent} + * @property {HTMLElement} target The form field that has changed + */ + fieldStructureChanged: 'core_form/fieldStructureChanged', }; // These are only imported for legacy. @@ -337,3 +347,21 @@ export const notifyUploadChanged = elementId => dispatchEvent( cancellable: false, } ); + +/** + * Trigger an event to notify the field structure has changed. + * + * @method + * @param {string} elementId The element which was changed + * @returns {CustomEvent} + * @fires fieldStructureChanged + */ +export const notifyFieldStructureChanged = elementId => dispatchEvent( + eventTypes.fieldStructureChanged, + {}, + document.getElementById(elementId), + { + bubbles: true, + cancellable: false, + } +); diff --git a/lib/form/filepicker.php b/lib/form/filepicker.php index e10fd46bf096..8fee6b48acaf 100644 --- a/lib/form/filepicker.php +++ b/lib/form/filepicker.php @@ -184,11 +184,10 @@ function toHtml() { $html .= "
"; $html .= ''; - if (!empty($options->accepted_types) && $options->accepted_types != '*') { + if (!empty($args->accepted_types) && $args->accepted_types != '*') { $html .= html_writer::tag('p', get_string('filesofthesetypes', 'form')); $util = new \core_form\filetypes_util(); - $filetypes = $options->accepted_types; - $filetypedescriptions = $util->describe_file_types($filetypes); + $filetypedescriptions = $util->describe_file_types($args->accepted_types); $html .= $OUTPUT->render_from_template('core_form/filetypes-descriptions', $filetypedescriptions); } diff --git a/lib/form/templates/element-group.mustache b/lib/form/templates/element-group.mustache index 67d7866eeed0..208dd6d0d14a 100644 --- a/lib/form/templates/element-group.mustache +++ b/lib/form/templates/element-group.mustache @@ -7,17 +7,27 @@ {{/element.hiddenlabel}} {{/label}} {{$element}} -
- {{#label}} + {{#label}} +
{{label}} - {{/label}} -
- {{#element.elements}} - {{{separator}}} - {{{html}}} - {{/element.elements}} +
+ {{#element.elements}} + {{{separator}}} + {{{html}}} + {{/element.elements}} +
+
+ {{/label}} + {{^label}} +
+
+ {{#element.elements}} + {{{separator}}} + {{{html}}} + {{/element.elements}} +
-
+ {{/label}} {{/element}} {{/ core_form/element-template }} {{#js}} diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 1db650c1cf2f..79053882ceda 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -74,7 +74,6 @@ // We currently include \core\param manually here to avoid broken upgrades. // This may change after the next LTS release as LTS releases require the previous LTS release. require_once(__DIR__ . '/classes/deprecation.php'); -require_once(__DIR__ . '/classes/deprecated.php'); require_once(__DIR__ . '/classes/param.php'); /** @@ -601,6 +600,21 @@ */ define('MAX_PASSWORD_CHARACTERS', 128); +/** + * Toggle sensitive feature is disabled. Used for sensitive inputs (passwords, tokens, keys). + */ +define('TOGGLE_SENSITIVE_DISABLED', 0); + +/** + * Toggle sensitive feature is enabled. Used for sensitive inputs (passwords, tokens, keys). + */ +define('TOGGLE_SENSITIVE_ENABLED', 1); + +/** + * Toggle sensitive feature is enabled for small screens only. Used for sensitive inputs (passwords, tokens, keys). + */ +define('TOGGLE_SENSITIVE_SMALL_SCREENS_ONLY', 2); + // PARAMETER HANDLING. /** diff --git a/lib/openspout/src/Common/Entity/Cell.php b/lib/openspout/src/Common/Entity/Cell.php index 2cd263f2f029..af76d4de52e8 100644 --- a/lib/openspout/src/Common/Entity/Cell.php +++ b/lib/openspout/src/Common/Entity/Cell.php @@ -27,7 +27,7 @@ public function __construct(?Style $style) $this->setStyle($style); } - abstract public function getValue(): null|bool|string|int|float|DateTimeInterface|DateInterval; + abstract public function getValue(): null|bool|DateInterval|DateTimeInterface|float|int|string; final public function setStyle(?Style $style): void { @@ -39,7 +39,7 @@ final public function getStyle(): Style return $this->style; } - final public static function fromValue(null|bool|string|int|float|DateTimeInterface|DateInterval $value, ?Style $style = null): self + final public static function fromValue(null|bool|DateInterval|DateTimeInterface|float|int|string $value, ?Style $style = null): self { if (\is_bool($value)) { return new BooleanCell($value, $style); @@ -57,7 +57,7 @@ final public static function fromValue(null|bool|string|int|float|DateTimeInterf return new DateIntervalCell($value, $style); } if (isset($value[0]) && '=' === $value[0]) { - return new FormulaCell($value, $style); + return new FormulaCell($value, $style, null); } return new StringCell($value, $style); diff --git a/lib/openspout/src/Common/Entity/Cell/BooleanCell.php b/lib/openspout/src/Common/Entity/Cell/BooleanCell.php index 120a72b8a00e..ecba8e8c07ec 100644 --- a/lib/openspout/src/Common/Entity/Cell/BooleanCell.php +++ b/lib/openspout/src/Common/Entity/Cell/BooleanCell.php @@ -9,7 +9,7 @@ final class BooleanCell extends Cell { - private bool $value; + private readonly bool $value; public function __construct(bool $value, ?Style $style) { diff --git a/lib/openspout/src/Common/Entity/Cell/DateIntervalCell.php b/lib/openspout/src/Common/Entity/Cell/DateIntervalCell.php index 75b5eaf5916b..65d30861d965 100644 --- a/lib/openspout/src/Common/Entity/Cell/DateIntervalCell.php +++ b/lib/openspout/src/Common/Entity/Cell/DateIntervalCell.php @@ -10,8 +10,14 @@ final class DateIntervalCell extends Cell { - private DateInterval $value; + private readonly DateInterval $value; + /** + * For Excel make sure to set a format onto the style (Style::setFormat()) with the left most unit enclosed with + * brackets: '[h]:mm', '[hh]:mm:ss', '[m]:ss', '[s]', etc. + * This makes sure excel knows what to do with the remaining time that exceeds this unit. Without brackets Excel + * will interpret the value as date time and not duration if it is greater or equal 1. + */ public function __construct(DateInterval $value, ?Style $style) { $this->value = $value; diff --git a/lib/openspout/src/Common/Entity/Cell/DateTimeCell.php b/lib/openspout/src/Common/Entity/Cell/DateTimeCell.php index 7065abf5445d..bced40060a69 100644 --- a/lib/openspout/src/Common/Entity/Cell/DateTimeCell.php +++ b/lib/openspout/src/Common/Entity/Cell/DateTimeCell.php @@ -10,7 +10,7 @@ final class DateTimeCell extends Cell { - private DateTimeInterface $value; + private readonly DateTimeInterface $value; public function __construct(DateTimeInterface $value, ?Style $style) { diff --git a/lib/openspout/src/Common/Entity/Cell/EmptyCell.php b/lib/openspout/src/Common/Entity/Cell/EmptyCell.php index 8d3e41399c40..72678b961231 100644 --- a/lib/openspout/src/Common/Entity/Cell/EmptyCell.php +++ b/lib/openspout/src/Common/Entity/Cell/EmptyCell.php @@ -9,7 +9,7 @@ final class EmptyCell extends Cell { - private ?string $value; + private readonly ?string $value; public function __construct(?string $value, ?Style $style) { diff --git a/lib/openspout/src/Common/Entity/Cell/ErrorCell.php b/lib/openspout/src/Common/Entity/Cell/ErrorCell.php index 2c1d677bd999..53a445e98553 100644 --- a/lib/openspout/src/Common/Entity/Cell/ErrorCell.php +++ b/lib/openspout/src/Common/Entity/Cell/ErrorCell.php @@ -9,7 +9,7 @@ final class ErrorCell extends Cell { - private string $value; + private readonly string $value; public function __construct(string $value, ?Style $style) { diff --git a/lib/openspout/src/Common/Entity/Cell/FormulaCell.php b/lib/openspout/src/Common/Entity/Cell/FormulaCell.php index 97daa838cb61..2e07a96c647f 100644 --- a/lib/openspout/src/Common/Entity/Cell/FormulaCell.php +++ b/lib/openspout/src/Common/Entity/Cell/FormulaCell.php @@ -4,16 +4,18 @@ namespace OpenSpout\Common\Entity\Cell; +use DateInterval; +use DateTimeImmutable; use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Entity\Style\Style; final class FormulaCell extends Cell { - private string $value; - - public function __construct(string $value, ?Style $style) - { - $this->value = $value; + public function __construct( + private readonly string $value, + ?Style $style, + private readonly null|DateInterval|DateTimeImmutable|float|int|string $computedValue = null, + ) { parent::__construct($style); } @@ -21,4 +23,9 @@ public function getValue(): string { return $this->value; } + + public function getComputedValue(): null|DateInterval|DateTimeImmutable|float|int|string + { + return $this->computedValue; + } } diff --git a/lib/openspout/src/Common/Entity/Cell/NumericCell.php b/lib/openspout/src/Common/Entity/Cell/NumericCell.php index 810fe1113d55..ee5d0eaae4e7 100644 --- a/lib/openspout/src/Common/Entity/Cell/NumericCell.php +++ b/lib/openspout/src/Common/Entity/Cell/NumericCell.php @@ -9,15 +9,15 @@ final class NumericCell extends Cell { - private int|float $value; + private readonly float|int $value; - public function __construct(int|float $value, ?Style $style) + public function __construct(float|int $value, ?Style $style) { $this->value = $value; parent::__construct($style); } - public function getValue(): int|float + public function getValue(): float|int { return $this->value; } diff --git a/lib/openspout/src/Common/Entity/Cell/StringCell.php b/lib/openspout/src/Common/Entity/Cell/StringCell.php index 94ffa8fa6d2d..85397945847a 100644 --- a/lib/openspout/src/Common/Entity/Cell/StringCell.php +++ b/lib/openspout/src/Common/Entity/Cell/StringCell.php @@ -9,7 +9,7 @@ final class StringCell extends Cell { - private string $value; + private readonly string $value; public function __construct(string $value, ?Style $style) { diff --git a/lib/openspout/src/Common/Entity/Row.php b/lib/openspout/src/Common/Entity/Row.php index 6443ea19bf71..5715b9f959df 100644 --- a/lib/openspout/src/Common/Entity/Row.php +++ b/lib/openspout/src/Common/Entity/Row.php @@ -41,7 +41,7 @@ public function __construct(array $cells, ?Style $style = null) */ public static function fromValues(array $cellValues = [], ?Style $rowStyle = null): self { - $cells = array_map(static function (null|bool|string|int|float|DateTimeInterface|DateInterval $cellValue): Cell { + $cells = array_map(static function (null|bool|DateInterval|DateTimeInterface|float|int|string $cellValue): Cell { return Cell::fromValue($cellValue); }, $cellValues); @@ -134,7 +134,7 @@ public function getHeight(): float */ public function toArray(): array { - return array_map(static function (Cell $cell): null|bool|string|int|float|DateTimeInterface|DateInterval { + return array_map(static function (Cell $cell): null|bool|DateInterval|DateTimeInterface|float|int|string { return $cell->getValue(); }, $this->cells); } diff --git a/lib/openspout/src/Common/Entity/Style/BorderPart.php b/lib/openspout/src/Common/Entity/Style/BorderPart.php index e5819e36362d..8bd9a1abbddb 100644 --- a/lib/openspout/src/Common/Entity/Style/BorderPart.php +++ b/lib/openspout/src/Common/Entity/Style/BorderPart.php @@ -31,10 +31,10 @@ final class BorderPart Border::WIDTH_THICK, ]; - private string $style; - private string $name; - private string $color; - private string $width; + private readonly string $style; + private readonly string $name; + private readonly string $color; + private readonly string $width; /** * @param string $name @see BorderPart::allowedNames diff --git a/lib/openspout/src/Common/Entity/Style/Color.php b/lib/openspout/src/Common/Entity/Style/Color.php index 4dd5e3e1b480..e4ee1e7026a2 100644 --- a/lib/openspout/src/Common/Entity/Style/Color.php +++ b/lib/openspout/src/Common/Entity/Style/Color.php @@ -65,7 +65,7 @@ public static function toARGB(string $rgbColor): string /** * Throws an exception is the color component value is outside of bounds (0 - 255). * - * @throws \OpenSpout\Common\Exception\InvalidColorException + * @throws InvalidColorException */ private static function throwIfInvalidColorComponentValue(int $colorComponent): void { diff --git a/lib/openspout/src/Common/Exception/EncodingConversionException.php b/lib/openspout/src/Common/Exception/EncodingConversionException.php index 0a0fce8847bd..d08d0ba3af07 100644 --- a/lib/openspout/src/Common/Exception/EncodingConversionException.php +++ b/lib/openspout/src/Common/Exception/EncodingConversionException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Common\Exception; -final class EncodingConversionException extends OpenSpoutException -{ -} +final class EncodingConversionException extends OpenSpoutException {} diff --git a/lib/openspout/src/Common/Exception/IOException.php b/lib/openspout/src/Common/Exception/IOException.php index b452091e6270..3e5154a75960 100644 --- a/lib/openspout/src/Common/Exception/IOException.php +++ b/lib/openspout/src/Common/Exception/IOException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Common\Exception; -final class IOException extends OpenSpoutException -{ -} +final class IOException extends OpenSpoutException {} diff --git a/lib/openspout/src/Common/Exception/InvalidArgumentException.php b/lib/openspout/src/Common/Exception/InvalidArgumentException.php index 231881ad8adf..6241a1de2c41 100644 --- a/lib/openspout/src/Common/Exception/InvalidArgumentException.php +++ b/lib/openspout/src/Common/Exception/InvalidArgumentException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Common\Exception; -final class InvalidArgumentException extends OpenSpoutException -{ -} +final class InvalidArgumentException extends OpenSpoutException {} diff --git a/lib/openspout/src/Common/Exception/InvalidColorException.php b/lib/openspout/src/Common/Exception/InvalidColorException.php index 98882adec5c0..0983024bafe3 100644 --- a/lib/openspout/src/Common/Exception/InvalidColorException.php +++ b/lib/openspout/src/Common/Exception/InvalidColorException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Common\Exception; -final class InvalidColorException extends OpenSpoutException -{ -} +final class InvalidColorException extends OpenSpoutException {} diff --git a/lib/openspout/src/Common/Exception/OpenSpoutException.php b/lib/openspout/src/Common/Exception/OpenSpoutException.php index 9a4596ebe3ec..3753525f1116 100644 --- a/lib/openspout/src/Common/Exception/OpenSpoutException.php +++ b/lib/openspout/src/Common/Exception/OpenSpoutException.php @@ -6,6 +6,4 @@ use Exception; -abstract class OpenSpoutException extends Exception -{ -} +abstract class OpenSpoutException extends Exception {} diff --git a/lib/openspout/src/Common/Exception/UnsupportedTypeException.php b/lib/openspout/src/Common/Exception/UnsupportedTypeException.php index bcae72183007..f8d71452b4be 100644 --- a/lib/openspout/src/Common/Exception/UnsupportedTypeException.php +++ b/lib/openspout/src/Common/Exception/UnsupportedTypeException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Common\Exception; -final class UnsupportedTypeException extends OpenSpoutException -{ -} +final class UnsupportedTypeException extends OpenSpoutException {} diff --git a/lib/openspout/src/Common/Helper/EncodingHelper.php b/lib/openspout/src/Common/Helper/EncodingHelper.php index d1fc51f1d9ec..82de24492266 100644 --- a/lib/openspout/src/Common/Helper/EncodingHelper.php +++ b/lib/openspout/src/Common/Helper/EncodingHelper.php @@ -33,9 +33,9 @@ final class EncodingHelper /** @var array Map representing the encodings supporting BOMs (key) and their associated BOM (value) */ private array $supportedEncodingsWithBom; - private bool $canUseIconv; + private readonly bool $canUseIconv; - private bool $canUseMbString; + private readonly bool $canUseMbString; public function __construct(bool $canUseIconv, bool $canUseMbString) { @@ -89,7 +89,7 @@ public function getBytesOffsetToSkipBOM($filePointer, string $encoding): int * * @return string The converted, UTF-8 string * - * @throws \OpenSpout\Common\Exception\EncodingConversionException If conversion is not supported or if the conversion failed + * @throws EncodingConversionException If conversion is not supported or if the conversion failed */ public function attemptConversionToUTF8(?string $string, string $sourceEncoding): ?string { @@ -104,7 +104,7 @@ public function attemptConversionToUTF8(?string $string, string $sourceEncoding) * * @return string The converted string, encoded with the given encoding * - * @throws \OpenSpout\Common\Exception\EncodingConversionException If conversion is not supported or if the conversion failed + * @throws EncodingConversionException If conversion is not supported or if the conversion failed */ public function attemptConversionFromUTF8(?string $string, string $targetEncoding): ?string { @@ -145,7 +145,7 @@ private function hasBOM($filePointer, string $encoding): bool * * @return string The converted string, encoded with the given encoding * - * @throws \OpenSpout\Common\Exception\EncodingConversionException If conversion is not supported or if the conversion failed + * @throws EncodingConversionException If conversion is not supported or if the conversion failed */ private function attemptConversion(?string $string, string $sourceEncoding, string $targetEncoding): ?string { diff --git a/lib/openspout/src/Common/Helper/Escaper/XLSX.php b/lib/openspout/src/Common/Helper/Escaper/XLSX.php index 130ee5f4973b..059b7d9bdc76 100644 --- a/lib/openspout/src/Common/Helper/Escaper/XLSX.php +++ b/lib/openspout/src/Common/Helper/Escaper/XLSX.php @@ -33,6 +33,7 @@ public function escape(string $string): string $this->initIfNeeded(); $escapedString = $this->escapeControlCharacters($string); + // @NOTE: Using ENT_QUOTES as XML entities ('<', '>', '&') as well as // single/double quotes (for XML attributes) need to be encoded. return htmlspecialchars($escapedString, ENT_QUOTES, 'UTF-8'); diff --git a/lib/openspout/src/Common/Helper/FileSystemHelper.php b/lib/openspout/src/Common/Helper/FileSystemHelper.php index 0fb223bb2747..2309bfe68e21 100644 --- a/lib/openspout/src/Common/Helper/FileSystemHelper.php +++ b/lib/openspout/src/Common/Helper/FileSystemHelper.php @@ -14,7 +14,7 @@ final class FileSystemHelper implements FileSystemHelperInterface { /** @var string Real path of the base folder where all the I/O can occur */ - private string $baseFolderRealPath; + private readonly string $baseFolderRealPath; /** * @param string $baseFolderPath The path of the base folder where all the I/O can occur @@ -39,7 +39,7 @@ public function getBaseFolderRealPath(): string * * @return string Path of the created folder * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or if the folder path is not inside of the base folder + * @throws IOException If unable to create the folder or if the folder path is not inside of the base folder */ public function createFolder(string $parentFolderPath, string $folderName): string { @@ -73,7 +73,7 @@ public function createFolder(string $parentFolderPath, string $folderName): stri * * @return string Path of the created file * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file or if the file path is not inside of the base folder + * @throws IOException If unable to create the file or if the file path is not inside of the base folder */ public function createFileWithContents(string $parentFolderPath, string $fileName, string $fileContents): string { @@ -102,7 +102,7 @@ public function createFileWithContents(string $parentFolderPath, string $fileNam * * @param string $filePath Path of the file to delete * - * @throws \OpenSpout\Common\Exception\IOException If the file path is not inside of the base folder + * @throws IOException If the file path is not inside of the base folder */ public function deleteFile(string $filePath): void { @@ -118,7 +118,7 @@ public function deleteFile(string $filePath): void * * @param string $folderPath Path of the folder to delete * - * @throws \OpenSpout\Common\Exception\IOException If the folder path is not inside of the base folder + * @throws IOException If the folder path is not inside of the base folder */ public function deleteFolderRecursively(string $folderPath): void { @@ -147,8 +147,8 @@ public function deleteFolderRecursively(string $folderPath): void * * @param string $operationFolderPath The path of the folder where the I/O operation should occur * - * @throws \OpenSpout\Common\Exception\IOException If the folder where the I/O operation should occur - * is not inside the base folder or the base folder does not exist + * @throws IOException If the folder where the I/O operation should occur + * is not inside the base folder or the base folder does not exist */ private function throwIfOperationNotInBaseFolder(string $operationFolderPath): void { diff --git a/lib/openspout/src/Common/Helper/FileSystemHelperInterface.php b/lib/openspout/src/Common/Helper/FileSystemHelperInterface.php index a6d12d89fa6f..390346e39a09 100644 --- a/lib/openspout/src/Common/Helper/FileSystemHelperInterface.php +++ b/lib/openspout/src/Common/Helper/FileSystemHelperInterface.php @@ -4,6 +4,8 @@ namespace OpenSpout\Common\Helper; +use OpenSpout\Common\Exception\IOException; + /** * @internal */ @@ -17,7 +19,7 @@ interface FileSystemHelperInterface * * @return string Path of the created folder * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or if the folder path is not inside of the base folder + * @throws IOException If unable to create the folder or if the folder path is not inside of the base folder */ public function createFolder(string $parentFolderPath, string $folderName): string; @@ -31,7 +33,7 @@ public function createFolder(string $parentFolderPath, string $folderName): stri * * @return string Path of the created file * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file or if the file path is not inside of the base folder + * @throws IOException If unable to create the file or if the file path is not inside of the base folder */ public function createFileWithContents(string $parentFolderPath, string $fileName, string $fileContents): string; @@ -40,7 +42,7 @@ public function createFileWithContents(string $parentFolderPath, string $fileNam * * @param string $filePath Path of the file to delete * - * @throws \OpenSpout\Common\Exception\IOException If the file path is not inside of the base folder + * @throws IOException If the file path is not inside of the base folder */ public function deleteFile(string $filePath): void; @@ -49,7 +51,7 @@ public function deleteFile(string $filePath): void; * * @param string $folderPath Path of the folder to delete * - * @throws \OpenSpout\Common\Exception\IOException If the folder path is not inside of the base folder + * @throws IOException If the folder path is not inside of the base folder */ public function deleteFolderRecursively(string $folderPath): void; } diff --git a/lib/openspout/src/Common/Helper/StringHelper.php b/lib/openspout/src/Common/Helper/StringHelper.php index dfc6d56d7f91..fb5bada0a5e0 100644 --- a/lib/openspout/src/Common/Helper/StringHelper.php +++ b/lib/openspout/src/Common/Helper/StringHelper.php @@ -10,7 +10,7 @@ final class StringHelper { /** @var bool Whether the mbstring extension is loaded */ - private bool $hasMbstringSupport; + private readonly bool $hasMbstringSupport; public function __construct(bool $hasMbstringSupport) { diff --git a/lib/openspout/src/Reader/AbstractReader.php b/lib/openspout/src/Reader/AbstractReader.php index 3afa0cef6b00..3582345f58eb 100644 --- a/lib/openspout/src/Reader/AbstractReader.php +++ b/lib/openspout/src/Reader/AbstractReader.php @@ -24,7 +24,7 @@ abstract class AbstractReader implements ReaderInterface * * @param string $filePath Path of the file to be read * - * @throws \OpenSpout\Common\Exception\IOException If the file at the given path does not exist, is not readable or is corrupted + * @throws IOException If the file at the given path does not exist, is not readable or is corrupted */ public function open(string $filePath): void { diff --git a/lib/openspout/src/Reader/CSV/Reader.php b/lib/openspout/src/Reader/CSV/Reader.php index ac92b53e2aa3..f455dbbbf05c 100644 --- a/lib/openspout/src/Reader/CSV/Reader.php +++ b/lib/openspout/src/Reader/CSV/Reader.php @@ -4,6 +4,7 @@ namespace OpenSpout\Reader\CSV; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\EncodingHelper; use OpenSpout\Reader\AbstractReader; @@ -18,14 +19,8 @@ final class Reader extends AbstractReader /** @var SheetIterator To iterator over the CSV unique "sheet" */ private SheetIterator $sheetIterator; - /** @var string Original value for the "auto_detect_line_endings" INI value */ - private string $originalAutoDetectLineEndings; - - /** @var bool Whether the code is running with PHP >= 8.1 */ - private bool $isRunningAtLeastPhp81; - - private Options $options; - private EncodingHelper $encodingHelper; + private readonly Options $options; + private readonly EncodingHelper $encodingHelper; public function __construct( ?Options $options = null, @@ -33,7 +28,6 @@ public function __construct( ) { $this->options = $options ?? new Options(); $this->encodingHelper = $encodingHelper ?? EncodingHelper::factory(); - $this->isRunningAtLeastPhp81 = \PHP_VERSION_ID >= 80100; } public function getSheetIterator(): SheetIterator @@ -57,20 +51,10 @@ protected function doesSupportStreamWrapper(): bool * * @param string $filePath Path of the CSV file to be read * - * @throws \OpenSpout\Common\Exception\IOException + * @throws IOException */ protected function openReader(string $filePath): void { - // "auto_detect_line_endings" is deprecated in PHP 8.1 - if (!$this->isRunningAtLeastPhp81) { - // @codeCoverageIgnoreStart - $originalAutoDetectLineEndings = \ini_get('auto_detect_line_endings'); - \assert(false !== $originalAutoDetectLineEndings); - $this->originalAutoDetectLineEndings = $originalAutoDetectLineEndings; - ini_set('auto_detect_line_endings', '1'); - // @codeCoverageIgnoreEnd - } - $resource = fopen($filePath, 'r'); \assert(false !== $resource); $this->filePointer = $resource; @@ -92,12 +76,5 @@ protected function openReader(string $filePath): void protected function closeReader(): void { fclose($this->filePointer); - - // "auto_detect_line_endings" is deprecated in PHP 8.1 - if (!$this->isRunningAtLeastPhp81) { - // @codeCoverageIgnoreStart - ini_set('auto_detect_line_endings', $this->originalAutoDetectLineEndings); - // @codeCoverageIgnoreEnd - } } } diff --git a/lib/openspout/src/Reader/CSV/RowIterator.php b/lib/openspout/src/Reader/CSV/RowIterator.php index 88b7c00cc9b7..81f50bd7a3d1 100644 --- a/lib/openspout/src/Reader/CSV/RowIterator.php +++ b/lib/openspout/src/Reader/CSV/RowIterator.php @@ -6,6 +6,7 @@ use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\EncodingConversionException; use OpenSpout\Common\Helper\EncodingHelper; use OpenSpout\Reader\RowIteratorInterface; @@ -26,15 +27,15 @@ final class RowIterator implements RowIteratorInterface private int $numReadRows = 0; /** @var null|Row Buffer used to store the current row, while checking if there are more rows to read */ - private ?Row $rowBuffer; + private ?Row $rowBuffer = null; /** @var bool Indicates whether all rows have been read */ private bool $hasReachedEndOfFile = false; - private Options $options; + private readonly Options $options; /** @var EncodingHelper Helper to work with different encodings */ - private EncodingHelper $encodingHelper; + private readonly EncodingHelper $encodingHelper; /** * @param resource $filePointer Pointer to the CSV file to read @@ -79,7 +80,7 @@ public function valid(): bool * * @see http://php.net/manual/en/iterator.next.php * - * @throws \OpenSpout\Common\Exception\EncodingConversionException If unable to convert data to UTF-8 + * @throws EncodingConversionException If unable to convert data to UTF-8 */ public function next(): void { @@ -123,7 +124,7 @@ private function rewindAndSkipBom(): void } /** - * @throws \OpenSpout\Common\Exception\EncodingConversionException If unable to convert data to UTF-8 + * @throws EncodingConversionException If unable to convert data to UTF-8 */ private function readDataForNextRow(): void { @@ -168,7 +169,7 @@ private function shouldReadNextRow($currentRowData): bool * * @return array|false The row for the current file pointer, encoded in UTF-8 or FALSE if nothing to read * - * @throws \OpenSpout\Common\Exception\EncodingConversionException If unable to convert data to UTF-8 + * @throws EncodingConversionException If unable to convert data to UTF-8 */ private function getNextUTF8EncodedRow(): array|false { diff --git a/lib/openspout/src/Reader/CSV/Sheet.php b/lib/openspout/src/Reader/CSV/Sheet.php index f4e1be1c6979..142e6255e206 100644 --- a/lib/openspout/src/Reader/CSV/Sheet.php +++ b/lib/openspout/src/Reader/CSV/Sheet.php @@ -12,7 +12,7 @@ final class Sheet implements SheetInterface { /** @var RowIterator To iterate over the CSV's rows */ - private RowIterator $rowIterator; + private readonly RowIterator $rowIterator; /** * @param RowIterator $rowIterator Corresponding row iterator diff --git a/lib/openspout/src/Reader/CSV/SheetIterator.php b/lib/openspout/src/Reader/CSV/SheetIterator.php index 7bba3aa09b63..5a2b9153e2d4 100644 --- a/lib/openspout/src/Reader/CSV/SheetIterator.php +++ b/lib/openspout/src/Reader/CSV/SheetIterator.php @@ -12,7 +12,7 @@ final class SheetIterator implements SheetIteratorInterface { /** @var Sheet The CSV unique "sheet" */ - private Sheet $sheet; + private readonly Sheet $sheet; /** @var bool Whether the unique "sheet" has already been read */ private bool $hasReadUniqueSheet = false; diff --git a/lib/openspout/src/Reader/Common/ColumnWidth.php b/lib/openspout/src/Reader/Common/ColumnWidth.php index 1350a10e2ead..73ecb627a5a4 100644 --- a/lib/openspout/src/Reader/Common/ColumnWidth.php +++ b/lib/openspout/src/Reader/Common/ColumnWidth.php @@ -14,9 +14,8 @@ final class ColumnWidth * @param positive-int $end */ public function __construct( - public int $start, - public int $end, - public float $width, - ) { - } + public readonly int $start, + public readonly int $end, + public readonly float $width, + ) {} } diff --git a/lib/openspout/src/Reader/Common/Creator/ReaderFactory.php b/lib/openspout/src/Reader/Common/Creator/ReaderFactory.php index c72bcfa4b91b..f769f48994a0 100644 --- a/lib/openspout/src/Reader/Common/Creator/ReaderFactory.php +++ b/lib/openspout/src/Reader/Common/Creator/ReaderFactory.php @@ -14,6 +14,8 @@ /** * This factory is used to create readers, based on the type of the file to be read. * It supports CSV, XLSX and ODS formats. + * + * @deprecated Guessing mechanisms are brittle by nature and won't be provided by this library anymore */ final class ReaderFactory { @@ -22,7 +24,7 @@ final class ReaderFactory * * @param string $path The path to the spreadsheet file. Supported extensions are .csv,.ods and .xlsx * - * @throws \OpenSpout\Common\Exception\UnsupportedTypeException + * @throws UnsupportedTypeException */ public static function createFromFile(string $path): ReaderInterface { @@ -41,8 +43,8 @@ public static function createFromFile(string $path): ReaderInterface * * @param string $path the path to the spreadsheet file * - * @throws \OpenSpout\Common\Exception\UnsupportedTypeException - * @throws \OpenSpout\Common\Exception\IOException + * @throws UnsupportedTypeException + * @throws IOException */ public static function createFromFileByMimeType(string $path): ReaderInterface { diff --git a/lib/openspout/src/Reader/Common/XMLProcessor.php b/lib/openspout/src/Reader/Common/XMLProcessor.php index 85dff666eba1..b185ad6e6ddb 100644 --- a/lib/openspout/src/Reader/Common/XMLProcessor.php +++ b/lib/openspout/src/Reader/Common/XMLProcessor.php @@ -4,6 +4,7 @@ namespace OpenSpout\Reader\Common; +use OpenSpout\Reader\Exception\XMLProcessingException; use OpenSpout\Reader\Wrapper\XMLReader; use ReflectionMethod; @@ -25,7 +26,7 @@ final class XMLProcessor public const PROCESSING_STOP = 2; /** @var XMLReader The XMLReader object that will help read sheet's XML data */ - private XMLReader $xmlReader; + private readonly XMLReader $xmlReader; /** @var array Registered callbacks */ private array $callbacks = []; @@ -55,7 +56,7 @@ public function registerCallback(string $nodeName, int $nodeType, $callback): se * Resumes the reading of the XML file where it was left off. * Stops whenever a callback indicates that reading should stop or at the end of the file. * - * @throws \OpenSpout\Reader\Exception\XMLProcessingException + * @throws XMLProcessingException */ public function readUntilStopped(): void { diff --git a/lib/openspout/src/Reader/Exception/InvalidValueException.php b/lib/openspout/src/Reader/Exception/InvalidValueException.php index 3f5c4b042152..4475e512ea97 100644 --- a/lib/openspout/src/Reader/Exception/InvalidValueException.php +++ b/lib/openspout/src/Reader/Exception/InvalidValueException.php @@ -8,7 +8,7 @@ final class InvalidValueException extends ReaderException { - private string $invalidValue; + private readonly string $invalidValue; public function __construct(string $invalidValue, string $message = '', int $code = 0, ?Throwable $previous = null) { diff --git a/lib/openspout/src/Reader/Exception/IteratorNotRewindableException.php b/lib/openspout/src/Reader/Exception/IteratorNotRewindableException.php index 80bff913fbd9..b1d5198d0786 100644 --- a/lib/openspout/src/Reader/Exception/IteratorNotRewindableException.php +++ b/lib/openspout/src/Reader/Exception/IteratorNotRewindableException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Reader\Exception; -final class IteratorNotRewindableException extends ReaderException -{ -} +final class IteratorNotRewindableException extends ReaderException {} diff --git a/lib/openspout/src/Reader/Exception/NoSheetsFoundException.php b/lib/openspout/src/Reader/Exception/NoSheetsFoundException.php index b240b3dee738..3844c246a804 100644 --- a/lib/openspout/src/Reader/Exception/NoSheetsFoundException.php +++ b/lib/openspout/src/Reader/Exception/NoSheetsFoundException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Reader\Exception; -final class NoSheetsFoundException extends ReaderException -{ -} +final class NoSheetsFoundException extends ReaderException {} diff --git a/lib/openspout/src/Reader/Exception/ReaderException.php b/lib/openspout/src/Reader/Exception/ReaderException.php index 676158904c93..9f5433a66d91 100644 --- a/lib/openspout/src/Reader/Exception/ReaderException.php +++ b/lib/openspout/src/Reader/Exception/ReaderException.php @@ -6,6 +6,4 @@ use OpenSpout\Common\Exception\OpenSpoutException; -abstract class ReaderException extends OpenSpoutException -{ -} +abstract class ReaderException extends OpenSpoutException {} diff --git a/lib/openspout/src/Reader/Exception/ReaderNotOpenedException.php b/lib/openspout/src/Reader/Exception/ReaderNotOpenedException.php index 913cb21aeb95..8cd2303244fb 100644 --- a/lib/openspout/src/Reader/Exception/ReaderNotOpenedException.php +++ b/lib/openspout/src/Reader/Exception/ReaderNotOpenedException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Reader\Exception; -final class ReaderNotOpenedException extends ReaderException -{ -} +final class ReaderNotOpenedException extends ReaderException {} diff --git a/lib/openspout/src/Reader/Exception/SharedStringNotFoundException.php b/lib/openspout/src/Reader/Exception/SharedStringNotFoundException.php index 0f50ac69ffa7..3f8337565b97 100644 --- a/lib/openspout/src/Reader/Exception/SharedStringNotFoundException.php +++ b/lib/openspout/src/Reader/Exception/SharedStringNotFoundException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Reader\Exception; -final class SharedStringNotFoundException extends ReaderException -{ -} +final class SharedStringNotFoundException extends ReaderException {} diff --git a/lib/openspout/src/Reader/Exception/XMLProcessingException.php b/lib/openspout/src/Reader/Exception/XMLProcessingException.php index bd7d1b9ea767..e4864f725ac2 100644 --- a/lib/openspout/src/Reader/Exception/XMLProcessingException.php +++ b/lib/openspout/src/Reader/Exception/XMLProcessingException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Reader\Exception; -final class XMLProcessingException extends ReaderException -{ -} +final class XMLProcessingException extends ReaderException {} diff --git a/lib/openspout/src/Reader/ODS/Helper/CellValueFormatter.php b/lib/openspout/src/Reader/ODS/Helper/CellValueFormatter.php index 3202e6e2c7be..f525a471bcc0 100644 --- a/lib/openspout/src/Reader/ODS/Helper/CellValueFormatter.php +++ b/lib/openspout/src/Reader/ODS/Helper/CellValueFormatter.php @@ -61,10 +61,10 @@ final class CellValueFormatter ]; /** @var bool Whether date/time values should be returned as PHP objects or be formatted as strings */ - private bool $shouldFormatDates; + private readonly bool $shouldFormatDates; /** @var ODS Used to unescape XML data */ - private ODS $escaper; + private readonly ODS $escaper; /** * @param bool $shouldFormatDates Whether date/time values should be returned as PHP objects or be formatted as strings @@ -150,7 +150,7 @@ private function formatBooleanCellValue(DOMElement $node): bool * * @throws InvalidValueException If the value is not a valid date */ - private function formatDateCellValue(DOMElement $node): string|DateTimeImmutable + private function formatDateCellValue(DOMElement $node): DateTimeImmutable|string { // The XML node looks like this: // diff --git a/lib/openspout/src/Reader/ODS/Helper/SettingsHelper.php b/lib/openspout/src/Reader/ODS/Helper/SettingsHelper.php index 9925e88a08f7..a3c9b9a714a6 100644 --- a/lib/openspout/src/Reader/ODS/Helper/SettingsHelper.php +++ b/lib/openspout/src/Reader/ODS/Helper/SettingsHelper.php @@ -43,7 +43,7 @@ public function getActiveSheetName(string $filePath): ?string break; } } - } catch (XMLProcessingException $exception) { // @codeCoverageIgnore + } catch (XMLProcessingException) { // @codeCoverageIgnore // do nothing } diff --git a/lib/openspout/src/Reader/ODS/Reader.php b/lib/openspout/src/Reader/ODS/Reader.php index 80a6852b8e8a..0e10b9c70b12 100644 --- a/lib/openspout/src/Reader/ODS/Reader.php +++ b/lib/openspout/src/Reader/ODS/Reader.php @@ -7,6 +7,7 @@ use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\Escaper\ODS; use OpenSpout\Reader\AbstractReader; +use OpenSpout\Reader\Exception\NoSheetsFoundException; use OpenSpout\Reader\ODS\Helper\SettingsHelper; use ZipArchive; @@ -17,7 +18,7 @@ final class Reader extends AbstractReader { private ZipArchive $zip; - private Options $options; + private readonly Options $options; /** @var SheetIterator To iterator over the ODS sheets */ private SheetIterator $sheetIterator; @@ -47,8 +48,8 @@ protected function doesSupportStreamWrapper(): bool * * @param string $filePath Path of the file to be read * - * @throws \OpenSpout\Common\Exception\IOException If the file at the given path or its content cannot be read - * @throws \OpenSpout\Reader\Exception\NoSheetsFoundException If there are no sheets in the file + * @throws IOException If the file at the given path or its content cannot be read + * @throws NoSheetsFoundException If there are no sheets in the file */ protected function openReader(string $filePath): void { diff --git a/lib/openspout/src/Reader/ODS/RowIterator.php b/lib/openspout/src/Reader/ODS/RowIterator.php index 9bdbbd203501..cfb6eeafc9b5 100644 --- a/lib/openspout/src/Reader/ODS/RowIterator.php +++ b/lib/openspout/src/Reader/ODS/RowIterator.php @@ -7,9 +7,11 @@ use DOMElement; use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Reader\Common\XMLProcessor; use OpenSpout\Reader\Exception\InvalidValueException; use OpenSpout\Reader\Exception\IteratorNotRewindableException; +use OpenSpout\Reader\Exception\SharedStringNotFoundException; use OpenSpout\Reader\ODS\Helper\CellValueFormatter; use OpenSpout\Reader\RowIteratorInterface; use OpenSpout\Reader\Wrapper\XMLReader; @@ -30,13 +32,13 @@ final class RowIterator implements RowIteratorInterface public const XML_ATTRIBUTE_NUM_ROWS_REPEATED = 'table:number-rows-repeated'; public const XML_ATTRIBUTE_NUM_COLUMNS_REPEATED = 'table:number-columns-repeated'; - private Options $options; + private readonly Options $options; /** @var XMLProcessor Helper Object to process XML nodes */ - private XMLProcessor $xmlProcessor; + private readonly XMLProcessor $xmlProcessor; /** @var Helper\CellValueFormatter Helper to format cell values */ - private Helper\CellValueFormatter $cellValueFormatter; + private readonly Helper\CellValueFormatter $cellValueFormatter; /** @var bool Whether the iterator has already been rewound once */ private bool $hasAlreadyBeenRewound = false; @@ -45,7 +47,7 @@ final class RowIterator implements RowIteratorInterface private Row $currentlyProcessedRow; /** @var null|Row Buffer used to store the current row, while checking if there are more rows to read */ - private ?Row $rowBuffer; + private ?Row $rowBuffer = null; /** @var bool Indicates whether all rows have been read */ private bool $hasReachedEndOfFile = false; @@ -57,7 +59,7 @@ final class RowIterator implements RowIteratorInterface private int $nextRowIndexToBeProcessed = 1; /** @var null|Cell Last processed cell (because when reading cell at column N+1, cell N is processed) */ - private ?Cell $lastProcessedCell; + private ?Cell $lastProcessedCell = null; /** @var int Number of times the last processed row should be repeated */ private int $numRowsRepeated = 1; @@ -90,7 +92,7 @@ public function __construct( * * @see http://php.net/manual/en/iterator.rewind.php * - * @throws \OpenSpout\Reader\Exception\IteratorNotRewindableException If the iterator is rewound more than once + * @throws IteratorNotRewindableException If the iterator is rewound more than once */ public function rewind(): void { @@ -125,8 +127,8 @@ public function valid(): bool * * @see http://php.net/manual/en/iterator.next.php * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If a shared string was not found - * @throws \OpenSpout\Common\Exception\IOException If unable to read the sheet data XML + * @throws SharedStringNotFoundException If a shared string was not found + * @throws IOException If unable to read the sheet data XML */ public function next(): void { @@ -176,8 +178,8 @@ private function doesNeedDataForNextRowToBeProcessed(): bool } /** - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If a shared string was not found - * @throws \OpenSpout\Common\Exception\IOException If unable to read the sheet data XML + * @throws SharedStringNotFoundException If a shared string was not found + * @throws IOException If unable to read the sheet data XML */ private function readDataForNextRow(): void { diff --git a/lib/openspout/src/Reader/ODS/Sheet.php b/lib/openspout/src/Reader/ODS/Sheet.php index 7f71d0a09e03..52917b586390 100644 --- a/lib/openspout/src/Reader/ODS/Sheet.php +++ b/lib/openspout/src/Reader/ODS/Sheet.php @@ -12,19 +12,19 @@ final class Sheet implements SheetWithVisibilityInterface { /** @var RowIterator To iterate over sheet's rows */ - private RowIterator $rowIterator; + private readonly RowIterator $rowIterator; /** @var int Index of the sheet, based on order in the workbook (zero-based) */ - private int $index; + private readonly int $index; /** @var string Name of the sheet */ - private string $name; + private readonly string $name; /** @var bool Whether the sheet was the active one */ - private bool $isActive; + private readonly bool $isActive; /** @var bool Whether the sheet is visible */ - private bool $isVisible; + private readonly bool $isVisible; /** * @param RowIterator $rowIterator The corresponding row iterator diff --git a/lib/openspout/src/Reader/ODS/SheetIterator.php b/lib/openspout/src/Reader/ODS/SheetIterator.php index 9d66d1068ad5..a6b34de16438 100644 --- a/lib/openspout/src/Reader/ODS/SheetIterator.php +++ b/lib/openspout/src/Reader/ODS/SheetIterator.php @@ -35,15 +35,15 @@ final class SheetIterator implements SheetIteratorInterface public const XML_ATTRIBUTE_TABLE_DISPLAY = 'table:display'; /** @var string Path of the file to be read */ - private string $filePath; + private readonly string $filePath; - private Options $options; + private readonly Options $options; /** @var XMLReader The XMLReader object that will help read sheet's XML data */ - private XMLReader $xmlReader; + private readonly XMLReader $xmlReader; /** @var ODS Used to unescape XML data */ - private ODS $escaper; + private readonly ODS $escaper; /** @var bool Whether there are still at least a sheet to be read */ private bool $hasFoundSheet; @@ -52,7 +52,7 @@ final class SheetIterator implements SheetIteratorInterface private int $currentSheetIndex; /** @var string The name of the sheet that was defined as active */ - private ?string $activeSheetName; + private readonly ?string $activeSheetName; /** @var array Associative array [STYLE_NAME] => [IS_SHEET_VISIBLE] */ private array $sheetsVisibility; @@ -75,7 +75,7 @@ public function __construct( * * @see http://php.net/manual/en/iterator.rewind.php * - * @throws \OpenSpout\Common\Exception\IOException If unable to open the XML file containing sheets' data + * @throws IOException If unable to open the XML file containing sheets' data */ public function rewind(): void { diff --git a/lib/openspout/src/Reader/ReaderInterface.php b/lib/openspout/src/Reader/ReaderInterface.php index 146bdf88c62d..691bdd6698e1 100644 --- a/lib/openspout/src/Reader/ReaderInterface.php +++ b/lib/openspout/src/Reader/ReaderInterface.php @@ -4,6 +4,8 @@ namespace OpenSpout\Reader; +use OpenSpout\Common\Exception\IOException; + /** * @template T of SheetIteratorInterface */ @@ -15,7 +17,7 @@ interface ReaderInterface * * @param string $filePath Path of the file to be read * - * @throws \OpenSpout\Common\Exception\IOException + * @throws IOException */ public function open(string $filePath): void; @@ -24,7 +26,7 @@ public function open(string $filePath): void; * * @return T * - * @throws \OpenSpout\Reader\Exception\ReaderNotOpenedException If called before opening the reader + * @throws Exception\ReaderNotOpenedException If called before opening the reader */ public function getSheetIterator(): SheetIteratorInterface; diff --git a/lib/openspout/src/Reader/Wrapper/XMLInternalErrorsHelper.php b/lib/openspout/src/Reader/Wrapper/XMLInternalErrorsHelper.php index 971750c5c7ec..76ccc202143d 100644 --- a/lib/openspout/src/Reader/Wrapper/XMLInternalErrorsHelper.php +++ b/lib/openspout/src/Reader/Wrapper/XMLInternalErrorsHelper.php @@ -28,7 +28,7 @@ private function useXMLInternalErrors(): void * Throws an XMLProcessingException if an error occured. * It also always resets the "libxml_use_internal_errors" setting back to its initial value. * - * @throws \OpenSpout\Reader\Exception\XMLProcessingException + * @throws XMLProcessingException */ private function resetXMLInternalErrorsSettingAndThrowIfXMLErrorOccured(): void { diff --git a/lib/openspout/src/Reader/Wrapper/XMLReader.php b/lib/openspout/src/Reader/Wrapper/XMLReader.php index 8fa9663f12cb..c2ebc16bd2da 100644 --- a/lib/openspout/src/Reader/Wrapper/XMLReader.php +++ b/lib/openspout/src/Reader/Wrapper/XMLReader.php @@ -4,6 +4,7 @@ namespace OpenSpout\Reader\Wrapper; +use OpenSpout\Reader\Exception\XMLProcessingException; use ZipArchive; /** @@ -59,7 +60,7 @@ public function getRealPathURIForFileInZip(string $zipFilePath, string $fileInsi * * @see \XMLReader::read * - * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred + * @throws XMLProcessingException If an error/warning occurred */ public function read(): bool { @@ -79,7 +80,7 @@ public function read(): bool * * @return bool TRUE on success or FALSE on failure * - * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred + * @throws XMLProcessingException If an error/warning occurred */ public function readUntilNodeFound(string $nodeName): bool { @@ -98,7 +99,7 @@ public function readUntilNodeFound(string $nodeName): bool * * @param null|string $localName The name of the next node to move to * - * @throws \OpenSpout\Reader\Exception\XMLProcessingException If an error/warning occurred + * @throws XMLProcessingException If an error/warning occurred */ public function next($localName = null): bool { diff --git a/lib/openspout/src/Reader/XLSX/Helper/CellHelper.php b/lib/openspout/src/Reader/XLSX/Helper/CellHelper.php index 19c4c248df2a..0b1fec262484 100644 --- a/lib/openspout/src/Reader/XLSX/Helper/CellHelper.php +++ b/lib/openspout/src/Reader/XLSX/Helper/CellHelper.php @@ -27,7 +27,7 @@ final class CellHelper * * @param string $cellIndex The Excel cell index ('A1', 'BC13', ...) * - * @throws \OpenSpout\Common\Exception\InvalidArgumentException When the given cell index is invalid + * @throws InvalidArgumentException When the given cell index is invalid */ public static function getColumnIndexFromCellIndex(string $cellIndex): int { diff --git a/lib/openspout/src/Reader/XLSX/Helper/CellValueFormatter.php b/lib/openspout/src/Reader/XLSX/Helper/CellValueFormatter.php index 4a4548db6645..0157f5c2b9cb 100644 --- a/lib/openspout/src/Reader/XLSX/Helper/CellValueFormatter.php +++ b/lib/openspout/src/Reader/XLSX/Helper/CellValueFormatter.php @@ -4,9 +4,11 @@ namespace OpenSpout\Reader\XLSX\Helper; +use DateInterval; use DateTimeImmutable; use DOMElement; use Exception; +use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Helper\Escaper\XLSX; use OpenSpout\Reader\Exception\InvalidValueException; use OpenSpout\Reader\XLSX\Manager\SharedStringsManager; @@ -33,6 +35,7 @@ final class CellValueFormatter */ public const XML_NODE_VALUE = 'v'; public const XML_NODE_INLINE_STRING_VALUE = 't'; + public const XML_NODE_FORMULA = 'f'; /** * Definition of XML attributes used to parse data. @@ -46,19 +49,19 @@ final class CellValueFormatter public const NUM_SECONDS_IN_ONE_DAY = 86400; /** @var SharedStringsManager Manages shared strings */ - private SharedStringsManager $sharedStringsManager; + private readonly SharedStringsManager $sharedStringsManager; /** @var StyleManagerInterface Manages styles */ - private StyleManagerInterface $styleManager; + private readonly StyleManagerInterface $styleManager; /** @var bool Whether date/time values should be returned as PHP objects or be formatted as strings */ - private bool $shouldFormatDates; + private readonly bool $shouldFormatDates; /** @var bool Whether date/time values should use a calendar starting in 1904 instead of 1900 */ - private bool $shouldUse1904Dates; + private readonly bool $shouldUse1904Dates; /** @var XLSX Used to unescape XML data */ - private XLSX $escaper; + private readonly XLSX $escaper; /** * @param SharedStringsManager $sharedStringsManager Manages shared strings @@ -83,31 +86,44 @@ public function __construct( /** * Returns the (unescaped) correctly marshalled, cell value associated to the given XML node. - * - * @return bool|DateTimeImmutable|float|int|string The value associated with the cell - * - * @throws InvalidValueException If the value is not valid */ - public function extractAndFormatNodeValue(DOMElement $node): bool|DateTimeImmutable|float|int|string + public function extractAndFormatNodeValue(DOMElement $node): Cell { // Default cell type is "n" - $cellType = $node->getAttribute(self::XML_ATTRIBUTE_TYPE) ?: self::CELL_TYPE_NUMERIC; - $cellStyleId = (int) $node->getAttribute(self::XML_ATTRIBUTE_STYLE_ID); + $cellType = $node->getAttribute(self::XML_ATTRIBUTE_TYPE); + if ('' === $cellType) { + $cellType = self::CELL_TYPE_NUMERIC; + } $vNodeValue = $this->getVNodeValue($node); - if (('' === $vNodeValue) && (self::CELL_TYPE_INLINE_STRING !== $cellType)) { - return $vNodeValue; + if (self::CELL_TYPE_NUMERIC === $cellType) { + $fNodeValue = $node->getElementsByTagName(self::XML_NODE_FORMULA)->item(0)?->nodeValue; + if (null !== $fNodeValue) { + $computedValue = $this->formatNumericCellValue($vNodeValue, (int) $node->getAttribute(self::XML_ATTRIBUTE_STYLE_ID)); + + return new Cell\FormulaCell('='.$fNodeValue, null, $computedValue); + } } - return match ($cellType) { + if ('' === $vNodeValue && self::CELL_TYPE_INLINE_STRING !== $cellType) { + return Cell::fromValue($vNodeValue); + } + + $rawValue = match ($cellType) { self::CELL_TYPE_INLINE_STRING => $this->formatInlineStringCellValue($node), self::CELL_TYPE_SHARED_STRING => $this->formatSharedStringCellValue($vNodeValue), self::CELL_TYPE_STR => $this->formatStrCellValue($vNodeValue), self::CELL_TYPE_BOOLEAN => $this->formatBooleanCellValue($vNodeValue), - self::CELL_TYPE_NUMERIC => $this->formatNumericCellValue($vNodeValue, $cellStyleId), + self::CELL_TYPE_NUMERIC => $this->formatNumericCellValue($vNodeValue, (int) $node->getAttribute(self::XML_ATTRIBUTE_STYLE_ID)), self::CELL_TYPE_DATE => $this->formatDateCellValue($vNodeValue), - default => throw new InvalidValueException($vNodeValue), + default => new Cell\ErrorCell($vNodeValue, null), }; + + if ($rawValue instanceof Cell) { + return $rawValue; + } + + return Cell::fromValue($rawValue); } /** @@ -178,13 +194,15 @@ private function formatStrCellValue(string $nodeValue): string * * @param int $cellStyleId 0 being the default style */ - private function formatNumericCellValue(int|float|string $nodeValue, int $cellStyleId): DateTimeImmutable|float|int|string + private function formatNumericCellValue(float|int|string $nodeValue, int $cellStyleId): DateInterval|DateTimeImmutable|float|int|string { // Numeric values can represent numbers as well as timestamps. // We need to look at the style of the cell to determine whether it is one or the other. - $shouldFormatAsDate = $this->styleManager->shouldFormatNumericValueAsDate($cellStyleId); + $formatCode = $this->styleManager->getNumberFormatCode($cellStyleId); - if ($shouldFormatAsDate) { + if (DateIntervalFormatHelper::isDurationFormat($formatCode)) { + $cellValue = $this->formatExcelDateIntervalValue((float) $nodeValue, $formatCode); + } elseif ($this->styleManager->shouldFormatNumericValueAsDate($cellStyleId)) { $cellValue = $this->formatExcelTimestampValue((float) $nodeValue, $cellStyleId); } else { $nodeIntValue = (int) $nodeValue; @@ -195,6 +213,16 @@ private function formatNumericCellValue(int|float|string $nodeValue, int $cellSt return $cellValue; } + private function formatExcelDateIntervalValue(float $nodeValue, string $excelFormat): DateInterval|string + { + $dateInterval = DateIntervalFormatHelper::createDateIntervalFromHours($nodeValue); + if ($this->shouldFormatDates) { + return DateIntervalFormatHelper::formatDateInterval($dateInterval, $excelFormat); + } + + return $dateInterval; + } + /** * Returns a cell's PHP Date value, associated to the given timestamp. * NOTE: The timestamp is a float representing the number of days since the base Excel date: @@ -207,7 +235,7 @@ private function formatNumericCellValue(int|float|string $nodeValue, int $cellSt * * @see ECMA-376 Part 1 - §18.17.4 */ - private function formatExcelTimestampValue(float $nodeValue, int $cellStyleId): string|DateTimeImmutable + private function formatExcelTimestampValue(float $nodeValue, int $cellStyleId): DateTimeImmutable|string { if (!$this->isValidTimestampValue($nodeValue)) { throw new InvalidValueException((string) $nodeValue); @@ -236,7 +264,7 @@ private function isValidTimestampValue(float $timestampValue): bool * * @param int $cellStyleId 0 being the default style */ - private function formatExcelTimestampValueAsDateTimeValue(float $nodeValue, int $cellStyleId): string|DateTimeImmutable + private function formatExcelTimestampValueAsDateTimeValue(float $nodeValue, int $cellStyleId): DateTimeImmutable|string { $baseDate = $this->shouldUse1904Dates ? '1904-01-01' : '1899-12-30'; @@ -288,16 +316,14 @@ private function formatBooleanCellValue(string $nodeValue): bool * @see ECMA-376 Part 1 - §18.17.4 * * @param string $nodeValue ISO 8601 Date string - * - * @throws InvalidValueException If the value is not a valid date */ - private function formatDateCellValue(string $nodeValue): string|DateTimeImmutable + private function formatDateCellValue(string $nodeValue): Cell\ErrorCell|DateTimeImmutable|string { // Mitigate thrown Exception on invalid date-time format (http://php.net/manual/en/datetime.construct.php) try { $cellValue = ($this->shouldFormatDates) ? $nodeValue : new DateTimeImmutable($nodeValue); - } catch (Exception $exception) { - throw new InvalidValueException($nodeValue, '', 0, $exception); + } catch (Exception) { + return new Cell\ErrorCell($nodeValue, null); } return $cellValue; diff --git a/lib/openspout/src/Reader/XLSX/Helper/DateIntervalFormatHelper.php b/lib/openspout/src/Reader/XLSX/Helper/DateIntervalFormatHelper.php new file mode 100644 index 000000000000..7ae1a6e5be11 --- /dev/null +++ b/lib/openspout/src/Reader/XLSX/Helper/DateIntervalFormatHelper.php @@ -0,0 +1,96 @@ + '%H', + 'h' => '%h', + 'mm' => '%I', + 'm' => '%i', + 'ss' => '%S', + 's' => '%s', + ]; + + /** + * Excel stores durations as fractions of days (24h = 1). + * + * Only fills hours/minutes/seconds because those are the only values that we can format back out again. + * Excel can also only handle those units as duration. + * PHP's DateInterval is also quite limited - it will not automatically convert unit overflow + * (60 seconds are not converted to 1 minute). + */ + public static function createDateIntervalFromHours(float $dayFractions): DateInterval + { + $time = abs($dayFractions) * 24; // convert to hours + $hours = floor($time); + $time = ($time - $hours) * 60; + $minutes = (int) floor($time); // must cast to int for type strict compare below + $time = ($time - $minutes) * 60; + $seconds = (int) round($time); // must cast to int for type strict compare below + + // Bubble up rounding gain if we ended up with 60 seconds - disadvantage of using fraction of days for small durations: + if (60 === $seconds) { + $seconds = 0; + ++$minutes; + } + if (60 === $minutes) { + $minutes = 0; + ++$hours; + } + + $interval = new DateInterval("P0DT{$hours}H{$minutes}M{$seconds}S"); + if ($dayFractions < 0) { + $interval->invert = 1; + } + + return $interval; + } + + public static function isDurationFormat(string $excelFormat): bool + { + // Only consider formats with leading brackets as valid duration formats (e.g. "[hh]:mm", "[mm]:ss", etc.): + return 1 === preg_match('/^(\[hh?](:mm(:ss)?)?|\[mm?](:ss)?|\[ss?])$/', $excelFormat); + } + + public static function toPHPDateIntervalFormat(string $excelDateFormat, ?string &$startUnit = null): string + { + $startUnit = null; + $phpFormatParts = []; + $formatParts = explode(':', str_replace(['[', ']'], '', $excelDateFormat)); + foreach ($formatParts as $formatPart) { + $startUnit ??= $formatPart; + $phpFormatParts[] = self::dateIntervalFormats[$formatPart]; + } + + // Add the minus sign for potential negative durations: + return '%r'.implode(':', $phpFormatParts); + } + + public static function formatDateInterval(DateInterval $dateInterval, string $excelDateFormat): string + { + $phpFormat = self::toPHPDateIntervalFormat($excelDateFormat, $startUnit); + + // We have to move the hours to minutes or hours+minutes to seconds if the format in Excel did the same: + $startUnit = $startUnit[0]; // only take the first char + $dateIntervalClone = clone $dateInterval; + if ('m' === $startUnit) { + $dateIntervalClone->i = $dateIntervalClone->i + $dateIntervalClone->h * 60; + $dateIntervalClone->h = 0; + } elseif ('s' === $startUnit) { + $dateIntervalClone->s = $dateIntervalClone->s + $dateIntervalClone->i * 60 + $dateIntervalClone->h * 3600; + $dateIntervalClone->i = 0; + $dateIntervalClone->h = 0; + } + + return $dateIntervalClone->format($phpFormat); + } +} diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyFactory.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyFactory.php index ac1a71d6c438..749e628537c2 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyFactory.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyFactory.php @@ -50,7 +50,7 @@ final class CachingStrategyFactory implements CachingStrategyFactoryInterface */ public const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000; - private MemoryLimit $memoryLimit; + private readonly MemoryLimit $memoryLimit; public function __construct(MemoryLimit $memoryLimit) { diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyInterface.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyInterface.php index e120c9595a8f..bc2cb5b07f3b 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyInterface.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/CachingStrategyInterface.php @@ -4,6 +4,8 @@ namespace OpenSpout\Reader\XLSX\Manager\SharedStringsCaching; +use OpenSpout\Reader\Exception\SharedStringNotFoundException; + /** * @internal */ @@ -30,7 +32,7 @@ public function closeCache(): void; * * @return string The shared string at the given index * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If no shared string found for the given index + * @throws SharedStringNotFoundException If no shared string found for the given index */ public function getStringAtIndex(int $sharedStringIndex): string; diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/FileBasedStrategy.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/FileBasedStrategy.php index f018b765424a..2e9dc35e9c1a 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/FileBasedStrategy.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/FileBasedStrategy.php @@ -22,17 +22,17 @@ final class FileBasedStrategy implements CachingStrategyInterface public const ESCAPED_LINE_FEED_CHARACTER = '_x000A_'; /** @var FileSystemHelper Helper to perform file system operations */ - private FileSystemHelper $fileSystemHelper; + private readonly FileSystemHelper $fileSystemHelper; /** @var string Temporary folder where the temporary files will be created */ - private string $tempFolder; + private readonly string $tempFolder; /** * @var int Maximum number of strings that can be stored in one temp file * * @see CachingStrategyFactory::MAX_NUM_STRINGS_PER_TEMP_FILE */ - private int $maxNumStringsPerTempFile; + private readonly int $maxNumStringsPerTempFile; /** @var null|resource Pointer to the last temp file a shared string was written to */ private $tempFilePointer; @@ -61,8 +61,6 @@ public function __construct(string $tempFolder, int $maxNumStringsPerTempFile) $this->tempFolder = $this->fileSystemHelper->createFolder($tempFolder, uniqid('sharedstrings')); $this->maxNumStringsPerTempFile = $maxNumStringsPerTempFile; - - $this->tempFilePointer = null; } /** @@ -110,7 +108,7 @@ public function closeCache(): void * * @return string The shared string at the given index * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If no shared string found for the given index + * @throws SharedStringNotFoundException If no shared string found for the given index */ public function getStringAtIndex(int $sharedStringIndex): string { diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/InMemoryStrategy.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/InMemoryStrategy.php index 488581016643..a3bcffc48c8d 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/InMemoryStrategy.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/InMemoryStrategy.php @@ -20,7 +20,7 @@ final class InMemoryStrategy implements CachingStrategyInterface private SplFixedArray $inMemoryCache; /** @var bool Whether the cache has been closed */ - private bool $isCacheClosed; + private bool $isCacheClosed = false; /** * @param int $sharedStringsUniqueCount Number of unique shared strings @@ -28,7 +28,6 @@ final class InMemoryStrategy implements CachingStrategyInterface public function __construct(int $sharedStringsUniqueCount) { $this->inMemoryCache = new SplFixedArray($sharedStringsUniqueCount); - $this->isCacheClosed = false; } /** @@ -60,13 +59,13 @@ public function closeCache(): void * * @return string The shared string at the given index * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If no shared string found for the given index + * @throws SharedStringNotFoundException If no shared string found for the given index */ public function getStringAtIndex(int $sharedStringIndex): string { try { return $this->inMemoryCache->offsetGet($sharedStringIndex); - } catch (RuntimeException $e) { + } catch (RuntimeException) { throw new SharedStringNotFoundException("Shared string not found for index: {$sharedStringIndex}"); } } diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/MemoryLimit.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/MemoryLimit.php index e9d76286c5e6..5645908f1bfa 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/MemoryLimit.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsCaching/MemoryLimit.php @@ -9,7 +9,7 @@ */ final class MemoryLimit { - private string $memoryLimit; + private readonly string $memoryLimit; public function __construct(string $memoryLimit) { diff --git a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsManager.php b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsManager.php index 9a129a18f5f6..5a93b01a4230 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SharedStringsManager.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SharedStringsManager.php @@ -6,6 +6,7 @@ use DOMElement; use OpenSpout\Common\Exception\IOException; +use OpenSpout\Reader\Exception\SharedStringNotFoundException; use OpenSpout\Reader\Exception\XMLProcessingException; use OpenSpout\Reader\Wrapper\XMLReader; use OpenSpout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyFactoryInterface; @@ -34,15 +35,15 @@ final class SharedStringsManager public const XML_ATTRIBUTE_VALUE_PRESERVE = 'preserve'; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; - private Options $options; + private readonly Options $options; /** @var WorkbookRelationshipsManager Helps retrieving workbook relationships */ - private WorkbookRelationshipsManager $workbookRelationshipsManager; + private readonly WorkbookRelationshipsManager $workbookRelationshipsManager; /** @var CachingStrategyFactoryInterface Factory to create shared strings caching strategies */ - private CachingStrategyFactoryInterface $cachingStrategyFactory; + private readonly CachingStrategyFactoryInterface $cachingStrategyFactory; /** @var CachingStrategyInterface The best caching strategy for storing shared strings */ private CachingStrategyInterface $cachingStrategy; @@ -77,7 +78,7 @@ public function hasSharedStrings(): bool * The XML file can be really big with sheets containing a lot of data. That is why * we need to use a XML reader that provides streaming like the XMLReader library. * - * @throws \OpenSpout\Common\Exception\IOException If shared strings XML file can't be read + * @throws IOException If shared strings XML file can't be read */ public function extractSharedStrings(): void { @@ -118,7 +119,7 @@ public function extractSharedStrings(): void * * @return string The shared string at the given index * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If no shared string found for the given index + * @throws SharedStringNotFoundException If no shared string found for the given index */ public function getStringAtIndex(int $sharedStringIndex): string { @@ -142,7 +143,7 @@ public function cleanup(): void * * @return null|int Number of unique shared strings in the sharedStrings.xml file * - * @throws \OpenSpout\Common\Exception\IOException If sharedStrings.xml is invalid and can't be read + * @throws IOException If sharedStrings.xml is invalid and can't be read */ private function getSharedStringsUniqueCount(XMLReader $xmlReader): ?int { diff --git a/lib/openspout/src/Reader/XLSX/Manager/SheetManager.php b/lib/openspout/src/Reader/XLSX/Manager/SheetManager.php index 296cba3f3712..69aa11d36112 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/SheetManager.php +++ b/lib/openspout/src/Reader/XLSX/Manager/SheetManager.php @@ -51,15 +51,15 @@ final class SheetManager public const SHEET_STATE_HIDDEN = 'hidden'; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; - private Options $options; + private readonly Options $options; /** @var SharedStringsManager Manages shared strings */ - private SharedStringsManager $sharedStringsManager; + private readonly SharedStringsManager $sharedStringsManager; /** @var XLSX Used to unescape XML data */ - private XLSX $escaper; + private readonly XLSX $escaper; /** @var Sheet[] List of sheets */ private array $sheets; @@ -111,7 +111,7 @@ public function getSheets(): array } /** - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReader XMLReader object, positioned on a "" starting node + * @param XMLReader $xmlReader XMLReader object, positioned on a "" starting node * * @return int A return code that indicates what action should the processor take next */ @@ -126,7 +126,7 @@ private function processWorkbookPropertiesStartingNode(XMLReader $xmlReader): in } /** - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReader XMLReader object, positioned on a "" starting node + * @param XMLReader $xmlReader XMLReader object, positioned on a "" starting node * * @return int A return code that indicates what action should the processor take next */ @@ -140,7 +140,7 @@ private function processWorkbookViewStartingNode(XMLReader $xmlReader): int } /** - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReader XMLReader object, positioned on a "" starting node + * @param XMLReader $xmlReader XMLReader object, positioned on a "" starting node * * @return int A return code that indicates what action should the processor take next */ @@ -166,11 +166,11 @@ private function processSheetsEndingNode(): int * We can find the XML file path describing the sheet inside "workbook.xml.res", by mapping with the sheet ID * ("r:id" in "workbook.xml", "Id" in "workbook.xml.res"). * - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReaderOnSheetNode XML Reader instance, pointing on the node describing the sheet, as defined in "workbook.xml" - * @param int $sheetIndexZeroBased Index of the sheet, based on order of appearance in the workbook (zero-based) - * @param bool $isSheetActive Whether this sheet was defined as active + * @param XMLReader $xmlReaderOnSheetNode XML Reader instance, pointing on the node describing the sheet, as defined in "workbook.xml" + * @param int $sheetIndexZeroBased Index of the sheet, based on order of appearance in the workbook (zero-based) + * @param bool $isSheetActive Whether this sheet was defined as active * - * @return \OpenSpout\Reader\XLSX\Sheet Sheet instance + * @return Sheet Sheet instance */ private function getSheetFromSheetXMLNode(XMLReader $xmlReaderOnSheetNode, int $sheetIndexZeroBased, bool $isSheetActive): Sheet { diff --git a/lib/openspout/src/Reader/XLSX/Manager/StyleManager.php b/lib/openspout/src/Reader/XLSX/Manager/StyleManager.php index 6c56ea8f781f..caac7dbcd86b 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/StyleManager.php +++ b/lib/openspout/src/Reader/XLSX/Manager/StyleManager.php @@ -11,25 +11,25 @@ class StyleManager implements StyleManagerInterface /** * Nodes used to find relevant information in the styles XML file. */ - public const XML_NODE_NUM_FMTS = 'numFmts'; - public const XML_NODE_NUM_FMT = 'numFmt'; - public const XML_NODE_CELL_XFS = 'cellXfs'; - public const XML_NODE_XF = 'xf'; + final public const XML_NODE_NUM_FMTS = 'numFmts'; + final public const XML_NODE_NUM_FMT = 'numFmt'; + final public const XML_NODE_CELL_XFS = 'cellXfs'; + final public const XML_NODE_XF = 'xf'; /** * Attributes used to find relevant information in the styles XML file. */ - public const XML_ATTRIBUTE_NUM_FMT_ID = 'numFmtId'; - public const XML_ATTRIBUTE_FORMAT_CODE = 'formatCode'; - public const XML_ATTRIBUTE_APPLY_NUMBER_FORMAT = 'applyNumberFormat'; - public const XML_ATTRIBUTE_COUNT = 'count'; + final public const XML_ATTRIBUTE_NUM_FMT_ID = 'numFmtId'; + final public const XML_ATTRIBUTE_FORMAT_CODE = 'formatCode'; + final public const XML_ATTRIBUTE_APPLY_NUMBER_FORMAT = 'applyNumberFormat'; + final public const XML_ATTRIBUTE_COUNT = 'count'; /** * By convention, default style ID is 0. */ - public const DEFAULT_STYLE_ID = 0; + final public const DEFAULT_STYLE_ID = 0; - public const NUMBER_FORMAT_GENERAL = 'General'; + final public const NUMBER_FORMAT_GENERAL = 'General'; /** * Mapping between built-in numFmtId and the associated format - for dates only. @@ -52,10 +52,10 @@ class StyleManager implements StyleManagerInterface ]; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; /** @var null|string Path of the styles XML file */ - private ?string $stylesXMLFilePath; + private readonly ?string $stylesXMLFilePath; /** @var array Array containing a mapping NUM_FMT_ID => FORMAT_CODE */ private array $customNumberFormats; @@ -107,7 +107,7 @@ public function getNumberFormatCode(int $styleId): string $numberFormatCode = self::builtinNumFmtIdToNumFormatMapping[$numFmtId]; } else { $customNumberFormats = $this->getCustomNumberFormats(); - $numberFormatCode = $customNumberFormats[$numFmtId]; + $numberFormatCode = $customNumberFormats[$numFmtId] ?? ''; } return $numberFormatCode; @@ -166,7 +166,7 @@ private function extractRelevantInfo(): void * For simplicity, the styles attributes are kept in memory. This is possible thanks * to the reuse of formats. So 1 million cells should not use 1 million formats. * - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReader XML Reader positioned on the "numFmts" node + * @param XMLReader $xmlReader XML Reader positioned on the "numFmts" node */ private function extractNumberFormats(XMLReader $xmlReader): void { @@ -188,7 +188,7 @@ private function extractNumberFormats(XMLReader $xmlReader): void * For simplicity, the styles attributes are kept in memory. This is possible thanks * to the reuse of styles. So 1 million cells should not use 1 million styles. * - * @param \OpenSpout\Reader\Wrapper\XMLReader $xmlReader XML Reader positioned on the "cellXfs" node + * @param XMLReader $xmlReader XML Reader positioned on the "cellXfs" node */ private function extractStyleAttributes(XMLReader $xmlReader): void { @@ -262,7 +262,7 @@ private function getFormatCodeForNumFmtId(int $numFmtId): ?string $customNumberFormats = $this->getCustomNumberFormats(); // Using isset here because it is way faster than array_key_exists... - return (isset($customNumberFormats[$numFmtId])) ? $customNumberFormats[$numFmtId] : null; + return $customNumberFormats[$numFmtId] ?? null; } /** @@ -296,6 +296,10 @@ private function isFormatCodeMatchingDateFormatPattern(string $formatCode): bool $formatCode = preg_replace($pattern, '', $formatCode); \assert(null !== $formatCode); + // Remove strings in double quotes, as they won't be interpreted as date format characters + $formatCode = preg_replace('/"[^"]+"/', '', $formatCode); + \assert(null !== $formatCode); + // custom date formats contain specific characters to represent the date: // e - yy - m - d - h - s // and all of their variants (yyyy - mm - dd...) diff --git a/lib/openspout/src/Reader/XLSX/Manager/WorkbookRelationshipsManager.php b/lib/openspout/src/Reader/XLSX/Manager/WorkbookRelationshipsManager.php index 1c3e209ce32e..9ffa8874544d 100644 --- a/lib/openspout/src/Reader/XLSX/Manager/WorkbookRelationshipsManager.php +++ b/lib/openspout/src/Reader/XLSX/Manager/WorkbookRelationshipsManager.php @@ -35,7 +35,7 @@ final class WorkbookRelationshipsManager public const XML_ATTRIBUTE_TARGET = 'Target'; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; /** @var array Cache of the already read workbook relationships: [TYPE] => [FILE_NAME] */ private array $cachedWorkbookRelationships; @@ -114,7 +114,7 @@ public function getStylesXMLFilePath(): string * * @return array * - * @throws \OpenSpout\Common\Exception\IOException If workbook.xml.rels can't be read + * @throws IOException If workbook.xml.rels can't be read */ private function getWorkbookRelationships(): array { diff --git a/lib/openspout/src/Reader/XLSX/Reader.php b/lib/openspout/src/Reader/XLSX/Reader.php index a87b78e17d96..f9bbc0923326 100644 --- a/lib/openspout/src/Reader/XLSX/Reader.php +++ b/lib/openspout/src/Reader/XLSX/Reader.php @@ -7,6 +7,7 @@ use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\Escaper\XLSX; use OpenSpout\Reader\AbstractReader; +use OpenSpout\Reader\Exception\NoSheetsFoundException; use OpenSpout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyFactory; use OpenSpout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyFactoryInterface; use OpenSpout\Reader\XLSX\Manager\SharedStringsCaching\MemoryLimit; @@ -28,8 +29,8 @@ final class Reader extends AbstractReader /** @var SheetIterator To iterator over the XLSX sheets */ private SheetIterator $sheetIterator; - private Options $options; - private CachingStrategyFactoryInterface $cachingStrategyFactory; + private readonly Options $options; + private readonly CachingStrategyFactoryInterface $cachingStrategyFactory; public function __construct( ?Options $options = null, @@ -66,8 +67,8 @@ protected function doesSupportStreamWrapper(): bool * * @param string $filePath Path of the file to be read * - * @throws \OpenSpout\Common\Exception\IOException If the file at the given path or its content cannot be read - * @throws \OpenSpout\Reader\Exception\NoSheetsFoundException If there are no sheets in the file + * @throws IOException If the file at the given path or its content cannot be read + * @throws NoSheetsFoundException If there are no sheets in the file */ protected function openReader(string $filePath): void { diff --git a/lib/openspout/src/Reader/XLSX/RowIterator.php b/lib/openspout/src/Reader/XLSX/RowIterator.php index b5ca46cc57eb..b3ad10e84c5d 100644 --- a/lib/openspout/src/Reader/XLSX/RowIterator.php +++ b/lib/openspout/src/Reader/XLSX/RowIterator.php @@ -7,10 +7,11 @@ use DOMElement; use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\InvalidArgumentException; use OpenSpout\Common\Exception\IOException; use OpenSpout\Reader\Common\Manager\RowManager; use OpenSpout\Reader\Common\XMLProcessor; -use OpenSpout\Reader\Exception\InvalidValueException; +use OpenSpout\Reader\Exception\SharedStringNotFoundException; use OpenSpout\Reader\RowIteratorInterface; use OpenSpout\Reader\Wrapper\XMLReader; use OpenSpout\Reader\XLSX\Helper\CellHelper; @@ -35,22 +36,22 @@ final class RowIterator implements RowIteratorInterface public const XML_ATTRIBUTE_CELL_INDEX = 'r'; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; /** @var string Path of the sheet data XML file as in [Content_Types].xml */ - private string $sheetDataXMLFilePath; + private readonly string $sheetDataXMLFilePath; /** @var XMLReader The XMLReader object that will help read sheet's XML data */ - private XMLReader $xmlReader; + private readonly XMLReader $xmlReader; /** @var XMLProcessor Helper Object to process XML nodes */ - private XMLProcessor $xmlProcessor; + private readonly XMLProcessor $xmlProcessor; /** @var Helper\CellValueFormatter Helper to format cell values */ - private Helper\CellValueFormatter $cellValueFormatter; + private readonly Helper\CellValueFormatter $cellValueFormatter; /** @var RowManager Manages rows */ - private RowManager $rowManager; + private readonly RowManager $rowManager; /** * TODO: This variable can be deleted when row indices get preserved. @@ -63,7 +64,7 @@ final class RowIterator implements RowIteratorInterface private Row $currentlyProcessedRow; /** @var null|Row Buffer used to store the current row, while checking if there are more rows to read */ - private ?Row $rowBuffer; + private ?Row $rowBuffer = null; /** @var bool Indicates whether all rows have been read */ private bool $hasReachedEndOfFile = false; @@ -72,7 +73,7 @@ final class RowIterator implements RowIteratorInterface private int $numColumns = 0; /** @var bool Whether empty rows should be returned or skipped */ - private bool $shouldPreserveEmptyRows; + private readonly bool $shouldPreserveEmptyRows; /** @var int Last row index processed (one-based) */ private int $lastRowIndexProcessed = 0; @@ -124,7 +125,7 @@ public function __construct( * * @see http://php.net/manual/en/iterator.rewind.php * - * @throws \OpenSpout\Common\Exception\IOException If the sheet data XML cannot be read + * @throws IOException If the sheet data XML cannot be read */ public function rewind(): void { @@ -164,8 +165,8 @@ public function valid(): bool * * @see http://php.net/manual/en/iterator.next.php * - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If a shared string was not found - * @throws \OpenSpout\Common\Exception\IOException If unable to read the sheet data XML + * @throws SharedStringNotFoundException If a shared string was not found + * @throws IOException If unable to read the sheet data XML */ public function next(): void { @@ -251,8 +252,8 @@ private function doesNeedDataForNextRowToBeProcessed(): bool } /** - * @throws \OpenSpout\Reader\Exception\SharedStringNotFoundException If a shared string was not found - * @throws \OpenSpout\Common\Exception\IOException If unable to read the sheet data XML + * @throws SharedStringNotFoundException If a shared string was not found + * @throws IOException If unable to read the sheet data XML */ private function readDataForNextRow(): void { @@ -317,9 +318,9 @@ private function processCellStartingNode(XMLReader $xmlReader): int $currentColumnIndex = $this->getColumnIndex($xmlReader); // NOTE: expand() will automatically decode all XML entities of the child nodes - /** @var DOMElement $node */ $node = $xmlReader->expand(); - $cell = $this->getCell($node); + \assert($node instanceof DOMElement); + $cell = $this->cellValueFormatter->extractAndFormatNodeValue($node); $this->currentlyProcessedRow->setCellAtIndex($cell, $currentColumnIndex); $this->lastColumnIndexProcessed = $currentColumnIndex; @@ -366,7 +367,7 @@ private function processWorksheetEndingNode(): int * * @return int Row index * - * @throws \OpenSpout\Common\Exception\InvalidArgumentException When the given cell index is invalid + * @throws InvalidArgumentException When the given cell index is invalid */ private function getRowIndex(XMLReader $xmlReader): int { @@ -383,7 +384,7 @@ private function getRowIndex(XMLReader $xmlReader): int * * @return int Column index * - * @throws \OpenSpout\Common\Exception\InvalidArgumentException When the given cell index is invalid + * @throws InvalidArgumentException When the given cell index is invalid */ private function getColumnIndex(XMLReader $xmlReader): int { @@ -394,21 +395,4 @@ private function getColumnIndex(XMLReader $xmlReader): int CellHelper::getColumnIndexFromCellIndex($currentCellIndex) : $this->lastColumnIndexProcessed + 1; } - - /** - * Returns the cell with (unescaped) correctly marshalled, cell value associated to the given XML node. - * - * @return Cell The cell set with the associated with the cell - */ - private function getCell(DOMElement $node): Cell - { - try { - $cellValue = $this->cellValueFormatter->extractAndFormatNodeValue($node); - $cell = Cell::fromValue($cellValue); - } catch (InvalidValueException $exception) { - $cell = new Cell\ErrorCell($exception->getInvalidValue(), null); - } - - return $cell; - } } diff --git a/lib/openspout/src/Reader/XLSX/Sheet.php b/lib/openspout/src/Reader/XLSX/Sheet.php index dc671234f75d..504b20ed33a8 100644 --- a/lib/openspout/src/Reader/XLSX/Sheet.php +++ b/lib/openspout/src/Reader/XLSX/Sheet.php @@ -13,22 +13,22 @@ final class Sheet implements SheetWithVisibilityInterface { /** @var RowIterator To iterate over sheet's rows */ - private RowIterator $rowIterator; + private readonly RowIterator $rowIterator; /** @var SheetHeaderReader To read the header of the sheet, containing for instance the col widths */ - private SheetHeaderReader $headerReader; + private readonly SheetHeaderReader $headerReader; /** @var int Index of the sheet, based on order in the workbook (zero-based) */ - private int $index; + private readonly int $index; /** @var string Name of the sheet */ - private string $name; + private readonly string $name; /** @var bool Whether the sheet was the active one */ - private bool $isActive; + private readonly bool $isActive; /** @var bool Whether the sheet is visible */ - private bool $isVisible; + private readonly bool $isVisible; /** * @param RowIterator $rowIterator The corresponding row iterator diff --git a/lib/openspout/src/Reader/XLSX/SheetHeaderReader.php b/lib/openspout/src/Reader/XLSX/SheetHeaderReader.php index ea4be2bb7493..5c6b4296f9bf 100644 --- a/lib/openspout/src/Reader/XLSX/SheetHeaderReader.php +++ b/lib/openspout/src/Reader/XLSX/SheetHeaderReader.php @@ -18,16 +18,16 @@ final class SheetHeaderReader public const XML_ATTRIBUTE_WIDTH = 'width'; /** @var string Path of the XLSX file being read */ - private string $filePath; + private readonly string $filePath; /** @var string Path of the sheet data XML file as in [Content_Types].xml */ - private string $sheetDataXMLFilePath; + private readonly string $sheetDataXMLFilePath; /** @var XMLReader The XMLReader object that will help read sheet's XML data */ - private XMLReader $xmlReader; + private readonly XMLReader $xmlReader; /** @var XMLProcessor Helper Object to process XML nodes */ - private XMLProcessor $xmlProcessor; + private readonly XMLProcessor $xmlProcessor; /** @var ColumnWidth[] The widths of the columns in the sheet, if specified */ private array $columnWidths = []; diff --git a/lib/openspout/src/Writer/AutoFilter.php b/lib/openspout/src/Writer/AutoFilter.php index b9796446457c..5fefac1068be 100644 --- a/lib/openspout/src/Writer/AutoFilter.php +++ b/lib/openspout/src/Writer/AutoFilter.php @@ -16,10 +16,9 @@ final class AutoFilter * @param positive-int $toRow */ public function __construct( - public int $fromColumnIndex, - public int $fromRow, - public int $toColumnIndex, - public int $toRow - ) { - } + public readonly int $fromColumnIndex, + public readonly int $fromRow, + public readonly int $toColumnIndex, + public readonly int $toRow + ) {} } diff --git a/lib/openspout/src/Writer/CSV/Writer.php b/lib/openspout/src/Writer/CSV/Writer.php index f3d94e487b00..f1087eac7801 100644 --- a/lib/openspout/src/Writer/CSV/Writer.php +++ b/lib/openspout/src/Writer/CSV/Writer.php @@ -15,7 +15,7 @@ final class Writer extends AbstractWriter /** @var string Content-Type value for the header */ protected static string $headerContentType = 'text/csv; charset=UTF-8'; - private Options $options; + private readonly Options $options; private int $lastWrittenRowIndex = 0; @@ -49,10 +49,16 @@ protected function openWriter(): void */ protected function addRowToWriter(Row $row): void { - $cells = array_map(static function (Cell\BooleanCell|Cell\EmptyCell|Cell\NumericCell|Cell\StringCell|Cell\FormulaCell $value): string { + $cells = array_map(static function (Cell\BooleanCell|Cell\DateIntervalCell|Cell\DateTimeCell|Cell\EmptyCell|Cell\FormulaCell|Cell\NumericCell|Cell\StringCell $value): string { if ($value instanceof Cell\BooleanCell) { return (string) (int) $value->getValue(); } + if ($value instanceof Cell\DateTimeCell) { + return $value->getValue()->format(DATE_ATOM); + } + if ($value instanceof Cell\DateIntervalCell) { + return $value->getValue()->format('P%yY%mM%dDT%hH%iM%sS%fF'); + } return (string) $value->getValue(); }, $row->getCells()); diff --git a/lib/openspout/src/Writer/Common/ColumnWidth.php b/lib/openspout/src/Writer/Common/ColumnWidth.php index ba7b80205787..c24fbcb8d075 100644 --- a/lib/openspout/src/Writer/Common/ColumnWidth.php +++ b/lib/openspout/src/Writer/Common/ColumnWidth.php @@ -14,9 +14,8 @@ final class ColumnWidth * @param positive-int $end */ public function __construct( - public int $start, - public int $end, - public float $width, - ) { - } + public readonly int $start, + public readonly int $end, + public readonly float $width, + ) {} } diff --git a/lib/openspout/src/Writer/Common/Creator/WriterFactory.php b/lib/openspout/src/Writer/Common/Creator/WriterFactory.php index 530633ecab79..4106a2dfd846 100644 --- a/lib/openspout/src/Writer/Common/Creator/WriterFactory.php +++ b/lib/openspout/src/Writer/Common/Creator/WriterFactory.php @@ -13,6 +13,8 @@ /** * This factory is used to create writers, based on the type of the file to be read. * It supports CSV, XLSX and ODS formats. + * + * @deprecated Guessing mechanisms are brittle by nature and won't be provided by this library anymore */ final class WriterFactory { @@ -21,7 +23,7 @@ final class WriterFactory * * @param string $path The path to the spreadsheet file. Supported extensions are .csv,.ods and .xlsx * - * @throws \OpenSpout\Common\Exception\UnsupportedTypeException + * @throws UnsupportedTypeException */ public static function createFromFile(string $path): WriterInterface { diff --git a/lib/openspout/src/Writer/Common/Entity/Sheet.php b/lib/openspout/src/Writer/Common/Entity/Sheet.php index fb41a722257c..fba9f3051772 100644 --- a/lib/openspout/src/Writer/Common/Entity/Sheet.php +++ b/lib/openspout/src/Writer/Common/Entity/Sheet.php @@ -7,6 +7,7 @@ use OpenSpout\Writer\AutoFilter; use OpenSpout\Writer\Common\ColumnWidth; use OpenSpout\Writer\Common\Manager\SheetManager; +use OpenSpout\Writer\Exception\InvalidSheetNameException; use OpenSpout\Writer\XLSX\Entity\SheetView; /** @@ -17,10 +18,10 @@ final class Sheet public const DEFAULT_SHEET_NAME_PREFIX = 'Sheet'; /** @var 0|positive-int Index of the sheet, based on order in the workbook (zero-based) */ - private int $index; + private readonly int $index; /** @var string ID of the sheet's associated workbook. Used to restrict sheet name uniqueness enforcement to a single workbook */ - private string $associatedWorkbookId; + private readonly string $associatedWorkbookId; /** @var string Name of the sheet */ private string $name; @@ -29,7 +30,7 @@ final class Sheet private bool $isVisible; /** @var SheetManager Sheet manager */ - private SheetManager $sheetManager; + private readonly SheetManager $sheetManager; private ?SheetView $sheetView = null; @@ -41,6 +42,9 @@ final class Sheet /** @var ColumnWidth[] Array of min-max-width arrays */ private array $COLUMN_WIDTHS = []; + /** @var string rows to repeat at top */ + private ?string $printTitleRows = null; + /** * @param 0|positive-int $sheetIndex Index of the sheet, based on order in the workbook (zero-based) * @param string $associatedWorkbookId ID of the sheet's associated workbook @@ -88,7 +92,7 @@ public function getName(): string * * @param string $name Name of the sheet * - * @throws \OpenSpout\Writer\Exception\InvalidSheetNameException if the sheet's name is invalid + * @throws InvalidSheetNameException if the sheet's name is invalid */ public function setName(string $name): self { @@ -205,4 +209,14 @@ public function getColumnWidths(): array { return $this->COLUMN_WIDTHS; } + + public function getPrintTitleRows(): ?string + { + return $this->printTitleRows; + } + + public function setPrintTitleRows(string $printTitleRows): void + { + $this->printTitleRows = $printTitleRows; + } } diff --git a/lib/openspout/src/Writer/Common/Entity/Workbook.php b/lib/openspout/src/Writer/Common/Entity/Workbook.php index e179c513b76b..859508633da8 100644 --- a/lib/openspout/src/Writer/Common/Entity/Workbook.php +++ b/lib/openspout/src/Writer/Common/Entity/Workbook.php @@ -13,7 +13,7 @@ final class Workbook private array $worksheets = []; /** @var string Timestamp based unique ID identifying the workbook */ - private string $internalId; + private readonly string $internalId; /** * Workbook constructor. diff --git a/lib/openspout/src/Writer/Common/Entity/Worksheet.php b/lib/openspout/src/Writer/Common/Entity/Worksheet.php index 6fc6a2f659cb..f1db1cbffe3b 100644 --- a/lib/openspout/src/Writer/Common/Entity/Worksheet.php +++ b/lib/openspout/src/Writer/Common/Entity/Worksheet.php @@ -10,19 +10,19 @@ final class Worksheet { /** @var string Path to the XML file that will contain the sheet data */ - private string $filePath; + private readonly string $filePath; /** @var null|resource Pointer to the sheet data file (e.g. xl/worksheets/sheet1.xml) */ private $filePointer; /** @var Sheet The "external" sheet */ - private Sheet $externalSheet; + private readonly Sheet $externalSheet; /** @var int Maximum number of columns among all the written rows */ - private int $maxNumColumns; + private int $maxNumColumns = 0; /** @var int Index of the last written row */ - private int $lastWrittenRowIndex; + private int $lastWrittenRowIndex = 0; /** * Worksheet constructor. @@ -30,10 +30,7 @@ final class Worksheet public function __construct(string $worksheetFilePath, Sheet $externalSheet) { $this->filePath = $worksheetFilePath; - $this->filePointer = null; $this->externalSheet = $externalSheet; - $this->maxNumColumns = 0; - $this->lastWrittenRowIndex = 0; } public function getFilePath(): string diff --git a/lib/openspout/src/Writer/Common/Helper/FileSystemWithRootFolderHelperInterface.php b/lib/openspout/src/Writer/Common/Helper/FileSystemWithRootFolderHelperInterface.php index afd365b12ccb..0efd02602078 100644 --- a/lib/openspout/src/Writer/Common/Helper/FileSystemWithRootFolderHelperInterface.php +++ b/lib/openspout/src/Writer/Common/Helper/FileSystemWithRootFolderHelperInterface.php @@ -4,6 +4,7 @@ namespace OpenSpout\Writer\Common\Helper; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\FileSystemHelperInterface; /** @@ -14,7 +15,7 @@ interface FileSystemWithRootFolderHelperInterface extends FileSystemHelperInterf /** * Creates all the folders needed to create a spreadsheet, as well as the files that won't change. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the base folders + * @throws IOException If unable to create at least one of the base folders */ public function createBaseFilesAndFolders(): void; diff --git a/lib/openspout/src/Writer/Common/Manager/AbstractWorkbookManager.php b/lib/openspout/src/Writer/Common/Manager/AbstractWorkbookManager.php index 3411b140bb33..dc3fbb1a496b 100644 --- a/lib/openspout/src/Writer/Common/Manager/AbstractWorkbookManager.php +++ b/lib/openspout/src/Writer/Common/Manager/AbstractWorkbookManager.php @@ -5,6 +5,7 @@ namespace OpenSpout\Writer\Common\Manager; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\InvalidArgumentException; use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\StringHelper; use OpenSpout\Writer\Common\AbstractOptions; @@ -32,10 +33,10 @@ abstract class AbstractWorkbookManager implements WorkbookManagerInterface protected AbstractOptions $options; /** @var Workbook The workbook to manage */ - private Workbook $workbook; + private readonly Workbook $workbook; /** @var StyleMerger Helper to merge styles */ - private StyleMerger $styleMerger; + private readonly StyleMerger $styleMerger; /** @var Worksheet The worksheet where data will be written to */ private Worksheet $currentWorksheet; @@ -113,8 +114,8 @@ final public function setCurrentSheet(Sheet $sheet): void * * @param Row $row The row to be added * - * @throws IOException If trying to create a new sheet and unable to open the sheet for writing - * @throws \OpenSpout\Common\Exception\InvalidArgumentException + * @throws IOException If trying to create a new sheet and unable to open the sheet for writing + * @throws InvalidArgumentException */ final public function addRowToCurrentWorksheet(Row $row): void { @@ -190,7 +191,7 @@ private function cleanupTempFolder(): void * * @return Worksheet The created sheet * - * @throws \OpenSpout\Common\Exception\IOException If unable to open the sheet for writing + * @throws IOException If unable to open the sheet for writing */ private function addNewSheet(): Worksheet { @@ -253,7 +254,7 @@ private function hasCurrentWorksheetReachedMaxRows(): bool * @param Row $row The row to be added * * @throws IOException - * @throws \OpenSpout\Common\Exception\InvalidArgumentException + * @throws InvalidArgumentException */ private function addRowToWorksheet(Worksheet $worksheet, Row $row): void { diff --git a/lib/openspout/src/Writer/Common/Manager/RegisteredStyle.php b/lib/openspout/src/Writer/Common/Manager/RegisteredStyle.php index 1144cee528bc..ff7fe3803e06 100644 --- a/lib/openspout/src/Writer/Common/Manager/RegisteredStyle.php +++ b/lib/openspout/src/Writer/Common/Manager/RegisteredStyle.php @@ -13,9 +13,9 @@ */ final class RegisteredStyle { - private Style $style; + private readonly Style $style; - private bool $isMatchingRowStyle; + private readonly bool $isMatchingRowStyle; public function __construct(Style $style, bool $isMatchingRowStyle) { diff --git a/lib/openspout/src/Writer/Common/Manager/SheetManager.php b/lib/openspout/src/Writer/Common/Manager/SheetManager.php index 937093f4cb17..2fe54df60d85 100644 --- a/lib/openspout/src/Writer/Common/Manager/SheetManager.php +++ b/lib/openspout/src/Writer/Common/Manager/SheetManager.php @@ -26,7 +26,7 @@ final class SheetManager /** @var array> Associative array [WORKBOOK_ID] => [[SHEET_INDEX] => [SHEET_NAME]] keeping track of sheets' name to enforce uniqueness per workbook */ private static array $SHEETS_NAME_USED = []; - private StringHelper $stringHelper; + private readonly StringHelper $stringHelper; /** * SheetManager constructor. @@ -43,7 +43,7 @@ public function __construct(StringHelper $stringHelper) * * @param Sheet $sheet The sheet whose future name is checked * - * @throws \OpenSpout\Writer\Exception\InvalidSheetNameException if the sheet's name is invalid + * @throws InvalidSheetNameException if the sheet's name is invalid */ public function throwIfNameIsInvalid(string $name, Sheet $sheet): void { diff --git a/lib/openspout/src/Writer/Common/Manager/Style/PossiblyUpdatedStyle.php b/lib/openspout/src/Writer/Common/Manager/Style/PossiblyUpdatedStyle.php index c147c35aa6d0..ac6ae85851de 100644 --- a/lib/openspout/src/Writer/Common/Manager/Style/PossiblyUpdatedStyle.php +++ b/lib/openspout/src/Writer/Common/Manager/Style/PossiblyUpdatedStyle.php @@ -11,8 +11,8 @@ */ final class PossiblyUpdatedStyle { - private Style $style; - private bool $isUpdated; + private readonly Style $style; + private readonly bool $isUpdated; public function __construct(Style $style, bool $isUpdated) { diff --git a/lib/openspout/src/Writer/Common/Manager/WorksheetManagerInterface.php b/lib/openspout/src/Writer/Common/Manager/WorksheetManagerInterface.php index 3817cbc5a571..897dd9d4efba 100644 --- a/lib/openspout/src/Writer/Common/Manager/WorksheetManagerInterface.php +++ b/lib/openspout/src/Writer/Common/Manager/WorksheetManagerInterface.php @@ -5,6 +5,8 @@ namespace OpenSpout\Writer\Common\Manager; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\InvalidArgumentException; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Writer\Common\Entity\Worksheet; /** @@ -18,8 +20,8 @@ interface WorksheetManagerInterface * @param Worksheet $worksheet The worksheet to add the row to * @param Row $row The row to be added * - * @throws \OpenSpout\Common\Exception\IOException If the data cannot be written - * @throws \OpenSpout\Common\Exception\InvalidArgumentException If a cell value's type is not supported + * @throws IOException If the data cannot be written + * @throws InvalidArgumentException If a cell value's type is not supported */ public function addRow(Worksheet $worksheet, Row $row): void; @@ -28,7 +30,7 @@ public function addRow(Worksheet $worksheet, Row $row): void; * * @param Worksheet $worksheet The worksheet to start * - * @throws \OpenSpout\Common\Exception\IOException If the sheet data file cannot be opened for writing + * @throws IOException If the sheet data file cannot be opened for writing */ public function startSheet(Worksheet $worksheet): void; diff --git a/lib/openspout/src/Writer/Exception/InvalidSheetNameException.php b/lib/openspout/src/Writer/Exception/InvalidSheetNameException.php index a01add1ebdf5..ed9cdd93c605 100644 --- a/lib/openspout/src/Writer/Exception/InvalidSheetNameException.php +++ b/lib/openspout/src/Writer/Exception/InvalidSheetNameException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Writer\Exception; -final class InvalidSheetNameException extends WriterException -{ -} +final class InvalidSheetNameException extends WriterException {} diff --git a/lib/openspout/src/Writer/Exception/SheetNotFoundException.php b/lib/openspout/src/Writer/Exception/SheetNotFoundException.php index 25622c13835a..9689ab0a1408 100644 --- a/lib/openspout/src/Writer/Exception/SheetNotFoundException.php +++ b/lib/openspout/src/Writer/Exception/SheetNotFoundException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Writer\Exception; -final class SheetNotFoundException extends WriterException -{ -} +final class SheetNotFoundException extends WriterException {} diff --git a/lib/openspout/src/Writer/Exception/WriterAlreadyOpenedException.php b/lib/openspout/src/Writer/Exception/WriterAlreadyOpenedException.php index b91b3e8f4718..026a59eda0bf 100644 --- a/lib/openspout/src/Writer/Exception/WriterAlreadyOpenedException.php +++ b/lib/openspout/src/Writer/Exception/WriterAlreadyOpenedException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Writer\Exception; -final class WriterAlreadyOpenedException extends WriterException -{ -} +final class WriterAlreadyOpenedException extends WriterException {} diff --git a/lib/openspout/src/Writer/Exception/WriterException.php b/lib/openspout/src/Writer/Exception/WriterException.php index 270cbb712e93..91faa27b9b74 100644 --- a/lib/openspout/src/Writer/Exception/WriterException.php +++ b/lib/openspout/src/Writer/Exception/WriterException.php @@ -6,6 +6,4 @@ use OpenSpout\Common\Exception\OpenSpoutException; -abstract class WriterException extends OpenSpoutException -{ -} +abstract class WriterException extends OpenSpoutException {} diff --git a/lib/openspout/src/Writer/Exception/WriterNotOpenedException.php b/lib/openspout/src/Writer/Exception/WriterNotOpenedException.php index 39b06fd39999..49b8db870832 100644 --- a/lib/openspout/src/Writer/Exception/WriterNotOpenedException.php +++ b/lib/openspout/src/Writer/Exception/WriterNotOpenedException.php @@ -4,6 +4,4 @@ namespace OpenSpout\Writer\Exception; -final class WriterNotOpenedException extends WriterException -{ -} +final class WriterNotOpenedException extends WriterException {} diff --git a/lib/openspout/src/Writer/ODS/Helper/FileSystemHelper.php b/lib/openspout/src/Writer/ODS/Helper/FileSystemHelper.php index a2545eae061a..df9c0e3929aa 100644 --- a/lib/openspout/src/Writer/ODS/Helper/FileSystemHelper.php +++ b/lib/openspout/src/Writer/ODS/Helper/FileSystemHelper.php @@ -5,6 +5,7 @@ namespace OpenSpout\Writer\ODS\Helper; use DateTimeImmutable; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\FileSystemHelper as CommonFileSystemHelper; use OpenSpout\Writer\Common\Entity\Worksheet; use OpenSpout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface; @@ -27,11 +28,11 @@ final class FileSystemHelper implements FileSystemWithRootFolderHelperInterface public const MIMETYPE_FILE_NAME = 'mimetype'; public const STYLES_XML_FILE_NAME = 'styles.xml'; - private string $baseFolderRealPath; + private readonly string $baseFolderRealPath; /** @var string document creator */ - private string $creator; - private CommonFileSystemHelper $baseFileSystemHelper; + private readonly string $creator; + private readonly CommonFileSystemHelper $baseFileSystemHelper; /** @var string Path to the root folder inside the temp folder where the files to create the ODS will be stored */ private string $rootFolder; @@ -43,7 +44,7 @@ final class FileSystemHelper implements FileSystemWithRootFolderHelperInterface private string $sheetsContentTempFolder; /** @var ZipHelper Helper to perform tasks with Zip archive */ - private ZipHelper $zipHelper; + private readonly ZipHelper $zipHelper; /** * @param string $baseFolderPath The path of the base folder where all the I/O can occur @@ -91,7 +92,7 @@ public function getSheetsContentTempFolder(): string /** * Creates all the folders needed to create a ODS file, as well as the files that won't change. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the base folders + * @throws IOException If unable to create at least one of the base folders */ public function createBaseFilesAndFolders(): void { @@ -214,7 +215,7 @@ public function zipRootFolderAndCopyToStream($streamPointer): void /** * Creates the folder that will be used as root. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createRootFolder(): self { @@ -226,7 +227,7 @@ private function createRootFolder(): self /** * Creates the "META-INF" folder under the root folder as well as the "manifest.xml" file in it. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or the "manifest.xml" file + * @throws IOException If unable to create the folder or the "manifest.xml" file */ private function createMetaInfoFolderAndFile(): self { @@ -240,7 +241,7 @@ private function createMetaInfoFolderAndFile(): self /** * Creates the "manifest.xml" file under the "META-INF" folder (under root). * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createManifestFile(): self { @@ -263,7 +264,7 @@ private function createManifestFile(): self * Creates the temp folder where specific sheets content will be written to. * This folder is not part of the final ODS file and is only used to be able to jump between sheets. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createSheetsContentTempFolder(): self { @@ -275,7 +276,7 @@ private function createSheetsContentTempFolder(): self /** * Creates the "meta.xml" file under the root folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createMetaFile(): self { @@ -300,7 +301,7 @@ private function createMetaFile(): self /** * Creates the "mimetype" file under the root folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createMimetypeFile(): self { diff --git a/lib/openspout/src/Writer/ODS/Manager/Style/StyleManager.php b/lib/openspout/src/Writer/ODS/Manager/Style/StyleManager.php index 967d33dea72e..ca516d6ea955 100644 --- a/lib/openspout/src/Writer/ODS/Manager/Style/StyleManager.php +++ b/lib/openspout/src/Writer/ODS/Manager/Style/StyleManager.php @@ -22,7 +22,7 @@ */ final class StyleManager extends CommonStyleManager { - private AbstractOptions $options; + private readonly AbstractOptions $options; public function __construct(StyleRegistry $styleRegistry, AbstractOptions $options) { diff --git a/lib/openspout/src/Writer/ODS/Manager/WorksheetManager.php b/lib/openspout/src/Writer/ODS/Manager/WorksheetManager.php index c77f72f43bf4..0c548fd21f4e 100644 --- a/lib/openspout/src/Writer/ODS/Manager/WorksheetManager.php +++ b/lib/openspout/src/Writer/ODS/Manager/WorksheetManager.php @@ -25,13 +25,13 @@ final class WorksheetManager implements WorksheetManagerInterface { /** @var ODSEscaper Strings escaper */ - private ODSEscaper $stringsEscaper; + private readonly ODSEscaper $stringsEscaper; /** @var StyleManager Manages styles */ - private StyleManager $styleManager; + private readonly StyleManager $styleManager; /** @var StyleMerger Helper to merge styles together */ - private StyleMerger $styleMerger; + private readonly StyleMerger $styleMerger; /** * WorksheetManager constructor. @@ -51,7 +51,7 @@ public function __construct( * * @param Worksheet $worksheet The worksheet to start * - * @throws \OpenSpout\Common\Exception\IOException If the sheet data file cannot be opened for writing + * @throws IOException If the sheet data file cannot be opened for writing */ public function startSheet(Worksheet $worksheet): void { diff --git a/lib/openspout/src/Writer/ODS/Options.php b/lib/openspout/src/Writer/ODS/Options.php index 547ee2da8056..ab26415dc2df 100644 --- a/lib/openspout/src/Writer/ODS/Options.php +++ b/lib/openspout/src/Writer/ODS/Options.php @@ -6,6 +6,4 @@ use OpenSpout\Writer\Common\AbstractOptions; -final class Options extends AbstractOptions -{ -} +final class Options extends AbstractOptions {} diff --git a/lib/openspout/src/Writer/ODS/Writer.php b/lib/openspout/src/Writer/ODS/Writer.php index 665e186bc5e8..fbbb56c07b8e 100644 --- a/lib/openspout/src/Writer/ODS/Writer.php +++ b/lib/openspout/src/Writer/ODS/Writer.php @@ -19,7 +19,7 @@ final class Writer extends AbstractWriterMultiSheets { /** @var string Content-Type value for the header */ protected static string $headerContentType = 'application/vnd.oasis.opendocument.spreadsheet'; - private Options $options; + private readonly Options $options; public function __construct(?Options $options = null) { diff --git a/lib/openspout/src/Writer/WriterInterface.php b/lib/openspout/src/Writer/WriterInterface.php index c294d6d16fc9..272eba96143d 100644 --- a/lib/openspout/src/Writer/WriterInterface.php +++ b/lib/openspout/src/Writer/WriterInterface.php @@ -5,6 +5,8 @@ namespace OpenSpout\Writer; use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Exception\InvalidArgumentException; +use OpenSpout\Common\Exception\IOException; interface WriterInterface { @@ -14,7 +16,7 @@ interface WriterInterface * * @param string $outputFilePath Path of the output file that will contain the data * - * @throws \OpenSpout\Common\Exception\IOException If the writer cannot be opened or if the given path is not writable + * @throws IOException If the writer cannot be opened or if the given path is not writable */ public function openToFile(string $outputFilePath): void; @@ -24,7 +26,7 @@ public function openToFile(string $outputFilePath): void; * * @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept * - * @throws \OpenSpout\Common\Exception\IOException If the writer cannot be opened + * @throws IOException If the writer cannot be opened */ public function openToBrowser(string $outputFileName): void; @@ -33,8 +35,8 @@ public function openToBrowser(string $outputFileName): void; * * @param Row $row The row to be appended to the stream * - * @throws \OpenSpout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yet - * @throws \OpenSpout\Common\Exception\IOException If unable to write data + * @throws Exception\WriterNotOpenedException If the writer has not been opened yet + * @throws IOException If unable to write data */ public function addRow(Row $row): void; @@ -43,9 +45,9 @@ public function addRow(Row $row): void; * * @param Row[] $rows The rows to be appended to the stream * - * @throws \OpenSpout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \OpenSpout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yet - * @throws \OpenSpout\Common\Exception\IOException If unable to write data + * @throws InvalidArgumentException If the input param is not valid + * @throws Exception\WriterNotOpenedException If the writer has not been opened yet + * @throws IOException If unable to write data */ public function addRows(array $rows): void; diff --git a/lib/openspout/src/Writer/XLSX/Entity/SheetView.php b/lib/openspout/src/Writer/XLSX/Entity/SheetView.php index 4cbd400006b0..e4f89a9a424f 100644 --- a/lib/openspout/src/Writer/XLSX/Entity/SheetView.php +++ b/lib/openspout/src/Writer/XLSX/Entity/SheetView.php @@ -256,7 +256,7 @@ private function getFreezeCellPaneXml(): string private function generateAttributes(array $data): string { // Create attribute for each key - $attributes = array_map(static function (string $key, bool|string|int $value): string { + $attributes = array_map(static function (string $key, bool|int|string $value): string { if (\is_bool($value)) { $value = $value ? 'true' : 'false'; } diff --git a/lib/openspout/src/Writer/XLSX/Helper/DateIntervalHelper.php b/lib/openspout/src/Writer/XLSX/Helper/DateIntervalHelper.php new file mode 100644 index 000000000000..5fc5017aa8a1 --- /dev/null +++ b/lib/openspout/src/Writer/XLSX/Helper/DateIntervalHelper.php @@ -0,0 +1,41 @@ +y * 365.25 + + $interval->m * 30.437 + + $interval->d + + $interval->h / 24 + + $interval->i / 24 / 60 + + $interval->s / 24 / 60 / 60; + + if (1 === $interval->invert) { + $days *= -1; + } + + return $days; + } +} diff --git a/lib/openspout/src/Writer/XLSX/Helper/FileSystemHelper.php b/lib/openspout/src/Writer/XLSX/Helper/FileSystemHelper.php index ba1293f96c1c..b39bdb6e71ea 100644 --- a/lib/openspout/src/Writer/XLSX/Helper/FileSystemHelper.php +++ b/lib/openspout/src/Writer/XLSX/Helper/FileSystemHelper.php @@ -5,6 +5,7 @@ namespace OpenSpout\Writer\XLSX\Helper; use DateTimeImmutable; +use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\Escaper\XLSX; use OpenSpout\Common\Helper\FileSystemHelper as CommonFileSystemHelper; use OpenSpout\Writer\Common\Entity\Sheet; @@ -40,17 +41,17 @@ final class FileSystemHelper implements FileSystemWithRootFolderHelperInterface EOD; - private string $baseFolderRealPath; - private CommonFileSystemHelper $baseFileSystemHelper; + private readonly string $baseFolderRealPath; + private readonly CommonFileSystemHelper $baseFileSystemHelper; /** @var ZipHelper Helper to perform tasks with Zip archive */ - private ZipHelper $zipHelper; + private readonly ZipHelper $zipHelper; /** @var string document creator */ - private string $creator; + private readonly string $creator; /** @var XLSX Used to escape XML data */ - private XLSX $escaper; + private readonly XLSX $escaper; /** @var string Path to the root folder inside the temp folder where the files to create the XLSX will be stored */ private string $rootFolder; @@ -131,7 +132,7 @@ public function getSheetsContentTempFolder(): string /** * Creates all the folders needed to create a XLSX file, as well as the files that won't change. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the base folders + * @throws IOException If unable to create at least one of the base folders */ public function createBaseFilesAndFolders(): void { @@ -221,6 +222,9 @@ public function createWorkbookFile(array $worksheets): self ); $definedNames .= ''; } + if (null !== $printTitleRows = $sheet->getPrintTitleRows()) { + $definedNames .= ''.$this->escaper->escape($sheet->getName()).'!'.$printTitleRows.''; + } } if ('' !== $definedNames) { $workbookXmlFileContents .= ''.$definedNames.''; @@ -307,7 +311,7 @@ public function createStylesFile(StyleManager $styleManager): self public function createContentFiles(Options $options, array $worksheets): self { $allMergeCells = $options->getMergeCells(); - + $pageSetup = $options->getPageSetup(); foreach ($worksheets as $worksheet) { $contentXmlFilePath = $this->getXlWorksheetsFolder().\DIRECTORY_SEPARATOR.basename($worksheet->getFilePath()); $worksheetFilePointer = fopen($contentXmlFilePath, 'w'); @@ -326,10 +330,15 @@ public function createContentFiles(Options $options, array $worksheets): self CellHelper::getColumnLettersFromColumnIndex($autofilter->toColumnIndex), $autofilter->toRow ); - fwrite($worksheetFilePointer, ''); + if (isset($pageSetup) && $pageSetup->fitToPage) { + fwrite($worksheetFilePointer, ''); + } else { + fwrite($worksheetFilePointer, ''); + } fwrite($worksheetFilePointer, sprintf('', $range)); + } elseif (isset($pageSetup) && $pageSetup->fitToPage) { + fwrite($worksheetFilePointer, ''); } - if (null !== ($sheetView = $sheet->getSheetView())) { fwrite($worksheetFilePointer, ''.$sheetView->getXml().''); } @@ -366,6 +375,12 @@ public function createContentFiles(Options $options, array $worksheets): self fwrite($worksheetFilePointer, $mergeCellString); } + $this->getXMLFragmentForPageMargin($worksheetFilePointer, $options); + + $this->getXMLFragmentForPageSetup($worksheetFilePointer, $options); + + $this->getXMLFragmentForHeaderFooter($worksheetFilePointer, $options); + // Add the legacy drawing for comments fwrite($worksheetFilePointer, ''); @@ -411,6 +426,93 @@ public function zipRootFolderAndCopyToStream($streamPointer): void $this->deleteFile($zipFilePath); } + /** + * @param resource $targetResource + */ + private function getXMLFragmentForPageMargin($targetResource, Options $options): void + { + $pageMargin = $options->getPageMargin(); + if (null === $pageMargin) { + return; + } + + fwrite($targetResource, "top}\" right=\"{$pageMargin->right}\" bottom=\"{$pageMargin->bottom}\" left=\"{$pageMargin->left}\" header=\"{$pageMargin->header}\" footer=\"{$pageMargin->footer}\"/>"); + } + + /** + * @param resource $targetResource + */ + private function getXMLFragmentForHeaderFooter($targetResource, Options $options): void + { + $headerFooter = $options->getHeaderFooter(); + if (null === $headerFooter) { + return; + } + + $xml = 'differentOddEven) { + $xml .= " differentOddEven=\"{$headerFooter->differentOddEven}\""; + } + + $xml .= '>'; + + if (null !== $headerFooter->oddHeader) { + $xml .= "{$headerFooter->oddHeader}"; + } + + if (null !== $headerFooter->oddFooter) { + $xml .= "{$headerFooter->oddFooter}"; + } + + if ($headerFooter->differentOddEven) { + if (null !== $headerFooter->evenHeader) { + $xml .= "{$headerFooter->evenHeader}"; + } + + if (null !== $headerFooter->evenFooter) { + $xml .= "{$headerFooter->evenFooter}"; + } + } + + $xml .= ''; + + fwrite($targetResource, $xml); + } + + /** + * @param resource $targetResource + */ + private function getXMLFragmentForPageSetup($targetResource, Options $options): void + { + $pageSetup = $options->getPageSetup(); + if (null === $pageSetup) { + return; + } + + $xml = 'pageOrientation) { + $xml .= " orientation=\"{$pageSetup->pageOrientation->value}\""; + } + + if (null !== $pageSetup->paperSize) { + $xml .= " paperSize=\"{$pageSetup->paperSize->value}\""; + } + + if (null !== $pageSetup->fitToHeight) { + $xml .= " fitToHeight=\"{$pageSetup->fitToHeight}\""; + } + + if (null !== $pageSetup->fitToWidth) { + $xml .= " fitToWidth=\"{$pageSetup->fitToWidth}\""; + } + + $xml .= '/>'; + + fwrite($targetResource, $xml); + } + /** * Construct column width references xml to inject into worksheet xml file. */ @@ -453,7 +555,7 @@ private function getXMLFragmentForDefaultCellSizing(Options $options): string /** * Creates the folder that will be used as root. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createRootFolder(): self { @@ -465,7 +567,7 @@ private function createRootFolder(): self /** * Creates the "_rels" folder under the root folder as well as the ".rels" file in it. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or the ".rels" file + * @throws IOException If unable to create the folder or the ".rels" file */ private function createRelsFolderAndFile(): self { @@ -479,7 +581,7 @@ private function createRelsFolderAndFile(): self /** * Creates the ".rels" file under the "_rels" folder (under root). * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createRelsFile(): self { @@ -500,7 +602,7 @@ private function createRelsFile(): self /** * Creates the "docProps" folder under the root folder as well as the "app.xml" and "core.xml" files in it. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or one of the files + * @throws IOException If unable to create the folder or one of the files */ private function createDocPropsFolderAndFiles(): self { @@ -515,7 +617,7 @@ private function createDocPropsFolderAndFiles(): self /** * Creates the "app.xml" file under the "docProps" folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createAppXmlFile(): self { @@ -535,7 +637,7 @@ private function createAppXmlFile(): self /** * Creates the "core.xml" file under the "docProps" folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the file + * @throws IOException If unable to create the file */ private function createCoreXmlFile(): self { @@ -557,7 +659,7 @@ private function createCoreXmlFile(): self /** * Creates the "xl" folder under the root folder as well as its subfolders. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the folders + * @throws IOException If unable to create at least one of the folders */ private function createXlFolderAndSubFolders(): self { @@ -573,7 +675,7 @@ private function createXlFolderAndSubFolders(): self * Creates the temp folder where specific sheets content will be written to. * This folder is not part of the final ODS file and is only used to be able to jump between sheets. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createSheetsContentTempFolder(): self { @@ -585,7 +687,7 @@ private function createSheetsContentTempFolder(): self /** * Creates the "_rels" folder under the "xl" folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createXlRelsFolder(): self { @@ -597,7 +699,7 @@ private function createXlRelsFolder(): self /** * Creates the "drawings" folder under the "xl" folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createDrawingsFolder(): self { @@ -609,7 +711,7 @@ private function createDrawingsFolder(): self /** * Creates the "worksheets" folder under the "xl" folder. * - * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder + * @throws IOException If unable to create the folder */ private function createXlWorksheetsFolder(): self { diff --git a/lib/openspout/src/Writer/XLSX/Manager/CommentsManager.php b/lib/openspout/src/Writer/XLSX/Manager/CommentsManager.php index 525289c37827..b86c1a4744a6 100644 --- a/lib/openspout/src/Writer/XLSX/Manager/CommentsManager.php +++ b/lib/openspout/src/Writer/XLSX/Manager/CommentsManager.php @@ -64,11 +64,11 @@ final class CommentsManager */ private array $drawingFilePointers = []; - private string $xlFolder; + private readonly string $xlFolder; private int $shapeId = 1024; - private Escaper\XLSX $stringsEscaper; + private readonly Escaper\XLSX $stringsEscaper; /** * @param string $xlFolder Path to the "xl" folder diff --git a/lib/openspout/src/Writer/XLSX/Manager/SharedStringsManager.php b/lib/openspout/src/Writer/XLSX/Manager/SharedStringsManager.php index 3b232c7b614e..8f472ebbdcb9 100644 --- a/lib/openspout/src/Writer/XLSX/Manager/SharedStringsManager.php +++ b/lib/openspout/src/Writer/XLSX/Manager/SharedStringsManager.php @@ -31,7 +31,7 @@ final class SharedStringsManager private int $numSharedStrings = 0; /** @var Escaper\XLSX Strings escaper */ - private Escaper\XLSX $stringsEscaper; + private readonly Escaper\XLSX $stringsEscaper; /** * @param string $xlFolder Path to the "xl" folder diff --git a/lib/openspout/src/Writer/XLSX/Manager/WorksheetManager.php b/lib/openspout/src/Writer/XLSX/Manager/WorksheetManager.php index 2c43d638d550..94ca09c87e92 100644 --- a/lib/openspout/src/Writer/XLSX/Manager/WorksheetManager.php +++ b/lib/openspout/src/Writer/XLSX/Manager/WorksheetManager.php @@ -17,6 +17,7 @@ use OpenSpout\Writer\Common\Manager\Style\StyleMerger; use OpenSpout\Writer\Common\Manager\WorksheetManagerInterface; use OpenSpout\Writer\XLSX\Helper\DateHelper; +use OpenSpout\Writer\XLSX\Helper\DateIntervalHelper; use OpenSpout\Writer\XLSX\Manager\Style\StyleManager; use OpenSpout\Writer\XLSX\Options; @@ -35,24 +36,24 @@ final class WorksheetManager implements WorksheetManagerInterface public const MAX_CHARACTERS_PER_CELL = 32767; /** @var CommentsManager Manages comments */ - private CommentsManager $commentsManager; + private readonly CommentsManager $commentsManager; - private Options $options; + private readonly Options $options; /** @var StyleManager Manages styles */ - private StyleManager $styleManager; + private readonly StyleManager $styleManager; /** @var StyleMerger Helper to merge styles together */ - private StyleMerger $styleMerger; + private readonly StyleMerger $styleMerger; /** @var SharedStringsManager Helper to write shared strings */ - private SharedStringsManager $sharedStringsManager; + private readonly SharedStringsManager $sharedStringsManager; /** @var XLSXEscaper Strings escaper */ - private XLSXEscaper $stringsEscaper; + private readonly XLSXEscaper $stringsEscaper; /** @var StringHelper String helper */ - private StringHelper $stringHelper; + private readonly StringHelper $stringHelper; /** * WorksheetManager constructor. @@ -200,6 +201,8 @@ private function getCellXML(int $rowIndexOneBased, int $columnIndexZeroBased, Ce $cellXML .= '>'.substr($cell->getValue(), 1).''; } elseif ($cell instanceof Cell\DateTimeCell) { $cellXML .= '>'.DateHelper::toExcel($cell->getValue()).''; + } elseif ($cell instanceof Cell\DateIntervalCell) { + $cellXML .= '>'.DateIntervalHelper::toExcel($cell->getValue()).''; } elseif ($cell instanceof Cell\ErrorCell) { // only writes the error value if it's a string $cellXML .= ' t="e">'.$cell->getRawValue().''; diff --git a/lib/openspout/src/Writer/XLSX/MergeCell.php b/lib/openspout/src/Writer/XLSX/MergeCell.php index 3d342df529fa..02e23438bc75 100644 --- a/lib/openspout/src/Writer/XLSX/MergeCell.php +++ b/lib/openspout/src/Writer/XLSX/MergeCell.php @@ -17,11 +17,10 @@ final class MergeCell * @param positive-int $bottomRightRow */ public function __construct( - public int $sheetIndex, - public int $topLeftColumn, - public int $topLeftRow, - public int $bottomRightColumn, - public int $bottomRightRow, - ) { - } + public readonly int $sheetIndex, + public readonly int $topLeftColumn, + public readonly int $topLeftRow, + public readonly int $bottomRightColumn, + public readonly int $bottomRightRow, + ) {} } diff --git a/lib/openspout/src/Writer/XLSX/Options.php b/lib/openspout/src/Writer/XLSX/Options.php index 6bfd2f44419c..7f27a02b6bfc 100644 --- a/lib/openspout/src/Writer/XLSX/Options.php +++ b/lib/openspout/src/Writer/XLSX/Options.php @@ -6,6 +6,9 @@ use OpenSpout\Common\Entity\Style\Style; use OpenSpout\Writer\Common\AbstractOptions; +use OpenSpout\Writer\XLSX\Options\HeaderFooter; +use OpenSpout\Writer\XLSX\Options\PageMargin; +use OpenSpout\Writer\XLSX\Options\PageSetup; final class Options extends AbstractOptions { @@ -17,6 +20,12 @@ final class Options extends AbstractOptions /** @var MergeCell[] */ private array $MERGE_CELLS = []; + private ?PageMargin $pageMargin = null; + + private ?PageSetup $pageSetup = null; + + private ?HeaderFooter $headerFooter = null; + public function __construct() { parent::__construct(); @@ -63,4 +72,34 @@ public function getMergeCells(): array { return $this->MERGE_CELLS; } + + public function setPageMargin(PageMargin $pageMargin): void + { + $this->pageMargin = $pageMargin; + } + + public function getPageMargin(): ?PageMargin + { + return $this->pageMargin; + } + + public function setPageSetup(PageSetup $pageSetup): void + { + $this->pageSetup = $pageSetup; + } + + public function getPageSetup(): ?PageSetup + { + return $this->pageSetup; + } + + public function setHeaderFooter(HeaderFooter $headerFooter): void + { + $this->headerFooter = $headerFooter; + } + + public function getHeaderFooter(): ?HeaderFooter + { + return $this->headerFooter; + } } diff --git a/lib/openspout/src/Writer/XLSX/Options/HeaderFooter.php b/lib/openspout/src/Writer/XLSX/Options/HeaderFooter.php new file mode 100644 index 000000000000..cda9dde390b3 --- /dev/null +++ b/lib/openspout/src/Writer/XLSX/Options/HeaderFooter.php @@ -0,0 +1,16 @@ +fitToPage = null !== $fitToHeight || null !== $fitToWidth; + } +} diff --git a/lib/openspout/src/Writer/XLSX/Options/PaperSize.php b/lib/openspout/src/Writer/XLSX/Options/PaperSize.php new file mode 100644 index 000000000000..2eb24910665b --- /dev/null +++ b/lib/openspout/src/Writer/XLSX/Options/PaperSize.php @@ -0,0 +1,34 @@ +page->blocks->ensure_content_created($region, $this); } - $output = ''; - // Give plugins an opportunity to add any head elements. The callback // must always return a string containing valid html head content. - $hook = new \core\hook\output\standard_head_html_prepend(); - \core\hook\manager::get_instance()->dispatch($hook); + $hook = new \core\hook\output\before_standard_head_html_generation($this); + di::get(hook_manager::class)->dispatch($hook); $hook->process_legacy_callbacks(); - $output .= $hook->get_output(); // Allow a url_rewrite plugin to setup any dynamic head content. if (isset($CFG->urlrewriteclass) && !isset($CFG->upgraderunning)) { $class = $CFG->urlrewriteclass; - $output .= $class::html_head_setup(); + $hook->add_html($class::html_head_setup()); } - $output .= '' . "\n"; - $output .= '' . "\n"; + $hook->add_html('' . "\n"); + $hook->add_html('' . "\n"); // This is only set by the {@link redirect()} method - $output .= $this->metarefreshtag; + $hook->add_html($this->metarefreshtag); // Check if a periodic refresh delay has been set and make sure we arn't // already meta refreshing if ($this->metarefreshtag=='' && $this->page->periodicrefreshdelay!==null) { - $output .= ''; + $hook->add_html( + html_writer::empty_tag('meta', [ + 'http-equiv' => 'refresh', + 'content' => $this->page->periodicrefreshdelay . ';url='.$this->page->url->out(), + ]), + ); } + $output = $hook->get_output(); + // Set up help link popups for all links with the helptooltip class $this->page->requires->js_init_call('M.util.help_popups.setup'); diff --git a/lib/phpmailer/README.md b/lib/phpmailer/README.md index 53e66f11498f..e3e4ecff3db5 100644 --- a/lib/phpmailer/README.md +++ b/lib/phpmailer/README.md @@ -47,7 +47,7 @@ This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lg PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: ```json -"phpmailer/phpmailer": "^6.8.0" +"phpmailer/phpmailer": "^6.9.1" ``` or run @@ -58,7 +58,8 @@ composer require phpmailer/phpmailer Note that the `vendor` folder and the `vendor/autoload.php` script are generated by Composer; they are not part of PHPMailer. -If you want to use the Gmail XOAUTH2 authentication class, you will also need to add a dependency on the `league/oauth2-client` package in your `composer.json`. +If you want to use XOAUTH2 authentication, you will also need to add a dependency on the `league/oauth2-client` and appropriate service adapters package in your `composer.json`, or take a look at +by @decomplexity's [SendOauth2 wrapper](https://github.com/decomplexity/SendOauth2), especially if you're using Microsoft services. Alternatively, if you're not using Composer, you can [download PHPMailer as a zip file](https://github.com/PHPMailer/PHPMailer/archive/master.zip), (note that docs and examples are not included in the zip file), then copy the contents of the PHPMailer folder into one of the `include_path` directories specified in your PHP configuration and load each class file manually: @@ -150,7 +151,7 @@ PHPMailer defaults to English, but in the [language](https://github.com/PHPMaile $mail->setLanguage('fr', '/optional/path/to/language/directory/'); ``` -We welcome corrections and new languages – if you're looking for corrections, run the [PHPMailerLangTest.php](https://github.com/PHPMailer/PHPMailer/tree/master/test/PHPMailerLangTest.php) script in the tests folder and it will show any missing translations. +We welcome corrections and new languages – if you're looking for corrections, run the [Language/TranslationCompletenessTest.php](https://github.com/PHPMailer/PHPMailer/blob/master/test/Language/TranslationCompletenessTest.php) script in the tests folder and it will show any missing translations. ## Documentation Start reading at the [GitHub wiki](https://github.com/PHPMailer/PHPMailer/wiki). If you're having trouble, head for [the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting) as it's frequently updated. diff --git a/lib/phpmailer/VERSION b/lib/phpmailer/VERSION index 8a1c5c7e99c1..dc3829f5e077 100644 --- a/lib/phpmailer/VERSION +++ b/lib/phpmailer/VERSION @@ -1 +1 @@ -6.8.0 \ No newline at end of file +6.9.1 diff --git a/lib/phpmailer/language/phpmailer.lang-as.php b/lib/phpmailer/language/phpmailer.lang-as.php new file mode 100644 index 000000000000..327dfbafaf25 --- /dev/null +++ b/lib/phpmailer/language/phpmailer.lang-as.php @@ -0,0 +1,35 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP ত্ৰুটি: প্ৰমাণীকৰণ কৰিব নোৱাৰি'; +$PHPMAILER_LANG['buggy_php'] = 'আপোনাৰ PHP সংস্কৰণ এটা বাগৰ দ্বাৰা প্ৰভাৱিত হয় যাৰ ফলত নষ্ট বাৰ্তা হব পাৰে । ইয়াক সমাধান কৰিবলে, প্ৰেৰণ কৰিবলে SMTP ব্যৱহাৰ কৰক, আপোনাৰ php.ini ত mail.add_x_header বিকল্প নিষ্ক্ৰিয় কৰক, MacOS বা Linux লৈ সলনি কৰক, বা আপোনাৰ PHP সংস্কৰণ 7.0.17+ বা 7.1.3+ লৈ সলনি কৰক ।'; +$PHPMAILER_LANG['connect_host'] = 'SMTP ত্ৰুটি: SMTP চাৰ্ভাৰৰ সৈতে সংযোগ কৰিবলে অক্ষম'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP ত্ৰুটি: তথ্য গ্ৰহণ কৰা হোৱা নাই'; +$PHPMAILER_LANG['empty_message'] = 'বাৰ্তাৰ মূখ্য অংশ খালী।'; +$PHPMAILER_LANG['encoding'] = 'অজ্ঞাত এনকোডিং: '; +$PHPMAILER_LANG['execute'] = 'এক্সিকিউট কৰিব নোৱাৰি: '; +$PHPMAILER_LANG['extension_missing'] = 'সম্প্ৰসাৰণ নোহোৱা হৈছে: '; +$PHPMAILER_LANG['file_access'] = 'ফাইল অভিগম কৰিবলে অক্ষম: '; +$PHPMAILER_LANG['file_open'] = 'ফাইল ত্ৰুটি: ফাইল খোলিবলৈ অক্ষম: '; +$PHPMAILER_LANG['from_failed'] = 'নিম্নলিখিত প্ৰেৰকৰ ঠিকনা(সমূহ) ব্যৰ্থ: '; +$PHPMAILER_LANG['instantiate'] = 'মেইল ফাংচনৰ এটা উদাহৰণ সৃষ্টি কৰিবলে অক্ষম'; +$PHPMAILER_LANG['invalid_address'] = 'প্ৰেৰণ কৰিব নোৱাৰি: অবৈধ ইমেইল ঠিকনা: '; +$PHPMAILER_LANG['invalid_header'] = 'অবৈধ হেডাৰৰ নাম বা মান'; +$PHPMAILER_LANG['invalid_hostentry'] = 'অবৈধ হোষ্টেন্ট্ৰি: '; +$PHPMAILER_LANG['invalid_host'] = 'অবৈধ হস্ট:'; +$PHPMAILER_LANG['mailer_not_supported'] = 'মেইলাৰ সমৰ্থিত নহয়।'; +$PHPMAILER_LANG['provide_address'] = 'আপুনি অন্ততঃ এটা গন্তব্য ইমেইল ঠিকনা দিব লাগিব'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP ত্ৰুটি: নিম্নলিখিত গন্তব্যস্থানসমূহ ব্যৰ্থ: '; +$PHPMAILER_LANG['signing'] = 'স্বাক্ষৰ কৰাত ব্যৰ্থ: '; +$PHPMAILER_LANG['smtp_code'] = 'SMTP কড: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'অতিৰিক্ত SMTP তথ্য: '; +$PHPMAILER_LANG['smtp_detail'] = 'বিৱৰণ:'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP সংযোগ() ব্যৰ্থ'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP চাৰ্ভাৰৰ ত্ৰুটি: '; +$PHPMAILER_LANG['variable_set'] = 'চলক নিৰ্ধাৰণ কৰিব পৰা নগল: '; +$PHPMAILER_LANG['extension_missing'] = 'অনুপস্থিত সম্প্ৰসাৰণ: '; diff --git a/lib/phpmailer/language/phpmailer.lang-bn.php b/lib/phpmailer/language/phpmailer.lang-bn.php new file mode 100644 index 000000000000..473651080410 --- /dev/null +++ b/lib/phpmailer/language/phpmailer.lang-bn.php @@ -0,0 +1,35 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP ত্রুটি: প্রমাণীকরণ করতে অক্ষম৷'; +$PHPMAILER_LANG['buggy_php'] = 'আপনার PHP সংস্করণ একটি বাগ দ্বারা প্রভাবিত হয় যার ফলে দূষিত বার্তা হতে পারে। এটি ঠিক করতে, পাঠাতে SMTP ব্যবহার করুন, আপনার php.ini এ mail.add_x_header বিকল্পটি নিষ্ক্রিয় করুন, MacOS বা Linux-এ স্যুইচ করুন, অথবা আপনার PHP সংস্করণকে 7.0.17+ বা 7.1.3+ এ পরিবর্তন করুন।'; +$PHPMAILER_LANG['connect_host'] = 'SMTP ত্রুটি: SMTP সার্ভারের সাথে সংযোগ করতে অক্ষম৷'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP ত্রুটি: ডেটা গ্রহণ করা হয়নি৷'; +$PHPMAILER_LANG['empty_message'] = 'বার্তার অংশটি খালি।'; +$PHPMAILER_LANG['encoding'] = 'অজানা এনকোডিং: '; +$PHPMAILER_LANG['execute'] = 'নির্বাহ করতে অক্ষম: '; +$PHPMAILER_LANG['extension_missing'] = 'এক্সটেনশন অনুপস্থিত:'; +$PHPMAILER_LANG['file_access'] = 'ফাইল অ্যাক্সেস করতে অক্ষম: '; +$PHPMAILER_LANG['file_open'] = 'ফাইল ত্রুটি: ফাইল খুলতে অক্ষম: '; +$PHPMAILER_LANG['from_failed'] = 'নিম্নলিখিত প্রেরকের ঠিকানা(গুলি) ব্যর্থ হয়েছে: '; +$PHPMAILER_LANG['instantiate'] = 'মেল ফাংশনের একটি উদাহরণ তৈরি করতে অক্ষম৷'; +$PHPMAILER_LANG['invalid_address'] = 'পাঠাতে অক্ষম: অবৈধ ইমেল ঠিকানা: '; +$PHPMAILER_LANG['invalid_header'] = 'অবৈধ হেডার নাম বা মান'; +$PHPMAILER_LANG['invalid_hostentry'] = 'অবৈধ হোস্টেন্ট্রি: '; +$PHPMAILER_LANG['invalid_host'] = 'অবৈধ হোস্ট:'; +$PHPMAILER_LANG['mailer_not_supported'] = 'মেইলার সমর্থিত নয়।'; +$PHPMAILER_LANG['provide_address'] = 'আপনাকে অবশ্যই অন্তত একটি গন্তব্য ইমেল ঠিকানা প্রদান করতে হবে৷'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP ত্রুটি: নিম্নলিখিত গন্তব্যগুলি ব্যর্থ হয়েছে: '; +$PHPMAILER_LANG['signing'] = 'স্বাক্ষর করতে ব্যর্থ হয়েছে: '; +$PHPMAILER_LANG['smtp_code'] = 'SMTP কোড: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'অতিরিক্ত SMTP তথ্য:'; +$PHPMAILER_LANG['smtp_detail'] = 'বর্ণনা: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP সংযোগ() ব্যর্থ হয়েছে৷'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP সার্ভার ত্রুটি: '; +$PHPMAILER_LANG['variable_set'] = 'পরিবর্তনশীল সেট করা যায়নি: '; +$PHPMAILER_LANG['extension_missing'] = 'অনুপস্থিত এক্সটেনশন: '; diff --git a/lib/phpmailer/language/phpmailer.lang-da.php b/lib/phpmailer/language/phpmailer.lang-da.php index 8b7b38a6ee5f..db9a1ef5b02c 100644 --- a/lib/phpmailer/language/phpmailer.lang-da.php +++ b/lib/phpmailer/language/phpmailer.lang-da.php @@ -9,6 +9,7 @@ */ $PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Login mislykkedes.'; +$PHPMAILER_LANG['buggy_php'] = 'Din version af PHP er berørt af en fejl, som gør at dine beskeder muligvis vises forkert. For at rette dette kan du skifte til SMTP, slå mail.add_x_header headeren i din php.ini fil fra, skifte til MacOS eller Linux eller opgradere din version af PHP til 7.0.17+ eller 7.1.3+.'; $PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Forbindelse til SMTP serveren kunne ikke oprettes.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.'; $PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold'; diff --git a/lib/phpmailer/language/phpmailer.lang-fi.php b/lib/phpmailer/language/phpmailer.lang-fi.php index 243c05489e75..6d1e6373901c 100644 --- a/lib/phpmailer/language/phpmailer.lang-fi.php +++ b/lib/phpmailer/language/phpmailer.lang-fi.php @@ -20,7 +20,6 @@ $PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.'; $PHPMAILER_LANG['provide_address'] = 'Aseta vähintään yksi vastaanottajan sähköpostiosoite.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.'; -$PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: '; //$PHPMAILER_LANG['signing'] = 'Signing Error: '; //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; diff --git a/lib/phpmailer/language/phpmailer.lang-fr.php b/lib/phpmailer/language/phpmailer.lang-fr.php index 38a7a8e7e5b6..0d367fcf885b 100644 --- a/lib/phpmailer/language/phpmailer.lang-fr.php +++ b/lib/phpmailer/language/phpmailer.lang-fr.php @@ -35,4 +35,3 @@ $PHPMAILER_LANG['smtp_detail'] = 'Détails : '; $PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP : '; $PHPMAILER_LANG['variable_set'] = 'Impossible d’initialiser ou de réinitialiser une variable : '; -$PHPMAILER_LANG['extension_missing'] = 'Extension manquante : '; diff --git a/lib/phpmailer/language/phpmailer.lang-nb.php b/lib/phpmailer/language/phpmailer.lang-nb.php index 65793ce2b9fd..c9621a164f7c 100644 --- a/lib/phpmailer/language/phpmailer.lang-nb.php +++ b/lib/phpmailer/language/phpmailer.lang-nb.php @@ -5,22 +5,29 @@ * @package PHPMailer */ -$PHPMAILER_LANG['authenticate'] = 'SMTP Feil: Kunne ikke autentisere.'; -$PHPMAILER_LANG['connect_host'] = 'SMTP Feil: Kunne ikke koble til SMTP tjener.'; -$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Feil: Datainnhold ikke akseptert.'; -$PHPMAILER_LANG['empty_message'] = 'Meldingsinnhold mangler'; -$PHPMAILER_LANG['encoding'] = 'Ukjent koding: '; -$PHPMAILER_LANG['execute'] = 'Kunne ikke utføre: '; -$PHPMAILER_LANG['file_access'] = 'Får ikke tilgang til filen: '; -$PHPMAILER_LANG['file_open'] = 'Fil Feil: Kunne ikke åpne filen: '; -$PHPMAILER_LANG['from_failed'] = 'Følgende Frå adresse feilet: '; -$PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere post funksjon.'; -$PHPMAILER_LANG['invalid_address'] = 'Ugyldig adresse: '; -$PHPMAILER_LANG['mailer_not_supported'] = ' sender er ikke støttet.'; -$PHPMAILER_LANG['provide_address'] = 'Du må opppgi minst en mottakeradresse.'; -$PHPMAILER_LANG['recipients_failed'] = 'SMTP Feil: Følgende mottakeradresse feilet: '; -$PHPMAILER_LANG['signing'] = 'Signering Feil: '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() feilet.'; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server feil: '; -$PHPMAILER_LANG['variable_set'] = 'Kan ikke skrive eller omskrive variabel: '; -$PHPMAILER_LANG['extension_missing'] = 'Utvidelse mangler: '; + $PHPMAILER_LANG['authenticate'] = 'SMTP-feil: Kunne ikke autentiseres.'; + $PHPMAILER_LANG['buggy_php'] = 'Din versjon av PHP er berørt av en feil som kan føre til ødelagte meldinger. For å løse problemet kan du bytte til SMTP, deaktivere alternativet mail.add_x_header i php.ini, bytte til MacOS eller Linux eller oppgradere PHP til versjon 7.0.17+ eller 7.1.3+.'; + $PHPMAILER_LANG['connect_host'] = 'SMTP-feil: Kunne ikke koble til SMTP-vert.'; + $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-feil: data ikke akseptert.'; + $PHPMAILER_LANG['empty_message'] = 'Meldingstekst mangler'; + $PHPMAILER_LANG['encoding'] = 'Ukjent koding: '; + $PHPMAILER_LANG['execute'] = 'Kunne ikke utføres: '; + $PHPMAILER_LANG['extension_missing'] = 'Utvidelse mangler: '; + $PHPMAILER_LANG['file_access'] = 'Kunne ikke få tilgang til filen: '; + $PHPMAILER_LANG['file_open'] = 'Feil i fil: Kunne ikke åpne filen: '; + $PHPMAILER_LANG['from_failed'] = 'Følgende Fra-adresse mislyktes: '; + $PHPMAILER_LANG['instantiate'] = 'Kunne ikke instansiere e-postfunksjonen.'; + $PHPMAILER_LANG['invalid_address'] = 'Ugyldig adresse: '; + $PHPMAILER_LANG['invalid_header'] = 'Ugyldig headernavn eller verdi'; + $PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig vertsinngang: '; + $PHPMAILER_LANG['invalid_host'] = 'Ugyldig vert: '; + $PHPMAILER_LANG['mailer_not_supported'] = ' sender er ikke støttet.'; + $PHPMAILER_LANG['provide_address'] = 'Du må oppgi minst én mottaker-e-postadresse.'; + $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feil: Følgende mottakeradresse feilet: '; + $PHPMAILER_LANG['signing'] = 'Signeringsfeil: '; + $PHPMAILER_LANG['smtp_code'] = 'SMTP-kode: '; + $PHPMAILER_LANG['smtp_code_ex'] = 'Ytterligere SMTP-info: '; + $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() mislyktes.'; + $PHPMAILER_LANG['smtp_detail'] = 'Detaljer: '; + $PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfeil: '; + $PHPMAILER_LANG['variable_set'] = 'Kan ikke angi eller tilbakestille variabel: '; diff --git a/lib/phpmailer/language/phpmailer.lang-pl.php b/lib/phpmailer/language/phpmailer.lang-pl.php index b0469fdb7a84..cb7b2c21076f 100644 --- a/lib/phpmailer/language/phpmailer.lang-pl.php +++ b/lib/phpmailer/language/phpmailer.lang-pl.php @@ -6,21 +6,28 @@ */ $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.'; +$PHPMAILER_LANG['buggy_php'] = 'Twoja wersja PHP zawiera błąd, który może powodować uszkodzenie wiadomości. Aby go naprawić, przełącz się na wysyłanie za pomocą SMTP, wyłącz opcję mail.add_x_header w php.ini, przełącz się na MacOS lub Linux lub zaktualizuj PHP do wersji 7.0.17+ lub 7.1.3+.'; $PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.'; $PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.'; $PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.'; $PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: '; $PHPMAILER_LANG['execute'] = 'Nie można uruchomić: '; +$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: '; $PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: '; $PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: '; $PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: '; $PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.'; $PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: '; +$PHPMAILER_LANG['invalid_header'] = 'Nieprawidłowa nazwa lub wartość nagłówka'; +$PHPMAILER_LANG['invalid_hostentry'] = 'Nieprawidłowy wpis hosta: '; +$PHPMAILER_LANG['invalid_host'] = 'Nieprawidłowy host: '; $PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.'; $PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.'; $PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: '; $PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: '; +$PHPMAILER_LANG['smtp_code'] = 'Kod SMTP: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'Dodatkowe informacje SMTP: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.'; +$PHPMAILER_LANG['smtp_detail'] = 'Szczegóły: '; $PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: '; $PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: '; -$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: '; diff --git a/lib/phpmailer/language/phpmailer.lang-si.php b/lib/phpmailer/language/phpmailer.lang-si.php new file mode 100644 index 000000000000..dce502aa02f4 --- /dev/null +++ b/lib/phpmailer/language/phpmailer.lang-si.php @@ -0,0 +1,34 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP දෝෂය: සත්‍යාපනය අසාර්ථක විය.'; +$PHPMAILER_LANG['buggy_php'] = 'ඔබගේ PHP version එකෙහි පවතින දෝෂයක් නිසා email පණිවිඩ දෝෂ සහගත වීමේ හැකියාවක් ඇත. මෙය විසදීම සදහා SMTP භාවිතා කිරීම, mail.add_x_header INI setting එක අක්‍රීය කිරීම, MacOS හෝ Linux වලට මාරු වීම, හෝ ඔබගේ PHP version එක 7.0.17+ හෝ 7.1.3+ වලට අලුත් කිරීම කරගන්න.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP දෝෂය: සම්බන්ධ වීමට නොහැකි විය.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP දෝෂය: දත්ත පිළිගනු නොලැබේ.'; +$PHPMAILER_LANG['empty_message'] = 'පණිවිඩ අන්තර්ගතය හිස්'; +$PHPMAILER_LANG['encoding'] = 'නොදන්නා කේතනය: '; +$PHPMAILER_LANG['execute'] = 'ක්‍රියාත්මක කළ නොහැකි විය: '; +$PHPMAILER_LANG['extension_missing'] = 'Extension එක නොමැත: '; +$PHPMAILER_LANG['file_access'] = 'File එකට ප්‍රවේශ විය නොහැකි විය: '; +$PHPMAILER_LANG['file_open'] = 'File දෝෂය: File එක විවෘත කළ නොහැක: '; +$PHPMAILER_LANG['from_failed'] = 'පහත From ලිපිනයන් අසාර්ථක විය: '; +$PHPMAILER_LANG['instantiate'] = 'mail function එක ක්‍රියාත්මක කළ නොහැක.'; +$PHPMAILER_LANG['invalid_address'] = 'වලංගු නොවන ලිපිනය: '; +$PHPMAILER_LANG['invalid_header'] = 'වලංගු නොවන header නාමයක් හෝ අගයක්'; +$PHPMAILER_LANG['invalid_hostentry'] = 'වලංගු නොවන hostentry එකක්: '; +$PHPMAILER_LANG['invalid_host'] = 'වලංගු නොවන host එකක්: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer සහාය නොදක්වයි.'; +$PHPMAILER_LANG['provide_address'] = 'ඔබ අවම වශයෙන් එක් ලබන්නෙකුගේ ඊමේල් ලිපිනයක් සැපයිය යුතුය.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP දෝෂය: පහත ලබන්නන් අසමත් විය: '; +$PHPMAILER_LANG['signing'] = 'Sign කිරීමේ දෝෂය: '; +$PHPMAILER_LANG['smtp_code'] = 'SMTP කේතය: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'අමතර SMTP තොරතුරු: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP සම්බන්ධය අසාර්ථක විය.'; +$PHPMAILER_LANG['smtp_detail'] = 'තොරතුරු: '; +$PHPMAILER_LANG['smtp_error'] = 'SMTP දෝෂය: '; +$PHPMAILER_LANG['variable_set'] = 'Variable එක සැකසීමට හෝ නැවත සැකසීමට නොහැක: '; diff --git a/lib/phpmailer/language/phpmailer.lang-zh_cn.php b/lib/phpmailer/language/phpmailer.lang-zh_cn.php index 728a4994c523..03d491165b58 100644 --- a/lib/phpmailer/language/phpmailer.lang-zh_cn.php +++ b/lib/phpmailer/language/phpmailer.lang-zh_cn.php @@ -9,11 +9,13 @@ */ $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['buggy_php'] = '您的 PHP 版本存在漏洞,可能会导致消息损坏。为修复此问题,请切换到使用 SMTP 发送,在您的 php.ini 中禁用 mail.add_x_header 选项。切换到 MacOS 或 Linux,或将您的 PHP 升级到 7.0.17+ 或 7.1.3+ 版本。'; $PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; $PHPMAILER_LANG['empty_message'] = '邮件正文为空。'; $PHPMAILER_LANG['encoding'] = '未知编码:'; $PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['extension_missing'] = '缺少扩展名:'; $PHPMAILER_LANG['file_access'] = '无法访问文件:'; $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; $PHPMAILER_LANG['from_failed'] = '发送地址错误:'; @@ -22,8 +24,13 @@ $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; -$PHPMAILER_LANG['signing'] = '登录失败:'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。'; $PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错:'; $PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:'; -$PHPMAILER_LANG['extension_missing'] = '丢失模块 Extension:'; +$PHPMAILER_LANG['invalid_header'] = '无效的标题名称或值'; +$PHPMAILER_LANG['invalid_hostentry'] = '无效的hostentry: '; +$PHPMAILER_LANG['invalid_host'] = '无效的主机:'; +$PHPMAILER_LANG['signing'] = '签名错误:'; +$PHPMAILER_LANG['smtp_code'] = 'SMTP代码: '; +$PHPMAILER_LANG['smtp_code_ex'] = '附加SMTP信息: '; +$PHPMAILER_LANG['smtp_detail'] = '详情:'; diff --git a/lib/phpmailer/readme_moodle.txt b/lib/phpmailer/readme_moodle.txt index ca6ff5973701..2b7bea3a96b4 100644 --- a/lib/phpmailer/readme_moodle.txt +++ b/lib/phpmailer/readme_moodle.txt @@ -1,10 +1,8 @@ -Description of PHPMailer 6.7.1 library import into Moodle +Description of PHPMailer library import into Moodle We now use a vanilla version of phpmailer and do our customisations in a subclass. -For more information on this version of PHPMailer, check out https://github.com/PHPMailer/PHPMailer/releases/tag/v6.7.1 - To upgrade this library: 1. Download the latest release of PHPMailer in https://github.com/PHPMailer/PHPMailer/releases. 2. Remove everything inside lib/phpmailer/ folder except README_MOODLE.txt, moodle_phpmailer.php and moodle_phpmailer_oauth.php. diff --git a/lib/phpmailer/src/DSNConfigurator.php b/lib/phpmailer/src/DSNConfigurator.php index ab707d2b4f55..566c9618f56e 100644 --- a/lib/phpmailer/src/DSNConfigurator.php +++ b/lib/phpmailer/src/DSNConfigurator.php @@ -80,9 +80,7 @@ private function parseDSN($dsn) $config = $this->parseUrl($dsn); if (false === $config || !isset($config['scheme']) || !isset($config['host'])) { - throw new Exception( - sprintf('Malformed DSN: "%s".', $dsn) - ); + throw new Exception('Malformed DSN'); } if (isset($config['query'])) { diff --git a/lib/phpmailer/src/PHPMailer.php b/lib/phpmailer/src/PHPMailer.php index a644d2cac710..ba4bcd472866 100644 --- a/lib/phpmailer/src/PHPMailer.php +++ b/lib/phpmailer/src/PHPMailer.php @@ -357,6 +357,13 @@ class PHPMailer */ public $AuthType = ''; + /** + * SMTP SMTPXClient command attibutes + * + * @var array + */ + protected $SMTPXClient = []; + /** * An implementation of the PHPMailer OAuthTokenProvider interface. * @@ -750,7 +757,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.8.0'; + const VERSION = '6.9.1'; /** * Error severity: message only, continue processing. @@ -795,7 +802,7 @@ class PHPMailer * The maximum line length supported by mail(). * * Background: mail() will sometimes corrupt messages - * with headers headers longer than 65 chars, see #818. + * with headers longer than 65 chars, see #818. * * @var int */ @@ -1571,6 +1578,10 @@ public function preSend() //Validate From, Sender, and ConfirmReadingTo addresses foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) { + if ($this->{$address_kind} === null) { + $this->{$address_kind} = ''; + continue; + } $this->{$address_kind} = trim($this->{$address_kind}); if (empty($this->{$address_kind})) { continue; @@ -1997,6 +2008,38 @@ public function setSMTPInstance(SMTP $smtp) return $this->smtp; } + /** + * Provide SMTP XCLIENT attributes + * + * @param string $name Attribute name + * @param ?string $value Attribute value + * + * @return bool + */ + public function setSMTPXclientAttribute($name, $value) + { + if (!in_array($name, SMTP::$xclient_allowed_attributes)) { + return false; + } + if (isset($this->SMTPXClient[$name]) && $value === null) { + unset($this->SMTPXClient[$name]); + } elseif ($value !== null) { + $this->SMTPXClient[$name] = $value; + } + + return true; + } + + /** + * Get SMTP XCLIENT attributes + * + * @return array + */ + public function getSMTPXclientAttributes() + { + return $this->SMTPXClient; + } + /** * Send mail via SMTP. * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. @@ -2025,6 +2068,9 @@ protected function smtpSend($header, $body) } else { $smtp_from = $this->Sender; } + if (count($this->SMTPXClient)) { + $this->smtp->xclient($this->SMTPXClient); + } if (!$this->smtp->mail($smtp_from)) { $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); throw new Exception($this->ErrorInfo, self::STOP_CRITICAL); @@ -2187,10 +2233,17 @@ public function smtpConnect($options = null) $this->smtp->hello($hello); //Automatically enable TLS encryption if: //* it's not disabled + //* we are not connecting to localhost //* we have openssl extension //* we are not already using SSL //* the server offers STARTTLS - if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) { + if ( + $this->SMTPAutoTLS && + $this->Host !== 'localhost' && + $sslext && + $secure !== 'ssl' && + $this->smtp->getServerExt('STARTTLS') + ) { $tls = true; } if ($tls) { @@ -4047,6 +4100,79 @@ public function clearCustomHeaders() $this->CustomHeader = []; } + /** + * Clear a specific custom header by name or name and value. + * $name value can be overloaded to contain + * both header name and value (name:value). + * + * @param string $name Custom header name + * @param string|null $value Header value + * + * @return bool True if a header was replaced successfully + */ + public function clearCustomHeader($name, $value = null) + { + if (null === $value && strpos($name, ':') !== false) { + //Value passed in as name:value + list($name, $value) = explode(':', $name, 2); + } + $name = trim($name); + $value = (null === $value) ? null : trim($value); + + foreach ($this->CustomHeader as $k => $pair) { + if ($pair[0] == $name) { + // We remove the header if the value is not provided or it matches. + if (null === $value || $pair[1] == $value) { + unset($this->CustomHeader[$k]); + } + } + } + + return true; + } + + /** + * Replace a custom header. + * $name value can be overloaded to contain + * both header name and value (name:value). + * + * @param string $name Custom header name + * @param string|null $value Header value + * + * @return bool True if a header was replaced successfully + * @throws Exception + */ + public function replaceCustomHeader($name, $value = null) + { + if (null === $value && strpos($name, ':') !== false) { + //Value passed in as name:value + list($name, $value) = explode(':', $name, 2); + } + $name = trim($name); + $value = (null === $value) ? '' : trim($value); + + $replaced = false; + foreach ($this->CustomHeader as $k => $pair) { + if ($pair[0] == $name) { + if ($replaced) { + unset($this->CustomHeader[$k]); + continue; + } + if (strpbrk($name . $value, "\r\n") !== false) { + if ($this->exceptions) { + throw new Exception($this->lang('invalid_header')); + } + + return false; + } + $this->CustomHeader[$k] = [$name, $value]; + $replaced = true; + } + } + + return true; + } + /** * Add an error message to the error container. * diff --git a/lib/phpmailer/src/SMTP.php b/lib/phpmailer/src/SMTP.php index fc4b781a5fde..1b5b00771cf3 100644 --- a/lib/phpmailer/src/SMTP.php +++ b/lib/phpmailer/src/SMTP.php @@ -35,7 +35,7 @@ class SMTP * * @var string */ - const VERSION = '6.8.0'; + const VERSION = '6.9.1'; /** * SMTP line break constant. @@ -198,6 +198,18 @@ class SMTP 'Mailjet' => '/[\d]{3} OK queued as (.*)/', ]; + /** + * Allowed SMTP XCLIENT attributes. + * Must be allowed by the SMTP server. EHLO response is not checked. + * + * @see https://www.postfix.org/XCLIENT_README.html + * + * @var array + */ + public static $xclient_allowed_attributes = [ + 'NAME', 'ADDR', 'PORT', 'PROTO', 'HELO', 'LOGIN', 'DESTADDR', 'DESTPORT' + ]; + /** * The last transaction ID issued in response to a DATA command, * if one was detected. @@ -704,7 +716,7 @@ public function close() * Send an SMTP DATA command. * Issues a data command and sends the msg_data to the server, * finalizing the mail transaction. $msg_data is the message - * that is to be send with the headers. Each header needs to be + * that is to be sent with the headers. Each header needs to be * on a single line followed by a with the message headers * and the message body being separated by an additional . * Implements RFC 821: DATA . @@ -732,7 +744,7 @@ public function data($msg_data) $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field - * of the first line (':' separated) does not contain a space then it _should_ be a header and we will + * of the first line (':' separated) does not contain a space then it _should_ be a header, and we will * process all lines before a blank line as headers. */ @@ -971,6 +983,25 @@ public function recipient($address, $dsn = '') ); } + /** + * Send SMTP XCLIENT command to server and check its return code. + * + * @return bool True on success + */ + public function xclient(array $vars) + { + $xclient_options = ""; + foreach ($vars as $key => $value) { + if (in_array($key, SMTP::$xclient_allowed_attributes)) { + $xclient_options .= " {$key}={$value}"; + } + } + if (!$xclient_options) { + return true; + } + return $this->sendCommand('XCLIENT', 'XCLIENT' . $xclient_options, 250); + } + /** * Send an SMTP RSET command. * Abort any transaction that is currently in progress. diff --git a/lib/phpunit/classes/util.php b/lib/phpunit/classes/util.php index f12010d47692..86e8fa47cbe2 100644 --- a/lib/phpunit/classes/util.php +++ b/lib/phpunit/classes/util.php @@ -973,7 +973,6 @@ public static function run_all_adhoc_tasks() { public static function call_internal_method($object, $methodname, array $params, $classname) { $reflection = new \ReflectionClass($classname); $method = $reflection->getMethod($methodname); - $method->setAccessible(true); return $method->invokeArgs($object, $params); } diff --git a/lib/phpunit/tests/phpunit_dataset_test.php b/lib/phpunit/tests/phpunit_dataset_test.php index 4e0aa982f743..262ef52befb2 100644 --- a/lib/phpunit/tests/phpunit_dataset_test.php +++ b/lib/phpunit/tests/phpunit_dataset_test.php @@ -54,11 +54,8 @@ public function test_from_files() { // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // Expectations. $exptables = ['user', 'user2']; @@ -158,11 +155,8 @@ public function test_from_file(string $fullpath, string $tablename, ?string $exc // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // We are expecting an exception. if (!empty($exception)) { @@ -251,11 +245,8 @@ public function test_from_string(string $content, string $type, string $tablenam // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // We are expecting an exception. if (!empty($exception)) { @@ -397,11 +388,8 @@ public function test_from_array(array $structure, ?string $exception, // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // We are expecting an exception. if (!empty($exception)) { @@ -491,11 +479,8 @@ public function test_load_csv(array $files, ?string $exception, // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // We are expecting an exception. if (!empty($exception)) { @@ -662,11 +647,8 @@ public function test_load_xml(array $files, ?string $exception, // We need public properties to check the basis. $dsref = new \ReflectionClass($ds); $dstables = $dsref->getProperty('tables'); - $dstables->setAccessible(true); $dscolumns = $dsref->getProperty('columns'); - $dscolumns->setAccessible(true); $dsrows = $dsref->getProperty('rows'); - $dsrows->setAccessible(true); // We are expecting an exception. if (!empty($exception)) { diff --git a/lib/questionlib.php b/lib/questionlib.php index b867ea2dc4c9..f1bb8c79c505 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -2092,262 +2092,3 @@ function is_latest(string $version, string $questionbankentryid): bool { } return false; } - -// Deprecated functions from Moodle 4.0. - -/** - * Generate the URL for starting a new preview of a given question with the given options. - * @param integer $questionid the question to preview. - * @param string $preferredbehaviour the behaviour to use for the preview. - * @param float $maxmark the maximum to mark the question out of. - * @param question_display_options $displayoptions the display options to use. - * @param int $variant the variant of the question to preview. If null, one will - * be picked randomly. - * @param object $context context to run the preview in (affects things like - * filter settings, theme, lang, etc.) Defaults to $PAGE->context. - * @return moodle_url the URL. - * @deprecated since Moodle 4.0 - * @see qbank_previewquestion\helper::question_preview_url() - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_preview_url($questionid, $preferredbehaviour = null, - $maxmark = null, $displayoptions = null, $variant = null, $context = null) { - debugging('Function question_preview_url() has been deprecated and moved to qbank_previewquestion plugin, - Please use qbank_previewquestion\previewquestion_helper::question_preview_url() instead.', DEBUG_DEVELOPER); - - return \qbank_previewquestion\helper::question_preview_url($questionid, $preferredbehaviour, - $maxmark, $displayoptions, $variant, $context); -} - -/** - * Popup params for the question preview. - * - * @return array that can be passed as $params to the {@see popup_action()} constructor. - * @deprecated since Moodle 4.0 - * @see qbank_previewquestion\previewquestion_helper::question_preview_popup_params() - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_preview_popup_params() { - debugging('Function question_preview_popup_params() has been deprecated and moved to qbank_previewquestion plugin, - Please use qbank_previewquestion\previewquestion_helper::question_preview_popup_params() instead.', DEBUG_DEVELOPER); - - return \qbank_previewquestion\helper::question_preview_popup_params(); -} - -/** - * Creates a stamp that uniquely identifies this version of the question - * - * In future we want this to use a hash of the question data to guarantee that - * identical versions have the same version stamp. - * - * @param object $question - * @return string A unique version stamp - * @deprecated since Moodle 4.0 - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_hash($question) { - debugging('Function question_hash() has been deprecated without replacement.', DEBUG_DEVELOPER); - return make_unique_id_code(); -} - -/** - * Create url for question export. - * - * @param int $contextid - * @param int $categoryid - * @param string $format - * @param string $withcategories - * @param string $withcontexts - * @param string $filename - * @return moodle_url export file url - * @deprecated since Moodle 4.0 MDL-71573 - * @see qbank_exportquestions\exportquestions_helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_make_export_url($contextid, $categoryid, $format, $withcategories, - $withcontexts, $filename) { - debugging('Function question_make_export_url() has been deprecated and moved to qbank_exportquestions plugin, - Please use qbank_exportquestions\exportquestions_helper::question_make_export_url() instead.', DEBUG_DEVELOPER); - - return \qbank_exportquestions\exportquestions_helper::question_make_export_url($contextid, $categoryid, $format, - $withcategories, $withcontexts, $filename); -} - -/** - * Get the URL to export a single question (exportone.php). - * - * @param stdClass|question_definition $question the question definition as obtained from - * question_bank::load_question_data() or question_bank::make_question(). - * (Only ->id and ->contextid are used.) - * @return moodle_url the requested URL. - * @deprecated since Moodle 4.0 - * @see \qbank_exporttoxml\helper::question_get_export_single_question_url() - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_get_export_single_question_url($question) { - debugging('Function question_get_export_single_question_url() has been deprecated and moved to qbank_exporttoxml plugin, - please use qbank_exporttoxml\helper::question_get_export_single_question_url() instead.', DEBUG_DEVELOPER); - qbank_exporttoxml\helper::question_get_export_single_question_url($question); -} - -/** - * Remove stale questions from a category. - * - * While questions should not be left behind when they are not used any more, - * it does happen, maybe via restore, or old logic, or uncovered scenarios. When - * this happens, the users are unable to delete the question category unless - * they move those stale questions to another one category, but to them the - * category is empty as it does not contain anything. The purpose of this function - * is to detect the questions that may have gone stale and remove them. - * - * You will typically use this prior to checking if the category contains questions. - * - * The stale questions (unused and hidden to the user) handled are: - * - hidden questions - * - random questions - * - * @param int $categoryid The category ID. - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_remove_stale_questions_from_category($categoryid) { - debugging('Function question_remove_stale_questions_from_category() - has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::question_remove_stale_questions_from_category() instead.', - DEBUG_DEVELOPER); - \qbank_managecategories\helper::question_remove_stale_questions_from_category($categoryid); -} - -/** - * Private method, only for the use of add_indented_names(). - * - * Recursively adds an indentedname field to each category, starting with the category - * with id $id, and dealing with that category and all its children, and - * return a new array, with those categories in the right order. - * - * @param array $categories an array of categories which has had childids - * fields added by flatten_category_tree(). Passed by reference for - * performance only. It is not modfied. - * @param int $id the category to start the indenting process from. - * @param int $depth the indent depth. Used in recursive calls. - * @param int $nochildrenof - * @return array a new array of categories, in the right order for the tree. - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function flatten_category_tree(&$categories, $id, $depth = 0, $nochildrenof = -1) { - debugging('Function flatten_category_tree() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::flatten_category_tree() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::flatten_category_tree($categories, $id, $depth, $nochildrenof); -} - -/** - * Format categories into an indented list reflecting the tree structure. - * - * @param array $categories An array of category objects, for example from the. - * @param int $nochildrenof - * @return array The formatted list of categories. - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function add_indented_names($categories, $nochildrenof = -1) { - debugging('Function add_indented_names() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::add_indented_names() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::add_indented_names($categories, $nochildrenof); -} - -/** - * Output a select menu of question categories. - * Categories from this course and (optionally) published categories from other courses - * are included. Optionally, only categories the current user may edit can be included. - * - * @param array $contexts - * @param bool $top - * @param int $currentcat - * @param integer $selected optionally, the id of a category to be selected by - * default in the dropdown. - * @param int $nochildrenof - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_category_select_menu($contexts, $top = false, $currentcat = 0, - $selected = "", $nochildrenof = -1) { - debugging('Function question_category_select_menu() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::question_category_select_menu() instead.', DEBUG_DEVELOPER); - \qbank_managecategories\helper::question_category_select_menu($contexts, $top, $currentcat, $selected, $nochildrenof); -} - -/** - * Get all the category objects, including a count of the number of questions in that category, - * for all the categories in the lists $contexts. - * - * @param mixed $contexts either a single contextid, or a comma-separated list of context ids. - * @param string $sortorder used as the ORDER BY clause in the select statement. - * @param bool $top Whether to return the top categories or not. - * @return array of category objects. - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function get_categories_for_contexts($contexts, $sortorder = 'parent, sortorder, name ASC', $top = false) { - debugging('Function get_categories_for_contexts() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::get_categories_for_contexts() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::get_categories_for_contexts($contexts, $sortorder, $top); -} - -/** - * Output an array of question categories. - * - * @param array $contexts The list of contexts. - * @param bool $top Whether to return the top categories or not. - * @param int $currentcat - * @param bool $popupform - * @param int $nochildrenof - * @param boolean $escapecontextnames Whether the returned name of the thing is to be HTML escaped or not. - * @return array - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_category_options($contexts, $top = false, $currentcat = 0, - $popupform = false, $nochildrenof = -1, $escapecontextnames = true) { - debugging('Function question_category_options() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::question_category_options() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::question_category_options($contexts, $top, $currentcat, - $popupform, $nochildrenof, $escapecontextnames); -} - -/** - * Add context in categories key. - * - * @param array $categories The list of categories. - * @return array - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_add_context_in_key($categories) { - debugging('Function question_add_context_in_key() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::question_add_context_in_key() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::question_add_context_in_key($categories); -} - -/** - * Finds top categories in the given categories hierarchy and replace their name with a proper localised string. - * - * @param array $categories An array of question categories. - * @param boolean $escape Whether the returned name of the thing is to be HTML escaped or not. - * @return array The same question category list given to the function, with the top category names being translated. - * @deprecated since Moodle 4.0 MDL-71585 - * @see qbank_managecategories\helper - * @todo Final deprecation on Moodle 4.4 MDL-72438 - */ -function question_fix_top_names($categories, $escape = true) { - debugging('Function question_fix_top_names() has been deprecated and moved to qbank_managecategories plugin, - Please use qbank_managecategories\helper::question_fix_top_names() instead.', DEBUG_DEVELOPER); - return \qbank_managecategories\helper::question_fix_top_names($categories, $escape); -} diff --git a/lib/setuplib.php b/lib/setuplib.php index af340a89e0c9..b56ba5f97a59 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -958,7 +958,13 @@ function initialise_fullme() { throw new moodle_exception('requirecorrectaccess', 'error', '', null, 'You called ' . $calledurl .', you should have called ' . $correcturl); } - redirect($CFG->wwwroot . $rurl['fullpath'], get_string('wwwrootmismatch', 'error', $CFG->wwwroot), 3); + $rfullpath = $rurl['fullpath']; + // Check that URL is under $CFG->wwwroot. + if (strpos($rfullpath, $wwwroot['path']) === 0) { + $rfullpath = substr($rurl['fullpath'], strlen($wwwroot['path']) - 1); + $rfullpath = (new moodle_url($rfullpath))->out(false); + } + redirect($rfullpath, get_string('wwwrootmismatch', 'error', $CFG->wwwroot), 3); } } @@ -1492,7 +1498,7 @@ function disable_output_buffering() { */ function is_major_upgrade_required() { global $CFG; - $lastmajordbchanges = 2022101400.03; // This should be the version where the breaking changes happen. + $lastmajordbchanges = 2024010400.00; // This should be the version where the breaking changes happen. $required = empty($CFG->version); $required = $required || (float)$CFG->version < $lastmajordbchanges; diff --git a/calendar/templates/threemonth_month.mustache b/lib/templates/form_input_toggle_sensitive.mustache similarity index 55% rename from calendar/templates/threemonth_month.mustache rename to lib/templates/form_input_toggle_sensitive.mustache index bac1b5b68ee8..ba47b469c0c8 100644 --- a/calendar/templates/threemonth_month.mustache +++ b/lib/templates/form_input_toggle_sensitive.mustache @@ -15,14 +15,9 @@ along with Moodle. If not, see . }} {{! - @template core_calendar/threemonth_month + @template core/form_input_toggle_sensitive - @deprecated since 4.0 MDL-72810. - @todo MDL-73117 This will be deleted in Moodle 4.4. - - Calendar view to show three months as a block. - - The purpose of this template is to render a set of three months of calendar_mini in a block. + Moodle template for toggling senstive inputs. Classes required for JS: * none @@ -30,13 +25,21 @@ Data attributes required for JS: * none + Context variables required for this template: + * none + Example context (json): { + "smallscreensonly": true, + "sensitiveinput": "" } }} -
- {{> core_calendar/calendar_mini}} +
+ {{{sensitiveinput}}} +
+ +
diff --git a/lib/templates/loginform.mustache b/lib/templates/loginform.mustache index 05060f3ff6e9..9e5fd7aa72fd 100644 --- a/lib/templates/loginform.mustache +++ b/lib/templates/loginform.mustache @@ -91,7 +91,9 @@ "sitename": "Beer & Chips", "logintoken": "randomstring", "maintenance": "For full access to this site, you need to login in as an admin.", - "languagemenu": "Choose language" + "languagemenu": "Choose language", + "togglepassword": true, + "smallscreensonly": true } }} @@ -214,13 +216,24 @@ {{#js}} {{^error}} + {{#togglepassword}} + require(['core/togglesensitive'], function(ToggleSensitive) { + ToggleSensitive.init("password", {{smallscreensonly}}); + }); + {{/togglepassword}} {{#autofocusform}} - var userNameField = document.getElementById('username'); - if (userNameField.value.length == 0) { - userNameField.focus(); - } else { - document.getElementById('password').focus(); - } + require(['core_form/events'], function(FormEvent) { + function autoFocus() { + const userNameField = document.getElementById('username'); + if (userNameField.value.length == 0) { + userNameField.focus(); + } else { + document.getElementById('password').focus(); + } + } + autoFocus(); + window.addEventListener(FormEvent.eventTypes.fieldStructureChanged, autoFocus); + }); {{/autofocusform}} {{/error}} {{#error}} diff --git a/lib/tests/accesslib_test.php b/lib/tests/accesslib_test.php index ba4f0f143acc..8b72994b1cc6 100644 --- a/lib/tests/accesslib_test.php +++ b/lib/tests/accesslib_test.php @@ -1965,7 +1965,6 @@ protected function setup_fake_plugin($pluginname) { // the access.php works. $mockedcomponent = new ReflectionClass(core_component::class); $mockedplugins = $mockedcomponent->getProperty('plugins'); - $mockedplugins->setAccessible(true); $plugins = $mockedplugins->getValue(); $plugins['fake'] = [$pluginname => "{$CFG->dirroot}/lib/tests/fixtures/fakeplugins/$pluginname"]; $mockedplugins->setValue(null, $plugins); @@ -4877,7 +4876,6 @@ public function test_is_parent_of(string $contextpath, string $testpath, bool $t ->getMock(); $rcp = new ReflectionProperty($context, '_path'); - $rcp->setAccessible(true); $rcp->setValue($context, $contextpath); $comparisoncontext = $this->getMockBuilder(\context::class) @@ -4889,7 +4887,6 @@ public function test_is_parent_of(string $contextpath, string $testpath, bool $t ->getMock(); $rcp = new ReflectionProperty($comparisoncontext, '_path'); - $rcp->setAccessible(true); $rcp->setValue($comparisoncontext, $testpath); $this->assertEquals($expected, $context->is_parent_of($comparisoncontext, $testself)); @@ -4986,7 +4983,6 @@ public function test_is_child_of(string $contextpath, string $testpath, bool $te ->getMock(); $rcp = new ReflectionProperty($context, '_path'); - $rcp->setAccessible(true); $rcp->setValue($context, $contextpath); $comparisoncontext = $this->getMockBuilder(\context::class) @@ -4998,7 +4994,6 @@ public function test_is_child_of(string $contextpath, string $testpath, bool $te ->getMock(); $rcp = new ReflectionProperty($comparisoncontext, '_path'); - $rcp->setAccessible(true); $rcp->setValue($comparisoncontext, $testpath); $this->assertEquals($expected, $context->is_child_of($comparisoncontext, $testself)); diff --git a/lib/tests/analysers_test.php b/lib/tests/analysers_test.php index 1e5c3e813a82..875646c6b16a 100644 --- a/lib/tests/analysers_test.php +++ b/lib/tests/analysers_test.php @@ -57,7 +57,6 @@ public function test_courses_analyser() { // Just 1 sample per course. $class = new \ReflectionClass('\core\analytics\analyser\courses'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $this->assertCount(1, $sampleids); $sampleid = reset($sampleids); @@ -107,7 +106,6 @@ public function test_site_courses_analyser() { $class = new \ReflectionClass('\core\analytics\analyser\site_courses'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); $this->assertCount(3, $sampleids); @@ -159,7 +157,6 @@ public function test_student_enrolments_analyser() { $class = new \ReflectionClass('\core\analytics\analyser\student_enrolments'); $method = $class->getMethod('get_all_samples'); - $method->setAccessible(true); list($sampleids, $samplesdata) = $method->invoke($analyser, $analysable); // Only students. $this->assertCount(2, $sampleids); diff --git a/lib/tests/client_test.php b/lib/tests/client_test.php index 2f6a71838476..66cdb3b7a7bd 100644 --- a/lib/tests/client_test.php +++ b/lib/tests/client_test.php @@ -109,7 +109,6 @@ public function test_map_userinfo_to_fields(array $mapping, array $expected) { ]; $method = new ReflectionMethod("core\oauth2\client", "map_userinfo_to_fields"); - $method->setAccessible(true); $issuer = new \core\oauth2\issuer(0); $mockbuilder = $this->getMockBuilder('core\oauth2\client'); diff --git a/lib/tests/completionlib_test.php b/lib/tests/completionlib_test.php index ced754c46bf1..fb0904bbb2df 100644 --- a/lib/tests/completionlib_test.php +++ b/lib/tests/completionlib_test.php @@ -966,7 +966,6 @@ public function test_get_other_cm_completion_data() { $completioninfo = new completion_info($this->course); $method = new ReflectionMethod("completion_info", "get_other_cm_completion_data"); - $method->setAccessible(true); // Check that fetching data for a module with custom completion provides its info. $choicecompletiondata = $method->invoke($completioninfo, $cmchoice, $user->id); @@ -1813,7 +1812,6 @@ public function test_save() { // We're testing a private method, so we need to setup reflector magic. $method = new ReflectionMethod($ccompletion, '_save'); - $method->setAccessible(true); // Allow accessing of private method. $completionid = $method->invoke($ccompletion); $completions = $DB->get_records('course_completions'); $this->assertEquals(count($completions), 1); @@ -1821,7 +1819,6 @@ public function test_save() { $ccompletion->id = 0; $method = new ReflectionMethod($ccompletion, '_save'); - $method->setAccessible(true); // Allow accessing of private method. $completionid = $method->invoke($ccompletion); $this->assertDebuggingCalled('Can not update data object, no id!'); $this->assertNull($completionid); diff --git a/lib/tests/component_test.php b/lib/tests/component_test.php index 5df2a1c34d89..d9c714cec5ce 100644 --- a/lib/tests/component_test.php +++ b/lib/tests/component_test.php @@ -640,11 +640,9 @@ public static function classloader_provider(): array { */ public function test_classloader($psr0, $psr4, $classname, $includedfiles): void { $psr0namespaces = new ReflectionProperty('core_component', 'psr0namespaces'); - $psr0namespaces->setAccessible(true); $psr0namespaces->setValue(null, $psr0); $psr4namespaces = new ReflectionProperty('core_component', 'psr4namespaces'); - $psr4namespaces->setAccessible(true); $psr4namespaces->setValue(null, $psr4); core_component::classloader($classname); @@ -775,16 +773,13 @@ public static function psr_classloader_provider(): array { */ public function test_psr_classloader($psr0, $psr4, $classname, $file): void { $psr0namespaces = new ReflectionProperty('core_component', 'psr0namespaces'); - $psr0namespaces->setAccessible(true); $psr0namespaces->setValue(null, $psr0); $psr4namespaces = new ReflectionProperty('core_component', 'psr4namespaces'); - $psr4namespaces->setAccessible(true); $psr4namespaces->setValue(null, $psr4); $component = new ReflectionClass('core_component'); $psrclassloader = $component->getMethod('psr_classloader'); - $psrclassloader->setAccessible(true); $returnvalue = $psrclassloader->invokeArgs(null, [$classname]); // Normalise to forward slashes for testing comparison. @@ -845,7 +840,6 @@ public static function get_class_file_provider(): array { public function test_get_class_file($classname, $prefix, $path, $separators, $result): void { $component = new ReflectionClass('core_component'); $psrclassloader = $component->getMethod('get_class_file'); - $psrclassloader->setAccessible(true); $file = $psrclassloader->invokeArgs(null, [$classname, $prefix, $path, $separators]); $this->assertEquals($result, $file); diff --git a/lib/tests/core_renderer_template_exploit_test.php b/lib/tests/core_renderer_template_exploit_test.php index 771ad6be66a9..992fa1f95bc3 100644 --- a/lib/tests/core_renderer_template_exploit_test.php +++ b/lib/tests/core_renderer_template_exploit_test.php @@ -410,7 +410,6 @@ public function test_core_mustache_engine_strips_js_helper( // Get the mustache engine from the renderer. $reflection = new \ReflectionMethod($renderer, 'get_mustache'); - $reflection->setAccessible(true); $engine = $reflection->invoke($renderer); // Swap the loader out with an array loader so that we can set some diff --git a/lib/tests/deprecation_test.php b/lib/tests/deprecation_test.php index 12a0dd52bd93..bebad9ce3fc3 100644 --- a/lib/tests/deprecation_test.php +++ b/lib/tests/deprecation_test.php @@ -16,14 +16,18 @@ namespace core; +use core\attribute\deprecated; +use core\attribute\deprecated_with_reference; + /** - * Tests for \core\deprecated and \core\deprecation. + * Tests for \core\attribute\sdeprecated and \core\deprecation. * * @package core * @category test * @copyright 2024 Andrew Lyons * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @covers \core\deprecated + * @covers \core\attribute\deprecated + * @covers \core\attribute\deprecated_with_reference * @covers \core\deprecation */ class deprecation_test extends \advanced_testcase { @@ -40,11 +44,13 @@ public function test_emit( } $attribute = new deprecated( - 'Test description', ...$args, + replacement: 'Test replacement', ); - deprecation::emit_deprecation_notice($attribute); + $rc = new \ReflectionClass(deprecation::class); + $method = $rc->getMethod('emit_deprecation_notice'); + $method->invoke(null, $attribute); if ($expectdebugging) { $this->assertdebuggingcalledcount(1); @@ -92,19 +98,20 @@ public static function emit_provider(): array { * @dataProvider get_deprecation_string_provider */ public function test_get_deprecation_string( - string $descriptor, + ?string $replacement, ?string $since, ?string $reason, - ?string $replacement, ?string $mdl, string $expected, ): void { - $attribute = new deprecated( - descriptor: $descriptor, + $attribute = new deprecated_with_reference( + owner: 'Test description', + replacement: $replacement, since: $since, reason: $reason, - replacement: $replacement, mdl: $mdl, + final: false, + emit: true, ); $this->assertEquals( @@ -112,63 +119,81 @@ public function test_get_deprecation_string( deprecation::get_deprecation_string($attribute), ); - deprecation::emit_deprecation_notice($attribute); + $rc = new \ReflectionClass(deprecation::class); + $method = $rc->getMethod('emit_deprecation_notice'); + $method->invoke(null, $attribute); + $this->assertDebuggingCalled($expected); } public static function get_deprecation_string_provider(): array { return [ [ - 'Test description', - null, + 'Test replacement', null, null, null, - 'Deprecation: Test description has been deprecated.', + 'Deprecation: Test description has been deprecated. Use Test replacement instead.', ], [ - 'Test description', + 'Test replacement', '4.1', null, null, - null, - 'Deprecation: Test description has been deprecated since 4.1.', + 'Deprecation: Test description has been deprecated since 4.1. Use Test replacement instead.', ], [ - 'Test description', + 'Test replacement', null, 'Test reason', null, - null, - 'Deprecation: Test description has been deprecated. Test reason.', + 'Deprecation: Test description has been deprecated. Test reason. Use Test replacement instead.', ], [ - 'Test description', + 'Test replacement', null, null, - 'Test replacement', null, 'Deprecation: Test description has been deprecated. Use Test replacement instead.', ], [ - 'Test description', - null, + 'Test replacement', null, null, 'https://docs.moodle.org/311/en/Deprecated', - 'Deprecation: Test description has been deprecated. See https://docs.moodle.org/311/en/Deprecated for more information.', + 'Deprecation: Test description has been deprecated. Use Test replacement instead. See https://docs.moodle.org/311/en/Deprecated for more information.', ], [ - 'Test description', + 'Test replacement', '4.1', 'Test reason', - 'Test replacement', 'https://docs.moodle.org/311/en/Deprecated', 'Deprecation: Test description has been deprecated since 4.1. Test reason. Use Test replacement instead. See https://docs.moodle.org/311/en/Deprecated for more information.', ], + [ + null, + null, + 'Test reason', + null, + 'Deprecation: Test description has been deprecated. Test reason.', + ], + [ + null, + null, + null, + 'MDL-80677', + 'Deprecation: Test description has been deprecated. See MDL-80677 for more information.', + ], ]; } + public function test_deprecated_without_replacement(): void { + $this->expectException(\coding_exception::class); + new deprecated( + replacement: null, + ); + } + /** * @dataProvider from_provider */ @@ -201,41 +226,168 @@ public static function from_provider(): array { return [ // Classes. [\core\fixtures\deprecated_class::class, true], + [\core\fixtures\deprecated_interface::class, true], + [\core\fixtures\deprecated_trait::class, true], [[\core\fixtures\deprecated_class::class], true], + [[\core\fixtures\deprecated_interface::class], true], + [[\core\fixtures\deprecated_trait::class], true], + + [\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class, false], + [[\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class], false], + [\core\fixtures\not_deprecated_class::class, false], + [\core\fixtures\not_deprecated_interface::class, false], + [\core\fixtures\not_deprecated_trait::class, false], [[\core\fixtures\not_deprecated_class::class], false], + [[\core\fixtures\not_deprecated_interface::class], false], + [[\core\fixtures\not_deprecated_trait::class], false], - // Class properties. + // Class properties in a deprecated class. [\core\fixtures\deprecated_class::class . '::deprecatedproperty', true], [[\core\fixtures\deprecated_class::class, 'deprecatedproperty'], true], + [\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class . '::deprecatedproperty', true], + [[\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class, 'deprecatedproperty'], true], + [\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class . '::deprecatedproperty', true], + [[\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class, 'deprecatedproperty'], true], - [\core\fixtures\deprecated_class::class . '::notdeprecatedproperty', false], - [[\core\fixtures\deprecated_class::class, 'notdeprecatedproperty'], false], + [\core\fixtures\deprecated_class::class . '::notdeprecatedproperty', true], + [[\core\fixtures\deprecated_class::class, 'notdeprecatedproperty'], true], + [\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class . '::notdeprecatedproperty', true], + [[\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class, 'notdeprecatedproperty'], true], + [\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class . '::notdeprecatedproperty', false], + [[\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class, 'notdeprecatedproperty'], false], - // Class constants. + // Class constants in a deprecated class. [\core\fixtures\deprecated_class::class . '::DEPRECATED_CONST', true], [[\core\fixtures\deprecated_class::class, 'DEPRECATED_CONST'], true], - [\core\fixtures\deprecated_class::class . '::NOT_DEPRECATED_CONST', false], - [[\core\fixtures\deprecated_class::class, 'NOT_DEPRECATED_CONST'], false], + [\core\fixtures\deprecated_class::class . '::NOT_DEPRECATED_CONST', true], + [[\core\fixtures\deprecated_class::class, 'NOT_DEPRECATED_CONST'], true], - // Class methods. + // Class methods in a deprecated class. [\core\fixtures\deprecated_class::class . '::deprecated_method', true], [[\core\fixtures\deprecated_class::class, 'deprecated_method'], true], - [\core\fixtures\deprecated_class::class . '::not_deprecated_method', false], - [[\core\fixtures\deprecated_class::class, 'not_deprecated_method'], false], + [\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class . '::deprecated_method', true], + [[\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class, 'deprecated_method'], true], + [\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class . '::deprecated_method', true], + [[\core\fixtures\not_deprecated_class_using_not_deprecated_trait_features::class, 'deprecated_method'], true], + + [\core\fixtures\deprecated_class::class . '::not_deprecated_method', true], + [[\core\fixtures\deprecated_class::class, 'not_deprecated_method'], true], + + [\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class . '::not_deprecated_method', true], + [[\core\fixtures\not_deprecated_class_using_deprecated_trait_features::class, 'not_deprecated_method'], true], + [\core\fixtures\not_deprecated_class_implementing_deprecated_interface::class . '::not_deprecated_method', true], + [[\core\fixtures\not_deprecated_class_implementing_deprecated_interface::class, 'not_deprecated_method'], true], + + // Class properties in a not-deprecated class. + [\core\fixtures\not_deprecated_class::class . '::deprecatedproperty', true], + [[\core\fixtures\not_deprecated_class::class, 'deprecatedproperty'], true], + + [\core\fixtures\not_deprecated_class::class . '::notdeprecatedproperty', false], + [[\core\fixtures\not_deprecated_class::class, 'notdeprecatedproperty'], false], + + // Class constants in a not-deprecated class. + [\core\fixtures\not_deprecated_class::class . '::DEPRECATED_CONST', true], + [[\core\fixtures\not_deprecated_class::class, 'DEPRECATED_CONST'], true], + + [\core\fixtures\not_deprecated_class::class . '::NOT_DEPRECATED_CONST', false], + [[\core\fixtures\not_deprecated_class::class, 'NOT_DEPRECATED_CONST'], false], + + [\core\fixtures\not_deprecated_interface::class . '::DEPRECATED_CONST', true], + [[\core\fixtures\not_deprecated_interface::class, 'DEPRECATED_CONST'], true], + + [\core\fixtures\not_deprecated_interface::class . '::NOT_DEPRECATED_CONST', false], + [[\core\fixtures\not_deprecated_interface::class, 'NOT_DEPRECATED_CONST'], false], + + // Class methods in a not-deprecated class. + [\core\fixtures\not_deprecated_class::class . '::deprecated_method', true], + [[\core\fixtures\not_deprecated_class::class, 'deprecated_method'], true], + + [\core\fixtures\not_deprecated_class::class . '::not_deprecated_method', false], + [[\core\fixtures\not_deprecated_class::class, 'not_deprecated_method'], false], // Non-existent class. ['non_existent_class', false], [['non_existent_class'], false], + // Non-existent feature in an existent class. + [[\core\fixtures\not_deprecated_class::class, 'no_such_method'], false], + // Not-deprecated class. [\core\fixtures\not_deprecated_class::class, false], // Deprecated global function. ['core\fixtures\deprecated_function', true], ['core\fixtures\not_deprecated_function', false], + + // Empty array. + [[], false], + ]; + } + + /** + * @dataProvider deprecated_ownership_provider + */ + public function test_deprecated_class( + array $reference, + string $expectedowner, + ): void { + require_once(dirname(__FILE__) . '/fixtures/deprecated_fixtures.php'); + + // All attributes for any part of a deprecated class should belong to the deprecated class. + $this->assertEquals( + $expectedowner, + deprecation::from($reference)->owner, + ); + } + + public static function deprecated_ownership_provider(): array { + return [ + // Any part of a deprecated class will emit the deprecation for the class as a whole. + [ + [\core\fixtures\deprecated_class::class], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'deprecatedproperty'], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'notdeprecatedproperty'], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'deprecated_method'], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'not_deprecated_method'], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'DEPRECATED_CONST'], + \core\fixtures\deprecated_class::class, + ], + [ + [\core\fixtures\deprecated_class::class, 'NOT_DEPRECATED_CONST'], + \core\fixtures\deprecated_class::class, + ], + + // A non-deprecated class will emit just for that feature. + [ + [\core\fixtures\not_deprecated_class::class, 'deprecatedproperty'], + \core\fixtures\not_deprecated_class::class . '::deprecatedproperty', + ], + [ + [\core\fixtures\not_deprecated_class::class, 'deprecated_method'], + \core\fixtures\not_deprecated_class::class . '::deprecated_method', + ], + [ + [\core\fixtures\not_deprecated_class::class, 'DEPRECATED_CONST'], + \core\fixtures\not_deprecated_class::class . '::DEPRECATED_CONST', + ], ]; } } diff --git a/lib/tests/external/check/get_result_admintree_test.php b/lib/tests/external/check/get_result_admintree_test.php index 5814e6c4a24b..702e40acd401 100644 --- a/lib/tests/external/check/get_result_admintree_test.php +++ b/lib/tests/external/check/get_result_admintree_test.php @@ -227,7 +227,6 @@ public function test_find_check_from_setting_tree(array $settings, string $searc $root = $this->setup_admin_tree($settings); $method = new ReflectionMethod(get_result_admintree::class, 'get_check_from_setting'); - $method->setAccessible(true); $result = $method->invoke(new get_result_admintree(), $searchid, $searchname, $root); diff --git a/lib/tests/filelib_test.php b/lib/tests/filelib_test.php index 1e3760a4bf21..6ed87509a20f 100644 --- a/lib/tests/filelib_test.php +++ b/lib/tests/filelib_test.php @@ -2061,7 +2061,6 @@ class testable_curl extends curl { public function get_options() { // Access to private property. $rp = new \ReflectionProperty('curl', 'options'); - $rp->setAccessible(true); return $rp->getValue($this); } @@ -2073,7 +2072,6 @@ public function get_options() { public function set_options($options) { // Access to private property. $rp = new \ReflectionProperty('curl', 'options'); - $rp->setAccessible(true); $rp->setValue($this, $options); } @@ -2107,7 +2105,6 @@ public function unset_option($option) { public function call_apply_opt($options = null) { // Access to private method. $rm = new \ReflectionMethod('curl', 'apply_opt'); - $rm->setAccessible(true); $ch = curl_init(); return $rm->invoke($this, $ch, $options); } diff --git a/lib/tests/filestorage_zip_archive_test.php b/lib/tests/filestorage_zip_archive_test.php index 06eb9db2fed3..7ed424995031 100644 --- a/lib/tests/filestorage_zip_archive_test.php +++ b/lib/tests/filestorage_zip_archive_test.php @@ -44,7 +44,6 @@ public function test_mangle_pathname($string, $expected) { $ziparchive = new zip_archive(); $method = new \ReflectionMethod('zip_archive', 'mangle_pathname'); - $method->setAccessible(true); $result = $method->invoke($ziparchive, $string); $this->assertSame($expected, $result); diff --git a/lib/tests/fixtures/deprecated_fixtures.php b/lib/tests/fixtures/deprecated_fixtures.php index a5f8990f4745..3956671127d2 100644 --- a/lib/tests/fixtures/deprecated_fixtures.php +++ b/lib/tests/fixtures/deprecated_fixtures.php @@ -16,7 +16,7 @@ namespace core\fixtures; -use core\deprecated; +use core\attribute\deprecated; /** * A file containing a variety of fixturs for deprecated attribute tests. @@ -26,27 +26,111 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -#[deprecated('Deprecated class')] +#[deprecated('not_deprecated_class')] class deprecated_class { protected string $notdeprecatedproperty = 'Not deprecated property'; - #[deprecated('Deprecated property')] + #[deprecated('$this->notdeprecatedproperty')] protected string $deprecatedproperty = 'Deprecated property'; const NOT_DEPRECATED_CONST = 'Not deprecated const'; - #[deprecated('Deprecated const')] + #[deprecated('not_deprecated_class::NEW_CONSTANT')] const DEPRECATED_CONST = 'Deprecated const'; - public function not_deprecated_method() {} + public function not_deprecated_method() { + } - #[deprecated('Deprecated method')] - public function deprecated_method() {} + #[deprecated(replacement: null, mdl: 'MDL-80677')] + public function deprecated_method() { + } } -class not_deprecated_class {} +class not_deprecated_class { + protected string $notdeprecatedproperty = 'Not deprecated property'; + + #[deprecated('$this->notdeprecatedproperty')] + protected string $deprecatedproperty = 'Deprecated property'; + + const NOT_DEPRECATED_CONST = 'Not deprecated const'; + + #[deprecated('self::NOT_DEPRECATED_CONST')] + const DEPRECATED_CONST = 'Deprecated const'; + + public function not_deprecated_method() { + } + + #[deprecated('$this->not_deprecated_method()')] + public function deprecated_method() { + } +} + +function not_deprecated_function() { +} + +#[deprecated('not_deprecated_class::not_deprecated_method()')] +function deprecated_function() { +} + +interface not_deprecated_interface { + const NOT_DEPRECATED_CONST = 'Not deprecated const'; + + #[deprecated('self::NOT_DEPRECATED_CONST')] + const DEPRECATED_CONST = 'Deprecated const'; + + // Note: It does not make sense to deprecate methods in an _interface_ as the interface itself should be deprecated. +} + +#[deprecated('not_deprecated_interface')] +interface deprecated_interface { + const DEPRECATED_CONST = 'Deprecated const'; -function not_deprecated_function() {} + public function not_deprecated_method(); +} + +trait not_deprecated_trait { + protected string $notdeprecatedproperty = 'Not deprecated property'; + + #[deprecated('$this->notdeprecatedproperty')] + protected string $deprecatedproperty = 'Deprecated property'; + + public function not_deprecated_method() { + } + + #[deprecated('$this->not_deprecated_method()')] + public function deprecated_method() { + } +} + +#[deprecated(not_deprecated_trait::class)] +trait deprecated_trait { + protected string $notdeprecatedproperty = 'Not deprecated property'; + + #[deprecated('$this->notdeprecatedproperty')] + protected string $deprecatedproperty = 'Deprecated property'; + + public function not_deprecated_method() { + } + + #[deprecated(replacement: null, mdl: 'MDL-80677')] + public function deprecated_method() { + } +} + +class not_deprecated_class_using_deprecated_trait_features { + use deprecated_trait; +} -#[deprecated('Deprecated function')] -function deprecated_function() {} +class not_deprecated_class_implementing_deprecated_interface implements deprecated_interface { + public function not_deprecated_method() { + } +} + +class not_deprecated_class_using_not_deprecated_trait_features { + use not_deprecated_trait; +} + +class not_deprecated_class_implementing_not_deprecated_interface implements not_deprecated_interface { + public function not_deprecated_method() { + } +} diff --git a/lib/tests/http_client_test.php b/lib/tests/http_client_test.php index 8d405ff9a46f..b5cb24b97c54 100644 --- a/lib/tests/http_client_test.php +++ b/lib/tests/http_client_test.php @@ -57,12 +57,10 @@ public static function read_object_attribute(object $object, string $attributena return $object->$attributename; } - $attribute->setAccessible(true); try { return $attribute->getValue($object); } finally { - $attribute->setAccessible(false); } } catch (\ReflectionException $e) { // Do nothing. diff --git a/lib/tests/medialib_test.php b/lib/tests/medialib_test.php index e95bda6f6795..c5eddec9fe72 100644 --- a/lib/tests/medialib_test.php +++ b/lib/tests/medialib_test.php @@ -475,7 +475,6 @@ public function test_initialise() { */ public function get_players_test($manager) { $method = new \ReflectionMethod("core_media_manager", "get_players"); - $method->setAccessible(true); $players = $method->invoke($manager); $out = ''; foreach ($players as $player) { diff --git a/lib/tests/moodle_url_test.php b/lib/tests/moodle_url_test.php index 786736a4ed36..4c36c81a3115 100644 --- a/lib/tests/moodle_url_test.php +++ b/lib/tests/moodle_url_test.php @@ -16,6 +16,8 @@ namespace core; +use GuzzleHttp\Psr7\Uri; + /** * Tests for moodle_url. * @@ -414,4 +416,33 @@ public function make_pluginfile_url_provider() { ], ]; } + + public function test_from_uri(): void { + global $CFG; + + $uri = new Uri('http://www.example.org:447/my/file/is/here.txt?really=1'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('http://www.example.org:447/my/file/is/here.txt?really=1', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + + $uri = new Uri('https://www.example.org/my/file/is/here.txt?really=1'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('https://www.example.org/my/file/is/here.txt?really=1', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + + // Multiple params. + $uri = new Uri('https://www.example.org/my/file/is/here.txt?really=1&another=2&&more=3&moar=4'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('https://www.example.org/my/file/is/here.txt?really=1&another=2&more=3&moar=4', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + $this->assertEquals(2, $url->param('another')); + $this->assertEquals(3, $url->param('more')); + $this->assertEquals(4, $url->param('moar')); + + // Anchors. + $uri = new Uri("{$CFG->wwwroot}/course/view/#section-1"); + $url = \moodle_url::from_uri($uri); + $this->assertSame("{$CFG->wwwroot}/course/view/#section-1", $url->out(false)); + $this->assertEmpty($url->params()); + } } diff --git a/lib/tests/moodlenet/activity_packager_test.php b/lib/tests/moodlenet/activity_packager_test.php index c14ecfd9f940..e290c6c8e6b7 100644 --- a/lib/tests/moodlenet/activity_packager_test.php +++ b/lib/tests/moodlenet/activity_packager_test.php @@ -54,10 +54,8 @@ public function test_override_task_setting(): void { // Fetch all backup task settings. $rc = new \ReflectionClass(activity_packager::class); $rcmgetbackup = $rc->getMethod('get_backup_controller'); - $rcmgetbackup->setAccessible(true); $controller = $rcmgetbackup->invoke($packager); $rcmgetall = $rc->getMethod('get_all_task_settings'); - $rcmgetall->setAccessible(true); $tasksettings = $rcmgetall->invoke($packager, $controller); // Fetch the default settings and grab an example value (setting_root_users). @@ -80,7 +78,6 @@ public function test_override_task_setting(): void { // Override the setting_root_users value, then re-fetch the settings to check the change is reflected. $overridevalue = ($oldvalue == 1) ? 0 : 1; $rcmoverridesetting = $rc->getMethod('override_task_setting'); - $rcmoverridesetting->setAccessible(true); $rcmoverridesetting->invoke($packager, $tasksettings, $testsettingname, $overridevalue); $tasksettings = $rcmgetall->invoke($packager, $controller); $rootsettings = $tasksettings[\backup_root_task::class]; diff --git a/lib/tests/moodlenet/activity_sender_test.php b/lib/tests/moodlenet/activity_sender_test.php index 3c106b9f569b..352d847f2430 100644 --- a/lib/tests/moodlenet/activity_sender_test.php +++ b/lib/tests/moodlenet/activity_sender_test.php @@ -95,7 +95,6 @@ public function test_prepare_share_contents(): void { // Set get_file method accessibility. $method = new ReflectionMethod(activity_sender::class, 'prepare_share_contents'); - $method->setAccessible(true); // Test with invalid share format. $this->expectException(\moodle_exception::class); @@ -157,7 +156,6 @@ public function test_get_resource_description(): void { // Set get_resource_description method accessibility. $method = new ReflectionMethod(activity_sender::class, 'get_resource_description'); - $method->setAccessible(true); // Test the processed description. $processeddescription = $method->invoke(new activity_sender( diff --git a/lib/tests/moodlenet/course_packager_test.php b/lib/tests/moodlenet/course_packager_test.php index 780cc3655398..96b1e9af1a40 100644 --- a/lib/tests/moodlenet/course_packager_test.php +++ b/lib/tests/moodlenet/course_packager_test.php @@ -49,10 +49,8 @@ public function test_override_task_setting(): void { // Fetch all backup task settings. $rc = new \ReflectionClass(course_packager::class); $rcmgetbackup = $rc->getMethod('get_backup_controller'); - $rcmgetbackup->setAccessible(true); $controller = $rcmgetbackup->invoke($packager); $rcmgetall = $rc->getMethod('get_all_task_settings'); - $rcmgetall->setAccessible(true); $tasksettings = $rcmgetall->invoke($packager, $controller); // Fetch the default settings and grab an example value (setting_root_users). @@ -75,7 +73,6 @@ public function test_override_task_setting(): void { // Override the setting_root_users value, then re-fetch the settings to check the change is reflected. $overridevalue = ($oldvalue == 1) ? 0 : 1; $rcmoverridesetting = $rc->getMethod('override_task_setting'); - $rcmoverridesetting->setAccessible(true); $rcmoverridesetting->invoke($packager, $tasksettings, $testsettingname, $overridevalue); $tasksettings = $rcmgetall->invoke($packager, $controller); $rootsettings = $tasksettings[\backup_root_task::class]; diff --git a/lib/tests/moodlenet/course_partial_packager_test.php b/lib/tests/moodlenet/course_partial_packager_test.php index 996769ee8eb4..d94c42a71f55 100644 --- a/lib/tests/moodlenet/course_partial_packager_test.php +++ b/lib/tests/moodlenet/course_partial_packager_test.php @@ -51,11 +51,9 @@ public function test_remove_unselected_activities(): void { // Fetch all backup task settings. $rc = new \ReflectionClass(course_partial_packager::class); $rcmgetbackup = $rc->getMethod('get_backup_controller'); - $rcmgetbackup->setAccessible(true); $controller = $rcmgetbackup->invoke($packager); $rcmremove = $rc->getMethod('remove_unselected_activities'); - $rcmremove->setAccessible(true); $rcmremove->invoke($packager, $controller); // Fetch all backup task settings for asserting them. diff --git a/lib/tests/moodlenet/course_partial_sender_test.php b/lib/tests/moodlenet/course_partial_sender_test.php index 0fc86fc84e6b..271720e05207 100644 --- a/lib/tests/moodlenet/course_partial_sender_test.php +++ b/lib/tests/moodlenet/course_partial_sender_test.php @@ -95,7 +95,6 @@ public function test_prepare_share_contents(): void { // Set get_file method accessibility. $method = new ReflectionMethod(course_partial_sender::class, 'prepare_share_contents'); - $method->setAccessible(true); $httpclient = new http_client(); $moodlenetclient = new moodlenet_client($httpclient, $this->mockoauthclient); @@ -151,7 +150,6 @@ public function test_get_resource_description(): void { // Set get_resource_description method accessibility. $method = new ReflectionMethod(course_partial_sender::class, 'get_resource_description'); - $method->setAccessible(true); // Test the processed description. $httpclient = new http_client(); diff --git a/lib/tests/moodlenet/course_sender_test.php b/lib/tests/moodlenet/course_sender_test.php index 3827e5fdeaea..c6a9739be979 100644 --- a/lib/tests/moodlenet/course_sender_test.php +++ b/lib/tests/moodlenet/course_sender_test.php @@ -90,7 +90,6 @@ public function test_prepare_share_contents(): void { // Set get_file method accessibility. $method = new ReflectionMethod(course_sender::class, 'prepare_share_contents'); - $method->setAccessible(true); // Test with invalid share format. $this->expectException(\moodle_exception::class); @@ -158,7 +157,6 @@ public function test_get_resource_description(): void { // Set get_resource_description method accessibility. $method = new ReflectionMethod(course_sender::class, 'get_resource_description'); - $method->setAccessible(true); // Test the processed description. $httpclient = new http_client(); diff --git a/lib/tests/myprofilelib_test.php b/lib/tests/myprofilelib_test.php index a444ef28da27..fd7344f484bd 100644 --- a/lib/tests/myprofilelib_test.php +++ b/lib/tests/myprofilelib_test.php @@ -66,7 +66,6 @@ public function test_core_myprofile_navigation_as_admin() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $categories = $reflector->getProperty('categories'); - $categories->setAccessible(true); $cats = $categories->getValue($this->tree); $this->assertArrayHasKey('contact', $cats); $this->assertArrayHasKey('coursedetails', $cats); @@ -76,7 +75,6 @@ public function test_core_myprofile_navigation_as_admin() { $this->assertArrayHasKey('loginactivity', $cats); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('fullprofile', $nodes->getValue($this->tree)); } @@ -92,7 +90,6 @@ public function test_core_myprofile_navigation_course_without_permission() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('fullprofile', $nodes->getValue($this->tree)); } @@ -106,7 +103,6 @@ public function test_core_myprofile_navigation_profile_link_as_current_user() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('editprofile', $nodes->getValue($this->tree)); } @@ -120,7 +116,6 @@ public function test_core_myprofile_navigation_profile_link_as_admin() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('editprofile', $nodes->getValue($this->tree)); } @@ -134,7 +129,6 @@ public function test_core_myprofile_navigation_preference_as_admin() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('preferences', $nodes->getValue($this->tree)); $this->assertArrayHasKey('loginas', $nodes->getValue($this->tree)); } @@ -151,7 +145,6 @@ public function test_core_myprofile_navigation_preference_without_permission() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, $this->course); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('loginas', $nodes->getValue($this->tree)); } @@ -189,7 +182,6 @@ public function test_core_myprofile_navigation_contact_fields_as_admin() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); foreach ($hiddenfields as $field) { $this->assertArrayHasKey($field, $nodes->getValue($this->tree)); } @@ -214,7 +206,6 @@ public function test_core_myprofile_navigation_contact_field_without_permission( core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); foreach ($hiddenfields as $field) { $this->assertArrayNotHasKey($field, $nodes->getValue($this->tree)); } @@ -262,7 +253,6 @@ public function test_core_myprofile_navigation_contact_timezone(string $hiddenus $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); /** @var \core_user\output\myprofile\node[] $tree */ $tree = $nodes->getValue($this->tree); @@ -286,7 +276,6 @@ public function test_core_myprofile_navigation_login_activity() { core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayHasKey('firstaccess', $nodes->getValue($this->tree)); $this->assertArrayHasKey('lastaccess', $nodes->getValue($this->tree)); $this->assertArrayHasKey('lastip', $nodes->getValue($this->tree)); @@ -305,7 +294,6 @@ public function test_core_myprofile_navigationn_login_activity_without_permissio core_myprofile_navigation($this->tree, $this->user, $iscurrentuser, null); $reflector = new \ReflectionObject($this->tree); $nodes = $reflector->getProperty('nodes'); - $nodes->setAccessible(true); $this->assertArrayNotHasKey('firstaccess', $nodes->getValue($this->tree)); $this->assertArrayNotHasKey('lastaccess', $nodes->getValue($this->tree)); $this->assertArrayNotHasKey('lastip', $nodes->getValue($this->tree)); diff --git a/lib/tests/navigation/output/primary_test.php b/lib/tests/navigation/output/primary_test.php index 649ff0cefe92..b542762f6872 100644 --- a/lib/tests/navigation/output/primary_test.php +++ b/lib/tests/navigation/output/primary_test.php @@ -168,7 +168,6 @@ protected function get_custom_menu(string $config): array { $CFG->custommenuitems = $config; $output = new primary($PAGE); $method = new ReflectionMethod('core\navigation\output\primary', 'get_custom_menu'); - $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); // We can't assert the value of each menuitem "moremenuid" property (because it's random). @@ -375,7 +374,6 @@ protected function merge_and_render_menus(?string $url = null, ?bool $ismobile = $primary = new primary($PAGE); $method = new ReflectionMethod('core\navigation\output\primary', 'get_primary_nav'); - $method->setAccessible(true); $dataprimary = $method->invoke($primary); // Take this custom menu that would come from the setting custommenitems. @@ -395,7 +393,6 @@ protected function merge_and_render_menus(?string $url = null, ?bool $ismobile = $datacustom = $this->get_custom_menu($custommenuitems); $method = new ReflectionMethod('core\navigation\output\primary', 'merge_primary_and_custom'); - $method->setAccessible(true); $menucomplete = $method->invoke($primary, $dataprimary, $datacustom, $ismobile); return $menucomplete; } diff --git a/lib/tests/navigation/views/primary_test.php b/lib/tests/navigation/views/primary_test.php index 2551a9031b6c..7e210bb80635 100644 --- a/lib/tests/navigation/views/primary_test.php +++ b/lib/tests/navigation/views/primary_test.php @@ -126,7 +126,6 @@ public function test_search_and_set_active_node(string $expectedkey, ?string $ke $primary = new primary($PAGE); $method = new ReflectionMethod('core\navigation\views\primary', 'search_and_set_active_node'); - $method->setAccessible(true); $result = $method->invoke($primary, $node); diff --git a/lib/tests/navigation/views/secondary_test.php b/lib/tests/navigation/views/secondary_test.php index 619f295293d4..c99253ffd59d 100644 --- a/lib/tests/navigation/views/secondary_test.php +++ b/lib/tests/navigation/views/secondary_test.php @@ -63,7 +63,6 @@ public function test_get_leaf_nodes(float $siteorder, float $courseorder, float ]; $method = new ReflectionMethod('core\navigation\views\secondary', 'get_leaf_nodes'); - $method->setAccessible(true); $sortednodes = $method->invoke($secondary, $secondary, $nodes); foreach ($sortednodes as $order => $node) { $this->assertEquals($expectednodes[$order], $node->key); @@ -216,7 +215,6 @@ public function test_active_node_scan(string $expectedkey, ?string $key = null, $node = $this->get_tree_initilised_to_set_activate($seturl); $secondary = new secondary($PAGE); $method = new ReflectionMethod('core\navigation\views\secondary', 'active_node_scan'); - $method->setAccessible(true); $result = $method->invoke($secondary, $node); @@ -274,7 +272,6 @@ public function test_force_nodes_into_more_menu(array $secondarynavnodesdata, ar } $method = new ReflectionMethod('core\navigation\views\secondary', 'force_nodes_into_more_menu'); - $method->setAccessible(true); $method->invoke($secondary, $defaultmoremenunodes, $maxdisplayednodes); $actualmoremenunodes = []; @@ -465,7 +462,6 @@ public function test_nodes_match_current_url(string $selectedurl, string $expect $PAGE->set_url($selectedurl); $secondary = new secondary($PAGE); $method = new ReflectionMethod('core\navigation\views\secondary', 'nodes_match_current_url'); - $method->setAccessible(true); $response = $method->invoke($secondary, $node); $this->assertSame($response->key ?? null, $expectednode); @@ -630,7 +626,6 @@ public function test_get_node_with_first_action(string $selectedkey, ?string $ex $secondary = new secondary($PAGE); $method = new ReflectionMethod('core\navigation\views\secondary', 'get_node_with_first_action'); - $method->setAccessible(true); $response = $method->invoke($secondary, $selectednode, $selectednode); $this->assertEquals($expected, $response); } @@ -688,7 +683,6 @@ public function test_add_external_nodes_to_secondary(array $structure, array $ex } $method = new ReflectionMethod('core\navigation\views\secondary', 'add_external_nodes_to_secondary'); - $method->setAccessible(true); $method->invoke($secondary, $firstnode, $firstnode, $customparent); $actualnodes = $separatenode ? $customparent->get_children_key_list() : $secondary->get_children_key_list(); @@ -850,12 +844,10 @@ public function test_get_overflow_menu_data(string $selectedurl, bool $expectedn } else { // Set the correct node as active. $method = new ReflectionMethod('core\navigation\views\secondary', 'scan_for_active_node'); - $method->setAccessible(true); $method->invoke($secondary, $secondary); } $method = new ReflectionMethod('core\navigation\views\secondary', 'get_overflow_menu_data'); - $method->setAccessible(true); $response = $method->invoke($secondary); if ($expectednull) { $this->assertNull($response); diff --git a/lib/tests/output/language_menu_test.php b/lib/tests/output/language_menu_test.php index 7587227f8f30..b7f9f82d9304 100644 --- a/lib/tests/output/language_menu_test.php +++ b/lib/tests/output/language_menu_test.php @@ -61,7 +61,6 @@ public function test_get_lang_menu(bool $withadditionallangs, string $language, $output = new language_menu($PAGE); $method = new ReflectionMethod('\core\output\language_menu', 'export_for_template'); - $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); $response = $method->invoke($output, $renderer); diff --git a/lib/tests/output/participants_action_bar_test.php b/lib/tests/output/participants_action_bar_test.php index 6a1468ec5562..9c85e5358fb0 100644 --- a/lib/tests/output/participants_action_bar_test.php +++ b/lib/tests/output/participants_action_bar_test.php @@ -57,7 +57,6 @@ public function test_get_content_for_select($type, $expectedcount, $expecteditem $PAGE->set_context($context); $output = new participants_action_bar($course, $PAGE, null); $method = new ReflectionMethod('\core\output\participants_action_bar', 'get_content_for_select'); - $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); $response = $method->invoke($output, $renderer); diff --git a/lib/tests/outputrequirementslib_test.php b/lib/tests/outputrequirementslib_test.php index 28e8bced8db1..a0d9a8507c69 100644 --- a/lib/tests/outputrequirementslib_test.php +++ b/lib/tests/outputrequirementslib_test.php @@ -155,7 +155,6 @@ public function test_js_fix_url_moodle_url(\moodle_url $moodleurl, int $cfgslash $CFG->slasharguments = $cfgslashargs; $rc = new \ReflectionClass(\page_requirements_manager::class); $rcm = $rc->getMethod('js_fix_url'); - $rcm->setAccessible(true); $requires = new \page_requirements_manager(); $actualmoodleurl = $rcm->invokeArgs($requires, [$moodleurl]); $this->assertEquals($expected, $actualmoodleurl->out(false)); @@ -239,7 +238,6 @@ public function test_js_fix_url_plain_string(string $url, int $cfgslashargs, str $CFG->slasharguments = $cfgslashargs; $rc = new \ReflectionClass(\page_requirements_manager::class); $rcm = $rc->getMethod('js_fix_url'); - $rcm->setAccessible(true); $requires = new \page_requirements_manager(); $actualmoodleurl = $rcm->invokeArgs($requires, [$url]); $this->assertEquals($expected, $actualmoodleurl->out(false)); @@ -316,7 +314,6 @@ public function js_fix_url_plain_string_provider() { public function test_js_fix_url_coding_exception($url, string $exmessage) { $rc = new \ReflectionClass(\page_requirements_manager::class); $rcm = $rc->getMethod('js_fix_url'); - $rcm->setAccessible(true); $requires = new \page_requirements_manager(); $this->expectException(\coding_exception::class); $this->expectExceptionMessage($exmessage); diff --git a/lib/tests/session_manager_test.php b/lib/tests/session_manager_test.php index ad84b7f18cc5..34239875caa4 100644 --- a/lib/tests/session_manager_test.php +++ b/lib/tests/session_manager_test.php @@ -916,7 +916,6 @@ public function array_session_diff_provider() { public function test_array_session_diff(array $a, array $b, array $expected) { $class = new \ReflectionClass('\core\session\manager'); $method = $class->getMethod('array_session_diff'); - $method->setAccessible(true); $result = $method->invokeArgs(null, [$a, $b]); $this->assertSame($expected, $result); diff --git a/lib/tests/session_redis_test.php b/lib/tests/session_redis_test.php index a77a3375f00f..4d5af406a85e 100644 --- a/lib/tests/session_redis_test.php +++ b/lib/tests/session_redis_test.php @@ -368,7 +368,6 @@ public function test_session_redis_encrypt() { $sess = new \core\session\redis(); $prop = new \ReflectionProperty(\core\session\redis::class, 'host'); - $prop->setAccessible(true); $this->assertEquals('tls://' . TEST_SESSION_REDIS_HOST, $prop->getValue($sess)); } } diff --git a/lib/tests/setuplib_test.php b/lib/tests/setuplib_test.php index 0ef30f714a02..75413706af81 100644 --- a/lib/tests/setuplib_test.php +++ b/lib/tests/setuplib_test.php @@ -491,7 +491,6 @@ public function test_core_uuid_generate_uuid_via_pecl_uuid_extension() { // The \core\uuid::generate_uuid_via_pecl_uuid_extension static method is protected. Use Reflection to call the method. $method = new \ReflectionMethod('\core\uuid', 'generate_uuid_via_pecl_uuid_extension'); - $method->setAccessible(true); $uuid = $method->invoke(null); $this->assertTrue(self::is_valid_uuid_v4($uuid), "Invalid v4 uuid: '$uuid'"); } @@ -508,7 +507,6 @@ public function test_core_uuid_generate_uuid_via_random_bytes() { // The \core\uuid::generate_uuid_via_random_bytes static method is protected. Use Reflection to call the method. $method = new \ReflectionMethod('\core\uuid', 'generate_uuid_via_random_bytes'); - $method->setAccessible(true); $uuid = $method->invoke(null); $this->assertTrue(self::is_valid_uuid_v4($uuid), "Invalid v4 uuid: '$uuid'"); } diff --git a/lib/tests/xhprof_test.php b/lib/tests/xhprof_test.php index 60ccbf910db8..43fd556fda69 100644 --- a/lib/tests/xhprof_test.php +++ b/lib/tests/xhprof_test.php @@ -180,7 +180,6 @@ public function test_xhprof_topo_sort(array $rundata, array $expectations) { // Make moodle_xhprofrun::xhprof_topo_sort() accessible. $reflection = new \ReflectionClass('\moodle_xhprofrun'); $method = $reflection->getMethod('xhprof_topo_sort'); - $method->setAccessible(true); // Sort the data. $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); $this->assertIsArray($result); @@ -227,7 +226,6 @@ public function test_reduce_run_data(array $rundata, array $expectations) { // Make moodle_xhprofrun::reduce_run_data() accessible. $reflection = new \ReflectionClass('\moodle_xhprofrun'); $method = $reflection->getMethod('reduce_run_data'); - $method->setAccessible(true); // Reduce the data. $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); $this->assertIsArray($result); diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 5f0ad938744c..79e11d674b37 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -155,7 +155,7 @@ phpmailer PHPMailer Class for sending email using either sendmail, PHP mail(), or SMTP. Methods are based upon the standard AspEmail(tm) classes. - 6.8.0 + 6.9.1 LGPL 2.1 https://github.com/PHPMailer/PHPMailer @@ -365,7 +365,7 @@ All rights reserved. openspout OpenSpout Library to read and write spreadsheet files (CSV, XLSX and ODS). - 4.15.0 + 4.23.0 MIT https://github.com/openspout/openspout diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 10ce896f2a74..1c94bf2a7dbd 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -37,9 +37,9 @@ information provided here is intended especially for developers. - get_attempts_available(): Used to get the number of attempts available for the task. * There is a new DML method $DB->get_fieldset. For some reason, this did not exist even though get_fieldset_select etc. did. * The following callbacks have been migrated to hooks: - - before_standard_html_head() -> core\hook\output\standard_head_html_prepend + - before_standard_html_head() -> core\hook\output\before_standard_head_html_generation * Deprecated PARAM_ types with the exception of PARAM_CLEAN now emit a deprecation exception. These were all deprecated in Moodle 2.0. -* A new \core\deprecated attribute can be used to more clearly describe deprecated methods. +* A new \core\attribute\deprecated attribute can be used to more clearly describe deprecated methods. * A new \core\deprecation class can be used to inspect for deprecated attributes: - `\core\deprecation::is_deprecated(example::class);` - `\core\deprecation::emit_deprecation_if_present([self::class, 'some_method']);` @@ -76,6 +76,20 @@ information provided here is intended especially for developers. as an alternative to implementing the \core\hook\described_hook interface. * The hook API now supports the use of the new \core\attribute\hook\replaces_callbacks() attribute as an alternative to implementing the \core\hook\deprecated_callback_replacement interface. +* The following previously deprecated methods have been removed and can no longer be used: + - `question_preview_url` + - `question_preview_popup_params` + - `question_hash` + - `question_make_export_url` + - `question_get_export_single_question_url` + - `question_remove_stale_questions_from_category` + - `flatten_category_tree` + - `add_indented_names` + - `question_category_select_menu` + - `get_categories_for_contexts` + - `question_category_options` + - `question_add_context_in_key` + - `question_fix_top_names` === 4.3 === diff --git a/lib/weblib.php b/lib/weblib.php index 0cac8cf5e83f..a4e6dbb9cd5c 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -30,6 +30,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use Psr\Http\Message\UriInterface; + defined('MOODLE_INTERNAL') || die(); // Constants. @@ -770,6 +772,26 @@ public function set_slashargument($path, $parameter = 'file', $supported = null) // Static factory methods. + /** + * Create a new moodle_url instance from a UriInterface. + * + * @param UriInterface $uri + * @return self + */ + public static function from_uri(UriInterface $uri): self { + $url = new self( + url: $uri->getScheme() . '://' . $uri->getAuthority() . $uri->getPath(), + anchor: $uri->getFragment() ?: null, + ); + + $params = $uri->getQuery(); + foreach (explode('&', $params) as $param) { + $url->param(...explode('=', $param, 2)); + } + + return $url; + } + /** * General moodle file url. * diff --git a/media/player/videojs/amd/build/video-lazy.min.js b/media/player/videojs/amd/build/video-lazy.min.js index 72bad06d90ad..fd1913983af1 100644 --- a/media/player/videojs/amd/build/video-lazy.min.js +++ b/media/player/videojs/amd/build/video-lazy.min.js @@ -1,6 +1,6 @@ /** * @license - * Video.js 8.3.0 + * Video.js 8.10.0 * Copyright Brightcove, Inc. * Available under Apache License Version 2.0 * @@ -9,7 +9,7 @@ * Available under Apache License Version 2.0 * */ -!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define("media_videojs/video-lazy",factory):(global="undefined"!=typeof globalThis?globalThis:global||self).videojs=factory()}(window,(function(){const hooks_={},hooks=function(type,fn){return hooks_[type]=hooks_[type]||[],fn&&(hooks_[type]=hooks_[type].concat(fn)),hooks_[type]},removeHook=function(type,fn){const index=hooks(type).indexOf(fn);return!(index<=-1)&&(hooks_[type]=hooks_[type].slice(),hooks_[type].splice(index,1),!0)},FullscreenApi={prefixed:!0},apiMap=[["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"]],specApi=apiMap[0];let browserApi;for(let i=0;i(type,level,args)=>{const lvl=log.levels[level],lvlRegExp=new RegExp("^(".concat(lvl,")$"));if("log"!==type&&args.unshift(type.toUpperCase()+":"),args.unshift(name+":"),history){history.push([].concat(args));const splice=history.length-1e3;history.splice(0,splice>0?splice:0)}if(!window.console)return;let fn=window.console[type];fn||"debug"!==type||(fn=window.console.info||window.console.log),fn&&lvl&&lvlRegExp.test(type)&&fn[Array.isArray(args)?"apply":"call"](window.console,args)})(name,log),log.createLogger=subname=>createLogger$1(name+": "+subname),log.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:level},log.level=lvl=>{if("string"==typeof lvl){if(!log.levels.hasOwnProperty(lvl))throw new Error('"'.concat(lvl,'" in not a valid log level'));level=lvl}return level},(log.history=()=>history?[].concat(history):[]).filter=fname=>(history||[]).filter((historyItem=>new RegExp(".*".concat(fname,".*")).test(historyItem[0]))),log.history.clear=()=>{history&&(history.length=0)},log.history.disable=()=>{null!==history&&(history.length=0,history=null)},log.history.enable=()=>{null===history&&(history=[])},log.error=function(){for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++)args[_key3]=arguments[_key3];return logByType("error",level,args)},log.warn=function(){for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++)args[_key4]=arguments[_key4];return logByType("warn",level,args)},log.debug=function(){for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++)args[_key5]=arguments[_key5];return logByType("debug",level,args)},log}("VIDEOJS"),createLogger=log$1.createLogger,toString$1=Object.prototype.toString,keys=function(object){return isObject$1(object)?Object.keys(object):[]};function each(object,fn){keys(object).forEach((key=>fn(object[key],key)))}function reduce(object,fn){let initial=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return keys(object).reduce(((accum,key)=>fn(accum,object[key],key)),initial)}function isObject$1(value){return!!value&&"object"==typeof value}function isPlain(value){return isObject$1(value)&&"[object Object]"===toString$1.call(value)&&value.constructor===Object}function merge$2(){const result={};for(var _len6=arguments.length,sources=new Array(_len6),_key6=0;_key6<_len6;_key6++)sources[_key6]=arguments[_key6];return sources.forEach((source=>{source&&each(source,((value,key)=>{isPlain(value)?(isPlain(result[key])||(result[key]={}),result[key]=merge$2(result[key],value)):result[key]=value}))})),result}function defineLazyProperty(obj,key,getValue){let setter=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const set=value=>Object.defineProperty(obj,key,{value:value,enumerable:!0,writable:!0}),options={configurable:!0,enumerable:!0,get(){const value=getValue();return set(value),value}};return setter&&(options.set=set),Object.defineProperty(obj,key,options)}var Obj=Object.freeze({__proto__:null,each:each,reduce:reduce,isObject:isObject$1,isPlain:isPlain,merge:merge$2,defineLazyProperty:defineLazyProperty});let ANDROID_VERSION,IS_IPOD=!1,IOS_VERSION=null,IS_ANDROID=!1,IS_FIREFOX=!1,IS_EDGE=!1,IS_CHROMIUM=!1,IS_CHROME=!1,CHROMIUM_VERSION=null,CHROME_VERSION=null,IE_VERSION=null,IS_SAFARI=!1,IS_WINDOWS=!1,IS_IPAD=!1,IS_IPHONE=!1;const TOUCH_ENABLED=Boolean(isReal()&&("ontouchstart"in window||window.navigator.maxTouchPoints||window.DocumentTouch&&window.document instanceof window.DocumentTouch)),UAD=window.navigator&&window.navigator.userAgentData;if(UAD&&(IS_ANDROID="Android"===UAD.platform,IS_EDGE=Boolean(UAD.brands.find((b=>"Microsoft Edge"===b.brand))),IS_CHROMIUM=Boolean(UAD.brands.find((b=>"Chromium"===b.brand))),IS_CHROME=!IS_EDGE&&IS_CHROMIUM,CHROMIUM_VERSION=CHROME_VERSION=(UAD.brands.find((b=>"Chromium"===b.brand))||{}).version||null,IS_WINDOWS="Windows"===UAD.platform),!IS_CHROMIUM){const USER_AGENT=window.navigator&&window.navigator.userAgent||"";IS_IPOD=/iPod/i.test(USER_AGENT),IOS_VERSION=function(){const match=USER_AGENT.match(/OS (\d+)_/i);return match&&match[1]?match[1]:null}(),IS_ANDROID=/Android/i.test(USER_AGENT),ANDROID_VERSION=function(){const match=USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!match)return null;const major=match[1]&&parseFloat(match[1]),minor=match[2]&&parseFloat(match[2]);return major&&minor?parseFloat(match[1]+"."+match[2]):major||null}(),IS_FIREFOX=/Firefox/i.test(USER_AGENT),IS_EDGE=/Edg/i.test(USER_AGENT),IS_CHROMIUM=/Chrome/i.test(USER_AGENT)||/CriOS/i.test(USER_AGENT),IS_CHROME=!IS_EDGE&&IS_CHROMIUM,CHROMIUM_VERSION=CHROME_VERSION=function(){const match=USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/);return match&&match[2]?parseFloat(match[2]):null}(),IE_VERSION=function(){const result=/MSIE\s(\d+)\.\d/.exec(USER_AGENT);let version=result&&parseFloat(result[1]);return!version&&/Trident\/7.0/i.test(USER_AGENT)&&/rv:11.0/.test(USER_AGENT)&&(version=11),version}(),IS_SAFARI=/Safari/i.test(USER_AGENT)&&!IS_CHROME&&!IS_ANDROID&&!IS_EDGE,IS_WINDOWS=/Windows/i.test(USER_AGENT),IS_IPAD=/iPad/i.test(USER_AGENT)||IS_SAFARI&&TOUCH_ENABLED&&!/iPhone/i.test(USER_AGENT),IS_IPHONE=/iPhone/i.test(USER_AGENT)&&!IS_IPAD}const IS_IOS=IS_IPHONE||IS_IPAD||IS_IPOD,IS_ANY_SAFARI=(IS_SAFARI||IS_IOS)&&!IS_CHROME;var browser=Object.freeze({__proto__:null,get IS_IPOD(){return IS_IPOD},get IOS_VERSION(){return IOS_VERSION},get IS_ANDROID(){return IS_ANDROID},get ANDROID_VERSION(){return ANDROID_VERSION},get IS_FIREFOX(){return IS_FIREFOX},get IS_EDGE(){return IS_EDGE},get IS_CHROMIUM(){return IS_CHROMIUM},get IS_CHROME(){return IS_CHROME},get CHROMIUM_VERSION(){return CHROMIUM_VERSION},get CHROME_VERSION(){return CHROME_VERSION},get IE_VERSION(){return IE_VERSION},get IS_SAFARI(){return IS_SAFARI},get IS_WINDOWS(){return IS_WINDOWS},get IS_IPAD(){return IS_IPAD},get IS_IPHONE(){return IS_IPHONE},TOUCH_ENABLED:TOUCH_ENABLED,IS_IOS:IS_IOS,IS_ANY_SAFARI:IS_ANY_SAFARI});function isNonBlankString(str){return"string"==typeof str&&Boolean(str.trim())}function isReal(){return document===window.document}function isEl(value){return isObject$1(value)&&1===value.nodeType}function isInFrame(){try{return window.parent!==window.self}catch(x){return!0}}function createQuerier(method){return function(selector,context){if(!isNonBlankString(selector))return document[method](null);isNonBlankString(context)&&(context=document.querySelector(context));const ctx=isEl(context)?context:document;return ctx[method]&&ctx[method](selector)}}function createEl(){let tagName=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",properties=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},content=arguments.length>3?arguments[3]:void 0;const el=document.createElement(tagName);return Object.getOwnPropertyNames(properties).forEach((function(propName){const val=properties[propName];"textContent"===propName?textContent(el,val):el[propName]===val&&"tabIndex"!==propName||(el[propName]=val)})),Object.getOwnPropertyNames(attributes).forEach((function(attrName){el.setAttribute(attrName,attributes[attrName])})),content&&appendContent(el,content),el}function textContent(el,text){return void 0===el.textContent?el.innerText=text:el.textContent=text,el}function prependTo(child,parent){parent.firstChild?parent.insertBefore(child,parent.firstChild):parent.appendChild(child)}function hasClass(element,classToCheck){return function(str){if(str.indexOf(" ")>=0)throw new Error("class has illegal whitespace characters")}(classToCheck),element.classList.contains(classToCheck)}function addClass(element){for(var _len7=arguments.length,classesToAdd=new Array(_len7>1?_len7-1:0),_key7=1;_key7<_len7;_key7++)classesToAdd[_key7-1]=arguments[_key7];return element.classList.add(...classesToAdd.reduce(((prev,current)=>prev.concat(current.split(/\s+/))),[])),element}function removeClass(element){if(!element)return log$1.warn("removeClass was called with an element that doesn't exist"),null;for(var _len8=arguments.length,classesToRemove=new Array(_len8>1?_len8-1:0),_key8=1;_key8<_len8;_key8++)classesToRemove[_key8-1]=arguments[_key8];return element.classList.remove(...classesToRemove.reduce(((prev,current)=>prev.concat(current.split(/\s+/))),[])),element}function toggleClass(element,classToToggle,predicate){return"function"==typeof predicate&&(predicate=predicate(element,classToToggle)),"boolean"!=typeof predicate&&(predicate=void 0),classToToggle.split(/\s+/).forEach((className=>element.classList.toggle(className,predicate))),element}function setAttributes(el,attributes){Object.getOwnPropertyNames(attributes).forEach((function(attrName){const attrValue=attributes[attrName];null==attrValue||!1===attrValue?el.removeAttribute(attrName):el.setAttribute(attrName,!0===attrValue?"":attrValue)}))}function getAttributes(tag){const obj={},knownBooleans=",autoplay,controls,playsinline,loop,muted,default,defaultMuted,";if(tag&&tag.attributes&&tag.attributes.length>0){const attrs=tag.attributes;for(let i=attrs.length-1;i>=0;i--){const attrName=attrs[i].name;let attrVal=attrs[i].value;"boolean"!=typeof tag[attrName]&&-1===knownBooleans.indexOf(","+attrName+",")||(attrVal=null!==attrVal),obj[attrName]=attrVal}}return obj}function getAttribute(el,attribute){return el.getAttribute(attribute)}function setAttribute(el,attribute,value){el.setAttribute(attribute,value)}function removeAttribute(el,attribute){el.removeAttribute(attribute)}function blockTextSelection(){document.body.focus(),document.onselectstart=function(){return!1}}function unblockTextSelection(){document.onselectstart=function(){return!0}}function getBoundingClientRect(el){if(el&&el.getBoundingClientRect&&el.parentNode){const rect=el.getBoundingClientRect(),result={};return["bottom","height","left","right","top","width"].forEach((k=>{void 0!==rect[k]&&(result[k]=rect[k])})),result.height||(result.height=parseFloat(computedStyle(el,"height"))),result.width||(result.width=parseFloat(computedStyle(el,"width"))),result}}function findPosition(el){if(!el||el&&!el.offsetParent)return{left:0,top:0,width:0,height:0};const width=el.offsetWidth,height=el.offsetHeight;let left=0,top=0;for(;el.offsetParent&&el!==document[FullscreenApi.fullscreenElement];)left+=el.offsetLeft,top+=el.offsetTop,el=el.offsetParent;return{left:left,top:top,width:width,height:height}}function getPointerPosition(el,event){const translated={x:0,y:0};if(IS_IOS){let item=el;for(;item&&"html"!==item.nodeName.toLowerCase();){const transform=computedStyle(item,"transform");if(/^matrix/.test(transform)){const values=transform.slice(7,-1).split(/,\s/).map(Number);translated.x+=values[4],translated.y+=values[5]}else if(/^matrix3d/.test(transform)){const values=transform.slice(9,-1).split(/,\s/).map(Number);translated.x+=values[12],translated.y+=values[13]}item=item.parentNode}}const position={},boxTarget=findPosition(event.target),box=findPosition(el),boxW=box.width,boxH=box.height;let offsetY=event.offsetY-(box.top-boxTarget.top),offsetX=event.offsetX-(box.left-boxTarget.left);return event.changedTouches&&(offsetX=event.changedTouches[0].pageX-box.left,offsetY=event.changedTouches[0].pageY+box.top,IS_IOS&&(offsetX-=translated.x,offsetY-=translated.y)),position.y=1-Math.max(0,Math.min(1,offsetY/boxH)),position.x=Math.max(0,Math.min(1,offsetX/boxW)),position}function isTextNode$1(value){return isObject$1(value)&&3===value.nodeType}function emptyEl(el){for(;el.firstChild;)el.removeChild(el.firstChild);return el}function normalizeContent(content){return"function"==typeof content&&(content=content()),(Array.isArray(content)?content:[content]).map((value=>("function"==typeof value&&(value=value()),isEl(value)||isTextNode$1(value)?value:"string"==typeof value&&/\S/.test(value)?document.createTextNode(value):void 0))).filter((value=>value))}function appendContent(el,content){return normalizeContent(content).forEach((node=>el.appendChild(node))),el}function insertContent(el,content){return appendContent(emptyEl(el),content)}function isSingleLeftClick(event){return void 0===event.button&&void 0===event.buttons||(0===event.button&&void 0===event.buttons||("mouseup"===event.type&&0===event.button&&0===event.buttons||0===event.button&&1===event.buttons))}const $=createQuerier("querySelector"),$$=createQuerier("querySelectorAll");function computedStyle(el,prop){if(!el||!prop)return"";if("function"==typeof window.getComputedStyle){let computedStyleValue;try{computedStyleValue=window.getComputedStyle(el)}catch(e){return""}return computedStyleValue?computedStyleValue.getPropertyValue(prop)||computedStyleValue[prop]:""}return""}var Dom=Object.freeze({__proto__:null,isReal:isReal,isEl:isEl,isInFrame:isInFrame,createEl:createEl,textContent:textContent,prependTo:prependTo,hasClass:hasClass,addClass:addClass,removeClass:removeClass,toggleClass:toggleClass,setAttributes:setAttributes,getAttributes:getAttributes,getAttribute:getAttribute,setAttribute:setAttribute,removeAttribute:removeAttribute,blockTextSelection:blockTextSelection,unblockTextSelection:unblockTextSelection,getBoundingClientRect:getBoundingClientRect,findPosition:findPosition,getPointerPosition:getPointerPosition,isTextNode:isTextNode$1,emptyEl:emptyEl,normalizeContent:normalizeContent,appendContent:appendContent,insertContent:insertContent,isSingleLeftClick:isSingleLeftClick,$:$,$$:$$,computedStyle:computedStyle});let videojs$1,_windowLoaded=!1;const autoSetup=function(){if(!1===videojs$1.options.autoSetup)return;const vids=Array.prototype.slice.call(document.getElementsByTagName("video")),audios=Array.prototype.slice.call(document.getElementsByTagName("audio")),divs=Array.prototype.slice.call(document.getElementsByTagName("video-js")),mediaEls=vids.concat(audios,divs);if(mediaEls&&mediaEls.length>0)for(let i=0,e=mediaEls.length;i-1&&(options={passive:!0}),elem.addEventListener(type,data.dispatcher,options)}else elem.attachEvent&&elem.attachEvent("on"+type,data.dispatcher)}function off(elem,type,fn){if(!DomData.has(elem))return;const data=DomData.get(elem);if(!data.handlers)return;if(Array.isArray(type))return _handleMultipleEvents(off,elem,type,fn);const removeType=function(el,t){data.handlers[t]=[],_cleanUpEvents(el,t)};if(void 0===type){for(const t in data.handlers)Object.prototype.hasOwnProperty.call(data.handlers||{},t)&&removeType(elem,t);return}const handlers=data.handlers[type];if(handlers)if(fn){if(fn.guid)for(let n=0;n=wait&&(fn(...arguments),last=now)}},debounce=function(func,wait,immediate){let timeout,context=arguments.length>3&&void 0!==arguments[3]?arguments[3]:window;const cancel=()=>{context.clearTimeout(timeout),timeout=null},debounced=function(){const self=this,args=arguments;let later=function(){timeout=null,later=null,immediate||func.apply(self,args)};!timeout&&immediate&&func.apply(self,args),context.clearTimeout(timeout),timeout=context.setTimeout(later,wait)};return debounced.cancel=cancel,debounced};var Fn=Object.freeze({__proto__:null,UPDATE_REFRESH_INTERVAL:30,bind_:bind_,throttle:throttle,debounce:debounce});let EVENT_MAP;class EventTarget$2{on(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},on(this,type,fn),this.addEventListener=ael}off(type,fn){off(this,type,fn)}one(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},one(this,type,fn),this.addEventListener=ael}any(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},any(this,type,fn),this.addEventListener=ael}trigger(event){const type=event.type||event;"string"==typeof event&&(event={type:type}),event=fixEvent(event),this.allowedEvents_[type]&&this["on"+type]&&this["on"+type](event),trigger(this,event)}queueTrigger(event){EVENT_MAP||(EVENT_MAP=new Map);const type=event.type||event;let map=EVENT_MAP.get(this);map||(map=new Map,EVENT_MAP.set(this,map));const oldTimeout=map.get(type);map.delete(type),window.clearTimeout(oldTimeout);const timeout=window.setTimeout((()=>{map.delete(type),0===map.size&&(map=null,EVENT_MAP.delete(this)),this.trigger(event)}),0);map.set(type,timeout)}}EventTarget$2.prototype.allowedEvents_={},EventTarget$2.prototype.addEventListener=EventTarget$2.prototype.on,EventTarget$2.prototype.removeEventListener=EventTarget$2.prototype.off,EventTarget$2.prototype.dispatchEvent=EventTarget$2.prototype.trigger;const objName=obj=>"function"==typeof obj.name?obj.name():"string"==typeof obj.name?obj.name:obj.name_?obj.name_:obj.constructor&&obj.constructor.name?obj.constructor.name:typeof obj,isEvented=object=>object instanceof EventTarget$2||!!object.eventBusEl_&&["on","one","off","trigger"].every((k=>"function"==typeof object[k])),isValidEventType=type=>"string"==typeof type&&/\S/.test(type)||Array.isArray(type)&&!!type.length,validateTarget=(target,obj,fnName)=>{if(!target||!target.nodeName&&!isEvented(target))throw new Error("Invalid target for ".concat(objName(obj),"#").concat(fnName,"; must be a DOM node or evented object."))},validateEventType=(type,obj,fnName)=>{if(!isValidEventType(type))throw new Error("Invalid event type for ".concat(objName(obj),"#").concat(fnName,"; must be a non-empty string or array."))},validateListener=(listener,obj,fnName)=>{if("function"!=typeof listener)throw new Error("Invalid listener for ".concat(objName(obj),"#").concat(fnName,"; must be a function."))},normalizeListenArgs=(self,args,fnName)=>{const isTargetingSelf=args.length<3||args[0]===self||args[0]===self.eventBusEl_;let target,type,listener;return isTargetingSelf?(target=self.eventBusEl_,args.length>=3&&args.shift(),[type,listener]=args):[target,type,listener]=args,validateTarget(target,self,fnName),validateEventType(type,self,fnName),validateListener(listener,self,fnName),listener=bind_(self,listener),{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}},listen=(target,method,type,listener)=>{validateTarget(target,target,method),target.nodeName?Events[method](target,type,listener):target[method](type,listener)},EventedMixin={on(){for(var _len9=arguments.length,args=new Array(_len9),_key9=0;_key9<_len9;_key9++)args[_key9]=arguments[_key9];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"on");if(listen(target,"on",type,listener),!isTargetingSelf){const removeListenerOnDispose=()=>this.off(target,type,listener);removeListenerOnDispose.guid=listener.guid;const removeRemoverOnTargetDispose=()=>this.off("dispose",removeListenerOnDispose);removeRemoverOnTargetDispose.guid=listener.guid,listen(this,"on","dispose",removeListenerOnDispose),listen(target,"on","dispose",removeRemoverOnTargetDispose)}},one(){for(var _this=this,_len10=arguments.length,args=new Array(_len10),_key10=0;_key10<_len10;_key10++)args[_key10]=arguments[_key10];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"one");if(isTargetingSelf)listen(target,"one",type,listener);else{const wrapper=function(){_this.off(target,type,wrapper);for(var _len11=arguments.length,largs=new Array(_len11),_key11=0;_key11<_len11;_key11++)largs[_key11]=arguments[_key11];listener.apply(null,largs)};wrapper.guid=listener.guid,listen(target,"one",type,wrapper)}},any(){for(var _this2=this,_len12=arguments.length,args=new Array(_len12),_key12=0;_key12<_len12;_key12++)args[_key12]=arguments[_key12];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"any");if(isTargetingSelf)listen(target,"any",type,listener);else{const wrapper=function(){_this2.off(target,type,wrapper);for(var _len13=arguments.length,largs=new Array(_len13),_key13=0;_key13<_len13;_key13++)largs[_key13]=arguments[_key13];listener.apply(null,largs)};wrapper.guid=listener.guid,listen(target,"any",type,wrapper)}},off(targetOrType,typeOrListener,listener){if(!targetOrType||isValidEventType(targetOrType))off(this.eventBusEl_,targetOrType,typeOrListener);else{const target=targetOrType,type=typeOrListener;validateTarget(target,this,"off"),validateEventType(type,this,"off"),validateListener(listener,this,"off"),listener=bind_(this,listener),this.off("dispose",listener),target.nodeName?(off(target,type,listener),off(target,"dispose",listener)):isEvented(target)&&(target.off(type,listener),target.off("dispose",listener))}},trigger(event,hash){validateTarget(this.eventBusEl_,this,"trigger");const type=event&&"string"!=typeof event?event.type:event;if(!isValidEventType(type))throw new Error("Invalid event type for ".concat(objName(this),"#trigger; ")+"must be a non-empty string or object with a type key that has a non-empty value.");return trigger(this.eventBusEl_,event,hash)}};function evented(target){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{eventBusKey:eventBusKey}=options;if(eventBusKey){if(!target[eventBusKey].nodeName)throw new Error('The eventBusKey "'.concat(eventBusKey,'" does not refer to an element.'));target.eventBusEl_=target[eventBusKey]}else target.eventBusEl_=createEl("span",{className:"vjs-event-bus"});return Object.assign(target,EventedMixin),target.eventedCallbacks&&target.eventedCallbacks.forEach((callback=>{callback()})),target.on("dispose",(()=>{target.off(),[target,target.el_,target.eventBusEl_].forEach((function(val){val&&DomData.has(val)&&DomData.delete(val)})),window.setTimeout((()=>{target.eventBusEl_=null}),0)})),target}const StatefulMixin={state:{},setState(stateUpdates){let changes;return"function"==typeof stateUpdates&&(stateUpdates=stateUpdates()),each(stateUpdates,((value,key)=>{this.state[key]!==value&&(changes=changes||{},changes[key]={from:this.state[key],to:value}),this.state[key]=value})),changes&&isEvented(this)&&this.trigger({changes:changes,type:"statechanged"}),changes}};function stateful(target,defaultState){return Object.assign(target,StatefulMixin),target.state=Object.assign({},target.state,defaultState),"function"==typeof target.handleStateChanged&&isEvented(target)&&target.on("statechanged",target.handleStateChanged),target}const toLowerCase=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toLowerCase()))},toTitleCase$1=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toUpperCase()))},titleCaseEquals=function(str1,str2){return toTitleCase$1(str1)===toTitleCase$1(str2)};var Str=Object.freeze({__proto__:null,toLowerCase:toLowerCase,toTitleCase:toTitleCase$1,titleCaseEquals:titleCaseEquals}),commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(fn,module){return fn(module={exports:{}},module.exports),module.exports}var keycode=createCommonjsModule((function(module,exports){function keyCode(searchInput){if(searchInput&&"object"==typeof searchInput){var hasKeyCode=searchInput.which||searchInput.keyCode||searchInput.charCode;hasKeyCode&&(searchInput=hasKeyCode)}if("number"==typeof searchInput)return names[searchInput];var foundNamedKey,search=String(searchInput);return(foundNamedKey=codes[search.toLowerCase()])?foundNamedKey:(foundNamedKey=aliases[search.toLowerCase()])||(1===search.length?search.charCodeAt(0):void 0)}keyCode.isEventKey=function(event,nameOrCode){if(event&&"object"==typeof event){var keyCode=event.which||event.keyCode||event.charCode;if(null==keyCode)return!1;if("string"==typeof nameOrCode){var foundNamedKey;if(foundNamedKey=codes[nameOrCode.toLowerCase()])return foundNamedKey===keyCode;if(foundNamedKey=aliases[nameOrCode.toLowerCase()])return foundNamedKey===keyCode}else if("number"==typeof nameOrCode)return nameOrCode===keyCode;return!1}};var codes=(exports=module.exports=keyCode).code=exports.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},aliases=exports.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(i=97;i<123;i++)codes[String.fromCharCode(i)]=i-32;for(var i=48;i<58;i++)codes[i-48]=i;for(i=1;i<13;i++)codes["f"+i]=i+111;for(i=0;i<10;i++)codes["numpad "+i]=i+96;var names=exports.names=exports.title={};for(i in codes)names[codes[i]]=i;for(var alias in aliases)codes[alias]=aliases[alias]}));keycode.code,keycode.codes,keycode.aliases,keycode.names,keycode.title;class Component$1{constructor(player,options,ready){if(!player&&this.play?this.player_=player=this:this.player_=player,this.isDisposed_=!1,this.parentComponent_=null,this.options_=merge$2({},this.options_),options=this.options_=merge$2(this.options_,options),this.id_=options.id||options.el&&options.el.id,!this.id_){const id=player&&player.id&&player.id()||"no_player";this.id_="".concat(id,"_component_").concat(newGUID())}this.name_=options.name||null,options.el?this.el_=options.el:!1!==options.createEl&&(this.el_=this.createEl()),options.className&&this.el_&&options.className.split(" ").forEach((c=>this.addClass(c))),["on","off","one","any","trigger"].forEach((fn=>{this[fn]=void 0})),!1!==options.evented&&(evented(this,{eventBusKey:this.el_?"el_":null}),this.handleLanguagechange=this.handleLanguagechange.bind(this),this.on(this.player_,"languagechange",this.handleLanguagechange)),stateful(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},this.childNameIndex_={},this.setTimeoutIds_=new Set,this.setIntervalIds_=new Set,this.rafIds_=new Set,this.namedRafs_=new Map,this.clearingTimersOnDispose_=!1,!1!==options.initChildren&&this.initChildren(),this.ready(ready),!1!==options.reportTouchActivity&&this.enableTouchActivity()}on(type,fn){}off(type,fn){}one(type,fn){}any(type,fn){}trigger(event){}dispose(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.isDisposed_){if(this.readyQueue_&&(this.readyQueue_.length=0),this.trigger({type:"dispose",bubbles:!1}),this.isDisposed_=!0,this.children_)for(let i=this.children_.length-1;i>=0;i--)this.children_[i].dispose&&this.children_[i].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&(options.restoreEl?this.el_.parentNode.replaceChild(options.restoreEl,this.el_):this.el_.parentNode.removeChild(this.el_)),this.el_=null),this.player_=null}}isDisposed(){return Boolean(this.isDisposed_)}player(){return this.player_}options(obj){return obj?(this.options_=merge$2(this.options_,obj),this.options_):this.options_}el(){return this.el_}createEl(tagName,properties,attributes){return createEl(tagName,properties,attributes)}localize(string,tokens){let defaultValue=arguments.length>2&&void 0!==arguments[2]?arguments[2]:string;const code=this.player_.language&&this.player_.language(),languages=this.player_.languages&&this.player_.languages(),language=languages&&languages[code],primaryCode=code&&code.split("-")[0],primaryLang=languages&&languages[primaryCode];let localizedString=defaultValue;return language&&language[string]?localizedString=language[string]:primaryLang&&primaryLang[string]&&(localizedString=primaryLang[string]),tokens&&(localizedString=localizedString.replace(/\{(\d+)\}/g,(function(match,index){const value=tokens[index-1];let ret=value;return void 0===value&&(ret=match),ret}))),localizedString}handleLanguagechange(){}contentEl(){return this.contentEl_||this.el_}id(){return this.id_}name(){return this.name_}children(){return this.children_}getChildById(id){return this.childIndex_[id]}getChild(name){if(name)return this.childNameIndex_[name]}getDescendant(){for(var _len14=arguments.length,names=new Array(_len14),_key14=0;_key14<_len14;_key14++)names[_key14]=arguments[_key14];names=names.reduce(((acc,n)=>acc.concat(n)),[]);let currentChild=this;for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:{},index=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.children_.length;if("string"==typeof child){componentName=toTitleCase$1(child);const componentClassName=options.componentClass||componentName;options.name=componentName;const ComponentClass=Component$1.getComponent(componentClassName);if(!ComponentClass)throw new Error("Component ".concat(componentClassName," does not exist"));if("function"!=typeof ComponentClass)return null;component=new ComponentClass(this.player_||this,options)}else component=child;if(component.parentComponent_&&component.parentComponent_.removeChild(component),this.children_.splice(index,0,component),component.parentComponent_=this,"function"==typeof component.id&&(this.childIndex_[component.id()]=component),componentName=componentName||component.name&&toTitleCase$1(component.name()),componentName&&(this.childNameIndex_[componentName]=component,this.childNameIndex_[toLowerCase(componentName)]=component),"function"==typeof component.el&&component.el()){let refNode=null;this.children_[index+1]&&(this.children_[index+1].el_?refNode=this.children_[index+1].el_:isEl(this.children_[index+1])&&(refNode=this.children_[index+1])),this.contentEl().insertBefore(component.el(),refNode)}return component}removeChild(component){if("string"==typeof component&&(component=this.getChild(component)),!component||!this.children_)return;let childFound=!1;for(let i=this.children_.length-1;i>=0;i--)if(this.children_[i]===component){childFound=!0,this.children_.splice(i,1);break}if(!childFound)return;component.parentComponent_=null,this.childIndex_[component.id()]=null,this.childNameIndex_[toTitleCase$1(component.name())]=null,this.childNameIndex_[toLowerCase(component.name())]=null;const compEl=component.el();compEl&&compEl.parentNode===this.contentEl()&&this.contentEl().removeChild(component.el())}initChildren(){const children=this.options_.children;if(children){const parentOptions=this.options_,handleAdd=child=>{const name=child.name;let opts=child.opts;if(void 0!==parentOptions[name]&&(opts=parentOptions[name]),!1===opts)return;!0===opts&&(opts={}),opts.playerOptions=this.options_.playerOptions;const newChild=this.addChild(name,opts);newChild&&(this[name]=newChild)};let workingChildren;const Tech=Component$1.getComponent("Tech");workingChildren=Array.isArray(children)?children:Object.keys(children),workingChildren.concat(Object.keys(this.options_).filter((function(child){return!workingChildren.some((function(wchild){return"string"==typeof wchild?child===wchild:child===wchild.name}))}))).map((child=>{let name,opts;return"string"==typeof child?(name=child,opts=children[name]||this.options_[name]||{}):(name=child.name,opts=child),{name:name,opts:opts}})).filter((child=>{const c=Component$1.getComponent(child.opts.componentClass||toTitleCase$1(child.name));return c&&!Tech.isTech(c)})).forEach(handleAdd)}}buildCSSClass(){return""}ready(fn){let sync=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(fn)return this.isReady_?void(sync?fn.call(this):this.setTimeout(fn,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(fn))}triggerReady(){this.isReady_=!0,this.setTimeout((function(){const readyQueue=this.readyQueue_;this.readyQueue_=[],readyQueue&&readyQueue.length>0&&readyQueue.forEach((function(fn){fn.call(this)}),this),this.trigger("ready")}),1)}$(selector,context){return $(selector,context||this.contentEl())}$$(selector,context){return $$(selector,context||this.contentEl())}hasClass(classToCheck){return hasClass(this.el_,classToCheck)}addClass(){for(var _len15=arguments.length,classesToAdd=new Array(_len15),_key15=0;_key15<_len15;_key15++)classesToAdd[_key15]=arguments[_key15];addClass(this.el_,...classesToAdd)}removeClass(){for(var _len16=arguments.length,classesToRemove=new Array(_len16),_key16=0;_key16<_len16;_key16++)classesToRemove[_key16]=arguments[_key16];removeClass(this.el_,...classesToRemove)}toggleClass(classToToggle,predicate){toggleClass(this.el_,classToToggle,predicate)}show(){this.removeClass("vjs-hidden")}hide(){this.addClass("vjs-hidden")}lockShowing(){this.addClass("vjs-lock-showing")}unlockShowing(){this.removeClass("vjs-lock-showing")}getAttribute(attribute){return getAttribute(this.el_,attribute)}setAttribute(attribute,value){setAttribute(this.el_,attribute,value)}removeAttribute(attribute){removeAttribute(this.el_,attribute)}width(num,skipListeners){return this.dimension("width",num,skipListeners)}height(num,skipListeners){return this.dimension("height",num,skipListeners)}dimensions(width,height){this.width(width,!0),this.height(height)}dimension(widthOrHeight,num,skipListeners){if(void 0!==num)return null!==num&&num==num||(num=0),-1!==(""+num).indexOf("%")||-1!==(""+num).indexOf("px")?this.el_.style[widthOrHeight]=num:this.el_.style[widthOrHeight]="auto"===num?"":num+"px",void(skipListeners||this.trigger("componentresize"));if(!this.el_)return 0;const val=this.el_.style[widthOrHeight],pxIndex=val.indexOf("px");return-1!==pxIndex?parseInt(val.slice(0,pxIndex),10):parseInt(this.el_["offset"+toTitleCase$1(widthOrHeight)],10)}currentDimension(widthOrHeight){let computedWidthOrHeight=0;if("width"!==widthOrHeight&&"height"!==widthOrHeight)throw new Error("currentDimension only accepts width or height value");if(computedWidthOrHeight=computedStyle(this.el_,widthOrHeight),computedWidthOrHeight=parseFloat(computedWidthOrHeight),0===computedWidthOrHeight||isNaN(computedWidthOrHeight)){const rule="offset".concat(toTitleCase$1(widthOrHeight));computedWidthOrHeight=this.el_[rule]}return computedWidthOrHeight}currentDimensions(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}}currentWidth(){return this.currentDimension("width")}currentHeight(){return this.currentDimension("height")}focus(){this.el_.focus()}blur(){this.el_.blur()}handleKeyDown(event){this.player_&&(keycode.isEventKey(event,"Tab")||event.stopPropagation(),this.player_.handleKeyDown(event))}handleKeyPress(event){this.handleKeyDown(event)}emitTapEvents(){let touchStart=0,firstTouch=null;let couldBeTap;this.on("touchstart",(function(event){1===event.touches.length&&(firstTouch={pageX:event.touches[0].pageX,pageY:event.touches[0].pageY},touchStart=window.performance.now(),couldBeTap=!0)})),this.on("touchmove",(function(event){if(event.touches.length>1)couldBeTap=!1;else if(firstTouch){const xdiff=event.touches[0].pageX-firstTouch.pageX,ydiff=event.touches[0].pageY-firstTouch.pageY;Math.sqrt(xdiff*xdiff+ydiff*ydiff)>10&&(couldBeTap=!1)}}));const noTap=function(){couldBeTap=!1};this.on("touchleave",noTap),this.on("touchcancel",noTap),this.on("touchend",(function(event){if(firstTouch=null,!0===couldBeTap){window.performance.now()-touchStart<200&&(event.preventDefault(),this.trigger("tap"))}}))}enableTouchActivity(){if(!this.player()||!this.player().reportUserActivity)return;const report=bind_(this.player(),this.player().reportUserActivity);let touchHolding;this.on("touchstart",(function(){report(),this.clearInterval(touchHolding),touchHolding=this.setInterval(report,250)}));const touchEnd=function(event){report(),this.clearInterval(touchHolding)};this.on("touchmove",report),this.on("touchend",touchEnd),this.on("touchcancel",touchEnd)}setTimeout(fn,timeout){var timeoutId;return fn=bind_(this,fn),this.clearTimersOnDispose_(),timeoutId=window.setTimeout((()=>{this.setTimeoutIds_.has(timeoutId)&&this.setTimeoutIds_.delete(timeoutId),fn()}),timeout),this.setTimeoutIds_.add(timeoutId),timeoutId}clearTimeout(timeoutId){return this.setTimeoutIds_.has(timeoutId)&&(this.setTimeoutIds_.delete(timeoutId),window.clearTimeout(timeoutId)),timeoutId}setInterval(fn,interval){fn=bind_(this,fn),this.clearTimersOnDispose_();const intervalId=window.setInterval(fn,interval);return this.setIntervalIds_.add(intervalId),intervalId}clearInterval(intervalId){return this.setIntervalIds_.has(intervalId)&&(this.setIntervalIds_.delete(intervalId),window.clearInterval(intervalId)),intervalId}requestAnimationFrame(fn){var id;return this.clearTimersOnDispose_(),fn=bind_(this,fn),id=window.requestAnimationFrame((()=>{this.rafIds_.has(id)&&this.rafIds_.delete(id),fn()})),this.rafIds_.add(id),id}requestNamedAnimationFrame(name,fn){if(this.namedRafs_.has(name))return;this.clearTimersOnDispose_(),fn=bind_(this,fn);const id=this.requestAnimationFrame((()=>{fn(),this.namedRafs_.has(name)&&this.namedRafs_.delete(name)}));return this.namedRafs_.set(name,id),name}cancelNamedAnimationFrame(name){this.namedRafs_.has(name)&&(this.cancelAnimationFrame(this.namedRafs_.get(name)),this.namedRafs_.delete(name))}cancelAnimationFrame(id){return this.rafIds_.has(id)&&(this.rafIds_.delete(id),window.cancelAnimationFrame(id)),id}clearTimersOnDispose_(){this.clearingTimersOnDispose_||(this.clearingTimersOnDispose_=!0,this.one("dispose",(()=>{[["namedRafs_","cancelNamedAnimationFrame"],["rafIds_","cancelAnimationFrame"],["setTimeoutIds_","clearTimeout"],["setIntervalIds_","clearInterval"]].forEach((_ref4=>{let[idName,cancelName]=_ref4;this[idName].forEach(((val,key)=>this[cancelName](key)))})),this.clearingTimersOnDispose_=!1})))}static registerComponent(name,ComponentToRegister){if("string"!=typeof name||!name)throw new Error('Illegal component name, "'.concat(name,'"; must be a non-empty string.'));const Tech=Component$1.getComponent("Tech"),isTech=Tech&&Tech.isTech(ComponentToRegister),isComp=Component$1===ComponentToRegister||Component$1.prototype.isPrototypeOf(ComponentToRegister.prototype);if(isTech||!isComp){let reason;throw reason=isTech?"techs must be registered using Tech.registerTech()":"must be a Component subclass",new Error('Illegal component, "'.concat(name,'"; ').concat(reason,"."))}name=toTitleCase$1(name),Component$1.components_||(Component$1.components_={});const Player=Component$1.getComponent("Player");if("Player"===name&&Player&&Player.players){const players=Player.players,playerNames=Object.keys(players);if(players&&playerNames.length>0&&playerNames.map((pname=>players[pname])).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return Component$1.components_[name]=ComponentToRegister,Component$1.components_[toLowerCase(name)]=ComponentToRegister,ComponentToRegister}static getComponent(name){if(name&&Component$1.components_)return Component$1.components_[name]}}function getRange(fnName,valueIndex,ranges,rangeIndex){return function(fnName,index,maxIndex){if("number"!=typeof index||index<0||index>maxIndex)throw new Error("Failed to execute '".concat(fnName,"' on 'TimeRanges': The index provided (").concat(index,") is non-numeric or out of bounds (0-").concat(maxIndex,")."))}(fnName,rangeIndex,ranges.length-1),ranges[rangeIndex][valueIndex]}function createTimeRangesObj(ranges){let timeRangesObj;return timeRangesObj=void 0===ranges||0===ranges.length?{length:0,start(){throw new Error("This TimeRanges object is empty")},end(){throw new Error("This TimeRanges object is empty")}}:{length:ranges.length,start:getRange.bind(null,"start",0,ranges),end:getRange.bind(null,"end",1,ranges)},window.Symbol&&window.Symbol.iterator&&(timeRangesObj[window.Symbol.iterator]=()=>(ranges||[]).values()),timeRangesObj}function createTimeRanges$1(start,end){return Array.isArray(start)?createTimeRangesObj(start):void 0===start||void 0===end?createTimeRangesObj():createTimeRangesObj([[start,end]])}Component$1.registerComponent("Component",Component$1);const defaultImplementation=function(seconds,guide){seconds=seconds<0?0:seconds;let s=Math.floor(seconds%60),m=Math.floor(seconds/60%60),h=Math.floor(seconds/3600);const gm=Math.floor(guide/60%60),gh=Math.floor(guide/3600);return(isNaN(seconds)||seconds===1/0)&&(h=m=s="-"),h=h>0||gh>0?h+":":"",m=((h||gm>=10)&&m<10?"0"+m:m)+":",s=s<10?"0"+s:s,h+m+s};let implementation=defaultImplementation;function setFormatTime(customImplementation){implementation=customImplementation}function resetFormatTime(){implementation=defaultImplementation}function formatTime(seconds){let guide=arguments.length>1&&void 0!==arguments[1]?arguments[1]:seconds;return implementation(seconds,guide)}var Time=Object.freeze({__proto__:null,createTimeRanges:createTimeRanges$1,createTimeRange:createTimeRanges$1,setFormatTime:setFormatTime,resetFormatTime:resetFormatTime,formatTime:formatTime});function bufferedPercent(buffered,duration){let start,end,bufferedDuration=0;if(!duration)return 0;buffered&&buffered.length||(buffered=createTimeRanges$1(0,0));for(let i=0;iduration&&(end=duration),bufferedDuration+=end-start;return bufferedDuration/duration}function MediaError(value){if(value instanceof MediaError)return value;"number"==typeof value?this.code=value:"string"==typeof value?this.message=value:isObject$1(value)&&("number"==typeof value.code&&(this.code=value.code),Object.assign(this,value)),this.message||(this.message=MediaError.defaultMessages[this.code]||"")}MediaError.prototype.code=0,MediaError.prototype.message="",MediaError.prototype.status=null,MediaError.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],MediaError.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(let errNum=0;errNum{}))}const trackToJson_=function(track){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(((acc,prop,i)=>(track[prop]&&(acc[prop]=track[prop]),acc)),{cues:track.cues&&Array.prototype.map.call(track.cues,(function(cue){return{startTime:cue.startTime,endTime:cue.endTime,text:cue.text,id:cue.id}}))})};var textTrackConverter_textTracksToJson=function(tech){const trackEls=tech.$$("track"),trackObjs=Array.prototype.map.call(trackEls,(t=>t.track));return Array.prototype.map.call(trackEls,(function(trackEl){const json=trackToJson_(trackEl.track);return trackEl.src&&(json.src=trackEl.src),json})).concat(Array.prototype.filter.call(tech.textTracks(),(function(track){return-1===trackObjs.indexOf(track)})).map(trackToJson_))},textTrackConverter_jsonToTextTracks=function(json,tech){return json.forEach((function(track){const addedTrack=tech.addRemoteTextTrack(track).track;!track.src&&track.cues&&track.cues.forEach((cue=>addedTrack.addCue(cue)))})),tech.textTracks()};class ModalDialog extends Component$1{constructor(player,options){super(player,options),this.handleKeyDown_=e=>this.handleKeyDown(e),this.close_=e=>this.close(e),this.opened_=this.hasBeenOpened_=this.hasBeenFilled_=!1,this.closeable(!this.options_.uncloseable),this.content(this.options_.content),this.contentEl_=createEl("div",{className:"".concat("vjs-modal-dialog","-content")},{role:"document"}),this.descEl_=createEl("p",{className:"".concat("vjs-modal-dialog","-description vjs-control-text"),id:this.el().getAttribute("aria-describedby")}),textContent(this.descEl_,this.description()),this.el_.appendChild(this.descEl_),this.el_.appendChild(this.contentEl_)}createEl(){return super.createEl("div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":"".concat(this.id(),"_description"),"aria-hidden":"true","aria-label":this.label(),role:"dialog"})}dispose(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,super.dispose()}buildCSSClass(){return"".concat("vjs-modal-dialog"," vjs-hidden ").concat(super.buildCSSClass())}label(){return this.localize(this.options_.label||"Modal Window")}description(){let desc=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(desc+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),desc}open(){if(!this.opened_){const player=this.player();this.trigger("beforemodalopen"),this.opened_=!0,(this.options_.fillAlways||!this.hasBeenOpened_&&!this.hasBeenFilled_)&&this.fill(),this.wasPlaying_=!player.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&player.pause(),this.on("keydown",this.handleKeyDown_),this.hadControls_=player.controls(),player.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0}}opened(value){return"boolean"==typeof value&&this[value?"open":"close"](),this.opened_}close(){if(!this.opened_)return;const player=this.player();this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&player.play(),this.off("keydown",this.handleKeyDown_),this.hadControls_&&player.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose()}closeable(value){if("boolean"==typeof value){const closeable=this.closeable_=!!value;let close=this.getChild("closeButton");if(closeable&&!close){const temp=this.contentEl_;this.contentEl_=this.el_,close=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=temp,this.on(close,"close",this.close_)}!closeable&&close&&(this.off(close,"close",this.close_),this.removeChild(close),close.dispose())}return this.closeable_}fill(){this.fillWith(this.content())}fillWith(content){const contentEl=this.contentEl(),parentEl=contentEl.parentNode,nextSiblingEl=contentEl.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,parentEl.removeChild(contentEl),this.empty(),insertContent(contentEl,content),this.trigger("modalfill"),nextSiblingEl?parentEl.insertBefore(contentEl,nextSiblingEl):parentEl.appendChild(contentEl);const closeButton=this.getChild("closeButton");closeButton&&parentEl.appendChild(closeButton.el_)}empty(){this.trigger("beforemodalempty"),emptyEl(this.contentEl()),this.trigger("modalempty")}content(value){return void 0!==value&&(this.content_=value),this.content_}conditionalFocus_(){const activeEl=document.activeElement,playerEl=this.player_.el_;this.previouslyActiveEl_=null,(playerEl.contains(activeEl)||playerEl===activeEl)&&(this.previouslyActiveEl_=activeEl,this.focus())}conditionalBlur_(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)}handleKeyDown(event){if(event.stopPropagation(),keycode.isEventKey(event,"Escape")&&this.closeable())return event.preventDefault(),void this.close();if(!keycode.isEventKey(event,"Tab"))return;const focusableEls=this.focusableEls_(),activeEl=this.el_.querySelector(":focus");let focusIndex;for(let i=0;i(child instanceof window.HTMLAnchorElement||child instanceof window.HTMLAreaElement)&&child.hasAttribute("href")||(child instanceof window.HTMLInputElement||child instanceof window.HTMLSelectElement||child instanceof window.HTMLTextAreaElement||child instanceof window.HTMLButtonElement)&&!child.hasAttribute("disabled")||child instanceof window.HTMLIFrameElement||child instanceof window.HTMLObjectElement||child instanceof window.HTMLEmbedElement||child.hasAttribute("tabindex")&&-1!==child.getAttribute("tabindex")||child.hasAttribute("contenteditable")))}}ModalDialog.prototype.options_={pauseOnOpen:!0,temporary:!0},Component$1.registerComponent("ModalDialog",ModalDialog);class TrackList extends EventTarget$2{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];super(),this.tracks_=[],Object.defineProperty(this,"length",{get(){return this.tracks_.length}});for(let i=0;i{this.trigger({track:track,type:"labelchange",target:this})},isEvented(track)&&track.addEventListener("labelchange",track.labelchange_)}removeTrack(rtrack){let track;for(let i=0,l=this.length;ithis.queueTrigger("change")),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=()=>this.trigger("selectedlanguagechange")),track.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(track.kind)&&track.addEventListener("modechange",this.triggerSelectedlanguagechange_)}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&(this.queueChange_&&rtrack.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&rtrack.removeEventListener("modechange",this.triggerSelectedlanguagechange_))}}class TextTrackCueList{constructor(cues){TextTrackCueList.prototype.setCues_.call(this,cues),Object.defineProperty(this,"length",{get(){return this.length_}})}setCues_(cues){const oldLength=this.length||0;let i=0;const l=cues.length;this.cues_=cues,this.length_=cues.length;const defineProp=function(index){""+index in this||Object.defineProperty(this,""+index,{get(){return this.cues_[index]}})};if(oldLength0&&void 0!==arguments[0]?arguments[0]:{};super();const trackProps={id:options.id||"vjs_track_"+newGUID(),kind:options.kind||"",language:options.language||""};let label=options.label||"";for(const key in trackProps)Object.defineProperty(this,key,{get:()=>trackProps[key],set(){}});Object.defineProperty(this,"label",{get:()=>label,set(newLabel){newLabel!==label&&(label=newLabel,this.trigger("labelchange"))}})}}const parseUrl=function(url){const props=["protocol","hostname","port","pathname","search","hash","host"],a=document.createElement("a");a.href=url;const details={};for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:window.location;const urlInfo=parseUrl(url),srcProtocol=":"===urlInfo.protocol?winLoc.protocol:urlInfo.protocol,crossOrigin=srcProtocol+urlInfo.host!==winLoc.protocol+winLoc.host;return crossOrigin};var x,Url=Object.freeze({__proto__:null,parseUrl:parseUrl,getAbsoluteURL:getAbsoluteURL,getFileExtension:getFileExtension,isCrossOrigin:isCrossOrigin}),window_1="undefined"!=typeof window?window:void 0!==commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{},_extends_1=createCommonjsModule((function(module){function _extends(){return module.exports=_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i=400&&response.statusCode<=599){var cause=responseBody;if(decodeResponseBody)if(window_1.TextDecoder){var charset=function(contentTypeHeader){void 0===contentTypeHeader&&(contentTypeHeader="");return contentTypeHeader.toLowerCase().split(";").reduce((function(charset,contentType){var _contentType$split=contentType.split("="),type=_contentType$split[0],value=_contentType$split[1];return"charset"===type.trim()?value.trim():charset}),"utf-8")}(response.headers&&response.headers["content-type"]);try{cause=new TextDecoder(charset).decode(responseBody)}catch(e){}}else cause=String.fromCharCode.apply(null,new Uint8Array(responseBody));callback({cause:cause})}else callback(null,responseBody)}};createXHR.httpHandler=httpHandler; +!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define("media_videojs/video-lazy",factory):(global="undefined"!=typeof globalThis?globalThis:global||self).videojs=factory()}(window,(function(){const hooks_={},hooks=function(type,fn){return hooks_[type]=hooks_[type]||[],fn&&(hooks_[type]=hooks_[type].concat(fn)),hooks_[type]},removeHook=function(type,fn){const index=hooks(type).indexOf(fn);return!(index<=-1)&&(hooks_[type]=hooks_[type].slice(),hooks_[type].splice(index,1),!0)},FullscreenApi={prefixed:!0},apiMap=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror","fullscreen"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror","-webkit-full-screen"]],specApi=apiMap[0];let browserApi;for(let i=0;i(type,level,args)=>{const lvl=log.levels[level],lvlRegExp=new RegExp("^(".concat(lvl,")$"));let resultName=name;if("log"!==type&&args.unshift(type.toUpperCase()+":"),styles&&(resultName="%c".concat(name),args.unshift(styles)),args.unshift(resultName+":"),history){history.push([].concat(args));const splice=history.length-1e3;history.splice(0,splice>0?splice:0)}if(!window.console)return;let fn=window.console[type];fn||"debug"!==type||(fn=window.console.info||window.console.log),fn&&lvl&&lvlRegExp.test(type)&&fn[Array.isArray(args)?"apply":"call"](window.console,args)};const log$1=function createLogger$1(name){let logByType,delimiter=arguments.length>1&&void 0!==arguments[1]?arguments[1]:":",styles=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",level="info";const log=function(){for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++)args[_key2]=arguments[_key2];logByType("log",level,args)};return logByType=LogByTypeFactory(name,log,styles),log.createLogger=(subName,subDelimiter,subStyles)=>{const resultDelimiter=void 0!==subDelimiter?subDelimiter:delimiter,resultStyles=void 0!==subStyles?subStyles:styles;return createLogger$1("".concat(name," ").concat(resultDelimiter," ").concat(subName),resultDelimiter,resultStyles)},log.createNewLogger=(newName,newDelimiter,newStyles)=>createLogger$1(newName,newDelimiter,newStyles),log.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:level},log.level=lvl=>{if("string"==typeof lvl){if(!log.levels.hasOwnProperty(lvl))throw new Error('"'.concat(lvl,'" in not a valid log level'));level=lvl}return level},log.history=()=>history?[].concat(history):[],log.history.filter=fname=>(history||[]).filter((historyItem=>new RegExp(".*".concat(fname,".*")).test(historyItem[0]))),log.history.clear=()=>{history&&(history.length=0)},log.history.disable=()=>{null!==history&&(history.length=0,history=null)},log.history.enable=()=>{null===history&&(history=[])},log.error=function(){for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++)args[_key3]=arguments[_key3];return logByType("error",level,args)},log.warn=function(){for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++)args[_key4]=arguments[_key4];return logByType("warn",level,args)},log.debug=function(){for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++)args[_key5]=arguments[_key5];return logByType("debug",level,args)},log}("VIDEOJS"),createLogger=log$1.createLogger,toString$1=Object.prototype.toString,keys=function(object){return isObject$1(object)?Object.keys(object):[]};function each(object,fn){keys(object).forEach((key=>fn(object[key],key)))}function reduce(object,fn){let initial=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return keys(object).reduce(((accum,key)=>fn(accum,object[key],key)),initial)}function isObject$1(value){return!!value&&"object"==typeof value}function isPlain(value){return isObject$1(value)&&"[object Object]"===toString$1.call(value)&&value.constructor===Object}function merge$2(){const result={};for(var _len6=arguments.length,sources=new Array(_len6),_key6=0;_key6<_len6;_key6++)sources[_key6]=arguments[_key6];return sources.forEach((source=>{source&&each(source,((value,key)=>{isPlain(value)?(isPlain(result[key])||(result[key]={}),result[key]=merge$2(result[key],value)):result[key]=value}))})),result}function values$1(){let source=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const result=[];for(const key in source)if(source.hasOwnProperty(key)){const value=source[key];result.push(value)}return result}function defineLazyProperty(obj,key,getValue){let setter=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const set=value=>Object.defineProperty(obj,key,{value:value,enumerable:!0,writable:!0}),options={configurable:!0,enumerable:!0,get(){const value=getValue();return set(value),value}};return setter&&(options.set=set),Object.defineProperty(obj,key,options)}var Obj=Object.freeze({__proto__:null,each:each,reduce:reduce,isObject:isObject$1,isPlain:isPlain,merge:merge$2,values:values$1,defineLazyProperty:defineLazyProperty});let ANDROID_VERSION,IS_IPOD=!1,IOS_VERSION=null,IS_ANDROID=!1,IS_FIREFOX=!1,IS_EDGE=!1,IS_CHROMIUM=!1,IS_CHROME=!1,CHROMIUM_VERSION=null,CHROME_VERSION=null,IE_VERSION=null,IS_SAFARI=!1,IS_WINDOWS=!1,IS_IPAD=!1,IS_IPHONE=!1;const TOUCH_ENABLED=Boolean(isReal()&&("ontouchstart"in window||window.navigator.maxTouchPoints||window.DocumentTouch&&window.document instanceof window.DocumentTouch)),UAD=window.navigator&&window.navigator.userAgentData;if(UAD&&UAD.platform&&UAD.brands&&(IS_ANDROID="Android"===UAD.platform,IS_EDGE=Boolean(UAD.brands.find((b=>"Microsoft Edge"===b.brand))),IS_CHROMIUM=Boolean(UAD.brands.find((b=>"Chromium"===b.brand))),IS_CHROME=!IS_EDGE&&IS_CHROMIUM,CHROMIUM_VERSION=CHROME_VERSION=(UAD.brands.find((b=>"Chromium"===b.brand))||{}).version||null,IS_WINDOWS="Windows"===UAD.platform),!IS_CHROMIUM){const USER_AGENT=window.navigator&&window.navigator.userAgent||"";IS_IPOD=/iPod/i.test(USER_AGENT),IOS_VERSION=function(){const match=USER_AGENT.match(/OS (\d+)_/i);return match&&match[1]?match[1]:null}(),IS_ANDROID=/Android/i.test(USER_AGENT),ANDROID_VERSION=function(){const match=USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!match)return null;const major=match[1]&&parseFloat(match[1]),minor=match[2]&&parseFloat(match[2]);return major&&minor?parseFloat(match[1]+"."+match[2]):major||null}(),IS_FIREFOX=/Firefox/i.test(USER_AGENT),IS_EDGE=/Edg/i.test(USER_AGENT),IS_CHROMIUM=/Chrome/i.test(USER_AGENT)||/CriOS/i.test(USER_AGENT),IS_CHROME=!IS_EDGE&&IS_CHROMIUM,CHROMIUM_VERSION=CHROME_VERSION=function(){const match=USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/);return match&&match[2]?parseFloat(match[2]):null}(),IE_VERSION=function(){const result=/MSIE\s(\d+)\.\d/.exec(USER_AGENT);let version=result&&parseFloat(result[1]);return!version&&/Trident\/7.0/i.test(USER_AGENT)&&/rv:11.0/.test(USER_AGENT)&&(version=11),version}(),IS_SAFARI=/Safari/i.test(USER_AGENT)&&!IS_CHROME&&!IS_ANDROID&&!IS_EDGE,IS_WINDOWS=/Windows/i.test(USER_AGENT),IS_IPAD=/iPad/i.test(USER_AGENT)||IS_SAFARI&&TOUCH_ENABLED&&!/iPhone/i.test(USER_AGENT),IS_IPHONE=/iPhone/i.test(USER_AGENT)&&!IS_IPAD}const IS_IOS=IS_IPHONE||IS_IPAD||IS_IPOD,IS_ANY_SAFARI=(IS_SAFARI||IS_IOS)&&!IS_CHROME;var browser=Object.freeze({__proto__:null,get IS_IPOD(){return IS_IPOD},get IOS_VERSION(){return IOS_VERSION},get IS_ANDROID(){return IS_ANDROID},get ANDROID_VERSION(){return ANDROID_VERSION},get IS_FIREFOX(){return IS_FIREFOX},get IS_EDGE(){return IS_EDGE},get IS_CHROMIUM(){return IS_CHROMIUM},get IS_CHROME(){return IS_CHROME},get CHROMIUM_VERSION(){return CHROMIUM_VERSION},get CHROME_VERSION(){return CHROME_VERSION},get IE_VERSION(){return IE_VERSION},get IS_SAFARI(){return IS_SAFARI},get IS_WINDOWS(){return IS_WINDOWS},get IS_IPAD(){return IS_IPAD},get IS_IPHONE(){return IS_IPHONE},TOUCH_ENABLED:TOUCH_ENABLED,IS_IOS:IS_IOS,IS_ANY_SAFARI:IS_ANY_SAFARI});function isNonBlankString(str){return"string"==typeof str&&Boolean(str.trim())}function isReal(){return document===window.document}function isEl(value){return isObject$1(value)&&1===value.nodeType}function isInFrame(){try{return window.parent!==window.self}catch(x){return!0}}function createQuerier(method){return function(selector,context){if(!isNonBlankString(selector))return document[method](null);isNonBlankString(context)&&(context=document.querySelector(context));const ctx=isEl(context)?context:document;return ctx[method]&&ctx[method](selector)}}function createEl(){let tagName=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",properties=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},content=arguments.length>3?arguments[3]:void 0;const el=document.createElement(tagName);return Object.getOwnPropertyNames(properties).forEach((function(propName){const val=properties[propName];"textContent"===propName?textContent(el,val):el[propName]===val&&"tabIndex"!==propName||(el[propName]=val)})),Object.getOwnPropertyNames(attributes).forEach((function(attrName){el.setAttribute(attrName,attributes[attrName])})),content&&appendContent(el,content),el}function textContent(el,text){return void 0===el.textContent?el.innerText=text:el.textContent=text,el}function prependTo(child,parent){parent.firstChild?parent.insertBefore(child,parent.firstChild):parent.appendChild(child)}function hasClass(element,classToCheck){return function(str){if(str.indexOf(" ")>=0)throw new Error("class has illegal whitespace characters")}(classToCheck),element.classList.contains(classToCheck)}function addClass(element){for(var _len7=arguments.length,classesToAdd=new Array(_len7>1?_len7-1:0),_key7=1;_key7<_len7;_key7++)classesToAdd[_key7-1]=arguments[_key7];return element.classList.add(...classesToAdd.reduce(((prev,current)=>prev.concat(current.split(/\s+/))),[])),element}function removeClass(element){if(!element)return log$1.warn("removeClass was called with an element that doesn't exist"),null;for(var _len8=arguments.length,classesToRemove=new Array(_len8>1?_len8-1:0),_key8=1;_key8<_len8;_key8++)classesToRemove[_key8-1]=arguments[_key8];return element.classList.remove(...classesToRemove.reduce(((prev,current)=>prev.concat(current.split(/\s+/))),[])),element}function toggleClass(element,classToToggle,predicate){return"function"==typeof predicate&&(predicate=predicate(element,classToToggle)),"boolean"!=typeof predicate&&(predicate=void 0),classToToggle.split(/\s+/).forEach((className=>element.classList.toggle(className,predicate))),element}function setAttributes(el,attributes){Object.getOwnPropertyNames(attributes).forEach((function(attrName){const attrValue=attributes[attrName];null==attrValue||!1===attrValue?el.removeAttribute(attrName):el.setAttribute(attrName,!0===attrValue?"":attrValue)}))}function getAttributes(tag){const obj={},knownBooleans=["autoplay","controls","playsinline","loop","muted","default","defaultMuted"];if(tag&&tag.attributes&&tag.attributes.length>0){const attrs=tag.attributes;for(let i=attrs.length-1;i>=0;i--){const attrName=attrs[i].name;let attrVal=attrs[i].value;knownBooleans.includes(attrName)&&(attrVal=null!==attrVal),obj[attrName]=attrVal}}return obj}function getAttribute(el,attribute){return el.getAttribute(attribute)}function setAttribute(el,attribute,value){el.setAttribute(attribute,value)}function removeAttribute(el,attribute){el.removeAttribute(attribute)}function blockTextSelection(){document.body.focus(),document.onselectstart=function(){return!1}}function unblockTextSelection(){document.onselectstart=function(){return!0}}function getBoundingClientRect(el){if(el&&el.getBoundingClientRect&&el.parentNode){const rect=el.getBoundingClientRect(),result={};return["bottom","height","left","right","top","width"].forEach((k=>{void 0!==rect[k]&&(result[k]=rect[k])})),result.height||(result.height=parseFloat(computedStyle(el,"height"))),result.width||(result.width=parseFloat(computedStyle(el,"width"))),result}}function findPosition(el){if(!el||el&&!el.offsetParent)return{left:0,top:0,width:0,height:0};const width=el.offsetWidth,height=el.offsetHeight;let left=0,top=0;for(;el.offsetParent&&el!==document[FullscreenApi.fullscreenElement];)left+=el.offsetLeft,top+=el.offsetTop,el=el.offsetParent;return{left:left,top:top,width:width,height:height}}function getPointerPosition(el,event){const translated={x:0,y:0};if(IS_IOS){let item=el;for(;item&&"html"!==item.nodeName.toLowerCase();){const transform=computedStyle(item,"transform");if(/^matrix/.test(transform)){const values=transform.slice(7,-1).split(/,\s/).map(Number);translated.x+=values[4],translated.y+=values[5]}else if(/^matrix3d/.test(transform)){const values=transform.slice(9,-1).split(/,\s/).map(Number);translated.x+=values[12],translated.y+=values[13]}item=item.parentNode}}const position={},boxTarget=findPosition(event.target),box=findPosition(el),boxW=box.width,boxH=box.height;let offsetY=event.offsetY-(box.top-boxTarget.top),offsetX=event.offsetX-(box.left-boxTarget.left);return event.changedTouches&&(offsetX=event.changedTouches[0].pageX-box.left,offsetY=event.changedTouches[0].pageY+box.top,IS_IOS&&(offsetX-=translated.x,offsetY-=translated.y)),position.y=1-Math.max(0,Math.min(1,offsetY/boxH)),position.x=Math.max(0,Math.min(1,offsetX/boxW)),position}function isTextNode$1(value){return isObject$1(value)&&3===value.nodeType}function emptyEl(el){for(;el.firstChild;)el.removeChild(el.firstChild);return el}function normalizeContent(content){return"function"==typeof content&&(content=content()),(Array.isArray(content)?content:[content]).map((value=>("function"==typeof value&&(value=value()),isEl(value)||isTextNode$1(value)?value:"string"==typeof value&&/\S/.test(value)?document.createTextNode(value):void 0))).filter((value=>value))}function appendContent(el,content){return normalizeContent(content).forEach((node=>el.appendChild(node))),el}function insertContent(el,content){return appendContent(emptyEl(el),content)}function isSingleLeftClick(event){return void 0===event.button&&void 0===event.buttons||(0===event.button&&void 0===event.buttons||("mouseup"===event.type&&0===event.button&&0===event.buttons||0===event.button&&1===event.buttons))}const $=createQuerier("querySelector"),$$=createQuerier("querySelectorAll");function computedStyle(el,prop){if(!el||!prop)return"";if("function"==typeof window.getComputedStyle){let computedStyleValue;try{computedStyleValue=window.getComputedStyle(el)}catch(e){return""}return computedStyleValue?computedStyleValue.getPropertyValue(prop)||computedStyleValue[prop]:""}return""}function copyStyleSheetsToWindow(win){[...document.styleSheets].forEach((styleSheet=>{try{const cssRules=[...styleSheet.cssRules].map((rule=>rule.cssText)).join(""),style=document.createElement("style");style.textContent=cssRules,win.document.head.appendChild(style)}catch(e){const link=document.createElement("link");link.rel="stylesheet",link.type=styleSheet.type,link.media=styleSheet.media.mediaText,link.href=styleSheet.href,win.document.head.appendChild(link)}}))}var Dom=Object.freeze({__proto__:null,isReal:isReal,isEl:isEl,isInFrame:isInFrame,createEl:createEl,textContent:textContent,prependTo:prependTo,hasClass:hasClass,addClass:addClass,removeClass:removeClass,toggleClass:toggleClass,setAttributes:setAttributes,getAttributes:getAttributes,getAttribute:getAttribute,setAttribute:setAttribute,removeAttribute:removeAttribute,blockTextSelection:blockTextSelection,unblockTextSelection:unblockTextSelection,getBoundingClientRect:getBoundingClientRect,findPosition:findPosition,getPointerPosition:getPointerPosition,isTextNode:isTextNode$1,emptyEl:emptyEl,normalizeContent:normalizeContent,appendContent:appendContent,insertContent:insertContent,isSingleLeftClick:isSingleLeftClick,$:$,$$:$$,computedStyle:computedStyle,copyStyleSheetsToWindow:copyStyleSheetsToWindow});let videojs$1,_windowLoaded=!1;const autoSetup=function(){if(!1===videojs$1.options.autoSetup)return;const vids=Array.prototype.slice.call(document.getElementsByTagName("video")),audios=Array.prototype.slice.call(document.getElementsByTagName("audio")),divs=Array.prototype.slice.call(document.getElementsByTagName("video-js")),mediaEls=vids.concat(audios,divs);if(mediaEls&&mediaEls.length>0)for(let i=0,e=mediaEls.length;i-1&&(options={passive:!0}),elem.addEventListener(type,data.dispatcher,options)}else elem.attachEvent&&elem.attachEvent("on"+type,data.dispatcher)}function off(elem,type,fn){if(!DomData.has(elem))return;const data=DomData.get(elem);if(!data.handlers)return;if(Array.isArray(type))return _handleMultipleEvents(off,elem,type,fn);const removeType=function(el,t){data.handlers[t]=[],_cleanUpEvents(el,t)};if(void 0===type){for(const t in data.handlers)Object.prototype.hasOwnProperty.call(data.handlers||{},t)&&removeType(elem,t);return}const handlers=data.handlers[type];if(handlers)if(fn){if(fn.guid)for(let n=0;n=wait&&(fn(...arguments),last=now)}},debounce=function(func,wait,immediate){let timeout,context=arguments.length>3&&void 0!==arguments[3]?arguments[3]:window;const cancel=()=>{context.clearTimeout(timeout),timeout=null},debounced=function(){const self=this,args=arguments;let later=function(){timeout=null,later=null,immediate||func.apply(self,args)};!timeout&&immediate&&func.apply(self,args),context.clearTimeout(timeout),timeout=context.setTimeout(later,wait)};return debounced.cancel=cancel,debounced};var Fn=Object.freeze({__proto__:null,UPDATE_REFRESH_INTERVAL:30,bind_:bind_,throttle:throttle,debounce:debounce});let EVENT_MAP;class EventTarget$2{on(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},on(this,type,fn),this.addEventListener=ael}off(type,fn){off(this,type,fn)}one(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},one(this,type,fn),this.addEventListener=ael}any(type,fn){const ael=this.addEventListener;this.addEventListener=()=>{},any(this,type,fn),this.addEventListener=ael}trigger(event){const type=event.type||event;"string"==typeof event&&(event={type:type}),event=fixEvent(event),this.allowedEvents_[type]&&this["on"+type]&&this["on"+type](event),trigger(this,event)}queueTrigger(event){EVENT_MAP||(EVENT_MAP=new Map);const type=event.type||event;let map=EVENT_MAP.get(this);map||(map=new Map,EVENT_MAP.set(this,map));const oldTimeout=map.get(type);map.delete(type),window.clearTimeout(oldTimeout);const timeout=window.setTimeout((()=>{map.delete(type),0===map.size&&(map=null,EVENT_MAP.delete(this)),this.trigger(event)}),0);map.set(type,timeout)}}EventTarget$2.prototype.allowedEvents_={},EventTarget$2.prototype.addEventListener=EventTarget$2.prototype.on,EventTarget$2.prototype.removeEventListener=EventTarget$2.prototype.off,EventTarget$2.prototype.dispatchEvent=EventTarget$2.prototype.trigger;const objName=obj=>"function"==typeof obj.name?obj.name():"string"==typeof obj.name?obj.name:obj.name_?obj.name_:obj.constructor&&obj.constructor.name?obj.constructor.name:typeof obj,isEvented=object=>object instanceof EventTarget$2||!!object.eventBusEl_&&["on","one","off","trigger"].every((k=>"function"==typeof object[k])),isValidEventType=type=>"string"==typeof type&&/\S/.test(type)||Array.isArray(type)&&!!type.length,validateTarget=(target,obj,fnName)=>{if(!target||!target.nodeName&&!isEvented(target))throw new Error("Invalid target for ".concat(objName(obj),"#").concat(fnName,"; must be a DOM node or evented object."))},validateEventType=(type,obj,fnName)=>{if(!isValidEventType(type))throw new Error("Invalid event type for ".concat(objName(obj),"#").concat(fnName,"; must be a non-empty string or array."))},validateListener=(listener,obj,fnName)=>{if("function"!=typeof listener)throw new Error("Invalid listener for ".concat(objName(obj),"#").concat(fnName,"; must be a function."))},normalizeListenArgs=(self,args,fnName)=>{const isTargetingSelf=args.length<3||args[0]===self||args[0]===self.eventBusEl_;let target,type,listener;return isTargetingSelf?(target=self.eventBusEl_,args.length>=3&&args.shift(),[type,listener]=args):[target,type,listener]=args,validateTarget(target,self,fnName),validateEventType(type,self,fnName),validateListener(listener,self,fnName),listener=bind_(self,listener),{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}},listen=(target,method,type,listener)=>{validateTarget(target,target,method),target.nodeName?Events[method](target,type,listener):target[method](type,listener)},EventedMixin={on(){for(var _len9=arguments.length,args=new Array(_len9),_key9=0;_key9<_len9;_key9++)args[_key9]=arguments[_key9];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"on");if(listen(target,"on",type,listener),!isTargetingSelf){const removeListenerOnDispose=()=>this.off(target,type,listener);removeListenerOnDispose.guid=listener.guid;const removeRemoverOnTargetDispose=()=>this.off("dispose",removeListenerOnDispose);removeRemoverOnTargetDispose.guid=listener.guid,listen(this,"on","dispose",removeListenerOnDispose),listen(target,"on","dispose",removeRemoverOnTargetDispose)}},one(){for(var _this=this,_len10=arguments.length,args=new Array(_len10),_key10=0;_key10<_len10;_key10++)args[_key10]=arguments[_key10];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"one");if(isTargetingSelf)listen(target,"one",type,listener);else{const wrapper=function(){_this.off(target,type,wrapper);for(var _len11=arguments.length,largs=new Array(_len11),_key11=0;_key11<_len11;_key11++)largs[_key11]=arguments[_key11];listener.apply(null,largs)};wrapper.guid=listener.guid,listen(target,"one",type,wrapper)}},any(){for(var _this2=this,_len12=arguments.length,args=new Array(_len12),_key12=0;_key12<_len12;_key12++)args[_key12]=arguments[_key12];const{isTargetingSelf:isTargetingSelf,target:target,type:type,listener:listener}=normalizeListenArgs(this,args,"any");if(isTargetingSelf)listen(target,"any",type,listener);else{const wrapper=function(){_this2.off(target,type,wrapper);for(var _len13=arguments.length,largs=new Array(_len13),_key13=0;_key13<_len13;_key13++)largs[_key13]=arguments[_key13];listener.apply(null,largs)};wrapper.guid=listener.guid,listen(target,"any",type,wrapper)}},off(targetOrType,typeOrListener,listener){if(!targetOrType||isValidEventType(targetOrType))off(this.eventBusEl_,targetOrType,typeOrListener);else{const target=targetOrType,type=typeOrListener;validateTarget(target,this,"off"),validateEventType(type,this,"off"),validateListener(listener,this,"off"),listener=bind_(this,listener),this.off("dispose",listener),target.nodeName?(off(target,type,listener),off(target,"dispose",listener)):isEvented(target)&&(target.off(type,listener),target.off("dispose",listener))}},trigger(event,hash){validateTarget(this.eventBusEl_,this,"trigger");const type=event&&"string"!=typeof event?event.type:event;if(!isValidEventType(type))throw new Error("Invalid event type for ".concat(objName(this),"#trigger; ")+"must be a non-empty string or object with a type key that has a non-empty value.");return trigger(this.eventBusEl_,event,hash)}};function evented(target){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{eventBusKey:eventBusKey}=options;if(eventBusKey){if(!target[eventBusKey].nodeName)throw new Error('The eventBusKey "'.concat(eventBusKey,'" does not refer to an element.'));target.eventBusEl_=target[eventBusKey]}else target.eventBusEl_=createEl("span",{className:"vjs-event-bus"});return Object.assign(target,EventedMixin),target.eventedCallbacks&&target.eventedCallbacks.forEach((callback=>{callback()})),target.on("dispose",(()=>{target.off(),[target,target.el_,target.eventBusEl_].forEach((function(val){val&&DomData.has(val)&&DomData.delete(val)})),window.setTimeout((()=>{target.eventBusEl_=null}),0)})),target}const StatefulMixin={state:{},setState(stateUpdates){let changes;return"function"==typeof stateUpdates&&(stateUpdates=stateUpdates()),each(stateUpdates,((value,key)=>{this.state[key]!==value&&(changes=changes||{},changes[key]={from:this.state[key],to:value}),this.state[key]=value})),changes&&isEvented(this)&&this.trigger({changes:changes,type:"statechanged"}),changes}};function stateful(target,defaultState){return Object.assign(target,StatefulMixin),target.state=Object.assign({},target.state,defaultState),"function"==typeof target.handleStateChanged&&isEvented(target)&&target.on("statechanged",target.handleStateChanged),target}const toLowerCase=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toLowerCase()))},toTitleCase$1=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toUpperCase()))},titleCaseEquals=function(str1,str2){return toTitleCase$1(str1)===toTitleCase$1(str2)};var Str=Object.freeze({__proto__:null,toLowerCase:toLowerCase,toTitleCase:toTitleCase$1,titleCaseEquals:titleCaseEquals}),commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(fn,module){return fn(module={exports:{}},module.exports),module.exports}var keycode=createCommonjsModule((function(module,exports){function keyCode(searchInput){if(searchInput&&"object"==typeof searchInput){var hasKeyCode=searchInput.which||searchInput.keyCode||searchInput.charCode;hasKeyCode&&(searchInput=hasKeyCode)}if("number"==typeof searchInput)return names[searchInput];var foundNamedKey,search=String(searchInput);return(foundNamedKey=codes[search.toLowerCase()])?foundNamedKey:(foundNamedKey=aliases[search.toLowerCase()])||(1===search.length?search.charCodeAt(0):void 0)}keyCode.isEventKey=function(event,nameOrCode){if(event&&"object"==typeof event){var keyCode=event.which||event.keyCode||event.charCode;if(null==keyCode)return!1;if("string"==typeof nameOrCode){var foundNamedKey;if(foundNamedKey=codes[nameOrCode.toLowerCase()])return foundNamedKey===keyCode;if(foundNamedKey=aliases[nameOrCode.toLowerCase()])return foundNamedKey===keyCode}else if("number"==typeof nameOrCode)return nameOrCode===keyCode;return!1}};var codes=(exports=module.exports=keyCode).code=exports.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},aliases=exports.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(i=97;i<123;i++)codes[String.fromCharCode(i)]=i-32;for(var i=48;i<58;i++)codes[i-48]=i;for(i=1;i<13;i++)codes["f"+i]=i+111;for(i=0;i<10;i++)codes["numpad "+i]=i+96;var names=exports.names=exports.title={};for(i in codes)names[codes[i]]=i;for(var alias in aliases)codes[alias]=aliases[alias]}));keycode.code,keycode.codes,keycode.aliases,keycode.names,keycode.title;class Component$1{constructor(player,options,ready){if(!player&&this.play?this.player_=player=this:this.player_=player,this.isDisposed_=!1,this.parentComponent_=null,this.options_=merge$2({},this.options_),options=this.options_=merge$2(this.options_,options),this.id_=options.id||options.el&&options.el.id,!this.id_){const id=player&&player.id&&player.id()||"no_player";this.id_="".concat(id,"_component_").concat(newGUID())}this.name_=options.name||null,options.el?this.el_=options.el:!1!==options.createEl&&(this.el_=this.createEl()),options.className&&this.el_&&options.className.split(" ").forEach((c=>this.addClass(c))),["on","off","one","any","trigger"].forEach((fn=>{this[fn]=void 0})),!1!==options.evented&&(evented(this,{eventBusKey:this.el_?"el_":null}),this.handleLanguagechange=this.handleLanguagechange.bind(this),this.on(this.player_,"languagechange",this.handleLanguagechange)),stateful(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},this.childNameIndex_={},this.setTimeoutIds_=new Set,this.setIntervalIds_=new Set,this.rafIds_=new Set,this.namedRafs_=new Map,this.clearingTimersOnDispose_=!1,!1!==options.initChildren&&this.initChildren(),this.ready(ready),!1!==options.reportTouchActivity&&this.enableTouchActivity()}on(type,fn){}off(type,fn){}one(type,fn){}any(type,fn){}trigger(event,hash){}dispose(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.isDisposed_){if(this.readyQueue_&&(this.readyQueue_.length=0),this.trigger({type:"dispose",bubbles:!1}),this.isDisposed_=!0,this.children_)for(let i=this.children_.length-1;i>=0;i--)this.children_[i].dispose&&this.children_[i].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&(options.restoreEl?this.el_.parentNode.replaceChild(options.restoreEl,this.el_):this.el_.parentNode.removeChild(this.el_)),this.el_=null),this.player_=null}}isDisposed(){return Boolean(this.isDisposed_)}player(){return this.player_}options(obj){return obj?(this.options_=merge$2(this.options_,obj),this.options_):this.options_}el(){return this.el_}createEl(tagName,properties,attributes){return createEl(tagName,properties,attributes)}localize(string,tokens){let defaultValue=arguments.length>2&&void 0!==arguments[2]?arguments[2]:string;const code=this.player_.language&&this.player_.language(),languages=this.player_.languages&&this.player_.languages(),language=languages&&languages[code],primaryCode=code&&code.split("-")[0],primaryLang=languages&&languages[primaryCode];let localizedString=defaultValue;return language&&language[string]?localizedString=language[string]:primaryLang&&primaryLang[string]&&(localizedString=primaryLang[string]),tokens&&(localizedString=localizedString.replace(/\{(\d+)\}/g,(function(match,index){const value=tokens[index-1];let ret=value;return void 0===value&&(ret=match),ret}))),localizedString}handleLanguagechange(){}contentEl(){return this.contentEl_||this.el_}id(){return this.id_}name(){return this.name_}children(){return this.children_}getChildById(id){return this.childIndex_[id]}getChild(name){if(name)return this.childNameIndex_[name]}getDescendant(){for(var _len14=arguments.length,names=new Array(_len14),_key14=0;_key14<_len14;_key14++)names[_key14]=arguments[_key14];names=names.reduce(((acc,n)=>acc.concat(n)),[]);let currentChild=this;for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:this.el();if(!this.player_.options_.experimentalSvgIcons)return;const xmlnsURL="http://www.w3.org/2000/svg",iconContainer=createEl("span",{className:"vjs-icon-placeholder vjs-svg-icon"},{"aria-hidden":"true"}),svgEl=document.createElementNS(xmlnsURL,"svg");svgEl.setAttributeNS(null,"viewBox","0 0 512 512");const useEl=document.createElementNS(xmlnsURL,"use");return svgEl.appendChild(useEl),useEl.setAttributeNS(null,"href","#vjs-icon-".concat(iconName)),iconContainer.appendChild(svgEl),this.iconIsSet_?el.replaceChild(iconContainer,el.querySelector(".vjs-icon-placeholder")):el.appendChild(iconContainer),this.iconIsSet_=!0,iconContainer}addChild(child){let component,componentName,options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},index=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.children_.length;if("string"==typeof child){componentName=toTitleCase$1(child);const componentClassName=options.componentClass||componentName;options.name=componentName;const ComponentClass=Component$1.getComponent(componentClassName);if(!ComponentClass)throw new Error("Component ".concat(componentClassName," does not exist"));if("function"!=typeof ComponentClass)return null;component=new ComponentClass(this.player_||this,options)}else component=child;if(component.parentComponent_&&component.parentComponent_.removeChild(component),this.children_.splice(index,0,component),component.parentComponent_=this,"function"==typeof component.id&&(this.childIndex_[component.id()]=component),componentName=componentName||component.name&&toTitleCase$1(component.name()),componentName&&(this.childNameIndex_[componentName]=component,this.childNameIndex_[toLowerCase(componentName)]=component),"function"==typeof component.el&&component.el()){let refNode=null;this.children_[index+1]&&(this.children_[index+1].el_?refNode=this.children_[index+1].el_:isEl(this.children_[index+1])&&(refNode=this.children_[index+1])),this.contentEl().insertBefore(component.el(),refNode)}return component}removeChild(component){if("string"==typeof component&&(component=this.getChild(component)),!component||!this.children_)return;let childFound=!1;for(let i=this.children_.length-1;i>=0;i--)if(this.children_[i]===component){childFound=!0,this.children_.splice(i,1);break}if(!childFound)return;component.parentComponent_=null,this.childIndex_[component.id()]=null,this.childNameIndex_[toTitleCase$1(component.name())]=null,this.childNameIndex_[toLowerCase(component.name())]=null;const compEl=component.el();compEl&&compEl.parentNode===this.contentEl()&&this.contentEl().removeChild(component.el())}initChildren(){const children=this.options_.children;if(children){const parentOptions=this.options_,handleAdd=child=>{const name=child.name;let opts=child.opts;if(void 0!==parentOptions[name]&&(opts=parentOptions[name]),!1===opts)return;!0===opts&&(opts={}),opts.playerOptions=this.options_.playerOptions;const newChild=this.addChild(name,opts);newChild&&(this[name]=newChild)};let workingChildren;const Tech=Component$1.getComponent("Tech");workingChildren=Array.isArray(children)?children:Object.keys(children),workingChildren.concat(Object.keys(this.options_).filter((function(child){return!workingChildren.some((function(wchild){return"string"==typeof wchild?child===wchild:child===wchild.name}))}))).map((child=>{let name,opts;return"string"==typeof child?(name=child,opts=children[name]||this.options_[name]||{}):(name=child.name,opts=child),{name:name,opts:opts}})).filter((child=>{const c=Component$1.getComponent(child.opts.componentClass||toTitleCase$1(child.name));return c&&!Tech.isTech(c)})).forEach(handleAdd)}}buildCSSClass(){return""}ready(fn){let sync=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(fn)return this.isReady_?void(sync?fn.call(this):this.setTimeout(fn,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(fn))}triggerReady(){this.isReady_=!0,this.setTimeout((function(){const readyQueue=this.readyQueue_;this.readyQueue_=[],readyQueue&&readyQueue.length>0&&readyQueue.forEach((function(fn){fn.call(this)}),this),this.trigger("ready")}),1)}$(selector,context){return $(selector,context||this.contentEl())}$$(selector,context){return $$(selector,context||this.contentEl())}hasClass(classToCheck){return hasClass(this.el_,classToCheck)}addClass(){for(var _len15=arguments.length,classesToAdd=new Array(_len15),_key15=0;_key15<_len15;_key15++)classesToAdd[_key15]=arguments[_key15];addClass(this.el_,...classesToAdd)}removeClass(){for(var _len16=arguments.length,classesToRemove=new Array(_len16),_key16=0;_key16<_len16;_key16++)classesToRemove[_key16]=arguments[_key16];removeClass(this.el_,...classesToRemove)}toggleClass(classToToggle,predicate){toggleClass(this.el_,classToToggle,predicate)}show(){this.removeClass("vjs-hidden")}hide(){this.addClass("vjs-hidden")}lockShowing(){this.addClass("vjs-lock-showing")}unlockShowing(){this.removeClass("vjs-lock-showing")}getAttribute(attribute){return getAttribute(this.el_,attribute)}setAttribute(attribute,value){setAttribute(this.el_,attribute,value)}removeAttribute(attribute){removeAttribute(this.el_,attribute)}width(num,skipListeners){return this.dimension("width",num,skipListeners)}height(num,skipListeners){return this.dimension("height",num,skipListeners)}dimensions(width,height){this.width(width,!0),this.height(height)}dimension(widthOrHeight,num,skipListeners){if(void 0!==num)return null!==num&&num==num||(num=0),-1!==(""+num).indexOf("%")||-1!==(""+num).indexOf("px")?this.el_.style[widthOrHeight]=num:this.el_.style[widthOrHeight]="auto"===num?"":num+"px",void(skipListeners||this.trigger("componentresize"));if(!this.el_)return 0;const val=this.el_.style[widthOrHeight],pxIndex=val.indexOf("px");return-1!==pxIndex?parseInt(val.slice(0,pxIndex),10):parseInt(this.el_["offset"+toTitleCase$1(widthOrHeight)],10)}currentDimension(widthOrHeight){let computedWidthOrHeight=0;if("width"!==widthOrHeight&&"height"!==widthOrHeight)throw new Error("currentDimension only accepts width or height value");if(computedWidthOrHeight=computedStyle(this.el_,widthOrHeight),computedWidthOrHeight=parseFloat(computedWidthOrHeight),0===computedWidthOrHeight||isNaN(computedWidthOrHeight)){const rule="offset".concat(toTitleCase$1(widthOrHeight));computedWidthOrHeight=this.el_[rule]}return computedWidthOrHeight}currentDimensions(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}}currentWidth(){return this.currentDimension("width")}currentHeight(){return this.currentDimension("height")}focus(){this.el_.focus()}blur(){this.el_.blur()}handleKeyDown(event){this.player_&&(keycode.isEventKey(event,"Tab")||event.stopPropagation(),this.player_.handleKeyDown(event))}handleKeyPress(event){this.handleKeyDown(event)}emitTapEvents(){let touchStart=0,firstTouch=null;let couldBeTap;this.on("touchstart",(function(event){1===event.touches.length&&(firstTouch={pageX:event.touches[0].pageX,pageY:event.touches[0].pageY},touchStart=window.performance.now(),couldBeTap=!0)})),this.on("touchmove",(function(event){if(event.touches.length>1)couldBeTap=!1;else if(firstTouch){const xdiff=event.touches[0].pageX-firstTouch.pageX,ydiff=event.touches[0].pageY-firstTouch.pageY;Math.sqrt(xdiff*xdiff+ydiff*ydiff)>10&&(couldBeTap=!1)}}));const noTap=function(){couldBeTap=!1};this.on("touchleave",noTap),this.on("touchcancel",noTap),this.on("touchend",(function(event){if(firstTouch=null,!0===couldBeTap){window.performance.now()-touchStart<200&&(event.preventDefault(),this.trigger("tap"))}}))}enableTouchActivity(){if(!this.player()||!this.player().reportUserActivity)return;const report=bind_(this.player(),this.player().reportUserActivity);let touchHolding;this.on("touchstart",(function(){report(),this.clearInterval(touchHolding),touchHolding=this.setInterval(report,250)}));const touchEnd=function(event){report(),this.clearInterval(touchHolding)};this.on("touchmove",report),this.on("touchend",touchEnd),this.on("touchcancel",touchEnd)}setTimeout(fn,timeout){var timeoutId;return fn=bind_(this,fn),this.clearTimersOnDispose_(),timeoutId=window.setTimeout((()=>{this.setTimeoutIds_.has(timeoutId)&&this.setTimeoutIds_.delete(timeoutId),fn()}),timeout),this.setTimeoutIds_.add(timeoutId),timeoutId}clearTimeout(timeoutId){return this.setTimeoutIds_.has(timeoutId)&&(this.setTimeoutIds_.delete(timeoutId),window.clearTimeout(timeoutId)),timeoutId}setInterval(fn,interval){fn=bind_(this,fn),this.clearTimersOnDispose_();const intervalId=window.setInterval(fn,interval);return this.setIntervalIds_.add(intervalId),intervalId}clearInterval(intervalId){return this.setIntervalIds_.has(intervalId)&&(this.setIntervalIds_.delete(intervalId),window.clearInterval(intervalId)),intervalId}requestAnimationFrame(fn){var id;return this.clearTimersOnDispose_(),fn=bind_(this,fn),id=window.requestAnimationFrame((()=>{this.rafIds_.has(id)&&this.rafIds_.delete(id),fn()})),this.rafIds_.add(id),id}requestNamedAnimationFrame(name,fn){if(this.namedRafs_.has(name))return;this.clearTimersOnDispose_(),fn=bind_(this,fn);const id=this.requestAnimationFrame((()=>{fn(),this.namedRafs_.has(name)&&this.namedRafs_.delete(name)}));return this.namedRafs_.set(name,id),name}cancelNamedAnimationFrame(name){this.namedRafs_.has(name)&&(this.cancelAnimationFrame(this.namedRafs_.get(name)),this.namedRafs_.delete(name))}cancelAnimationFrame(id){return this.rafIds_.has(id)&&(this.rafIds_.delete(id),window.cancelAnimationFrame(id)),id}clearTimersOnDispose_(){this.clearingTimersOnDispose_||(this.clearingTimersOnDispose_=!0,this.one("dispose",(()=>{[["namedRafs_","cancelNamedAnimationFrame"],["rafIds_","cancelAnimationFrame"],["setTimeoutIds_","clearTimeout"],["setIntervalIds_","clearInterval"]].forEach((_ref4=>{let[idName,cancelName]=_ref4;this[idName].forEach(((val,key)=>this[cancelName](key)))})),this.clearingTimersOnDispose_=!1})))}static registerComponent(name,ComponentToRegister){if("string"!=typeof name||!name)throw new Error('Illegal component name, "'.concat(name,'"; must be a non-empty string.'));const Tech=Component$1.getComponent("Tech"),isTech=Tech&&Tech.isTech(ComponentToRegister),isComp=Component$1===ComponentToRegister||Component$1.prototype.isPrototypeOf(ComponentToRegister.prototype);if(isTech||!isComp){let reason;throw reason=isTech?"techs must be registered using Tech.registerTech()":"must be a Component subclass",new Error('Illegal component, "'.concat(name,'"; ').concat(reason,"."))}name=toTitleCase$1(name),Component$1.components_||(Component$1.components_={});const Player=Component$1.getComponent("Player");if("Player"===name&&Player&&Player.players){const players=Player.players,playerNames=Object.keys(players);if(players&&playerNames.length>0&&playerNames.map((pname=>players[pname])).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return Component$1.components_[name]=ComponentToRegister,Component$1.components_[toLowerCase(name)]=ComponentToRegister,ComponentToRegister}static getComponent(name){if(name&&Component$1.components_)return Component$1.components_[name]}}function getRange(fnName,valueIndex,ranges,rangeIndex){return function(fnName,index,maxIndex){if("number"!=typeof index||index<0||index>maxIndex)throw new Error("Failed to execute '".concat(fnName,"' on 'TimeRanges': The index provided (").concat(index,") is non-numeric or out of bounds (0-").concat(maxIndex,")."))}(fnName,rangeIndex,ranges.length-1),ranges[rangeIndex][valueIndex]}function createTimeRangesObj(ranges){let timeRangesObj;return timeRangesObj=void 0===ranges||0===ranges.length?{length:0,start(){throw new Error("This TimeRanges object is empty")},end(){throw new Error("This TimeRanges object is empty")}}:{length:ranges.length,start:getRange.bind(null,"start",0,ranges),end:getRange.bind(null,"end",1,ranges)},window.Symbol&&window.Symbol.iterator&&(timeRangesObj[window.Symbol.iterator]=()=>(ranges||[]).values()),timeRangesObj}function createTimeRanges$1(start,end){return Array.isArray(start)?createTimeRangesObj(start):void 0===start||void 0===end?createTimeRangesObj():createTimeRangesObj([[start,end]])}Component$1.registerComponent("Component",Component$1);const defaultImplementation=function(seconds,guide){seconds=seconds<0?0:seconds;let s=Math.floor(seconds%60),m=Math.floor(seconds/60%60),h=Math.floor(seconds/3600);const gm=Math.floor(guide/60%60),gh=Math.floor(guide/3600);return(isNaN(seconds)||seconds===1/0)&&(h=m=s="-"),h=h>0||gh>0?h+":":"",m=((h||gm>=10)&&m<10?"0"+m:m)+":",s=s<10?"0"+s:s,h+m+s};let implementation=defaultImplementation;function setFormatTime(customImplementation){implementation=customImplementation}function resetFormatTime(){implementation=defaultImplementation}function formatTime(seconds){let guide=arguments.length>1&&void 0!==arguments[1]?arguments[1]:seconds;return implementation(seconds,guide)}var Time=Object.freeze({__proto__:null,createTimeRanges:createTimeRanges$1,createTimeRange:createTimeRanges$1,setFormatTime:setFormatTime,resetFormatTime:resetFormatTime,formatTime:formatTime});function bufferedPercent(buffered,duration){let start,end,bufferedDuration=0;if(!duration)return 0;buffered&&buffered.length||(buffered=createTimeRanges$1(0,0));for(let i=0;iduration&&(end=duration),bufferedDuration+=end-start;return bufferedDuration/duration}function MediaError(value){if(value instanceof MediaError)return value;"number"==typeof value?this.code=value:"string"==typeof value?this.message=value:isObject$1(value)&&("number"==typeof value.code&&(this.code=value.code),Object.assign(this,value)),this.message||(this.message=MediaError.defaultMessages[this.code]||"")}MediaError.prototype.code=0,MediaError.prototype.message="",MediaError.prototype.status=null,MediaError.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],MediaError.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(let errNum=0;errNum{}))}const trackToJson_=function(track){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(((acc,prop,i)=>(track[prop]&&(acc[prop]=track[prop]),acc)),{cues:track.cues&&Array.prototype.map.call(track.cues,(function(cue){return{startTime:cue.startTime,endTime:cue.endTime,text:cue.text,id:cue.id}}))})};var textTrackConverter_textTracksToJson=function(tech){const trackEls=tech.$$("track"),trackObjs=Array.prototype.map.call(trackEls,(t=>t.track));return Array.prototype.map.call(trackEls,(function(trackEl){const json=trackToJson_(trackEl.track);return trackEl.src&&(json.src=trackEl.src),json})).concat(Array.prototype.filter.call(tech.textTracks(),(function(track){return-1===trackObjs.indexOf(track)})).map(trackToJson_))},textTrackConverter_jsonToTextTracks=function(json,tech){return json.forEach((function(track){const addedTrack=tech.addRemoteTextTrack(track).track;!track.src&&track.cues&&track.cues.forEach((cue=>addedTrack.addCue(cue)))})),tech.textTracks()};class ModalDialog extends Component$1{constructor(player,options){super(player,options),this.handleKeyDown_=e=>this.handleKeyDown(e),this.close_=e=>this.close(e),this.opened_=this.hasBeenOpened_=this.hasBeenFilled_=!1,this.closeable(!this.options_.uncloseable),this.content(this.options_.content),this.contentEl_=createEl("div",{className:"".concat("vjs-modal-dialog","-content")},{role:"document"}),this.descEl_=createEl("p",{className:"".concat("vjs-modal-dialog","-description vjs-control-text"),id:this.el().getAttribute("aria-describedby")}),textContent(this.descEl_,this.description()),this.el_.appendChild(this.descEl_),this.el_.appendChild(this.contentEl_)}createEl(){return super.createEl("div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":"".concat(this.id(),"_description"),"aria-hidden":"true","aria-label":this.label(),role:"dialog"})}dispose(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,super.dispose()}buildCSSClass(){return"".concat("vjs-modal-dialog"," vjs-hidden ").concat(super.buildCSSClass())}label(){return this.localize(this.options_.label||"Modal Window")}description(){let desc=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(desc+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),desc}open(){if(!this.opened_){const player=this.player();this.trigger("beforemodalopen"),this.opened_=!0,(this.options_.fillAlways||!this.hasBeenOpened_&&!this.hasBeenFilled_)&&this.fill(),this.wasPlaying_=!player.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&player.pause(),this.on("keydown",this.handleKeyDown_),this.hadControls_=player.controls(),player.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0}}opened(value){return"boolean"==typeof value&&this[value?"open":"close"](),this.opened_}close(){if(!this.opened_)return;const player=this.player();this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&player.play(),this.off("keydown",this.handleKeyDown_),this.hadControls_&&player.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose()}closeable(value){if("boolean"==typeof value){const closeable=this.closeable_=!!value;let close=this.getChild("closeButton");if(closeable&&!close){const temp=this.contentEl_;this.contentEl_=this.el_,close=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=temp,this.on(close,"close",this.close_)}!closeable&&close&&(this.off(close,"close",this.close_),this.removeChild(close),close.dispose())}return this.closeable_}fill(){this.fillWith(this.content())}fillWith(content){const contentEl=this.contentEl(),parentEl=contentEl.parentNode,nextSiblingEl=contentEl.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,parentEl.removeChild(contentEl),this.empty(),insertContent(contentEl,content),this.trigger("modalfill"),nextSiblingEl?parentEl.insertBefore(contentEl,nextSiblingEl):parentEl.appendChild(contentEl);const closeButton=this.getChild("closeButton");closeButton&&parentEl.appendChild(closeButton.el_)}empty(){this.trigger("beforemodalempty"),emptyEl(this.contentEl()),this.trigger("modalempty")}content(value){return void 0!==value&&(this.content_=value),this.content_}conditionalFocus_(){const activeEl=document.activeElement,playerEl=this.player_.el_;this.previouslyActiveEl_=null,(playerEl.contains(activeEl)||playerEl===activeEl)&&(this.previouslyActiveEl_=activeEl,this.focus())}conditionalBlur_(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)}handleKeyDown(event){if(event.stopPropagation(),keycode.isEventKey(event,"Escape")&&this.closeable())return event.preventDefault(),void this.close();if(!keycode.isEventKey(event,"Tab"))return;const focusableEls=this.focusableEls_(),activeEl=this.el_.querySelector(":focus");let focusIndex;for(let i=0;i(child instanceof window.HTMLAnchorElement||child instanceof window.HTMLAreaElement)&&child.hasAttribute("href")||(child instanceof window.HTMLInputElement||child instanceof window.HTMLSelectElement||child instanceof window.HTMLTextAreaElement||child instanceof window.HTMLButtonElement)&&!child.hasAttribute("disabled")||child instanceof window.HTMLIFrameElement||child instanceof window.HTMLObjectElement||child instanceof window.HTMLEmbedElement||child.hasAttribute("tabindex")&&-1!==child.getAttribute("tabindex")||child.hasAttribute("contenteditable")))}}ModalDialog.prototype.options_={pauseOnOpen:!0,temporary:!0},Component$1.registerComponent("ModalDialog",ModalDialog);class TrackList extends EventTarget$2{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];super(),this.tracks_=[],Object.defineProperty(this,"length",{get(){return this.tracks_.length}});for(let i=0;i{this.trigger({track:track,type:"labelchange",target:this})},isEvented(track)&&track.addEventListener("labelchange",track.labelchange_)}removeTrack(rtrack){let track;for(let i=0,l=this.length;ithis.queueTrigger("change")),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=()=>this.trigger("selectedlanguagechange")),track.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(track.kind)&&track.addEventListener("modechange",this.triggerSelectedlanguagechange_)}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&(this.queueChange_&&rtrack.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&rtrack.removeEventListener("modechange",this.triggerSelectedlanguagechange_))}}class TextTrackCueList{constructor(cues){TextTrackCueList.prototype.setCues_.call(this,cues),Object.defineProperty(this,"length",{get(){return this.length_}})}setCues_(cues){const oldLength=this.length||0;let i=0;const l=cues.length;this.cues_=cues,this.length_=cues.length;const defineProp=function(index){""+index in this||Object.defineProperty(this,""+index,{get(){return this.cues_[index]}})};if(oldLength0&&void 0!==arguments[0]?arguments[0]:{};super();const trackProps={id:options.id||"vjs_track_"+newGUID(),kind:options.kind||"",language:options.language||""};let label=options.label||"";for(const key in trackProps)Object.defineProperty(this,key,{get:()=>trackProps[key],set(){}});Object.defineProperty(this,"label",{get:()=>label,set(newLabel){newLabel!==label&&(label=newLabel,this.trigger("labelchange"))}})}}const parseUrl=function(url){const props=["protocol","hostname","port","pathname","search","hash","host"],a=document.createElement("a");a.href=url;const details={};for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:window.location;const urlInfo=parseUrl(url),srcProtocol=":"===urlInfo.protocol?winLoc.protocol:urlInfo.protocol,crossOrigin=srcProtocol+urlInfo.host!==winLoc.protocol+winLoc.host;return crossOrigin};var x,Url=Object.freeze({__proto__:null,parseUrl:parseUrl,getAbsoluteURL:getAbsoluteURL,getFileExtension:getFileExtension,isCrossOrigin:isCrossOrigin}),window_1="undefined"!=typeof window?window:void 0!==commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{},_extends_1=createCommonjsModule((function(module){function _extends(){return module.exports=_extends=Object.assign?Object.assign.bind():function(target){for(var i=1;i=400&&response.statusCode<=599){var cause=responseBody;if(decodeResponseBody)if(window_1.TextDecoder){var charset=function(contentTypeHeader){void 0===contentTypeHeader&&(contentTypeHeader="");return contentTypeHeader.toLowerCase().split(";").reduce((function(charset,contentType){var _contentType$split=contentType.split("="),type=_contentType$split[0],value=_contentType$split[1];return"charset"===type.trim()?value.trim():charset}),"utf-8")}(response.headers&&response.headers["content-type"]);try{cause=new TextDecoder(charset).decode(responseBody)}catch(e){}}else cause=String.fromCharCode.apply(null,new Uint8Array(responseBody));callback({cause:cause})}else callback(null,responseBody)}};createXHR.httpHandler=httpHandler; /** * @license * slighly modified parse-headers 2.0.2 @@ -17,15 +17,15 @@ * Available under the MIT license * */ -var lib=createXHR,default_1=createXHR;function initParams(uri,options,callback){var params=uri;return isFunction_1(options)?(callback=options,"string"==typeof uri&&(params={uri:uri})):params=_extends_1({},options,{uri:uri}),params.callback=callback,params}function createXHR(uri,options,callback){return _createXHR(options=initParams(uri,options,callback))}function _createXHR(options){if(void 0===options.callback)throw new Error("callback argument missing");var called=!1,callback=function(err,response,body){called||(called=!0,options.callback(err,response,body))};function getBody(){var body=void 0;if(body=xhr.response?xhr.response:xhr.responseText||function(xhr){try{if("document"===xhr.responseType)return xhr.responseXML;var firefoxBugTakenEffect=xhr.responseXML&&"parsererror"===xhr.responseXML.documentElement.nodeName;if(""===xhr.responseType&&!firefoxBugTakenEffect)return xhr.responseXML}catch(e){}return null}(xhr),isJson)try{body=JSON.parse(body)}catch(e){}return body}function errorFunc(evt){return clearTimeout(timeoutTimer),evt instanceof Error||(evt=new Error(""+(evt||"Unknown XMLHttpRequest Error"))),evt.statusCode=0,callback(evt,failureResponse)}function loadFunc(){if(!aborted){var status;clearTimeout(timeoutTimer),status=options.useXDR&&void 0===xhr.status?200:1223===xhr.status?204:xhr.status;var response=failureResponse,err=null;return 0!==status?(response={body:getBody(),statusCode:status,method:method,headers:{},url:uri,rawRequest:xhr},xhr.getAllResponseHeaders&&(response.headers=function(headers){var result={};return headers?(headers.trim().split("\n").forEach((function(row){var index=row.indexOf(":"),key=row.slice(0,index).trim().toLowerCase(),value=row.slice(index+1).trim();void 0===result[key]?result[key]=value:Array.isArray(result[key])?result[key].push(value):result[key]=[result[key],value]})),result):result}(xhr.getAllResponseHeaders()))):err=new Error("Internal XMLHttpRequest Error"),callback(err,response,response.body)}}var key,aborted,xhr=options.xhr||null;xhr||(xhr=options.cors||options.useXDR?new createXHR.XDomainRequest:new createXHR.XMLHttpRequest);var timeoutTimer,uri=xhr.url=options.uri||options.url,method=xhr.method=options.method||"GET",body=options.body||options.data,headers=xhr.headers=options.headers||{},sync=!!options.sync,isJson=!1,failureResponse={body:void 0,headers:{},statusCode:0,method:method,url:uri,rawRequest:xhr};if("json"in options&&!1!==options.json&&(isJson=!0,headers.accept||headers.Accept||(headers.Accept="application/json"),"GET"!==method&&"HEAD"!==method&&(headers["content-type"]||headers["Content-Type"]||(headers["Content-Type"]="application/json"),body=JSON.stringify(!0===options.json?body:options.json))),xhr.onreadystatechange=function(){4===xhr.readyState&&setTimeout(loadFunc,0)},xhr.onload=loadFunc,xhr.onerror=errorFunc,xhr.onprogress=function(){},xhr.onabort=function(){aborted=!0},xhr.ontimeout=errorFunc,xhr.open(method,uri,!sync,options.username,options.password),sync||(xhr.withCredentials=!!options.withCredentials),!sync&&options.timeout>0&&(timeoutTimer=setTimeout((function(){if(!aborted){aborted=!0,xhr.abort("timeout");var e=new Error("XMLHttpRequest timeout");e.code="ETIMEDOUT",errorFunc(e)}}),options.timeout)),xhr.setRequestHeader)for(key in headers)headers.hasOwnProperty(key)&&xhr.setRequestHeader(key,headers[key]);else if(options.headers&&!function(obj){for(var i in obj)if(obj.hasOwnProperty(i))return!1;return!0}(options.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in options&&(xhr.responseType=options.responseType),"beforeSend"in options&&"function"==typeof options.beforeSend&&options.beforeSend(xhr),xhr.send(body||null),xhr}createXHR.XMLHttpRequest=window_1.XMLHttpRequest||function(){},createXHR.XDomainRequest="withCredentials"in new createXHR.XMLHttpRequest?createXHR.XMLHttpRequest:window_1.XDomainRequest,function(array,iterator){for(var i=0;i0&&(window.console&&window.console.groupCollapsed&&window.console.groupCollapsed("Text Track parsing errors for ".concat(track.src)),errors.forEach((error=>log$1.error(error))),window.console&&window.console.groupEnd&&window.console.groupEnd()),parser.flush()},loadTrack=function(src,track){const opts={uri:src},crossOrigin=isCrossOrigin(src);crossOrigin&&(opts.cors=crossOrigin);const withCredentials="use-credentials"===track.tech_.crossOrigin();withCredentials&&(opts.withCredentials=withCredentials),lib(opts,bind_(this,(function(err,response,responseBody){if(err)return log$1.error(err,response);track.loaded_=!0,"function"!=typeof window.WebVTT?track.tech_&&track.tech_.any(["vttjsloaded","vttjserror"],(event=>{if("vttjserror"!==event.type)return parseCues(responseBody,track);log$1.error("vttjs failed to load, stopping trying to process ".concat(track.src))})):parseCues(responseBody,track)})))};class TextTrack extends Track{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!options.tech)throw new Error("A tech was not provided.");const settings=merge$2(options,{kind:TextTrackKind[options.kind]||"subtitles",language:options.language||options.srclang||""});let mode=TextTrackMode[settings.mode]||"disabled";const default_=settings.default;"metadata"!==settings.kind&&"chapters"!==settings.kind||(mode="hidden"),super(settings),this.tech_=settings.tech,this.cues_=[],this.activeCues_=[],this.preload_=!1!==this.tech_.preloadTextTracks;const cues=new TextTrackCueList(this.cues_),activeCues=new TextTrackCueList(this.activeCues_);let changed=!1;this.timeupdateHandler=bind_(this,(function(){let event=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.tech_.isDisposed()||(this.tech_.isReady_?(this.activeCues=this.activeCues,changed&&(this.trigger("cuechange"),changed=!1),"timeupdate"!==event.type&&(this.rvf_=this.tech_.requestVideoFrameCallback(this.timeupdateHandler))):"timeupdate"!==event.type&&(this.rvf_=this.tech_.requestVideoFrameCallback(this.timeupdateHandler)))}));this.tech_.one("dispose",(()=>{this.stopTracking()})),"disabled"!==mode&&this.startTracking(),Object.defineProperties(this,{default:{get:()=>default_,set(){}},mode:{get:()=>mode,set(newMode){TextTrackMode[newMode]&&mode!==newMode&&(mode=newMode,this.preload_||"disabled"===mode||0!==this.cues.length||loadTrack(this.src,this),this.stopTracking(),"disabled"!==mode&&this.startTracking(),this.trigger("modechange"))}},cues:{get(){return this.loaded_?cues:null},set(){}},activeCues:{get(){if(!this.loaded_)return null;if(0===this.cues.length)return activeCues;const ct=this.tech_.currentTime(),active=[];for(let i=0,l=this.cues.length;i=ct&&active.push(cue)}if(changed=!1,active.length!==this.activeCues_.length)changed=!0;else for(let i=0;i0&&void 0!==arguments[0]?arguments[0]:{};const settings=merge$2(options,{kind:AudioTrackKind[options.kind]||""});super(settings);let enabled=!1;Object.defineProperty(this,"enabled",{get:()=>enabled,set(newEnabled){"boolean"==typeof newEnabled&&newEnabled!==enabled&&(enabled=newEnabled,this.trigger("enabledchange"))}}),settings.enabled&&(this.enabled=settings.enabled),this.loaded_=!0}}class VideoTrack extends Track{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const settings=merge$2(options,{kind:VideoTrackKind[options.kind]||""});super(settings);let selected=!1;Object.defineProperty(this,"selected",{get:()=>selected,set(newSelected){"boolean"==typeof newSelected&&newSelected!==selected&&(selected=newSelected,this.trigger("selectedchange"))}}),settings.selected&&(this.selected=settings.selected)}}class HTMLTrackElement extends EventTarget$2{constructor(){let readyState,options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super();const track=new TextTrack(options);this.kind=track.kind,this.src=track.src,this.srclang=track.language,this.label=track.label,this.default=track.default,Object.defineProperties(this,{readyState:{get:()=>readyState},track:{get:()=>track}}),readyState=HTMLTrackElement.NONE,track.addEventListener("loadeddata",(()=>{readyState=HTMLTrackElement.LOADED,this.trigger({type:"load",target:this})}))}}HTMLTrackElement.prototype.allowedEvents_={load:"load"},HTMLTrackElement.NONE=0,HTMLTrackElement.LOADING=1,HTMLTrackElement.LOADED=2,HTMLTrackElement.ERROR=3;const NORMAL={audio:{ListClass:class extends TrackList{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];for(let i=tracks.length-1;i>=0;i--)if(tracks[i].enabled){disableOthers$1(tracks,tracks[i]);break}super(tracks),this.changing_=!1}addTrack(track){track.enabled&&disableOthers$1(this,track),super.addTrack(track),track.addEventListener&&(track.enabledChange_=()=>{this.changing_||(this.changing_=!0,disableOthers$1(this,track),this.changing_=!1,this.trigger("change"))},track.addEventListener("enabledchange",track.enabledChange_))}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&rtrack.enabledChange_&&(rtrack.removeEventListener("enabledchange",rtrack.enabledChange_),rtrack.enabledChange_=null)}},TrackClass:AudioTrack,capitalName:"Audio"},video:{ListClass:class extends TrackList{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];for(let i=tracks.length-1;i>=0;i--)if(tracks[i].selected){disableOthers(tracks,tracks[i]);break}super(tracks),this.changing_=!1,Object.defineProperty(this,"selectedIndex",{get(){for(let i=0;i{this.changing_||(this.changing_=!0,disableOthers(this,track),this.changing_=!1,this.trigger("change"))},track.addEventListener("selectedchange",track.selectedChange_))}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&rtrack.selectedChange_&&(rtrack.removeEventListener("selectedchange",rtrack.selectedChange_),rtrack.selectedChange_=null)}},TrackClass:VideoTrack,capitalName:"Video"},text:{ListClass:TextTrackList,TrackClass:TextTrack,capitalName:"Text"}};Object.keys(NORMAL).forEach((function(type){NORMAL[type].getterName="".concat(type,"Tracks"),NORMAL[type].privateName="".concat(type,"Tracks_")}));const REMOTE={remoteText:{ListClass:TextTrackList,TrackClass:TextTrack,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:class{constructor(){let trackElements=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.trackElements_=[],Object.defineProperty(this,"length",{get(){return this.trackElements_.length}});for(let i=0,length=trackElements.length;i59?computeSeconds(m[1],m[2],0,m[4]):computeSeconds(0,m[1],m[2],m[4]):null}function Settings(){this.values=_objCreate(null)}function parseOptions(input,callback,keyValueDelim,groupDelim){var groups=groupDelim?input.split(groupDelim):[input];for(var i in groups)if("string"==typeof groups[i]){var kv=groups[i].split(keyValueDelim);if(2===kv.length)callback(kv[0].trim(),kv[1].trim())}}function parseCue(input,cue,regionList){var oInput=input;function consumeTimeStamp(){var ts=parseTimeStamp(input);if(null===ts)throw new ParsingError(ParsingError.Errors.BadTimeStamp,"Malformed timestamp: "+oInput);return input=input.replace(/^[^\sa-zA-Z-]+/,""),ts}function skipWhitespace(){input=input.replace(/^\s+/,"")}if(skipWhitespace(),cue.startTime=consumeTimeStamp(),skipWhitespace(),"--\x3e"!==input.substr(0,3))throw new ParsingError(ParsingError.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+oInput);input=input.substr(3),skipWhitespace(),cue.endTime=consumeTimeStamp(),skipWhitespace(),function(input,cue){var settings=new Settings;parseOptions(input,(function(k,v){switch(k){case"region":for(var i=regionList.length-1;i>=0;i--)if(regionList[i].id===v){settings.set(k,regionList[i].region);break}break;case"vertical":settings.alt(k,v,["rl","lr"]);break;case"line":var vals=v.split(","),vals0=vals[0];settings.integer(k,vals0),settings.percent(k,vals0)&&settings.set("snapToLines",!1),settings.alt(k,vals0,["auto"]),2===vals.length&&settings.alt("lineAlign",vals[1],["start","center","end"]);break;case"position":vals=v.split(","),settings.percent(k,vals[0]),2===vals.length&&settings.alt("positionAlign",vals[1],["start","center","end"]);break;case"size":settings.percent(k,v);break;case"align":settings.alt(k,v,["start","center","end","left","right"])}}),/:/,/\s/),cue.region=settings.get("region",null),cue.vertical=settings.get("vertical","");try{cue.line=settings.get("line","auto")}catch(e){}cue.lineAlign=settings.get("lineAlign","start"),cue.snapToLines=settings.get("snapToLines",!0),cue.size=settings.get("size",100);try{cue.align=settings.get("align","center")}catch(e){cue.align=settings.get("align","middle")}try{cue.position=settings.get("position","auto")}catch(e){cue.position=settings.get("position",{start:0,left:0,center:50,middle:50,end:100,right:100},cue.align)}cue.positionAlign=settings.get("positionAlign",{start:"start",left:"start",center:"center",middle:"center",end:"end",right:"end"},cue.align)}(input,cue)}ParsingError.prototype=_objCreate(Error.prototype),ParsingError.prototype.constructor=ParsingError,ParsingError.Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},Settings.prototype={set:function(k,v){this.get(k)||""===v||(this.values[k]=v)},get:function(k,dflt,defaultKey){return defaultKey?this.has(k)?this.values[k]:dflt[defaultKey]:this.has(k)?this.values[k]:dflt},has:function(k){return k in this.values},alt:function(k,v,a){for(var n=0;n=0&&v<=100)&&(this.set(k,v),!0)}};var TEXTAREA_ELEMENT=document_1.createElement&&document_1.createElement("textarea"),TAG_NAME={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},DEFAULT_COLOR_CLASS={white:"rgba(255,255,255,1)",lime:"rgba(0,255,0,1)",cyan:"rgba(0,255,255,1)",red:"rgba(255,0,0,1)",yellow:"rgba(255,255,0,1)",magenta:"rgba(255,0,255,1)",blue:"rgba(0,0,255,1)",black:"rgba(0,0,0,1)"},TAG_ANNOTATION={v:"title",lang:"lang"},NEEDS_PARENT={rt:"ruby"};function parseContent(window,input){function nextToken(){if(!input)return null;var result,m=input.match(/^([^<]*)(<[^>]*>?)?/);return result=m[1]?m[1]:m[2],input=input.substr(result.length),result}function shouldAdd(current,element){return!NEEDS_PARENT[element.localName]||NEEDS_PARENT[element.localName]===current.localName}function createElement(type,annotation){var tagName=TAG_NAME[type];if(!tagName)return null;var element=window.document.createElement(tagName),name=TAG_ANNOTATION[type];return name&&annotation&&(element[name]=annotation.trim()),element}for(var t,s,rootDiv=window.document.createElement("div"),current=rootDiv,tagStack=[];null!==(t=nextToken());)if("<"!==t[0])current.appendChild(window.document.createTextNode((s=t,TEXTAREA_ELEMENT.innerHTML=s,s=TEXTAREA_ELEMENT.textContent,TEXTAREA_ELEMENT.textContent="",s)));else{if("/"===t[1]){tagStack.length&&tagStack[tagStack.length-1]===t.substr(2).replace(">","")&&(tagStack.pop(),current=current.parentNode);continue}var node,ts=parseTimeStamp(t.substr(1,t.length-2));if(ts){node=window.document.createProcessingInstruction("timestamp",ts),current.appendChild(node);continue}var m=t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!m)continue;if(!(node=createElement(m[1],m[3])))continue;if(!shouldAdd(current,node))continue;if(m[2]){var classes=m[2].split(".");classes.forEach((function(cl){var bgColor=/^bg_/.test(cl),colorName=bgColor?cl.slice(3):cl;if(DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)){var propName=bgColor?"background-color":"color",propValue=DEFAULT_COLOR_CLASS[colorName];node.style[propName]=propValue}})),node.className=classes.join(" ")}tagStack.push(m[1]),current.appendChild(node),current=node}return rootDiv}var strongRTLRanges=[[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 isStrongRTLChar(charCode){for(var i=0;i=currentRange[0]&&charCode<=currentRange[1])return!0}return!1}function determineBidi(cueDiv){var nodeStack=[],text="";if(!cueDiv||!cueDiv.childNodes)return"ltr";function pushNodes(nodeStack,node){for(var i=node.childNodes.length-1;i>=0;i--)nodeStack.push(node.childNodes[i])}function nextTextNode(nodeStack){if(!nodeStack||!nodeStack.length)return null;var node=nodeStack.pop(),text=node.textContent||node.innerText;if(text){var m=text.match(/^.*(\n|\r)/);return m?(nodeStack.length=0,m[0]):text}return"ruby"===node.tagName?nextTextNode(nodeStack):node.childNodes?(pushNodes(nodeStack,node),nextTextNode(nodeStack)):void 0}for(pushNodes(nodeStack,cueDiv);text=nextTextNode(nodeStack);)for(var i=0;i=0&&cue.line<=100))return cue.line;if(!cue.track||!cue.track.textTrackList||!cue.track.textTrackList.mediaElement)return-1;for(var track=cue.track,trackList=track.textTrackList,count=0,i=0;imaxPosition&&(position=position<0?-1:1,position*=Math.ceil(maxPosition/step)*step),linePos<0&&(position+=""===cue.vertical?containerBox.height:containerBox.width,axis=axis.reverse()),boxPosition.move(initialAxis,position)}else{var calculatedPercentage=boxPosition.lineHeight/containerBox.height*100;switch(cue.lineAlign){case"center":linePos-=calculatedPercentage/2;break;case"end":linePos-=calculatedPercentage}switch(cue.vertical){case"":styleBox.applyStyles({top:styleBox.formatStyle(linePos,"%")});break;case"rl":styleBox.applyStyles({left:styleBox.formatStyle(linePos,"%")});break;case"lr":styleBox.applyStyles({right:styleBox.formatStyle(linePos,"%")})}axis=["+y","-x","+x","-y"],boxPosition=new BoxPosition(styleBox)}var bestPosition=function(b,axis){for(var bestPosition,specifiedPosition=new BoxPosition(b),percentage=1,i=0;ip&&(bestPosition=new BoxPosition(b),percentage=p),b=new BoxPosition(specifiedPosition)}return bestPosition||specifiedPosition}(boxPosition,axis);styleBox.move(bestPosition.toCSSCompatValues(containerBox))}function WebVTT$1(){}StyleBox.prototype.applyStyles=function(styles,div){for(var prop in div=div||this.div,styles)styles.hasOwnProperty(prop)&&(div.style[prop]=styles[prop])},StyleBox.prototype.formatStyle=function(val,unit){return 0===val?0:val+unit},CueStyleBox.prototype=_objCreate(StyleBox.prototype),CueStyleBox.prototype.constructor=CueStyleBox,BoxPosition.prototype.move=function(axis,toMove){switch(toMove=void 0!==toMove?toMove:this.lineHeight,axis){case"+x":this.left+=toMove,this.right+=toMove;break;case"-x":this.left-=toMove,this.right-=toMove;break;case"+y":this.top+=toMove,this.bottom+=toMove;break;case"-y":this.top-=toMove,this.bottom-=toMove}},BoxPosition.prototype.overlaps=function(b2){return this.leftb2.left&&this.topb2.top},BoxPosition.prototype.overlapsAny=function(boxes){for(var i=0;i=container.top&&this.bottom<=container.bottom&&this.left>=container.left&&this.right<=container.right},BoxPosition.prototype.overlapsOppositeAxis=function(container,axis){switch(axis){case"+x":return this.leftcontainer.right;case"+y":return this.topcontainer.bottom}},BoxPosition.prototype.intersectPercentage=function(b2){return Math.max(0,Math.min(this.right,b2.right)-Math.max(this.left,b2.left))*Math.max(0,Math.min(this.bottom,b2.bottom)-Math.max(this.top,b2.top))/(this.height*this.width)},BoxPosition.prototype.toCSSCompatValues=function(reference){return{top:this.top-reference.top,bottom:reference.bottom-this.bottom,left:this.left-reference.left,right:reference.right-this.right,height:this.height,width:this.width}},BoxPosition.getSimpleBoxPosition=function(obj){var height=obj.div?obj.div.offsetHeight:obj.tagName?obj.offsetHeight:0,width=obj.div?obj.div.offsetWidth:obj.tagName?obj.offsetWidth:0,top=obj.div?obj.div.offsetTop:obj.tagName?obj.offsetTop:0;return{left:(obj=obj.div?obj.div.getBoundingClientRect():obj.tagName?obj.getBoundingClientRect():obj).left,right:obj.right,top:obj.top||top,height:obj.height||height,bottom:obj.bottom||top+(obj.height||height),width:obj.width||width}},WebVTT$1.StringDecoder=function(){return{decode:function(data){if(!data)return"";if("string"!=typeof data)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(data))}}},WebVTT$1.convertCueToDOMTree=function(window,cuetext){return window&&cuetext?parseContent(window,cuetext):null};WebVTT$1.processCues=function(window,cues,overlay){if(!window||!cues||!overlay)return null;for(;overlay.firstChild;)overlay.removeChild(overlay.firstChild);var paddedOverlay=window.document.createElement("div");if(paddedOverlay.style.position="absolute",paddedOverlay.style.left="0",paddedOverlay.style.right="0",paddedOverlay.style.top="0",paddedOverlay.style.bottom="0",paddedOverlay.style.margin="1.5%",overlay.appendChild(paddedOverlay),function(cues){for(var i=0;i100)throw new Error("Position must be between 0 and 100.");_position=value,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return _positionAlign},set:function(value){var setting=findAlignSetting(value);setting?(_positionAlign=setting,this.hasBeenReset=!0):console.warn("positionAlign: an invalid or illegal string was specified.")}},size:{enumerable:!0,get:function(){return _size},set:function(value){if(value<0||value>100)throw new Error("Size must be between 0 and 100.");_size=value,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return _align},set:function(value){var setting=findAlignSetting(value);if(!setting)throw new SyntaxError("align: an invalid or illegal alignment string was specified.");_align=setting,this.hasBeenReset=!0}}}),this.displayState=void 0}VTTCue.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var vttcue=VTTCue,scrollSetting={"":!0,up:!0};function isValidPercentValue(value){return"number"==typeof value&&value>=0&&value<=100}var vttregion=function(){var _width=100,_lines=3,_regionAnchorX=0,_regionAnchorY=100,_viewportAnchorX=0,_viewportAnchorY=100,_scroll="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return _width},set:function(value){if(!isValidPercentValue(value))throw new Error("Width must be between 0 and 100.");_width=value}},lines:{enumerable:!0,get:function(){return _lines},set:function(value){if("number"!=typeof value)throw new TypeError("Lines must be set to a number.");_lines=value}},regionAnchorY:{enumerable:!0,get:function(){return _regionAnchorY},set:function(value){if(!isValidPercentValue(value))throw new Error("RegionAnchorX must be between 0 and 100.");_regionAnchorY=value}},regionAnchorX:{enumerable:!0,get:function(){return _regionAnchorX},set:function(value){if(!isValidPercentValue(value))throw new Error("RegionAnchorY must be between 0 and 100.");_regionAnchorX=value}},viewportAnchorY:{enumerable:!0,get:function(){return _viewportAnchorY},set:function(value){if(!isValidPercentValue(value))throw new Error("ViewportAnchorY must be between 0 and 100.");_viewportAnchorY=value}},viewportAnchorX:{enumerable:!0,get:function(){return _viewportAnchorX},set:function(value){if(!isValidPercentValue(value))throw new Error("ViewportAnchorX must be between 0 and 100.");_viewportAnchorX=value}},scroll:{enumerable:!0,get:function(){return _scroll},set:function(value){var setting=function(value){return"string"==typeof value&&!!scrollSetting[value.toLowerCase()]&&value.toLowerCase()}(value);!1===setting?console.warn("Scroll: an invalid or illegal string was specified."):_scroll=setting}}})},browserIndex=createCommonjsModule((function(module){var vttjs=module.exports={WebVTT:vtt,VTTCue:vttcue,VTTRegion:vttregion};window_1.vttjs=vttjs,window_1.WebVTT=vttjs.WebVTT;var cueShim=vttjs.VTTCue,regionShim=vttjs.VTTRegion,nativeVTTCue=window_1.VTTCue,nativeVTTRegion=window_1.VTTRegion;vttjs.shim=function(){window_1.VTTCue=cueShim,window_1.VTTRegion=regionShim},vttjs.restore=function(){window_1.VTTCue=nativeVTTCue,window_1.VTTRegion=nativeVTTRegion},window_1.VTTCue||vttjs.shim()}));browserIndex.WebVTT,browserIndex.VTTCue,browserIndex.VTTRegion;class Tech extends Component$1{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},ready=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};options.reportTouchActivity=!1,super(null,options,ready),this.onDurationChange_=e=>this.onDurationChange(e),this.trackProgress_=e=>this.trackProgress(e),this.trackCurrentTime_=e=>this.trackCurrentTime(e),this.stopTrackingCurrentTime_=e=>this.stopTrackingCurrentTime(e),this.disposeSourceHandler_=e=>this.disposeSourceHandler(e),this.queuedHanders_=new Set,this.hasStarted_=!1,this.on("playing",(function(){this.hasStarted_=!0})),this.on("loadstart",(function(){this.hasStarted_=!1})),ALL.names.forEach((name=>{const props=ALL[name];options&&options[props.getterName]&&(this[props.privateName]=options[props.getterName])})),this.featuresProgressEvents||this.manualProgressOn(),this.featuresTimeupdateEvents||this.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach((track=>{!1===options["native".concat(track,"Tracks")]&&(this["featuresNative".concat(track,"Tracks")]=!1)})),!1===options.nativeCaptions||!1===options.nativeTextTracks?this.featuresNativeTextTracks=!1:!0!==options.nativeCaptions&&!0!==options.nativeTextTracks||(this.featuresNativeTextTracks=!0),this.featuresNativeTextTracks||this.emulateTextTracks(),this.preloadTextTracks=!1!==options.preloadTextTracks,this.autoRemoteTextTracks_=new ALL.text.ListClass,this.initTrackListeners(),options.nativeControlsForTouch||this.emitTapEvents(),this.constructor&&(this.name_=this.constructor.name||"Unknown Tech")}triggerSourceset(src){this.isReady_||this.one("ready",(()=>this.setTimeout((()=>this.triggerSourceset(src)),1))),this.trigger({src:src,type:"sourceset"})}manualProgressOn(){this.on("durationchange",this.onDurationChange_),this.manualProgress=!0,this.one("ready",this.trackProgress_)}manualProgressOff(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange_)}trackProgress(event){this.stopTrackingProgress(),this.progressInterval=this.setInterval(bind_(this,(function(){const numBufferedPercent=this.bufferedPercent();this.bufferedPercent_!==numBufferedPercent&&this.trigger("progress"),this.bufferedPercent_=numBufferedPercent,1===numBufferedPercent&&this.stopTrackingProgress()})),500)}onDurationChange(event){this.duration_=this.duration()}buffered(){return createTimeRanges$1(0,0)}bufferedPercent(){return bufferedPercent(this.buffered(),this.duration_)}stopTrackingProgress(){this.clearInterval(this.progressInterval)}manualTimeUpdatesOn(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime_),this.on("pause",this.stopTrackingCurrentTime_)}manualTimeUpdatesOff(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime_),this.off("pause",this.stopTrackingCurrentTime_)}trackCurrentTime(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval((function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}),250)}stopTrackingCurrentTime(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}dispose(){this.clearTracks(NORMAL.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),super.dispose()}clearTracks(types){(types=[].concat(types)).forEach((type=>{const list=this["".concat(type,"Tracks")]()||[];let i=list.length;for(;i--;){const track=list[i];"text"===type&&this.removeRemoteTextTrack(track),list.removeTrack(track)}}))}cleanupAutoTextTracks(){const list=this.autoRemoteTextTracks_||[];let i=list.length;for(;i--;){const track=list[i];this.removeRemoteTextTrack(track)}}reset(){}crossOrigin(){}setCrossOrigin(){}error(err){return void 0!==err&&(this.error_=new MediaError(err),this.trigger("error")),this.error_}played(){return this.hasStarted_?createTimeRanges$1(0,0):createTimeRanges$1()}play(){}setScrubbing(_isScrubbing){}scrubbing(){}setCurrentTime(_seconds){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}initTrackListeners(){NORMAL.names.forEach((name=>{const props=NORMAL[name],trackListChanges=()=>{this.trigger("".concat(name,"trackchange"))},tracks=this[props.getterName]();tracks.addEventListener("removetrack",trackListChanges),tracks.addEventListener("addtrack",trackListChanges),this.on("dispose",(()=>{tracks.removeEventListener("removetrack",trackListChanges),tracks.removeEventListener("addtrack",trackListChanges)}))}))}addWebVttScript_(){if(!window.WebVTT)if(document.body.contains(this.el())){if(!this.options_["vtt.js"]&&isPlain(browserIndex)&&Object.keys(browserIndex).length>0)return void this.trigger("vttjsloaded");const script=document.createElement("script");script.src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",script.onload=()=>{this.trigger("vttjsloaded")},script.onerror=()=>{this.trigger("vttjserror")},this.on("dispose",(()=>{script.onload=null,script.onerror=null})),window.WebVTT=!0,this.el().parentNode.appendChild(script)}else this.ready(this.addWebVttScript_)}emulateTextTracks(){const tracks=this.textTracks(),remoteTracks=this.remoteTextTracks(),handleAddTrack=e=>tracks.addTrack(e.track),handleRemoveTrack=e=>tracks.removeTrack(e.track);remoteTracks.on("addtrack",handleAddTrack),remoteTracks.on("removetrack",handleRemoveTrack),this.addWebVttScript_();const updateDisplay=()=>this.trigger("texttrackchange"),textTracksChanges=()=>{updateDisplay();for(let i=0;i4&&void 0!==arguments[4]?arguments[4]:{};const tracks=self.textTracks();options.kind=kind,label&&(options.label=label),language&&(options.language=language),options.tech=self;const track=new ALL.text.TrackClass(options);return tracks.addTrack(track),track}(this,kind,label,language)}createRemoteTextTrack(options){const track=merge$2(options,{tech:this});return new REMOTE.remoteTextEl.TrackClass(track)}addRemoteTextTrack(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},manualCleanup=arguments.length>1?arguments[1]:void 0;const htmlTrackElement=this.createRemoteTextTrack(options);return"boolean"!=typeof manualCleanup&&(manualCleanup=!1),this.remoteTextTrackEls().addTrackElement_(htmlTrackElement),this.remoteTextTracks().addTrack(htmlTrackElement.track),!1===manualCleanup&&this.ready((()=>this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track))),htmlTrackElement}removeRemoteTextTrack(track){const trackElement=this.remoteTextTrackEls().getTrackElementByTrack_(track);this.remoteTextTrackEls().removeTrackElement_(trackElement),this.remoteTextTracks().removeTrack(track),this.autoRemoteTextTracks_.removeTrack(track)}getVideoPlaybackQuality(){return{}}requestPictureInPicture(){return Promise.reject()}disablePictureInPicture(){return!0}setDisablePictureInPicture(){}requestVideoFrameCallback(cb){const id=newGUID();return!this.isReady_||this.paused()?(this.queuedHanders_.add(id),this.one("playing",(()=>{this.queuedHanders_.has(id)&&(this.queuedHanders_.delete(id),cb())}))):this.requestNamedAnimationFrame(id,cb),id}cancelVideoFrameCallback(id){this.queuedHanders_.has(id)?this.queuedHanders_.delete(id):this.cancelNamedAnimationFrame(id)}setPoster(){}playsinline(){}setPlaysinline(){}overrideNativeAudioTracks(override){}overrideNativeVideoTracks(override){}canPlayType(_type){return""}static canPlayType(_type){return""}static canPlaySource(srcObj,options){return Tech.canPlayType(srcObj.type)}static isTech(component){return component.prototype instanceof Tech||component instanceof Tech||component===Tech}static registerTech(name,tech){if(Tech.techs_||(Tech.techs_={}),!Tech.isTech(tech))throw new Error("Tech ".concat(name," must be a Tech"));if(!Tech.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!Tech.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return name=toTitleCase$1(name),Tech.techs_[name]=tech,Tech.techs_[toLowerCase(name)]=tech,"Tech"!==name&&Tech.defaultTechOrder_.push(name),tech}static getTech(name){if(name)return Tech.techs_&&Tech.techs_[name]?Tech.techs_[name]:(name=toTitleCase$1(name),window&&window.videojs&&window.videojs[name]?(log$1.warn("The ".concat(name," tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)")),window.videojs[name]):void 0)}}ALL.names.forEach((function(name){const props=ALL[name];Tech.prototype[props.getterName]=function(){return this[props.privateName]=this[props.privateName]||new props.ListClass,this[props.privateName]}})),Tech.prototype.featuresVolumeControl=!0,Tech.prototype.featuresMuteControl=!0,Tech.prototype.featuresFullscreenResize=!1,Tech.prototype.featuresPlaybackRate=!1,Tech.prototype.featuresProgressEvents=!1,Tech.prototype.featuresSourceset=!1,Tech.prototype.featuresTimeupdateEvents=!1,Tech.prototype.featuresNativeTextTracks=!1,Tech.prototype.featuresVideoFrameCallback=!1,Tech.withSourceHandlers=function(_Tech){_Tech.registerSourceHandler=function(handler,index){let handlers=_Tech.sourceHandlers;handlers||(handlers=_Tech.sourceHandlers=[]),void 0===index&&(index=handlers.length),handlers.splice(index,0,handler)},_Tech.canPlayType=function(type){const handlers=_Tech.sourceHandlers||[];let can;for(let i=0;isetSourceHelper(src,middlewares[src.type],next,player)),1)}function mediate(middleware,tech,method){let arg=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;const callMethod="call"+toTitleCase$1(method),middlewareValue=middleware.reduce(middlewareIterator(callMethod),arg),terminated=middlewareValue===TERMINATOR,returnValue=terminated?null:tech[method](middlewareValue);return executeRight(middleware,method,returnValue,terminated),returnValue}const allowedGetters={buffered:1,currentTime:1,duration:1,muted:1,played:1,paused:1,seekable:1,volume:1,ended:1},allowedSetters={setCurrentTime:1,setMuted:1,setVolume:1},allowedMediators={play:1,pause:1};function middlewareIterator(method){return(value,mw)=>value===TERMINATOR?TERMINATOR:mw[method]?mw[method](value):value}function executeRight(mws,method,value,terminated){for(let i=mws.length-1;i>=0;i--){const mw=mws[i];mw[method]&&mw[method](terminated,value)}}function getOrCreateFactory(player,mwFactory){const mws=middlewareInstances[player.id()];let mw=null;if(null==mws)return mw=mwFactory(player),middlewareInstances[player.id()]=[[mwFactory,mw]],mw;for(let i=0;i0&&void 0!==arguments[0]?arguments[0]:{},middleware=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],next=arguments.length>2?arguments[2]:void 0,player=arguments.length>3?arguments[3]:void 0,acc=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],lastRun=arguments.length>5&&void 0!==arguments[5]&&arguments[5];const[mwFactory,...mwrest]=middleware;if("string"==typeof mwFactory)setSourceHelper(src,middlewares[mwFactory],next,player,acc,lastRun);else if(mwFactory){const mw=getOrCreateFactory(player,mwFactory);if(!mw.setSource)return acc.push(mw),setSourceHelper(src,mwrest,next,player,acc,lastRun);mw.setSource(Object.assign({},src),(function(err,_src){if(err)return setSourceHelper(src,mwrest,next,player,acc,lastRun);acc.push(mw),setSourceHelper(_src,src.type===_src.type?mwrest:middlewares[_src.type],next,player,acc,lastRun)}))}else mwrest.length?setSourceHelper(src,mwrest,next,player,acc,lastRun):lastRun?next(src,acc):setSourceHelper(src,middlewares["*"],next,player,acc,!0)}const MimetypesKind={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",caf:"audio/x-caf",flac:"audio/flac",oga:"audio/ogg",wav:"audio/wav",m3u8:"application/x-mpegURL",mpd:"application/dash+xml",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"},getMimetype=function(){let src=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const ext=getFileExtension(src),mimetype=MimetypesKind[ext.toLowerCase()];return mimetype||""},filterSource=function(src){if(Array.isArray(src)){let newsrc=[];src.forEach((function(srcobj){srcobj=filterSource(srcobj),Array.isArray(srcobj)?newsrc=newsrc.concat(srcobj):isObject$1(srcobj)&&newsrc.push(srcobj)})),src=newsrc}else src="string"==typeof src&&src.trim()?[fixSource({src:src})]:isObject$1(src)&&"string"==typeof src.src&&src.src&&src.src.trim()?[fixSource(src)]:[];return src};function fixSource(src){if(!src.type){const mimetype=getMimetype(src.src);mimetype&&(src.type=mimetype)}return src}Component$1.registerComponent("MediaLoader",class extends Component$1{constructor(player,options,ready){if(super(player,merge$2({createEl:!1},options),ready),options.playerOptions.sources&&0!==options.playerOptions.sources.length)player.src(options.playerOptions.sources);else for(let i=0,j=options.playerOptions.techOrder;ithis.handleMouseOver(e),this.handleMouseOut_=e=>this.handleMouseOut(e),this.handleClick_=e=>this.handleClick(e),this.handleKeyDown_=e=>this.handleKeyDown(e),this.emitTapEvents(),this.enable()}createEl(){let tag=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};props=Object.assign({className:this.buildCSSClass(),tabIndex:0},props),"button"===tag&&log$1.error("Creating a ClickableComponent with an HTML element of ".concat(tag," is not supported; use a Button instead.")),attributes=Object.assign({role:"button"},attributes),this.tabIndex_=props.tabIndex;const el=createEl(tag,props,attributes);return el.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(el),el}dispose(){this.controlTextEl_=null,super.dispose()}createControlTextEl(el){return this.controlTextEl_=createEl("span",{className:"vjs-control-text"},{"aria-live":"polite"}),el&&el.appendChild(this.controlTextEl_),this.controlText(this.controlText_,el),this.controlTextEl_}controlText(text){let el=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.el();if(void 0===text)return this.controlText_||"Need Text";const localizedText=this.localize(text);this.controlText_=text,textContent(this.controlTextEl_,localizedText),this.nonIconControl||this.player_.options_.noUITitleAttributes||el.setAttribute("title",localizedText)}buildCSSClass(){return"vjs-control vjs-button ".concat(super.buildCSSClass())}enable(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),void 0!==this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick_),this.on("keydown",this.handleKeyDown_))}disable(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),void 0!==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_)}handleLanguagechange(){this.controlText(this.controlText_)}handleClick(event){this.options_.clickHandler&&this.options_.clickHandler.call(this,arguments)}handleKeyDown(event){keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter")?(event.preventDefault(),event.stopPropagation(),this.trigger("click")):super.handleKeyDown(event)}}Component$1.registerComponent("ClickableComponent",ClickableComponent);class PosterImage extends ClickableComponent{constructor(player,options){super(player,options),this.update(),this.update_=e=>this.update(e),player.on("posterchange",this.update_)}dispose(){this.player().off("posterchange",this.update_),super.dispose()}createEl(){return createEl("div",{className:"vjs-poster"})}crossOrigin(value){if(void 0===value)return this.$("img")?this.$("img").crossOrigin:this.player_.tech_&&this.player_.tech_.isReady_?this.player_.crossOrigin():this.player_.options_.crossOrigin||this.player_.options_.crossorigin||null;null===value||"anonymous"===value||"use-credentials"===value?this.$("img")&&(this.$("img").crossOrigin=value):this.player_.log.warn('crossOrigin must be null, "anonymous" or "use-credentials", given "'.concat(value,'"'))}update(event){const url=this.player().poster();this.setSrc(url),url?this.show():this.hide()}setSrc(url){url?(this.$("img")||this.el_.appendChild(createEl("picture",{className:"vjs-poster",tabIndex:-1},{},createEl("img",{loading:"lazy",crossOrigin:this.crossOrigin()},{alt:""}))),this.$("img").src=url):this.el_.textContent=""}handleClick(event){this.player_.controls()&&(this.player_.tech(!0)&&this.player_.tech(!0).focus(),this.player_.paused()?silencePromise(this.player_.play()):this.player_.pause())}}PosterImage.prototype.crossorigin=PosterImage.prototype.crossOrigin,Component$1.registerComponent("PosterImage",PosterImage);const fontMap={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 constructColor(color,opacity){let hex;if(4===color.length)hex=color[1]+color[1]+color[2]+color[2]+color[3]+color[3];else{if(7!==color.length)throw new Error("Invalid color code provided, "+color+"; must be formatted as e.g. #f0e or #f604e2.");hex=color.slice(1)}return"rgba("+parseInt(hex.slice(0,2),16)+","+parseInt(hex.slice(2,4),16)+","+parseInt(hex.slice(4,6),16)+","+opacity+")"}function tryUpdateStyle(el,style,rule){try{el.style[style]=rule}catch(e){return}}Component$1.registerComponent("TextTrackDisplay",class extends Component$1{constructor(player,options,ready){super(player,options,ready);const updateDisplayHandler=e=>this.updateDisplay(e);player.on("loadstart",(e=>this.toggleDisplay(e))),player.on("texttrackchange",updateDisplayHandler),player.on("loadedmetadata",(e=>this.preselectTrack(e))),player.ready(bind_(this,(function(){if(player.tech_&&player.tech_.featuresNativeTextTracks)return void this.hide();player.on("fullscreenchange",updateDisplayHandler),player.on("playerresize",updateDisplayHandler);const screenOrientation=window.screen.orientation||window,changeOrientationEvent=window.screen.orientation?"change":"orientationchange";screenOrientation.addEventListener(changeOrientationEvent,updateDisplayHandler),player.on("dispose",(()=>screenOrientation.removeEventListener(changeOrientationEvent,updateDisplayHandler)));const tracks=this.options_.playerOptions.tracks||[];for(let i=0;i!track.activeCues)))return;const cues=[];for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};tag="button",props=Object.assign({className:this.buildCSSClass()},props),attributes=Object.assign({type:"button"},attributes);const el=createEl("button",props,attributes);return el.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(el),el}addChild(child){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const className=this.constructor.name;return log$1.warn("Adding an actionable (user controllable) child to a Button (".concat(className,") is not supported; use a ClickableComponent instead.")),Component$1.prototype.addChild.call(this,child,options)}enable(){super.enable(),this.el_.removeAttribute("disabled")}disable(){super.disable(),this.el_.setAttribute("disabled","disabled")}handleKeyDown(event){keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter")?event.stopPropagation():super.handleKeyDown(event)}}Component$1.registerComponent("Button",Button);class BigPlayButton extends Button{constructor(player,options){super(player,options),this.mouseused_=!1,this.on("mousedown",(e=>this.handleMouseDown(e)))}buildCSSClass(){return"vjs-big-play-button"}handleClick(event){const playPromise=this.player_.play();if(this.mouseused_&&event.clientX&&event.clientY)return silencePromise(playPromise),void(this.player_.tech(!0)&&this.player_.tech(!0).focus());const cb=this.player_.getChild("controlBar"),playToggle=cb&&cb.getChild("playToggle");if(!playToggle)return void this.player_.tech(!0).focus();const playFocus=()=>playToggle.focus();isPromise(playPromise)?playPromise.then(playFocus,(()=>{})):this.setTimeout(playFocus,1)}handleKeyDown(event){this.mouseused_=!1,super.handleKeyDown(event)}handleMouseDown(event){this.mouseused_=!0}}BigPlayButton.prototype.controlText_="Play Video",Component$1.registerComponent("BigPlayButton",BigPlayButton);Component$1.registerComponent("CloseButton",class extends Button{constructor(player,options){super(player,options),this.controlText(options&&options.controlText||this.localize("Close"))}buildCSSClass(){return"vjs-close-button ".concat(super.buildCSSClass())}handleClick(event){this.trigger({type:"close",bubbles:!1})}handleKeyDown(event){keycode.isEventKey(event,"Esc")?(event.preventDefault(),event.stopPropagation(),this.trigger("click")):super.handleKeyDown(event)}});class PlayToggle extends Button{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(player,options),options.replay=void 0===options.replay||options.replay,this.on(player,"play",(e=>this.handlePlay(e))),this.on(player,"pause",(e=>this.handlePause(e))),options.replay&&this.on(player,"ended",(e=>this.handleEnded(e)))}buildCSSClass(){return"vjs-play-control ".concat(super.buildCSSClass())}handleClick(event){this.player_.paused()?silencePromise(this.player_.play()):this.player_.pause()}handleSeeked(event){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(event):this.handlePlay(event)}handlePlay(event){this.removeClass("vjs-ended","vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")}handlePause(event){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")}handleEnded(event){this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.controlText("Replay"),this.one(this.player_,"seeked",(e=>this.handleSeeked(e)))}}PlayToggle.prototype.controlText_="Play",Component$1.registerComponent("PlayToggle",PlayToggle);class TimeDisplay extends Component$1{constructor(player,options){super(player,options),this.on(player,["timeupdate","ended"],(e=>this.updateContent(e))),this.updateTextNode_()}createEl(){const className=this.buildCSSClass(),el=super.createEl("div",{className:"".concat(className," vjs-time-control vjs-control")}),span=createEl("span",{className:"vjs-control-text",textContent:"".concat(this.localize(this.labelText_)," ")},{role:"presentation"});return el.appendChild(span),this.contentEl_=createEl("span",{className:"".concat(className,"-display")},{role:"presentation"}),el.appendChild(this.contentEl_),el}dispose(){this.contentEl_=null,this.textNode_=null,super.dispose()}updateTextNode_(){let time=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;time=formatTime(time),this.formattedTime_!==time&&(this.formattedTime_=time,this.requestNamedAnimationFrame("TimeDisplay#updateTextNode_",(()=>{if(!this.contentEl_)return;let oldNode=this.textNode_;oldNode&&this.contentEl_.firstChild!==oldNode&&(oldNode=null,log$1.warn("TimeDisplay#updateTextnode_: Prevented replacement of text node element since it was no longer a child of this node. Appending a new node instead.")),this.textNode_=document.createTextNode(this.formattedTime_),this.textNode_&&(oldNode?this.contentEl_.replaceChild(this.textNode_,oldNode):this.contentEl_.appendChild(this.textNode_))})))}updateContent(event){}}TimeDisplay.prototype.labelText_="Time",TimeDisplay.prototype.controlText_="Time",Component$1.registerComponent("TimeDisplay",TimeDisplay);class CurrentTimeDisplay extends TimeDisplay{buildCSSClass(){return"vjs-current-time"}updateContent(event){let time;time=this.player_.ended()?this.player_.duration():this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),this.updateTextNode_(time)}}CurrentTimeDisplay.prototype.labelText_="Current Time",CurrentTimeDisplay.prototype.controlText_="Current Time",Component$1.registerComponent("CurrentTimeDisplay",CurrentTimeDisplay);class DurationDisplay extends TimeDisplay{constructor(player,options){super(player,options);const updateContent=e=>this.updateContent(e);this.on(player,"durationchange",updateContent),this.on(player,"loadstart",updateContent),this.on(player,"loadedmetadata",updateContent)}buildCSSClass(){return"vjs-duration"}updateContent(event){const duration=this.player_.duration();this.updateTextNode_(duration)}}DurationDisplay.prototype.labelText_="Duration",DurationDisplay.prototype.controlText_="Duration",Component$1.registerComponent("DurationDisplay",DurationDisplay);Component$1.registerComponent("TimeDivider",class extends Component$1{createEl(){const el=super.createEl("div",{className:"vjs-time-control vjs-time-divider"},{"aria-hidden":!0}),div=super.createEl("div"),span=super.createEl("span",{textContent:"/"});return div.appendChild(span),el.appendChild(div),el}});class RemainingTimeDisplay extends TimeDisplay{constructor(player,options){super(player,options),this.on(player,"durationchange",(e=>this.updateContent(e)))}buildCSSClass(){return"vjs-remaining-time"}createEl(){const el=super.createEl();return!1!==this.options_.displayNegative&&el.insertBefore(createEl("span",{},{"aria-hidden":!0},"-"),this.contentEl_),el}updateContent(event){if("number"!=typeof this.player_.duration())return;let time;time=this.player_.ended()?0:this.player_.remainingTimeDisplay?this.player_.remainingTimeDisplay():this.player_.remainingTime(),this.updateTextNode_(time)}}RemainingTimeDisplay.prototype.labelText_="Remaining Time",RemainingTimeDisplay.prototype.controlText_="Remaining Time",Component$1.registerComponent("RemainingTimeDisplay",RemainingTimeDisplay);Component$1.registerComponent("LiveDisplay",class extends Component$1{constructor(player,options){super(player,options),this.updateShowing(),this.on(this.player(),"durationchange",(e=>this.updateShowing(e)))}createEl(){const el=super.createEl("div",{className:"vjs-live-control vjs-control"});return this.contentEl_=createEl("div",{className:"vjs-live-display"},{"aria-live":"off"}),this.contentEl_.appendChild(createEl("span",{className:"vjs-control-text",textContent:"".concat(this.localize("Stream Type")," ")})),this.contentEl_.appendChild(document.createTextNode(this.localize("LIVE"))),el.appendChild(this.contentEl_),el}dispose(){this.contentEl_=null,super.dispose()}updateShowing(event){this.player().duration()===1/0?this.show():this.hide()}});class SeekToLive extends Button{constructor(player,options){super(player,options),this.updateLiveEdgeStatus(),this.player_.liveTracker&&(this.updateLiveEdgeStatusHandler_=e=>this.updateLiveEdgeStatus(e),this.on(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_))}createEl(){const el=super.createEl("button",{className:"vjs-seek-to-live-control vjs-control"});return this.textEl_=createEl("span",{className:"vjs-seek-to-live-text",textContent:this.localize("LIVE")},{"aria-hidden":"true"}),el.appendChild(this.textEl_),el}updateLiveEdgeStatus(){!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"))}handleClick(){this.player_.liveTracker.seekToLiveEdge()}dispose(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_),this.textEl_=null,super.dispose()}}function clamp(number,min,max){return number=Number(number),Math.min(max,Math.max(min,isNaN(number)?min:number))}SeekToLive.prototype.controlText_="Seek to live, currently playing live",Component$1.registerComponent("SeekToLive",SeekToLive);var Num=Object.freeze({__proto__:null,clamp:clamp});class Slider extends Component$1{constructor(player,options){super(player,options),this.handleMouseDown_=e=>this.handleMouseDown(e),this.handleMouseUp_=e=>this.handleMouseUp(e),this.handleKeyDown_=e=>this.handleKeyDown(e),this.handleClick_=e=>this.handleClick(e),this.handleMouseMove_=e=>this.handleMouseMove(e),this.update_=e=>this.update(e),this.bar=this.getChild(this.options_.barName),this.vertical(!!this.options_.vertical),this.enable()}enabled(){return this.enabled_}enable(){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)}disable(){if(!this.enabled())return;const doc=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(doc,"mousemove",this.handleMouseMove_),this.off(doc,"mouseup",this.handleMouseUp_),this.off(doc,"touchmove",this.handleMouseMove_),this.off(doc,"touchend",this.handleMouseUp_),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1}createEl(type){let props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return props.className=props.className+" vjs-slider",props=Object.assign({tabIndex:0},props),attributes=Object.assign({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100},attributes),super.createEl(type,props,attributes)}handleMouseDown(event){const doc=this.bar.el_.ownerDocument;"mousedown"===event.type&&event.preventDefault(),"touchstart"!==event.type||IS_CHROME||event.preventDefault(),blockTextSelection(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(doc,"mousemove",this.handleMouseMove_),this.on(doc,"mouseup",this.handleMouseUp_),this.on(doc,"touchmove",this.handleMouseMove_),this.on(doc,"touchend",this.handleMouseUp_),this.handleMouseMove(event,!0)}handleMouseMove(event){}handleMouseUp(event){const doc=this.bar.el_.ownerDocument;unblockTextSelection(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(doc,"mousemove",this.handleMouseMove_),this.off(doc,"mouseup",this.handleMouseUp_),this.off(doc,"touchmove",this.handleMouseMove_),this.off(doc,"touchend",this.handleMouseUp_),this.update()}update(){if(!this.el_||!this.bar)return;const progress=this.getProgress();return progress===this.progress_||(this.progress_=progress,this.requestNamedAnimationFrame("Slider#update",(()=>{const sizeKey=this.vertical()?"height":"width";this.bar.el().style[sizeKey]=(100*progress).toFixed(2)+"%"}))),progress}getProgress(){return Number(clamp(this.getPercent(),0,1).toFixed(4))}calculateDistance(event){const position=getPointerPosition(this.el_,event);return this.vertical()?position.y:position.x}handleKeyDown(event){keycode.isEventKey(event,"Left")||keycode.isEventKey(event,"Down")?(event.preventDefault(),event.stopPropagation(),this.stepBack()):keycode.isEventKey(event,"Right")||keycode.isEventKey(event,"Up")?(event.preventDefault(),event.stopPropagation(),this.stepForward()):super.handleKeyDown(event)}handleClick(event){event.stopPropagation(),event.preventDefault()}vertical(bool){if(void 0===bool)return this.vertical_||!1;this.vertical_=!!bool,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")}}Component$1.registerComponent("Slider",Slider);const percentify=(time,end)=>clamp(time/end*100,0,100).toFixed(2)+"%";Component$1.registerComponent("LoadProgressBar",class extends Component$1{constructor(player,options){super(player,options),this.partEls_=[],this.on(player,"progress",(e=>this.update(e)))}createEl(){const el=super.createEl("div",{className:"vjs-load-progress"}),wrapper=createEl("span",{className:"vjs-control-text"}),loadedText=createEl("span",{textContent:this.localize("Loaded")}),separator=document.createTextNode(": ");return this.percentageEl_=createEl("span",{className:"vjs-control-text-loaded-percentage",textContent:"0%"}),el.appendChild(wrapper),wrapper.appendChild(loadedText),wrapper.appendChild(separator),wrapper.appendChild(this.percentageEl_),el}dispose(){this.partEls_=null,this.percentageEl_=null,super.dispose()}update(event){this.requestNamedAnimationFrame("LoadProgressBar#update",(()=>{const liveTracker=this.player_.liveTracker,buffered=this.player_.buffered(),duration=liveTracker&&liveTracker.isLive()?liveTracker.seekableEnd():this.player_.duration(),bufferedEnd=this.player_.bufferedEnd(),children=this.partEls_,percent=percentify(bufferedEnd,duration);this.percent_!==percent&&(this.el_.style.width=percent,textContent(this.percentageEl_,percent),this.percent_=percent);for(let i=0;ibuffered.length;i--)this.el_.removeChild(children[i-1]);children.length=buffered.length}))}});Component$1.registerComponent("TimeTooltip",class extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})}update(seekBarRect,seekBarPoint,content){const tooltipRect=findPosition(this.el_),playerRect=getBoundingClientRect(this.player_.el()),seekBarPointPx=seekBarRect.width*seekBarPoint;if(!playerRect||!tooltipRect)return;const spaceLeftOfPoint=seekBarRect.left-playerRect.left+seekBarPointPx,spaceRightOfPoint=seekBarRect.width-seekBarPointPx+(playerRect.right-seekBarRect.right);let pullTooltipBy=tooltipRect.width/2;spaceLeftOfPointtooltipRect.width&&(pullTooltipBy=tooltipRect.width),pullTooltipBy=Math.round(pullTooltipBy),this.el_.style.right="-".concat(pullTooltipBy,"px"),this.write(content)}write(content){textContent(this.el_,content)}updateTime(seekBarRect,seekBarPoint,time,cb){this.requestNamedAnimationFrame("TimeTooltip#updateTime",(()=>{let content;const duration=this.player_.duration();if(this.player_.liveTracker&&this.player_.liveTracker.isLive()){const liveWindow=this.player_.liveTracker.liveWindow(),secondsBehind=liveWindow-seekBarPoint*liveWindow;content=(secondsBehind<1?"":"-")+formatTime(secondsBehind,liveWindow)}else content=formatTime(time,duration);this.update(seekBarRect,seekBarPoint,content),cb&&cb()}))}});class PlayProgressBar extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})}update(seekBarRect,seekBarPoint){const timeTooltip=this.getChild("timeTooltip");if(!timeTooltip)return;const time=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();timeTooltip.updateTime(seekBarRect,seekBarPoint,time)}}PlayProgressBar.prototype.options_={children:[]},IS_IOS||IS_ANDROID||PlayProgressBar.prototype.options_.children.push("timeTooltip"),Component$1.registerComponent("PlayProgressBar",PlayProgressBar);class MouseTimeDisplay extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-mouse-display"})}update(seekBarRect,seekBarPoint){const time=seekBarPoint*this.player_.duration();this.getChild("timeTooltip").updateTime(seekBarRect,seekBarPoint,time,(()=>{this.el_.style.left="".concat(seekBarRect.width*seekBarPoint,"px")}))}}MouseTimeDisplay.prototype.options_={children:["timeTooltip"]},Component$1.registerComponent("MouseTimeDisplay",MouseTimeDisplay);class SeekBar extends Slider{constructor(player,options){super(player,options),this.setEventHandlers_()}setEventHandlers_(){this.update_=bind_(this,this.update),this.update=throttle(this.update_,30),this.on(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.enableIntervalHandler_=e=>this.enableInterval_(e),this.disableIntervalHandler_=e=>this.disableInterval_(e),this.on(this.player_,["playing"],this.enableIntervalHandler_),this.on(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.on(document,"visibilitychange",this.toggleVisibility_)}toggleVisibility_(e){"hidden"===document.visibilityState?(this.cancelNamedAnimationFrame("SeekBar#update"),this.cancelNamedAnimationFrame("Slider#update"),this.disableInterval_(e)):(this.player_.ended()||this.player_.paused()||this.enableInterval_(),this.update())}enableInterval_(){this.updateInterval||(this.updateInterval=this.setInterval(this.update,30))}disableInterval_(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&e&&"ended"!==e.type||this.updateInterval&&(this.clearInterval(this.updateInterval),this.updateInterval=null)}createEl(){return super.createEl("div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})}update(event){if("hidden"===document.visibilityState)return;const percent=super.update();return this.requestNamedAnimationFrame("SeekBar#update",(()=>{const currentTime=this.player_.ended()?this.player_.duration():this.getCurrentTime_(),liveTracker=this.player_.liveTracker;let duration=this.player_.duration();liveTracker&&liveTracker.isLive()&&(duration=this.player_.liveTracker.liveCurrentTime()),this.percent_!==percent&&(this.el_.setAttribute("aria-valuenow",(100*percent).toFixed(2)),this.percent_=percent),this.currentTime_===currentTime&&this.duration_===duration||(this.el_.setAttribute("aria-valuetext",this.localize("progress bar timing: currentTime={1} duration={2}",[formatTime(currentTime,duration),formatTime(duration,duration)],"{1} of {2}")),this.currentTime_=currentTime,this.duration_=duration),this.bar&&this.bar.update(getBoundingClientRect(this.el()),this.getProgress())})),percent}userSeek_(ct){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&this.player_.liveTracker.nextSeekedFromUser(),this.player_.currentTime(ct)}getCurrentTime_(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()}getPercent(){const currentTime=this.getCurrentTime_();let percent;const liveTracker=this.player_.liveTracker;return liveTracker&&liveTracker.isLive()?(percent=(currentTime-liveTracker.seekableStart())/liveTracker.liveWindow(),liveTracker.atLiveEdge()&&(percent=1)):percent=currentTime/this.player_.duration(),percent}handleMouseDown(event){isSingleLeftClick(event)&&(event.stopPropagation(),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),super.handleMouseDown(event))}handleMouseMove(event){let newTime,mouseDown=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!isSingleLeftClick(event))return;mouseDown||this.player_.scrubbing()||this.player_.scrubbing(!0);const distance=this.calculateDistance(event),liveTracker=this.player_.liveTracker;if(liveTracker&&liveTracker.isLive()){if(distance>=.99)return void liveTracker.seekToLiveEdge();const seekableStart=liveTracker.seekableStart(),seekableEnd=liveTracker.liveCurrentTime();if(newTime=seekableStart+distance*liveTracker.liveWindow(),newTime>=seekableEnd&&(newTime=seekableEnd),newTime<=seekableStart&&(newTime=seekableStart+.1),newTime===1/0)return}else newTime=distance*this.player_.duration(),newTime===this.player_.duration()&&(newTime-=.1);this.userSeek_(newTime)}enable(){super.enable();const mouseTimeDisplay=this.getChild("mouseTimeDisplay");mouseTimeDisplay&&mouseTimeDisplay.show()}disable(){super.disable();const mouseTimeDisplay=this.getChild("mouseTimeDisplay");mouseTimeDisplay&&mouseTimeDisplay.hide()}handleMouseUp(event){super.handleMouseUp(event),event&&event.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying?silencePromise(this.player_.play()):this.update_()}stepForward(){this.userSeek_(this.player_.currentTime()+5)}stepBack(){this.userSeek_(this.player_.currentTime()-5)}handleAction(event){this.player_.paused()?this.player_.play():this.player_.pause()}handleKeyDown(event){const liveTracker=this.player_.liveTracker;if(keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter"))event.preventDefault(),event.stopPropagation(),this.handleAction(event);else if(keycode.isEventKey(event,"Home"))event.preventDefault(),event.stopPropagation(),this.userSeek_(0);else if(keycode.isEventKey(event,"End"))event.preventDefault(),event.stopPropagation(),liveTracker&&liveTracker.isLive()?this.userSeek_(liveTracker.liveCurrentTime()):this.userSeek_(this.player_.duration());else if(/^[0-9]$/.test(keycode(event))){event.preventDefault(),event.stopPropagation();const gotoFraction=10*(keycode.codes[keycode(event)]-keycode.codes[0])/100;liveTracker&&liveTracker.isLive()?this.userSeek_(liveTracker.seekableStart()+liveTracker.liveWindow()*gotoFraction):this.userSeek_(this.player_.duration()*gotoFraction)}else keycode.isEventKey(event,"PgDn")?(event.preventDefault(),event.stopPropagation(),this.userSeek_(this.player_.currentTime()-60)):keycode.isEventKey(event,"PgUp")?(event.preventDefault(),event.stopPropagation(),this.userSeek_(this.player_.currentTime()+60)):super.handleKeyDown(event)}dispose(){this.disableInterval_(),this.off(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.update),this.off(this.player_,["playing"],this.enableIntervalHandler_),this.off(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.off(document,"visibilitychange",this.toggleVisibility_),super.dispose()}}SeekBar.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},IS_IOS||IS_ANDROID||SeekBar.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),Component$1.registerComponent("SeekBar",SeekBar);class ProgressControl extends Component$1{constructor(player,options){super(player,options),this.handleMouseMove=throttle(bind_(this,this.handleMouseMove),30),this.throttledHandleMouseSeek=throttle(bind_(this,this.handleMouseSeek),30),this.handleMouseUpHandler_=e=>this.handleMouseUp(e),this.handleMouseDownHandler_=e=>this.handleMouseDown(e),this.enable()}createEl(){return super.createEl("div",{className:"vjs-progress-control vjs-control"})}handleMouseMove(event){const seekBar=this.getChild("seekBar");if(!seekBar)return;const playProgressBar=seekBar.getChild("playProgressBar"),mouseTimeDisplay=seekBar.getChild("mouseTimeDisplay");if(!playProgressBar&&!mouseTimeDisplay)return;const seekBarEl=seekBar.el(),seekBarRect=findPosition(seekBarEl);let seekBarPoint=getPointerPosition(seekBarEl,event).x;seekBarPoint=clamp(seekBarPoint,0,1),mouseTimeDisplay&&mouseTimeDisplay.update(seekBarRect,seekBarPoint),playProgressBar&&playProgressBar.update(seekBarRect,seekBar.getProgress())}handleMouseSeek(event){const seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseMove(event)}enabled(){return this.enabled_}disable(){if(this.children().forEach((child=>child.disable&&child.disable())),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDownHandler_),this.off(this.el_,"mousemove",this.handleMouseMove),this.removeListenersAddedOnMousedownAndTouchstart(),this.addClass("disabled"),this.enabled_=!1,this.player_.scrubbing())){const seekBar=this.getChild("seekBar");this.player_.scrubbing(!1),seekBar.videoWasPlaying&&silencePromise(this.player_.play())}}enable(){this.children().forEach((child=>child.enable&&child.enable())),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDownHandler_),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)}removeListenersAddedOnMousedownAndTouchstart(){const doc=this.el_.ownerDocument;this.off(doc,"mousemove",this.throttledHandleMouseSeek),this.off(doc,"touchmove",this.throttledHandleMouseSeek),this.off(doc,"mouseup",this.handleMouseUpHandler_),this.off(doc,"touchend",this.handleMouseUpHandler_)}handleMouseDown(event){const doc=this.el_.ownerDocument,seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseDown(event),this.on(doc,"mousemove",this.throttledHandleMouseSeek),this.on(doc,"touchmove",this.throttledHandleMouseSeek),this.on(doc,"mouseup",this.handleMouseUpHandler_),this.on(doc,"touchend",this.handleMouseUpHandler_)}handleMouseUp(event){const seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseUp(event),this.removeListenersAddedOnMousedownAndTouchstart()}}ProgressControl.prototype.options_={children:["seekBar"]},Component$1.registerComponent("ProgressControl",ProgressControl);class PictureInPictureToggle extends Button{constructor(player,options){super(player,options),this.on(player,["enterpictureinpicture","leavepictureinpicture"],(e=>this.handlePictureInPictureChange(e))),this.on(player,["disablepictureinpicturechanged","loadedmetadata"],(e=>this.handlePictureInPictureEnabledChange(e))),this.on(player,["loadedmetadata","audioonlymodechange","audiopostermodechange"],(()=>{"audio"===player.currentType().substring(0,5)||player.audioPosterMode()||player.audioOnlyMode()?(player.isInPictureInPicture()&&player.exitPictureInPicture(),this.hide()):this.show()})),this.disable()}buildCSSClass(){return"vjs-picture-in-picture-control ".concat(super.buildCSSClass())}handlePictureInPictureEnabledChange(){document.pictureInPictureEnabled&&!1===this.player_.disablePictureInPicture()||this.player_.options_.enableDocumentPictureInPicture&&"documentPictureInPicture"in window?this.enable():this.disable()}handlePictureInPictureChange(event){this.player_.isInPictureInPicture()?this.controlText("Exit Picture-in-Picture"):this.controlText("Picture-in-Picture"),this.handlePictureInPictureEnabledChange()}handleClick(event){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()}}PictureInPictureToggle.prototype.controlText_="Picture-in-Picture",Component$1.registerComponent("PictureInPictureToggle",PictureInPictureToggle);class FullscreenToggle extends Button{constructor(player,options){super(player,options),this.on(player,"fullscreenchange",(e=>this.handleFullscreenChange(e))),!1===document[player.fsApi_.fullscreenEnabled]&&this.disable()}buildCSSClass(){return"vjs-fullscreen-control ".concat(super.buildCSSClass())}handleFullscreenChange(event){this.player_.isFullscreen()?this.controlText("Exit Fullscreen"):this.controlText("Fullscreen")}handleClick(event){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()}}FullscreenToggle.prototype.controlText_="Fullscreen",Component$1.registerComponent("FullscreenToggle",FullscreenToggle);Component$1.registerComponent("VolumeLevel",class extends Component$1{createEl(){const el=super.createEl("div",{className:"vjs-volume-level"});return el.appendChild(super.createEl("span",{className:"vjs-control-text"})),el}});Component$1.registerComponent("VolumeLevelTooltip",class extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-volume-tooltip"},{"aria-hidden":"true"})}update(rangeBarRect,rangeBarPoint,vertical,content){if(!vertical){const tooltipRect=getBoundingClientRect(this.el_),playerRect=getBoundingClientRect(this.player_.el()),volumeBarPointPx=rangeBarRect.width*rangeBarPoint;if(!playerRect||!tooltipRect)return;const spaceLeftOfPoint=rangeBarRect.left-playerRect.left+volumeBarPointPx,spaceRightOfPoint=rangeBarRect.width-volumeBarPointPx+(playerRect.right-rangeBarRect.right);let pullTooltipBy=tooltipRect.width/2;spaceLeftOfPointtooltipRect.width&&(pullTooltipBy=tooltipRect.width),this.el_.style.right="-".concat(pullTooltipBy,"px")}this.write("".concat(content,"%"))}write(content){textContent(this.el_,content)}updateVolume(rangeBarRect,rangeBarPoint,vertical,volume,cb){this.requestNamedAnimationFrame("VolumeLevelTooltip#updateVolume",(()=>{this.update(rangeBarRect,rangeBarPoint,vertical,volume.toFixed(0)),cb&&cb()}))}});class MouseVolumeLevelDisplay extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-mouse-display"})}update(rangeBarRect,rangeBarPoint,vertical){const volume=100*rangeBarPoint;this.getChild("volumeLevelTooltip").updateVolume(rangeBarRect,rangeBarPoint,vertical,volume,(()=>{vertical?this.el_.style.bottom="".concat(rangeBarRect.height*rangeBarPoint,"px"):this.el_.style.left="".concat(rangeBarRect.width*rangeBarPoint,"px")}))}}MouseVolumeLevelDisplay.prototype.options_={children:["volumeLevelTooltip"]},Component$1.registerComponent("MouseVolumeLevelDisplay",MouseVolumeLevelDisplay);class VolumeBar extends Slider{constructor(player,options){super(player,options),this.on("slideractive",(e=>this.updateLastVolume_(e))),this.on(player,"volumechange",(e=>this.updateARIAAttributes(e))),player.ready((()=>this.updateARIAAttributes()))}createEl(){return super.createEl("div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})}handleMouseDown(event){isSingleLeftClick(event)&&super.handleMouseDown(event)}handleMouseMove(event){const mouseVolumeLevelDisplay=this.getChild("mouseVolumeLevelDisplay");if(mouseVolumeLevelDisplay){const volumeBarEl=this.el(),volumeBarRect=getBoundingClientRect(volumeBarEl),vertical=this.vertical();let volumeBarPoint=getPointerPosition(volumeBarEl,event);volumeBarPoint=vertical?volumeBarPoint.y:volumeBarPoint.x,volumeBarPoint=clamp(volumeBarPoint,0,1),mouseVolumeLevelDisplay.update(volumeBarRect,volumeBarPoint,vertical)}isSingleLeftClick(event)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(event)))}checkMuted(){this.player_.muted()&&this.player_.muted(!1)}getPercent(){return this.player_.muted()?0:this.player_.volume()}stepForward(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)}stepBack(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)}updateARIAAttributes(event){const ariaValue=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",ariaValue),this.el_.setAttribute("aria-valuetext",ariaValue+"%")}volumeAsPercentage_(){return Math.round(100*this.player_.volume())}updateLastVolume_(){const volumeBeforeDrag=this.player_.volume();this.one("sliderinactive",(()=>{0===this.player_.volume()&&this.player_.lastVolume_(volumeBeforeDrag)}))}}VolumeBar.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},IS_IOS||IS_ANDROID||VolumeBar.prototype.options_.children.splice(0,0,"mouseVolumeLevelDisplay"),VolumeBar.prototype.playerEvent="volumechange",Component$1.registerComponent("VolumeBar",VolumeBar);class VolumeControl extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};options.vertical=options.vertical||!1,(void 0===options.volumeBar||isPlain(options.volumeBar))&&(options.volumeBar=options.volumeBar||{},options.volumeBar.vertical=options.vertical),super(player,options),function(self,player){player.tech_&&!player.tech_.featuresVolumeControl&&self.addClass("vjs-hidden"),self.on(player,"loadstart",(function(){player.tech_.featuresVolumeControl?self.removeClass("vjs-hidden"):self.addClass("vjs-hidden")}))}(this,player),this.throttledHandleMouseMove=throttle(bind_(this,this.handleMouseMove),30),this.handleMouseUpHandler_=e=>this.handleMouseUp(e),this.on("mousedown",(e=>this.handleMouseDown(e))),this.on("touchstart",(e=>this.handleMouseDown(e))),this.on("mousemove",(e=>this.handleMouseMove(e))),this.on(this.volumeBar,["focus","slideractive"],(()=>{this.volumeBar.addClass("vjs-slider-active"),this.addClass("vjs-slider-active"),this.trigger("slideractive")})),this.on(this.volumeBar,["blur","sliderinactive"],(()=>{this.volumeBar.removeClass("vjs-slider-active"),this.removeClass("vjs-slider-active"),this.trigger("sliderinactive")}))}createEl(){let orientationClass="vjs-volume-horizontal";return this.options_.vertical&&(orientationClass="vjs-volume-vertical"),super.createEl("div",{className:"vjs-volume-control vjs-control ".concat(orientationClass)})}handleMouseDown(event){const doc=this.el_.ownerDocument;this.on(doc,"mousemove",this.throttledHandleMouseMove),this.on(doc,"touchmove",this.throttledHandleMouseMove),this.on(doc,"mouseup",this.handleMouseUpHandler_),this.on(doc,"touchend",this.handleMouseUpHandler_)}handleMouseUp(event){const doc=this.el_.ownerDocument;this.off(doc,"mousemove",this.throttledHandleMouseMove),this.off(doc,"touchmove",this.throttledHandleMouseMove),this.off(doc,"mouseup",this.handleMouseUpHandler_),this.off(doc,"touchend",this.handleMouseUpHandler_)}handleMouseMove(event){this.volumeBar.handleMouseMove(event)}}VolumeControl.prototype.options_={children:["volumeBar"]},Component$1.registerComponent("VolumeControl",VolumeControl);class MuteToggle extends Button{constructor(player,options){super(player,options),function(self,player){player.tech_&&!player.tech_.featuresMuteControl&&self.addClass("vjs-hidden"),self.on(player,"loadstart",(function(){player.tech_.featuresMuteControl?self.removeClass("vjs-hidden"):self.addClass("vjs-hidden")}))}(this,player),this.on(player,["loadstart","volumechange"],(e=>this.update(e)))}buildCSSClass(){return"vjs-mute-control ".concat(super.buildCSSClass())}handleClick(event){const vol=this.player_.volume(),lastVolume=this.player_.lastVolume_();if(0===vol){const volumeToSet=lastVolume<.1?.1:lastVolume;this.player_.volume(volumeToSet),this.player_.muted(!1)}else this.player_.muted(!this.player_.muted())}update(event){this.updateIcon_(),this.updateControlText_()}updateIcon_(){const vol=this.player_.volume();let level=3;IS_IOS&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===vol||this.player_.muted()?level=0:vol<.33?level=1:vol<.67&&(level=2),removeClass(this.el_,[0,1,2,3].reduce(((str,i)=>str+"".concat(i?" ":"","vjs-vol-").concat(i)),"")),addClass(this.el_,"vjs-vol-".concat(level))}updateControlText_(){const text=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==text&&this.controlText(text)}}MuteToggle.prototype.controlText_="Mute",Component$1.registerComponent("MuteToggle",MuteToggle);class VolumePanel extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};void 0!==options.inline?options.inline=options.inline:options.inline=!0,(void 0===options.volumeControl||isPlain(options.volumeControl))&&(options.volumeControl=options.volumeControl||{},options.volumeControl.vertical=!options.inline),super(player,options),this.handleKeyPressHandler_=e=>this.handleKeyPress(e),this.on(player,["loadstart"],(e=>this.volumePanelState_(e))),this.on(this.muteToggle,"keyup",(e=>this.handleKeyPress(e))),this.on(this.volumeControl,"keyup",(e=>this.handleVolumeControlKeyUp(e))),this.on("keydown",(e=>this.handleKeyPress(e))),this.on("mouseover",(e=>this.handleMouseOver(e))),this.on("mouseout",(e=>this.handleMouseOut(e))),this.on(this.volumeControl,["slideractive"],this.sliderActive_),this.on(this.volumeControl,["sliderinactive"],this.sliderInactive_)}sliderActive_(){this.addClass("vjs-slider-active")}sliderInactive_(){this.removeClass("vjs-slider-active")}volumePanelState_(){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")}createEl(){let orientationClass="vjs-volume-panel-horizontal";return this.options_.inline||(orientationClass="vjs-volume-panel-vertical"),super.createEl("div",{className:"vjs-volume-panel vjs-control ".concat(orientationClass)})}dispose(){this.handleMouseOut(),super.dispose()}handleVolumeControlKeyUp(event){keycode.isEventKey(event,"Esc")&&this.muteToggle.focus()}handleMouseOver(event){this.addClass("vjs-hover"),on(document,"keyup",this.handleKeyPressHandler_)}handleMouseOut(event){this.removeClass("vjs-hover"),off(document,"keyup",this.handleKeyPressHandler_)}handleKeyPress(event){keycode.isEventKey(event,"Esc")&&this.handleMouseOut()}}VolumePanel.prototype.options_={children:["muteToggle","volumeControl"]},Component$1.registerComponent("VolumePanel",VolumePanel);Component$1.registerComponent("SkipForward",class extends Button{constructor(player,options){super(player,options),this.validOptions=[5,10,30],this.skipTime=this.getSkipForwardTime(),this.skipTime&&this.validOptions.includes(this.skipTime)?(this.controlText(this.localize("Skip forward {1} seconds",[this.skipTime])),this.show()):this.hide()}getSkipForwardTime(){const playerOptions=this.options_.playerOptions;return playerOptions.controlBar&&playerOptions.controlBar.skipButtons&&playerOptions.controlBar.skipButtons.forward}buildCSSClass(){return"vjs-skip-forward-".concat(this.getSkipForwardTime()," ").concat(super.buildCSSClass())}handleClick(event){const currentVideoTime=this.player_.currentTime(),liveTracker=this.player_.liveTracker,duration=liveTracker&&liveTracker.isLive()?liveTracker.seekableEnd():this.player_.duration();let newTime;newTime=currentVideoTime+this.skipTime<=duration?currentVideoTime+this.skipTime:duration,this.player_.currentTime(newTime)}handleLanguagechange(){this.controlText(this.localize("Skip forward {1} seconds",[this.skipTime]))}});class SkipBackward extends Button{constructor(player,options){super(player,options),this.validOptions=[5,10,30],this.skipTime=this.getSkipBackwardTime(),this.skipTime&&this.validOptions.includes(this.skipTime)?(this.controlText(this.localize("Skip backward {1} seconds",[this.skipTime])),this.show()):this.hide()}getSkipBackwardTime(){const playerOptions=this.options_.playerOptions;return playerOptions.controlBar&&playerOptions.controlBar.skipButtons&&playerOptions.controlBar.skipButtons.backward}buildCSSClass(){return"vjs-skip-backward-".concat(this.getSkipBackwardTime()," ").concat(super.buildCSSClass())}handleClick(event){const currentVideoTime=this.player_.currentTime(),liveTracker=this.player_.liveTracker,seekableStart=liveTracker&&liveTracker.isLive()&&liveTracker.seekableStart();let newTime;newTime=seekableStart&¤tVideoTime-this.skipTime<=seekableStart?seekableStart:currentVideoTime>=this.skipTime?currentVideoTime-this.skipTime:0,this.player_.currentTime(newTime)}handleLanguagechange(){this.controlText(this.localize("Skip backward {1} seconds",[this.skipTime]))}}SkipBackward.prototype.controlText_="Skip Backward",Component$1.registerComponent("SkipBackward",SkipBackward);class Menu extends Component$1{constructor(player,options){super(player,options),options&&(this.menuButton_=options.menuButton),this.focusedChild_=-1,this.on("keydown",(e=>this.handleKeyDown(e))),this.boundHandleBlur_=e=>this.handleBlur(e),this.boundHandleTapClick_=e=>this.handleTapClick(e)}addEventListenerForItem(component){component instanceof Component$1&&(this.on(component,"blur",this.boundHandleBlur_),this.on(component,["tap","click"],this.boundHandleTapClick_))}removeEventListenerForItem(component){component instanceof Component$1&&(this.off(component,"blur",this.boundHandleBlur_),this.off(component,["tap","click"],this.boundHandleTapClick_))}removeChild(component){"string"==typeof component&&(component=this.getChild(component)),this.removeEventListenerForItem(component),super.removeChild(component)}addItem(component){const childComponent=this.addChild(component);childComponent&&this.addEventListenerForItem(childComponent)}createEl(){const contentElType=this.options_.contentElType||"ul";this.contentEl_=createEl(contentElType,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");const el=super.createEl("div",{append:this.contentEl_,className:"vjs-menu"});return el.appendChild(this.contentEl_),on(el,"click",(function(event){event.preventDefault(),event.stopImmediatePropagation()})),el}dispose(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,super.dispose()}handleBlur(event){const relatedTarget=event.relatedTarget||document.activeElement;if(!this.children().some((element=>element.el()===relatedTarget))){const btn=this.menuButton_;btn&&btn.buttonPressed_&&relatedTarget!==btn.el().firstChild&&btn.unpressButton()}}handleTapClick(event){if(this.menuButton_){this.menuButton_.unpressButton();const childComponents=this.children();if(!Array.isArray(childComponents))return;const foundComponent=childComponents.filter((component=>component.el()===event.target))[0];if(!foundComponent)return;"CaptionSettingsMenuItem"!==foundComponent.name()&&this.menuButton_.focus()}}handleKeyDown(event){keycode.isEventKey(event,"Left")||keycode.isEventKey(event,"Down")?(event.preventDefault(),event.stopPropagation(),this.stepForward()):(keycode.isEventKey(event,"Right")||keycode.isEventKey(event,"Up"))&&(event.preventDefault(),event.stopPropagation(),this.stepBack())}stepForward(){let stepChild=0;void 0!==this.focusedChild_&&(stepChild=this.focusedChild_+1),this.focus(stepChild)}stepBack(){let stepChild=0;void 0!==this.focusedChild_&&(stepChild=this.focusedChild_-1),this.focus(stepChild)}focus(){let item=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;const children=this.children().slice();children.length&&children[0].hasClass("vjs-menu-title")&&children.shift(),children.length>0&&(item<0?item=0:item>=children.length&&(item=children.length-1),this.focusedChild_=item,children[item].el_.focus())}}Component$1.registerComponent("Menu",Menu);class MenuButton extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(player,options),this.menuButton_=new Button(player,options),this.menuButton_.controlText(this.controlText_),this.menuButton_.el_.setAttribute("aria-haspopup","true");const buttonClass=Button.prototype.buildCSSClass();this.menuButton_.el_.className=this.buildCSSClass()+" "+buttonClass,this.menuButton_.removeClass("vjs-control"),this.addChild(this.menuButton_),this.update(),this.enabled_=!0;const handleClick=e=>this.handleClick(e);this.handleMenuKeyUp_=e=>this.handleMenuKeyUp(e),this.on(this.menuButton_,"tap",handleClick),this.on(this.menuButton_,"click",handleClick),this.on(this.menuButton_,"keydown",(e=>this.handleKeyDown(e))),this.on(this.menuButton_,"mouseenter",(()=>{this.addClass("vjs-hover"),this.menu.show(),on(document,"keyup",this.handleMenuKeyUp_)})),this.on("mouseleave",(e=>this.handleMouseLeave(e))),this.on("keydown",(e=>this.handleSubmenuKeyDown(e)))}update(){const menu=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=menu,this.addChild(menu),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?(this.hide(),this.menu.contentEl_.removeAttribute("role")):(this.show(),this.menu.contentEl_.setAttribute("role","menu"))}createMenu(){const menu=new Menu(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title){const titleEl=createEl("li",{className:"vjs-menu-title",textContent:toTitleCase$1(this.options_.title),tabIndex:-1}),titleComponent=new Component$1(this.player_,{el:titleEl});menu.addItem(titleComponent)}if(this.items=this.createItems(),this.items)for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:this.menuButton_.el();return this.menuButton_.controlText(text,el)}dispose(){this.handleMouseLeave(),super.dispose()}handleClick(event){this.buttonPressed_?this.unpressButton():this.pressButton()}handleMouseLeave(event){this.removeClass("vjs-hover"),off(document,"keyup",this.handleMenuKeyUp_)}focus(){this.menuButton_.focus()}blur(){this.menuButton_.blur()}handleKeyDown(event){keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab")?(this.buttonPressed_&&this.unpressButton(),keycode.isEventKey(event,"Tab")||(event.preventDefault(),this.menuButton_.focus())):(keycode.isEventKey(event,"Up")||keycode.isEventKey(event,"Down"))&&(this.buttonPressed_||(event.preventDefault(),this.pressButton()))}handleMenuKeyUp(event){(keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab"))&&this.removeClass("vjs-hover")}handleSubmenuKeyPress(event){this.handleSubmenuKeyDown(event)}handleSubmenuKeyDown(event){(keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),keycode.isEventKey(event,"Tab")||(event.preventDefault(),this.menuButton_.focus()))}pressButton(){if(this.enabled_){if(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),IS_IOS&&isInFrame())return;this.menu.focus()}}unpressButton(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))}disable(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()}enable(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()}}Component$1.registerComponent("MenuButton",MenuButton);class TrackButton extends MenuButton{constructor(player,options){const tracks=options.tracks;if(super(player,options),this.items.length<=1&&this.hide(),!tracks)return;const updateHandler=bind_(this,this.update);tracks.addEventListener("removetrack",updateHandler),tracks.addEventListener("addtrack",updateHandler),tracks.addEventListener("labelchange",updateHandler),this.player_.on("ready",updateHandler),this.player_.on("dispose",(function(){tracks.removeEventListener("removetrack",updateHandler),tracks.removeEventListener("addtrack",updateHandler),tracks.removeEventListener("labelchange",updateHandler)}))}}Component$1.registerComponent("TrackButton",TrackButton);const MenuKeys=["Tab","Esc","Up","Down","Right","Left"];class MenuItem extends ClickableComponent{constructor(player,options){super(player,options),this.selectable=options.selectable,this.isSelected_=options.selected||!1,this.multiSelectable=options.multiSelectable,this.selected(this.isSelected_),this.selectable?this.multiSelectable?this.el_.setAttribute("role","menuitemcheckbox"):this.el_.setAttribute("role","menuitemradio"):this.el_.setAttribute("role","menuitem")}createEl(type,props,attrs){this.nonIconControl=!0;const el=super.createEl("li",Object.assign({className:"vjs-menu-item",tabIndex:-1},props),attrs);return el.replaceChild(createEl("span",{className:"vjs-menu-item-text",textContent:this.localize(this.options_.label)}),el.querySelector(".vjs-icon-placeholder")),el}handleKeyDown(event){MenuKeys.some((key=>keycode.isEventKey(event,key)))||super.handleKeyDown(event)}handleClick(event){this.selected(!0)}selected(selected){this.selectable&&(selected?(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))}}Component$1.registerComponent("MenuItem",MenuItem);class TextTrackMenuItem extends MenuItem{constructor(player,options){var _this3;const track=options.track,tracks=player.textTracks();options.label=track.label||track.language||"Unknown",options.selected="showing"===track.mode,super(player,options),_this3=this,this.track=track,this.kinds=(options.kinds||[options.kind||this.track.kind]).filter(Boolean);const changeHandler=function(){for(var _len17=arguments.length,args=new Array(_len17),_key17=0;_key17<_len17;_key17++)args[_key17]=arguments[_key17];_this3.handleTracksChange.apply(_this3,args)},selectedLanguageChangeHandler=function(){for(var _len18=arguments.length,args=new Array(_len18),_key18=0;_key18<_len18;_key18++)args[_key18]=arguments[_key18];_this3.handleSelectedLanguageChange.apply(_this3,args)};if(player.on(["loadstart","texttrackchange"],changeHandler),tracks.addEventListener("change",changeHandler),tracks.addEventListener("selectedlanguagechange",selectedLanguageChangeHandler),this.on("dispose",(function(){player.off(["loadstart","texttrackchange"],changeHandler),tracks.removeEventListener("change",changeHandler),tracks.removeEventListener("selectedlanguagechange",selectedLanguageChangeHandler)})),void 0===tracks.onchange){let event;this.on(["tap","click"],(function(){if("object"!=typeof window.Event)try{event=new window.Event("change")}catch(err){}event||(event=document.createEvent("Event"),event.initEvent("change",!0,!0)),tracks.dispatchEvent(event)}))}this.handleTracksChange()}handleClick(event){const referenceTrack=this.track,tracks=this.player_.textTracks();if(super.handleClick(event),tracks)for(let i=0;i-1&&"showing"===track.mode){shouldBeSelected=!1;break}}shouldBeSelected!==this.isSelected_&&this.selected(shouldBeSelected)}handleSelectedLanguageChange(event){const tracks=this.player().textTracks();let allHidden=!0;for(let i=0,l=tracks.length;i-1&&"showing"===track.mode){allHidden=!1;break}}allHidden&&(this.player_.cache_.selectedLanguage={enabled:!1})}handleLanguagechange(){this.$(".vjs-menu-item-text").textContent=this.player_.localize(this.options_.label),super.handleLanguagechange()}}Component$1.registerComponent("OffTextTrackMenuItem",OffTextTrackMenuItem);class TextTrackButton extends TrackButton{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};options.tracks=player.textTracks(),super(player,options)}createItems(){let label,items=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],TrackMenuItem=arguments.length>1&&void 0!==arguments[1]?arguments[1]:TextTrackMenuItem;this.label_&&(label="".concat(this.label_," off")),items.push(new OffTextTrackMenuItem(this.player_,{kinds:this.kinds_,kind:this.kind_,label:label})),this.hideThreshold_+=1;const tracks=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(let i=0;i-1){const item=new TrackMenuItem(this.player_,{track:track,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1});item.addClass("vjs-".concat(track.kind,"-menu-item")),items.push(item)}}return items}}Component$1.registerComponent("TextTrackButton",TextTrackButton);class ChaptersTrackMenuItem extends MenuItem{constructor(player,options){const track=options.track,cue=options.cue,currentTime=player.currentTime();options.selectable=!0,options.multiSelectable=!1,options.label=cue.text,options.selected=cue.startTime<=currentTime&¤tTime{this.items.forEach((item=>{item.selected(this.track_.activeCues[0]===item.cue)}))}}buildCSSClass(){return"vjs-chapters-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-chapters-button ".concat(super.buildWrapperCSSClass())}update(event){if(event&&event.track&&"chapters"!==event.track.kind)return;const track=this.findChaptersTrack();track!==this.track_?(this.setTrack(track),super.update()):(!this.items||track&&track.cues&&track.cues.length!==this.items.length)&&super.update()}setTrack(track){if(this.track_!==track){if(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_){const remoteTextTrackEl=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);remoteTextTrackEl&&remoteTextTrackEl.removeEventListener("load",this.updateHandler_),this.track_.removeEventListener("cuechange",this.selectCurrentItem_),this.track_=null}if(this.track_=track,this.track_){this.track_.mode="hidden";const remoteTextTrackEl=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);remoteTextTrackEl&&remoteTextTrackEl.addEventListener("load",this.updateHandler_),this.track_.addEventListener("cuechange",this.selectCurrentItem_)}}}findChaptersTrack(){const tracks=this.player_.textTracks()||[];for(let i=tracks.length-1;i>=0;i--){const track=tracks[i];if(track.kind===this.kind_)return track}}getMenuCaption(){return this.track_&&this.track_.label?this.track_.label:this.localize(toTitleCase$1(this.kind_))}createMenu(){return this.options_.title=this.getMenuCaption(),super.createMenu()}createItems(){const items=[];if(!this.track_)return items;const cues=this.track_.cues;if(!cues)return items;for(let i=0,l=cues.length;i1&&void 0!==arguments[1]?arguments[1]:{}),this.label_="subtitles",["en","en-us","en-ca","fr-ca"].indexOf(this.player_.language_)>-1&&(this.label_="captions"),this.menuButton_.controlText(toTitleCase$1(this.label_))}buildCSSClass(){return"vjs-subs-caps-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-subs-caps-button ".concat(super.buildWrapperCSSClass())}createItems(){let items=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(items.push(new CaptionSettingsMenuItem(this.player_,{kind:this.label_})),this.hideThreshold_+=1),items=super.createItems(items,SubsCapsMenuItem),items}}SubsCapsButton.prototype.kinds_=["captions","subtitles"],SubsCapsButton.prototype.controlText_="Subtitles",Component$1.registerComponent("SubsCapsButton",SubsCapsButton);class AudioTrackMenuItem extends MenuItem{constructor(player,options){var _this4;const track=options.track,tracks=player.audioTracks();options.label=track.label||track.language||"Unknown",options.selected=track.enabled,super(player,options),_this4=this,this.track=track,this.addClass("vjs-".concat(track.kind,"-menu-item"));const changeHandler=function(){for(var _len19=arguments.length,args=new Array(_len19),_key19=0;_key19<_len19;_key19++)args[_key19]=arguments[_key19];_this4.handleTracksChange.apply(_this4,args)};tracks.addEventListener("change",changeHandler),this.on("dispose",(()=>{tracks.removeEventListener("change",changeHandler)}))}createEl(type,props,attrs){const el=super.createEl(type,props,attrs),parentSpan=el.querySelector(".vjs-menu-item-text");return"main-desc"===this.options_.track.kind&&(parentSpan.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),parentSpan.appendChild(createEl("span",{className:"vjs-control-text",textContent:" "+this.localize("Descriptions")}))),el}handleClick(event){if(super.handleClick(event),this.track.enabled=!0,this.player_.tech_.featuresNativeAudioTracks){const tracks=this.player_.audioTracks();for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:{};options.tracks=player.audioTracks(),super(player,options)}buildCSSClass(){return"vjs-audio-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-audio-button ".concat(super.buildWrapperCSSClass())}createItems(){let items=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.hideThreshold_=1;const tracks=this.player_.audioTracks();for(let i=0;ithis.update(e)))}handleClick(event){super.handleClick(),this.player().playbackRate(this.rate)}update(event){this.selected(this.player().playbackRate()===this.rate)}}PlaybackRateMenuItem.prototype.contentElType="button",Component$1.registerComponent("PlaybackRateMenuItem",PlaybackRateMenuItem);class PlaybackRateMenuButton extends MenuButton{constructor(player,options){super(player,options),this.menuButton_.el_.setAttribute("aria-describedby",this.labelElId_),this.updateVisibility(),this.updateLabel(),this.on(player,"loadstart",(e=>this.updateVisibility(e))),this.on(player,"ratechange",(e=>this.updateLabel(e))),this.on(player,"playbackrateschange",(e=>this.handlePlaybackRateschange(e)))}createEl(){const el=super.createEl();return this.labelElId_="vjs-playback-rate-value-label-"+this.id_,this.labelEl_=createEl("div",{className:"vjs-playback-rate-value",id:this.labelElId_,textContent:"1x"}),el.appendChild(this.labelEl_),el}dispose(){this.labelEl_=null,super.dispose()}buildCSSClass(){return"vjs-playback-rate ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-playback-rate ".concat(super.buildWrapperCSSClass())}createItems(){const rates=this.playbackRates(),items=[];for(let i=rates.length-1;i>=0;i--)items.push(new PlaybackRateMenuItem(this.player(),{rate:rates[i]+"x"}));return items}handlePlaybackRateschange(event){this.update()}playbackRates(){const player=this.player();return player.playbackRates&&player.playbackRates()||[]}playbackRateSupported(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&this.playbackRates().length>0}updateVisibility(event){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")}updateLabel(event){this.playbackRateSupported()&&(this.labelEl_.textContent=this.player().playbackRate()+"x")}}PlaybackRateMenuButton.prototype.controlText_="Playback Rate",Component$1.registerComponent("PlaybackRateMenuButton",PlaybackRateMenuButton);class Spacer extends Component$1{buildCSSClass(){return"vjs-spacer ".concat(super.buildCSSClass())}createEl(){let tag=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return props.className||(props.className=this.buildCSSClass()),super.createEl(tag,props,attributes)}}Component$1.registerComponent("Spacer",Spacer);Component$1.registerComponent("CustomControlSpacer",class extends Spacer{buildCSSClass(){return"vjs-custom-control-spacer ".concat(super.buildCSSClass())}createEl(){return super.createEl("div",{className:this.buildCSSClass(),textContent:" "})}});class ControlBar extends Component$1{createEl(){return super.createEl("div",{className:"vjs-control-bar",dir:"ltr"})}}ControlBar.prototype.options_={children:["playToggle","skipBackward","skipForward","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","fullscreenToggle"]},"exitPictureInPicture"in document&&ControlBar.prototype.options_.children.splice(ControlBar.prototype.options_.children.length-1,0,"pictureInPictureToggle"),Component$1.registerComponent("ControlBar",ControlBar);class ErrorDisplay extends ModalDialog{constructor(player,options){super(player,options),this.on(player,"error",(e=>this.open(e)))}buildCSSClass(){return"vjs-error-display ".concat(super.buildCSSClass())}content(){const error=this.player().error();return error?this.localize(error.message):""}}ErrorDisplay.prototype.options_=Object.assign({},ModalDialog.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),Component$1.registerComponent("ErrorDisplay",ErrorDisplay);const COLOR_BLACK=["#000","Black"],COLOR_BLUE=["#00F","Blue"],COLOR_CYAN=["#0FF","Cyan"],COLOR_GREEN=["#0F0","Green"],COLOR_MAGENTA=["#F0F","Magenta"],COLOR_RED=["#F00","Red"],COLOR_WHITE=["#FFF","White"],COLOR_YELLOW=["#FF0","Yellow"],OPACITY_OPAQUE=["1","Opaque"],OPACITY_SEMI=["0.5","Semi-Transparent"],OPACITY_TRANS=["0","Transparent"],selectConfigs={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[COLOR_BLACK,COLOR_WHITE,COLOR_RED,COLOR_GREEN,COLOR_BLUE,COLOR_YELLOW,COLOR_MAGENTA,COLOR_CYAN]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Opacity",options:[OPACITY_OPAQUE,OPACITY_SEMI,OPACITY_TRANS]},color:{selector:".vjs-text-color > select",id:"captions-foreground-color-%s",label:"Color",options:[COLOR_WHITE,COLOR_BLACK,COLOR_RED,COLOR_GREEN,COLOR_BLUE,COLOR_YELLOW,COLOR_MAGENTA,COLOR_CYAN]},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:v=>"1.00"===v?null:Number(v)},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Opacity",options:[OPACITY_OPAQUE,OPACITY_SEMI]},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:"Opacity",options:[OPACITY_TRANS,OPACITY_SEMI,OPACITY_OPAQUE]}};function parseOptionValue(value,parser){if(parser&&(value=parser(value)),value&&"none"!==value)return value}selectConfigs.windowColor.options=selectConfigs.backgroundColor.options;Component$1.registerComponent("TextTrackSettings",class extends ModalDialog{constructor(player,options){options.temporary=!1,super(player,options),this.updateDisplay=this.updateDisplay.bind(this),this.fill(),this.hasBeenOpened_=this.hasBeenFilled_=!0,this.endDialog=createEl("p",{className:"vjs-control-text",textContent:this.localize("End of dialog window.")}),this.el().appendChild(this.endDialog),this.setDefaults(),void 0===options.persistTextTrackSettings&&(this.options_.persistTextTrackSettings=this.options_.playerOptions.persistTextTrackSettings),this.on(this.$(".vjs-done-button"),"click",(()=>{this.saveSettings(),this.close()})),this.on(this.$(".vjs-default-button"),"click",(()=>{this.setDefaults(),this.updateDisplay()})),each(selectConfigs,(config=>{this.on(this.$(config.selector),"change",this.updateDisplay)})),this.options_.persistTextTrackSettings&&this.restoreSettings()}dispose(){this.endDialog=null,super.dispose()}createElSelect_(key){let legendId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",type=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"label";const config=selectConfigs[key],id=config.id.replace("%s",this.id_),selectLabelledbyIds=[legendId,id].join(" ").trim();return["<".concat(type,' id="').concat(id,'" class="').concat("label"===type?"vjs-label":"",'">'),this.localize(config.label),""),'").join("")}createElFgColor_(){const legendId="captions-text-legend-".concat(this.id_);return['
',''),this.localize("Text"),"",'',this.createElSelect_("color",legendId),"",'',this.createElSelect_("textOpacity",legendId),"","
"].join("")}createElBgColor_(){const legendId="captions-background-".concat(this.id_);return['
',''),this.localize("Text Background"),"",'',this.createElSelect_("backgroundColor",legendId),"",'',this.createElSelect_("backgroundOpacity",legendId),"","
"].join("")}createElWinColor_(){const legendId="captions-window-".concat(this.id_);return['
',''),this.localize("Caption Area Background"),"",'',this.createElSelect_("windowColor",legendId),"",'',this.createElSelect_("windowOpacity",legendId),"","
"].join("")}createElColors_(){return createEl("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})}createElFont_(){return createEl("div",{className:"vjs-track-settings-font",innerHTML:['
',this.createElSelect_("fontPercent","","legend"),"
",'
',this.createElSelect_("edgeStyle","","legend"),"
",'
',this.createElSelect_("fontFamily","","legend"),"
"].join("")})}createElControls_(){const defaultsDescription=this.localize("restore all settings to the default values");return createEl("div",{className:"vjs-track-settings-controls",innerHTML:['",'")].join("")})}content(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]}label(){return this.localize("Caption Settings Dialog")}description(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")}buildCSSClass(){return super.buildCSSClass()+" vjs-text-track-settings"}getValues(){return reduce(selectConfigs,((accum,config,key)=>{const value=(el=this.$(config.selector),parser=config.parser,parseOptionValue(el.options[el.options.selectedIndex].value,parser));var el,parser;return void 0!==value&&(accum[key]=value),accum}),{})}setValues(values){each(selectConfigs,((config,key)=>{!function(el,value,parser){if(value)for(let i=0;i{const index=config.hasOwnProperty("default")?config.default:0;this.$(config.selector).selectedIndex=index}))}restoreSettings(){let values;try{values=JSON.parse(window.localStorage.getItem("vjs-text-track-settings"))}catch(err){log$1.warn(err)}values&&this.setValues(values)}saveSettings(){if(!this.options_.persistTextTrackSettings)return;const values=this.getValues();try{Object.keys(values).length?window.localStorage.setItem("vjs-text-track-settings",JSON.stringify(values)):window.localStorage.removeItem("vjs-text-track-settings")}catch(err){log$1.warn(err)}}updateDisplay(){const ttDisplay=this.player_.getChild("textTrackDisplay");ttDisplay&&ttDisplay.updateDisplay()}conditionalBlur_(){this.previouslyActiveEl_=null;const cb=this.player_.controlBar,subsCapsBtn=cb&&cb.subsCapsButton,ccBtn=cb&&cb.captionsButton;subsCapsBtn?subsCapsBtn.focus():ccBtn&&ccBtn.focus()}handleLanguagechange(){this.fill()}});Component$1.registerComponent("ResizeManager",class extends Component$1{constructor(player,options){let RESIZE_OBSERVER_AVAILABLE=options.ResizeObserver||window.ResizeObserver;null===options.ResizeObserver&&(RESIZE_OBSERVER_AVAILABLE=!1);super(player,merge$2({createEl:!RESIZE_OBSERVER_AVAILABLE,reportTouchActivity:!1},options)),this.ResizeObserver=options.ResizeObserver||window.ResizeObserver,this.loadListener_=null,this.resizeObserver_=null,this.debouncedHandler_=debounce((()=>{this.resizeHandler()}),100,!1,this),RESIZE_OBSERVER_AVAILABLE?(this.resizeObserver_=new this.ResizeObserver(this.debouncedHandler_),this.resizeObserver_.observe(player.el())):(this.loadListener_=()=>{if(!this.el_||!this.el_.contentWindow)return;const debouncedHandler_=this.debouncedHandler_;let unloadListener_=this.unloadListener_=function(){off(this,"resize",debouncedHandler_),off(this,"unload",unloadListener_),unloadListener_=null};on(this.el_.contentWindow,"unload",unloadListener_),on(this.el_.contentWindow,"resize",debouncedHandler_)},this.one("load",this.loadListener_))}createEl(){return super.createEl("iframe",{className:"vjs-resize-manager",tabIndex:-1,title:this.localize("No content")},{"aria-hidden":"true"})}resizeHandler(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")}dispose(){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,super.dispose()}});const defaults={trackingThreshold:20,liveTolerance:15};Component$1.registerComponent("LiveTracker",class extends Component$1{constructor(player,options){super(player,merge$2(defaults,options,{createEl:!1})),this.trackLiveHandler_=()=>this.trackLive_(),this.handlePlay_=e=>this.handlePlay(e),this.handleFirstTimeupdate_=e=>this.handleFirstTimeupdate(e),this.handleSeeked_=e=>this.handleSeeked(e),this.seekToLiveEdge_=e=>this.seekToLiveEdge(e),this.reset_(),this.on(this.player_,"durationchange",(e=>this.handleDurationchange(e))),this.on(this.player_,"canplay",(()=>this.toggleTracking()))}trackLive_(){const seekable=this.player_.seekable();if(!seekable||!seekable.length)return;const newTime=Number(window.performance.now().toFixed(4)),deltaTime=-1===this.lastTime_?0:(newTime-this.lastTime_)/1e3;this.lastTime_=newTime,this.pastSeekEnd_=this.pastSeekEnd()+deltaTime;const liveCurrentTime=this.liveCurrentTime(),currentTime=this.player_.currentTime();let isBehind=this.player_.paused()||this.seekedBehindLive_||Math.abs(liveCurrentTime-currentTime)>this.options_.liveTolerance;this.timeupdateSeen_&&liveCurrentTime!==1/0||(isBehind=!1),isBehind!==this.behindLiveEdge_&&(this.behindLiveEdge_=isBehind,this.trigger("liveedgechange"))}handleDurationchange(){this.toggleTracking()}toggleTracking(){this.player_.duration()===1/0&&this.liveWindow()>=this.options_.trackingThreshold?(this.player_.options_.liveui&&this.player_.addClass("vjs-liveui"),this.startTracking()):(this.player_.removeClass("vjs-liveui"),this.stopTracking())}startTracking(){this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLiveHandler_,30),this.trackLive_(),this.on(this.player_,["play","pause"],this.trackLiveHandler_),this.timeupdateSeen_?this.on(this.player_,"seeked",this.handleSeeked_):(this.one(this.player_,"play",this.handlePlay_),this.one(this.player_,"timeupdate",this.handleFirstTimeupdate_)))}handleFirstTimeupdate(){this.timeupdateSeen_=!0,this.on(this.player_,"seeked",this.handleSeeked_)}handleSeeked(){const timeDiff=Math.abs(this.liveCurrentTime()-this.player_.currentTime());this.seekedBehindLive_=this.nextSeekedFromUser_&&timeDiff>2,this.nextSeekedFromUser_=!1,this.trackLive_()}handlePlay(){this.one(this.player_,"timeupdate",this.seekToLiveEdge_)}reset_(){this.lastTime_=-1,this.pastSeekEnd_=0,this.lastSeekEnd_=-1,this.behindLiveEdge_=!0,this.timeupdateSeen_=!1,this.seekedBehindLive_=!1,this.nextSeekedFromUser_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.off(this.player_,["play","pause"],this.trackLiveHandler_),this.off(this.player_,"seeked",this.handleSeeked_),this.off(this.player_,"play",this.handlePlay_),this.off(this.player_,"timeupdate",this.handleFirstTimeupdate_),this.off(this.player_,"timeupdate",this.seekToLiveEdge_)}nextSeekedFromUser(){this.nextSeekedFromUser_=!0}stopTracking(){this.isTracking()&&(this.reset_(),this.trigger("liveedgechange"))}seekableEnd(){const seekable=this.player_.seekable(),seekableEnds=[];let i=seekable?seekable.length:0;for(;i--;)seekableEnds.push(seekable.end(i));return seekableEnds.length?seekableEnds.sort()[seekableEnds.length-1]:1/0}seekableStart(){const seekable=this.player_.seekable(),seekableStarts=[];let i=seekable?seekable.length:0;for(;i--;)seekableStarts.push(seekable.start(i));return seekableStarts.length?seekableStarts.sort()[0]:0}liveWindow(){const liveCurrentTime=this.liveCurrentTime();return liveCurrentTime===1/0?0:liveCurrentTime-this.seekableStart()}isLive(){return this.isTracking()}atLiveEdge(){return!this.behindLiveEdge()}liveCurrentTime(){return this.pastSeekEnd()+this.seekableEnd()}pastSeekEnd(){const seekableEnd=this.seekableEnd();return-1!==this.lastSeekEnd_&&seekableEnd!==this.lastSeekEnd_&&(this.pastSeekEnd_=0),this.lastSeekEnd_=seekableEnd,this.pastSeekEnd_}behindLiveEdge(){return this.behindLiveEdge_}isTracking(){return"number"==typeof this.trackingInterval_}seekToLiveEdge(){this.seekedBehindLive_=!1,this.atLiveEdge()||(this.nextSeekedFromUser_=!1,this.player_.currentTime(this.liveCurrentTime()))}dispose(){this.stopTracking(),super.dispose()}});Component$1.registerComponent("TitleBar",class extends Component$1{constructor(player,options){super(player,options),this.on("statechanged",(e=>this.updateDom_())),this.updateDom_()}createEl(){return this.els={title:createEl("div",{className:"vjs-title-bar-title",id:"vjs-title-bar-title-".concat(newGUID())}),description:createEl("div",{className:"vjs-title-bar-description",id:"vjs-title-bar-description-".concat(newGUID())})},createEl("div",{className:"vjs-title-bar"},{},Object.values(this.els))}updateDom_(){const tech=this.player_.tech_,techEl=tech&&tech.el_,techAriaAttrs={title:"aria-labelledby",description:"aria-describedby"};["title","description"].forEach((k=>{const value=this.state[k],el=this.els[k],techAriaAttr=techAriaAttrs[k];emptyEl(el),value&&textContent(el,value),techEl&&(techEl.removeAttribute(techAriaAttr),value&&techEl.setAttribute(techAriaAttr,el.id))})),this.state.title||this.state.description?this.show():this.hide()}update(options){this.setState(options)}dispose(){const tech=this.player_.tech_,techEl=tech&&tech.el_;techEl&&(techEl.removeAttribute("aria-labelledby"),techEl.removeAttribute("aria-describedby")),super.dispose(),this.els=null}});const sourcesetLoad=tech=>{const el=tech.el();if(el.hasAttribute("src"))return tech.triggerSourceset(el.src),!0;const sources=tech.$$("source"),srcUrls=[];let src="";if(!sources.length)return!1;for(let i=0;i{let descriptor={};for(let i=0;igetDescriptor([tech.el(),window.HTMLMediaElement.prototype,window.Element.prototype,innerHTMLDescriptorPolyfill],"innerHTML"))(tech),appendWrapper=appendFn=>function(){for(var _len20=arguments.length,args=new Array(_len20),_key20=0;_key20<_len20;_key20++)args[_key20]=arguments[_key20];const retval=appendFn.apply(el,args);return sourcesetLoad(tech),retval};["append","appendChild","insertAdjacentHTML"].forEach((k=>{el[k]&&(old[k]=el[k],el[k]=appendWrapper(old[k]))})),Object.defineProperty(el,"innerHTML",merge$2(innerDescriptor,{set:appendWrapper(innerDescriptor.set)})),el.resetSourceWatch_=()=>{el.resetSourceWatch_=null,Object.keys(old).forEach((k=>{el[k]=old[k]})),Object.defineProperty(el,"innerHTML",innerDescriptor)},tech.one("sourceset",el.resetSourceWatch_)},srcDescriptorPolyfill=Object.defineProperty({},"src",{get(){return this.hasAttribute("src")?getAbsoluteURL(window.Element.prototype.getAttribute.call(this,"src")):""},set(v){return window.Element.prototype.setAttribute.call(this,"src",v),v}}),setupSourceset=function(tech){if(!tech.featuresSourceset)return;const el=tech.el();if(el.resetSourceset_)return;const srcDescriptor=(tech=>getDescriptor([tech.el(),window.HTMLMediaElement.prototype,srcDescriptorPolyfill],"src"))(tech),oldSetAttribute=el.setAttribute,oldLoad=el.load;Object.defineProperty(el,"src",merge$2(srcDescriptor,{set:v=>{const retval=srcDescriptor.set.call(el,v);return tech.triggerSourceset(el.src),retval}})),el.setAttribute=(n,v)=>{const retval=oldSetAttribute.call(el,n,v);return/src/i.test(n)&&tech.triggerSourceset(el.src),retval},el.load=()=>{const retval=oldLoad.call(el);return sourcesetLoad(tech)||(tech.triggerSourceset(""),firstSourceWatch(tech)),retval},el.currentSrc?tech.triggerSourceset(el.currentSrc):sourcesetLoad(tech)||firstSourceWatch(tech),el.resetSourceset_=()=>{el.resetSourceset_=null,el.load=oldLoad,el.setAttribute=oldSetAttribute,Object.defineProperty(el,"src",srcDescriptor),el.resetSourceWatch_&&el.resetSourceWatch_()}};class Html5 extends Tech{constructor(options,ready){super(options,ready);const source=options.source;let crossoriginTracks=!1;if(this.featuresVideoFrameCallback=this.featuresVideoFrameCallback&&"VIDEO"===this.el_.tagName,source&&(this.el_.currentSrc!==source.src||options.tag&&3===options.tag.initNetworkState_)?this.setSource(source):this.handleLateInit_(this.el_),options.enableSourceset&&this.setupSourcesetHandling_(),this.isScrubbing_=!1,this.el_.hasChildNodes()){const nodes=this.el_.childNodes;let nodesLength=nodes.length;const removeNodes=[];for(;nodesLength--;){const node=nodes[nodesLength];"track"===node.nodeName.toLowerCase()&&(this.featuresNativeTextTracks?(this.remoteTextTrackEls().addTrackElement_(node),this.remoteTextTracks().addTrack(node.track),this.textTracks().addTrack(node.track),crossoriginTracks||this.el_.hasAttribute("crossorigin")||!isCrossOrigin(node.src)||(crossoriginTracks=!0)):removeNodes.push(node))}for(let i=0;i{metadataTracksPreFullscreenState=[];for(let i=0;itextTracks.removeEventListener("change",takeMetadataTrackSnapshot)));const restoreTrackMode=()=>{for(let i=0;i{textTracks.removeEventListener("change",takeMetadataTrackSnapshot),textTracks.removeEventListener("change",restoreTrackMode),textTracks.addEventListener("change",restoreTrackMode)})),this.on("webkitendfullscreen",(()=>{textTracks.removeEventListener("change",takeMetadataTrackSnapshot),textTracks.addEventListener("change",takeMetadataTrackSnapshot),textTracks.removeEventListener("change",restoreTrackMode)}))}overrideNative_(type,override){if(override!==this["featuresNative".concat(type,"Tracks")])return;const lowerCaseType=type.toLowerCase();this["".concat(lowerCaseType,"TracksListeners_")]&&Object.keys(this["".concat(lowerCaseType,"TracksListeners_")]).forEach((eventName=>{this.el()["".concat(lowerCaseType,"Tracks")].removeEventListener(eventName,this["".concat(lowerCaseType,"TracksListeners_")][eventName])})),this["featuresNative".concat(type,"Tracks")]=!override,this["".concat(lowerCaseType,"TracksListeners_")]=null,this.proxyNativeTracksForType_(lowerCaseType)}overrideNativeAudioTracks(override){this.overrideNative_("Audio",override)}overrideNativeVideoTracks(override){this.overrideNative_("Video",override)}proxyNativeTracksForType_(name){const props=NORMAL[name],elTracks=this.el()[props.getterName],techTracks=this[props.getterName]();if(!this["featuresNative".concat(props.capitalName,"Tracks")]||!elTracks||!elTracks.addEventListener)return;const listeners={change:e=>{const event={type:"change",target:techTracks,currentTarget:techTracks,srcElement:techTracks};techTracks.trigger(event),"text"===name&&this[REMOTE.remoteText.getterName]().trigger(event)},addtrack(e){techTracks.addTrack(e.track)},removetrack(e){techTracks.removeTrack(e.track)}},removeOldTracks=function(){const removeTracks=[];for(let i=0;i{const listener=listeners[eventName];elTracks.addEventListener(eventName,listener),this.on("dispose",(e=>elTracks.removeEventListener(eventName,listener)))})),this.on("loadstart",removeOldTracks),this.on("dispose",(e=>this.off("loadstart",removeOldTracks)))}proxyNativeTracks_(){NORMAL.names.forEach((name=>{this.proxyNativeTracksForType_(name)}))}createEl(){let el=this.options_.tag;if(!el||!this.options_.playerElIngest&&!this.movingMediaElementInDOM){if(el){const clone=el.cloneNode(!0);el.parentNode&&el.parentNode.insertBefore(clone,el),Html5.disposeMediaElement(el),el=clone}else{el=document.createElement("video");const attributes=merge$2({},this.options_.tag&&getAttributes(this.options_.tag));TOUCH_ENABLED&&!0===this.options_.nativeControlsForTouch||delete attributes.controls,setAttributes(el,Object.assign(attributes,{id:this.options_.techId,class:"vjs-tech"}))}el.playerId=this.options_.playerId}void 0!==this.options_.preload&&setAttribute(el,"preload",this.options_.preload),void 0!==this.options_.disablePictureInPicture&&(el.disablePictureInPicture=this.options_.disablePictureInPicture);const settingsAttrs=["loop","muted","playsinline","autoplay"];for(let i=0;i=2&&eventsToTrigger.push("loadeddata"),el.readyState>=3&&eventsToTrigger.push("canplay"),el.readyState>=4&&eventsToTrigger.push("canplaythrough"),this.ready((function(){eventsToTrigger.forEach((function(type){this.trigger(type)}),this)}))}setScrubbing(isScrubbing){this.isScrubbing_=isScrubbing}scrubbing(){return this.isScrubbing_}setCurrentTime(seconds){try{this.isScrubbing_&&this.el_.fastSeek&&IS_ANY_SAFARI?this.el_.fastSeek(seconds):this.el_.currentTime=seconds}catch(e){log$1(e,"Video is not ready. (Video.js)")}}duration(){if(this.el_.duration===1/0&&IS_ANDROID&&IS_CHROME&&0===this.el_.currentTime){const checkProgress=()=>{this.el_.currentTime>0&&(this.el_.duration===1/0&&this.trigger("durationchange"),this.off("timeupdate",checkProgress))};return this.on("timeupdate",checkProgress),NaN}return this.el_.duration||NaN}width(){return this.el_.offsetWidth}height(){return this.el_.offsetHeight}proxyWebkitFullscreen_(){if(!("webkitDisplayingFullscreen"in this.el_))return;const endFn=function(){this.trigger("fullscreenchange",{isFullscreen:!1}),this.el_.controls&&!this.options_.nativeControlsForTouch&&this.controls()&&(this.el_.controls=!1)},beginFn=function(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",endFn),this.trigger("fullscreenchange",{isFullscreen:!0,nativeIOSFullscreen:!0}))};this.on("webkitbeginfullscreen",beginFn),this.on("dispose",(()=>{this.off("webkitbeginfullscreen",beginFn),this.off("webkitendfullscreen",endFn)}))}supportsFullScreen(){return"function"==typeof this.el_.webkitEnterFullScreen}enterFullScreen(){const video=this.el_;if(video.paused&&video.networkState<=video.HAVE_METADATA)silencePromise(this.el_.play()),this.setTimeout((function(){video.pause();try{video.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}}),0);else try{video.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}}exitFullScreen(){this.el_.webkitDisplayingFullscreen?this.el_.webkitExitFullScreen():this.trigger("fullscreenerror",new Error("The video is not fullscreen"))}requestPictureInPicture(){return this.el_.requestPictureInPicture()}requestVideoFrameCallback(cb){return this.featuresVideoFrameCallback&&!this.el_.webkitKeys?this.el_.requestVideoFrameCallback(cb):super.requestVideoFrameCallback(cb)}cancelVideoFrameCallback(id){this.featuresVideoFrameCallback&&!this.el_.webkitKeys?this.el_.cancelVideoFrameCallback(id):super.cancelVideoFrameCallback(id)}src(src){if(void 0===src)return this.el_.src;this.setSrc(src)}reset(){Html5.resetMediaElement(this.el_)}currentSrc(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc}setControls(val){this.el_.controls=!!val}addTextTrack(kind,label,language){return this.featuresNativeTextTracks?this.el_.addTextTrack(kind,label,language):super.addTextTrack(kind,label,language)}createRemoteTextTrack(options){if(!this.featuresNativeTextTracks)return super.createRemoteTextTrack(options);const htmlTrackElement=document.createElement("track");return options.kind&&(htmlTrackElement.kind=options.kind),options.label&&(htmlTrackElement.label=options.label),(options.language||options.srclang)&&(htmlTrackElement.srclang=options.language||options.srclang),options.default&&(htmlTrackElement.default=options.default),options.id&&(htmlTrackElement.id=options.id),options.src&&(htmlTrackElement.src=options.src),htmlTrackElement}addRemoteTextTrack(options,manualCleanup){const htmlTrackElement=super.addRemoteTextTrack(options,manualCleanup);return this.featuresNativeTextTracks&&this.el().appendChild(htmlTrackElement),htmlTrackElement}removeRemoteTextTrack(track){if(super.removeRemoteTextTrack(track),this.featuresNativeTextTracks){const tracks=this.$$("track");let i=tracks.length;for(;i--;)track!==tracks[i]&&track!==tracks[i].track||this.el().removeChild(tracks[i])}}getVideoPlaybackQuality(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();const videoPlaybackQuality={};return void 0!==this.el().webkitDroppedFrameCount&&void 0!==this.el().webkitDecodedFrameCount&&(videoPlaybackQuality.droppedVideoFrames=this.el().webkitDroppedFrameCount,videoPlaybackQuality.totalVideoFrames=this.el().webkitDecodedFrameCount),window.performance&&(videoPlaybackQuality.creationTime=window.performance.now()),videoPlaybackQuality}}defineLazyProperty(Html5,"TEST_VID",(function(){if(!isReal())return;const video=document.createElement("video"),track=document.createElement("track");return track.kind="captions",track.srclang="en",track.label="English",video.appendChild(track),video})),Html5.isSupported=function(){try{Html5.TEST_VID.volume=.5}catch(e){return!1}return!(!Html5.TEST_VID||!Html5.TEST_VID.canPlayType)},Html5.canPlayType=function(type){return Html5.TEST_VID.canPlayType(type)},Html5.canPlaySource=function(srcObj,options){return Html5.canPlayType(srcObj.type)},Html5.canControlVolume=function(){try{const volume=Html5.TEST_VID.volume;Html5.TEST_VID.volume=volume/2+.1;const canControl=volume!==Html5.TEST_VID.volume;return canControl&&IS_IOS?(window.setTimeout((()=>{Html5&&Html5.prototype&&(Html5.prototype.featuresVolumeControl=volume!==Html5.TEST_VID.volume)})),!1):canControl}catch(e){return!1}},Html5.canMuteVolume=function(){try{const muted=Html5.TEST_VID.muted;return Html5.TEST_VID.muted=!muted,Html5.TEST_VID.muted?setAttribute(Html5.TEST_VID,"muted","muted"):removeAttribute(Html5.TEST_VID,"muted"),muted!==Html5.TEST_VID.muted}catch(e){return!1}},Html5.canControlPlaybackRate=function(){if(IS_ANDROID&&IS_CHROME&&CHROME_VERSION<58)return!1;try{const playbackRate=Html5.TEST_VID.playbackRate;return Html5.TEST_VID.playbackRate=playbackRate/2+.1,playbackRate!==Html5.TEST_VID.playbackRate}catch(e){return!1}},Html5.canOverrideAttributes=function(){try{const noop=()=>{};Object.defineProperty(document.createElement("video"),"src",{get:noop,set:noop}),Object.defineProperty(document.createElement("audio"),"src",{get:noop,set:noop}),Object.defineProperty(document.createElement("video"),"innerHTML",{get:noop,set:noop}),Object.defineProperty(document.createElement("audio"),"innerHTML",{get:noop,set:noop})}catch(e){return!1}return!0},Html5.supportsNativeTextTracks=function(){return IS_ANY_SAFARI||IS_IOS&&IS_CHROME},Html5.supportsNativeVideoTracks=function(){return!(!Html5.TEST_VID||!Html5.TEST_VID.videoTracks)},Html5.supportsNativeAudioTracks=function(){return!(!Html5.TEST_VID||!Html5.TEST_VID.audioTracks)},Html5.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],[["featuresMuteControl","canMuteVolume"],["featuresPlaybackRate","canControlPlaybackRate"],["featuresSourceset","canOverrideAttributes"],["featuresNativeTextTracks","supportsNativeTextTracks"],["featuresNativeVideoTracks","supportsNativeVideoTracks"],["featuresNativeAudioTracks","supportsNativeAudioTracks"]].forEach((function(_ref5){let[key,fn]=_ref5;defineLazyProperty(Html5.prototype,key,(()=>Html5[fn]()),!0)})),Html5.prototype.featuresVolumeControl=Html5.canControlVolume(),Html5.prototype.movingMediaElementInDOM=!IS_IOS,Html5.prototype.featuresFullscreenResize=!0,Html5.prototype.featuresProgressEvents=!0,Html5.prototype.featuresTimeupdateEvents=!0,Html5.prototype.featuresVideoFrameCallback=!(!Html5.TEST_VID||!Html5.TEST_VID.requestVideoFrameCallback),Html5.disposeMediaElement=function(el){if(el){for(el.parentNode&&el.parentNode.removeChild(el);el.hasChildNodes();)el.removeChild(el.firstChild);el.removeAttribute("src"),"function"==typeof el.load&&function(){try{el.load()}catch(e){}}()}},Html5.resetMediaElement=function(el){if(!el)return;const sources=el.querySelectorAll("source");let i=sources.length;for(;i--;)el.removeChild(sources[i]);el.removeAttribute("src"),"function"==typeof el.load&&function(){try{el.load()}catch(e){}}()},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]||this.el_.hasAttribute(prop)}})),["muted","defaultMuted","autoplay","loop","playsinline"].forEach((function(prop){Html5.prototype["set"+toTitleCase$1(prop)]=function(v){this.el_[prop]=v,v?this.el_.setAttribute(prop,prop):this.el_.removeAttribute(prop)}})),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","disablePictureInPicture","played","networkState","readyState","videoWidth","videoHeight","crossOrigin"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]}})),["volume","src","poster","preload","playbackRate","defaultPlaybackRate","disablePictureInPicture","crossOrigin"].forEach((function(prop){Html5.prototype["set"+toTitleCase$1(prop)]=function(v){this.el_[prop]=v}})),["pause","load","play"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]()}})),Tech.withSourceHandlers(Html5),Html5.nativeSourceHandler={},Html5.nativeSourceHandler.canPlayType=function(type){try{return Html5.TEST_VID.canPlayType(type)}catch(e){return""}},Html5.nativeSourceHandler.canHandleSource=function(source,options){if(source.type)return Html5.nativeSourceHandler.canPlayType(source.type);if(source.src){const ext=getFileExtension(source.src);return Html5.nativeSourceHandler.canPlayType("video/".concat(ext))}return""},Html5.nativeSourceHandler.handleSource=function(source,tech,options){tech.setSrc(source.src)},Html5.nativeSourceHandler.dispose=function(){},Html5.registerSourceHandler(Html5.nativeSourceHandler),Tech.registerTech("Html5",Html5);const TECH_EVENTS_RETRIGGER=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],TECH_EVENTS_QUEUE={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},BREAKPOINT_ORDER=["tiny","xsmall","small","medium","large","xlarge","huge"],BREAKPOINT_CLASSES={};BREAKPOINT_ORDER.forEach((k=>{const v="x"===k.charAt(0)?"x-".concat(k.substring(1)):k;BREAKPOINT_CLASSES[k]="vjs-layout-".concat(v)}));const DEFAULT_BREAKPOINTS={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0};class Player extends Component$1{constructor(tag,options,ready){if(tag.id=tag.id||options.id||"vjs_video_".concat(newGUID()),(options=Object.assign(Player.getTagSettings(tag),options)).initChildren=!1,options.createEl=!1,options.evented=!1,options.reportTouchActivity=!1,!options.language){const closest=tag.closest("[lang]");closest&&(options.language=closest.getAttribute("lang"))}if(super(null,options,ready),this.boundDocumentFullscreenChange_=e=>this.documentFullscreenChange_(e),this.boundFullWindowOnEscKey_=e=>this.fullWindowOnEscKey(e),this.boundUpdateStyleEl_=e=>this.updateStyleEl_(e),this.boundApplyInitTime_=e=>this.applyInitTime_(e),this.boundUpdateCurrentBreakpoint_=e=>this.updateCurrentBreakpoint_(e),this.boundHandleTechClick_=e=>this.handleTechClick_(e),this.boundHandleTechDoubleClick_=e=>this.handleTechDoubleClick_(e),this.boundHandleTechTouchStart_=e=>this.handleTechTouchStart_(e),this.boundHandleTechTouchMove_=e=>this.handleTechTouchMove_(e),this.boundHandleTechTouchEnd_=e=>this.handleTechTouchEnd_(e),this.boundHandleTechTap_=e=>this.handleTechTap_(e),this.isFullscreen_=!1,this.log=createLogger(this.id_),this.fsApi_=FullscreenApi,this.isPosterFromTech_=!1,this.queuedCallbacks_=[],this.isReady_=!1,this.hasStarted_=!1,this.userActive_=!1,this.debugEnabled_=!1,this.audioOnlyMode_=!1,this.audioPosterMode_=!1,this.audioOnlyCache_={playerHeight:null,hiddenChildren:[]},!this.options_||!this.options_.techOrder||!this.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(this.tag=tag,this.tagAttributes=tag&&getAttributes(tag),this.language(this.options_.language),options.languages){const languagesToLower={};Object.getOwnPropertyNames(options.languages).forEach((function(name){languagesToLower[name.toLowerCase()]=options.languages[name]})),this.languages_=languagesToLower}else this.languages_=Player.prototype.options_.languages;this.resetCache_(),this.poster_=options.poster||"",this.controls_=!!options.controls,tag.controls=!1,tag.removeAttribute("controls"),this.changingSrc_=!1,this.playCallbacks_=[],this.playTerminatedQueue_=[],tag.hasAttribute("autoplay")?this.autoplay(!0):this.autoplay(this.options_.autoplay),options.plugins&&Object.keys(options.plugins).forEach((name=>{if("function"!=typeof this[name])throw new Error('plugin "'.concat(name,'" does not exist'))})),this.scrubbing_=!1,this.el_=this.createEl(),evented(this,{eventBusKey:"el_"}),this.fsApi_.requestFullscreen&&(on(document,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.on(this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_)),this.fluid_&&this.on(["playerreset","resize"],this.boundUpdateStyleEl_);const playerOptionsCopy=merge$2(this.options_);options.plugins&&Object.keys(options.plugins).forEach((name=>{this[name](options.plugins[name])})),options.debug&&this.debug(!0),this.options_.playerOptions=playerOptionsCopy,this.middleware_=[],this.playbackRates(options.playbackRates),this.initChildren(),this.isAudio("audio"===tag.nodeName.toLowerCase()),this.controls()?this.addClass("vjs-controls-enabled"):this.addClass("vjs-controls-disabled"),this.el_.setAttribute("role","region"),this.isAudio()?this.el_.setAttribute("aria-label",this.localize("Audio Player")):this.el_.setAttribute("aria-label",this.localize("Video Player")),this.isAudio()&&this.addClass("vjs-audio"),TOUCH_ENABLED&&this.addClass("vjs-touch-enabled"),IS_IOS||this.addClass("vjs-workinghover"),Player.players[this.id_]=this;const majorVersion="8.3.0".split(".")[0];this.addClass("vjs-v".concat(majorVersion)),this.userActive(!0),this.reportUserActivity(),this.one("play",(e=>this.listenForUserActivity_(e))),this.on("keydown",(e=>this.handleKeyDown(e))),this.on("languagechange",(e=>this.handleLanguagechange(e))),this.breakpoints(this.options_.breakpoints),this.responsive(this.options_.responsive),this.on("ready",(()=>{this.audioPosterMode(this.options_.audioPosterMode),this.audioOnlyMode(this.options_.audioOnlyMode)}))}dispose(){this.trigger("dispose"),this.off("dispose"),off(document,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),off(document,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),Player.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),middlewareInstances[this.id()]=null,ALL.names.forEach((name=>{const list=this[ALL[name].getterName]();list&&list.off&&list.off()})),super.dispose({restoreEl:this.options_.restoreEl})}createEl(){let el,tag=this.tag,playerElIngest=this.playerElIngest_=tag.parentNode&&tag.parentNode.hasAttribute&&tag.parentNode.hasAttribute("data-vjs-player");const divEmbed="video-js"===this.tag.tagName.toLowerCase();playerElIngest?el=this.el_=tag.parentNode:divEmbed||(el=this.el_=super.createEl("div"));const attrs=getAttributes(tag);if(divEmbed){for(el=this.el_=tag,tag=this.tag=document.createElement("video");el.children.length;)tag.appendChild(el.firstChild);hasClass(el,"video-js")||addClass(el,"video-js"),el.appendChild(tag),playerElIngest=this.playerElIngest_=el,Object.keys(el).forEach((k=>{try{tag[k]=el[k]}catch(e){}}))}if(tag.setAttribute("tabindex","-1"),attrs.tabindex="-1",IS_CHROME&&IS_WINDOWS&&(tag.setAttribute("role","application"),attrs.role="application"),tag.removeAttribute("width"),tag.removeAttribute("height"),"width"in attrs&&delete attrs.width,"height"in attrs&&delete attrs.height,Object.getOwnPropertyNames(attrs).forEach((function(attr){divEmbed&&"class"===attr||el.setAttribute(attr,attrs[attr]),divEmbed&&tag.setAttribute(attr,attrs[attr])})),tag.playerId=tag.id,tag.id+="_html5_api",tag.className="vjs-tech",tag.player=el.player=this,this.addClass("vjs-paused"),!0!==window.VIDEOJS_NO_DYNAMIC_STYLE){this.styleEl_=createStyleElement("vjs-styles-dimensions");const defaultsStyleEl=$(".vjs-styles-defaults"),head=$("head");head.insertBefore(this.styleEl_,defaultsStyleEl?defaultsStyleEl.nextSibling:head.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),this.crossOrigin(this.options_.crossOrigin||this.options_.crossorigin);const links=tag.getElementsByTagName("a");for(let i=0;i{this.on(["playerreset","resize"],this.boundUpdateStyleEl_)},isEvented(target=this)?callback():(target.eventedCallbacks||(target.eventedCallbacks=[]),target.eventedCallbacks.push(callback))):this.removeClass("vjs-fluid"),this.updateStyleEl_()}fill(bool){if(void 0===bool)return!!this.fill_;this.fill_=!!bool,bool?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")}aspectRatio(ratio){if(void 0===ratio)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(ratio))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=ratio,this.fluid(!0),this.updateStyleEl_()}updateStyleEl_(){if(!0===window.VIDEOJS_NO_DYNAMIC_STYLE){const width="number"==typeof this.width_?this.width_:this.options_.width,height="number"==typeof this.height_?this.height_:this.options_.height,techEl=this.tech_&&this.tech_.el();return void(techEl&&(width>=0&&(techEl.width=width),height>=0&&(techEl.height=height)))}let width,height,aspectRatio,idClass;aspectRatio=void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:this.videoWidth()>0?this.videoWidth()+":"+this.videoHeight():"16:9";const ratioParts=aspectRatio.split(":"),ratioMultiplier=ratioParts[1]/ratioParts[0];width=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/ratioMultiplier:this.videoWidth()||300,height=void 0!==this.height_?this.height_:width*ratioMultiplier,idClass=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(idClass),setTextContent(this.styleEl_,"\n .".concat(idClass," {\n width: ").concat(width,"px;\n height: ").concat(height,"px;\n }\n\n .").concat(idClass,".vjs-fluid:not(.vjs-audio-only-mode) {\n padding-top: ").concat(100*ratioMultiplier,"%;\n }\n "))}loadTech_(techName,source){this.tech_&&this.unloadTech_();const titleTechName=toTitleCase$1(techName),camelTechName=techName.charAt(0).toLowerCase()+techName.slice(1);"Html5"!==titleTechName&&this.tag&&(Tech.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=titleTechName,this.isReady_=!1;let autoplay=this.autoplay();("string"==typeof this.autoplay()||!0===this.autoplay()&&this.options_.normalizeAutoplay)&&(autoplay=!1);const techOptions={source:source,autoplay:autoplay,nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:"".concat(this.id(),"_").concat(camelTechName,"_api"),playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,disablePictureInPicture:this.options_.disablePictureInPicture,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};ALL.names.forEach((name=>{const props=ALL[name];techOptions[props.getterName]=this[props.privateName]})),Object.assign(techOptions,this.options_[titleTechName]),Object.assign(techOptions,this.options_[camelTechName]),Object.assign(techOptions,this.options_[techName.toLowerCase()]),this.tag&&(techOptions.tag=this.tag),source&&source.src===this.cache_.src&&this.cache_.currentTime>0&&(techOptions.startTime=this.cache_.currentTime);const TechClass=Tech.getTech(techName);if(!TechClass)throw new Error("No Tech named '".concat(titleTechName,"' exists! '").concat(titleTechName,"' should be registered using videojs.registerTech()'"));this.tech_=new TechClass(techOptions),this.tech_.ready(bind_(this,this.handleTechReady_),!0),textTrackConverter_jsonToTextTracks(this.textTracksJson_||[],this.tech_),TECH_EVENTS_RETRIGGER.forEach((event=>{this.on(this.tech_,event,(e=>this["handleTech".concat(toTitleCase$1(event),"_")](e)))})),Object.keys(TECH_EVENTS_QUEUE).forEach((event=>{this.on(this.tech_,event,(eventObj=>{0===this.tech_.playbackRate()&&this.tech_.seeking()?this.queuedCallbacks_.push({callback:this["handleTech".concat(TECH_EVENTS_QUEUE[event],"_")].bind(this),event:eventObj}):this["handleTech".concat(TECH_EVENTS_QUEUE[event],"_")](eventObj)}))})),this.on(this.tech_,"loadstart",(e=>this.handleTechLoadStart_(e))),this.on(this.tech_,"sourceset",(e=>this.handleTechSourceset_(e))),this.on(this.tech_,"waiting",(e=>this.handleTechWaiting_(e))),this.on(this.tech_,"ended",(e=>this.handleTechEnded_(e))),this.on(this.tech_,"seeking",(e=>this.handleTechSeeking_(e))),this.on(this.tech_,"play",(e=>this.handleTechPlay_(e))),this.on(this.tech_,"pause",(e=>this.handleTechPause_(e))),this.on(this.tech_,"durationchange",(e=>this.handleTechDurationChange_(e))),this.on(this.tech_,"fullscreenchange",((e,data)=>this.handleTechFullscreenChange_(e,data))),this.on(this.tech_,"fullscreenerror",((e,err)=>this.handleTechFullscreenError_(e,err))),this.on(this.tech_,"enterpictureinpicture",(e=>this.handleTechEnterPictureInPicture_(e))),this.on(this.tech_,"leavepictureinpicture",(e=>this.handleTechLeavePictureInPicture_(e))),this.on(this.tech_,"error",(e=>this.handleTechError_(e))),this.on(this.tech_,"posterchange",(e=>this.handleTechPosterChange_(e))),this.on(this.tech_,"textdata",(e=>this.handleTechTextData_(e))),this.on(this.tech_,"ratechange",(e=>this.handleTechRateChange_(e))),this.on(this.tech_,"loadedmetadata",this.boundUpdateStyleEl_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===titleTechName&&this.tag||prependTo(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)}unloadTech_(){ALL.names.forEach((name=>{const props=ALL[name];this[props.privateName]=this[props.getterName]()})),this.textTracksJson_=textTrackConverter_textTracksToJson(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1}tech(safety){return void 0===safety&&log$1.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_}addTechControlsListeners_(){this.removeTechControlsListeners_(),this.on(this.tech_,"click",this.boundHandleTechClick_),this.on(this.tech_,"dblclick",this.boundHandleTechDoubleClick_),this.on(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.on(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.on(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.on(this.tech_,"tap",this.boundHandleTechTap_)}removeTechControlsListeners_(){this.off(this.tech_,"tap",this.boundHandleTechTap_),this.off(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.off(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.off(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.off(this.tech_,"click",this.boundHandleTechClick_),this.off(this.tech_,"dblclick",this.boundHandleTechDoubleClick_)}handleTechReady_(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()}handleTechLoadStart_(){this.removeClass("vjs-ended","vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):this.trigger("loadstart"),this.manualAutoplay_(!0===this.autoplay()&&this.options_.normalizeAutoplay?"play":this.autoplay())}manualAutoplay_(type){if(!this.tech_||"string"!=typeof type)return;const resolveMuted=()=>{const previouslyMuted=this.muted();this.muted(!0);const restoreMuted=()=>{this.muted(previouslyMuted)};this.playTerminatedQueue_.push(restoreMuted);const mutedPromise=this.play();if(isPromise(mutedPromise))return mutedPromise.catch((err=>{throw restoreMuted(),new Error("Rejection at manualAutoplay. Restoring muted value. ".concat(err||""))}))};let promise;return"any"!==type||this.muted()?promise="muted"!==type||this.muted()?this.play():resolveMuted():(promise=this.play(),isPromise(promise)&&(promise=promise.catch(resolveMuted))),isPromise(promise)?promise.then((()=>{this.trigger({type:"autoplay-success",autoplay:type})})).catch((()=>{this.trigger({type:"autoplay-failure",autoplay:type})})):void 0}updateSourceCaches_(){let srcObj=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",src=srcObj,type="";"string"!=typeof src&&(src=srcObj.src,type=srcObj.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],src&&!type&&(type=((player,src)=>{if(!src)return"";if(player.cache_.source.src===src&&player.cache_.source.type)return player.cache_.source.type;const matchingSources=player.cache_.sources.filter((s=>s.src===src));if(matchingSources.length)return matchingSources[0].type;const sources=player.$$("source");for(let i=0;is.src&&s.src===src)),sourceElSources=[],sourceEls=this.$$("source"),matchingSourceEls=[];for(let i=0;ithis.updateSourceCaches_(src);const playerSrc=this.currentSource().src,eventSrc=event.src;playerSrc&&!/^blob:/.test(playerSrc)&&/^blob:/.test(eventSrc)&&(!this.lastSource_||this.lastSource_.tech!==eventSrc&&this.lastSource_.player!==playerSrc)&&(updateSourceCaches=()=>{}),updateSourceCaches(eventSrc),event.src||this.tech_.any(["sourceset","loadstart"],(e=>{if("sourceset"===e.type)return;const techSrc=this.techGet("currentSrc");this.lastSource_.tech=techSrc,this.updateSourceCaches_(techSrc)}))}this.lastSource_={player:this.currentSource().src,tech:event.src},this.trigger({src:event.src,type:"sourceset"})}hasStarted(request){if(void 0===request)return this.hasStarted_;request!==this.hasStarted_&&(this.hasStarted_=request,this.hasStarted_?this.addClass("vjs-has-started"):this.removeClass("vjs-has-started"))}handleTechPlay_(){this.removeClass("vjs-ended","vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")}handleTechRateChange_(){this.tech_.playbackRate()>0&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach((queued=>queued.callback(queued.event))),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")}handleTechWaiting_(){this.addClass("vjs-waiting"),this.trigger("waiting");const timeWhenWaiting=this.currentTime(),timeUpdateListener=()=>{timeWhenWaiting!==this.currentTime()&&(this.removeClass("vjs-waiting"),this.off("timeupdate",timeUpdateListener))};this.on("timeupdate",timeUpdateListener)}handleTechCanPlay_(){this.removeClass("vjs-waiting"),this.trigger("canplay")}handleTechCanPlayThrough_(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")}handleTechPlaying_(){this.removeClass("vjs-waiting"),this.trigger("playing")}handleTechSeeking_(){this.addClass("vjs-seeking"),this.trigger("seeking")}handleTechSeeked_(){this.removeClass("vjs-seeking","vjs-ended"),this.trigger("seeked")}handleTechPause_(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")}handleTechEnded_(){this.addClass("vjs-ended"),this.removeClass("vjs-waiting"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")}handleTechDurationChange_(){this.duration(this.techGet_("duration"))}handleTechClick_(event){this.controls_&&(void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.click&&!1===this.options_.userActions.click||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.click?this.options_.userActions.click.call(this,event):this.paused()?silencePromise(this.play()):this.pause()))}handleTechDoubleClick_(event){if(!this.controls_)return;Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),(el=>el.contains(event.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,event):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen())}handleTechTap_(){this.userActive(!this.userActive())}handleTechTouchStart_(){this.userWasActive=this.userActive()}handleTechTouchMove_(){this.userWasActive&&this.reportUserActivity()}handleTechTouchEnd_(event){event.cancelable&&event.preventDefault()}toggleFullscreenClass_(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")}documentFullscreenChange_(e){const targetPlayer=e.target.player;if(targetPlayer&&targetPlayer!==this)return;const el=this.el();let isFs=document[this.fsApi_.fullscreenElement]===el;!isFs&&el.matches?isFs=el.matches(":"+this.fsApi_.fullscreen):!isFs&&el.msMatchesSelector&&(isFs=el.msMatchesSelector(":"+this.fsApi_.fullscreen)),this.isFullscreen(isFs)}handleTechFullscreenChange_(event,data){data&&(data.nativeIOSFullscreen&&(this.addClass("vjs-ios-native-fs"),this.tech_.one("webkitendfullscreen",(()=>{this.removeClass("vjs-ios-native-fs")}))),this.isFullscreen(data.isFullscreen))}handleTechFullscreenError_(event,err){this.trigger("fullscreenerror",err)}togglePictureInPictureClass_(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")}handleTechEnterPictureInPicture_(event){this.isInPictureInPicture(!0)}handleTechLeavePictureInPicture_(event){this.isInPictureInPicture(!1)}handleTechError_(){const error=this.tech_.error();this.error(error)}handleTechTextData_(){let data=null;arguments.length>1&&(data=arguments[1]),this.trigger("textdata",data)}getCache(){return this.cache_}resetCache_(){this.cache_={currentTime:0,initTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],playbackRates:[],volume:1}}techCall_(method,arg){this.ready((function(){if(method in allowedSetters)return function(middleware,tech,method,arg){return tech[method](middleware.reduce(middlewareIterator(method),arg))}(this.middleware_,this.tech_,method,arg);if(method in allowedMediators)return mediate(this.middleware_,this.tech_,method,arg);try{this.tech_&&this.tech_[method](arg)}catch(e){throw log$1(e),e}}),!0)}techGet_(method){if(this.tech_&&this.tech_.isReady_){if(method in allowedGetters)return function(middleware,tech,method){return middleware.reduceRight(middlewareIterator(method),tech[method]())}(this.middleware_,this.tech_,method);if(method in allowedMediators)return mediate(this.middleware_,this.tech_,method);try{return this.tech_[method]()}catch(e){if(void 0===this.tech_[method])throw log$1("Video.js: ".concat(method," method not defined for ").concat(this.techName_," playback technology."),e),e;if("TypeError"===e.name)throw log$1("Video.js: ".concat(method," unavailable on ").concat(this.techName_," playback technology element."),e),this.tech_.isReady_=!1,e;throw log$1(e),e}}}play(){return new Promise((resolve=>{this.play_(resolve)}))}play_(){let callback=arguments.length>0&&void 0!==arguments[0]?arguments[0]:silencePromise;this.playCallbacks_.push(callback);const isSrcReady=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc())),isSafariOrIOS=Boolean(IS_ANY_SAFARI||IS_IOS);if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!isSrcReady)return this.waitToPlay_=e=>{this.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(!isSrcReady&&isSafariOrIOS&&this.load());const val=this.techGet_("play");isSafariOrIOS&&this.hasClass("vjs-ended")&&this.resetProgressBar_(),null===val?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(val)}runPlayTerminatedQueue_(){const queue=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],queue.forEach((function(q){q()}))}runPlayCallbacks_(val){const callbacks=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],callbacks.forEach((function(cb){cb(val)}))}pause(){this.techCall_("pause")}paused(){return!1!==this.techGet_("paused")}played(){return this.techGet_("played")||createTimeRanges$1(0,0)}scrubbing(isScrubbing){if(void 0===isScrubbing)return this.scrubbing_;this.scrubbing_=!!isScrubbing,this.techCall_("setScrubbing",this.scrubbing_),isScrubbing?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")}currentTime(seconds){return void 0!==seconds?(seconds<0&&(seconds=0),this.isReady_&&!this.changingSrc_&&this.tech_&&this.tech_.isReady_?(this.techCall_("setCurrentTime",seconds),void(this.cache_.initTime=0)):(this.cache_.initTime=seconds,this.off("canplay",this.boundApplyInitTime_),void this.one("canplay",this.boundApplyInitTime_))):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)}applyInitTime_(){this.currentTime(this.cache_.initTime)}duration(seconds){if(void 0===seconds)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(seconds=parseFloat(seconds))<0&&(seconds=1/0),seconds!==this.cache_.duration&&(this.cache_.duration=seconds,seconds===1/0?this.addClass("vjs-live"):this.removeClass("vjs-live"),isNaN(seconds)||this.trigger("durationchange"))}remainingTime(){return this.duration()-this.currentTime()}remainingTimeDisplay(){return Math.floor(this.duration())-Math.floor(this.currentTime())}buffered(){let buffered=this.techGet_("buffered");return buffered&&buffered.length||(buffered=createTimeRanges$1(0,0)),buffered}bufferedPercent(){return bufferedPercent(this.buffered(),this.duration())}bufferedEnd(){const buffered=this.buffered(),duration=this.duration();let end=buffered.end(buffered.length-1);return end>duration&&(end=duration),end}volume(percentAsDecimal){let vol;return void 0!==percentAsDecimal?(vol=Math.max(0,Math.min(1,parseFloat(percentAsDecimal))),this.cache_.volume=vol,this.techCall_("setVolume",vol),void(vol>0&&this.lastVolume_(vol))):(vol=parseFloat(this.techGet_("volume")),isNaN(vol)?1:vol)}muted(muted){if(void 0===muted)return this.techGet_("muted")||!1;this.techCall_("setMuted",muted)}defaultMuted(defaultMuted){return void 0!==defaultMuted?this.techCall_("setDefaultMuted",defaultMuted):this.techGet_("defaultMuted")||!1}lastVolume_(percentAsDecimal){if(void 0===percentAsDecimal||0===percentAsDecimal)return this.cache_.lastVolume;this.cache_.lastVolume=percentAsDecimal}supportsFullScreen(){return this.techGet_("supportsFullScreen")||!1}isFullscreen(isFS){if(void 0!==isFS){const oldValue=this.isFullscreen_;return this.isFullscreen_=Boolean(isFS),this.isFullscreen_!==oldValue&&this.fsApi_.prefixed&&this.trigger("fullscreenchange"),void this.toggleFullscreenClass_()}return this.isFullscreen_}requestFullscreen(fullscreenOptions){this.isInPictureInPicture()&&this.exitPictureInPicture();const self=this;return new Promise(((resolve,reject)=>{function offHandler(){self.off("fullscreenerror",errorHandler),self.off("fullscreenchange",changeHandler)}function changeHandler(){offHandler(),resolve()}function errorHandler(e,err){offHandler(),reject(err)}self.one("fullscreenchange",changeHandler),self.one("fullscreenerror",errorHandler);const promise=self.requestFullscreenHelper_(fullscreenOptions);promise&&(promise.then(offHandler,offHandler),promise.then(resolve,reject))}))}requestFullscreenHelper_(fullscreenOptions){let fsOptions;if(this.fsApi_.prefixed||(fsOptions=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==fullscreenOptions&&(fsOptions=fullscreenOptions)),this.fsApi_.requestFullscreen){const promise=this.el_[this.fsApi_.requestFullscreen](fsOptions);return promise&&promise.then((()=>this.isFullscreen(!0)),(()=>this.isFullscreen(!1))),promise}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("enterFullScreen"):this.enterFullWindow()}exitFullscreen(){const self=this;return new Promise(((resolve,reject)=>{function offHandler(){self.off("fullscreenerror",errorHandler),self.off("fullscreenchange",changeHandler)}function changeHandler(){offHandler(),resolve()}function errorHandler(e,err){offHandler(),reject(err)}self.one("fullscreenchange",changeHandler),self.one("fullscreenerror",errorHandler);const promise=self.exitFullscreenHelper_();promise&&(promise.then(offHandler,offHandler),promise.then(resolve,reject))}))}exitFullscreenHelper_(){if(this.fsApi_.requestFullscreen){const promise=document[this.fsApi_.exitFullscreen]();return promise&&silencePromise(promise.then((()=>this.isFullscreen(!1)))),promise}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("exitFullScreen"):this.exitFullWindow()}enterFullWindow(){this.isFullscreen(!0),this.isFullWindow=!0,this.docOrigOverflow=document.documentElement.style.overflow,on(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow="hidden",addClass(document.body,"vjs-full-window"),this.trigger("enterFullWindow")}fullWindowOnEscKey(event){keycode.isEventKey(event,"Esc")&&!0===this.isFullscreen()&&(this.isFullWindow?this.exitFullWindow():this.exitFullscreen())}exitFullWindow(){this.isFullscreen(!1),this.isFullWindow=!1,off(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow=this.docOrigOverflow,removeClass(document.body,"vjs-full-window"),this.trigger("exitFullWindow")}disablePictureInPicture(value){if(void 0===value)return this.techGet_("disablePictureInPicture");this.techCall_("setDisablePictureInPicture",value),this.options_.disablePictureInPicture=value,this.trigger("disablepictureinpicturechanged")}isInPictureInPicture(isPiP){return void 0!==isPiP?(this.isInPictureInPicture_=!!isPiP,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_}requestPictureInPicture(){if(this.options_.enableDocumentPictureInPicture&&window.documentPictureInPicture){const pipContainer=document.createElement(this.el().tagName);return pipContainer.classList=this.el().classList,pipContainer.classList.add("vjs-pip-container"),this.posterImage&&pipContainer.appendChild(this.posterImage.el().cloneNode(!0)),this.titleBar&&pipContainer.appendChild(this.titleBar.el().cloneNode(!0)),pipContainer.appendChild(createEl("p",{className:"vjs-pip-text"},{},this.localize("Playing in picture-in-picture"))),window.documentPictureInPicture.requestWindow({initialAspectRatio:this.videoWidth()/this.videoHeight(),copyStyleSheets:!0}).then((pipWindow=>(this.el_.parentNode.insertBefore(pipContainer,this.el_),pipWindow.document.body.append(this.el_),pipWindow.document.body.classList.add("vjs-pip-window"),this.player_.isInPictureInPicture(!0),this.player_.trigger("enterpictureinpicture"),pipWindow.addEventListener("unload",(event=>{const pipVideo=event.target.querySelector(".video-js");pipContainer.replaceWith(pipVideo),this.player_.isInPictureInPicture(!1),this.player_.trigger("leavepictureinpicture")})),pipWindow)))}return"pictureInPictureEnabled"in document&&!1===this.disablePictureInPicture()?this.techGet_("requestPictureInPicture"):Promise.reject("No PiP mode is available")}exitPictureInPicture(){return window.documentPictureInPicture&&window.documentPictureInPicture.window?(window.documentPictureInPicture.window.close(),Promise.resolve()):"pictureInPictureEnabled"in document?document.exitPictureInPicture():void 0}handleKeyDown(event){const{userActions:userActions}=this.options_;if(!userActions||!userActions.hotkeys)return;(el=>{const tagName=el.tagName.toLowerCase();if(el.isContentEditable)return!0;if("input"===tagName)return-1===["button","checkbox","hidden","radio","reset","submit"].indexOf(el.type);return-1!==["textarea"].indexOf(tagName)})(this.el_.ownerDocument.activeElement)||("function"==typeof userActions.hotkeys?userActions.hotkeys.call(this,event):this.handleHotkeys(event))}handleHotkeys(event){const hotkeys=this.options_.userActions?this.options_.userActions.hotkeys:{},{fullscreenKey:fullscreenKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"f")),muteKey:muteKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"m")),playPauseKey:playPauseKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"k")||keycode.isEventKey(keydownEvent,"Space"))}=hotkeys;if(fullscreenKey.call(this,event)){event.preventDefault(),event.stopPropagation();const FSToggle=Component$1.getComponent("FullscreenToggle");!1!==document[this.fsApi_.fullscreenEnabled]&&FSToggle.prototype.handleClick.call(this,event)}else if(muteKey.call(this,event)){event.preventDefault(),event.stopPropagation();Component$1.getComponent("MuteToggle").prototype.handleClick.call(this,event)}else if(playPauseKey.call(this,event)){event.preventDefault(),event.stopPropagation();Component$1.getComponent("PlayToggle").prototype.handleClick.call(this,event)}}canPlayType(type){let can;for(let i=0,j=this.options_.techOrder;i[techName,Tech.getTech(techName)])).filter((_ref6=>{let[techName,tech]=_ref6;return tech?tech.isSupported():(log$1.error('The "'.concat(techName,'" tech is undefined. Skipped browser support check for that tech.')),!1)})),findFirstPassingTechSourcePair=function(outerArray,innerArray,tester){let found;return outerArray.some((outerChoice=>innerArray.some((innerChoice=>{if(found=tester(outerChoice,innerChoice),found)return!0})))),found};let foundSourceAndTech;const finder=(_ref7,source)=>{let[techName,tech]=_ref7;if(tech.canPlaySource(source,this.options_[techName.toLowerCase()]))return{source:source,tech:techName}};var fn;return foundSourceAndTech=this.options_.sourceOrder?findFirstPassingTechSourcePair(sources,techs,(fn=finder,(a,b)=>fn(b,a))):findFirstPassingTechSourcePair(techs,sources,finder),foundSourceAndTech||!1}handleSrc_(source,isRetry){if(void 0===source)return this.cache_.src||"";this.resetRetryOnError_&&this.resetRetryOnError_();const sources=filterSource(source);if(sources.length){if(this.changingSrc_=!0,isRetry||(this.cache_.sources=sources),this.updateSourceCaches_(sources[0]),setSource(this,sources[0],((middlewareSource,mws)=>{this.middleware_=mws,isRetry||(this.cache_.sources=sources),this.updateSourceCaches_(middlewareSource);if(this.src_(middlewareSource))return sources.length>1?this.handleSrc_(sources.slice(1)):(this.changingSrc_=!1,this.setTimeout((function(){this.error({code:4,message:this.options_.notSupportedMessage})}),0),void this.triggerReady());var middleware,tech;middleware=mws,tech=this.tech_,middleware.forEach((mw=>mw.setTech&&mw.setTech(tech)))})),sources.length>1){const retry=()=>{this.error(null),this.handleSrc_(sources.slice(1),!0)},stopListeningForErrors=()=>{this.off("error",retry)};this.one("error",retry),this.one("playing",stopListeningForErrors),this.resetRetryOnError_=()=>{this.off("error",retry),this.off("playing",stopListeningForErrors)}}}else this.setTimeout((function(){this.error({code:4,message:this.options_.notSupportedMessage})}),0)}src(source){return this.handleSrc_(source,!1)}src_(source){const sourceTech=this.selectSource([source]);return!sourceTech||(titleCaseEquals(sourceTech.tech,this.techName_)?(this.ready((function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",source):this.techCall_("src",source.src),this.changingSrc_=!1}),!0),!1):(this.changingSrc_=!0,this.loadTech_(sourceTech.tech,sourceTech.source),this.tech_.ready((()=>{this.changingSrc_=!1})),!1))}load(){this.techCall_("load")}reset(){if(this.paused())this.doReset_();else{silencePromise(this.play().then((()=>this.doReset_())))}}doReset_(){this.tech_&&this.tech_.clearTracks("text"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),isEvented(this)&&this.trigger("playerreset")}resetControlBarUI_(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()}resetProgressBar_(){this.currentTime(0);const{currentTimeDisplay:currentTimeDisplay,durationDisplay:durationDisplay,progressControl:progressControl,remainingTimeDisplay:remainingTimeDisplay}=this.controlBar||{},{seekBar:seekBar}=progressControl||{};currentTimeDisplay&¤tTimeDisplay.updateContent(),durationDisplay&&durationDisplay.updateContent(),remainingTimeDisplay&&remainingTimeDisplay.updateContent(),seekBar&&(seekBar.update(),seekBar.loadProgressBar&&seekBar.loadProgressBar.update())}resetPlaybackRate_(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()}resetVolumeBar_(){this.volume(1),this.trigger("volumechange")}currentSources(){const source=this.currentSource(),sources=[];return 0!==Object.keys(source).length&&sources.push(source),this.cache_.sources||sources}currentSource(){return this.cache_.source||{}}currentSrc(){return this.currentSource()&&this.currentSource().src||""}currentType(){return this.currentSource()&&this.currentSource().type||""}preload(value){return void 0!==value?(this.techCall_("setPreload",value),void(this.options_.preload=value)):this.techGet_("preload")}autoplay(value){if(void 0===value)return this.options_.autoplay||!1;let techAutoplay;"string"==typeof value&&/(any|play|muted)/.test(value)||!0===value&&this.options_.normalizeAutoplay?(this.options_.autoplay=value,this.manualAutoplay_("string"==typeof value?value:"play"),techAutoplay=!1):this.options_.autoplay=!!value,techAutoplay=void 0===techAutoplay?this.options_.autoplay:techAutoplay,this.tech_&&this.techCall_("setAutoplay",techAutoplay)}playsinline(value){return void 0!==value?(this.techCall_("setPlaysinline",value),this.options_.playsinline=value,this):this.techGet_("playsinline")}loop(value){return void 0!==value?(this.techCall_("setLoop",value),void(this.options_.loop=value)):this.techGet_("loop")}poster(src){if(void 0===src)return this.poster_;src||(src=""),src!==this.poster_&&(this.poster_=src,this.techCall_("setPoster",src),this.isPosterFromTech_=!1,this.trigger("posterchange"))}handleTechPosterChange_(){if((!this.poster_||this.options_.techCanOverridePoster)&&this.tech_&&this.tech_.poster){const newPoster=this.tech_.poster()||"";newPoster!==this.poster_&&(this.poster_=newPoster,this.isPosterFromTech_=!0,this.trigger("posterchange"))}}controls(bool){if(void 0===bool)return!!this.controls_;bool=!!bool,this.controls_!==bool&&(this.controls_=bool,this.usingNativeControls()&&this.techCall_("setControls",bool),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_()))}usingNativeControls(bool){if(void 0===bool)return!!this.usingNativeControls_;bool=!!bool,this.usingNativeControls_!==bool&&(this.usingNativeControls_=bool,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))}error(err){if(void 0===err)return this.error_||null;if(hooks("beforeerror").forEach((hookFunction=>{const newErr=hookFunction(this,err);isObject$1(newErr)&&!Array.isArray(newErr)||"string"==typeof newErr||"number"==typeof newErr||null===newErr?err=newErr:this.log.error("please return a value that MediaError expects in beforeerror hooks")})),this.options_.suppressNotSupportedError&&err&&4===err.code){const triggerSuppressedError=function(){this.error(err)};return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],triggerSuppressedError),void this.one("loadstart",(function(){this.off(["click","touchstart"],triggerSuppressedError)}))}if(null===err)return this.error_=err,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new MediaError(err),this.addClass("vjs-error"),log$1.error("(CODE:".concat(this.error_.code," ").concat(MediaError.errorTypes[this.error_.code],")"),this.error_.message,this.error_),this.trigger("error"),hooks("error").forEach((hookFunction=>hookFunction(this,this.error_)))}reportUserActivity(event){this.userActivity_=!0}userActive(bool){if(void 0===bool)return this.userActive_;if((bool=!!bool)!==this.userActive_){if(this.userActive_=bool,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")}}listenForUserActivity_(){let mouseInProgress,lastMoveX,lastMoveY;const handleActivity=bind_(this,this.reportUserActivity),handleMouseUpAndMouseLeave=function(event){handleActivity(),this.clearInterval(mouseInProgress)};this.on("mousedown",(function(){handleActivity(),this.clearInterval(mouseInProgress),mouseInProgress=this.setInterval(handleActivity,250)})),this.on("mousemove",(function(e){e.screenX===lastMoveX&&e.screenY===lastMoveY||(lastMoveX=e.screenX,lastMoveY=e.screenY,handleActivity())})),this.on("mouseup",handleMouseUpAndMouseLeave),this.on("mouseleave",handleMouseUpAndMouseLeave);const controlBar=this.getChild("controlBar");let inactivityTimeout;!controlBar||IS_IOS||IS_ANDROID||(controlBar.on("mouseenter",(function(event){0!==this.player().options_.inactivityTimeout&&(this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout),this.player().options_.inactivityTimeout=0})),controlBar.on("mouseleave",(function(event){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout}))),this.on("keydown",handleActivity),this.on("keyup",handleActivity),this.setInterval((function(){if(!this.userActivity_)return;this.userActivity_=!1,this.userActive(!0),this.clearTimeout(inactivityTimeout);const timeout=this.options_.inactivityTimeout;timeout<=0||(inactivityTimeout=this.setTimeout((function(){this.userActivity_||this.userActive(!1)}),timeout))}),250)}playbackRate(rate){if(void 0===rate)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",rate)}defaultPlaybackRate(rate){return void 0!==rate?this.techCall_("setDefaultPlaybackRate",rate):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1}isAudio(bool){if(void 0===bool)return!!this.isAudio_;this.isAudio_=!!bool}enableAudioOnlyUI_(){this.addClass("vjs-audio-only-mode");const playerChildren=this.children(),controlBar=this.getChild("ControlBar"),controlBarHeight=controlBar&&controlBar.currentHeight();playerChildren.forEach((child=>{child!==controlBar&&child.el_&&!child.hasClass("vjs-hidden")&&(child.hide(),this.audioOnlyCache_.hiddenChildren.push(child))})),this.audioOnlyCache_.playerHeight=this.currentHeight(),this.height(controlBarHeight),this.trigger("audioonlymodechange")}disableAudioOnlyUI_(){this.removeClass("vjs-audio-only-mode"),this.audioOnlyCache_.hiddenChildren.forEach((child=>child.show())),this.height(this.audioOnlyCache_.playerHeight),this.trigger("audioonlymodechange")}audioOnlyMode(value){if("boolean"!=typeof value||value===this.audioOnlyMode_)return this.audioOnlyMode_;if(this.audioOnlyMode_=value,value){const exitPromises=[];return this.isInPictureInPicture()&&exitPromises.push(this.exitPictureInPicture()),this.isFullscreen()&&exitPromises.push(this.exitFullscreen()),this.audioPosterMode()&&exitPromises.push(this.audioPosterMode(!1)),Promise.all(exitPromises).then((()=>this.enableAudioOnlyUI_()))}return Promise.resolve().then((()=>this.disableAudioOnlyUI_()))}enablePosterModeUI_(){(this.tech_&&this.tech_).hide(),this.addClass("vjs-audio-poster-mode"),this.trigger("audiopostermodechange")}disablePosterModeUI_(){(this.tech_&&this.tech_).show(),this.removeClass("vjs-audio-poster-mode"),this.trigger("audiopostermodechange")}audioPosterMode(value){if("boolean"!=typeof value||value===this.audioPosterMode_)return this.audioPosterMode_;if(this.audioPosterMode_=value,value){if(this.audioOnlyMode()){return this.audioOnlyMode(!1).then((()=>{this.enablePosterModeUI_()}))}return Promise.resolve().then((()=>{this.enablePosterModeUI_()}))}return Promise.resolve().then((()=>{this.disablePosterModeUI_()}))}addTextTrack(kind,label,language){if(this.tech_)return this.tech_.addTextTrack(kind,label,language)}addRemoteTextTrack(options,manualCleanup){if(this.tech_)return this.tech_.addRemoteTextTrack(options,manualCleanup)}removeRemoteTextTrack(){let obj=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{track:track}=obj;if(track||(track=obj),this.tech_)return this.tech_.removeRemoteTextTrack(track)}getVideoPlaybackQuality(){return this.techGet_("getVideoPlaybackQuality")}videoWidth(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0}videoHeight(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0}language(code){if(void 0===code)return this.language_;this.language_!==String(code).toLowerCase()&&(this.language_=String(code).toLowerCase(),isEvented(this)&&this.trigger("languagechange"))}languages(){return merge$2(Player.prototype.options_.languages,this.languages_)}toJSON(){const options=merge$2(this.options_),tracks=options.tracks;options.tracks=[];for(let i=0;i{this.removeChild(modal)})),modal.open(),modal}updateCurrentBreakpoint_(){if(!this.responsive())return;const currentBreakpoint=this.currentBreakpoint(),currentWidth=this.currentWidth();for(let i=0;ithis.addRemoteTextTrack(tt,!1))),this.titleBar&&this.titleBar.update({title:title,description:description||artist||""}),this.ready(ready)}getMedia(){if(!this.cache_.media){const poster=this.poster(),media={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),(tt=>({kind:tt.kind,label:tt.label,language:tt.language,src:tt.src})))};return poster&&(media.poster=poster,media.artwork=[{src:media.poster,type:getMimetype(media.poster)}]),media}return merge$2(this.cache_.media)}static getTagSettings(tag){const baseOptions={sources:[],tracks:[]},tagOptions=getAttributes(tag),dataSetup=tagOptions["data-setup"];if(hasClass(tag,"vjs-fill")&&(tagOptions.fill=!0),hasClass(tag,"vjs-fluid")&&(tagOptions.fluid=!0),null!==dataSetup){const[err,data]=tuple(dataSetup||"{}");err&&log$1.error(err),Object.assign(tagOptions,data)}if(Object.assign(baseOptions,tagOptions),tag.hasChildNodes()){const children=tag.childNodes;for(let i=0,j=children.length;i"number"==typeof rate))&&(this.cache_.playbackRates=newRates,this.trigger("playbackrateschange"))}}ALL.names.forEach((function(name){const props=ALL[name];Player.prototype[props.getterName]=function(){return this.tech_?this.tech_[props.getterName]():(this[props.privateName]=this[props.privateName]||new props.ListClass,this[props.privateName])}})),Player.prototype.crossorigin=Player.prototype.crossOrigin,Player.players={};const navigator=window.navigator;Player.prototype.options_={techOrder:Tech.defaultTechOrder_,html5:{},enableSourceset:!0,inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","titleBar","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:navigator&&(navigator.languages&&navigator.languages[0]||navigator.userLanguage||navigator.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",normalizeAutoplay:!1,fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1,audioOnlyMode:!1,audioPosterMode:!1},["ended","seeking","seekable","networkState","readyState"].forEach((function(fn){Player.prototype[fn]=function(){return this.techGet_(fn)}})),TECH_EVENTS_RETRIGGER.forEach((function(event){Player.prototype["handleTech".concat(toTitleCase$1(event),"_")]=function(){return this.trigger(event)}})),Component$1.registerComponent("Player",Player);const pluginStorage={},pluginExists=name=>pluginStorage.hasOwnProperty(name),getPlugin=name=>pluginExists(name)?pluginStorage[name]:void 0,markPluginAsActive=(player,name)=>{player.activePlugins_=player.activePlugins_||{},player.activePlugins_[name]=!0},triggerSetupEvent=(player,hash,before)=>{const eventName=(before?"before":"")+"pluginsetup";player.trigger(eventName,hash),player.trigger(eventName+":"+hash.name,hash)},createPluginFactory=(name,PluginSubClass)=>(PluginSubClass.prototype.name=name,function(){triggerSetupEvent(this,{name:name,plugin:PluginSubClass,instance:null},!0);for(var _len21=arguments.length,args=new Array(_len21),_key21=0;_key21<_len21;_key21++)args[_key21]=arguments[_key21];const instance=new PluginSubClass(...[this,...args]);return this[name]=()=>instance,triggerSetupEvent(this,instance.getEventHash()),instance});class Plugin{constructor(player){if(this.constructor===Plugin)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=player,this.log||(this.log=this.player.log.createLogger(this.name)),evented(this),delete this.trigger,stateful(this,this.constructor.defaultState),markPluginAsActive(player,this.name),this.dispose=this.dispose.bind(this),player.on("dispose",this.dispose)}version(){return this.constructor.VERSION}getEventHash(){let hash=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return hash.name=this.name,hash.plugin=this.constructor,hash.instance=this,hash}trigger(event){let hash=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return trigger(this.eventBusEl_,event,this.getEventHash(hash))}handleStateChanged(e){}dispose(){const{name:name,player:player}=this;this.trigger("dispose"),this.off(),player.off("dispose",this.dispose),player.activePlugins_[name]=!1,this.player=this.state=null,player[name]=createPluginFactory(name,pluginStorage[name])}static isBasic(plugin){const p="string"==typeof plugin?getPlugin(plugin):plugin;return"function"==typeof p&&!Plugin.prototype.isPrototypeOf(p.prototype)}static registerPlugin(name,plugin){if("string"!=typeof name)throw new Error('Illegal plugin name, "'.concat(name,'", must be a string, was ').concat(typeof name,"."));if(pluginExists(name))log$1.warn('A plugin named "'.concat(name,'" already exists. You may want to avoid re-registering plugins!'));else if(Player.prototype.hasOwnProperty(name))throw new Error('Illegal plugin name, "'.concat(name,'", cannot share a name with an existing player method!'));if("function"!=typeof plugin)throw new Error('Illegal plugin for "'.concat(name,'", must be a function, was ').concat(typeof plugin,"."));return pluginStorage[name]=plugin,"plugin"!==name&&(Plugin.isBasic(plugin)?Player.prototype[name]=function(name,plugin){const basicPluginWrapper=function(){triggerSetupEvent(this,{name:name,plugin:plugin,instance:null},!0);const instance=plugin.apply(this,arguments);return markPluginAsActive(this,name),triggerSetupEvent(this,{name:name,plugin:plugin,instance:instance}),instance};return Object.keys(plugin).forEach((function(prop){basicPluginWrapper[prop]=plugin[prop]})),basicPluginWrapper}(name,plugin):Player.prototype[name]=createPluginFactory(name,plugin)),plugin}static deregisterPlugin(name){if("plugin"===name)throw new Error("Cannot de-register base plugin.");pluginExists(name)&&(delete pluginStorage[name],delete Player.prototype[name])}static getPlugins(){let result;return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:Object.keys(pluginStorage)).forEach((name=>{const plugin=getPlugin(name);plugin&&(result=result||{},result[name]=plugin)})),result}static getPluginVersion(name){const plugin=getPlugin(name);return plugin&&plugin.VERSION||""}}function deprecateForMajor(major,oldName,newName,fn){return function(message,fn){let warned=!1;return function(){warned||log$1.warn(message),warned=!0;for(var _len22=arguments.length,args=new Array(_len22),_key22=0;_key22<_len22;_key22++)args[_key22]=arguments[_key22];return fn.apply(this,args)}}("".concat(oldName," is deprecated and will be removed in ").concat(major,".0; please use ").concat(newName," instead."),fn)}Plugin.getPlugin=getPlugin,Plugin.BASE_PLUGIN_NAME="plugin",Plugin.registerPlugin("plugin",Plugin),Player.prototype.usingPlugin=function(name){return!!this.activePlugins_&&!0===this.activePlugins_[name]},Player.prototype.hasPlugin=function(name){return!!pluginExists(name)};const normalizeId=id=>0===id.indexOf("#")?id.slice(1):id;function videojs(id,options,ready){let player=videojs.getPlayer(id);if(player)return options&&log$1.warn('Player "'.concat(id,'" is already initialised. Options will not be applied.')),ready&&player.ready(ready),player;const el="string"==typeof id?$("#"+normalizeId(id)):id;if(!isEl(el))throw new TypeError("The element or ID supplied is not valid. (videojs)");el.ownerDocument.defaultView&&el.ownerDocument.body.contains(el)||log$1.warn("The element supplied is not included in the DOM"),!0===(options=options||{}).restoreEl&&(options.restoreEl=(el.parentNode&&el.parentNode.hasAttribute("data-vjs-player")?el.parentNode:el).cloneNode(!0)),hooks("beforesetup").forEach((hookFunction=>{const opts=hookFunction(el,merge$2(options));isObject$1(opts)&&!Array.isArray(opts)?options=merge$2(options,opts):log$1.error("please return an object in beforesetup hooks")}));const PlayerComponent=Component$1.getComponent("Player");return player=new PlayerComponent(el,options,ready),hooks("setup").forEach((hookFunction=>hookFunction(player))),player}if(videojs.hooks_=hooks_,videojs.hooks=hooks,videojs.hook=function(type,fn){hooks(type,fn)},videojs.hookOnce=function(type,fn){hooks(type,[].concat(fn).map((original=>{const wrapper=function(){return removeHook(type,wrapper),original(...arguments)};return wrapper})))},videojs.removeHook=removeHook,!0!==window.VIDEOJS_NO_DYNAMIC_STYLE&&isReal()){let style=$(".vjs-styles-defaults");if(!style){style=createStyleElement("vjs-styles-defaults");const head=$("head");head&&head.insertBefore(style,head.firstChild),setTextContent(style,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid:not(.vjs-audio-only-mode) {\n padding-top: 56.25%\n }\n ")}}autoSetupTimeout(1,videojs),videojs.VERSION="8.3.0",videojs.options=Player.prototype.options_,videojs.getPlayers=()=>Player.players,videojs.getPlayer=id=>{const players=Player.players;let tag;if("string"==typeof id){const nId=normalizeId(id),player=players[nId];if(player)return player;tag=$("#"+nId)}else tag=id;if(isEl(tag)){const{player:player,playerId:playerId}=tag;if(player||players[playerId])return player||players[playerId]}},videojs.getAllPlayers=()=>Object.keys(Player.players).map((k=>Player.players[k])).filter(Boolean),videojs.players=Player.players,videojs.getComponent=Component$1.getComponent,videojs.registerComponent=(name,comp)=>{Tech.isTech(comp)&&log$1.warn("The ".concat(name," tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)")),Component$1.registerComponent.call(Component$1,name,comp)},videojs.getTech=Tech.getTech,videojs.registerTech=Tech.registerTech,videojs.use=function(type,middleware){middlewares[type]=middlewares[type]||[],middlewares[type].push(middleware)},Object.defineProperty(videojs,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(videojs.middleware,"TERMINATOR",{value:TERMINATOR,writeable:!1,enumerable:!0}),videojs.browser=browser,videojs.obj=Obj,videojs.mergeOptions=deprecateForMajor(9,"videojs.mergeOptions","videojs.obj.merge",merge$2),videojs.defineLazyProperty=deprecateForMajor(9,"videojs.defineLazyProperty","videojs.obj.defineLazyProperty",defineLazyProperty),videojs.bind=deprecateForMajor(9,"videojs.bind","native Function.prototype.bind",bind_),videojs.registerPlugin=Plugin.registerPlugin,videojs.deregisterPlugin=Plugin.deregisterPlugin,videojs.plugin=(name,plugin)=>(log$1.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),Plugin.registerPlugin(name,plugin)),videojs.getPlugins=Plugin.getPlugins,videojs.getPlugin=Plugin.getPlugin,videojs.getPluginVersion=Plugin.getPluginVersion,videojs.addLanguage=function(code,data){return code=(""+code).toLowerCase(),videojs.options.languages=merge$2(videojs.options.languages,{[code]:data}),videojs.options.languages[code]},videojs.log=log$1,videojs.createLogger=createLogger,videojs.time=Time,videojs.createTimeRange=deprecateForMajor(9,"videojs.createTimeRange","videojs.time.createTimeRanges",createTimeRanges$1),videojs.createTimeRanges=deprecateForMajor(9,"videojs.createTimeRanges","videojs.time.createTimeRanges",createTimeRanges$1),videojs.formatTime=deprecateForMajor(9,"videojs.formatTime","videojs.time.formatTime",formatTime),videojs.setFormatTime=deprecateForMajor(9,"videojs.setFormatTime","videojs.time.setFormatTime",setFormatTime),videojs.resetFormatTime=deprecateForMajor(9,"videojs.resetFormatTime","videojs.time.resetFormatTime",resetFormatTime),videojs.parseUrl=deprecateForMajor(9,"videojs.parseUrl","videojs.url.parseUrl",parseUrl),videojs.isCrossOrigin=deprecateForMajor(9,"videojs.isCrossOrigin","videojs.url.isCrossOrigin",isCrossOrigin),videojs.EventTarget=EventTarget$2,videojs.any=any,videojs.on=on,videojs.one=one,videojs.off=off,videojs.trigger=trigger,videojs.xhr=lib,videojs.TextTrack=TextTrack,videojs.AudioTrack=AudioTrack,videojs.VideoTrack=VideoTrack,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach((k=>{videojs[k]=function(){return log$1.warn("videojs.".concat(k,"() is deprecated; use videojs.dom.").concat(k,"() instead")),Dom[k].apply(null,arguments)}})),videojs.computedStyle=deprecateForMajor(9,"videojs.computedStyle","videojs.dom.computedStyle",computedStyle),videojs.dom=Dom,videojs.fn=Fn,videojs.num=Num,videojs.str=Str,videojs.url=Url,createCommonjsModule((function(module,exports){ -/*! @name videojs-contrib-quality-levels @version 3.0.0 @license Apache-2.0 */ -module.exports=function(videojs){function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var videojs__default=_interopDefaultLegacy(videojs);class QualityLevel{constructor(representation){let level=this;return level.id=representation.id,level.label=level.id,level.width=representation.width,level.height=representation.height,level.bitrate=representation.bandwidth,level.frameRate=representation.frameRate,level.enabled_=representation.enabled,Object.defineProperty(level,"enabled",{get:()=>level.enabled_(),set(enable){level.enabled_(enable)}}),level}}class QualityLevelList extends videojs__default.default.EventTarget{constructor(){super();let list=this;return list.levels_=[],list.selectedIndex_=-1,Object.defineProperty(list,"selectedIndex",{get:()=>list.selectedIndex_}),Object.defineProperty(list,"length",{get:()=>list.levels_.length}),list}addQualityLevel(representation){let qualityLevel=this.getQualityLevelById(representation.id);if(qualityLevel)return qualityLevel;const index=this.levels_.length;return qualityLevel=new QualityLevel(representation),""+index in this||Object.defineProperty(this,index,{get(){return this.levels_[index]}}),this.levels_.push(qualityLevel),this.trigger({qualityLevel:qualityLevel,type:"addqualitylevel"}),qualityLevel}removeQualityLevel(qualityLevel){let removed=null;for(let i=0,l=this.length;ii&&this.selectedIndex_--;break}return removed&&this.trigger({qualityLevel:qualityLevel,type:"removequalitylevel"}),removed}getQualityLevelById(id){for(let i=0,l=this.length;iqualityLevelList,player.qualityLevels.VERSION=version,qualityLevelList},qualityLevels=function(options){return initPlugin(this,videojs__default.default.mergeOptions({},options))};return registerPlugin("qualityLevels",qualityLevels),qualityLevels.VERSION=version,qualityLevels}(videojs)}));var urlToolkit=createCommonjsModule((function(module,exports){var URL_REGEX,FIRST_SEGMENT_REGEX,SLASH_DOT_REGEX,SLASH_DOT_DOT_REGEX,URLToolkit;URL_REGEX=/^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/,FIRST_SEGMENT_REGEX=/^(?=([^\/?#]*))\1([^]*)$/,SLASH_DOT_REGEX=/(?:\/|^)\.(?=\/)/g,SLASH_DOT_DOT_REGEX=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,URLToolkit={buildAbsoluteURL:function(baseURL,relativeURL,opts){if(opts=opts||{},baseURL=baseURL.trim(),!(relativeURL=relativeURL.trim())){if(!opts.alwaysNormalize)return baseURL;var basePartsForNormalise=URLToolkit.parseURL(baseURL);if(!basePartsForNormalise)throw new Error("Error trying to parse base URL.");return basePartsForNormalise.path=URLToolkit.normalizePath(basePartsForNormalise.path),URLToolkit.buildURLFromParts(basePartsForNormalise)}var relativeParts=URLToolkit.parseURL(relativeURL);if(!relativeParts)throw new Error("Error trying to parse relative URL.");if(relativeParts.scheme)return opts.alwaysNormalize?(relativeParts.path=URLToolkit.normalizePath(relativeParts.path),URLToolkit.buildURLFromParts(relativeParts)):relativeURL;var baseParts=URLToolkit.parseURL(baseURL);if(!baseParts)throw new Error("Error trying to parse base URL.");if(!baseParts.netLoc&&baseParts.path&&"/"!==baseParts.path[0]){var pathParts=FIRST_SEGMENT_REGEX.exec(baseParts.path);baseParts.netLoc=pathParts[1],baseParts.path=pathParts[2]}baseParts.netLoc&&!baseParts.path&&(baseParts.path="/");var builtParts={scheme:baseParts.scheme,netLoc:relativeParts.netLoc,path:null,params:relativeParts.params,query:relativeParts.query,fragment:relativeParts.fragment};if(!relativeParts.netLoc&&(builtParts.netLoc=baseParts.netLoc,"/"!==relativeParts.path[0]))if(relativeParts.path){var baseURLPath=baseParts.path,newPath=baseURLPath.substring(0,baseURLPath.lastIndexOf("/")+1)+relativeParts.path;builtParts.path=URLToolkit.normalizePath(newPath)}else builtParts.path=baseParts.path,relativeParts.params||(builtParts.params=baseParts.params,relativeParts.query||(builtParts.query=baseParts.query));return null===builtParts.path&&(builtParts.path=opts.alwaysNormalize?URLToolkit.normalizePath(relativeParts.path):relativeParts.path),URLToolkit.buildURLFromParts(builtParts)},parseURL:function(url){var parts=URL_REGEX.exec(url);return parts?{scheme:parts[1]||"",netLoc:parts[2]||"",path:parts[3]||"",params:parts[4]||"",query:parts[5]||"",fragment:parts[6]||""}:null},normalizePath:function(path){for(path=path.split("").reverse().join("").replace(SLASH_DOT_REGEX,"");path.length!==(path=path.replace(SLASH_DOT_DOT_REGEX,"")).length;);return path.split("").reverse().join("")},buildURLFromParts:function(parts){return parts.scheme+parts.netLoc+parts.path+parts.params+parts.query+parts.fragment}},module.exports=URLToolkit})),Stream=function(){function Stream(){this.listeners={}}var _proto=Stream.prototype;return _proto.on=function(type,listener){this.listeners[type]||(this.listeners[type]=[]),this.listeners[type].push(listener)},_proto.off=function(type,listener){if(!this.listeners[type])return!1;var index=this.listeners[type].indexOf(listener);return this.listeners[type]=this.listeners[type].slice(0),this.listeners[type].splice(index,1),index>-1},_proto.trigger=function(type){var callbacks=this.listeners[type];if(callbacks)if(2===arguments.length)for(var length=callbacks.length,i=0;i-1;nextNewline=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,nextNewline)),this.buffer=this.buffer.substring(nextNewline+1)}}const TAB=String.fromCharCode(9),parseByterange=function(byterangeString){const match=/([0-9.]*)?@?([0-9.]*)?/.exec(byterangeString||""),result={};return match[1]&&(result.length=parseInt(match[1],10)),match[2]&&(result.offset=parseInt(match[2],10)),result},parseAttributes$1=function(attributes){const result={};if(!attributes)return result;const attrs=attributes.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))'));let attr,i=attrs.length;for(;i--;)""!==attrs[i]&&(attr=/([^=]*)=(.*)/.exec(attrs[i]).slice(1),attr[0]=attr[0].replace(/^\s+|\s+$/g,""),attr[1]=attr[1].replace(/^\s+|\s+$/g,""),attr[1]=attr[1].replace(/^['"](.*)['"]$/g,"$1"),result[attr[0]]=attr[1]);return result};class ParseStream extends Stream{constructor(){super(),this.customParsers=[],this.tagMappers=[]}push(line){let match,event;if(0===(line=line.trim()).length)return;if("#"!==line[0])return void this.trigger("data",{type:"uri",uri:line});this.tagMappers.reduce(((acc,mapper)=>{const mappedLine=mapper(line);return mappedLine===line?acc:acc.concat([mappedLine])}),[line]).forEach((newLine=>{for(let i=0;iline),this.customParsers.push((line=>{if(expression.exec(line))return this.trigger("data",{type:"custom",data:dataParser(line),customType:customType,segment:segment}),!0}))}addTagMapper(_ref9){let{expression:expression,map:map}=_ref9;this.tagMappers.push((line=>expression.test(line)?map(line):line))}}const camelCaseKeys=function(attributes){const result={};return Object.keys(attributes).forEach((function(key){var str;result[(str=key,str.toLowerCase().replace(/-(\w)/g,(a=>a[1].toUpperCase())))]=attributes[key]})),result},setHoldBack=function(manifest){const{serverControl:serverControl,targetDuration:targetDuration,partTargetDuration:partTargetDuration}=manifest;if(!serverControl)return;const tag="#EXT-X-SERVER-CONTROL",hb="holdBack",phb="partHoldBack",minTargetDuration=targetDuration&&3*targetDuration,minPartDuration=partTargetDuration&&2*partTargetDuration;targetDuration&&!serverControl.hasOwnProperty(hb)&&(serverControl[hb]=minTargetDuration,this.trigger("info",{message:"".concat(tag," defaulting HOLD-BACK to targetDuration * 3 (").concat(minTargetDuration,").")})),minTargetDuration&&serverControl[hb]{currentUri.uri||!currentUri.parts&&!currentUri.preloadHints||(!currentUri.map&¤tMap&&(currentUri.map=currentMap),!currentUri.key&&key&&(currentUri.key=key),currentUri.timeline||"number"!=typeof currentTimeline||(currentUri.timeline=currentTimeline),this.manifest.preloadSegment=currentUri)})),this.parseStream.on("data",(function(entry){let mediaGroup,rendition;({tag(){({version(){entry.version&&(this.manifest.version=entry.version)},"allow-cache"(){this.manifest.allowCache=entry.allowed,"allowed"in entry||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange(){const byterange={};"length"in entry&&(currentUri.byterange=byterange,byterange.length=entry.length,"offset"in entry||(entry.offset=lastByterangeEnd)),"offset"in entry&&(currentUri.byterange=byterange,byterange.offset=entry.offset),lastByterangeEnd=byterange.offset+byterange.length},endlist(){this.manifest.endList=!0},inf(){"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"})),entry.duration>0&&(currentUri.duration=entry.duration),0===entry.duration&&(currentUri.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=uris},key(){if(entry.attributes)if("NONE"!==entry.attributes.METHOD)if(entry.attributes.URI){if("com.apple.streamingkeydelivery"===entry.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:entry.attributes});if("com.microsoft.playready"===entry.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.microsoft.playready"]={uri:entry.attributes.URI});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===entry.attributes.KEYFORMAT){return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(entry.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===entry.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==entry.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):entry.attributes.KEYID&&"0x"===entry.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:entry.attributes.KEYFORMAT,keyId:entry.attributes.KEYID.substring(2)},pssh:decodeB64ToUint8Array$1(entry.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}))}entry.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),key={method:entry.attributes.METHOD||"AES-128",uri:entry.attributes.URI},void 0!==entry.attributes.IV&&(key.iv=entry.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else key=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence"(){isFinite(entry.number)?this.manifest.mediaSequence=entry.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+entry.number})},"discontinuity-sequence"(){isFinite(entry.number)?(this.manifest.discontinuitySequence=entry.number,currentTimeline=entry.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+entry.number})},"playlist-type"(){/VOD|EVENT/.test(entry.playlistType)?this.manifest.playlistType=entry.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+entry.playlist})},map(){currentMap={},entry.uri&&(currentMap.uri=entry.uri),entry.byterange&&(currentMap.byterange=entry.byterange),key&&(currentMap.key=key)},"stream-inf"(){this.manifest.playlists=uris,this.manifest.mediaGroups=this.manifest.mediaGroups||defaultMediaGroups,entry.attributes?(currentUri.attributes||(currentUri.attributes={}),_extends$1(currentUri.attributes,entry.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||defaultMediaGroups,!(entry.attributes&&entry.attributes.TYPE&&entry.attributes["GROUP-ID"]&&entry.attributes.NAME))return void this.trigger("warn",{message:"ignoring incomplete or missing media group"});const mediaGroupType=this.manifest.mediaGroups[entry.attributes.TYPE];mediaGroupType[entry.attributes["GROUP-ID"]]=mediaGroupType[entry.attributes["GROUP-ID"]]||{},mediaGroup=mediaGroupType[entry.attributes["GROUP-ID"]],rendition={default:/yes/i.test(entry.attributes.DEFAULT)},rendition.default?rendition.autoselect=!0:rendition.autoselect=/yes/i.test(entry.attributes.AUTOSELECT),entry.attributes.LANGUAGE&&(rendition.language=entry.attributes.LANGUAGE),entry.attributes.URI&&(rendition.uri=entry.attributes.URI),entry.attributes["INSTREAM-ID"]&&(rendition.instreamId=entry.attributes["INSTREAM-ID"]),entry.attributes.CHARACTERISTICS&&(rendition.characteristics=entry.attributes.CHARACTERISTICS),entry.attributes.FORCED&&(rendition.forced=/yes/i.test(entry.attributes.FORCED)),mediaGroup[entry.attributes.NAME]=rendition},discontinuity(){currentTimeline+=1,currentUri.discontinuity=!0,this.manifest.discontinuityStarts.push(uris.length)},"program-date-time"(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=entry.dateTimeString,this.manifest.dateTimeObject=entry.dateTimeObject),currentUri.dateTimeString=entry.dateTimeString,currentUri.dateTimeObject=entry.dateTimeObject},targetduration(){!isFinite(entry.duration)||entry.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+entry.duration}):(this.manifest.targetDuration=entry.duration,setHoldBack.call(this,this.manifest))},start(){entry.attributes&&!isNaN(entry.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:entry.attributes["TIME-OFFSET"],precise:entry.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out"(){currentUri.cueOut=entry.data},"cue-out-cont"(){currentUri.cueOutCont=entry.data},"cue-in"(){currentUri.cueIn=entry.data},skip(){this.manifest.skip=camelCaseKeys(entry.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",entry.attributes,["SKIPPED-SEGMENTS"])},part(){hasParts=!0;const segmentIndex=this.manifest.segments.length,part=camelCaseKeys(entry.attributes);currentUri.parts=currentUri.parts||[],currentUri.parts.push(part),part.byterange&&(part.byterange.hasOwnProperty("offset")||(part.byterange.offset=lastPartByterangeEnd),lastPartByterangeEnd=part.byterange.offset+part.byterange.length);const partIndex=currentUri.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #".concat(partIndex," for segment #").concat(segmentIndex),entry.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach(((r,i)=>{r.hasOwnProperty("lastPart")||this.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #".concat(i," lacks required attribute(s): LAST-PART")})}))},"server-control"(){const attrs=this.manifest.serverControl=camelCaseKeys(entry.attributes);attrs.hasOwnProperty("canBlockReload")||(attrs.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),setHoldBack.call(this,this.manifest),attrs.canSkipDateranges&&!attrs.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"})},"preload-hint"(){const segmentIndex=this.manifest.segments.length,hint=camelCaseKeys(entry.attributes),isPart=hint.type&&"PART"===hint.type;currentUri.preloadHints=currentUri.preloadHints||[],currentUri.preloadHints.push(hint),hint.byterange&&(hint.byterange.hasOwnProperty("offset")||(hint.byterange.offset=isPart?lastPartByterangeEnd:0,isPart&&(lastPartByterangeEnd=hint.byterange.offset+hint.byterange.length)));const index=currentUri.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #".concat(index," for segment #").concat(segmentIndex),entry.attributes,["TYPE","URI"]),hint.type)for(let i=0;imax&&(number-=max,number-=max,number-=BigInt(2))}return Number(number)},numberToBytes=function(number,_temp2){var _ref2$le=(void 0===_temp2?{}:_temp2).le,le=void 0!==_ref2$le&&_ref2$le;("bigint"!=typeof number&&"number"!=typeof number||"number"==typeof number&&number!=number)&&(number=0);for(var byteCount=function(x){return Math.ceil(function(x){return x.toString(2).length}(x)/8)}(number=BigInt(number)),bytes=new Uint8Array(new ArrayBuffer(byteCount)),i=0;i=b.length&&fn.call(b,(function(bByte,i){return bByte===(mask[i]?mask[i]&a[offset+i]:a[offset+i])}))},resolveUrl$1=function(baseUrl,relativeUrl){if(/^[a-z]+:/i.test(relativeUrl))return relativeUrl;/^data:/.test(baseUrl)&&(baseUrl=window.location&&window.location.href||"");var nativeURL="function"==typeof window.URL,protocolLess=/^\/\//.test(baseUrl),removeLocation=!window.location&&!/\/\//i.test(baseUrl);if(nativeURL?baseUrl=new window.URL(baseUrl,window.location||"http://example.com"):/\/\//i.test(baseUrl)||(baseUrl=urlToolkit.buildAbsoluteURL(window.location&&window.location.href||"",baseUrl)),nativeURL){var newUrl=new URL(relativeUrl,baseUrl);return removeLocation?newUrl.href.slice("http://example.com".length):protocolLess?newUrl.href.slice(newUrl.protocol.length):newUrl.href}return urlToolkit.buildAbsoluteURL(baseUrl,relativeUrl)};function decodeB64ToUint8Array(b64Text){for(var s,decodedString=(s=b64Text,window.atob?window.atob(s):Buffer.from(s,"base64").toString("binary")),array=new Uint8Array(decodedString.length),i=0;i=0))throw new DOMException(NOT_FOUND_ERR,new Error(el.tagName+"@"+attr));for(var lastIndex=list.length-1;i"==c&&">")||"&"==c&&"&"||'"'==c&&"""||"&#"+c.charCodeAt()+";"}function _visitNode(node,callback){if(callback(node))return!0;if(node=node.firstChild)do{if(_visitNode(node,callback))return!0}while(node=node.nextSibling)}function Document(){this.ownerDocument=this}function _onRemoveAttribute(doc,el,newAttr,remove){doc&&doc._inc++,newAttr.namespaceURI===NAMESPACE$2.XMLNS&&delete el._nsMap[newAttr.prefix?newAttr.localName:""]}function _onUpdateChild(doc,el,newChild){if(doc&&doc._inc){doc._inc++;var cs=el.childNodes;if(newChild)cs[cs.length++]=newChild;else{for(var child=el.firstChild,i=0;child;)cs[i++]=child,child=child.nextSibling;cs.length=i,delete cs[cs.length]}}}function _removeChild(parentNode,child){var previous=child.previousSibling,next=child.nextSibling;return previous?previous.nextSibling=next:parentNode.firstChild=next,next?next.previousSibling=previous:parentNode.lastChild=previous,child.parentNode=null,child.previousSibling=null,child.nextSibling=null,_onUpdateChild(parentNode.ownerDocument,parentNode),child}function isDocTypeNode(node){return node&&node.nodeType===Node.DOCUMENT_TYPE_NODE}function isElementNode(node){return node&&node.nodeType===Node.ELEMENT_NODE}function isTextNode(node){return node&&node.nodeType===Node.TEXT_NODE}function isElementInsertionPossible(doc,child){var parentChildNodes=doc.childNodes||[];if(find(parentChildNodes,isElementNode)||isDocTypeNode(child))return!1;var docTypeNode=find(parentChildNodes,isDocTypeNode);return!(child&&docTypeNode&&parentChildNodes.indexOf(docTypeNode)>parentChildNodes.indexOf(child))}function isElementReplacementPossible(doc,child){var parentChildNodes=doc.childNodes||[];if(find(parentChildNodes,(function(node){return isElementNode(node)&&node!==child})))return!1;var docTypeNode=find(parentChildNodes,isDocTypeNode);return!(child&&docTypeNode&&parentChildNodes.indexOf(docTypeNode)>parentChildNodes.indexOf(child))}function assertPreInsertionValidity1to5(parent,node,child){if(!function(node){return node&&(node.nodeType===Node.DOCUMENT_NODE||node.nodeType===Node.DOCUMENT_FRAGMENT_NODE||node.nodeType===Node.ELEMENT_NODE)}(parent))throw new DOMException(HIERARCHY_REQUEST_ERR,"Unexpected parent node type "+parent.nodeType);if(child&&child.parentNode!==parent)throw new DOMException(NOT_FOUND_ERR,"child not in parent");if(!function(node){return node&&(isElementNode(node)||isTextNode(node)||isDocTypeNode(node)||node.nodeType===Node.DOCUMENT_FRAGMENT_NODE||node.nodeType===Node.COMMENT_NODE||node.nodeType===Node.PROCESSING_INSTRUCTION_NODE)}(node)||isDocTypeNode(node)&&parent.nodeType!==Node.DOCUMENT_NODE)throw new DOMException(HIERARCHY_REQUEST_ERR,"Unexpected node type "+node.nodeType+" for parent node type "+parent.nodeType)}function assertPreInsertionValidityInDocument(parent,node,child){var parentChildNodes=parent.childNodes||[],nodeChildNodes=node.childNodes||[];if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var nodeChildElements=nodeChildNodes.filter(isElementNode);if(nodeChildElements.length>1||find(nodeChildNodes,isTextNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"More than one element or text in fragment");if(1===nodeChildElements.length&&!isElementInsertionPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Element in fragment can not be inserted before doctype")}if(isElementNode(node)&&!isElementInsertionPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one element can be added and only after doctype");if(isDocTypeNode(node)){if(find(parentChildNodes,isDocTypeNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one doctype is allowed");var parentElementChild=find(parentChildNodes,isElementNode);if(child&&parentChildNodes.indexOf(parentElementChild)1||find(nodeChildNodes,isTextNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"More than one element or text in fragment");if(1===nodeChildElements.length&&!isElementReplacementPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Element in fragment can not be inserted before doctype")}if(isElementNode(node)&&!isElementReplacementPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one element can be added and only after doctype");if(isDocTypeNode(node)){function hasDoctypeChildThatIsNotChild(node){return isDocTypeNode(node)&&node!==child}if(find(parentChildNodes,hasDoctypeChildThatIsNotChild))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one doctype is allowed");var parentElementChild=find(parentChildNodes,isElementNode);if(child&&parentChildNodes.indexOf(parentElementChild)=0;nsi--){if(""===(namespace=visibleNamespaces[nsi]).prefix&&namespace.namespace===node.namespaceURI){defaultNS=namespace.namespace;break}}if(defaultNS!==node.namespaceURI)for(nsi=visibleNamespaces.length-1;nsi>=0;nsi--){var namespace;if((namespace=visibleNamespaces[nsi]).namespace===node.namespaceURI){namespace.prefix&&(prefixedNodeName=namespace.prefix+":"+nodeName);break}}}buf.push("<",prefixedNodeName);for(var i=0;i"),isHTML&&/^script$/i.test(nodeName))for(;child;)child.data?buf.push(child.data):serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;else for(;child;)serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;buf.push("")}else buf.push("/>");return;case DOCUMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(child=node.firstChild;child;)serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;return;case ATTRIBUTE_NODE:return addSerializedAttribute(buf,node.name,node.value);case TEXT_NODE:return buf.push(node.data.replace(/[<&>]/g,_xmlEncoder));case CDATA_SECTION_NODE:return buf.push("");case COMMENT_NODE:return buf.push("\x3c!--",node.data,"--\x3e");case DOCUMENT_TYPE_NODE:var pubid=node.publicId,sysid=node.systemId;if(buf.push("");else if(sysid&&"."!=sysid)buf.push(" SYSTEM ",sysid,">");else{var sub=node.internalSubset;sub&&buf.push(" [",sub,"]"),buf.push(">")}return;case PROCESSING_INSTRUCTION_NODE:return buf.push("");case ENTITY_REFERENCE_NODE:return buf.push("&",node.nodeName,";");default:buf.push("??",node.nodeName)}}function importNode(doc,node,deep){var node2;switch(node.nodeType){case ELEMENT_NODE:(node2=node.cloneNode(!1)).ownerDocument=doc;case DOCUMENT_FRAGMENT_NODE:break;case ATTRIBUTE_NODE:deep=!0}if(node2||(node2=node.cloneNode(!1)),node2.ownerDocument=doc,node2.parentNode=null,deep)for(var child=node.firstChild;child;)node2.appendChild(importNode(doc,child,deep)),child=child.nextSibling;return node2}function cloneNode(doc,node,deep){var node2=new node.constructor;for(var n in node)if(Object.prototype.hasOwnProperty.call(node,n)){var v=node[n];"object"!=typeof v&&v!=node2[n]&&(node2[n]=v)}switch(node.childNodes&&(node2.childNodes=new NodeList),node2.ownerDocument=doc,node2.nodeType){case ELEMENT_NODE:var attrs=node.attributes,attrs2=node2.attributes=new NamedNodeMap,len=attrs.length;attrs2._ownerElement=node2;for(var i=0;i0},lookupPrefix:function(namespaceURI){for(var el=this;el;){var map=el._nsMap;if(map)for(var n in map)if(Object.prototype.hasOwnProperty.call(map,n)&&map[n]===namespaceURI)return n;el=el.nodeType==ATTRIBUTE_NODE?el.ownerDocument:el.parentNode}return null},lookupNamespaceURI:function(prefix){for(var el=this;el;){var map=el._nsMap;if(map&&Object.prototype.hasOwnProperty.call(map,prefix))return map[prefix];el=el.nodeType==ATTRIBUTE_NODE?el.ownerDocument:el.parentNode}return null},isDefaultNamespace:function(namespaceURI){return null==this.lookupPrefix(namespaceURI)}},copy(NodeType,Node),copy(NodeType,Node.prototype),Document.prototype={nodeName:"#document",nodeType:DOCUMENT_NODE,doctype:null,documentElement:null,_inc:1,insertBefore:function(newChild,refChild){if(newChild.nodeType==DOCUMENT_FRAGMENT_NODE){for(var child=newChild.firstChild;child;){var next=child.nextSibling;this.insertBefore(child,refChild),child=next}return newChild}return _insertBefore(this,newChild,refChild),newChild.ownerDocument=this,null===this.documentElement&&newChild.nodeType===ELEMENT_NODE&&(this.documentElement=newChild),newChild},removeChild:function(oldChild){return this.documentElement==oldChild&&(this.documentElement=null),_removeChild(this,oldChild)},replaceChild:function(newChild,oldChild){_insertBefore(this,newChild,oldChild,assertPreReplacementValidityInDocument),newChild.ownerDocument=this,oldChild&&this.removeChild(oldChild),isElementNode(newChild)&&(this.documentElement=newChild)},importNode:function(importedNode,deep){return importNode(this,importedNode,deep)},getElementById:function(id){var rtv=null;return _visitNode(this.documentElement,(function(node){if(node.nodeType==ELEMENT_NODE&&node.getAttribute("id")==id)return rtv=node,!0})),rtv},getElementsByClassName:function(classNames){var classNamesSet=toOrderedSet(classNames);return new LiveNodeList(this,(function(base){var ls=[];return classNamesSet.length>0&&_visitNode(base.documentElement,(function(node){if(node!==base&&node.nodeType===ELEMENT_NODE){var nodeClassNames=node.getAttribute("class");if(nodeClassNames){var matches=classNames===nodeClassNames;if(!matches){var nodeClassNamesSet=toOrderedSet(nodeClassNames);matches=classNamesSet.every((list=nodeClassNamesSet,function(element){return list&&-1!==list.indexOf(element)}))}matches&&ls.push(node)}}var list})),ls}))},createElement:function(tagName){var node=new Element;return node.ownerDocument=this,node.nodeName=tagName,node.tagName=tagName,node.localName=tagName,node.childNodes=new NodeList,(node.attributes=new NamedNodeMap)._ownerElement=node,node},createDocumentFragment:function(){var node=new DocumentFragment;return node.ownerDocument=this,node.childNodes=new NodeList,node},createTextNode:function(data){var node=new Text;return node.ownerDocument=this,node.appendData(data),node},createComment:function(data){var node=new Comment;return node.ownerDocument=this,node.appendData(data),node},createCDATASection:function(data){var node=new CDATASection;return node.ownerDocument=this,node.appendData(data),node},createProcessingInstruction:function(target,data){var node=new ProcessingInstruction;return node.ownerDocument=this,node.tagName=node.target=target,node.nodeValue=node.data=data,node},createAttribute:function(name){var node=new Attr;return node.ownerDocument=this,node.name=name,node.nodeName=name,node.localName=name,node.specified=!0,node},createEntityReference:function(name){var node=new EntityReference;return node.ownerDocument=this,node.nodeName=name,node},createElementNS:function(namespaceURI,qualifiedName){var node=new Element,pl=qualifiedName.split(":"),attrs=node.attributes=new NamedNodeMap;return node.childNodes=new NodeList,node.ownerDocument=this,node.nodeName=qualifiedName,node.tagName=qualifiedName,node.namespaceURI=namespaceURI,2==pl.length?(node.prefix=pl[0],node.localName=pl[1]):node.localName=qualifiedName,attrs._ownerElement=node,node},createAttributeNS:function(namespaceURI,qualifiedName){var node=new Attr,pl=qualifiedName.split(":");return node.ownerDocument=this,node.nodeName=qualifiedName,node.name=qualifiedName,node.namespaceURI=namespaceURI,node.specified=!0,2==pl.length?(node.prefix=pl[0],node.localName=pl[1]):node.localName=qualifiedName,node}},_extends(Document,Node),Element.prototype={nodeType:ELEMENT_NODE,hasAttribute:function(name){return null!=this.getAttributeNode(name)},getAttribute:function(name){var attr=this.getAttributeNode(name);return attr&&attr.value||""},getAttributeNode:function(name){return this.attributes.getNamedItem(name)},setAttribute:function(name,value){var attr=this.ownerDocument.createAttribute(name);attr.value=attr.nodeValue=""+value,this.setAttributeNode(attr)},removeAttribute:function(name){var attr=this.getAttributeNode(name);attr&&this.removeAttributeNode(attr)},appendChild:function(newChild){return newChild.nodeType===DOCUMENT_FRAGMENT_NODE?this.insertBefore(newChild,null):function(parentNode,newChild){return newChild.parentNode&&newChild.parentNode.removeChild(newChild),newChild.parentNode=parentNode,newChild.previousSibling=parentNode.lastChild,newChild.nextSibling=null,newChild.previousSibling?newChild.previousSibling.nextSibling=newChild:parentNode.firstChild=newChild,parentNode.lastChild=newChild,_onUpdateChild(parentNode.ownerDocument,parentNode,newChild),newChild}(this,newChild)},setAttributeNode:function(newAttr){return this.attributes.setNamedItem(newAttr)},setAttributeNodeNS:function(newAttr){return this.attributes.setNamedItemNS(newAttr)},removeAttributeNode:function(oldAttr){return this.attributes.removeNamedItem(oldAttr.nodeName)},removeAttributeNS:function(namespaceURI,localName){var old=this.getAttributeNodeNS(namespaceURI,localName);old&&this.removeAttributeNode(old)},hasAttributeNS:function(namespaceURI,localName){return null!=this.getAttributeNodeNS(namespaceURI,localName)},getAttributeNS:function(namespaceURI,localName){var attr=this.getAttributeNodeNS(namespaceURI,localName);return attr&&attr.value||""},setAttributeNS:function(namespaceURI,qualifiedName,value){var attr=this.ownerDocument.createAttributeNS(namespaceURI,qualifiedName);attr.value=attr.nodeValue=""+value,this.setAttributeNode(attr)},getAttributeNodeNS:function(namespaceURI,localName){return this.attributes.getNamedItemNS(namespaceURI,localName)},getElementsByTagName:function(tagName){return new LiveNodeList(this,(function(base){var ls=[];return _visitNode(base,(function(node){node===base||node.nodeType!=ELEMENT_NODE||"*"!==tagName&&node.tagName!=tagName||ls.push(node)})),ls}))},getElementsByTagNameNS:function(namespaceURI,localName){return new LiveNodeList(this,(function(base){var ls=[];return _visitNode(base,(function(node){node===base||node.nodeType!==ELEMENT_NODE||"*"!==namespaceURI&&node.namespaceURI!==namespaceURI||"*"!==localName&&node.localName!=localName||ls.push(node)})),ls}))}},Document.prototype.getElementsByTagName=Element.prototype.getElementsByTagName,Document.prototype.getElementsByTagNameNS=Element.prototype.getElementsByTagNameNS,_extends(Element,Node),Attr.prototype.nodeType=ATTRIBUTE_NODE,_extends(Attr,Node),CharacterData.prototype={data:"",substringData:function(offset,count){return this.data.substring(offset,offset+count)},appendData:function(text){text=this.data+text,this.nodeValue=this.data=text,this.length=text.length},insertData:function(offset,text){this.replaceData(offset,0,text)},appendChild:function(newChild){throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])},deleteData:function(offset,count){this.replaceData(offset,count,"")},replaceData:function(offset,count,text){text=this.data.substring(0,offset)+text+this.data.substring(offset+count),this.nodeValue=this.data=text,this.length=text.length}},_extends(CharacterData,Node),Text.prototype={nodeName:"#text",nodeType:TEXT_NODE,splitText:function(offset){var text=this.data,newText=text.substring(offset);text=text.substring(0,offset),this.data=this.nodeValue=text,this.length=text.length;var newNode=this.ownerDocument.createTextNode(newText);return this.parentNode&&this.parentNode.insertBefore(newNode,this.nextSibling),newNode}},_extends(Text,CharacterData),Comment.prototype={nodeName:"#comment",nodeType:COMMENT_NODE},_extends(Comment,CharacterData),CDATASection.prototype={nodeName:"#cdata-section",nodeType:CDATA_SECTION_NODE},_extends(CDATASection,CharacterData),DocumentType.prototype.nodeType=DOCUMENT_TYPE_NODE,_extends(DocumentType,Node),Notation.prototype.nodeType=NOTATION_NODE,_extends(Notation,Node),Entity.prototype.nodeType=ENTITY_NODE,_extends(Entity,Node),EntityReference.prototype.nodeType=ENTITY_REFERENCE_NODE,_extends(EntityReference,Node),DocumentFragment.prototype.nodeName="#document-fragment",DocumentFragment.prototype.nodeType=DOCUMENT_FRAGMENT_NODE,_extends(DocumentFragment,Node),ProcessingInstruction.prototype.nodeType=PROCESSING_INSTRUCTION_NODE,_extends(ProcessingInstruction,Node),XMLSerializer.prototype.serializeToString=function(node,isHtml,nodeFilter){return nodeSerializeToString.call(node,isHtml,nodeFilter)},Node.prototype.toString=nodeSerializeToString;try{if(Object.defineProperty){function getTextContent(node){switch(node.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:var buf=[];for(node=node.firstChild;node;)7!==node.nodeType&&8!==node.nodeType&&buf.push(getTextContent(node)),node=node.nextSibling;return buf.join("");default:return node.nodeValue}}Object.defineProperty(LiveNodeList.prototype,"length",{get:function(){return _updateLiveList(this),this.$$length}}),Object.defineProperty(Node.prototype,"textContent",{get:function(){return getTextContent(this)},set:function(data){switch(this.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(data||String(data))&&this.appendChild(this.ownerDocument.createTextNode(data));break;default:this.data=data,this.value=data,this.nodeValue=data}}}),__set__=function(object,key,value){object["$$"+key]=value}}}catch(e){}var dom={DocumentType:DocumentType,DOMException:DOMException,DOMImplementation:DOMImplementation$1,Element:Element,Node:Node,NodeList:NodeList,XMLSerializer:XMLSerializer},entities=createCommonjsModule((function(module,exports){var freeze=conventions.freeze;exports.XML_ENTITIES=freeze({amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}),exports.HTML_ENTITIES=freeze({lt:"<",gt:">",amp:"&",quot:'"',apos:"'",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",nbsp:" ",iexcl:"¡",cent:"¢",pound:"£",curren:"¤",yen:"¥",brvbar:"¦",sect:"§",uml:"¨",copy:"©",ordf:"ª",laquo:"«",not:"¬",shy:"­­",reg:"®",macr:"¯",deg:"°",plusmn:"±",sup2:"²",sup3:"³",acute:"´",micro:"µ",para:"¶",middot:"·",cedil:"¸",sup1:"¹",ordm:"º",raquo:"»",frac14:"¼",frac12:"½",frac34:"¾",iquest:"¿",times:"×",divide:"÷",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",infin:"∞",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",ne:"≠",equiv:"≡",le:"≤",ge:"≥",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",fnof:"ƒ",circ:"ˆ",tilde:"˜",ensp:" ",emsp:" ",thinsp:" ",zwnj:"‌",zwj:"‍",lrm:"‎",rlm:"‏",ndash:"–",mdash:"—",lsquo:"‘",rsquo:"’",sbquo:"‚",ldquo:"“",rdquo:"”",bdquo:"„",dagger:"†",Dagger:"‡",bull:"•",hellip:"…",permil:"‰",prime:"′",Prime:"″",lsaquo:"‹",rsaquo:"›",oline:"‾",euro:"€",trade:"™",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦"}),exports.entityMap=exports.HTML_ENTITIES}));entities.XML_ENTITIES,entities.HTML_ENTITIES,entities.entityMap;var NAMESPACE$1=conventions.NAMESPACE,nameStartChar=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,nameChar=new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"),tagNamePattern=new RegExp("^"+nameStartChar.source+nameChar.source+"*(?::"+nameStartChar.source+nameChar.source+"*)?$");function ParseError$1(message,locator){this.message=message,this.locator=locator,Error.captureStackTrace&&Error.captureStackTrace(this,ParseError$1)}function XMLReader$1(){}function copyLocator(f,t){return t.lineNumber=f.lineNumber,t.columnNumber=f.columnNumber,t}function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){function addAttribute(qname,value,startIndex){el.attributeNames.hasOwnProperty(qname)&&errorHandler.fatalError("Attribute "+qname+" redefined"),el.addValue(qname,value.replace(/[\t\n\r]/g," ").replace(/&#?\w+;/g,entityReplacer),startIndex)}for(var attrName,p=++start,s=0;;){var c=source.charAt(p);switch(c){case"=":if(1===s)attrName=source.slice(start,p),s=3;else{if(2!==s)throw new Error("attribute equal must after attrName");s=3}break;case"'":case'"':if(3===s||1===s){if(1===s&&(errorHandler.warning('attribute value must after "="'),attrName=source.slice(start,p)),start=p+1,!((p=source.indexOf(c,start))>0))throw new Error("attribute value no end '"+c+"' match");addAttribute(attrName,value=source.slice(start,p),start-1),s=5}else{if(4!=s)throw new Error('attribute value must after "="');addAttribute(attrName,value=source.slice(start,p),start),errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+")!!"),start=p+1,s=5}break;case"/":switch(s){case 0:el.setTagName(source.slice(start,p));case 5:case 6:case 7:s=7,el.closed=!0;case 4:case 1:case 2:break;default:throw new Error("attribute invalid close char('/')")}break;case"":return errorHandler.error("unexpected end of input"),0==s&&el.setTagName(source.slice(start,p)),p;case">":switch(s){case 0:el.setTagName(source.slice(start,p));case 5:case 6:case 7:break;case 4:case 1:"/"===(value=source.slice(start,p)).slice(-1)&&(el.closed=!0,value=value.slice(0,-1));case 2:2===s&&(value=attrName),4==s?(errorHandler.warning('attribute "'+value+'" missed quot(")!'),addAttribute(attrName,value,start)):(NAMESPACE$1.isHTML(currentNSMap[""])&&value.match(/^(?:disabled|checked|selected)$/i)||errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!'),addAttribute(value,value,start));break;case 3:throw new Error("attribute value missed!!")}return p;case"€":c=" ";default:if(c<=" ")switch(s){case 0:el.setTagName(source.slice(start,p)),s=6;break;case 1:attrName=source.slice(start,p),s=2;break;case 4:var value=source.slice(start,p);errorHandler.warning('attribute "'+value+'" missed quot(")!!'),addAttribute(attrName,value,start);case 5:s=6}else switch(s){case 2:el.tagName,NAMESPACE$1.isHTML(currentNSMap[""])&&attrName.match(/^(?:disabled|checked|selected)$/i)||errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!'),addAttribute(attrName,attrName,start),start=p,s=1;break;case 5:errorHandler.warning('attribute space is required"'+attrName+'"!!');case 6:s=1,start=p;break;case 3:s=4,start=p;break;case 7:throw new Error("elements closed character '/' and '>' must be connected to")}}p++}}function appendElement$1(el,domBuilder,currentNSMap){for(var tagName=el.tagName,localNSMap=null,i=el.length;i--;){var a=el[i],qName=a.qName,value=a.value;if((nsp=qName.indexOf(":"))>0)var prefix=a.prefix=qName.slice(0,nsp),localName=qName.slice(nsp+1),nsPrefix="xmlns"===prefix&&localName;else localName=qName,prefix=null,nsPrefix="xmlns"===qName&&"";a.localName=localName,!1!==nsPrefix&&(null==localNSMap&&(localNSMap={},_copy(currentNSMap,currentNSMap={})),currentNSMap[nsPrefix]=localNSMap[nsPrefix]=value,a.uri=NAMESPACE$1.XMLNS,domBuilder.startPrefixMapping(nsPrefix,value))}for(i=el.length;i--;){(prefix=(a=el[i]).prefix)&&("xml"===prefix&&(a.uri=NAMESPACE$1.XML),"xmlns"!==prefix&&(a.uri=currentNSMap[prefix||""]))}var nsp;(nsp=tagName.indexOf(":"))>0?(prefix=el.prefix=tagName.slice(0,nsp),localName=el.localName=tagName.slice(nsp+1)):(prefix=null,localName=el.localName=tagName);var ns=el.uri=currentNSMap[prefix||""];if(domBuilder.startElement(ns,localName,tagName,el),!el.closed)return el.currentNSMap=currentNSMap,el.localNSMap=localNSMap,!0;if(domBuilder.endElement(ns,localName,tagName),localNSMap)for(prefix in localNSMap)Object.prototype.hasOwnProperty.call(localNSMap,prefix)&&domBuilder.endPrefixMapping(prefix)}function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){if(/^(?:script|textarea)$/i.test(tagName)){var elEndStart=source.indexOf("",elStartEnd),text=source.substring(elStartEnd+1,elEndStart);if(/[&<]/.test(text))return/^script$/i.test(tagName)?(domBuilder.characters(text,0,text.length),elEndStart):(text=text.replace(/&#?\w+;/g,entityReplacer),domBuilder.characters(text,0,text.length),elEndStart)}return elStartEnd+1}function fixSelfClosed(source,elStartEnd,tagName,closeMap){var pos=closeMap[tagName];return null==pos&&((pos=source.lastIndexOf(""))start?(domBuilder.comment(source,start+4,end-start-4),end+3):(errorHandler.error("Unclosed comment"),-1):-1;if("CDATA["==source.substr(start+3,6)){var end=source.indexOf("]]>",start+9);return domBuilder.startCDATA(),domBuilder.characters(source,start+9,end-start-9),domBuilder.endCDATA(),end+3}var matchs=function(source,start){var match,buf=[],reg=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;reg.lastIndex=start,reg.exec(source);for(;match=reg.exec(source);)if(buf.push(match),match[1])return buf}(source,start),len=matchs.length;if(len>1&&/!doctype/i.test(matchs[0][0])){var name=matchs[1][0],pubid=!1,sysid=!1;len>3&&(/^public$/i.test(matchs[2][0])?(pubid=matchs[3][0],sysid=len>4&&matchs[4][0]):/^system$/i.test(matchs[2][0])&&(sysid=matchs[3][0]));var lastMatch=matchs[len-1];return domBuilder.startDTD(name,pubid,sysid),domBuilder.endDTD(),lastMatch.index+lastMatch[0].length}return-1}function parseInstruction(source,start,domBuilder){var end=source.indexOf("?>",start);if(end){var match=source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);return match?(match[0].length,domBuilder.processingInstruction(match[1],match[2]),end+2):-1}return-1}function ElementAttributes(){this.attributeNames={}}ParseError$1.prototype=new Error,ParseError$1.prototype.name=ParseError$1.name,XMLReader$1.prototype={parse:function(source,defaultNSMap,entityMap){var domBuilder=this.domBuilder;domBuilder.startDocument(),_copy(defaultNSMap,defaultNSMap={}),function(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){function fixedFromCharCode(code){if(code>65535){var surrogate1=55296+((code-=65536)>>10),surrogate2=56320+(1023&code);return String.fromCharCode(surrogate1,surrogate2)}return String.fromCharCode(code)}function entityReplacer(a){var k=a.slice(1,-1);return Object.hasOwnProperty.call(entityMap,k)?entityMap[k]:"#"===k.charAt(0)?fixedFromCharCode(parseInt(k.substr(1).replace("x","0x"))):(errorHandler.error("entity not found:"+a),a)}function appendText(end){if(end>start){var xt=source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);locator&&position(start),domBuilder.characters(xt,0,end-start),start=end}}function position(p,m){for(;p>=lineEnd&&(m=linePattern.exec(source));)lineStart=m.index,lineEnd=lineStart+m[0].length,locator.lineNumber++;locator.columnNumber=p-lineStart+1}var lineStart=0,lineEnd=0,linePattern=/.*(?:\r\n?|\n)|.*$/g,locator=domBuilder.locator,parseStack=[{currentNSMap:defaultNSMapCopy}],closeMap={},start=0;for(;;){try{var tagStart=source.indexOf("<",start);if(tagStart<0){if(!source.substr(start).match(/^\s*$/)){var doc=domBuilder.doc,text=doc.createTextNode(source.substr(start));doc.appendChild(text),domBuilder.currentElement=text}return}switch(tagStart>start&&appendText(tagStart),source.charAt(tagStart+1)){case"/":var end=source.indexOf(">",tagStart+3),tagName=source.substring(tagStart+2,end).replace(/[ \t\n\r]+$/g,""),config=parseStack.pop();end<0?(tagName=source.substring(tagStart+2).replace(/[\s<].*/,""),errorHandler.error("end tag name: "+tagName+" is not complete:"+config.tagName),end=tagStart+1+tagName.length):tagName.match(/\sstart?start=end:appendText(Math.max(tagStart,start)+1)}}(source,defaultNSMap,entityMap,domBuilder,this.errorHandler),domBuilder.endDocument()}},ElementAttributes.prototype={setTagName:function(tagName){if(!tagNamePattern.test(tagName))throw new Error("invalid tagName:"+tagName);this.tagName=tagName},addValue:function(qName,value,offset){if(!tagNamePattern.test(qName))throw new Error("invalid attribute:"+qName);this.attributeNames[qName]=this.length,this[this.length++]={qName:qName,value:value,offset:offset}},length:0,getLocalName:function(i){return this[i].localName},getLocator:function(i){return this[i].locator},getQName:function(i){return this[i].qName},getURI:function(i){return this[i].uri},getValue:function(i){return this[i].value}};var sax={XMLReader:XMLReader$1,ParseError:ParseError$1},DOMImplementation=dom.DOMImplementation,NAMESPACE=conventions.NAMESPACE,ParseError=sax.ParseError,XMLReader=sax.XMLReader;function normalizeLineEndings(input){return input.replace(/\r[\n\u0085]/g,"\n").replace(/[\r\u0085\u2028]/g,"\n")}function DOMParser$1(options){this.options=options||{locator:{}}}function DOMHandler(){this.cdata=!1}function position(locator,node){node.lineNumber=locator.lineNumber,node.columnNumber=locator.columnNumber}function _locator(l){if(l)return"\n@"+(l.systemId||"")+"#[line:"+l.lineNumber+",col:"+l.columnNumber+"]"}function _toString(chars,start,length){return"string"==typeof chars?chars.substr(start,length):chars.length>=start+length||start?new java.lang.String(chars,start,length)+"":chars}function appendElement(hander,node){hander.currentElement?hander.currentElement.appendChild(node):hander.doc.appendChild(node)}DOMParser$1.prototype.parseFromString=function(source,mimeType){var options=this.options,sax=new XMLReader,domBuilder=options.domBuilder||new DOMHandler,errorHandler=options.errorHandler,locator=options.locator,defaultNSMap=options.xmlns||{},isHTML=/\/x?html?$/.test(mimeType),entityMap=isHTML?entities.HTML_ENTITIES:entities.XML_ENTITIES;locator&&domBuilder.setDocumentLocator(locator),sax.errorHandler=function(errorImpl,domBuilder,locator){if(!errorImpl){if(domBuilder instanceof DOMHandler)return domBuilder;errorImpl=domBuilder}var errorHandler={},isCallback=errorImpl instanceof Function;function build(key){var fn=errorImpl[key];!fn&&isCallback&&(fn=2==errorImpl.length?function(msg){errorImpl(key,msg)}:errorImpl),errorHandler[key]=fn&&function(msg){fn("[xmldom "+key+"]\t"+msg+_locator(locator))}||function(){}}return locator=locator||{},build("warning"),build("error"),build("fatalError"),errorHandler}(errorHandler,domBuilder,locator),sax.domBuilder=options.domBuilder||domBuilder,isHTML&&(defaultNSMap[""]=NAMESPACE.HTML),defaultNSMap.xml=defaultNSMap.xml||NAMESPACE.XML;var normalize=options.normalizeLineEndings||normalizeLineEndings;return source&&"string"==typeof source?sax.parse(normalize(source),defaultNSMap,entityMap):sax.errorHandler.error("invalid doc source"),domBuilder.doc},DOMHandler.prototype={startDocument:function(){this.doc=(new DOMImplementation).createDocument(null,null,null),this.locator&&(this.doc.documentURI=this.locator.systemId)},startElement:function(namespaceURI,localName,qName,attrs){var doc=this.doc,el=doc.createElementNS(namespaceURI,qName||localName),len=attrs.length;appendElement(this,el),this.currentElement=el,this.locator&&position(this.locator,el);for(var i=0;i!!obj&&"object"==typeof obj,merge$1=function(){for(var _len23=arguments.length,objects=new Array(_len23),_key23=0;_key23<_len23;_key23++)objects[_key23]=arguments[_key23];return objects.reduce(((result,source)=>("object"!=typeof source||Object.keys(source).forEach((key=>{Array.isArray(result[key])&&Array.isArray(source[key])?result[key]=result[key].concat(source[key]):isObject(result[key])&&isObject(source[key])?result[key]=merge$1(result[key],source[key]):result[key]=source[key]})),result)),{})},values=o=>Object.keys(o).map((k=>o[k])),flatten=lists=>lists.reduce(((x,y)=>x.concat(y)),[]),from=list=>{if(!list.length)return[];const result=[];for(let i=0;i{let{baseUrl:baseUrl="",source:source="",range:range="",indexRange:indexRange=""}=_ref10;const segment={uri:source,resolvedUri:resolveUrl$1(baseUrl||"",source)};if(range||indexRange){const ranges=(range||indexRange).split("-");let length,startRange=window.BigInt?window.BigInt(ranges[0]):parseInt(ranges[0],10),endRange=window.BigInt?window.BigInt(ranges[1]):parseInt(ranges[1],10);startRange(endNumber&&"number"!=typeof endNumber&&(endNumber=parseInt(endNumber,10)),isNaN(endNumber)?null:endNumber),segmentRange={static(attributes){const{duration:duration,timescale:timescale=1,sourceDuration:sourceDuration,periodDuration:periodDuration}=attributes,endNumber=parseEndNumber(attributes.endNumber),segmentDuration=duration/timescale;return"number"==typeof endNumber?{start:0,end:endNumber}:"number"==typeof periodDuration?{start:0,end:periodDuration/segmentDuration}:{start:0,end:sourceDuration/segmentDuration}},dynamic(attributes){const{NOW:NOW,clientOffset:clientOffset,availabilityStartTime:availabilityStartTime,timescale:timescale=1,duration:duration,periodStart:periodStart=0,minimumUpdatePeriod:minimumUpdatePeriod=0,timeShiftBufferDepth:timeShiftBufferDepth=1/0}=attributes,endNumber=parseEndNumber(attributes.endNumber),now=(NOW+clientOffset)/1e3,periodStartWC=availabilityStartTime+periodStart,periodDuration=now+minimumUpdatePeriod-periodStartWC,segmentCount=Math.ceil(periodDuration*timescale/duration),availableStart=Math.floor((now-periodStartWC-timeShiftBufferDepth)*timescale/duration),availableEnd=Math.floor((now-periodStartWC)*timescale/duration);return{start:Math.max(0,availableStart),end:"number"==typeof endNumber?endNumber:Math.min(segmentCount,availableEnd)}}},parseByDuration=attributes=>{const{type:type,duration:duration,timescale:timescale=1,periodDuration:periodDuration,sourceDuration:sourceDuration}=attributes,{start:start,end:end}=segmentRange[type](attributes),segments=((start,end)=>{const result=[];for(let i=start;inumber=>{const{duration:duration,timescale:timescale=1,periodStart:periodStart,startNumber:startNumber=1}=attributes;return{number:startNumber+number,duration:duration/timescale,timeline:periodStart,time:number*duration}})(attributes));if("static"===type){const index=segments.length-1,sectionDuration="number"==typeof periodDuration?periodDuration:sourceDuration;segments[index].duration=sectionDuration-duration/timescale*index}return segments},segmentsFromBase=attributes=>{const{baseUrl:baseUrl,initialization:initialization={},sourceDuration:sourceDuration,indexRange:indexRange="",periodStart:periodStart,presentationTime:presentationTime,number:number=0,duration:duration}=attributes;if(!baseUrl)throw new Error(errors_NO_BASE_URL);const initSegment=urlTypeToSegment({baseUrl:baseUrl,source:initialization.sourceURL,range:initialization.range}),segment=urlTypeToSegment({baseUrl:baseUrl,source:baseUrl,indexRange:indexRange});if(segment.map=initSegment,duration){const segmentTimeInfo=parseByDuration(attributes);segmentTimeInfo.length&&(segment.duration=segmentTimeInfo[0].duration,segment.timeline=segmentTimeInfo[0].timeline)}else sourceDuration&&(segment.duration=sourceDuration,segment.timeline=periodStart);return segment.presentationTime=presentationTime||periodStart,segment.number=number,[segment]},addSidxSegmentsToPlaylist$1=(playlist,sidx,baseUrl)=>{const initSegment=playlist.sidx.map?playlist.sidx.map:null,sourceDuration=playlist.sidx.duration,timeline=playlist.timeline||0,sidxByteRange=playlist.sidx.byterange,sidxEnd=sidxByteRange.offset+sidxByteRange.length,timescale=sidx.timescale,mediaReferences=sidx.references.filter((r=>1!==r.referenceType)),segments=[],type=playlist.endList?"static":"dynamic",periodStart=playlist.sidx.timeline;let startIndex,presentationTime=periodStart,number=playlist.mediaSequence||0;startIndex="bigint"==typeof sidx.firstOffset?window.BigInt(sidxEnd)+sidx.firstOffset:sidxEnd+sidx.firstOffset;for(let i=0;i{return(lists=timelineStarts,keyFunction=_ref11=>{let{timeline:timeline}=_ref11;return timeline},values(lists.reduce(((acc,list)=>(list.forEach((el=>{acc[keyFunction(el)]=el})),acc)),{}))).sort(((a,b)=>a.timeline>b.timeline?1:-1));var lists,keyFunction},getMediaGroupPlaylists=manifest=>{let mediaGroupPlaylists=[];var master,callback;return master=manifest,callback=(properties,type,group,label)=>{mediaGroupPlaylists=mediaGroupPlaylists.concat(properties.playlists||[])},SUPPORTED_MEDIA_TYPES.forEach((function(mediaType){for(var groupKey in master.mediaGroups[mediaType])for(var labelKey in master.mediaGroups[mediaType][groupKey]){var mediaProperties=master.mediaGroups[mediaType][groupKey][labelKey];callback(mediaProperties,mediaType,groupKey,labelKey)}})),mediaGroupPlaylists},updateMediaSequenceForPlaylist=_ref12=>{let{playlist:playlist,mediaSequence:mediaSequence}=_ref12;playlist.mediaSequence=mediaSequence,playlist.segments.forEach(((segment,index)=>{segment.number=playlist.mediaSequence+index}))},positionManifestOnTimeline=_ref15=>{let{oldManifest:oldManifest,newManifest:newManifest}=_ref15;const oldPlaylists=oldManifest.playlists.concat(getMediaGroupPlaylists(oldManifest)),newPlaylists=newManifest.playlists.concat(getMediaGroupPlaylists(newManifest));return newManifest.timelineStarts=getUniqueTimelineStarts([oldManifest.timelineStarts,newManifest.timelineStarts]),(_ref13=>{let{oldPlaylists:oldPlaylists,newPlaylists:newPlaylists,timelineStarts:timelineStarts}=_ref13;newPlaylists.forEach((playlist=>{playlist.discontinuitySequence=timelineStarts.findIndex((function(_ref14){let{timeline:timeline}=_ref14;return timeline===playlist.timeline}));const oldPlaylist=((playlists,name)=>{for(let i=0;ioldPlaylist.timeline||oldPlaylist.segments.length&&playlist.timeline>oldPlaylist.segments[oldPlaylist.segments.length-1].timeline)&&playlist.discontinuitySequence--);oldPlaylist.segments[oldMatchingSegmentIndex].discontinuity&&!firstNewSegment.discontinuity&&(firstNewSegment.discontinuity=!0,playlist.discontinuityStarts.unshift(0),playlist.discontinuitySequence--),updateMediaSequenceForPlaylist({playlist:playlist,mediaSequence:oldPlaylist.segments[oldMatchingSegmentIndex].number})}))})({oldPlaylists:oldPlaylists,newPlaylists:newPlaylists,timelineStarts:newManifest.timelineStarts}),newManifest},generateSidxKey=sidx=>sidx&&sidx.uri+"-"+(byterange=>{let endRange;return endRange="bigint"==typeof byterange.offset||"bigint"==typeof byterange.length?window.BigInt(byterange.offset)+window.BigInt(byterange.length)-window.BigInt(1):byterange.offset+byterange.length-1,"".concat(byterange.offset,"-").concat(endRange)})(sidx.byterange),mergeDiscontiguousPlaylists=playlists=>values(playlists.reduce(((acc,playlist)=>{const name=playlist.attributes.id+(playlist.attributes.lang||"");return acc[name]?(playlist.segments&&(playlist.segments[0]&&(playlist.segments[0].discontinuity=!0),acc[name].segments.push(...playlist.segments)),playlist.attributes.contentProtection&&(acc[name].attributes.contentProtection=playlist.attributes.contentProtection)):(acc[name]=playlist,acc[name].attributes.timelineStarts=[]),acc[name].attributes.timelineStarts.push({start:playlist.attributes.periodStart,timeline:playlist.attributes.periodStart}),acc}),{})).map((playlist=>{var l,key;return playlist.discontinuityStarts=(l=playlist.segments||[],key="discontinuity",l.reduce(((a,e,i)=>(e[key]&&a.push(i),a)),[])),playlist})),addSidxSegmentsToPlaylist=(playlist,sidxMapping)=>{const sidxKey=generateSidxKey(playlist.sidx),sidxMatch=sidxKey&&sidxMapping[sidxKey]&&sidxMapping[sidxKey].sidx;return sidxMatch&&addSidxSegmentsToPlaylist$1(playlist,sidxMatch,playlist.sidx.resolvedUri),playlist},addSidxSegmentsToPlaylists=function(playlists){let sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!Object.keys(sidxMapping).length)return playlists;for(const i in playlists)playlists[i]=addSidxSegmentsToPlaylist(playlists[i],sidxMapping);return playlists},formatAudioPlaylist=(_ref16,isAudioOnly)=>{let{attributes:attributes,segments:segments,sidx:sidx,mediaSequence:mediaSequence,discontinuitySequence:discontinuitySequence,discontinuityStarts:discontinuityStarts}=_ref16;const playlist={attributes:{NAME:attributes.id,BANDWIDTH:attributes.bandwidth,CODECS:attributes.codecs,"PROGRAM-ID":1},uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:"",targetDuration:attributes.duration,discontinuitySequence:discontinuitySequence,discontinuityStarts:discontinuityStarts,timelineStarts:attributes.timelineStarts,mediaSequence:mediaSequence,segments:segments};return attributes.contentProtection&&(playlist.contentProtection=attributes.contentProtection),sidx&&(playlist.sidx=sidx),isAudioOnly&&(playlist.attributes.AUDIO="audio",playlist.attributes.SUBTITLES="subs"),playlist},formatVttPlaylist=_ref17=>{let{attributes:attributes,segments:segments,mediaSequence:mediaSequence,discontinuityStarts:discontinuityStarts,discontinuitySequence:discontinuitySequence}=_ref17;void 0===segments&&(segments=[{uri:attributes.baseUrl,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",duration:attributes.sourceDuration,number:0}],attributes.duration=attributes.sourceDuration);const m3u8Attributes={NAME:attributes.id,BANDWIDTH:attributes.bandwidth,"PROGRAM-ID":1};return attributes.codecs&&(m3u8Attributes.CODECS=attributes.codecs),{attributes:m3u8Attributes,uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",targetDuration:attributes.duration,timelineStarts:attributes.timelineStarts,discontinuityStarts:discontinuityStarts,discontinuitySequence:discontinuitySequence,mediaSequence:mediaSequence,segments:segments}},formatVideoPlaylist=_ref18=>{let{attributes:attributes,segments:segments,sidx:sidx,discontinuityStarts:discontinuityStarts}=_ref18;const playlist={attributes:{NAME:attributes.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:attributes.width,height:attributes.height},CODECS:attributes.codecs,BANDWIDTH:attributes.bandwidth,"PROGRAM-ID":1},uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:"",targetDuration:attributes.duration,discontinuityStarts:discontinuityStarts,timelineStarts:attributes.timelineStarts,segments:segments};return attributes.frameRate&&(playlist.attributes["FRAME-RATE"]=attributes.frameRate),attributes.contentProtection&&(playlist.contentProtection=attributes.contentProtection),sidx&&(playlist.sidx=sidx),playlist},videoOnly=_ref19=>{let{attributes:attributes}=_ref19;return"video/mp4"===attributes.mimeType||"video/webm"===attributes.mimeType||"video"===attributes.contentType},audioOnly=_ref20=>{let{attributes:attributes}=_ref20;return"audio/mp4"===attributes.mimeType||"audio/webm"===attributes.mimeType||"audio"===attributes.contentType},vttOnly=_ref21=>{let{attributes:attributes}=_ref21;return"text/vtt"===attributes.mimeType||"text"===attributes.contentType},flattenMediaGroupPlaylists=mediaGroupObject=>mediaGroupObject?Object.keys(mediaGroupObject).reduce(((acc,label)=>{const labelContents=mediaGroupObject[label];return acc.concat(labelContents.playlists)}),[]):[],toM3u8=_ref23=>{let{dashPlaylists:dashPlaylists,locations:locations,sidxMapping:sidxMapping={},previousManifest:previousManifest}=_ref23;if(!dashPlaylists.length)return{};const{sourceDuration:duration,type:type,suggestedPresentationDelay:suggestedPresentationDelay,minimumUpdatePeriod:minimumUpdatePeriod}=dashPlaylists[0].attributes,videoPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist),audioPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly)),vttPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(vttOnly)),captions=dashPlaylists.map((playlist=>playlist.attributes.captionServices)).filter(Boolean),manifest={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:"",duration:duration,playlists:addSidxSegmentsToPlaylists(videoPlaylists,sidxMapping)};minimumUpdatePeriod>=0&&(manifest.minimumUpdatePeriod=1e3*minimumUpdatePeriod),locations&&(manifest.locations=locations),"dynamic"===type&&(manifest.suggestedPresentationDelay=suggestedPresentationDelay);const isAudioOnly=0===manifest.playlists.length,organizedAudioGroup=audioPlaylists.length?function(playlists){let mainPlaylist,sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},isAudioOnly=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const formattedPlaylists=playlists.reduce(((a,playlist)=>{const role=playlist.attributes.role&&playlist.attributes.role.value||"",language=playlist.attributes.lang||"";let label=playlist.attributes.label||"main";if(language&&!playlist.attributes.label){const roleLabel=role?" (".concat(role,")"):"";label="".concat(playlist.attributes.lang).concat(roleLabel)}a[label]||(a[label]={language:language,autoselect:!0,default:"main"===role,playlists:[],uri:""});const formatted=addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist,isAudioOnly),sidxMapping);return a[label].playlists.push(formatted),void 0===mainPlaylist&&"main"===role&&(mainPlaylist=playlist,mainPlaylist.default=!0),a}),{});mainPlaylist||(formattedPlaylists[Object.keys(formattedPlaylists)[0]].default=!0);return formattedPlaylists}(audioPlaylists,sidxMapping,isAudioOnly):null,organizedVttGroup=vttPlaylists.length?function(playlists){let sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return playlists.reduce(((a,playlist)=>{const label=playlist.attributes.lang||"text";return a[label]||(a[label]={language:label,default:!1,autoselect:!1,playlists:[],uri:""}),a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist),sidxMapping)),a}),{})}(vttPlaylists,sidxMapping):null,formattedPlaylists=videoPlaylists.concat(flattenMediaGroupPlaylists(organizedAudioGroup),flattenMediaGroupPlaylists(organizedVttGroup)),playlistTimelineStarts=formattedPlaylists.map((_ref24=>{let{timelineStarts:timelineStarts}=_ref24;return timelineStarts}));var playlists,timelineStarts;return manifest.timelineStarts=getUniqueTimelineStarts(playlistTimelineStarts),playlists=formattedPlaylists,timelineStarts=manifest.timelineStarts,playlists.forEach((playlist=>{playlist.mediaSequence=0,playlist.discontinuitySequence=timelineStarts.findIndex((function(_ref22){let{timeline:timeline}=_ref22;return timeline===playlist.timeline})),playlist.segments&&playlist.segments.forEach(((segment,index)=>{segment.number=index}))})),organizedAudioGroup&&(manifest.mediaGroups.AUDIO.audio=organizedAudioGroup),organizedVttGroup&&(manifest.mediaGroups.SUBTITLES.subs=organizedVttGroup),captions.length&&(manifest.mediaGroups["CLOSED-CAPTIONS"].cc=captions.reduce(((svcObj,svc)=>svc?(svc.forEach((service=>{const{channel:channel,language:language}=service;svcObj[language]={autoselect:!1,default:!1,instreamId:channel,language:language},service.hasOwnProperty("aspectRatio")&&(svcObj[language].aspectRatio=service.aspectRatio),service.hasOwnProperty("easyReader")&&(svcObj[language].easyReader=service.easyReader),service.hasOwnProperty("3D")&&(svcObj[language]["3D"]=service["3D"])})),svcObj):svcObj),{})),previousManifest?positionManifestOnTimeline({oldManifest:previousManifest,newManifest:manifest}):manifest},getLiveRValue=(attributes,time,duration)=>{const{NOW:NOW,clientOffset:clientOffset,availabilityStartTime:availabilityStartTime,timescale:timescale=1,periodStart:periodStart=0,minimumUpdatePeriod:minimumUpdatePeriod=0}=attributes,periodDuration=(NOW+clientOffset)/1e3+minimumUpdatePeriod-(availabilityStartTime+periodStart);return Math.ceil((periodDuration*timescale-time)/duration)},parseByTimeline=(attributes,segmentTimeline)=>{const{type:type,minimumUpdatePeriod:minimumUpdatePeriod=0,media:media="",sourceDuration:sourceDuration,timescale:timescale=1,startNumber:startNumber=1,periodStart:timeline}=attributes,segments=[];let time=-1;for(let sIndex=0;sIndextime&&(time=segmentTime),repeat<0){const nextS=sIndex+1;count=nextS===segmentTimeline.length?"dynamic"===type&&minimumUpdatePeriod>0&&media.indexOf("$Number$")>0?getLiveRValue(attributes,time,duration):(sourceDuration*timescale-time)/duration:(segmentTimeline[nextS].t-time)/duration}else count=repeat+1;const end=startNumber+segments.length+count;let number=startNumber+segments.length;for(;numberurl.replace(identifierPattern,(values=>(match,identifier,format,width)=>{if("$$"===match)return"$";if(void 0===values[identifier])return match;const value=""+values[identifier];return"RepresentationID"===identifier?value:(width=format?parseInt(width,10):1,value.length>=width?value:"".concat(new Array(width-value.length+1).join("0")).concat(value))})(values)),segmentsFromTemplate=(attributes,segmentTimeline)=>{const templateValues={RepresentationID:attributes.id,Bandwidth:attributes.bandwidth||0},{initialization:initialization={sourceURL:"",range:""}}=attributes,mapSegment=urlTypeToSegment({baseUrl:attributes.baseUrl,source:constructTemplateUrl(initialization.sourceURL,templateValues),range:initialization.range}),segments=((attributes,segmentTimeline)=>attributes.duration||segmentTimeline?attributes.duration?parseByDuration(attributes):parseByTimeline(attributes,segmentTimeline):[{number:attributes.startNumber||1,duration:attributes.sourceDuration,time:0,timeline:attributes.periodStart}])(attributes,segmentTimeline);return segments.map((segment=>{templateValues.Number=segment.number,templateValues.Time=segment.time;const uri=constructTemplateUrl(attributes.media||"",templateValues),timescale=attributes.timescale||1,presentationTimeOffset=attributes.presentationTimeOffset||0,presentationTime=attributes.periodStart+(segment.time-presentationTimeOffset)/timescale;return{uri:uri,timeline:segment.timeline,duration:segment.duration,resolvedUri:resolveUrl$1(attributes.baseUrl||"",uri),map:mapSegment,number:segment.number,presentationTime:presentationTime}}))},segmentsFromList=(attributes,segmentTimeline)=>{const{duration:duration,segmentUrls:segmentUrls=[],periodStart:periodStart}=attributes;if(!duration&&!segmentTimeline||duration&&segmentTimeline)throw new Error(errors_SEGMENT_TIME_UNSPECIFIED);const segmentUrlMap=segmentUrls.map((segmentUrlObject=>((attributes,segmentUrl)=>{const{baseUrl:baseUrl,initialization:initialization={}}=attributes,initSegment=urlTypeToSegment({baseUrl:baseUrl,source:initialization.sourceURL,range:initialization.range}),segment=urlTypeToSegment({baseUrl:baseUrl,source:segmentUrl.media,range:segmentUrl.mediaRange});return segment.map=initSegment,segment})(attributes,segmentUrlObject)));let segmentTimeInfo;duration&&(segmentTimeInfo=parseByDuration(attributes)),segmentTimeline&&(segmentTimeInfo=parseByTimeline(attributes,segmentTimeline));return segmentTimeInfo.map(((segmentTime,index)=>{if(segmentUrlMap[index]){const segment=segmentUrlMap[index],timescale=attributes.timescale||1,presentationTimeOffset=attributes.presentationTimeOffset||0;return segment.timeline=segmentTime.timeline,segment.duration=segmentTime.duration,segment.number=segmentTime.number,segment.presentationTime=periodStart+(segmentTime.time-presentationTimeOffset)/timescale,segment}})).filter((segment=>segment))},generateSegments=_ref25=>{let segmentAttributes,segmentsFn,{attributes:attributes,segmentInfo:segmentInfo}=_ref25;segmentInfo.template?(segmentsFn=segmentsFromTemplate,segmentAttributes=merge$1(attributes,segmentInfo.template)):segmentInfo.base?(segmentsFn=segmentsFromBase,segmentAttributes=merge$1(attributes,segmentInfo.base)):segmentInfo.list&&(segmentsFn=segmentsFromList,segmentAttributes=merge$1(attributes,segmentInfo.list));const segmentsInfo={attributes:attributes};if(!segmentsFn)return segmentsInfo;const segments=segmentsFn(segmentAttributes,segmentInfo.segmentTimeline);if(segmentAttributes.duration){const{duration:duration,timescale:timescale=1}=segmentAttributes;segmentAttributes.duration=duration/timescale}else segments.length?segmentAttributes.duration=segments.reduce(((max,segment)=>Math.max(max,Math.ceil(segment.duration))),0):segmentAttributes.duration=0;return segmentsInfo.attributes=segmentAttributes,segmentsInfo.segments=segments,segmentInfo.base&&segmentAttributes.indexRange&&(segmentsInfo.sidx=segments[0],segmentsInfo.segments=[]),segmentsInfo},toPlaylists=representations=>representations.map(generateSegments),findChildren=(element,name)=>from(element.childNodes).filter((_ref26=>{let{tagName:tagName}=_ref26;return tagName===name})),getContent=element=>element.textContent.trim(),parseDuration=str=>{const match=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(str);if(!match)return 0;const[year,month,day,hour,minute,second]=match.slice(1);return 31536e3*parseFloat(year||0)+2592e3*parseFloat(month||0)+86400*parseFloat(day||0)+3600*parseFloat(hour||0)+60*parseFloat(minute||0)+parseFloat(second||0)},parsers={mediaPresentationDuration:value=>parseDuration(value),availabilityStartTime(value){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(str=value)&&(str+="Z"),Date.parse(str)/1e3;var str},minimumUpdatePeriod:value=>parseDuration(value),suggestedPresentationDelay:value=>parseDuration(value),type:value=>value,timeShiftBufferDepth:value=>parseDuration(value),start:value=>parseDuration(value),width:value=>parseInt(value,10),height:value=>parseInt(value,10),bandwidth:value=>parseInt(value,10),frameRate:value=>(value=>parseFloat(value.split("/").reduce(((prev,current)=>prev/current))))(value),startNumber:value=>parseInt(value,10),timescale:value=>parseInt(value,10),presentationTimeOffset:value=>parseInt(value,10),duration(value){const parsedValue=parseInt(value,10);return isNaN(parsedValue)?parseDuration(value):parsedValue},d:value=>parseInt(value,10),t:value=>parseInt(value,10),r:value=>parseInt(value,10),DEFAULT:value=>value},parseAttributes=el=>el&&el.attributes?from(el.attributes).reduce(((a,e)=>{const parseFn=parsers[e.name]||parsers.DEFAULT;return a[e.name]=parseFn(e.value),a}),{}):{},keySystemsMap={"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"},buildBaseUrls=(referenceUrls,baseUrlElements)=>baseUrlElements.length?flatten(referenceUrls.map((function(reference){return baseUrlElements.map((function(baseUrlElement){return resolveUrl$1(reference,getContent(baseUrlElement))}))}))):referenceUrls,getSegmentInformation=adaptationSet=>{const segmentTemplate=findChildren(adaptationSet,"SegmentTemplate")[0],segmentList=findChildren(adaptationSet,"SegmentList")[0],segmentUrls=segmentList&&findChildren(segmentList,"SegmentURL").map((s=>merge$1({tag:"SegmentURL"},parseAttributes(s)))),segmentBase=findChildren(adaptationSet,"SegmentBase")[0],segmentTimelineParentNode=segmentList||segmentTemplate,segmentTimeline=segmentTimelineParentNode&&findChildren(segmentTimelineParentNode,"SegmentTimeline")[0],segmentInitializationParentNode=segmentList||segmentBase||segmentTemplate,segmentInitialization=segmentInitializationParentNode&&findChildren(segmentInitializationParentNode,"Initialization")[0],template=segmentTemplate&&parseAttributes(segmentTemplate);template&&segmentInitialization?template.initialization=segmentInitialization&&parseAttributes(segmentInitialization):template&&template.initialization&&(template.initialization={sourceURL:template.initialization});const segmentInfo={template:template,segmentTimeline:segmentTimeline&&findChildren(segmentTimeline,"S").map((s=>parseAttributes(s))),list:segmentList&&merge$1(parseAttributes(segmentList),{segmentUrls:segmentUrls,initialization:parseAttributes(segmentInitialization)}),base:segmentBase&&merge$1(parseAttributes(segmentBase),{initialization:parseAttributes(segmentInitialization)})};return Object.keys(segmentInfo).forEach((key=>{segmentInfo[key]||delete segmentInfo[key]})),segmentInfo},toRepresentations=(periodAttributes,periodBaseUrls,periodSegmentInfo)=>adaptationSet=>{const adaptationSetAttributes=parseAttributes(adaptationSet),adaptationSetBaseUrls=buildBaseUrls(periodBaseUrls,findChildren(adaptationSet,"BaseURL")),role=findChildren(adaptationSet,"Role")[0],roleAttributes={role:parseAttributes(role)};let attrs=merge$1(periodAttributes,adaptationSetAttributes,roleAttributes);const accessibility=findChildren(adaptationSet,"Accessibility")[0],captionServices=(service=>{if("urn:scte:dash:cc:cea-608:2015"===service.schemeIdUri)return("string"!=typeof service.value?[]:service.value.split(";")).map((value=>{let channel,language;return language=value,/^CC\d=/.test(value)?[channel,language]=value.split("="):/^CC\d$/.test(value)&&(channel=value),{channel:channel,language:language}}));if("urn:scte:dash:cc:cea-708:2015"===service.schemeIdUri)return("string"!=typeof service.value?[]:service.value.split(";")).map((value=>{const flags={channel:void 0,language:void 0,aspectRatio:1,easyReader:0,"3D":0};if(/=/.test(value)){const[channel,opts=""]=value.split("=");flags.channel=channel,flags.language=value,opts.split(",").forEach((opt=>{const[name,val]=opt.split(":");"lang"===name?flags.language=val:"er"===name?flags.easyReader=Number(val):"war"===name?flags.aspectRatio=Number(val):"3D"===name&&(flags["3D"]=Number(val))}))}else flags.language=value;return flags.channel&&(flags.channel="SERVICE"+flags.channel),flags}))})(parseAttributes(accessibility));captionServices&&(attrs=merge$1(attrs,{captionServices:captionServices}));const label=findChildren(adaptationSet,"Label")[0];if(label&&label.childNodes.length){const labelVal=label.childNodes[0].nodeValue.trim();attrs=merge$1(attrs,{label:labelVal})}const contentProtection=findChildren(adaptationSet,"ContentProtection").reduce(((acc,node)=>{const attributes=parseAttributes(node);attributes.schemeIdUri&&(attributes.schemeIdUri=attributes.schemeIdUri.toLowerCase());const keySystem=keySystemsMap[attributes.schemeIdUri];if(keySystem){acc[keySystem]={attributes:attributes};const psshNode=findChildren(node,"cenc:pssh")[0];if(psshNode){const pssh=getContent(psshNode);acc[keySystem].pssh=pssh&&decodeB64ToUint8Array(pssh)}}return acc}),{});Object.keys(contentProtection).length&&(attrs=merge$1(attrs,{contentProtection:contentProtection}));const segmentInfo=getSegmentInformation(adaptationSet),representations=findChildren(adaptationSet,"Representation"),adaptationSetSegmentInfo=merge$1(periodSegmentInfo,segmentInfo);return flatten(representations.map(((adaptationSetAttributes,adaptationSetBaseUrls,adaptationSetSegmentInfo)=>representation=>{const repBaseUrlElements=findChildren(representation,"BaseURL"),repBaseUrls=buildBaseUrls(adaptationSetBaseUrls,repBaseUrlElements),attributes=merge$1(adaptationSetAttributes,parseAttributes(representation)),representationSegmentInfo=getSegmentInformation(representation);return repBaseUrls.map((baseUrl=>({segmentInfo:merge$1(adaptationSetSegmentInfo,representationSegmentInfo),attributes:merge$1(attributes,{baseUrl:baseUrl})})))})(attrs,adaptationSetBaseUrls,adaptationSetSegmentInfo)))},toAdaptationSets=(mpdAttributes,mpdBaseUrls)=>(period,index)=>{const periodBaseUrls=buildBaseUrls(mpdBaseUrls,findChildren(period.node,"BaseURL")),periodAttributes=merge$1(mpdAttributes,{periodStart:period.attributes.start});"number"==typeof period.attributes.duration&&(periodAttributes.periodDuration=period.attributes.duration);const adaptationSets=findChildren(period.node,"AdaptationSet"),periodSegmentInfo=getSegmentInformation(period.node);return flatten(adaptationSets.map(toRepresentations(periodAttributes,periodBaseUrls,periodSegmentInfo)))},getPeriodStart=_ref27=>{let{attributes:attributes,priorPeriodAttributes:priorPeriodAttributes,mpdType:mpdType}=_ref27;return"number"==typeof attributes.start?attributes.start:priorPeriodAttributes&&"number"==typeof priorPeriodAttributes.start&&"number"==typeof priorPeriodAttributes.duration?priorPeriodAttributes.start+priorPeriodAttributes.duration:priorPeriodAttributes||"static"!==mpdType?null:0},inheritAttributes=function(mpd){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{manifestUri:manifestUri="",NOW:NOW=Date.now(),clientOffset:clientOffset=0}=options,periodNodes=findChildren(mpd,"Period");if(!periodNodes.length)throw new Error(errors_INVALID_NUMBER_OF_PERIOD);const locations=findChildren(mpd,"Location"),mpdAttributes=parseAttributes(mpd),mpdBaseUrls=buildBaseUrls([manifestUri],findChildren(mpd,"BaseURL"));mpdAttributes.type=mpdAttributes.type||"static",mpdAttributes.sourceDuration=mpdAttributes.mediaPresentationDuration||0,mpdAttributes.NOW=NOW,mpdAttributes.clientOffset=clientOffset,locations.length&&(mpdAttributes.locations=locations.map(getContent));const periods=[];return periodNodes.forEach(((node,index)=>{const attributes=parseAttributes(node),priorPeriod=periods[index-1];attributes.start=getPeriodStart({attributes:attributes,priorPeriodAttributes:priorPeriod?priorPeriod.attributes:null,mpdType:mpdAttributes.type}),periods.push({node:node,attributes:attributes})})),{locations:mpdAttributes.locations,representationInfo:flatten(periods.map(toAdaptationSets(mpdAttributes,mpdBaseUrls)))}},stringToMpdXml=manifestString=>{if(""===manifestString)throw new Error(errors_DASH_EMPTY_MANIFEST);const parser=new DOMParser;let xml,mpd;try{xml=parser.parseFromString(manifestString,"application/xml"),mpd=xml&&"MPD"===xml.documentElement.tagName?xml.documentElement:null}catch(e){}if(!mpd||mpd&&mpd.getElementsByTagName("parsererror").length>0)throw new Error(errors_DASH_INVALID_XML);return mpd},parseUTCTiming=manifestString=>(mpd=>{const UTCTimingNode=findChildren(mpd,"UTCTiming")[0];if(!UTCTimingNode)return null;const attributes=parseAttributes(UTCTimingNode);switch(attributes.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":attributes.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":attributes.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":attributes.method="DIRECT",attributes.value=Date.parse(attributes.value);break;default:throw new Error(errors_UNSUPPORTED_UTC_TIMING_SCHEME)}return attributes})(stringToMpdXml(manifestString));var MAX_UINT32=Math.pow(2,32),getUint64=function(uint8){var value,dv=new DataView(uint8.buffer,uint8.byteOffset,uint8.byteLength);return dv.getBigUint64?(value=dv.getBigUint64(0))0;i+=12,referenceCount--)result.references.push({referenceType:(128&data[i])>>>7,referencedSize:2147483647&view.getUint32(i),subsegmentDuration:view.getUint32(i+4),startsWithSap:!!(128&data[i+8]),sapType:(112&data[i+8])>>>4,sapDeltaTime:268435455&view.getUint32(i+8)});return result},ID3=toUint8([73,68,51]),getId3Offset=function getId3Offset(bytes,offset){return void 0===offset&&(offset=0),(bytes=toUint8(bytes)).length-offset<10||!bytesMatch(bytes,ID3,{offset:offset})?offset:(offset+=function(bytes,offset){void 0===offset&&(offset=0);var flags=(bytes=toUint8(bytes))[offset+5],returnSize=bytes[offset+6]<<21|bytes[offset+7]<<14|bytes[offset+8]<<7|bytes[offset+9];return(16&flags)>>4?returnSize+20:returnSize+10}(bytes,offset),getId3Offset(bytes,offset))},normalizePath$1=function(path){return"string"==typeof path?stringToBytes(path):path},findBox=function findBox(bytes,paths,complete){void 0===complete&&(complete=!1),paths=function(paths){return Array.isArray(paths)?paths.map((function(p){return normalizePath$1(p)})):[normalizePath$1(paths)]}(paths),bytes=toUint8(bytes);var results=[];if(!paths.length)return results;for(var i=0;i>>0,type=bytes.subarray(i+4,i+8);if(0===size)break;var end=i+size;if(end>bytes.length){if(complete)break;end=bytes.length}var data=bytes.subarray(i+8,end);bytesMatch(type,paths[0])&&(1===paths.length?results.push(data):results.push.apply(results,findBox(data,paths.slice(1),complete))),i=end}return results},EBML_TAGS={EBML:toUint8([26,69,223,163]),DocType:toUint8([66,130]),Segment:toUint8([24,83,128,103]),SegmentInfo:toUint8([21,73,169,102]),Tracks:toUint8([22,84,174,107]),Track:toUint8([174]),TrackNumber:toUint8([215]),DefaultDuration:toUint8([35,227,131]),TrackEntry:toUint8([174]),TrackType:toUint8([131]),FlagDefault:toUint8([136]),CodecID:toUint8([134]),CodecPrivate:toUint8([99,162]),VideoTrack:toUint8([224]),AudioTrack:toUint8([225]),Cluster:toUint8([31,67,182,117]),Timestamp:toUint8([231]),TimestampScale:toUint8([42,215,177]),BlockGroup:toUint8([160]),BlockDuration:toUint8([155]),Block:toUint8([161]),SimpleBlock:toUint8([163])},LENGTH_TABLE=[128,64,32,16,8,4,2,1],getvint=function(bytes,offset,removeLength,signed){void 0===removeLength&&(removeLength=!0),void 0===signed&&(signed=!1);var length=function(byte){for(var len=1,i=0;i=bytes.length)return bytes.length;var innerid=getvint(bytes,offset,!1);if(bytesMatch(id.bytes,innerid.bytes))return offset;var dataHeader=getvint(bytes,offset+innerid.length);return getInfinityDataSize(id,bytes,offset+dataHeader.length+dataHeader.value+innerid.length)},findEbml=function findEbml(bytes,paths){paths=function(paths){return Array.isArray(paths)?paths.map((function(p){return normalizePath(p)})):[normalizePath(paths)]}(paths),bytes=toUint8(bytes);var results=[];if(!paths.length)return results;for(var i=0;ibytes.length?bytes.length:dataStart+dataHeader.value,data=bytes.subarray(dataStart,dataEnd);bytesMatch(paths[0],id.bytes)&&(1===paths.length?results.push(data):results=results.concat(findEbml(data,paths.slice(1)))),i+=id.length+dataHeader.length+data.length}return results},NAL_TYPE_ONE=toUint8([0,0,0,1]),NAL_TYPE_TWO=toUint8([0,0,1]),EMULATION_PREVENTION=toUint8([0,0,3]),discardEmulationPreventionBytes=function(bytes){for(var positions=[],i=1;i>1&63),-1!==types.indexOf(nalType)&&(nalStart=i+nalOffset),i+=nalOffset+("h264"===dataType?1:2)}else i++}return bytes.subarray(0,0)},CONSTANTS={webm:toUint8([119,101,98,109]),matroska:toUint8([109,97,116,114,111,115,107,97]),flac:toUint8([102,76,97,67]),ogg:toUint8([79,103,103,83]),ac3:toUint8([11,119]),riff:toUint8([82,73,70,70]),avi:toUint8([65,86,73]),wav:toUint8([87,65,86,69]),"3gp":toUint8([102,116,121,112,51,103]),mp4:toUint8([102,116,121,112]),fmp4:toUint8([115,116,121,112]),mov:toUint8([102,116,121,112,113,116]),moov:toUint8([109,111,111,118]),moof:toUint8([109,111,111,102])},_isLikely={aac:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,[255,16],{offset:offset,mask:[255,22]})},mp3:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,[255,2],{offset:offset,mask:[255,6]})},webm:function(bytes){var docType=findEbml(bytes,[EBML_TAGS.EBML,EBML_TAGS.DocType])[0];return bytesMatch(docType,CONSTANTS.webm)},mkv:function(bytes){var docType=findEbml(bytes,[EBML_TAGS.EBML,EBML_TAGS.DocType])[0];return bytesMatch(docType,CONSTANTS.matroska)},mp4:function(bytes){return!_isLikely["3gp"](bytes)&&!_isLikely.mov(bytes)&&(!(!bytesMatch(bytes,CONSTANTS.mp4,{offset:4})&&!bytesMatch(bytes,CONSTANTS.fmp4,{offset:4}))||(!(!bytesMatch(bytes,CONSTANTS.moof,{offset:4})&&!bytesMatch(bytes,CONSTANTS.moov,{offset:4}))||void 0))},mov:function(bytes){return bytesMatch(bytes,CONSTANTS.mov,{offset:4})},"3gp":function(bytes){return bytesMatch(bytes,CONSTANTS["3gp"],{offset:4})},ac3:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,CONSTANTS.ac3,{offset:offset})},ts:function(bytes){if(bytes.length<189&&bytes.length>=1)return 71===bytes[0];for(var i=0;i+188req&&req.responseURL&&url!==req.responseURL?req.responseURL:url,logger=source=>videojs.log.debug?videojs.log.debug.bind(videojs,"VHS:","".concat(source," >")):function(){};function merge(){const context=videojs.obj||videojs,fn=context.merge||context.mergeOptions;for(var _len24=arguments.length,args=new Array(_len24),_key24=0;_key24<_len24;_key24++)args[_key24]=arguments[_key24];return fn.apply(context,args)}function createTimeRanges(){const context=videojs.time||videojs,fn=context.createTimeRanges||context.createTimeRanges;for(var _len25=arguments.length,args=new Array(_len25),_key25=0;_key25<_len25;_key25++)args[_key25]=arguments[_key25];return fn.apply(context,args)}const filterRanges=function(timeRanges,predicate){const results=[];let i;if(timeRanges&&timeRanges.length)for(i=0;i=time}))},findNextRange=function(timeRanges,time){return filterRanges(timeRanges,(function(start){return start-.03333333333333333>=time}))},printableRange=range=>{const strArr=[];if(!range||!range.length)return"";for(let i=0;i "+range.end(i));return strArr.join(", ")},timeRangesToArray=timeRanges=>{const timeRangesList=[];for(let i=0;iend||(time+=startTime>start&&startTime<=end?end-startTime:end-start)}return time},segmentDurationWithParts=(playlist,segment)=>{if(!segment.preload)return segment.duration;let result=0;return(segment.parts||[]).forEach((function(p){result+=p.duration})),(segment.preloadHints||[]).forEach((function(p){"PART"===p.type&&(result+=playlist.partTargetDuration)})),result},getPartsAndSegments=playlist=>(playlist.segments||[]).reduce(((acc,segment,si)=>(segment.parts?segment.parts.forEach((function(part,pi){acc.push({duration:part.duration,segmentIndex:si,partIndex:pi,part:part,segment:segment})})):acc.push({duration:segment.duration,segmentIndex:si,partIndex:null,segment:segment,part:null}),acc)),[]),getLastParts=media=>{const lastSegment=media.segments&&media.segments.length&&media.segments[media.segments.length-1];return lastSegment&&lastSegment.parts||[]},getKnownPartCount=_ref28=>{let{preloadSegment:preloadSegment}=_ref28;if(!preloadSegment)return;const{parts:parts,preloadHints:preloadHints}=preloadSegment;let partCount=(preloadHints||[]).reduce(((count,hint)=>count+("PART"===hint.type?1:0)),0);return partCount+=parts&&parts.length?parts.length:0,partCount},liveEdgeDelay=(main,media)=>{if(media.endList)return 0;if(main&&main.suggestedPresentationDelay)return main.suggestedPresentationDelay;const hasParts=getLastParts(media).length>0;return hasParts&&media.serverControl&&media.serverControl.partHoldBack?media.serverControl.partHoldBack:hasParts&&media.partTargetDuration?3*media.partTargetDuration:media.serverControl&&media.serverControl.holdBack?media.serverControl.holdBack:media.targetDuration?3*media.targetDuration:0},intervalDuration=function(playlist,endSequence,expired){if(void 0===endSequence&&(endSequence=playlist.mediaSequence+playlist.segments.length),endSequenceendIndex&&([startIndex,endIndex]=[endIndex,startIndex]),startIndex<0){for(let i=startIndex;iDate.now()},isIncompatible=function(playlist){return playlist.excludeUntil&&playlist.excludeUntil===1/0},isEnabled=function(playlist){const excluded=isExcluded(playlist);return!playlist.disabled&&!excluded},hasAttribute=function(attr,playlist){return playlist.attributes&&playlist.attributes[attr]},isLowestEnabledRendition=(main,media)=>{if(1===main.playlists.length)return!0;const currentBandwidth=media.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===main.playlists.filter((playlist=>!!isEnabled(playlist)&&(playlist.attributes.BANDWIDTH||0)!(!a&&!b||!a&&b||a&&!b)&&(a===b||(!(!a.id||!b.id||a.id!==b.id)||(!(!a.resolvedUri||!b.resolvedUri||a.resolvedUri!==b.resolvedUri)||!(!a.uri||!b.uri||a.uri!==b.uri)))),someAudioVariant=function(main,callback){const AUDIO=main&&main.mediaGroups&&main.mediaGroups.AUDIO||{};let found=!1;for(const groupName in AUDIO){for(const label in AUDIO[groupName])if(found=callback(AUDIO[groupName][label]),found)break;if(found)break}return!!found},isAudioOnly=main=>{if(!main||!main.playlists||!main.playlists.length){return someAudioVariant(main,(variant=>variant.playlists&&variant.playlists.length||variant.uri))}for(let i=0;iisAudioCodec(c))))continue;if(!someAudioVariant(main,(variant=>playlistMatch(playlist,variant))))return!1}return!0};var Playlist={liveEdgeDelay:liveEdgeDelay,duration:duration,seekable:function(playlist,expired,liveEdgePadding){const seekableStart=expired||0,seekableEnd=playlistEnd(playlist,expired,!0,liveEdgePadding);return null===seekableEnd?createTimeRanges():createTimeRanges(seekableStart,seekableEnd)},getMediaInfoForTime:function(_ref30){let{playlist:playlist,currentTime:currentTime,startingSegmentIndex:startingSegmentIndex,startingPartIndex:startingPartIndex,startTime:startTime,exactManifestTimings:exactManifestTimings}=_ref30,time=currentTime-startTime;const partsAndSegments=getPartsAndSegments(playlist);let startIndex=0;for(let i=0;i0)for(let i=startIndex-1;i>=0;i--){const partAndSegment=partsAndSegments[i];if(time+=partAndSegment.duration,exactManifestTimings){if(time<0)continue}else if(time+.03333333333333333<=0)continue;return{partIndex:partAndSegment.partIndex,segmentIndex:partAndSegment.segmentIndex,startTime:startTime-sumDurations({defaultDuration:playlist.targetDuration,durationList:partsAndSegments,startIndex:startIndex,endIndex:i})}}return{partIndex:partsAndSegments[0]&&partsAndSegments[0].partIndex||null,segmentIndex:partsAndSegments[0]&&partsAndSegments[0].segmentIndex||0,startTime:currentTime}}if(startIndex<0){for(let i=startIndex;i<0;i++)if(time-=playlist.targetDuration,time<0)return{partIndex:partsAndSegments[0]&&partsAndSegments[0].partIndex||null,segmentIndex:partsAndSegments[0]&&partsAndSegments[0].segmentIndex||0,startTime:currentTime};startIndex=0}for(let i=startIndex;i0)continue}else if(time-.03333333333333333>=0)continue;return{partIndex:partAndSegment.partIndex,segmentIndex:partAndSegment.segmentIndex,startTime:startTime+sumDurations({defaultDuration:playlist.targetDuration,durationList:partsAndSegments,startIndex:startIndex,endIndex:i})}}return{segmentIndex:partsAndSegments[partsAndSegments.length-1].segmentIndex,partIndex:partsAndSegments[partsAndSegments.length-1].partIndex,startTime:currentTime}},isEnabled:isEnabled,isDisabled:function(playlist){return playlist.disabled},isExcluded:isExcluded,isIncompatible:isIncompatible,playlistEnd:playlistEnd,isAes:function(media){for(let i=0;i3&&void 0!==arguments[3]?arguments[3]:0;if(!hasAttribute("BANDWIDTH",playlist))return NaN;const size=segmentDuration*playlist.attributes.BANDWIDTH;return(size-8*bytesReceived)/bandwidth},isLowestEnabledRendition:isLowestEnabledRendition,isAudioOnly:isAudioOnly,playlistMatch:playlistMatch,segmentDurationWithParts:segmentDurationWithParts};const{log:log}=videojs,createPlaylistID=(index,uri)=>"".concat(index,"-").concat(uri),groupID=(type,group,label)=>"placeholder-uri-".concat(type,"-").concat(group,"-").concat(label),forEachMediaGroup=(main,callback)=>{main.mediaGroups&&["AUDIO","SUBTITLES"].forEach((mediaType=>{if(main.mediaGroups[mediaType])for(const groupKey in main.mediaGroups[mediaType])for(const labelKey in main.mediaGroups[mediaType][groupKey]){const mediaProperties=main.mediaGroups[mediaType][groupKey][labelKey];callback(mediaProperties,mediaType,groupKey,labelKey)}}))},setupMediaPlaylist=_ref32=>{let{playlist:playlist,uri:uri,id:id}=_ref32;playlist.id=id,playlist.playlistErrors_=0,uri&&(playlist.uri=uri),playlist.attributes=playlist.attributes||{}},setupMediaPlaylists=main=>{let i=main.playlists.length;for(;i--;){const playlist=main.playlists[i];setupMediaPlaylist({playlist:playlist,id:createPlaylistID(i,playlist.uri)}),playlist.resolvedUri=resolveUrl(main.uri,playlist.uri),main.playlists[playlist.id]=playlist,main.playlists[playlist.uri]=playlist,playlist.attributes.BANDWIDTH||log.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute.")}},resolveMediaGroupUris=main=>{forEachMediaGroup(main,(properties=>{properties.uri&&(properties.resolvedUri=resolveUrl(main.uri,properties.uri))}))},addPropertiesToMain=function(main,uri){let createGroupID=arguments.length>2&&void 0!==arguments[2]?arguments[2]:groupID;main.uri=uri;for(let i=0;i{if(!properties.playlists||!properties.playlists.length){if(audioOnlyMain&&"AUDIO"===mediaType&&!properties.uri)for(let i=0;i{if(!a)return b;const result=merge(a,b);if(a.preloadHints&&!b.preloadHints&&delete result.preloadHints,a.parts&&!b.parts)delete result.parts;else if(a.parts&&b.parts)for(let i=0;i{const oldSegments=original.slice(),newSegments=update.slice();offset=offset||0;const result=[];let currentMap;for(let newIndex=0;newIndex{!segment.resolvedUri&&segment.uri&&(segment.resolvedUri=resolveUrl(baseUri,segment.uri)),segment.key&&!segment.key.resolvedUri&&(segment.key.resolvedUri=resolveUrl(baseUri,segment.key.uri)),segment.map&&!segment.map.resolvedUri&&(segment.map.resolvedUri=resolveUrl(baseUri,segment.map.uri)),segment.map&&segment.map.key&&!segment.map.key.resolvedUri&&(segment.map.key.resolvedUri=resolveUrl(baseUri,segment.map.key.uri)),segment.parts&&segment.parts.length&&segment.parts.forEach((p=>{p.resolvedUri||(p.resolvedUri=resolveUrl(baseUri,p.uri))})),segment.preloadHints&&segment.preloadHints.length&&segment.preloadHints.forEach((p=>{p.resolvedUri||(p.resolvedUri=resolveUrl(baseUri,p.uri))}))},getAllSegments=function(media){const segments=media.segments||[],preloadSegment=media.preloadSegment;if(preloadSegment&&preloadSegment.parts&&preloadSegment.parts.length){if(preloadSegment.preloadHints)for(let i=0;ia===b||a.segments&&b.segments&&a.segments.length===b.segments.length&&a.endList===b.endList&&a.mediaSequence===b.mediaSequence&&a.preloadSegment===b.preloadSegment,updateMain$1=function(main,newMedia){let unchangedCheck=arguments.length>2&&void 0!==arguments[2]?arguments[2]:isPlaylistUnchanged;const result=merge(main,{}),oldMedia=result.playlists[newMedia.id];if(!oldMedia)return null;if(unchangedCheck(oldMedia,newMedia))return null;newMedia.segments=getAllSegments(newMedia);const mergedPlaylist=merge(oldMedia,newMedia);if(mergedPlaylist.preloadSegment&&!newMedia.preloadSegment&&delete mergedPlaylist.preloadSegment,oldMedia.segments){if(newMedia.skip){newMedia.segments=newMedia.segments||[];for(let i=0;i{resolveSegmentUris(segment,mergedPlaylist.resolvedUri)}));for(let i=0;i{if(properties.playlists)for(let i=0;i{const segments=media.segments||[],lastSegment=segments[segments.length-1],lastPart=lastSegment&&lastSegment.parts&&lastSegment.parts[lastSegment.parts.length-1],lastDuration=lastPart&&lastPart.duration||lastSegment&&lastSegment.duration;return update&&lastDuration?1e3*lastDuration:500*(media.partTargetDuration||media.targetDuration||10)};class PlaylistLoader extends EventTarget$1{constructor(src,vhs){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(super(),!src)throw new Error("A non-empty playlist URL or object is required");this.logger_=logger("PlaylistLoader");const{withCredentials:withCredentials=!1}=options;this.src=src,this.vhs_=vhs,this.withCredentials=withCredentials;const vhsOptions=vhs.options_;this.customTagParsers=vhsOptions&&vhsOptions.customTagParsers||[],this.customTagMappers=vhsOptions&&vhsOptions.customTagMappers||[],this.llhls=vhsOptions&&vhsOptions.llhls,this.state="HAVE_NOTHING",this.handleMediaupdatetimeout_=this.handleMediaupdatetimeout_.bind(this),this.on("mediaupdatetimeout",this.handleMediaupdatetimeout_)}handleMediaupdatetimeout_(){if("HAVE_METADATA"!==this.state)return;const media=this.media();let uri=resolveUrl(this.main.uri,media.uri);this.llhls&&(uri=((uri,media)=>{if(media.endList||!media.serverControl)return uri;const parameters={};if(media.serverControl.canBlockReload){const{preloadSegment:preloadSegment}=media;let nextMSN=media.mediaSequence+media.segments.length;if(preloadSegment){const parts=preloadSegment.parts||[],nextPart=getKnownPartCount(media)-1;nextPart>-1&&nextPart!==parts.length-1&&(parameters._HLS_part=nextPart),(nextPart>-1||parts.length)&&nextMSN--}parameters._HLS_msn=nextMSN}if(media.serverControl&&media.serverControl.canSkipUntil&&(parameters._HLS_skip=media.serverControl.canSkipDateranges?"v2":"YES"),Object.keys(parameters).length){const parsedUri=new window.URL(uri);["_HLS_skip","_HLS_msn","_HLS_part"].forEach((function(name){parameters.hasOwnProperty(name)&&parsedUri.searchParams.set(name,parameters[name])})),uri=parsedUri.toString()}return uri})(uri,media)),this.state="HAVE_CURRENT_METADATA",this.request=this.vhs_.xhr({uri:uri,withCredentials:this.withCredentials},((error,req)=>{if(this.request)return error?this.playlistRequestError(this.request,this.media(),"HAVE_METADATA"):void this.haveMetadata({playlistString:this.request.responseText,url:this.media().uri,id:this.media().id})}))}playlistRequestError(xhr,playlist,startingState){const{uri:uri,id:id}=playlist;this.request=null,startingState&&(this.state=startingState),this.error={playlist:this.main.playlists[id],status:xhr.status,message:"HLS playlist request error at URL: ".concat(uri,"."),responseText:xhr.responseText,code:xhr.status>=500?4:2},this.trigger("error")}parseManifest_(_ref33){let{url:url,manifestString:manifestString}=_ref33;return(_ref31=>{let{onwarn:onwarn,oninfo:oninfo,manifestString:manifestString,customTagParsers:customTagParsers=[],customTagMappers:customTagMappers=[],llhls:llhls}=_ref31;const parser=new Parser;onwarn&&parser.on("warn",onwarn),oninfo&&parser.on("info",oninfo),customTagParsers.forEach((customParser=>parser.addParser(customParser))),customTagMappers.forEach((mapper=>parser.addTagMapper(mapper))),parser.push(manifestString),parser.end();const manifest=parser.manifest;if(llhls||(["preloadSegment","skip","serverControl","renditionReports","partInf","partTargetDuration"].forEach((function(k){manifest.hasOwnProperty(k)&&delete manifest[k]})),manifest.segments&&manifest.segments.forEach((function(segment){["parts","preloadHints"].forEach((function(k){segment.hasOwnProperty(k)&&delete segment[k]}))}))),!manifest.targetDuration){let targetDuration=10;manifest.segments&&manifest.segments.length&&(targetDuration=manifest.segments.reduce(((acc,s)=>Math.max(acc,s.duration)),0)),onwarn&&onwarn("manifest has no targetDuration defaulting to ".concat(targetDuration)),manifest.targetDuration=targetDuration}const parts=getLastParts(manifest);if(parts.length&&!manifest.partTargetDuration){const partTargetDuration=parts.reduce(((acc,p)=>Math.max(acc,p.duration)),0);onwarn&&(onwarn("manifest has no partTargetDuration defaulting to ".concat(partTargetDuration)),log.error("LL-HLS manifest has parts but lacks required #EXT-X-PART-INF:PART-TARGET value. See https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-09#section-4.4.3.7. Playback is not guaranteed.")),manifest.partTargetDuration=partTargetDuration}return manifest})({onwarn:_ref34=>{let{message:message}=_ref34;return this.logger_("m3u8-parser warn for ".concat(url,": ").concat(message))},oninfo:_ref35=>{let{message:message}=_ref35;return this.logger_("m3u8-parser info for ".concat(url,": ").concat(message))},manifestString:manifestString,customTagParsers:this.customTagParsers,customTagMappers:this.customTagMappers,llhls:this.llhls})}haveMetadata(_ref36){let{playlistString:playlistString,playlistObject:playlistObject,url:url,id:id}=_ref36;this.request=null,this.state="HAVE_METADATA";const playlist=playlistObject||this.parseManifest_({url:url,manifestString:playlistString});playlist.lastRequest=Date.now(),setupMediaPlaylist({playlist:playlist,uri:url,id:id});const update=updateMain$1(this.main,playlist);this.targetDuration=playlist.partTargetDuration||playlist.targetDuration,this.pendingMedia_=null,update?(this.main=update,this.media_=this.main.playlists[id]):this.trigger("playlistunchanged"),this.updateMediaUpdateTimeout_(refreshDelay(this.media(),!!update)),this.trigger("loadedplaylist")}dispose(){this.trigger("dispose"),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),window.clearTimeout(this.finalRenditionTimeout),this.off()}stopRequest(){if(this.request){const oldRequest=this.request;this.request=null,oldRequest.onreadystatechange=null,oldRequest.abort()}}media(playlist,shouldDelay){if(!playlist)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof playlist){if(!this.main.playlists[playlist])throw new Error("Unknown playlist URI: "+playlist);playlist=this.main.playlists[playlist]}if(window.clearTimeout(this.finalRenditionTimeout),shouldDelay){const delay=(playlist.partTargetDuration||playlist.targetDuration)/2*1e3||5e3;return void(this.finalRenditionTimeout=window.setTimeout(this.media.bind(this,playlist,!1),delay))}const startingState=this.state,mediaChange=!this.media_||playlist.id!==this.media_.id,mainPlaylistRef=this.main.playlists[playlist.id];if(mainPlaylistRef&&mainPlaylistRef.endList||playlist.endList&&playlist.segments.length)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=playlist,void(mediaChange&&(this.trigger("mediachanging"),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")));if(this.updateMediaUpdateTimeout_(refreshDelay(playlist,!0)),mediaChange){if(this.state="SWITCHING_MEDIA",this.request){if(playlist.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.pendingMedia_=playlist,this.request=this.vhs_.xhr({uri:playlist.resolvedUri,withCredentials:this.withCredentials},((error,req)=>{if(this.request){if(playlist.lastRequest=Date.now(),playlist.resolvedUri=resolveManifestRedirect(playlist.resolvedUri,req),error)return this.playlistRequestError(this.request,playlist,startingState);this.haveMetadata({playlistString:req.responseText,url:playlist.uri,id:playlist.id}),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")}}))}}pause(){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.stopRequest(),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MAIN_MANIFEST":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")}load(shouldDelay){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null);const media=this.media();if(shouldDelay){const delay=media?(media.partTargetDuration||media.targetDuration)/2*1e3:5e3;this.mediaUpdateTimeout=window.setTimeout((()=>{this.mediaUpdateTimeout=null,this.load()}),delay)}else this.started?media&&!media.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()}updateMediaUpdateTimeout_(delay){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.media()&&!this.media().endList&&(this.mediaUpdateTimeout=window.setTimeout((()=>{this.mediaUpdateTimeout=null,this.trigger("mediaupdatetimeout"),this.updateMediaUpdateTimeout_(delay)}),delay))}start(){if(this.started=!0,"object"==typeof this.src)return this.src.uri||(this.src.uri=window.location.href),this.src.resolvedUri=this.src.uri,void setTimeout((()=>{this.setupInitialPlaylist(this.src)}),0);this.request=this.vhs_.xhr({uri:this.src,withCredentials:this.withCredentials},((error,req)=>{if(!this.request)return;if(this.request=null,error)return this.error={status:req.status,message:"HLS playlist request error at URL: ".concat(this.src,"."),responseText:req.responseText,code:2},"HAVE_NOTHING"===this.state&&(this.started=!1),this.trigger("error");this.src=resolveManifestRedirect(this.src,req);const manifest=this.parseManifest_({manifestString:req.responseText,url:this.src});this.setupInitialPlaylist(manifest)}))}srcUri(){return"string"==typeof this.src?this.src:this.src.uri}setupInitialPlaylist(manifest){if(this.state="HAVE_MAIN_MANIFEST",manifest.playlists)return this.main=manifest,addPropertiesToMain(this.main,this.srcUri()),manifest.playlists.forEach((playlist=>{playlist.segments=getAllSegments(playlist),playlist.segments.forEach((segment=>{resolveSegmentUris(segment,playlist.resolvedUri)}))})),this.trigger("loadedplaylist"),void(this.request||this.media(this.main.playlists[0]));const uri=this.srcUri()||window.location.href;this.main=((media,uri)=>{const id=createPlaylistID(0,uri),main={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:window.location.href,resolvedUri:window.location.href,playlists:[{uri:uri,id:id,resolvedUri:uri,attributes:{}}]};return main.playlists[id]=main.playlists[0],main.playlists[uri]=main.playlists[0],main})(0,uri),this.haveMetadata({playlistObject:manifest,url:uri,id:this.main.playlists[0].id}),this.trigger("loadedmetadata")}}const{xhr:videojsXHR}=videojs,callbackWrapper=function(request,error,response,callback){const reqResponse="arraybuffer"===request.responseType?request.response:request.responseText;!error&&reqResponse&&(request.responseTime=Date.now(),request.roundTripTime=request.responseTime-request.requestTime,request.bytesReceived=reqResponse.byteLength||reqResponse.length,request.bandwidth||(request.bandwidth=Math.floor(request.bytesReceived/request.roundTripTime*8*1e3))),response.headers&&(request.responseHeaders=response.headers),error&&"ETIMEDOUT"===error.code&&(request.timedout=!0),error||request.aborted||200===response.statusCode||206===response.statusCode||0===response.statusCode||(error=new Error("XHR Failed with a response of: "+(request&&(reqResponse||request.responseText)))),callback(error,request)},xhrFactory=function(){const xhr=function XhrFunction(options,callback){options=merge({timeout:45e3},options);const beforeRequest=XhrFunction.beforeRequest||videojs.Vhs.xhr.beforeRequest;if(beforeRequest&&"function"==typeof beforeRequest){const newOptions=beforeRequest(options);newOptions&&(options=newOptions)}const request=(!0===videojs.Vhs.xhr.original?videojsXHR:videojs.Vhs.xhr)(options,(function(error,response){return callbackWrapper(request,error,response,callback)})),originalAbort=request.abort;return request.abort=function(){return request.aborted=!0,originalAbort.apply(request,arguments)},request.uri=options.uri,request.requestTime=Date.now(),request};return xhr.original=!0,xhr},segmentXhrHeaders=function(segment){const headers={};return segment.byterange&&(headers.Range=function(byterange){let byterangeEnd;const byterangeStart=byterange.offset;return byterangeEnd="bigint"==typeof byterange.offset||"bigint"==typeof byterange.length?window.BigInt(byterange.offset)+window.BigInt(byterange.length)-window.BigInt(1):byterange.offset+byterange.length-1,"bytes="+byterangeStart+"-"+byterangeEnd}(segment.byterange)),headers},textRange=function(range,i){return range.start(i)+"-"+range.end(i)},formatHexString=function(e,i){const value=e.toString(16);return"00".substring(0,2-value.length)+value+(i%2?" ":"")},formatAsciiString=function(e){return e>=32&&e<126?String.fromCharCode(e):"."},createTransferableMessage=function(message){const transferable={};return Object.keys(message).forEach((key=>{const value=message[key];isArrayBufferView(value)?transferable[key]={bytes:value.buffer,byteOffset:value.byteOffset,byteLength:value.byteLength}:transferable[key]=value})),transferable},initSegmentId=function(initSegment){const byterange=initSegment.byterange||{length:1/0,offset:0};return[byterange.length,byterange.offset,initSegment.resolvedUri].join(",")},segmentKeyId=function(key){return key.resolvedUri},hexDump=data=>{const bytes=Array.prototype.slice.call(data);let hex,ascii,result="";for(let j=0;j{let{bytes:bytes}=_ref37;return hexDump(bytes)},textRanges:ranges=>{let i,result="";for(i=0;i{let{playlist:playlist,time:time,callback:callback}=_ref38;if(!callback)throw new Error("getProgramTime: callback must be provided");if(!playlist||void 0===time)return callback({message:"getProgramTime: playlist and time must be provided"});const matchedSegment=((time,playlist)=>{if(!playlist||!playlist.segments||0===playlist.segments.length)return null;let segment,segmentEnd=0;for(let i=0;isegmentEnd){if(time>segmentEnd+.25*lastSegment.duration)return null;segment=lastSegment}return{segment:segment,estimatedStart:segment.videoTimingInfo?segment.videoTimingInfo.transmuxedPresentationStart:segmentEnd-segment.duration,type:segment.videoTimingInfo?"accurate":"estimate"}})(time,playlist);if(!matchedSegment)return callback({message:"valid programTime was not found"});if("estimate"===matchedSegment.type)return callback({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:matchedSegment.estimatedStart});const programTimeObject={mediaSeconds:time},programTime=((playerTime,segment)=>{if(!segment.dateTimeObject)return null;const transmuxerPrependedSeconds=segment.videoTimingInfo.transmuxerPrependedSeconds,offsetFromSegmentStart=playerTime-(segment.videoTimingInfo.transmuxedPresentationStart+transmuxerPrependedSeconds);return new Date(segment.dateTimeObject.getTime()+1e3*offsetFromSegmentStart)})(time,matchedSegment.segment);return programTime&&(programTimeObject.programDateTime=programTime.toISOString()),callback(null,programTimeObject)},seekToProgramTime=_ref39=>{let{programTime:programTime,playlist:playlist,retryCount:retryCount=2,seekTo:seekTo,pauseAfterSeek:pauseAfterSeek=!0,tech:tech,callback:callback}=_ref39;if(!callback)throw new Error("seekToProgramTime: callback must be provided");if(void 0===programTime||!playlist||!seekTo)return callback({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"});if(!playlist.endList&&!tech.hasStarted_)return callback({message:"player must be playing a live stream to start buffering"});if(!(playlist=>{if(!playlist.segments||0===playlist.segments.length)return!1;for(let i=0;i{let dateTimeObject;try{dateTimeObject=new Date(programTime)}catch(e){return null}if(!playlist||!playlist.segments||0===playlist.segments.length)return null;let segment=playlist.segments[0];if(dateTimeObjectnew Date(lastSegmentStart.getTime()+1e3*lastSegmentDuration)?null:(dateTimeObject>lastSegmentStart&&(segment=lastSegment),{segment:segment,estimatedStart:segment.videoTimingInfo?segment.videoTimingInfo.transmuxedPresentationStart:Playlist.duration(playlist,playlist.mediaSequence+playlist.segments.indexOf(segment)),type:segment.videoTimingInfo?"accurate":"estimate"})})(programTime,playlist);if(!matchedSegment)return callback({message:"".concat(programTime," was not found in the stream")});const segment=matchedSegment.segment,mediaOffset=((comparisonTimeStamp,programTime)=>{let segmentDateTime,programDateTime;try{segmentDateTime=new Date(comparisonTimeStamp),programDateTime=new Date(programTime)}catch(e){}const segmentTimeEpoch=segmentDateTime.getTime();return(programDateTime.getTime()-segmentTimeEpoch)/1e3})(segment.dateTimeObject,programTime);if("estimate"===matchedSegment.type)return 0===retryCount?callback({message:"".concat(programTime," is not buffered yet. Try again")}):(seekTo(matchedSegment.estimatedStart+mediaOffset),void tech.one("seeked",(()=>{seekToProgramTime({programTime:programTime,playlist:playlist,retryCount:retryCount-1,seekTo:seekTo,pauseAfterSeek:pauseAfterSeek,tech:tech,callback:callback})})));const seekToTime=segment.start+mediaOffset;tech.one("seeked",(()=>callback(null,tech.currentTime()))),pauseAfterSeek&&tech.pause(),seekTo(seekToTime)},callbackOnCompleted=(request,cb)=>{if(4===request.readyState)return cb()},containerRequest=(uri,xhr,cb)=>{let id3Offset,bytes=[],finished=!1;const endRequestAndCallback=function(err,req,type,_bytes){return req.abort(),finished=!0,cb(err,req,type,_bytes)},progressListener=function(error,request){if(finished)return;if(error)return endRequestAndCallback(error,request,"",bytes);const newPart=request.responseText.substring(bytes&&bytes.byteLength||0,request.responseText.length);if(bytes=function(){for(var _len=arguments.length,buffers=new Array(_len),_key=0;_key<_len;_key++)buffers[_key]=arguments[_key];if(buffers=buffers.filter((function(b){return b&&(b.byteLength||b.length)&&"string"!=typeof b})),buffers.length<=1)return toUint8(buffers[0]);var totalLen=buffers.reduce((function(total,buf,i){return total+(buf.byteLength||buf.length)}),0),tempBuffer=new Uint8Array(totalLen),offset=0;return buffers.forEach((function(buf){buf=toUint8(buf),tempBuffer.set(buf,offset),offset+=buf.byteLength})),tempBuffer}(bytes,stringToBytes(newPart,!0)),id3Offset=id3Offset||getId3Offset(bytes),bytes.length<10||id3Offset&&bytes.lengthendRequestAndCallback(error,request,"",bytes)));const type=detectContainerForBytes(bytes);return"ts"===type&&bytes.length<188||!type&&bytes.length<376?callbackOnCompleted(request,(()=>endRequestAndCallback(error,request,"",bytes))):endRequestAndCallback(null,request,type,bytes)},options={uri:uri,beforeSend(request){request.overrideMimeType("text/plain; charset=x-user-defined"),request.addEventListener("progress",(function(_ref40){let{total:total,loaded:loaded}=_ref40;return callbackWrapper(request,null,{statusCode:request.status},progressListener)}))}},request=xhr(options,(function(error,response){return callbackWrapper(request,error,response,progressListener)}));return request},{EventTarget:EventTarget}=videojs,dashPlaylistUnchanged=function(a,b){if(!isPlaylistUnchanged(a,b))return!1;if(a.sidx&&b.sidx&&(a.sidx.offset!==b.sidx.offset||a.sidx.length!==b.sidx.length))return!1;if(!a.sidx&&b.sidx||a.sidx&&!b.sidx)return!1;if(a.segments&&!b.segments||!a.segments&&b.segments)return!1;if(!a.segments&&!b.segments)return!0;for(let i=0;i{const playlistId=playlist.attributes.NAME||label;return"placeholder-uri-".concat(type,"-").concat(group,"-").concat(playlistId)},parseMainXml=_ref41=>{let{mainXml:mainXml,srcUrl:srcUrl,clientOffset:clientOffset,sidxMapping:sidxMapping,previousManifest:previousManifest}=_ref41;const manifest=function(manifestString){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const parsedManifestInfo=inheritAttributes(stringToMpdXml(manifestString),options),playlists=toPlaylists(parsedManifestInfo.representationInfo);return toM3u8({dashPlaylists:playlists,locations:parsedManifestInfo.locations,sidxMapping:options.sidxMapping,previousManifest:options.previousManifest})}(mainXml,{manifestUri:srcUrl,clientOffset:clientOffset,sidxMapping:sidxMapping,previousManifest:previousManifest});return addPropertiesToMain(manifest,srcUrl,dashGroupId),manifest},updateMain=(oldMain,newMain,sidxMapping)=>{let noChanges=!0,update=merge(oldMain,{duration:newMain.duration,minimumUpdatePeriod:newMain.minimumUpdatePeriod,timelineStarts:newMain.timelineStarts});for(let i=0;i{if(properties.playlists&&properties.playlists.length){const id=properties.playlists[0].id,playlistUpdate=updateMain$1(update,properties.playlists[0],dashPlaylistUnchanged);playlistUpdate&&(update=playlistUpdate,label in update.mediaGroups[type][group]||(update.mediaGroups[type][group][label]=properties),update.mediaGroups[type][group][label].playlists[0]=update.playlists[id],noChanges=!1)}})),((update,newMain)=>{forEachMediaGroup(update,((properties,type,group,label)=>{label in newMain.mediaGroups[type][group]||delete update.mediaGroups[type][group][label]}))})(update,newMain),newMain.minimumUpdatePeriod!==oldMain.minimumUpdatePeriod&&(noChanges=!1),noChanges?null:update},equivalentSidx=(a,b)=>(Boolean(!a.map&&!b.map)||Boolean(a.map&&b.map&&a.map.byterange.offset===b.map.byterange.offset&&a.map.byterange.length===b.map.byterange.length))&&a.uri===b.uri&&a.byterange.offset===b.byterange.offset&&a.byterange.length===b.byterange.length,compareSidxEntry=(playlists,oldSidxMapping)=>{const newSidxMapping={};for(const id in playlists){const currentSidxInfo=playlists[id].sidx;if(currentSidxInfo){const key=generateSidxKey(currentSidxInfo);if(!oldSidxMapping[key])break;const savedSidxInfo=oldSidxMapping[key].sidxInfo;equivalentSidx(savedSidxInfo,currentSidxInfo)&&(newSidxMapping[key]=oldSidxMapping[key])}}return newSidxMapping};class DashPlaylistLoader extends EventTarget{constructor(srcUrlOrPlaylist,vhs){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},mainPlaylistLoader=arguments.length>3?arguments[3]:void 0;super(),this.mainPlaylistLoader_=mainPlaylistLoader||this,mainPlaylistLoader||(this.isMain_=!0);const{withCredentials:withCredentials=!1}=options;if(this.vhs_=vhs,this.withCredentials=withCredentials,!srcUrlOrPlaylist)throw new Error("A non-empty playlist URL or object is required");this.on("minimumUpdatePeriod",(()=>{this.refreshXml_()})),this.on("mediaupdatetimeout",(()=>{this.refreshMedia_(this.media().id)})),this.state="HAVE_NOTHING",this.loadedPlaylists_={},this.logger_=logger("DashPlaylistLoader"),this.isMain_?(this.mainPlaylistLoader_.srcUrl=srcUrlOrPlaylist,this.mainPlaylistLoader_.sidxMapping_={}):this.childPlaylist_=srcUrlOrPlaylist}requestErrored_(err,request,startingState){return!this.request||(this.request=null,err?(this.error="object"!=typeof err||err instanceof Error?{status:request.status,message:"DASH request error at URL: "+request.uri,response:request.response,code:2}:err,startingState&&(this.state=startingState),this.trigger("error"),!0):void 0)}addSidxSegments_(playlist,startingState,cb){const sidxKey=playlist.sidx&&generateSidxKey(playlist.sidx);if(!playlist.sidx||!sidxKey||this.mainPlaylistLoader_.sidxMapping_[sidxKey])return void(this.mediaRequest_=window.setTimeout((()=>cb(!1)),0));const uri=resolveManifestRedirect(playlist.sidx.resolvedUri),fin=(err,request)=>{if(this.requestErrored_(err,request,startingState))return;const sidxMapping=this.mainPlaylistLoader_.sidxMapping_;let sidx;try{sidx=parseSidx_1(toUint8(request.response).subarray(8))}catch(e){return void this.requestErrored_(e,request,startingState)}return sidxMapping[sidxKey]={sidxInfo:playlist.sidx,sidx:sidx},addSidxSegmentsToPlaylist$1(playlist,sidx,playlist.sidx.resolvedUri),cb(!0)};this.request=containerRequest(uri,this.vhs_.xhr,((err,request,container,bytes)=>{if(err)return fin(err,request);if(!container||"mp4"!==container)return fin({status:request.status,message:"Unsupported ".concat(container||"unknown"," container type for sidx segment at URL: ").concat(uri),response:"",playlist:playlist,internal:!0,playlistExclusionDuration:1/0,code:2},request);const{offset:offset,length:length}=playlist.sidx.byterange;if(bytes.length>=length+offset)return fin(err,{response:bytes.subarray(offset,offset+length),status:request.status,uri:request.uri});this.request=this.vhs_.xhr({uri:uri,responseType:"arraybuffer",headers:segmentXhrHeaders({byterange:playlist.sidx.byterange})},fin)}))}dispose(){this.trigger("dispose"),this.stopRequest(),this.loadedPlaylists_={},window.clearTimeout(this.minimumUpdatePeriodTimeout_),window.clearTimeout(this.mediaRequest_),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.mediaRequest_=null,this.minimumUpdatePeriodTimeout_=null,this.mainPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.mainPlaylistLoader_.createMupOnMedia_),this.mainPlaylistLoader_.createMupOnMedia_=null),this.off()}hasPendingRequest(){return this.request||this.mediaRequest_}stopRequest(){if(this.request){const oldRequest=this.request;this.request=null,oldRequest.onreadystatechange=null,oldRequest.abort()}}media(playlist){if(!playlist)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);const startingState=this.state;if("string"==typeof playlist){if(!this.mainPlaylistLoader_.main.playlists[playlist])throw new Error("Unknown playlist URI: "+playlist);playlist=this.mainPlaylistLoader_.main.playlists[playlist]}const mediaChange=!this.media_||playlist.id!==this.media_.id;if(mediaChange&&this.loadedPlaylists_[playlist.id]&&this.loadedPlaylists_[playlist.id].endList)return this.state="HAVE_METADATA",this.media_=playlist,void(mediaChange&&(this.trigger("mediachanging"),this.trigger("mediachange")));mediaChange&&(this.media_&&this.trigger("mediachanging"),this.addSidxSegments_(playlist,startingState,(sidxChanged=>{this.haveMetadata({startingState:startingState,playlist:playlist})})))}haveMetadata(_ref42){let{startingState:startingState,playlist:playlist}=_ref42;this.state="HAVE_METADATA",this.loadedPlaylists_[playlist.id]=playlist,this.mediaRequest_=null,this.refreshMedia_(playlist.id),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")}pause(){this.mainPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.mainPlaylistLoader_.createMupOnMedia_),this.mainPlaylistLoader_.createMupOnMedia_=null),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.isMain_&&(window.clearTimeout(this.mainPlaylistLoader_.minimumUpdatePeriodTimeout_),this.mainPlaylistLoader_.minimumUpdatePeriodTimeout_=null),"HAVE_NOTHING"===this.state&&(this.started=!1)}load(isFinalRendition){window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null;const media=this.media();if(isFinalRendition){const delay=media?media.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=window.setTimeout((()=>this.load()),delay)}else this.started?media&&!media.endList?(this.isMain_&&!this.minimumUpdatePeriodTimeout_&&(this.trigger("minimumUpdatePeriod"),this.updateMinimumUpdatePeriodTimeout_()),this.trigger("mediaupdatetimeout")):this.trigger("loadedplaylist"):this.start()}start(){this.started=!0,this.isMain_?this.requestMain_(((req,mainChanged)=>{this.haveMain_(),this.hasPendingRequest()||this.media_||this.media(this.mainPlaylistLoader_.main.playlists[0])})):this.mediaRequest_=window.setTimeout((()=>this.haveMain_()),0)}requestMain_(cb){this.request=this.vhs_.xhr({uri:this.mainPlaylistLoader_.srcUrl,withCredentials:this.withCredentials},((error,req)=>{if(this.requestErrored_(error,req))return void("HAVE_NOTHING"===this.state&&(this.started=!1));const mainChanged=req.responseText!==this.mainPlaylistLoader_.mainXml_;return this.mainPlaylistLoader_.mainXml_=req.responseText,req.responseHeaders&&req.responseHeaders.date?this.mainLoaded_=Date.parse(req.responseHeaders.date):this.mainLoaded_=Date.now(),this.mainPlaylistLoader_.srcUrl=resolveManifestRedirect(this.mainPlaylistLoader_.srcUrl,req),mainChanged?(this.handleMain_(),void this.syncClientServerClock_((()=>cb(req,mainChanged)))):cb(req,mainChanged)}))}syncClientServerClock_(done){const utcTiming=parseUTCTiming(this.mainPlaylistLoader_.mainXml_);return null===utcTiming?(this.mainPlaylistLoader_.clientOffset_=this.mainLoaded_-Date.now(),done()):"DIRECT"===utcTiming.method?(this.mainPlaylistLoader_.clientOffset_=utcTiming.value-Date.now(),done()):void(this.request=this.vhs_.xhr({uri:resolveUrl(this.mainPlaylistLoader_.srcUrl,utcTiming.value),method:utcTiming.method,withCredentials:this.withCredentials},((error,req)=>{if(!this.request)return;if(error)return this.mainPlaylistLoader_.clientOffset_=this.mainLoaded_-Date.now(),done();let serverTime;serverTime="HEAD"===utcTiming.method?req.responseHeaders&&req.responseHeaders.date?Date.parse(req.responseHeaders.date):this.mainLoaded_:Date.parse(req.responseText),this.mainPlaylistLoader_.clientOffset_=serverTime-Date.now(),done()})))}haveMain_(){this.state="HAVE_MAIN_MANIFEST",this.isMain_?this.trigger("loadedplaylist"):this.media_||this.media(this.childPlaylist_)}handleMain_(){this.mediaRequest_=null;const oldMain=this.mainPlaylistLoader_.main;let newMain=parseMainXml({mainXml:this.mainPlaylistLoader_.mainXml_,srcUrl:this.mainPlaylistLoader_.srcUrl,clientOffset:this.mainPlaylistLoader_.clientOffset_,sidxMapping:this.mainPlaylistLoader_.sidxMapping_,previousManifest:oldMain});oldMain&&(newMain=updateMain(oldMain,newMain,this.mainPlaylistLoader_.sidxMapping_)),this.mainPlaylistLoader_.main=newMain||oldMain;const location=this.mainPlaylistLoader_.main.locations&&this.mainPlaylistLoader_.main.locations[0];return location&&location!==this.mainPlaylistLoader_.srcUrl&&(this.mainPlaylistLoader_.srcUrl=location),(!oldMain||newMain&&newMain.minimumUpdatePeriod!==oldMain.minimumUpdatePeriod)&&this.updateMinimumUpdatePeriodTimeout_(),Boolean(newMain)}updateMinimumUpdatePeriodTimeout_(){const mpl=this.mainPlaylistLoader_;mpl.createMupOnMedia_&&(mpl.off("loadedmetadata",mpl.createMupOnMedia_),mpl.createMupOnMedia_=null),mpl.minimumUpdatePeriodTimeout_&&(window.clearTimeout(mpl.minimumUpdatePeriodTimeout_),mpl.minimumUpdatePeriodTimeout_=null);let mup=mpl.main&&mpl.main.minimumUpdatePeriod;0===mup&&(mpl.media()?mup=1e3*mpl.media().targetDuration:(mpl.createMupOnMedia_=mpl.updateMinimumUpdatePeriodTimeout_,mpl.one("loadedmetadata",mpl.createMupOnMedia_))),"number"!=typeof mup||mup<=0?mup<0&&this.logger_("found invalid minimumUpdatePeriod of ".concat(mup,", not setting a timeout")):this.createMUPTimeout_(mup)}createMUPTimeout_(mup){const mpl=this.mainPlaylistLoader_;mpl.minimumUpdatePeriodTimeout_=window.setTimeout((()=>{mpl.minimumUpdatePeriodTimeout_=null,mpl.trigger("minimumUpdatePeriod"),mpl.createMUPTimeout_(mup)}),mup)}refreshXml_(){this.requestMain_(((req,mainChanged)=>{mainChanged&&(this.media_&&(this.media_=this.mainPlaylistLoader_.main.playlists[this.media_.id]),this.mainPlaylistLoader_.sidxMapping_=((main,oldSidxMapping)=>{let mediaGroupSidx=compareSidxEntry(main.playlists,oldSidxMapping);return forEachMediaGroup(main,((properties,mediaType,groupKey,labelKey)=>{if(properties.playlists&&properties.playlists.length){const playlists=properties.playlists;mediaGroupSidx=merge(mediaGroupSidx,compareSidxEntry(playlists,oldSidxMapping))}})),mediaGroupSidx})(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.sidxMapping_),this.addSidxSegments_(this.media(),this.state,(sidxChanged=>{this.refreshMedia_(this.media().id)})))}))}refreshMedia_(mediaID){if(!mediaID)throw new Error("refreshMedia_ must take a media id");this.media_&&this.isMain_&&this.handleMain_();const playlists=this.mainPlaylistLoader_.main.playlists,mediaChanged=!this.media_||this.media_!==playlists[mediaID];if(mediaChanged?this.media_=playlists[mediaID]:this.trigger("playlistunchanged"),!this.mediaUpdateTimeout){const createMediaUpdateTimeout=()=>{this.media().endList||(this.mediaUpdateTimeout=window.setTimeout((()=>{this.trigger("mediaupdatetimeout"),createMediaUpdateTimeout()}),refreshDelay(this.media(),Boolean(mediaChanged))))};createMediaUpdateTimeout()}this.trigger("loadedplaylist")}}var Config={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,BACK_BUFFER_LENGTH:30,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:16,BUFFER_LOW_WATER_LINE_RATE:1,BUFFER_HIGH_WATER_LINE:30};const browserWorkerPolyFill=function(workerObj){return workerObj.on=workerObj.addEventListener,workerObj.off=workerObj.removeEventListener,workerObj},factory=function(code){return function(){const objectUrl=function(str){try{return URL.createObjectURL(new Blob([str],{type:"application/javascript"}))}catch(e){const blob=new BlobBuilder;return blob.append(str),URL.createObjectURL(blob.getBlob())}}(code),worker=browserWorkerPolyFill(new Worker(objectUrl));worker.objURL=objectUrl;const terminate=worker.terminate;return worker.on=worker.addEventListener,worker.off=worker.removeEventListener,worker.terminate=function(){return URL.revokeObjectURL(objectUrl),terminate.call(this)},worker}},transform=function(code){return"var browserWorkerPolyFill = ".concat(browserWorkerPolyFill.toString(),";\n")+"browserWorkerPolyFill(self);\n"+code},getWorkerString=function(fn){return fn.toString().replace(/^function.+?{/,"").slice(0,-1)},workerCode$1=transform(getWorkerString((function(){var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},Stream$8=function(){this.init=function(){var listeners={};this.on=function(type,listener){listeners[type]||(listeners[type]=[]),listeners[type]=listeners[type].concat(listener)},this.off=function(type,listener){var index;return!!listeners[type]&&(index=listeners[type].indexOf(listener),listeners[type]=listeners[type].slice(),listeners[type].splice(index,1),index>-1)},this.trigger=function(type){var callbacks,i,length,args;if(callbacks=listeners[type])if(2===arguments.length)for(length=callbacks.length,i=0;i>>1,track.samplingfrequencyindex<<7|track.channelcount<<3,6,1,2]))},hdlr=function(type){return box(types.hdlr,HDLR_TYPES[type])},mdhd=function(track){var result=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,track.duration>>>24&255,track.duration>>>16&255,track.duration>>>8&255,255&track.duration,85,196,0,0]);return track.samplerate&&(result[12]=track.samplerate>>>24&255,result[13]=track.samplerate>>>16&255,result[14]=track.samplerate>>>8&255,result[15]=255&track.samplerate),box(types.mdhd,result)},mdia=function(track){return box(types.mdia,mdhd(track),hdlr(track.type),minf(track))},mfhd=function(sequenceNumber){return box(types.mfhd,new Uint8Array([0,0,0,0,(4278190080&sequenceNumber)>>24,(16711680&sequenceNumber)>>16,(65280&sequenceNumber)>>8,255&sequenceNumber]))},minf=function(track){return box(types.minf,"video"===track.type?box(types.vmhd,VMHD):box(types.smhd,SMHD),dinf(),stbl(track))},moof=function(sequenceNumber,tracks){for(var trackFragments=[],i=tracks.length;i--;)trackFragments[i]=traf(tracks[i]);return box.apply(null,[types.moof,mfhd(sequenceNumber)].concat(trackFragments))},moov=function(tracks){for(var i=tracks.length,boxes=[];i--;)boxes[i]=trak(tracks[i]);return box.apply(null,[types.moov,mvhd(4294967295)].concat(boxes).concat(mvex(tracks)))},mvex=function(tracks){for(var i=tracks.length,boxes=[];i--;)boxes[i]=trex(tracks[i]);return box.apply(null,[types.mvex].concat(boxes))},mvhd=function(duration){var bytes=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&duration)>>24,(16711680&duration)>>16,(65280&duration)>>8,255&duration,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 box(types.mvhd,bytes)},sdtp=function(track){var flags,i,samples=track.samples||[],bytes=new Uint8Array(4+samples.length);for(i=0;i>>8),sequenceParameterSets.push(255&sps[i].byteLength),sequenceParameterSets=sequenceParameterSets.concat(Array.prototype.slice.call(sps[i]));for(i=0;i>>8),pictureParameterSets.push(255&pps[i].byteLength),pictureParameterSets=pictureParameterSets.concat(Array.prototype.slice.call(pps[i]));if(avc1Box=[types.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&track.width)>>8,255&track.width,(65280&track.height)>>8,255&track.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]),box(types.avcC,new Uint8Array([1,track.profileIdc,track.profileCompatibility,track.levelIdc,255].concat([sps.length],sequenceParameterSets,[pps.length],pictureParameterSets))),box(types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],track.sarRatio){var hSpacing=track.sarRatio[0],vSpacing=track.sarRatio[1];avc1Box.push(box(types.pasp,new Uint8Array([(4278190080&hSpacing)>>24,(16711680&hSpacing)>>16,(65280&hSpacing)>>8,255&hSpacing,(4278190080&vSpacing)>>24,(16711680&vSpacing)>>16,(65280&vSpacing)>>8,255&vSpacing])))}return box.apply(null,avc1Box)},audioSample=function(track){return box(types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&track.channelcount)>>8,255&track.channelcount,(65280&track.samplesize)>>8,255&track.samplesize,0,0,0,0,(65280&track.samplerate)>>8,255&track.samplerate,0,0]),esds(track))},tkhd=function(track){var result=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,0,(4278190080&track.duration)>>24,(16711680&track.duration)>>16,(65280&track.duration)>>8,255&track.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&track.width)>>8,255&track.width,0,0,(65280&track.height)>>8,255&track.height,0,0]);return box(types.tkhd,result)},traf=function(track){var trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun,sampleDependencyTable,upperWordBaseMediaDecodeTime,lowerWordBaseMediaDecodeTime;return trackFragmentHeader=box(types.tfhd,new Uint8Array([0,0,0,58,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),upperWordBaseMediaDecodeTime=Math.floor(track.baseMediaDecodeTime/MAX_UINT32),lowerWordBaseMediaDecodeTime=Math.floor(track.baseMediaDecodeTime%MAX_UINT32),trackFragmentDecodeTime=box(types.tfdt,new Uint8Array([1,0,0,0,upperWordBaseMediaDecodeTime>>>24&255,upperWordBaseMediaDecodeTime>>>16&255,upperWordBaseMediaDecodeTime>>>8&255,255&upperWordBaseMediaDecodeTime,lowerWordBaseMediaDecodeTime>>>24&255,lowerWordBaseMediaDecodeTime>>>16&255,lowerWordBaseMediaDecodeTime>>>8&255,255&lowerWordBaseMediaDecodeTime])),92,"audio"===track.type?(trackFragmentRun=trun$1(track,92),box(types.traf,trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun)):(sampleDependencyTable=sdtp(track),trackFragmentRun=trun$1(track,sampleDependencyTable.length+92),box(types.traf,trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun,sampleDependencyTable))},trak=function(track){return track.duration=track.duration||4294967295,box(types.trak,tkhd(track),mdia(track))},trex=function(track){var result=new Uint8Array([0,0,0,0,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==track.type&&(result[result.length-1]=0),box(types.trex,result)},trunHeader=function(samples,offset){var durationPresent=0,sizePresent=0,flagsPresent=0,compositionTimeOffset=0;return samples.length&&(void 0!==samples[0].duration&&(durationPresent=1),void 0!==samples[0].size&&(sizePresent=2),void 0!==samples[0].flags&&(flagsPresent=4),void 0!==samples[0].compositionTimeOffset&&(compositionTimeOffset=8)),[0,0,durationPresent|sizePresent|flagsPresent|compositionTimeOffset,1,(4278190080&samples.length)>>>24,(16711680&samples.length)>>>16,(65280&samples.length)>>>8,255&samples.length,(4278190080&offset)>>>24,(16711680&offset)>>>16,(65280&offset)>>>8,255&offset]},videoTrun=function(track,offset){var bytesOffest,bytes,header,samples,sample,i;for(offset+=20+16*(samples=track.samples||[]).length,header=trunHeader(samples,offset),(bytes=new Uint8Array(header.length+16*samples.length)).set(header),bytesOffest=header.length,i=0;i>>24,bytes[bytesOffest++]=(16711680&sample.duration)>>>16,bytes[bytesOffest++]=(65280&sample.duration)>>>8,bytes[bytesOffest++]=255&sample.duration,bytes[bytesOffest++]=(4278190080&sample.size)>>>24,bytes[bytesOffest++]=(16711680&sample.size)>>>16,bytes[bytesOffest++]=(65280&sample.size)>>>8,bytes[bytesOffest++]=255&sample.size,bytes[bytesOffest++]=sample.flags.isLeading<<2|sample.flags.dependsOn,bytes[bytesOffest++]=sample.flags.isDependedOn<<6|sample.flags.hasRedundancy<<4|sample.flags.paddingValue<<1|sample.flags.isNonSyncSample,bytes[bytesOffest++]=61440&sample.flags.degradationPriority,bytes[bytesOffest++]=15&sample.flags.degradationPriority,bytes[bytesOffest++]=(4278190080&sample.compositionTimeOffset)>>>24,bytes[bytesOffest++]=(16711680&sample.compositionTimeOffset)>>>16,bytes[bytesOffest++]=(65280&sample.compositionTimeOffset)>>>8,bytes[bytesOffest++]=255&sample.compositionTimeOffset;return box(types.trun,bytes)},audioTrun=function(track,offset){var bytes,bytesOffest,header,samples,sample,i;for(offset+=20+8*(samples=track.samples||[]).length,header=trunHeader(samples,offset),(bytes=new Uint8Array(header.length+8*samples.length)).set(header),bytesOffest=header.length,i=0;i>>24,bytes[bytesOffest++]=(16711680&sample.duration)>>>16,bytes[bytesOffest++]=(65280&sample.duration)>>>8,bytes[bytesOffest++]=255&sample.duration,bytes[bytesOffest++]=(4278190080&sample.size)>>>24,bytes[bytesOffest++]=(16711680&sample.size)>>>16,bytes[bytesOffest++]=(65280&sample.size)>>>8,bytes[bytesOffest++]=255&sample.size;return box(types.trun,bytes)},trun$1=function(track,offset){return"audio"===track.type?audioTrun(track,offset):videoTrun(track,offset)};var silence,secondsToVideoTs,secondsToAudioTs,videoTsToSeconds,audioTsToSeconds,audioTsToVideoTs,videoTsToAudioTs,metadataTsToSeconds,mp4Generator={ftyp:ftyp=function(){return box(types.ftyp,MAJOR_BRAND,MINOR_VERSION,MAJOR_BRAND,AVC1_BRAND)},mdat:function(data){return box(types.mdat,data)},moof:moof,moov:moov,initSegment:function(tracks){var result,fileType=ftyp(),movie=moov(tracks);return(result=new Uint8Array(fileType.byteLength+movie.byteLength)).set(fileType),result.set(movie,fileType.byteLength),result}},sampleForFrame=function(frame,dataOffset){var sample={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return sample.dataOffset=dataOffset,sample.compositionTimeOffset=frame.pts-frame.dts,sample.duration=frame.duration,sample.size=4*frame.length,sample.size+=frame.byteLength,frame.keyFrame&&(sample.flags.dependsOn=2,sample.flags.isNonSyncSample=0),sample},frameUtils$1={groupNalsIntoFrames:function(nalUnits){var i,currentNal,currentFrame=[],frames=[];for(frames.byteLength=0,frames.nalCount=0,frames.duration=0,currentFrame.byteLength=0,i=0;i1&&(currentGop=gops.shift(),gops.byteLength-=currentGop.byteLength,gops.nalCount-=currentGop.nalCount,gops[0][0].dts=currentGop.dts,gops[0][0].pts=currentGop.pts,gops[0][0].duration+=currentGop.duration),gops},generateSampleTable:function(gops,baseDataOffset){var h,i,sample,currentGop,currentFrame,dataOffset=baseDataOffset||0,samples=[];for(h=0;hclock$1.ONE_SECOND_IN_TS/2))){for((silentFrame=coneOfSilence()[track.samplerate])||(silentFrame=frames[0].data),i=0;i=earliestAllowedDts?adtsFrames:(track.minSegmentDts=1/0,adtsFrames.filter((function(currentFrame){return currentFrame.dts>=earliestAllowedDts&&(track.minSegmentDts=Math.min(track.minSegmentDts,currentFrame.dts),track.minSegmentPts=track.minSegmentDts,!0)})))},generateSampleTable:function(frames){var i,currentFrame,samples=[];for(i=0;i=this.virtualRowCount&&"function"==typeof this.beforeRowOverflow&&this.beforeRowOverflow(pts),this.rows.length>0&&(this.rows.push(""),this.rowIdx++);this.rows.length>this.virtualRowCount;)this.rows.shift(),this.rowIdx--},Cea708Window.prototype.isEmpty=function(){return 0===this.rows.length||1===this.rows.length&&""===this.rows[0]},Cea708Window.prototype.addText=function(text){this.rows[this.rowIdx]+=text},Cea708Window.prototype.backspace=function(){if(!this.isEmpty()){var row=this.rows[this.rowIdx];this.rows[this.rowIdx]=row.substr(0,row.length-1)}};var Cea708Service=function(serviceNum,encoding,stream){this.serviceNum=serviceNum,this.text="",this.currentWindow=new Cea708Window(-1),this.windows=[],this.stream=stream,"string"==typeof encoding&&this.createTextDecoder(encoding)};Cea708Service.prototype.init=function(pts,beforeRowOverflow){this.startPts=pts;for(var win=0;win<8;win++)this.windows[win]=new Cea708Window(win),"function"==typeof beforeRowOverflow&&(this.windows[win].beforeRowOverflow=beforeRowOverflow)},Cea708Service.prototype.setCurrentWindow=function(windowNum){this.currentWindow=this.windows[windowNum]},Cea708Service.prototype.createTextDecoder=function(encoding){if("undefined"==typeof TextDecoder)this.stream.trigger("log",{level:"warn",message:"The `encoding` option is unsupported without TextDecoder support"});else try{this.textDecoder_=new TextDecoder(encoding)}catch(error){this.stream.trigger("log",{level:"warn",message:"TextDecoder could not be created with "+encoding+" encoding. "+error})}};var Cea708Stream=function(options){options=options||{},Cea708Stream.prototype.init.call(this);var serviceProps,self=this,captionServices=options.captionServices||{},captionServiceEncodings={};Object.keys(captionServices).forEach((serviceName=>{serviceProps=captionServices[serviceName],/^SERVICE/.test(serviceName)&&(captionServiceEncodings[serviceName]=serviceProps.encoding)})),this.serviceEncodings=captionServiceEncodings,this.current708Packet=null,this.services={},this.push=function(packet){3===packet.type?(self.new708Packet(),self.add708Bytes(packet)):(null===self.current708Packet&&self.new708Packet(),self.add708Bytes(packet))}};Cea708Stream.prototype=new Stream$7,Cea708Stream.prototype.new708Packet=function(){null!==this.current708Packet&&this.push708Packet(),this.current708Packet={data:[],ptsVals:[]}},Cea708Stream.prototype.add708Bytes=function(packet){var data=packet.ccData,byte0=data>>>8,byte1=255&data;this.current708Packet.ptsVals.push(packet.pts),this.current708Packet.data.push(byte0),this.current708Packet.data.push(byte1)},Cea708Stream.prototype.push708Packet=function(){var packet708=this.current708Packet,packetData=packet708.data,serviceNum=null,blockSize=null,i=0,b=packetData[i++];for(packet708.seq=b>>6,packet708.sizeCode=63&b;i>5)&&blockSize>0&&(serviceNum=b=packetData[i++]),this.pushServiceBlock(serviceNum,i,blockSize),blockSize>0&&(i+=blockSize-1)},Cea708Stream.prototype.pushServiceBlock=function(serviceNum,start,size){var b,i=start,packetData=this.current708Packet.data,service=this.services[serviceNum];for(service||(service=this.initService(serviceNum,i));i>5,win.rowLock=(16&b)>>4,win.columnLock=(8&b)>>3,win.priority=7&b,b=packetData[++i],win.relativePositioning=(128&b)>>7,win.anchorVertical=127&b,b=packetData[++i],win.anchorHorizontal=b,b=packetData[++i],win.anchorPoint=(240&b)>>4,win.rowCount=15&b,b=packetData[++i],win.columnCount=63&b,b=packetData[++i],win.windowStyle=(56&b)>>3,win.penStyle=7&b,win.virtualRowCount=win.rowCount+1,i},Cea708Stream.prototype.setWindowAttributes=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],winAttr=service.currentWindow.winAttr;return b=packetData[++i],winAttr.fillOpacity=(192&b)>>6,winAttr.fillRed=(48&b)>>4,winAttr.fillGreen=(12&b)>>2,winAttr.fillBlue=3&b,b=packetData[++i],winAttr.borderType=(192&b)>>6,winAttr.borderRed=(48&b)>>4,winAttr.borderGreen=(12&b)>>2,winAttr.borderBlue=3&b,b=packetData[++i],winAttr.borderType+=(128&b)>>5,winAttr.wordWrap=(64&b)>>6,winAttr.printDirection=(48&b)>>4,winAttr.scrollDirection=(12&b)>>2,winAttr.justify=3&b,b=packetData[++i],winAttr.effectSpeed=(240&b)>>4,winAttr.effectDirection=(12&b)>>2,winAttr.displayEffect=3&b,i},Cea708Stream.prototype.flushDisplayed=function(pts,service){for(var displayedText=[],winId=0;winId<8;winId++)service.windows[winId].visible&&!service.windows[winId].isEmpty()&&displayedText.push(service.windows[winId].getText());service.endPts=pts,service.text=displayedText.join("\n\n"),this.pushCaption(service),service.startPts=pts},Cea708Stream.prototype.pushCaption=function(service){""!==service.text&&(this.trigger("data",{startPts:service.startPts,endPts:service.endPts,text:service.text,stream:"cc708_"+service.serviceNum}),service.text="",service.startPts=service.endPts)},Cea708Stream.prototype.displayWindows=function(i,service){var b=this.current708Packet.data[++i],pts=this.getPts(i);this.flushDisplayed(pts,service);for(var winId=0;winId<8;winId++)b&1<>4,penAttr.offset=(12&b)>>2,penAttr.penSize=3&b,b=packetData[++i],penAttr.italics=(128&b)>>7,penAttr.underline=(64&b)>>6,penAttr.edgeType=(56&b)>>3,penAttr.fontStyle=7&b,i},Cea708Stream.prototype.setPenColor=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],penColor=service.currentWindow.penColor;return b=packetData[++i],penColor.fgOpacity=(192&b)>>6,penColor.fgRed=(48&b)>>4,penColor.fgGreen=(12&b)>>2,penColor.fgBlue=3&b,b=packetData[++i],penColor.bgOpacity=(192&b)>>6,penColor.bgRed=(48&b)>>4,penColor.bgGreen=(12&b)>>2,penColor.bgBlue=3&b,b=packetData[++i],penColor.edgeRed=(48&b)>>4,penColor.edgeGreen=(12&b)>>2,penColor.edgeBlue=3&b,i},Cea708Stream.prototype.setPenLocation=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],penLoc=service.currentWindow.penLoc;return service.currentWindow.pendingNewLine=!0,b=packetData[++i],penLoc.row=15&b,b=packetData[++i],penLoc.column=63&b,i},Cea708Stream.prototype.reset=function(i,service){var pts=this.getPts(i);return this.flushDisplayed(pts,service),this.initService(service.serviceNum,i)};var CHARACTER_TRANSLATION={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},getCharFromCode=function(code){return null===code?"":(code=CHARACTER_TRANSLATION[code]||code,String.fromCharCode(code))},ROWS=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],createDisplayBuffer=function(){for(var result=[],i=15;i--;)result.push("");return result},Cea608Stream=function(field,dataChannel){Cea608Stream.prototype.init.call(this),this.field_=field||0,this.dataChannel_=dataChannel||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(packet){var data,swap,char0,char1,text;if((data=32639&packet.ccData)!==this.lastControlCode_){if(4096==(61440&data)?this.lastControlCode_=data:data!==this.PADDING_&&(this.lastControlCode_=null),char0=data>>>8,char1=255&data,data!==this.PADDING_)if(data===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(data===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(packet.pts),this.flushDisplayed(packet.pts),swap=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=swap,this.startPts_=packet.pts;else if(data===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(packet.pts);else if(data===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(packet.pts);else if(data===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(packet.pts);else if(data===this.CARRIAGE_RETURN_)this.clearFormatting(packet.pts),this.flushDisplayed(packet.pts),this.shiftRowsUp_(),this.startPts_=packet.pts;else if(data===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(data===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(packet.pts),this.displayed_=createDisplayBuffer();else if(data===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=createDisplayBuffer();else if(data===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(packet.pts),this.displayed_=createDisplayBuffer()),this.mode_="paintOn",this.startPts_=packet.pts;else if(this.isSpecialCharacter(char0,char1))text=getCharFromCode((char0=(3&char0)<<8)|char1),this[this.mode_](packet.pts,text),this.column_++;else if(this.isExtCharacter(char0,char1))"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),text=getCharFromCode((char0=(3&char0)<<8)|char1),this[this.mode_](packet.pts,text),this.column_++;else if(this.isMidRowCode(char0,char1))this.clearFormatting(packet.pts),this[this.mode_](packet.pts," "),this.column_++,14==(14&char1)&&this.addFormatting(packet.pts,["i"]),1==(1&char1)&&this.addFormatting(packet.pts,["u"]);else if(this.isOffsetControlCode(char0,char1))this.column_+=3&char1;else if(this.isPAC(char0,char1)){var row=ROWS.indexOf(7968&data);"rollUp"===this.mode_&&(row-this.rollUpRows_+1<0&&(row=this.rollUpRows_-1),this.setRollUp(packet.pts,row)),row!==this.row_&&(this.clearFormatting(packet.pts),this.row_=row),1&char1&&-1===this.formatting_.indexOf("u")&&this.addFormatting(packet.pts,["u"]),16==(16&data)&&(this.column_=4*((14&data)>>1)),this.isColorPAC(char1)&&14==(14&char1)&&this.addFormatting(packet.pts,["i"])}else this.isNormalChar(char0)&&(0===char1&&(char1=null),text=getCharFromCode(char0),text+=getCharFromCode(char1),this[this.mode_](packet.pts,text),this.column_+=text.length)}else this.lastControlCode_=null}};Cea608Stream.prototype=new Stream$7,Cea608Stream.prototype.flushDisplayed=function(pts){var content=this.displayed_.map((function(row,index){try{return row.trim()}catch(e){return this.trigger("log",{level:"warn",message:"Skipping a malformed 608 caption at index "+index+"."}),""}}),this).join("\n").replace(/^\n+|\n+$/g,"");content.length&&this.trigger("data",{startPts:this.startPts_,endPts:pts,text:content,stream:this.name_})},Cea608Stream.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=createDisplayBuffer(),this.nonDisplayed_=createDisplayBuffer(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Cea608Stream.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_},Cea608Stream.prototype.isSpecialCharacter=function(char0,char1){return char0===this.EXT_&&char1>=48&&char1<=63},Cea608Stream.prototype.isExtCharacter=function(char0,char1){return(char0===this.EXT_+1||char0===this.EXT_+2)&&char1>=32&&char1<=63},Cea608Stream.prototype.isMidRowCode=function(char0,char1){return char0===this.EXT_&&char1>=32&&char1<=47},Cea608Stream.prototype.isOffsetControlCode=function(char0,char1){return char0===this.OFFSET_&&char1>=33&&char1<=35},Cea608Stream.prototype.isPAC=function(char0,char1){return char0>=this.BASE_&&char0=64&&char1<=127},Cea608Stream.prototype.isColorPAC=function(char1){return char1>=64&&char1<=79||char1>=96&&char1<=127},Cea608Stream.prototype.isNormalChar=function(char){return char>=32&&char<=127},Cea608Stream.prototype.setRollUp=function(pts,newBaseRow){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(pts),this.nonDisplayed_=createDisplayBuffer(),this.displayed_=createDisplayBuffer()),void 0!==newBaseRow&&newBaseRow!==this.row_)for(var i=0;i"}),"");this[this.mode_](pts,text)},Cea608Stream.prototype.clearFormatting=function(pts){if(this.formatting_.length){var text=this.formatting_.reverse().reduce((function(text,format){return text+""}),"");this.formatting_=[],this[this.mode_](pts,text)}},Cea608Stream.prototype.popOn=function(pts,text){var baseRow=this.nonDisplayed_[this.row_];baseRow+=text,this.nonDisplayed_[this.row_]=baseRow},Cea608Stream.prototype.rollUp=function(pts,text){var baseRow=this.displayed_[this.row_];baseRow+=text,this.displayed_[this.row_]=baseRow},Cea608Stream.prototype.shiftRowsUp_=function(){var i;for(i=0;ireference&&(direction=-1);Math.abs(reference-value)>4294967296;)value+=8589934592*direction;return value},TimestampRolloverStream$1=function(type){var lastDTS,referenceDTS;TimestampRolloverStream$1.prototype.init.call(this),this.type_=type||"shared",this.push=function(data){"shared"!==this.type_&&data.type!==this.type_||(void 0===referenceDTS&&(referenceDTS=data.dts),data.dts=handleRollover$1(data.dts,referenceDTS),data.pts=handleRollover$1(data.pts,referenceDTS),lastDTS=data.dts,this.trigger("data",data))},this.flush=function(){referenceDTS=lastDTS,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.discontinuity=function(){referenceDTS=void 0,lastDTS=void 0},this.reset=function(){this.discontinuity(),this.trigger("reset")}};TimestampRolloverStream$1.prototype=new Stream$6;var MetadataStream,timestampRolloverStream={TimestampRolloverStream:TimestampRolloverStream$1,handleRollover:handleRollover$1},typedArray_typedArrayIndexOf=(typedArray,element,fromIndex)=>{if(!typedArray)return-1;for(var currentIndex=fromIndex;currentIndex>>2;size*=4,size+=3&d[7],frame.timeStamp=size,void 0===tag.pts&&void 0===tag.dts&&(tag.pts=frame.timeStamp,tag.dts=frame.timeStamp),this.trigger("timestamp",frame)}tag.frames.push(frame),frameStart+=10,frameStart+=frameSize}while(frameStart>>4>1&&(offset+=packet[offset]+1),0===result.pid)result.type="pat",parsePsi(packet.subarray(offset),result),this.trigger("data",result);else if(result.pid===this.pmtPid)for(result.type="pmt",parsePsi(packet.subarray(offset),result),this.trigger("data",result);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([packet,offset,result]):this.processPes_(packet,offset,result)},this.processPes_=function(packet,offset,result){result.pid===this.programMapTable.video?result.streamType=StreamTypes$2.H264_STREAM_TYPE:result.pid===this.programMapTable.audio?result.streamType=StreamTypes$2.ADTS_STREAM_TYPE:result.streamType=this.programMapTable["timed-metadata"][result.pid],result.type="pes",result.data=packet.subarray(offset),this.trigger("data",result)}},TransportParseStream.prototype=new Stream$4,TransportParseStream.STREAM_TYPES={h264:27,adts:15},ElementaryStream=function(){var programMapTable,self=this,segmentHadPmt=!1,video={data:[],size:0},audio={data:[],size:0},timedMetadata={data:[],size:0},flushStream=function(stream,type,forceFlush){var packetFlushable,fragment,packetData=new Uint8Array(stream.size),event={type:type},i=0,offset=0;if(stream.data.length&&!(stream.size<9)){for(event.trackId=stream.data[0].pid,i=0;i>>3,pes.pts*=4,pes.pts+=(6&payload[13])>>>1,pes.dts=pes.pts,64&ptsDtsFlags&&(pes.dts=(14&payload[14])<<27|(255&payload[15])<<20|(254&payload[16])<<12|(255&payload[17])<<5|(254&payload[18])>>>3,pes.dts*=4,pes.dts+=(6&payload[18])>>>1)),pes.data=payload.subarray(9+payload[8]))}(packetData,event),packetFlushable="video"===type||event.packetLength<=stream.size,(forceFlush||packetFlushable)&&(stream.size=0,stream.data.length=0),packetFlushable&&self.trigger("data",event)}};ElementaryStream.prototype.init.call(this),this.push=function(data){({pat:function(){},pes:function(){var stream,streamType;switch(data.streamType){case StreamTypes$2.H264_STREAM_TYPE:stream=video,streamType="video";break;case StreamTypes$2.ADTS_STREAM_TYPE:stream=audio,streamType="audio";break;case StreamTypes$2.METADATA_STREAM_TYPE:stream=timedMetadata,streamType="timed-metadata";break;default:return}data.payloadUnitStartIndicator&&flushStream(stream,streamType,!0),stream.data.push(data),stream.size+=data.data.byteLength},pmt:function(){var event={type:"metadata",tracks:[]};null!==(programMapTable=data.programMapTable).video&&event.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.video,codec:"avc",type:"video"}),null!==programMapTable.audio&&event.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.audio,codec:"adts",type:"audio"}),segmentHadPmt=!0,self.trigger("data",event)}})[data.type]()},this.reset=function(){video.size=0,video.data.length=0,audio.size=0,audio.data.length=0,this.trigger("reset")},this.flushStreams_=function(){flushStream(video,"video"),flushStream(audio,"audio"),flushStream(timedMetadata,"timed-metadata")},this.flush=function(){if(!segmentHadPmt&&programMapTable){var pmt={type:"metadata",tracks:[]};null!==programMapTable.video&&pmt.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.video,codec:"avc",type:"video"}),null!==programMapTable.audio&&pmt.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.audio,codec:"adts",type:"audio"}),self.trigger("data",pmt)}segmentHadPmt=!1,this.flushStreams_(),this.trigger("done")}},ElementaryStream.prototype=new Stream$4;var m2ts$1={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:TransportPacketStream,TransportParseStream:TransportParseStream,ElementaryStream:ElementaryStream,TimestampRolloverStream:TimestampRolloverStream,CaptionStream:CaptionStream$1.CaptionStream,Cea608Stream:CaptionStream$1.Cea608Stream,Cea708Stream:CaptionStream$1.Cea708Stream,MetadataStream:metadataStream};for(var type in StreamTypes$2)StreamTypes$2.hasOwnProperty(type)&&(m2ts$1[type]=StreamTypes$2[type]);var AdtsStream$1,m2ts_1=m2ts$1,ONE_SECOND_IN_TS$2=clock$2.ONE_SECOND_IN_TS,ADTS_SAMPLING_FREQUENCIES$1=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(AdtsStream$1=function(handlePartialSegments){var buffer,frameNum=0;AdtsStream$1.prototype.init.call(this),this.skipWarn_=function(start,end){this.trigger("log",{level:"warn",message:"adts skiping bytes ".concat(start," to ").concat(end," in frame ").concat(frameNum," outside syncword")})},this.push=function(packet){var frameLength,protectionSkipBytes,oldBuffer,sampleCount,adtsFrameDuration,i=0;if(handlePartialSegments||(frameNum=0),"audio"===packet.type){var skip;for(buffer&&buffer.length?(oldBuffer=buffer,(buffer=new Uint8Array(oldBuffer.byteLength+packet.data.byteLength)).set(oldBuffer),buffer.set(packet.data,oldBuffer.byteLength)):buffer=packet.data;i+7>5,adtsFrameDuration=(sampleCount=1024*(1+(3&buffer[i+6])))*ONE_SECOND_IN_TS$2/ADTS_SAMPLING_FREQUENCIES$1[(60&buffer[i+2])>>>2],buffer.byteLength-i>>6&3),channelcount:(1&buffer[i+2])<<2|(192&buffer[i+3])>>>6,samplerate:ADTS_SAMPLING_FREQUENCIES$1[(60&buffer[i+2])>>>2],samplingfrequencyindex:(60&buffer[i+2])>>>2,samplesize:16,data:buffer.subarray(i+7+protectionSkipBytes,i+frameLength)}),frameNum++,i+=frameLength}else"number"!=typeof skip&&(skip=i),i++;"number"==typeof skip&&(this.skipWarn_(skip,i),skip=null),buffer=buffer.subarray(i)}},this.flush=function(){frameNum=0,this.trigger("done")},this.reset=function(){buffer=void 0,this.trigger("reset")},this.endTimeline=function(){buffer=void 0,this.trigger("endedtimeline")}}).prototype=new stream;var ExpGolomb$1,adts=AdtsStream$1;ExpGolomb$1=function(workingData){var workingBytesAvailable=workingData.byteLength,workingWord=0,workingBitsAvailable=0;this.length=function(){return 8*workingBytesAvailable},this.bitsAvailable=function(){return 8*workingBytesAvailable+workingBitsAvailable},this.loadWord=function(){var position=workingData.byteLength-workingBytesAvailable,workingBytes=new Uint8Array(4),availableBytes=Math.min(4,workingBytesAvailable);if(0===availableBytes)throw new Error("no bytes available");workingBytes.set(workingData.subarray(position,position+availableBytes)),workingWord=new DataView(workingBytes.buffer).getUint32(0),workingBitsAvailable=8*availableBytes,workingBytesAvailable-=availableBytes},this.skipBits=function(count){var skipBytes;workingBitsAvailable>count?(workingWord<<=count,workingBitsAvailable-=count):(count-=workingBitsAvailable,count-=8*(skipBytes=Math.floor(count/8)),workingBytesAvailable-=skipBytes,this.loadWord(),workingWord<<=count,workingBitsAvailable-=count)},this.readBits=function(size){var bits=Math.min(workingBitsAvailable,size),valu=workingWord>>>32-bits;return(workingBitsAvailable-=bits)>0?workingWord<<=bits:workingBytesAvailable>0&&this.loadWord(),(bits=size-bits)>0?valu<>>leadingZeroCount))return workingWord<<=leadingZeroCount,workingBitsAvailable-=leadingZeroCount,leadingZeroCount;return this.loadWord(),leadingZeroCount+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var clz=this.skipLeadingZeros();return this.readBits(clz+1)-1},this.readExpGolomb=function(){var valu=this.readUnsignedExpGolomb();return 1&valu?1+valu>>>1:-1*(valu>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()};var H264Stream$1,NalByteStream,PROFILES_WITH_OPTIONAL_SPS_DATA,Stream$2=stream,ExpGolomb=ExpGolomb$1;(NalByteStream=function(){var i,buffer,syncPoint=0;NalByteStream.prototype.init.call(this),this.push=function(data){var swapBuffer;buffer?((swapBuffer=new Uint8Array(buffer.byteLength+data.data.byteLength)).set(buffer),swapBuffer.set(data.data,buffer.byteLength),buffer=swapBuffer):buffer=data.data;for(var len=buffer.byteLength;syncPoint3&&this.trigger("data",buffer.subarray(syncPoint+3)),buffer=null,syncPoint=0,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")}}).prototype=new Stream$2,PROFILES_WITH_OPTIONAL_SPS_DATA={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},H264Stream$1=function(){var self,trackId,currentPts,currentDts,discardEmulationPreventionBytes,readSequenceParameterSet,skipScalingList,nalByteStream=new NalByteStream;H264Stream$1.prototype.init.call(this),self=this,this.push=function(packet){"video"===packet.type&&(trackId=packet.trackId,currentPts=packet.pts,currentDts=packet.dts,nalByteStream.push(packet))},nalByteStream.on("data",(function(data){var event={trackId:trackId,pts:currentPts,dts:currentDts,data:data,nalUnitTypeCode:31&data[0]};switch(event.nalUnitTypeCode){case 5:event.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:event.nalUnitType="sei_rbsp",event.escapedRBSP=discardEmulationPreventionBytes(data.subarray(1));break;case 7:event.nalUnitType="seq_parameter_set_rbsp",event.escapedRBSP=discardEmulationPreventionBytes(data.subarray(1)),event.config=readSequenceParameterSet(event.escapedRBSP);break;case 8:event.nalUnitType="pic_parameter_set_rbsp";break;case 9:event.nalUnitType="access_unit_delimiter_rbsp"}self.trigger("data",event)})),nalByteStream.on("done",(function(){self.trigger("done")})),nalByteStream.on("partialdone",(function(){self.trigger("partialdone")})),nalByteStream.on("reset",(function(){self.trigger("reset")})),nalByteStream.on("endedtimeline",(function(){self.trigger("endedtimeline")})),this.flush=function(){nalByteStream.flush()},this.partialFlush=function(){nalByteStream.partialFlush()},this.reset=function(){nalByteStream.reset()},this.endTimeline=function(){nalByteStream.endTimeline()},skipScalingList=function(count,expGolombDecoder){var j,lastScale=8,nextScale=8;for(j=0;j=0?returnSize:0,(16&header[byteIndex+5])>>4?returnSize+20:returnSize+10},getId3Offset=function(data,offset){return data.length-offset<10||data[offset]!=="I".charCodeAt(0)||data[offset+1]!=="D".charCodeAt(0)||data[offset+2]!=="3".charCodeAt(0)?offset:(offset+=parseId3TagSize(data,offset),getId3Offset(data,offset))},parseSyncSafeInteger=function(data){return data[0]<<21|data[1]<<14|data[2]<<7|data[3]},utils={isLikelyAacData:function(data){var offset=getId3Offset(data,0);return data.length>=offset+2&&255==(255&data[offset])&&240==(240&data[offset+1])&&16==(22&data[offset+1])},parseId3TagSize:parseId3TagSize,parseAdtsSize:function(header,byteIndex){var lowThree=(224&header[byteIndex+5])>>5,middle=header[byteIndex+4]<<3;return 6144&header[byteIndex+3]|middle|lowThree},parseType:function(header,byteIndex){return header[byteIndex]==="I".charCodeAt(0)&&header[byteIndex+1]==="D".charCodeAt(0)&&header[byteIndex+2]==="3".charCodeAt(0)?"timed-metadata":!0&header[byteIndex]&&240==(240&header[byteIndex+1])?"audio":null},parseSampleRate:function(packet){for(var i=0;i+5>>2];i++}return null},parseAacTimestamp:function(packet){var frameStart,frameSize,frame;frameStart=10,64&packet[5]&&(frameStart+=4,frameStart+=parseSyncSafeInteger(packet.subarray(10,14)));do{if((frameSize=parseSyncSafeInteger(packet.subarray(frameStart+4,frameStart+8)))<1)return null;if("PRIV"===String.fromCharCode(packet[frameStart],packet[frameStart+1],packet[frameStart+2],packet[frameStart+3])){frame=packet.subarray(frameStart+10,frameStart+frameSize+10);for(var i=0;i>>2;return size*=4,size+=3&d[7]}break}}frameStart+=10,frameStart+=frameSize}while(frameStart=3;)if(everything[byteIndex]!=="I".charCodeAt(0)||everything[byteIndex+1]!=="D".charCodeAt(0)||everything[byteIndex+2]!=="3".charCodeAt(0))if(255!=(255&everything[byteIndex])||240!=(240&everything[byteIndex+1]))byteIndex++;else{if(everything.length-byteIndex<7)break;if(byteIndex+(frameSize=aacUtils.parseAdtsSize(everything,byteIndex))>everything.length)break;packet={type:"audio",data:everything.subarray(byteIndex,byteIndex+frameSize),pts:timeStamp,dts:timeStamp},this.trigger("data",packet),byteIndex+=frameSize}else{if(everything.length-byteIndex<10)break;if(byteIndex+(frameSize=aacUtils.parseId3TagSize(everything,byteIndex))>everything.length)break;chunk={type:"timed-metadata",data:everything.subarray(byteIndex,byteIndex+frameSize)},this.trigger("data",chunk),byteIndex+=frameSize}bytesLeft=everything.length-byteIndex,everything=bytesLeft>0?everything.subarray(byteIndex):new Uint8Array},this.reset=function(){everything=new Uint8Array,this.trigger("reset")},this.endTimeline=function(){everything=new Uint8Array,this.trigger("endedtimeline")}}).prototype=new stream;var VideoSegmentStream,AudioSegmentStream,Transmuxer,CoalesceStream,Stream=stream,mp4=mp4Generator,frameUtils=frameUtils$1,audioFrameUtils=audioFrameUtils$1,trackDecodeInfo=trackDecodeInfo$1,m2ts=m2ts_1,clock=clock$2,AdtsStream=adts,H264Stream=h264.H264Stream,AacStream=AacStream$1,isLikelyAacData=utils.isLikelyAacData,ONE_SECOND_IN_TS$1=clock$2.ONE_SECOND_IN_TS,AUDIO_PROPERTIES=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],VIDEO_PROPERTIES=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"],retriggerForStream=function(key,event){event.stream=key,this.trigger("log",event)},addPipelineLogRetriggers=function(transmuxer,pipeline){for(var keys=Object.keys(pipeline),i=0;i=-1e4&&dtsDistance<=45e3&&(!nearestGopObj||nearestDistance>dtsDistance)&&(nearestGopObj=currentGopObj,nearestDistance=dtsDistance));return nearestGopObj?nearestGopObj.gop:null},this.alignGopsAtStart_=function(gops){var alignIndex,gopIndex,align,gop,byteLength,nalCount,duration,alignedGops;for(byteLength=gops.byteLength,nalCount=gops.nalCount,duration=gops.duration,alignIndex=gopIndex=0;alignIndexalign.pts?alignIndex++:(gopIndex++,byteLength-=gop.byteLength,nalCount-=gop.nalCount,duration-=gop.duration);return 0===gopIndex?gops:gopIndex===gops.length?null:((alignedGops=gops.slice(gopIndex)).byteLength=byteLength,alignedGops.duration=duration,alignedGops.nalCount=nalCount,alignedGops.pts=alignedGops[0].pts,alignedGops.dts=alignedGops[0].dts,alignedGops)},this.alignGopsAtEnd_=function(gops){var alignIndex,gopIndex,align,gop,alignEndIndex,matchFound,trimIndex;for(alignIndex=gopsToAlignWith.length-1,gopIndex=gops.length-1,alignEndIndex=null,matchFound=!1;alignIndex>=0&&gopIndex>=0;){if(align=gopsToAlignWith[alignIndex],gop=gops[gopIndex],align.pts===gop.pts){matchFound=!0;break}align.pts>gop.pts?alignIndex--:(alignIndex===gopsToAlignWith.length-1&&(alignEndIndex=gopIndex),gopIndex--)}if(!matchFound&&null===alignEndIndex)return null;if(0===(trimIndex=matchFound?gopIndex:alignEndIndex))return gops;var alignedGops=gops.slice(trimIndex),metadata=alignedGops.reduce((function(total,gop){return total.byteLength+=gop.byteLength,total.duration+=gop.duration,total.nalCount+=gop.nalCount,total}),{byteLength:0,duration:0,nalCount:0});return alignedGops.byteLength=metadata.byteLength,alignedGops.duration=metadata.duration,alignedGops.nalCount=metadata.nalCount,alignedGops.pts=alignedGops[0].pts,alignedGops.dts=alignedGops[0].dts,alignedGops},this.alignGopsWith=function(newGopsToAlignWith){gopsToAlignWith=newGopsToAlignWith}},VideoSegmentStream.prototype=new Stream,CoalesceStream=function(options,metadataStream){this.numberOfTracks=0,this.metadataStream=metadataStream,void 0!==(options=options||{}).remux?this.remuxTracks=!!options.remux:this.remuxTracks=!0,"boolean"==typeof options.keepOriginalTimestamps?this.keepOriginalTimestamps=options.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,CoalesceStream.prototype.init.call(this),this.push=function(output){return output.text?this.pendingCaptions.push(output):output.frames?this.pendingMetadata.push(output):(this.pendingTracks.push(output.track),this.pendingBytes+=output.boxes.byteLength,"video"===output.track.type&&(this.videoTrack=output.track,this.pendingBoxes.push(output.boxes)),void("audio"===output.track.type&&(this.audioTrack=output.track,this.pendingBoxes.unshift(output.boxes))))}},CoalesceStream.prototype=new Stream,CoalesceStream.prototype.flush=function(flushSource){var caption,id3,initSegment,i,offset=0,event={captions:[],captionStreams:{},metadata:[],info:{}},timelineStartPts=0;if(this.pendingTracks.length=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(timelineStartPts=this.videoTrack.timelineStartInfo.pts,VIDEO_PROPERTIES.forEach((function(prop){event.info[prop]=this.videoTrack[prop]}),this)):this.audioTrack&&(timelineStartPts=this.audioTrack.timelineStartInfo.pts,AUDIO_PROPERTIES.forEach((function(prop){event.info[prop]=this.audioTrack[prop]}),this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?event.type=this.pendingTracks[0].type:event.type="combined",this.emittedTracks+=this.pendingTracks.length,initSegment=mp4.initSegment(this.pendingTracks),event.initSegment=new Uint8Array(initSegment.byteLength),event.initSegment.set(initSegment),event.data=new Uint8Array(this.pendingBytes),i=0;i=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},CoalesceStream.prototype.setRemux=function(val){this.remuxTracks=val},(Transmuxer=function(options){var videoTrack,audioTrack,self=this,hasFlushed=!0;Transmuxer.prototype.init.call(this),options=options||{},this.baseMediaDecodeTime=options.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var pipeline={};this.transmuxPipeline_=pipeline,pipeline.type="aac",pipeline.metadataStream=new m2ts.MetadataStream,pipeline.aacStream=new AacStream,pipeline.audioTimestampRolloverStream=new m2ts.TimestampRolloverStream("audio"),pipeline.timedMetadataTimestampRolloverStream=new m2ts.TimestampRolloverStream("timed-metadata"),pipeline.adtsStream=new AdtsStream,pipeline.coalesceStream=new CoalesceStream(options,pipeline.metadataStream),pipeline.headOfPipeline=pipeline.aacStream,pipeline.aacStream.pipe(pipeline.audioTimestampRolloverStream).pipe(pipeline.adtsStream),pipeline.aacStream.pipe(pipeline.timedMetadataTimestampRolloverStream).pipe(pipeline.metadataStream).pipe(pipeline.coalesceStream),pipeline.metadataStream.on("timestamp",(function(frame){pipeline.aacStream.setTimestamp(frame.timeStamp)})),pipeline.aacStream.on("data",(function(data){"timed-metadata"!==data.type&&"audio"!==data.type||pipeline.audioSegmentStream||(audioTrack=audioTrack||{timelineStartInfo:{baseMediaDecodeTime:self.baseMediaDecodeTime},codec:"adts",type:"audio"},pipeline.coalesceStream.numberOfTracks++,pipeline.audioSegmentStream=new AudioSegmentStream(audioTrack,options),pipeline.audioSegmentStream.on("log",self.getLogTrigger_("audioSegmentStream")),pipeline.audioSegmentStream.on("timingInfo",self.trigger.bind(self,"audioTimingInfo")),pipeline.adtsStream.pipe(pipeline.audioSegmentStream).pipe(pipeline.coalesceStream),self.trigger("trackinfo",{hasAudio:!!audioTrack,hasVideo:!!videoTrack}))})),pipeline.coalesceStream.on("data",this.trigger.bind(this,"data")),pipeline.coalesceStream.on("done",this.trigger.bind(this,"done")),addPipelineLogRetriggers(this,pipeline)},this.setupTsPipeline=function(){var pipeline={};this.transmuxPipeline_=pipeline,pipeline.type="ts",pipeline.metadataStream=new m2ts.MetadataStream,pipeline.packetStream=new m2ts.TransportPacketStream,pipeline.parseStream=new m2ts.TransportParseStream,pipeline.elementaryStream=new m2ts.ElementaryStream,pipeline.timestampRolloverStream=new m2ts.TimestampRolloverStream,pipeline.adtsStream=new AdtsStream,pipeline.h264Stream=new H264Stream,pipeline.captionStream=new m2ts.CaptionStream(options),pipeline.coalesceStream=new CoalesceStream(options,pipeline.metadataStream),pipeline.headOfPipeline=pipeline.packetStream,pipeline.packetStream.pipe(pipeline.parseStream).pipe(pipeline.elementaryStream).pipe(pipeline.timestampRolloverStream),pipeline.timestampRolloverStream.pipe(pipeline.h264Stream),pipeline.timestampRolloverStream.pipe(pipeline.adtsStream),pipeline.timestampRolloverStream.pipe(pipeline.metadataStream).pipe(pipeline.coalesceStream),pipeline.h264Stream.pipe(pipeline.captionStream).pipe(pipeline.coalesceStream),pipeline.elementaryStream.on("data",(function(data){var i;if("metadata"===data.type){for(i=data.tracks.length;i--;)videoTrack||"video"!==data.tracks[i].type?audioTrack||"audio"!==data.tracks[i].type||((audioTrack=data.tracks[i]).timelineStartInfo.baseMediaDecodeTime=self.baseMediaDecodeTime):(videoTrack=data.tracks[i]).timelineStartInfo.baseMediaDecodeTime=self.baseMediaDecodeTime;videoTrack&&!pipeline.videoSegmentStream&&(pipeline.coalesceStream.numberOfTracks++,pipeline.videoSegmentStream=new VideoSegmentStream(videoTrack,options),pipeline.videoSegmentStream.on("log",self.getLogTrigger_("videoSegmentStream")),pipeline.videoSegmentStream.on("timelineStartInfo",(function(timelineStartInfo){audioTrack&&!options.keepOriginalTimestamps&&(audioTrack.timelineStartInfo=timelineStartInfo,pipeline.audioSegmentStream.setEarliestDts(timelineStartInfo.dts-self.baseMediaDecodeTime))})),pipeline.videoSegmentStream.on("processedGopsInfo",self.trigger.bind(self,"gopInfo")),pipeline.videoSegmentStream.on("segmentTimingInfo",self.trigger.bind(self,"videoSegmentTimingInfo")),pipeline.videoSegmentStream.on("baseMediaDecodeTime",(function(baseMediaDecodeTime){audioTrack&&pipeline.audioSegmentStream.setVideoBaseMediaDecodeTime(baseMediaDecodeTime)})),pipeline.videoSegmentStream.on("timingInfo",self.trigger.bind(self,"videoTimingInfo")),pipeline.h264Stream.pipe(pipeline.videoSegmentStream).pipe(pipeline.coalesceStream)),audioTrack&&!pipeline.audioSegmentStream&&(pipeline.coalesceStream.numberOfTracks++,pipeline.audioSegmentStream=new AudioSegmentStream(audioTrack,options),pipeline.audioSegmentStream.on("log",self.getLogTrigger_("audioSegmentStream")),pipeline.audioSegmentStream.on("timingInfo",self.trigger.bind(self,"audioTimingInfo")),pipeline.audioSegmentStream.on("segmentTimingInfo",self.trigger.bind(self,"audioSegmentTimingInfo")),pipeline.adtsStream.pipe(pipeline.audioSegmentStream).pipe(pipeline.coalesceStream)),self.trigger("trackinfo",{hasAudio:!!audioTrack,hasVideo:!!videoTrack})}})),pipeline.coalesceStream.on("data",this.trigger.bind(this,"data")),pipeline.coalesceStream.on("id3Frame",(function(id3Frame){id3Frame.dispatchType=pipeline.metadataStream.dispatchType,self.trigger("id3Frame",id3Frame)})),pipeline.coalesceStream.on("caption",this.trigger.bind(this,"caption")),pipeline.coalesceStream.on("done",this.trigger.bind(this,"done")),addPipelineLogRetriggers(this,pipeline)},this.setBaseMediaDecodeTime=function(baseMediaDecodeTime){var pipeline=this.transmuxPipeline_;options.keepOriginalTimestamps||(this.baseMediaDecodeTime=baseMediaDecodeTime),audioTrack&&(audioTrack.timelineStartInfo.dts=void 0,audioTrack.timelineStartInfo.pts=void 0,trackDecodeInfo.clearDtsInfo(audioTrack),pipeline.audioTimestampRolloverStream&&pipeline.audioTimestampRolloverStream.discontinuity()),videoTrack&&(pipeline.videoSegmentStream&&(pipeline.videoSegmentStream.gopCache_=[]),videoTrack.timelineStartInfo.dts=void 0,videoTrack.timelineStartInfo.pts=void 0,trackDecodeInfo.clearDtsInfo(videoTrack),pipeline.captionStream.reset()),pipeline.timestampRolloverStream&&pipeline.timestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(timestamp){audioTrack&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(timestamp)},this.setRemux=function(val){var pipeline=this.transmuxPipeline_;options.remux=val,pipeline&&pipeline.coalesceStream&&pipeline.coalesceStream.setRemux(val)},this.alignGopsWith=function(gopsToAlignWith){videoTrack&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(gopsToAlignWith)},this.getLogTrigger_=function(key){var self=this;return function(event){event.stream=key,self.trigger("log",event)}},this.push=function(data){if(hasFlushed){var isAac=isLikelyAacData(data);isAac&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():isAac||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),hasFlushed=!1}this.transmuxPipeline_.headOfPipeline.push(data)},this.flush=function(){hasFlushed=!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 Stream;var win,startTime,getTracks,getTimescaleFromMediaHeader,transmuxer={Transmuxer:Transmuxer,VideoSegmentStream:VideoSegmentStream,AudioSegmentStream:AudioSegmentStream,AUDIO_PROPERTIES:AUDIO_PROPERTIES,VIDEO_PROPERTIES:VIDEO_PROPERTIES,generateSegmentTimingInfo:generateSegmentTimingInfo},bin_toUnsigned=function(value){return value>>>0},parseType_1=function(buffer){var result="";return result+=String.fromCharCode(buffer[0]),result+=String.fromCharCode(buffer[1]),result+=String.fromCharCode(buffer[2]),result+=String.fromCharCode(buffer[3])},toUnsigned$2=bin_toUnsigned,parseType$2=parseType_1,findBox$2=function(data,path){var i,size,type,end,subresults,results=[];if(!path.length)return null;for(i=0;i1?i+size:data.byteLength,type===path[0]&&(1===path.length?results.push(data.subarray(i+8,end)):(subresults=findBox$2(data.subarray(i+8,end),path.slice(1))).length&&(results=results.concat(subresults))),i=end;return results},toUnsigned$1=bin_toUnsigned,getUint64$2=numbers.getUint64,parseTfdt$2=function(data){var result={version:data[0],flags:new Uint8Array(data.subarray(1,4))};return 1===result.version?result.baseMediaDecodeTime=getUint64$2(data.subarray(4)):result.baseMediaDecodeTime=toUnsigned$1(data[4]<<24|data[5]<<16|data[6]<<8|data[7]),result},parseSampleFlags=function(flags){return{isLeading:(12&flags[0])>>>2,dependsOn:3&flags[0],isDependedOn:(192&flags[1])>>>6,hasRedundancy:(48&flags[1])>>>4,paddingValue:(14&flags[1])>>>1,isNonSyncSample:1&flags[1],degradationPriority:flags[2]<<8|flags[3]}},parseTrun$2=function(data){var sample,result={version:data[0],flags:new Uint8Array(data.subarray(1,4)),samples:[]},view=new DataView(data.buffer,data.byteOffset,data.byteLength),dataOffsetPresent=1&result.flags[2],firstSampleFlagsPresent=4&result.flags[2],sampleDurationPresent=1&result.flags[1],sampleSizePresent=2&result.flags[1],sampleFlagsPresent=4&result.flags[1],sampleCompositionTimeOffsetPresent=8&result.flags[1],sampleCount=view.getUint32(4),offset=8;for(dataOffsetPresent&&(result.dataOffset=view.getInt32(offset),offset+=4),firstSampleFlagsPresent&&sampleCount&&(sample={flags:parseSampleFlags(data.subarray(offset,offset+4))},offset+=4,sampleDurationPresent&&(sample.duration=view.getUint32(offset),offset+=4),sampleSizePresent&&(sample.size=view.getUint32(offset),offset+=4),sampleCompositionTimeOffsetPresent&&(1===result.version?sample.compositionTimeOffset=view.getInt32(offset):sample.compositionTimeOffset=view.getUint32(offset),offset+=4),result.samples.push(sample),sampleCount--);sampleCount--;)sample={},sampleDurationPresent&&(sample.duration=view.getUint32(offset),offset+=4),sampleSizePresent&&(sample.size=view.getUint32(offset),offset+=4),sampleFlagsPresent&&(sample.flags=parseSampleFlags(data.subarray(offset,offset+4)),offset+=4),sampleCompositionTimeOffsetPresent&&(1===result.version?sample.compositionTimeOffset=view.getInt32(offset):sample.compositionTimeOffset=view.getUint32(offset),offset+=4),result.samples.push(sample);return result},parseTfhd$2=function(data){var i,view=new DataView(data.buffer,data.byteOffset,data.byteLength),result={version:data[0],flags:new Uint8Array(data.subarray(1,4)),trackId:view.getUint32(4)},baseDataOffsetPresent=1&result.flags[2],sampleDescriptionIndexPresent=2&result.flags[2],defaultSampleDurationPresent=8&result.flags[2],defaultSampleSizePresent=16&result.flags[2],defaultSampleFlagsPresent=32&result.flags[2],durationIsEmpty=65536&result.flags[0],defaultBaseIsMoof=131072&result.flags[0];return i=8,baseDataOffsetPresent&&(i+=4,result.baseDataOffset=view.getUint32(12),i+=4),sampleDescriptionIndexPresent&&(result.sampleDescriptionIndex=view.getUint32(i),i+=4),defaultSampleDurationPresent&&(result.defaultSampleDuration=view.getUint32(i),i+=4),defaultSampleSizePresent&&(result.defaultSampleSize=view.getUint32(i),i+=4),defaultSampleFlagsPresent&&(result.defaultSampleFlags=view.getUint32(i)),durationIsEmpty&&(result.durationIsEmpty=!0),!baseDataOffsetPresent&&defaultBaseIsMoof&&(result.baseDataOffsetIsMoof=!0),result},discardEmulationPreventionBytes=(win="undefined"!=typeof window?window:void 0!==commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{},captionPacketParser.discardEmulationPreventionBytes),CaptionStream=captionStream.CaptionStream,findBox$1=findBox$2,parseTfdt$1=parseTfdt$2,parseTrun$1=parseTrun$2,parseTfhd$1=parseTfhd$2,window$2=win,mapToSample=function(offset,samples){for(var approximateOffset=offset,i=0;i0?parseTfdt$1(tfdt[0]).baseMediaDecodeTime:0,truns=findBox$1(traf,["trun"]);videoTrackId===trackId&&truns.length>0&&(samples=function(truns,baseMediaDecodeTime,tfhd){var currentDts=baseMediaDecodeTime,defaultSampleDuration=tfhd.defaultSampleDuration||0,defaultSampleSize=tfhd.defaultSampleSize||0,trackId=tfhd.trackId,allSamples=[];return truns.forEach((function(trun){var samples=parseTrun$1(trun).samples;samples.forEach((function(sample){void 0===sample.duration&&(sample.duration=defaultSampleDuration),void 0===sample.size&&(sample.size=defaultSampleSize),sample.trackId=trackId,sample.dts=currentDts,void 0===sample.compositionTimeOffset&&(sample.compositionTimeOffset=0),"bigint"==typeof currentDts?(sample.pts=currentDts+window$2.BigInt(sample.compositionTimeOffset),currentDts+=window$2.BigInt(sample.duration)):(sample.pts=currentDts+sample.compositionTimeOffset,currentDts+=sample.duration)})),allSamples=allSamples.concat(samples)})),allSamples}(truns,baseMediaDecodeTime,headerInfo),result=function(avcStream,samples,trackId){var seiNal,i,length,lastMatchedSample,avcView=new DataView(avcStream.buffer,avcStream.byteOffset,avcStream.byteLength),result={logs:[],seiNals:[]};for(i=0;i+40;){var cachedSegment=segmentCache.shift();this.parse(cachedSegment,videoTrackIds,timescales)}return parsedData=function(segment,trackId,timescale){if(null===trackId)return null;var trackNals=parseCaptionNals(segment,trackId)[trackId]||{};return{seiNals:trackNals.seiNals,logs:trackNals.logs,timescale:timescale}}(segment,trackId,timescale),parsedData&&parsedData.logs&&(parsedCaptions.logs=parsedCaptions.logs.concat(parsedData.logs)),null!==parsedData&&parsedData.seiNals?(this.pushNals(parsedData.seiNals),this.flushStream(),parsedCaptions):parsedCaptions.logs.length?{logs:parsedCaptions.logs,captions:[],captionStreams:[]}:null},this.pushNals=function(nals){if(!this.isInitialized()||!nals||0===nals.length)return null;nals.forEach((function(nal){captionStream.push(nal)}))},this.flushStream=function(){if(!this.isInitialized())return null;parsingPartial?captionStream.partialFlush():captionStream.flush()},this.clearParsedCaptions=function(){parsedCaptions.captions=[],parsedCaptions.captionStreams={},parsedCaptions.logs=[]},this.resetCaptionStream=function(){if(!this.isInitialized())return null;captionStream.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){segmentCache=[],trackId=null,timescale=null,parsedCaptions?this.clearParsedCaptions():parsedCaptions={captions:[],captionStreams:{},logs:[]},this.resetCaptionStream()},this.reset()},uint8ToCString=function(data){for(var index=0,curChar=String.fromCharCode(data[index]),retString="";"\0"!==curChar;)retString+=curChar,index++,curChar=String.fromCharCode(data[index]);return retString+=curChar},getUint64$1=numbers.getUint64,isValidEmsgBox=function(version,emsg){var hasScheme="\0"!==emsg.scheme_id_uri,isValidV0Box=0===version&&isDefined(emsg.presentation_time_delta)&&hasScheme,isValidV1Box=1===version&&isDefined(emsg.presentation_time)&&hasScheme;return!(version>1)&&isValidV0Box||isValidV1Box},isDefined=function(data){return void 0!==data||null!==data},emsg$1={parseEmsgBox:function(boxData){var scheme_id_uri,value,timescale,presentation_time,presentation_time_delta,event_duration,id,offset=4,version=boxData[0];if(0===version)offset+=(scheme_id_uri=uint8ToCString(boxData.subarray(offset))).length,offset+=(value=uint8ToCString(boxData.subarray(offset))).length,timescale=(dv=new DataView(boxData.buffer)).getUint32(offset),offset+=4,presentation_time_delta=dv.getUint32(offset),offset+=4,event_duration=dv.getUint32(offset),offset+=4,id=dv.getUint32(offset),offset+=4;else if(1===version){var dv;timescale=(dv=new DataView(boxData.buffer)).getUint32(offset),offset+=4,presentation_time=getUint64$1(boxData.subarray(offset)),offset+=8,event_duration=dv.getUint32(offset),offset+=4,id=dv.getUint32(offset),offset+=4,offset+=(scheme_id_uri=uint8ToCString(boxData.subarray(offset))).length,offset+=(value=uint8ToCString(boxData.subarray(offset))).length}var emsgBox={scheme_id_uri:scheme_id_uri,value:value,timescale:timescale||1,presentation_time:presentation_time,presentation_time_delta:presentation_time_delta,event_duration:event_duration,id:id,message_data:new Uint8Array(boxData.subarray(offset,boxData.byteLength))};return isValidEmsgBox(version,emsgBox)?emsgBox:void 0},scaleTime:function(presentationTime,timescale,timeDelta,offset){return presentationTime||0===presentationTime?presentationTime/timescale:offset+timeDelta/timescale}},toUnsigned=bin_toUnsigned,toHexString=function(value){return("00"+value.toString(16)).slice(-2)},findBox=findBox$2,parseType$1=parseType_1,emsg=emsg$1,parseTfhd=parseTfhd$2,parseTrun=parseTrun$2,parseTfdt=parseTfdt$2,getUint64=numbers.getUint64,window$1=win,parseId3Frames=parseId3.parseId3Frames;startTime=function(timescale,fragment){var lowestTime=findBox(fragment,["moof","traf"]).reduce((function(acc,traf){var baseTime,tfhd=findBox(traf,["tfhd"])[0],id=toUnsigned(tfhd[4]<<24|tfhd[5]<<16|tfhd[6]<<8|tfhd[7]),scale=timescale[id]||9e4,tfdt=findBox(traf,["tfdt"])[0],dv=new DataView(tfdt.buffer,tfdt.byteOffset,tfdt.byteLength);let seconds;return"bigint"==typeof(baseTime=1===tfdt[0]?getUint64(tfdt.subarray(4,12)):dv.getUint32(4))?seconds=baseTime/window$1.BigInt(scale):"number"!=typeof baseTime||isNaN(baseTime)||(seconds=baseTime/scale),seconds11?(track.codec+=".",track.codec+=toHexString(codecConfig[9]),track.codec+=toHexString(codecConfig[10]),track.codec+=toHexString(codecConfig[11])):track.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(track.codec)?(codecConfig=codecBox.subarray(28),"esds"===parseType$1(codecConfig.subarray(4,8))&&codecConfig.length>20&&0!==codecConfig[19]?(track.codec+="."+toHexString(codecConfig[19]),track.codec+="."+toHexString(codecConfig[20]>>>2&63).replace(/^0/,"")):track.codec="mp4a.40.2"):track.codec=track.codec.toLowerCase())}var mdhd=findBox(trak,["mdia","mdhd"])[0];mdhd&&(track.timescale=getTimescaleFromMediaHeader(mdhd)),tracks.push(track)})),tracks};var probe$2_startTime=startTime,probe$2_tracks=getTracks,StreamTypes$1=streamTypes,parsePid=function(packet){var pid=31&packet[1];return pid<<=8,pid|=packet[2]},parsePayloadUnitStartIndicator=function(packet){return!!(64&packet[1])},parseAdaptionField=function(packet){var offset=0;return(48&packet[3])>>>4>1&&(offset+=packet[4]+1),offset},parseNalUnitType=function(type){switch(type){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}},probe$1={parseType:function(packet,pmtPid){var pid=parsePid(packet);return 0===pid?"pat":pid===pmtPid?"pmt":pmtPid?"pes":null},parsePat:function(packet){var pusi=parsePayloadUnitStartIndicator(packet),offset=4+parseAdaptionField(packet);return pusi&&(offset+=packet[offset]+1),(31&packet[offset+10])<<8|packet[offset+11]},parsePmt:function(packet){var programMapTable={},pusi=parsePayloadUnitStartIndicator(packet),payloadOffset=4+parseAdaptionField(packet);if(pusi&&(payloadOffset+=packet[payloadOffset]+1),1&packet[payloadOffset+5]){var tableEnd;tableEnd=3+((15&packet[payloadOffset+1])<<8|packet[payloadOffset+2])-4;for(var offset=12+((15&packet[payloadOffset+10])<<8|packet[payloadOffset+11]);offset=packet.byteLength)return null;var ptsDtsFlags,pes=null;return 192&(ptsDtsFlags=packet[offset+7])&&((pes={}).pts=(14&packet[offset+9])<<27|(255&packet[offset+10])<<20|(254&packet[offset+11])<<12|(255&packet[offset+12])<<5|(254&packet[offset+13])>>>3,pes.pts*=4,pes.pts+=(6&packet[offset+13])>>>1,pes.dts=pes.pts,64&ptsDtsFlags&&(pes.dts=(14&packet[offset+14])<<27|(255&packet[offset+15])<<20|(254&packet[offset+16])<<12|(255&packet[offset+17])<<5|(254&packet[offset+18])>>>3,pes.dts*=4,pes.dts+=(6&packet[offset+18])>>>1)),pes},videoPacketContainsKeyFrame:function(packet){for(var offset=4+parseAdaptionField(packet),frameBuffer=packet.subarray(offset),frameI=0,frameSyncPoint=0,foundKeyFrame=!1;frameSyncPoint3&&"slice_layer_without_partitioning_rbsp_idr"===parseNalUnitType(31&frameBuffer[frameSyncPoint+3])&&(foundKeyFrame=!0),foundKeyFrame}},StreamTypes=streamTypes,handleRollover=timestampRolloverStream.handleRollover,probe={};probe.ts=probe$1,probe.aac=utils;var ONE_SECOND_IN_TS=clock$2.ONE_SECOND_IN_TS,parseAudioPes_=function(bytes,pmt,result){for(var packet,pesType,pusi,parsed,startIndex=0,endIndex=188,endLoop=!1;endIndex<=bytes.byteLength;)if(71!==bytes[startIndex]||71!==bytes[endIndex]&&endIndex!==bytes.byteLength)startIndex++,endIndex++;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"audio"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="audio",result.audio.push(parsed),endLoop=!0);if(endLoop)break;startIndex+=188,endIndex+=188}for(startIndex=(endIndex=bytes.byteLength)-188,endLoop=!1;startIndex>=0;)if(71!==bytes[startIndex]||71!==bytes[endIndex]&&endIndex!==bytes.byteLength)startIndex--,endIndex--;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"audio"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="audio",result.audio.push(parsed),endLoop=!0);if(endLoop)break;startIndex-=188,endIndex-=188}},parseVideoPes_=function(bytes,pmt,result){for(var packet,pesType,pusi,parsed,frame,i,pes,startIndex=0,endIndex=188,endLoop=!1,currentFrame={data:[],size:0};endIndex=0;)if(71!==bytes[startIndex]||71!==bytes[endIndex])startIndex--,endIndex--;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"video"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="video",result.video.push(parsed),endLoop=!0);if(endLoop)break;startIndex-=188,endIndex-=188}},inspectTs_=function(bytes){var pmt={pid:null,table:null},result={};for(var pid in function(bytes,pmt){for(var packet,startIndex=0,endIndex=188;endIndex=3;){switch(probe.aac.parseType(bytes,byteIndex)){case"timed-metadata":if(bytes.length-byteIndex<10){endLoop=!0;break}if((frameSize=probe.aac.parseId3TagSize(bytes,byteIndex))>bytes.length){endLoop=!0;break}null===timestamp&&(packet=bytes.subarray(byteIndex,byteIndex+frameSize),timestamp=probe.aac.parseAacTimestamp(packet)),byteIndex+=frameSize;break;case"audio":if(bytes.length-byteIndex<7){endLoop=!0;break}if((frameSize=probe.aac.parseAdtsSize(bytes,byteIndex))>bytes.length){endLoop=!0;break}null===sampleRate&&(packet=bytes.subarray(byteIndex,byteIndex+frameSize),sampleRate=probe.aac.parseSampleRate(packet)),audioCount++,byteIndex+=frameSize;break;default:byteIndex++}if(endLoop)return null}if(null===sampleRate||null===timestamp)return null;var audioTimescale=ONE_SECOND_IN_TS/sampleRate;return{audio:[{type:"audio",dts:timestamp,pts:timestamp},{type:"audio",dts:timestamp+1024*audioCount*audioTimescale,pts:timestamp+1024*audioCount*audioTimescale}]}}(bytes):inspectTs_(bytes),result&&(result.audio||result.video)?(function(segmentInfo,baseTimestamp){if(segmentInfo.audio&&segmentInfo.audio.length){var audioBaseTimestamp=baseTimestamp;(void 0===audioBaseTimestamp||isNaN(audioBaseTimestamp))&&(audioBaseTimestamp=segmentInfo.audio[0].dts),segmentInfo.audio.forEach((function(info){info.dts=handleRollover(info.dts,audioBaseTimestamp),info.pts=handleRollover(info.pts,audioBaseTimestamp),info.dtsTime=info.dts/ONE_SECOND_IN_TS,info.ptsTime=info.pts/ONE_SECOND_IN_TS}))}if(segmentInfo.video&&segmentInfo.video.length){var videoBaseTimestamp=baseTimestamp;if((void 0===videoBaseTimestamp||isNaN(videoBaseTimestamp))&&(videoBaseTimestamp=segmentInfo.video[0].dts),segmentInfo.video.forEach((function(info){info.dts=handleRollover(info.dts,videoBaseTimestamp),info.pts=handleRollover(info.pts,videoBaseTimestamp),info.dtsTime=info.dts/ONE_SECOND_IN_TS,info.ptsTime=info.pts/ONE_SECOND_IN_TS})),segmentInfo.firstKeyFrame){var frame=segmentInfo.firstKeyFrame;frame.dts=handleRollover(frame.dts,videoBaseTimestamp),frame.pts=handleRollover(frame.pts,videoBaseTimestamp),frame.dtsTime=frame.dts/ONE_SECOND_IN_TS,frame.ptsTime=frame.pts/ONE_SECOND_IN_TS}}}(result,baseTimestamp),result):null};class MessageHandlers{constructor(self,options){this.options=options||{},this.self=self,this.init()}init(){this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new transmuxer.Transmuxer(this.options),function(self,transmuxer){transmuxer.on("data",(function(segment){const initArray=segment.initSegment;segment.initSegment={data:initArray.buffer,byteOffset:initArray.byteOffset,byteLength:initArray.byteLength};const typedArray=segment.data;segment.data=typedArray.buffer,self.postMessage({action:"data",segment:segment,byteOffset:typedArray.byteOffset,byteLength:typedArray.byteLength},[segment.data])})),transmuxer.on("done",(function(data){self.postMessage({action:"done"})})),transmuxer.on("gopInfo",(function(gopInfo){self.postMessage({action:"gopInfo",gopInfo:gopInfo})})),transmuxer.on("videoSegmentTimingInfo",(function(timingInfo){const videoSegmentTimingInfo={start:{decode:clock$2.videoTsToSeconds(timingInfo.start.dts),presentation:clock$2.videoTsToSeconds(timingInfo.start.pts)},end:{decode:clock$2.videoTsToSeconds(timingInfo.end.dts),presentation:clock$2.videoTsToSeconds(timingInfo.end.pts)},baseMediaDecodeTime:clock$2.videoTsToSeconds(timingInfo.baseMediaDecodeTime)};timingInfo.prependedContentDuration&&(videoSegmentTimingInfo.prependedContentDuration=clock$2.videoTsToSeconds(timingInfo.prependedContentDuration)),self.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:videoSegmentTimingInfo})})),transmuxer.on("audioSegmentTimingInfo",(function(timingInfo){const audioSegmentTimingInfo={start:{decode:clock$2.videoTsToSeconds(timingInfo.start.dts),presentation:clock$2.videoTsToSeconds(timingInfo.start.pts)},end:{decode:clock$2.videoTsToSeconds(timingInfo.end.dts),presentation:clock$2.videoTsToSeconds(timingInfo.end.pts)},baseMediaDecodeTime:clock$2.videoTsToSeconds(timingInfo.baseMediaDecodeTime)};timingInfo.prependedContentDuration&&(audioSegmentTimingInfo.prependedContentDuration=clock$2.videoTsToSeconds(timingInfo.prependedContentDuration)),self.postMessage({action:"audioSegmentTimingInfo",audioSegmentTimingInfo:audioSegmentTimingInfo})})),transmuxer.on("id3Frame",(function(id3Frame){self.postMessage({action:"id3Frame",id3Frame:id3Frame})})),transmuxer.on("caption",(function(caption){self.postMessage({action:"caption",caption:caption})})),transmuxer.on("trackinfo",(function(trackInfo){self.postMessage({action:"trackinfo",trackInfo:trackInfo})})),transmuxer.on("audioTimingInfo",(function(audioTimingInfo){self.postMessage({action:"audioTimingInfo",audioTimingInfo:{start:clock$2.videoTsToSeconds(audioTimingInfo.start),end:clock$2.videoTsToSeconds(audioTimingInfo.end)}})})),transmuxer.on("videoTimingInfo",(function(videoTimingInfo){self.postMessage({action:"videoTimingInfo",videoTimingInfo:{start:clock$2.videoTsToSeconds(videoTimingInfo.start),end:clock$2.videoTsToSeconds(videoTimingInfo.end)}})})),transmuxer.on("log",(function(log){self.postMessage({action:"log",log:log})}))}(this.self,this.transmuxer)}pushMp4Captions(data){this.captionParser||(this.captionParser=new captionParser,this.captionParser.init());const segment=new Uint8Array(data.data,data.byteOffset,data.byteLength),parsed=this.captionParser.parse(segment,data.trackIds,data.timescales);this.self.postMessage({action:"mp4Captions",captions:parsed&&parsed.captions||[],logs:parsed&&parsed.logs||[],data:segment.buffer},[segment.buffer])}probeMp4StartTime(_ref43){let{timescales:timescales,data:data}=_ref43;const startTime=probe$2_startTime(timescales,data);this.self.postMessage({action:"probeMp4StartTime",startTime:startTime,data:data},[data.buffer])}probeMp4Tracks(_ref44){let{data:data}=_ref44;const tracks=probe$2_tracks(data);this.self.postMessage({action:"probeMp4Tracks",tracks:tracks,data:data},[data.buffer])}probeTs(_ref45){let{data:data,baseStartTime:baseStartTime}=_ref45;const tsStartTime="number"!=typeof baseStartTime||isNaN(baseStartTime)?void 0:baseStartTime*clock$2.ONE_SECOND_IN_TS,timeInfo=tsInspector_inspect(data,tsStartTime);let result=null;timeInfo&&(result={hasVideo:timeInfo.video&&2===timeInfo.video.length||!1,hasAudio:timeInfo.audio&&2===timeInfo.audio.length||!1},result.hasVideo&&(result.videoStart=timeInfo.video[0].ptsTime),result.hasAudio&&(result.audioStart=timeInfo.audio[0].ptsTime)),this.self.postMessage({action:"probeTs",result:result,data:data},[data.buffer])}clearAllMp4Captions(){this.captionParser&&this.captionParser.clearAllCaptions()}clearParsedMp4Captions(){this.captionParser&&this.captionParser.clearParsedCaptions()}push(data){const segment=new Uint8Array(data.data,data.byteOffset,data.byteLength);this.transmuxer.push(segment)}reset(){this.transmuxer.reset()}setTimestampOffset(data){const timestampOffset=data.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(clock$2.secondsToVideoTs(timestampOffset)))}setAudioAppendStart(data){this.transmuxer.setAudioAppendStart(Math.ceil(clock$2.secondsToVideoTs(data.appendStart)))}setRemux(data){this.transmuxer.setRemux(data.remux)}flush(data){this.transmuxer.flush(),self.postMessage({action:"done",type:"transmuxed"})}endTimeline(){this.transmuxer.endTimeline(),self.postMessage({action:"endedtimeline",type:"transmuxed"})}alignGopsWith(data){this.transmuxer.alignGopsWith(data.gopsToAlignWith.slice())}}self.onmessage=function(event){"init"===event.data.action&&event.data.options?this.messageHandlers=new MessageHandlers(self,event.data.options):(this.messageHandlers||(this.messageHandlers=new MessageHandlers(self)),event.data&&event.data.action&&"init"!==event.data.action&&this.messageHandlers[event.data.action]&&this.messageHandlers[event.data.action](event.data))}})));var TransmuxWorker=factory(workerCode$1);const processTransmux=options=>{const{transmuxer:transmuxer,bytes:bytes,audioAppendStart:audioAppendStart,gopsToAlignWith:gopsToAlignWith,remux:remux,onData:onData,onTrackInfo:onTrackInfo,onAudioTimingInfo:onAudioTimingInfo,onVideoTimingInfo:onVideoTimingInfo,onVideoSegmentTimingInfo:onVideoSegmentTimingInfo,onAudioSegmentTimingInfo:onAudioSegmentTimingInfo,onId3:onId3,onCaptions:onCaptions,onDone:onDone,onEndedTimeline:onEndedTimeline,onTransmuxerLog:onTransmuxerLog,isEndOfTimeline:isEndOfTimeline}=options,transmuxedData={buffer:[]};let waitForEndedTimelineEvent=isEndOfTimeline;if(transmuxer.onmessage=event=>{transmuxer.currentTransmux===options&&("data"===event.data.action&&((event,transmuxedData,callback)=>{const{type:type,initSegment:initSegment,captions:captions,captionStreams:captionStreams,metadata:metadata,videoFrameDtsTime:videoFrameDtsTime,videoFramePtsTime:videoFramePtsTime}=event.data.segment;transmuxedData.buffer.push({captions:captions,captionStreams:captionStreams,metadata:metadata});const boxes=event.data.segment.boxes||{data:event.data.segment.data},result={type:type,data:new Uint8Array(boxes.data,boxes.data.byteOffset,boxes.data.byteLength),initSegment:new Uint8Array(initSegment.data,initSegment.byteOffset,initSegment.byteLength)};void 0!==videoFrameDtsTime&&(result.videoFrameDtsTime=videoFrameDtsTime),void 0!==videoFramePtsTime&&(result.videoFramePtsTime=videoFramePtsTime),callback(result)})(event,transmuxedData,onData),"trackinfo"===event.data.action&&onTrackInfo(event.data.trackInfo),"gopInfo"===event.data.action&&((event,transmuxedData)=>{transmuxedData.gopInfo=event.data.gopInfo})(event,transmuxedData),"audioTimingInfo"===event.data.action&&onAudioTimingInfo(event.data.audioTimingInfo),"videoTimingInfo"===event.data.action&&onVideoTimingInfo(event.data.videoTimingInfo),"videoSegmentTimingInfo"===event.data.action&&onVideoSegmentTimingInfo(event.data.videoSegmentTimingInfo),"audioSegmentTimingInfo"===event.data.action&&onAudioSegmentTimingInfo(event.data.audioSegmentTimingInfo),"id3Frame"===event.data.action&&onId3([event.data.id3Frame],event.data.id3Frame.dispatchType),"caption"===event.data.action&&onCaptions(event.data.caption),"endedtimeline"===event.data.action&&(waitForEndedTimelineEvent=!1,onEndedTimeline()),"log"===event.data.action&&onTransmuxerLog(event.data.log),"transmuxed"===event.data.type&&(waitForEndedTimelineEvent||(transmuxer.onmessage=null,(_ref46=>{let{transmuxedData:transmuxedData,callback:callback}=_ref46;transmuxedData.buffer=[],callback(transmuxedData)})({transmuxedData:transmuxedData,callback:onDone}),dequeue(transmuxer))))},audioAppendStart&&transmuxer.postMessage({action:"setAudioAppendStart",appendStart:audioAppendStart}),Array.isArray(gopsToAlignWith)&&transmuxer.postMessage({action:"alignGopsWith",gopsToAlignWith:gopsToAlignWith}),void 0!==remux&&transmuxer.postMessage({action:"setRemux",remux:remux}),bytes.byteLength){const buffer=bytes instanceof ArrayBuffer?bytes:bytes.buffer,byteOffset=bytes instanceof ArrayBuffer?0:bytes.byteOffset;transmuxer.postMessage({action:"push",data:buffer,byteOffset:byteOffset,byteLength:bytes.byteLength},[buffer])}isEndOfTimeline&&transmuxer.postMessage({action:"endTimeline"}),transmuxer.postMessage({action:"flush"})},dequeue=transmuxer=>{transmuxer.currentTransmux=null,transmuxer.transmuxQueue.length&&(transmuxer.currentTransmux=transmuxer.transmuxQueue.shift(),"function"==typeof transmuxer.currentTransmux?transmuxer.currentTransmux():processTransmux(transmuxer.currentTransmux))},processAction=(transmuxer,action)=>{transmuxer.postMessage({action:action}),dequeue(transmuxer)},enqueueAction=(action,transmuxer)=>{if(!transmuxer.currentTransmux)return transmuxer.currentTransmux=action,void processAction(transmuxer,action);transmuxer.transmuxQueue.push(processAction.bind(null,transmuxer,action))},transmux=options=>{if(!options.transmuxer.currentTransmux)return options.transmuxer.currentTransmux=options,void processTransmux(options);options.transmuxer.transmuxQueue.push(options)};var segmentTransmuxer_reset=transmuxer=>{enqueueAction("reset",transmuxer)},segmentTransmuxer_createTransmuxer=options=>{const transmuxer=new TransmuxWorker;transmuxer.currentTransmux=null,transmuxer.transmuxQueue=[];const term=transmuxer.terminate;return transmuxer.terminate=()=>(transmuxer.currentTransmux=null,transmuxer.transmuxQueue.length=0,term.call(transmuxer)),transmuxer.postMessage({action:"init",options:options}),transmuxer};const workerCallback=function(options){const transmuxer=options.transmuxer,endAction=options.endAction||options.action,callback=options.callback,message=_extends$1({},options,{endAction:null,transmuxer:null,callback:null}),listenForEndEvent=event=>{event.data.action===endAction&&(transmuxer.removeEventListener("message",listenForEndEvent),event.data.data&&(event.data.data=new Uint8Array(event.data.data,options.byteOffset||0,options.byteLength||event.data.data.byteLength),options.data&&(options.data=event.data.data)),callback(event.data))};if(transmuxer.addEventListener("message",listenForEndEvent),options.data){const isArrayBuffer=options.data instanceof ArrayBuffer;message.byteOffset=isArrayBuffer?0:options.data.byteOffset,message.byteLength=options.data.byteLength;const transfers=[isArrayBuffer?options.data:options.data.buffer];transmuxer.postMessage(message,transfers)}else transmuxer.postMessage(message)},REQUEST_ERRORS_FAILURE=2,REQUEST_ERRORS_TIMEOUT=-101,REQUEST_ERRORS_ABORTED=-102,abortAll=activeXhrs=>{activeXhrs.forEach((xhr=>{xhr.abort()}))},handleErrors=(error,request)=>request.timedout?{status:request.status,message:"HLS request timed-out at URL: "+request.uri,code:REQUEST_ERRORS_TIMEOUT,xhr:request}:request.aborted?{status:request.status,message:"HLS request aborted at URL: "+request.uri,code:REQUEST_ERRORS_ABORTED,xhr:request}:error?{status:request.status,message:"HLS request errored at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request}:"arraybuffer"===request.responseType&&0===request.response.byteLength?{status:request.status,message:"Empty HLS response at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request}:null,handleKeyResponse=(segment,objects,finishProcessingFn)=>(error,request)=>{const response=request.response,errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);if(16!==response.byteLength)return finishProcessingFn({status:request.status,message:"Invalid HLS key at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request},segment);const view=new DataView(response),bytes=new Uint32Array([view.getUint32(0),view.getUint32(4),view.getUint32(8),view.getUint32(12)]);for(let i=0;i{const type=detectContainerForBytes(segment.map.bytes);if("mp4"!==type){const uri=segment.map.resolvedUri||segment.map.uri;return callback({internal:!0,message:"Found unsupported ".concat(type||"unknown"," container for initialization segment at URL: ").concat(uri),code:REQUEST_ERRORS_FAILURE})}workerCallback({action:"probeMp4Tracks",data:segment.map.bytes,transmuxer:segment.transmuxer,callback:_ref47=>{let{tracks:tracks,data:data}=_ref47;return segment.map.bytes=data,tracks.forEach((function(track){segment.map.tracks=segment.map.tracks||{},segment.map.tracks[track.type]||(segment.map.tracks[track.type]=track,"number"==typeof track.id&&track.timescale&&(segment.map.timescales=segment.map.timescales||{},segment.map.timescales[track.id]=track.timescale))})),callback(null)}})},handleSegmentResponse=_ref49=>{let{segment:segment,finishProcessingFn:finishProcessingFn,responseType:responseType}=_ref49;return(error,request)=>{const errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);const newBytes="arraybuffer"!==responseType&&request.responseText?(string=>{const view=new Uint8Array(new ArrayBuffer(string.length));for(let i=0;i({bandwidth:request.bandwidth,bytesReceived:request.bytesReceived||0,roundTripTime:request.roundTripTime||0}))(request),segment.key?segment.encryptedBytes=new Uint8Array(newBytes):segment.bytes=new Uint8Array(newBytes),finishProcessingFn(null,segment)}},transmuxAndNotify=_ref50=>{let{segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref50;const fmp4Tracks=segment.map&&segment.map.tracks||{},isMuxed=Boolean(fmp4Tracks.audio&&fmp4Tracks.video);let audioStartFn=timingInfoFn.bind(null,segment,"audio","start");const audioEndFn=timingInfoFn.bind(null,segment,"audio","end");let videoStartFn=timingInfoFn.bind(null,segment,"video","start");const videoEndFn=timingInfoFn.bind(null,segment,"video","end");workerCallback({action:"probeTs",transmuxer:segment.transmuxer,data:bytes,baseStartTime:segment.baseStartTime,callback:data=>{segment.bytes=bytes=data.data;const probeResult=data.result;probeResult&&(trackInfoFn(segment,{hasAudio:probeResult.hasAudio,hasVideo:probeResult.hasVideo,isMuxed:isMuxed}),trackInfoFn=null,probeResult.hasAudio&&!isMuxed&&audioStartFn(probeResult.audioStart),probeResult.hasVideo&&videoStartFn(probeResult.videoStart),audioStartFn=null,videoStartFn=null),transmux({bytes:bytes,transmuxer:segment.transmuxer,audioAppendStart:segment.audioAppendStart,gopsToAlignWith:segment.gopsToAlignWith,remux:isMuxed,onData:result=>{result.type="combined"===result.type?"video":result.type,dataFn(segment,result)},onTrackInfo:trackInfo=>{trackInfoFn&&(isMuxed&&(trackInfo.isMuxed=!0),trackInfoFn(segment,trackInfo))},onAudioTimingInfo:audioTimingInfo=>{audioStartFn&&void 0!==audioTimingInfo.start&&(audioStartFn(audioTimingInfo.start),audioStartFn=null),audioEndFn&&void 0!==audioTimingInfo.end&&audioEndFn(audioTimingInfo.end)},onVideoTimingInfo:videoTimingInfo=>{videoStartFn&&void 0!==videoTimingInfo.start&&(videoStartFn(videoTimingInfo.start),videoStartFn=null),videoEndFn&&void 0!==videoTimingInfo.end&&videoEndFn(videoTimingInfo.end)},onVideoSegmentTimingInfo:videoSegmentTimingInfo=>{videoSegmentTimingInfoFn(videoSegmentTimingInfo)},onAudioSegmentTimingInfo:audioSegmentTimingInfo=>{audioSegmentTimingInfoFn(audioSegmentTimingInfo)},onId3:(id3Frames,dispatchType)=>{id3Fn(segment,id3Frames,dispatchType)},onCaptions:captions=>{captionsFn(segment,[captions])},isEndOfTimeline:isEndOfTimeline,onEndedTimeline:()=>{endedTimelineFn()},onTransmuxerLog:onTransmuxerLog,onDone:result=>{doneFn&&(result.type="combined"===result.type?"video":result.type,doneFn(null,segment,result))}})}})},handleSegmentBytes=_ref51=>{let{segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref51,bytesAsUint8Array=new Uint8Array(bytes);if(function(bytes){return findBox(bytes,["moof"]).length>0}(bytesAsUint8Array)){segment.isFmp4=!0;const{tracks:tracks}=segment.map,trackInfo={isFmp4:!0,hasVideo:!!tracks.video,hasAudio:!!tracks.audio};tracks.audio&&tracks.audio.codec&&"enca"!==tracks.audio.codec&&(trackInfo.audioCodec=tracks.audio.codec),tracks.video&&tracks.video.codec&&"encv"!==tracks.video.codec&&(trackInfo.videoCodec=tracks.video.codec),tracks.video&&tracks.audio&&(trackInfo.isMuxed=!0),trackInfoFn(segment,trackInfo);const finishLoading=captions=>{dataFn(segment,{data:bytesAsUint8Array,type:trackInfo.hasAudio&&!trackInfo.isMuxed?"audio":"video"}),captions&&captions.length&&captionsFn(segment,captions),doneFn(null,segment,{})};workerCallback({action:"probeMp4StartTime",timescales:segment.map.timescales,data:bytesAsUint8Array,transmuxer:segment.transmuxer,callback:_ref52=>{let{data:data,startTime:startTime}=_ref52;bytes=data.buffer,segment.bytes=bytesAsUint8Array=data,trackInfo.hasAudio&&!trackInfo.isMuxed&&timingInfoFn(segment,"audio","start",startTime),trackInfo.hasVideo&&timingInfoFn(segment,"video","start",startTime),tracks.video&&data.byteLength&&segment.transmuxer?workerCallback({action:"pushMp4Captions",endAction:"mp4Captions",transmuxer:segment.transmuxer,data:bytesAsUint8Array,timescales:segment.map.timescales,trackIds:[tracks.video.id],callback:message=>{bytes=message.data.buffer,segment.bytes=bytesAsUint8Array=message.data,message.logs.forEach((function(log){onTransmuxerLog(merge(log,{stream:"mp4CaptionParser"}))})),finishLoading(message.captions)}}):finishLoading()}})}else if(segment.transmuxer){if(void 0===segment.container&&(segment.container=detectContainerForBytes(bytesAsUint8Array)),"ts"!==segment.container&&"aac"!==segment.container)return trackInfoFn(segment,{hasAudio:!1,hasVideo:!1}),void doneFn(null,segment,{});transmuxAndNotify({segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})}else doneFn(null,segment,{})},decrypt=function(_ref53,callback){let{id:id,key:key,encryptedBytes:encryptedBytes,decryptionWorker:decryptionWorker}=_ref53;const decryptionHandler=event=>{if(event.data.source===id){decryptionWorker.removeEventListener("message",decryptionHandler);const decrypted=event.data.decrypted;callback(new Uint8Array(decrypted.bytes,decrypted.byteOffset,decrypted.byteLength))}};let keyBytes;decryptionWorker.addEventListener("message",decryptionHandler),keyBytes=key.bytes.slice?key.bytes.slice():new Uint32Array(Array.prototype.slice.call(key.bytes)),decryptionWorker.postMessage(createTransferableMessage({source:id,encrypted:encryptedBytes,key:keyBytes,iv:key.iv}),[encryptedBytes.buffer,keyBytes.buffer])},waitForCompletion=_ref55=>{let{activeXhrs:activeXhrs,decryptionWorker:decryptionWorker,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref55,count=0,didError=!1;return(error,segment)=>{if(!didError){if(error)return didError=!0,abortAll(activeXhrs),doneFn(error,segment);if(count+=1,count===activeXhrs.length){const segmentFinish=function(){if(segment.encryptedBytes)return(_ref54=>{let{decryptionWorker:decryptionWorker,segment:segment,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref54;decrypt({id:segment.requestId,key:segment.key,encryptedBytes:segment.encryptedBytes,decryptionWorker:decryptionWorker},(decryptedBytes=>{segment.bytes=decryptedBytes,handleSegmentBytes({segment:segment,bytes:segment.bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})}))})({decryptionWorker:decryptionWorker,segment:segment,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog});handleSegmentBytes({segment:segment,bytes:segment.bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})};if(segment.endOfAllRequests=Date.now(),segment.map&&segment.map.encryptedBytes&&!segment.map.bytes)return decrypt({decryptionWorker:decryptionWorker,id:segment.requestId+"-init",encryptedBytes:segment.map.encryptedBytes,key:segment.map.key},(decryptedBytes=>{segment.map.bytes=decryptedBytes,parseInitSegment(segment,(parseError=>{if(parseError)return abortAll(activeXhrs),doneFn(parseError,segment);segmentFinish()}))}));segmentFinish()}}}},handleProgress=_ref57=>{let{segment:segment,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn}=_ref57;return event=>{if(!event.target.aborted)return segment.stats=merge(segment.stats,(progressEvent=>{const request=progressEvent.target,stats={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-request.requestTime||0};return stats.bytesReceived=progressEvent.loaded,stats.bandwidth=Math.floor(stats.bytesReceived/stats.roundTripTime*8*1e3),stats})(event)),!segment.stats.firstBytesReceivedAt&&segment.stats.bytesReceived&&(segment.stats.firstBytesReceivedAt=Date.now()),progressFn(event,segment)}},mediaSegmentRequest=_ref58=>{let{xhr:xhr,xhrOptions:xhrOptions,decryptionWorker:decryptionWorker,segment:segment,abortFn:abortFn,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref58;const activeXhrs=[],finishProcessingFn=waitForCompletion({activeXhrs:activeXhrs,decryptionWorker:decryptionWorker,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog});if(segment.key&&!segment.key.bytes){const objects=[segment.key];segment.map&&!segment.map.bytes&&segment.map.key&&segment.map.key.resolvedUri===segment.key.resolvedUri&&objects.push(segment.map.key);const keyXhr=xhr(merge(xhrOptions,{uri:segment.key.resolvedUri,responseType:"arraybuffer"}),handleKeyResponse(segment,objects,finishProcessingFn));activeXhrs.push(keyXhr)}if(segment.map&&!segment.map.bytes){if(segment.map.key&&(!segment.key||segment.key.resolvedUri!==segment.map.key.resolvedUri)){const mapKeyXhr=xhr(merge(xhrOptions,{uri:segment.map.key.resolvedUri,responseType:"arraybuffer"}),handleKeyResponse(segment,[segment.map.key],finishProcessingFn));activeXhrs.push(mapKeyXhr)}const initSegmentOptions=merge(xhrOptions,{uri:segment.map.resolvedUri,responseType:"arraybuffer",headers:segmentXhrHeaders(segment.map)}),initSegmentRequestCallback=(_ref48=>{let{segment:segment,finishProcessingFn:finishProcessingFn}=_ref48;return(error,request)=>{const errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);const bytes=new Uint8Array(request.response);if(segment.map.key)return segment.map.encryptedBytes=bytes,finishProcessingFn(null,segment);segment.map.bytes=bytes,parseInitSegment(segment,(function(parseError){if(parseError)return parseError.xhr=request,parseError.status=request.status,finishProcessingFn(parseError,segment);finishProcessingFn(null,segment)}))}})({segment:segment,finishProcessingFn:finishProcessingFn}),initSegmentXhr=xhr(initSegmentOptions,initSegmentRequestCallback);activeXhrs.push(initSegmentXhr)}const segmentRequestOptions=merge(xhrOptions,{uri:segment.part&&segment.part.resolvedUri||segment.resolvedUri,responseType:"arraybuffer",headers:segmentXhrHeaders(segment)}),segmentXhr=xhr(segmentRequestOptions,handleSegmentResponse({segment:segment,finishProcessingFn:finishProcessingFn,responseType:segmentRequestOptions.responseType}));segmentXhr.addEventListener("progress",handleProgress({segment:segment,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn})),activeXhrs.push(segmentXhr);const loadendState={};return activeXhrs.forEach((activeXhr=>{activeXhr.addEventListener("loadend",(_ref56=>{let{loadendState:loadendState,abortFn:abortFn}=_ref56;return event=>{event.target.aborted&&abortFn&&!loadendState.calledAbortFn&&(abortFn(),loadendState.calledAbortFn=!0)}})({loadendState:loadendState,abortFn:abortFn}))})),()=>abortAll(activeXhrs)},logFn$1=logger("CodecUtils"),isMaat=(main,media)=>{const mediaAttributes=media.attributes||{};return main&&main.mediaGroups&&main.mediaGroups.AUDIO&&mediaAttributes.AUDIO&&main.mediaGroups.AUDIO[mediaAttributes.AUDIO]},unwrapCodecList=function(codecList){const codecs={};return codecList.forEach((_ref59=>{let{mediaType:mediaType,type:type,details:details}=_ref59;codecs[mediaType]=codecs[mediaType]||[],codecs[mediaType].push(translateLegacyCodec("".concat(type).concat(details)))})),Object.keys(codecs).forEach((function(mediaType){if(codecs[mediaType].length>1)return logFn$1("multiple ".concat(mediaType," codecs found as attributes: ").concat(codecs[mediaType].join(", "),". Setting playlist codecs to null so that we wait for mux.js to probe segments for real codecs.")),void(codecs[mediaType]=null);codecs[mediaType]=codecs[mediaType][0]})),codecs},codecCount=function(codecObj){let count=0;return codecObj.audio&&count++,codecObj.video&&count++,count},codecsForPlaylist=function(main,media){const mediaAttributes=media.attributes||{},codecInfo=unwrapCodecList(function(media){const mediaAttributes=media.attributes||{};if(mediaAttributes.CODECS)return parseCodecs(mediaAttributes.CODECS)}(media)||[]);if(isMaat(main,media)&&!codecInfo.audio&&!((main,media)=>{if(!isMaat(main,media))return!0;const mediaAttributes=media.attributes||{},audioGroup=main.mediaGroups.AUDIO[mediaAttributes.AUDIO];for(const groupId in audioGroup)if(!audioGroup[groupId].uri&&!audioGroup[groupId].playlists)return!0;return!1})(main,media)){const defaultCodecs=unwrapCodecList(function(master,audioGroupId){if(!master.mediaGroups.AUDIO||!audioGroupId)return null;var audioGroup=master.mediaGroups.AUDIO[audioGroupId];if(!audioGroup)return null;for(var name in audioGroup){var audioType=audioGroup[name];if(audioType.default&&audioType.playlists)return parseCodecs(audioType.playlists[0].attributes.CODECS)}return null}(main,mediaAttributes.AUDIO)||[]);defaultCodecs.audio&&(codecInfo.audio=defaultCodecs.audio)}return codecInfo},logFn=logger("PlaylistSelector"),representationToString=function(representation){if(!representation||!representation.playlist)return;const playlist=representation.playlist;return JSON.stringify({id:playlist.id,bandwidth:representation.bandwidth,width:representation.width,height:representation.height,codecs:playlist.attributes&&playlist.attributes.CODECS||""})},safeGetComputedStyle=function(el,property){if(!el)return"";const result=window.getComputedStyle(el);return result?result[property]:""},stableSort=function(array,sortFn){const newArray=array.slice();array.sort((function(left,right){const cmp=sortFn(left,right);return 0===cmp?newArray.indexOf(left)-newArray.indexOf(right):cmp}))},comparePlaylistBandwidth=function(left,right){let leftBandwidth,rightBandwidth;return left.attributes.BANDWIDTH&&(leftBandwidth=left.attributes.BANDWIDTH),leftBandwidth=leftBandwidth||window.Number.MAX_VALUE,right.attributes.BANDWIDTH&&(rightBandwidth=right.attributes.BANDWIDTH),rightBandwidth=rightBandwidth||window.Number.MAX_VALUE,leftBandwidth-rightBandwidth};let simpleSelector=function(main,playerBandwidth,playerWidth,playerHeight,limitRenditionByPlayerDimensions,playlistController){if(!main)return;const options={bandwidth:playerBandwidth,width:playerWidth,height:playerHeight,limitRenditionByPlayerDimensions:limitRenditionByPlayerDimensions};let playlists=main.playlists;Playlist.isAudioOnly(main)&&(playlists=playlistController.getAudioTrackPlaylists_(),options.audioOnly=!0);let sortedPlaylistReps=playlists.map((playlist=>{let bandwidth;const width=playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.width,height=playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.height;return bandwidth=playlist.attributes&&playlist.attributes.BANDWIDTH,bandwidth=bandwidth||window.Number.MAX_VALUE,{bandwidth:bandwidth,width:width,height:height,playlist:playlist}}));stableSort(sortedPlaylistReps,((left,right)=>left.bandwidth-right.bandwidth)),sortedPlaylistReps=sortedPlaylistReps.filter((rep=>!Playlist.isIncompatible(rep.playlist)));let enabledPlaylistReps=sortedPlaylistReps.filter((rep=>Playlist.isEnabled(rep.playlist)));enabledPlaylistReps.length||(enabledPlaylistReps=sortedPlaylistReps.filter((rep=>!Playlist.isDisabled(rep.playlist))));const bandwidthPlaylistReps=enabledPlaylistReps.filter((rep=>rep.bandwidth*Config.BANDWIDTH_VARIANCErep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0];if(!1===limitRenditionByPlayerDimensions){const chosenRep=bandwidthBestRep||enabledPlaylistReps[0]||sortedPlaylistReps[0];if(chosenRep&&chosenRep.playlist){let type="sortedPlaylistReps";return bandwidthBestRep&&(type="bandwidthBestRep"),enabledPlaylistReps[0]&&(type="enabledPlaylistReps"),logFn("choosing ".concat(representationToString(chosenRep)," using ").concat(type," with options"),options),chosenRep.playlist}return logFn("could not choose a playlist with options",options),null}const haveResolution=bandwidthPlaylistReps.filter((rep=>rep.width&&rep.height));stableSort(haveResolution,((left,right)=>left.width-right.width));const resolutionBestRepList=haveResolution.filter((rep=>rep.width===playerWidth&&rep.height===playerHeight));highestRemainingBandwidthRep=resolutionBestRepList[resolutionBestRepList.length-1];const resolutionBestRep=resolutionBestRepList.filter((rep=>rep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0];let resolutionPlusOneList,resolutionPlusOneSmallest,resolutionPlusOneRep,leastPixelDiffRep;if(resolutionBestRep||(resolutionPlusOneList=haveResolution.filter((rep=>rep.width>playerWidth||rep.height>playerHeight)),resolutionPlusOneSmallest=resolutionPlusOneList.filter((rep=>rep.width===resolutionPlusOneList[0].width&&rep.height===resolutionPlusOneList[0].height)),highestRemainingBandwidthRep=resolutionPlusOneSmallest[resolutionPlusOneSmallest.length-1],resolutionPlusOneRep=resolutionPlusOneSmallest.filter((rep=>rep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0]),playlistController.leastPixelDiffSelector){const leastPixelDiffList=haveResolution.map((rep=>(rep.pixelDiff=Math.abs(rep.width-playerWidth)+Math.abs(rep.height-playerHeight),rep)));stableSort(leastPixelDiffList,((left,right)=>left.pixelDiff===right.pixelDiff?right.bandwidth-left.bandwidth:left.pixelDiff-right.pixelDiff)),leastPixelDiffRep=leastPixelDiffList[0]}const chosenRep=leastPixelDiffRep||resolutionPlusOneRep||resolutionBestRep||bandwidthBestRep||enabledPlaylistReps[0]||sortedPlaylistReps[0];if(chosenRep&&chosenRep.playlist){let type="sortedPlaylistReps";return leastPixelDiffRep?type="leastPixelDiffRep":resolutionPlusOneRep?type="resolutionPlusOneRep":resolutionBestRep?type="resolutionBestRep":bandwidthBestRep?type="bandwidthBestRep":enabledPlaylistReps[0]&&(type="enabledPlaylistReps"),logFn("choosing ".concat(representationToString(chosenRep)," using ").concat(type," with options"),options),chosenRep.playlist}return logFn("could not choose a playlist with options",options),null};const lastBandwidthSelector=function(){const pixelRatio=this.useDevicePixelRatio&&window.devicePixelRatio||1;return simpleSelector(this.playlists.main,this.systemBandwidth,parseInt(safeGetComputedStyle(this.tech_.el(),"width"),10)*pixelRatio,parseInt(safeGetComputedStyle(this.tech_.el(),"height"),10)*pixelRatio,this.limitRenditionByPlayerDimensions,this.playlistController_)},addMetadata=_ref61=>{let{inbandTextTracks:inbandTextTracks,metadataArray:metadataArray,timestampOffset:timestampOffset,videoDuration:videoDuration}=_ref61;if(!metadataArray)return;const Cue=window.WebKitDataCue||window.VTTCue,metadataTrack=inbandTextTracks.metadataTrack_;if(!metadataTrack)return;if(metadataArray.forEach((metadata=>{const time=metadata.cueTime+timestampOffset;!("number"!=typeof time||window.isNaN(time)||time<0)&&time<1/0&&metadata.frames.forEach((frame=>{const cue=new Cue(time,time,frame.value||frame.url||frame.data||"");cue.frame=frame,cue.value=frame,function(cue){Object.defineProperties(cue.frame,{id:{get:()=>(videojs.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),cue.value.key)},value:{get:()=>(videojs.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),cue.value.data)},privateData:{get:()=>(videojs.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),cue.value.data)}})}(cue),metadataTrack.addCue(cue)}))})),!metadataTrack.cues||!metadataTrack.cues.length)return;const cues=metadataTrack.cues,cuesArray=[];for(let i=0;i{const timeSlot=obj[cue.startTime]||[];return timeSlot.push(cue),obj[cue.startTime]=timeSlot,obj}),{}),sortedStartTimes=Object.keys(cuesGroupedByStartTime).sort(((a,b)=>Number(a)-Number(b)));sortedStartTimes.forEach(((startTime,idx)=>{const cueGroup=cuesGroupedByStartTime[startTime],nextTime=Number(sortedStartTimes[idx+1])||videoDuration;cueGroup.forEach((cue=>{cue.endTime=nextTime}))}))},removeCuesFromTrack=function(start,end,track){let i,cue;if(track&&track.cues)for(i=track.cues.length;i--;)cue=track.cues[i],cue.startTime>=start&&cue.endTime<=end&&track.removeCue(cue)},finite=num=>"number"==typeof num&&isFinite(num),segmentInfoString=segmentInfo=>{const{startOfSegment:startOfSegment,duration:duration,segment:segment,part:part,playlist:{mediaSequence:seq,id:id,segments:segments=[]},mediaIndex:index,partIndex:partIndex,timeline:timeline}=segmentInfo,segmentLen=segments.length-1;let selection="mediaIndex/partIndex increment";segmentInfo.getMediaInfoForTime?selection="getMediaInfoForTime (".concat(segmentInfo.getMediaInfoForTime,")"):segmentInfo.isSyncRequest&&(selection="getSyncSegmentCandidate (isSyncRequest)"),segmentInfo.independent&&(selection+=" with independent ".concat(segmentInfo.independent));const hasPartIndex="number"==typeof partIndex,name=segmentInfo.segment.uri?"segment":"pre-segment",zeroBasedPartCount=hasPartIndex?getKnownPartCount({preloadSegment:segment})-1:0;return"".concat(name," [").concat(seq+index,"/").concat(seq+segmentLen,"]")+(hasPartIndex?" part [".concat(partIndex,"/").concat(zeroBasedPartCount,"]"):"")+" segment start/end [".concat(segment.start," => ").concat(segment.end,"]")+(hasPartIndex?" part start/end [".concat(part.start," => ").concat(part.end,"]"):"")+" startOfSegment [".concat(startOfSegment,"]")+" duration [".concat(duration,"]")+" timeline [".concat(timeline,"]")+" selected by [".concat(selection,"]")+" playlist [".concat(id,"]")},timingInfoPropertyForMedia=mediaType=>"".concat(mediaType,"TimingInfo"),shouldWaitForTimelineChange=_ref63=>{let{timelineChangeController:timelineChangeController,currentTimeline:currentTimeline,segmentTimeline:segmentTimeline,loaderType:loaderType,audioDisabled:audioDisabled}=_ref63;if(currentTimeline===segmentTimeline)return!1;if("audio"===loaderType){const lastMainTimelineChange=timelineChangeController.lastTimelineChange({type:"main"});return!lastMainTimelineChange||lastMainTimelineChange.to!==segmentTimeline}if("main"===loaderType&&audioDisabled){const pendingAudioTimelineChange=timelineChangeController.pendingTimelineChange({type:"audio"});return!pendingAudioTimelineChange||pendingAudioTimelineChange.to!==segmentTimeline}return!1},segmentTooLong=_ref64=>{let{segmentDuration:segmentDuration,maxDuration:maxDuration}=_ref64;return!!segmentDuration&&Math.round(segmentDuration)>maxDuration+.03333333333333333},getTroublesomeSegmentDurationMessage=(segmentInfo,sourceType)=>{if("hls"!==sourceType)return null;const segmentDuration=(timingInfos=>{let maxDuration=0;return["video","audio"].forEach((function(type){const typeTimingInfo=timingInfos["".concat(type,"TimingInfo")];if(!typeTimingInfo)return;const{start:start,end:end}=typeTimingInfo;let duration;"bigint"==typeof start||"bigint"==typeof end?duration=window.BigInt(end)-window.BigInt(start):"number"==typeof start&&"number"==typeof end&&(duration=end-start),void 0!==duration&&duration>maxDuration&&(maxDuration=duration)})),"bigint"==typeof maxDuration&&maxDuration=11,this.appendInitSegment_={audio:!0,video:!0},this.playlistOfLastInitSegment_={audio:null,video:null},this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_={id3:[],caption:[]},this.waitingOnRemove_=!1,this.quotaExceededErrorRetryTimeout_=null,this.activeInitSegmentId_=null,this.initSegments_={},this.cacheEncryptionKeys_=settings.cacheEncryptionKeys,this.keyCache_={},this.decrypter_=settings.decrypter,this.syncController_=settings.syncController,this.syncPoint_={segmentIndex:0,time:0},this.transmuxer_=this.createTransmuxer_(),this.triggerSyncInfoUpdate_=()=>this.trigger("syncinfoupdate"),this.syncController_.on("syncinfoupdate",this.triggerSyncInfoUpdate_),this.mediaSource_.addEventListener("sourceopen",(()=>{this.isEndOfStream_()||(this.ended_=!1)})),this.fetchAtBuffer_=!1,this.logger_=logger("SegmentLoader[".concat(this.loaderType_,"]")),Object.defineProperty(this,"state",{get(){return this.state_},set(newState){newState!==this.state_&&(this.logger_("".concat(this.state_," -> ").concat(newState)),this.state_=newState,this.trigger("statechange"))}}),this.sourceUpdater_.on("ready",(()=>{this.hasEnoughInfoToAppend_()&&this.processCallQueue_()})),"main"===this.loaderType_&&this.timelineChangeController_.on("pendingtimelinechange",(()=>{this.hasEnoughInfoToAppend_()&&this.processCallQueue_()})),"audio"===this.loaderType_&&this.timelineChangeController_.on("timelinechange",(()=>{this.hasEnoughInfoToLoad_()&&this.processLoadQueue_(),this.hasEnoughInfoToAppend_()&&this.processCallQueue_()}))}createTransmuxer_(){return segmentTransmuxer_createTransmuxer({remux:!1,alignGopsAtEnd:this.safeAppend_,keepOriginalTimestamps:!0,parse708captions:this.parse708captions_,captionServices:this.captionServices_})}resetStats_(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0,this.mediaAppends=0}dispose(){this.trigger("dispose"),this.state="DISPOSED",this.pause(),this.abort_(),this.transmuxer_&&this.transmuxer_.terminate(),this.resetStats_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.syncController_&&this.triggerSyncInfoUpdate_&&this.syncController_.off("syncinfoupdate",this.triggerSyncInfoUpdate_),this.off()}setAudio(enable){this.audioDisabled_=!enable,enable?this.appendInitSegment_.audio=!0:this.sourceUpdater_.removeAudio(0,this.duration_())}abort(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)}abort_(){this.pendingSegment_&&this.pendingSegment_.abortRequests&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.timelineChangeController_.clearPendingTimelineChange(this.loaderType_),this.waitingOnRemove_=!1,window.clearTimeout(this.quotaExceededErrorRetryTimeout_),this.quotaExceededErrorRetryTimeout_=null}checkForAbort_(requestId){return"APPENDING"!==this.state||this.pendingSegment_?!this.pendingSegment_||this.pendingSegment_.requestId!==requestId:(this.state="READY",!0)}error(error){return void 0!==error&&(this.logger_("error occurred:",error),this.error_=error),this.pendingSegment_=null,this.error_}endOfStream(){this.ended_=!0,this.transmuxer_&&segmentTransmuxer_reset(this.transmuxer_),this.gopBuffer_.length=0,this.pause(),this.trigger("ended")}buffered_(){const trackInfo=this.getMediaInfo_();if(!this.sourceUpdater_||!trackInfo)return createTimeRanges();if("main"===this.loaderType_){const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo;if(hasVideo&&hasAudio&&!this.audioDisabled_&&!isMuxed)return this.sourceUpdater_.buffered();if(hasVideo)return this.sourceUpdater_.videoBuffered()}return this.sourceUpdater_.audioBuffered()}initSegmentForMap(map){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!map)return null;const id=initSegmentId(map);let storedMap=this.initSegments_[id];return set&&!storedMap&&map.bytes&&(this.initSegments_[id]=storedMap={resolvedUri:map.resolvedUri,byterange:map.byterange,bytes:map.bytes,tracks:map.tracks,timescales:map.timescales}),storedMap||map}segmentKey(key){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!key)return null;const id=segmentKeyId(key);let storedKey=this.keyCache_[id];this.cacheEncryptionKeys_&&set&&!storedKey&&key.bytes&&(this.keyCache_[id]=storedKey={resolvedUri:key.resolvedUri,bytes:key.bytes});const result={resolvedUri:(storedKey||key).resolvedUri};return storedKey&&(result.bytes=storedKey.bytes),result}couldBeginLoading_(){return this.playlist_&&!this.paused()}load(){if(this.monitorBuffer_(),this.playlist_)return"INIT"===this.state&&this.couldBeginLoading_()?this.init_():void(!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY"))}init_(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}playlist(newPlaylist){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!newPlaylist)return;const oldPlaylist=this.playlist_,segmentInfo=this.pendingSegment_;this.playlist_=newPlaylist,this.xhrOptions_=options,"INIT"===this.state&&(newPlaylist.syncInfo={mediaSequence:newPlaylist.mediaSequence,time:0},"main"===this.loaderType_&&this.syncController_.setDateTimeMappingForStart(newPlaylist));let oldId=null;if(oldPlaylist&&(oldPlaylist.id?oldId=oldPlaylist.id:oldPlaylist.uri&&(oldId=oldPlaylist.uri)),this.logger_("playlist update [".concat(oldId," => ").concat(newPlaylist.id||newPlaylist.uri,"]")),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!oldPlaylist||oldPlaylist.uri!==newPlaylist.uri)return null!==this.mediaIndex&&(newPlaylist.endList?this.resyncLoader():this.resetLoader()),this.currentMediaInfo_=void 0,void this.trigger("playlistupdate");const mediaSequenceDiff=newPlaylist.mediaSequence-oldPlaylist.mediaSequence;if(this.logger_("live window shift [".concat(mediaSequenceDiff,"]")),null!==this.mediaIndex)if(this.mediaIndex-=mediaSequenceDiff,this.mediaIndex<0)this.mediaIndex=null,this.partIndex=null;else{const segment=this.playlist_.segments[this.mediaIndex];if(this.partIndex&&(!segment.parts||!segment.parts.length||!segment.parts[this.partIndex])){const mediaIndex=this.mediaIndex;this.logger_("currently processing part (index ".concat(this.partIndex,") no longer exists.")),this.resetLoader(),this.mediaIndex=mediaIndex}}segmentInfo&&(segmentInfo.mediaIndex-=mediaSequenceDiff,segmentInfo.mediaIndex<0?(segmentInfo.mediaIndex=null,segmentInfo.partIndex=null):(segmentInfo.mediaIndex>=0&&(segmentInfo.segment=newPlaylist.segments[segmentInfo.mediaIndex]),segmentInfo.partIndex>=0&&segmentInfo.segment.parts&&(segmentInfo.part=segmentInfo.segment.parts[segmentInfo.partIndex]))),this.syncController_.saveExpiredSegmentInfo(oldPlaylist,newPlaylist)}pause(){this.checkBufferTimeout_&&(window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)}paused(){return null===this.checkBufferTimeout_}resetEverything(done){this.ended_=!1,this.activeInitSegmentId_=null,this.appendInitSegment_={audio:!0,video:!0},this.resetLoader(),this.remove(0,1/0,done),this.transmuxer_&&(this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.transmuxer_.postMessage({action:"reset"}))}resetLoader(){this.fetchAtBuffer_=!1,this.resyncLoader()}resyncLoader(){this.transmuxer_&&segmentTransmuxer_reset(this.transmuxer_),this.mediaIndex=null,this.partIndex=null,this.syncPoint_=null,this.isPendingTimestampOffset_=!1,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})}remove(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},force=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(end===1/0&&(end=this.duration_()),end<=start)return void this.logger_("skipping remove because end ${end} is <= start ${start}");if(!this.sourceUpdater_||!this.getMediaInfo_())return void this.logger_("skipping remove because no source updater or starting media info");let removesRemaining=1;const removeFinished=()=>{removesRemaining--,0===removesRemaining&&done()};!force&&this.audioDisabled_||(removesRemaining++,this.sourceUpdater_.removeAudio(start,end,removeFinished)),(force||"main"===this.loaderType_)&&(this.gopBuffer_=((buffer,start,end,mapping)=>{const startPts=Math.ceil((start-mapping)*clock_1),endPts=Math.ceil((end-mapping)*clock_1),updatedBuffer=buffer.slice();let i=buffer.length;for(;i--&&!(buffer[i].pts<=endPts););if(-1===i)return updatedBuffer;let j=i+1;for(;j--&&!(buffer[j].pts<=startPts););return j=Math.max(j,0),updatedBuffer.splice(j,i-j+1),updatedBuffer})(this.gopBuffer_,start,end,this.timeMapping_),removesRemaining++,this.sourceUpdater_.removeVideo(start,end,removeFinished));for(const track in this.inbandTextTracks_)removeCuesFromTrack(start,end,this.inbandTextTracks_[track]);removeCuesFromTrack(start,end,this.segmentMetadataTrack_),removeFinished()}monitorBuffer_(){this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),1)}monitorBufferTick_(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),500)}fillBuffer_(){if(this.sourceUpdater_.updating())return;const segmentInfo=this.chooseNextRequest_();segmentInfo&&("number"==typeof segmentInfo.timestampOffset&&(this.isPendingTimestampOffset_=!1,this.timelineChangeController_.pendingTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:segmentInfo.timeline})),this.loadSegment_(segmentInfo))}isEndOfStream_(){let mediaIndex=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.mediaIndex,playlist=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.playlist_,partIndex=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.partIndex;if(!playlist||!this.mediaSource_)return!1;const segment="number"==typeof mediaIndex&&playlist.segments[mediaIndex],appendedLastSegment=mediaIndex+1===playlist.segments.length,appendedLastPart=!segment||!segment.parts||partIndex+1===segment.parts.length;return playlist.endList&&"open"===this.mediaSource_.readyState&&appendedLastSegment&&appendedLastPart}chooseNextRequest_(){const buffered=this.buffered_(),bufferedEnd=lastBufferedEnd(buffered)||0,bufferedTime=timeAheadOf(buffered,this.currentTime_()),preloaded=!this.hasPlayed_()&&bufferedTime>=1,haveEnoughBuffer=bufferedTime>=this.goalBufferLength_(),segments=this.playlist_.segments;if(!segments.length||preloaded||haveEnoughBuffer)return null;this.syncPoint_=this.syncPoint_||this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_());const next={partIndex:null,mediaIndex:null,startOfSegment:null,playlist:this.playlist_,isSyncRequest:Boolean(!this.syncPoint_)};if(next.isSyncRequest)next.mediaIndex=function(currentTimeline,segments,targetTime){segments=segments||[];const timelineSegments=[];let time=0;for(let i=0;itargetTime))return i}return 0===timelineSegments.length?0:timelineSegments[timelineSegments.length-1]}(this.currentTimeline_,segments,bufferedEnd);else if(null!==this.mediaIndex){const segment=segments[this.mediaIndex],partIndex="number"==typeof this.partIndex?this.partIndex:-1;next.startOfSegment=segment.end?segment.end:bufferedEnd,segment.parts&&segment.parts[partIndex+1]?(next.mediaIndex=this.mediaIndex,next.partIndex=partIndex+1):next.mediaIndex=this.mediaIndex+1}else{const{segmentIndex:segmentIndex,startTime:startTime,partIndex:partIndex}=Playlist.getMediaInfoForTime({exactManifestTimings:this.exactManifestTimings,playlist:this.playlist_,currentTime:this.fetchAtBuffer_?bufferedEnd:this.currentTime_(),startingPartIndex:this.syncPoint_.partIndex,startingSegmentIndex:this.syncPoint_.segmentIndex,startTime:this.syncPoint_.time});next.getMediaInfoForTime=this.fetchAtBuffer_?"bufferedEnd ".concat(bufferedEnd):"currentTime ".concat(this.currentTime_()),next.mediaIndex=segmentIndex,next.startOfSegment=startTime,next.partIndex=partIndex}const nextSegment=segments[next.mediaIndex];let nextPart=nextSegment&&"number"==typeof next.partIndex&&nextSegment.parts&&nextSegment.parts[next.partIndex];if(!nextSegment||"number"==typeof next.partIndex&&!nextPart)return null;if("number"!=typeof next.partIndex&&nextSegment.parts&&(next.partIndex=0,nextPart=nextSegment.parts[0]),!bufferedTime&&nextPart&&!nextPart.independent)if(0===next.partIndex){const lastSegment=segments[next.mediaIndex-1],lastSegmentLastPart=lastSegment.parts&&lastSegment.parts.length&&lastSegment.parts[lastSegment.parts.length-1];lastSegmentLastPart&&lastSegmentLastPart.independent&&(next.mediaIndex-=1,next.partIndex=lastSegment.parts.length-1,next.independent="previous segment")}else nextSegment.parts[next.partIndex-1].independent&&(next.partIndex-=1,next.independent="previous part");const ended=this.mediaSource_&&"ended"===this.mediaSource_.readyState;return next.mediaIndex>=segments.length-1&&ended&&!this.seeking_()?null:this.generateSegmentInfo_(next)}generateSegmentInfo_(options){const{independent:independent,playlist:playlist,mediaIndex:mediaIndex,startOfSegment:startOfSegment,isSyncRequest:isSyncRequest,partIndex:partIndex,forceTimestampOffset:forceTimestampOffset,getMediaInfoForTime:getMediaInfoForTime}=options,segment=playlist.segments[mediaIndex],part="number"==typeof partIndex&&segment.parts[partIndex],segmentInfo={requestId:"segment-loader-"+Math.random(),uri:part&&part.resolvedUri||segment.resolvedUri,mediaIndex:mediaIndex,partIndex:part?partIndex:null,isSyncRequest:isSyncRequest,startOfSegment:startOfSegment,playlist:playlist,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:segment.timeline,duration:part&&part.duration||segment.duration,segment:segment,part:part,byteLength:0,transmuxer:this.transmuxer_,getMediaInfoForTime:getMediaInfoForTime,independent:independent},overrideCheck=void 0!==forceTimestampOffset?forceTimestampOffset:this.isPendingTimestampOffset_;segmentInfo.timestampOffset=this.timestampOffsetForSegment_({segmentTimeline:segment.timeline,currentTimeline:this.currentTimeline_,startOfSegment:startOfSegment,buffered:this.buffered_(),overrideCheck:overrideCheck});const audioBufferedEnd=lastBufferedEnd(this.sourceUpdater_.audioBuffered());return"number"==typeof audioBufferedEnd&&(segmentInfo.audioAppendStart=audioBufferedEnd-this.sourceUpdater_.audioTimestampOffset()),this.sourceUpdater_.videoBuffered().length&&(segmentInfo.gopsToAlignWith=((buffer,currentTime,mapping)=>{if(null==currentTime||!buffer.length)return[];const currentTimePts=Math.ceil((currentTime-mapping+3)*clock_1);let i;for(i=0;icurrentTimePts);i++);return buffer.slice(i)})(this.gopBuffer_,this.currentTime_()-this.sourceUpdater_.videoTimestampOffset(),this.timeMapping_)),segmentInfo}timestampOffsetForSegment_(options){return(_ref62=>{let{segmentTimeline:segmentTimeline,currentTimeline:currentTimeline,startOfSegment:startOfSegment,buffered:buffered,overrideCheck:overrideCheck}=_ref62;return overrideCheck||segmentTimeline!==currentTimeline?segmentTimeline2&&void 0!==arguments[2]?arguments[2]:1;return((buffered.length?buffered.end(buffered.length-1):0)-currentTime)/playbackRate}(this.buffered_(),currentTime,this.vhs_.tech_.playbackRate())-1;if(requestTimeRemaining<=timeUntilRebuffer$1)return;const switchCandidate=function(settings){const{main:main,currentTime:currentTime,bandwidth:bandwidth,duration:duration,segmentDuration:segmentDuration,timeUntilRebuffer:timeUntilRebuffer,currentTimeline:currentTimeline,syncController:syncController}=settings,compatiblePlaylists=main.playlists.filter((playlist=>!Playlist.isIncompatible(playlist)));let enabledPlaylists=compatiblePlaylists.filter(Playlist.isEnabled);enabledPlaylists.length||(enabledPlaylists=compatiblePlaylists.filter((playlist=>!Playlist.isDisabled(playlist))));const rebufferingEstimates=enabledPlaylists.filter(Playlist.hasAttribute.bind(null,"BANDWIDTH")).map((playlist=>{const numRequests=syncController.getSyncPoint(playlist,duration,currentTimeline,currentTime)?1:2;return{playlist:playlist,rebufferingImpact:Playlist.estimateSegmentRequestTime(segmentDuration,bandwidth,playlist)*numRequests-timeUntilRebuffer}})),noRebufferingPlaylists=rebufferingEstimates.filter((estimate=>estimate.rebufferingImpact<=0));return stableSort(noRebufferingPlaylists,((a,b)=>comparePlaylistBandwidth(b.playlist,a.playlist))),noRebufferingPlaylists.length?noRebufferingPlaylists[0]:(stableSort(rebufferingEstimates,((a,b)=>a.rebufferingImpact-b.rebufferingImpact)),rebufferingEstimates[0]||null)}({main:this.vhs_.playlists.main,currentTime:currentTime,bandwidth:measuredBandwidth,duration:this.duration_(),segmentDuration:segmentDuration,timeUntilRebuffer:timeUntilRebuffer$1,currentTimeline:this.currentTimeline_,syncController:this.syncController_});if(!switchCandidate)return;const timeSavedBySwitching=requestTimeRemaining-timeUntilRebuffer$1-switchCandidate.rebufferingImpact;let minimumTimeSaving=.5;timeUntilRebuffer$1<=.03333333333333333&&(minimumTimeSaving=1),!switchCandidate.playlist||switchCandidate.playlist.uri===this.playlist_.uri||timeSavedBySwitching{captionTracks[caption.stream]=captionTracks[caption.stream]||{startTime:1/0,captions:[],endTime:0};const captionTrack=captionTracks[caption.stream];captionTrack.startTime=Math.min(captionTrack.startTime,caption.startTime+timestampOffset),captionTrack.endTime=Math.max(captionTrack.endTime,caption.endTime+timestampOffset),captionTrack.captions.push(caption)})),Object.keys(captionTracks).forEach((trackName=>{const{startTime:startTime,endTime:endTime,captions:captions}=captionTracks[trackName],inbandTextTracks=this.inbandTextTracks_;this.logger_("adding cues from ".concat(startTime," -> ").concat(endTime," for ").concat(trackName)),function(inbandTextTracks,tech,captionStream){if(!inbandTextTracks[captionStream]){tech.trigger({type:"usage",name:"vhs-608"});let instreamId=captionStream;/^cc708_/.test(captionStream)&&(instreamId="SERVICE"+captionStream.split("_")[1]);const track=tech.textTracks().getTrackById(instreamId);if(track)inbandTextTracks[captionStream]=track;else{let label=captionStream,language=captionStream,def=!1;const captionService=(tech.options_.vhs&&tech.options_.vhs.captionServices||{})[instreamId];captionService&&(label=captionService.label,language=captionService.language,def=captionService.default),inbandTextTracks[captionStream]=tech.addRemoteTextTrack({kind:"captions",id:instreamId,default:def,label:label,language:language},!1).track}}}(inbandTextTracks,this.vhs_.tech_,trackName),removeCuesFromTrack(startTime,endTime,inbandTextTracks[trackName]),function(_ref60){let{inbandTextTracks:inbandTextTracks,captionArray:captionArray,timestampOffset:timestampOffset}=_ref60;if(!captionArray)return;const Cue=window.WebKitDataCue||window.VTTCue;captionArray.forEach((caption=>{const track=caption.stream;inbandTextTracks[track].addCue(new Cue(caption.startTime+timestampOffset,caption.endTime+timestampOffset,caption.text))}))}({captionArray:captions,inbandTextTracks:inbandTextTracks,timestampOffset:timestampOffset})})),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})}handleId3_(simpleSegment,id3Frames,dispatchType){if(this.earlyAbortWhenNeeded_(simpleSegment.stats),this.checkForAbort_(simpleSegment.requestId))return;if(!this.pendingSegment_.hasAppendedData_)return void this.metadataQueue_.id3.push(this.handleId3_.bind(this,simpleSegment,id3Frames,dispatchType));const timestampOffset=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset();((inbandTextTracks,dispatchType,tech)=>{inbandTextTracks.metadataTrack_||(inbandTextTracks.metadataTrack_=tech.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,inbandTextTracks.metadataTrack_.inBandMetadataTrackDispatchType=dispatchType)})(this.inbandTextTracks_,dispatchType,this.vhs_.tech_),addMetadata({inbandTextTracks:this.inbandTextTracks_,metadataArray:id3Frames,timestampOffset:timestampOffset,videoDuration:this.duration_()})}processMetadataQueue_(){this.metadataQueue_.id3.forEach((fn=>fn())),this.metadataQueue_.caption.forEach((fn=>fn())),this.metadataQueue_.id3=[],this.metadataQueue_.caption=[]}processCallQueue_(){const callQueue=this.callQueue_;this.callQueue_=[],callQueue.forEach((fun=>fun()))}processLoadQueue_(){const loadQueue=this.loadQueue_;this.loadQueue_=[],loadQueue.forEach((fun=>fun()))}hasEnoughInfoToLoad_(){if("audio"!==this.loaderType_)return!0;const segmentInfo=this.pendingSegment_;return!!segmentInfo&&(!this.getCurrentMediaInfo_()||!shouldWaitForTimelineChange({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:segmentInfo.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))}getCurrentMediaInfo_(){let segmentInfo=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.pendingSegment_;return segmentInfo&&segmentInfo.trackInfo||this.currentMediaInfo_}getMediaInfo_(){let segmentInfo=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.pendingSegment_;return this.getCurrentMediaInfo_(segmentInfo)||this.startingMediaInfo_}getPendingSegmentPlaylist(){return this.pendingSegment_?this.pendingSegment_.playlist:null}hasEnoughInfoToAppend_(){if(!this.sourceUpdater_.ready())return!1;if(this.waitingOnRemove_||this.quotaExceededErrorRetryTimeout_)return!1;const segmentInfo=this.pendingSegment_,trackInfo=this.getCurrentMediaInfo_();if(!segmentInfo||!trackInfo)return!1;const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo;return!(hasVideo&&!segmentInfo.videoTimingInfo)&&(!(hasAudio&&!this.audioDisabled_&&!isMuxed&&!segmentInfo.audioTimingInfo)&&!shouldWaitForTimelineChange({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:segmentInfo.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))}handleData_(simpleSegment,result){if(this.earlyAbortWhenNeeded_(simpleSegment.stats),this.checkForAbort_(simpleSegment.requestId))return;if(this.callQueue_.length||!this.hasEnoughInfoToAppend_())return void this.callQueue_.push(this.handleData_.bind(this,simpleSegment,result));const segmentInfo=this.pendingSegment_;if(this.setTimeMapping_(segmentInfo.timeline),this.updateMediaSecondsLoaded_(segmentInfo.part||segmentInfo.segment),"closed"!==this.mediaSource_.readyState){if(simpleSegment.map&&(simpleSegment.map=this.initSegmentForMap(simpleSegment.map,!0),segmentInfo.segment.map=simpleSegment.map),simpleSegment.key&&this.segmentKey(simpleSegment.key,!0),segmentInfo.isFmp4=simpleSegment.isFmp4,segmentInfo.timingInfo=segmentInfo.timingInfo||{},segmentInfo.isFmp4)this.trigger("fmp4"),segmentInfo.timingInfo.start=segmentInfo[timingInfoPropertyForMedia(result.type)].start;else{const trackInfo=this.getCurrentMediaInfo_(),useVideoTimingInfo="main"===this.loaderType_&&trackInfo&&trackInfo.hasVideo;let firstVideoFrameTimeForData;useVideoTimingInfo&&(firstVideoFrameTimeForData=segmentInfo.videoTimingInfo.start),segmentInfo.timingInfo.start=this.trueSegmentStart_({currentStart:segmentInfo.timingInfo.start,playlist:segmentInfo.playlist,mediaIndex:segmentInfo.mediaIndex,currentVideoTimestampOffset:this.sourceUpdater_.videoTimestampOffset(),useVideoTimingInfo:useVideoTimingInfo,firstVideoFrameTimeForData:firstVideoFrameTimeForData,videoTimingInfo:segmentInfo.videoTimingInfo,audioTimingInfo:segmentInfo.audioTimingInfo})}if(this.updateAppendInitSegmentStatus(segmentInfo,result.type),this.updateSourceBufferTimestampOffset_(segmentInfo),segmentInfo.isSyncRequest){this.updateTimingInfoEnd_(segmentInfo),this.syncController_.saveSegmentTimingInfo({segmentInfo:segmentInfo,shouldSaveTimelineMapping:"main"===this.loaderType_});const next=this.chooseNextRequest_();if(next.mediaIndex!==segmentInfo.mediaIndex||next.partIndex!==segmentInfo.partIndex)return void this.logger_("sync segment was incorrect, not appending");this.logger_("sync segment was correct, appending")}segmentInfo.hasAppendedData_=!0,this.processMetadataQueue_(),this.appendData_(segmentInfo,result)}}updateAppendInitSegmentStatus(segmentInfo,type){"main"!==this.loaderType_||"number"!=typeof segmentInfo.timestampOffset||segmentInfo.changedTimestampOffset||(this.appendInitSegment_={audio:!0,video:!0}),this.playlistOfLastInitSegment_[type]!==segmentInfo.playlist&&(this.appendInitSegment_[type]=!0)}getInitSegmentAndUpdateState_(_ref65){let{type:type,initSegment:initSegment,map:map,playlist:playlist}=_ref65;if(map){const id=initSegmentId(map);if(this.activeInitSegmentId_===id)return null;initSegment=this.initSegmentForMap(map,!0).bytes,this.activeInitSegmentId_=id}return initSegment&&this.appendInitSegment_[type]?(this.playlistOfLastInitSegment_[type]=playlist,this.appendInitSegment_[type]=!1,this.activeInitSegmentId_=null,initSegment):null}handleQuotaExceededError_(_ref66,error){let{segmentInfo:segmentInfo,type:type,bytes:bytes}=_ref66;const audioBuffered=this.sourceUpdater_.audioBuffered(),videoBuffered=this.sourceUpdater_.videoBuffered();audioBuffered.length>1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the audio buffer: "+timeRangesToArray(audioBuffered).join(", ")),videoBuffered.length>1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the video buffer: "+timeRangesToArray(videoBuffered).join(", "));const audioBufferStart=audioBuffered.length?audioBuffered.start(0):0,audioBufferEnd=audioBuffered.length?audioBuffered.end(audioBuffered.length-1):0,videoBufferStart=videoBuffered.length?videoBuffered.start(0):0,videoBufferEnd=videoBuffered.length?videoBuffered.end(videoBuffered.length-1):0;if(audioBufferEnd-audioBufferStart<=1&&videoBufferEnd-videoBufferStart<=1)return this.logger_("On QUOTA_EXCEEDED_ERR, single segment too large to append to buffer, triggering an error. "+"Appended byte length: ".concat(bytes.byteLength,", ")+"audio buffer: ".concat(timeRangesToArray(audioBuffered).join(", "),", ")+"video buffer: ".concat(timeRangesToArray(videoBuffered).join(", "),", ")),this.error({message:"Quota exceeded error with append of a single segment of content",excludeUntil:1/0}),void this.trigger("error");this.waitingOnRemove_=!0,this.callQueue_.push(this.appendToSourceBuffer_.bind(this,{segmentInfo:segmentInfo,type:type,bytes:bytes}));const timeToRemoveUntil=this.currentTime_()-1;this.logger_("On QUOTA_EXCEEDED_ERR, removing audio/video from 0 to ".concat(timeToRemoveUntil)),this.remove(0,timeToRemoveUntil,(()=>{this.logger_("On QUOTA_EXCEEDED_ERR, retrying append in ".concat(1,"s")),this.waitingOnRemove_=!1,this.quotaExceededErrorRetryTimeout_=window.setTimeout((()=>{this.logger_("On QUOTA_EXCEEDED_ERR, re-processing call queue"),this.quotaExceededErrorRetryTimeout_=null,this.processCallQueue_()}),1e3)}),!0)}handleAppendError_(_ref67,error){let{segmentInfo:segmentInfo,type:type,bytes:bytes}=_ref67;error&&(22!==error.code?(this.logger_("Received non QUOTA_EXCEEDED_ERR on append",error),this.error("".concat(type," append of ").concat(bytes.length,"b failed for segment ")+"#".concat(segmentInfo.mediaIndex," in playlist ").concat(segmentInfo.playlist.id)),this.trigger("appenderror")):this.handleQuotaExceededError_({segmentInfo:segmentInfo,type:type,bytes:bytes}))}appendToSourceBuffer_(_ref68){let{segmentInfo:segmentInfo,type:type,initSegment:initSegment,data:data,bytes:bytes}=_ref68;if(!bytes){const segments=[data];let byteLength=data.byteLength;initSegment&&(segments.unshift(initSegment),byteLength+=initSegment.byteLength),bytes=(segmentObj=>{let tempBuffer,offset=0;return segmentObj.bytes&&(tempBuffer=new Uint8Array(segmentObj.bytes),segmentObj.segments.forEach((segment=>{tempBuffer.set(segment,offset),offset+=segment.byteLength}))),tempBuffer})({bytes:byteLength,segments:segments})}this.sourceUpdater_.appendBuffer({segmentInfo:segmentInfo,type:type,bytes:bytes},this.handleAppendError_.bind(this,{segmentInfo:segmentInfo,type:type,bytes:bytes}))}handleSegmentTimingInfo_(type,requestId,segmentTimingInfo){if(!this.pendingSegment_||requestId!==this.pendingSegment_.requestId)return;const segment=this.pendingSegment_.segment,timingInfoProperty="".concat(type,"TimingInfo");segment[timingInfoProperty]||(segment[timingInfoProperty]={}),segment[timingInfoProperty].transmuxerPrependedSeconds=segmentTimingInfo.prependedContentDuration||0,segment[timingInfoProperty].transmuxedPresentationStart=segmentTimingInfo.start.presentation,segment[timingInfoProperty].transmuxedDecodeStart=segmentTimingInfo.start.decode,segment[timingInfoProperty].transmuxedPresentationEnd=segmentTimingInfo.end.presentation,segment[timingInfoProperty].transmuxedDecodeEnd=segmentTimingInfo.end.decode,segment[timingInfoProperty].baseMediaDecodeTime=segmentTimingInfo.baseMediaDecodeTime}appendData_(segmentInfo,result){const{type:type,data:data}=result;if(!data||!data.byteLength)return;if("audio"===type&&this.audioDisabled_)return;const initSegment=this.getInitSegmentAndUpdateState_({type:type,initSegment:result.initSegment,playlist:segmentInfo.playlist,map:segmentInfo.isFmp4?segmentInfo.segment.map:null});this.appendToSourceBuffer_({segmentInfo:segmentInfo,type:type,initSegment:initSegment,data:data})}loadSegment_(segmentInfo){this.state="WAITING",this.pendingSegment_=segmentInfo,this.trimBackBuffer_(segmentInfo),"number"==typeof segmentInfo.timestampOffset&&this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.hasEnoughInfoToLoad_()?this.updateTransmuxerAndRequestSegment_(segmentInfo):this.loadQueue_.push((()=>{const options=_extends$1({},segmentInfo,{forceTimestampOffset:!0});_extends$1(segmentInfo,this.generateSegmentInfo_(options)),this.isPendingTimestampOffset_=!1,this.updateTransmuxerAndRequestSegment_(segmentInfo)}))}updateTransmuxerAndRequestSegment_(segmentInfo){this.shouldUpdateTransmuxerTimestampOffset_(segmentInfo.timestampOffset)&&(this.gopBuffer_.length=0,segmentInfo.gopsToAlignWith=[],this.timeMapping_=0,this.transmuxer_.postMessage({action:"reset"}),this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:segmentInfo.timestampOffset}));const simpleSegment=this.createSimplifiedSegmentObj_(segmentInfo),isEndOfStream=this.isEndOfStream_(segmentInfo.mediaIndex,segmentInfo.playlist,segmentInfo.partIndex),isWalkingForward=null!==this.mediaIndex,isDiscontinuity=segmentInfo.timeline!==this.currentTimeline_&&segmentInfo.timeline>0,isEndOfTimeline=isEndOfStream||isWalkingForward&&isDiscontinuity;this.logger_("Requesting ".concat(segmentInfoString(segmentInfo))),simpleSegment.map&&!simpleSegment.map.bytes&&(this.logger_("going to request init segment."),this.appendInitSegment_={video:!0,audio:!0}),segmentInfo.abortRequests=mediaSegmentRequest({xhr:this.vhs_.xhr,xhrOptions:this.xhrOptions_,decryptionWorker:this.decrypter_,segment:simpleSegment,abortFn:this.handleAbort_.bind(this,segmentInfo),progressFn:this.handleProgress_.bind(this),trackInfoFn:this.handleTrackInfo_.bind(this),timingInfoFn:this.handleTimingInfo_.bind(this),videoSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"video",segmentInfo.requestId),audioSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"audio",segmentInfo.requestId),captionsFn:this.handleCaptions_.bind(this),isEndOfTimeline:isEndOfTimeline,endedTimelineFn:()=>{this.logger_("received endedtimeline callback")},id3Fn:this.handleId3_.bind(this),dataFn:this.handleData_.bind(this),doneFn:this.segmentRequestFinished_.bind(this),onTransmuxerLog:_ref69=>{let{message:message,level:level,stream:stream}=_ref69;this.logger_("".concat(segmentInfoString(segmentInfo)," logged from transmuxer stream ").concat(stream," as a ").concat(level,": ").concat(message))}})}trimBackBuffer_(segmentInfo){const removeToTime=((seekable,currentTime,targetDuration)=>{let trimTime=currentTime-Config.BACK_BUFFER_LENGTH;seekable.length&&(trimTime=Math.max(trimTime,seekable.start(0)));const maxTrimTime=currentTime-targetDuration;return Math.min(maxTrimTime,trimTime)})(this.seekable_(),this.currentTime_(),this.playlist_.targetDuration||10);removeToTime>0&&this.remove(0,removeToTime)}createSimplifiedSegmentObj_(segmentInfo){const segment=segmentInfo.segment,part=segmentInfo.part,simpleSegment={resolvedUri:part?part.resolvedUri:segment.resolvedUri,byterange:part?part.byterange:segment.byterange,requestId:segmentInfo.requestId,transmuxer:segmentInfo.transmuxer,audioAppendStart:segmentInfo.audioAppendStart,gopsToAlignWith:segmentInfo.gopsToAlignWith,part:segmentInfo.part},previousSegment=segmentInfo.playlist.segments[segmentInfo.mediaIndex-1];if(previousSegment&&previousSegment.timeline===segment.timeline&&(previousSegment.videoTimingInfo?simpleSegment.baseStartTime=previousSegment.videoTimingInfo.transmuxedDecodeEnd:previousSegment.audioTimingInfo&&(simpleSegment.baseStartTime=previousSegment.audioTimingInfo.transmuxedDecodeEnd)),segment.key){const iv=segment.key.iv||new Uint32Array([0,0,0,segmentInfo.mediaIndex+segmentInfo.playlist.mediaSequence]);simpleSegment.key=this.segmentKey(segment.key),simpleSegment.key.iv=iv}return segment.map&&(simpleSegment.map=this.initSegmentForMap(segment.map)),simpleSegment}saveTransferStats_(stats){this.mediaRequests+=1,stats&&(this.mediaBytesTransferred+=stats.bytesReceived,this.mediaTransferDuration+=stats.roundTripTime)}saveBandwidthRelatedStats_(duration,stats){this.pendingSegment_.byteLength=stats.bytesReceived,duration<.016666666666666666?this.logger_("Ignoring segment's bandwidth because its duration of ".concat(duration)+" is less than the min to record ".concat(.016666666666666666)):(this.bandwidth=stats.bandwidth,this.roundTrip=stats.roundTripTime)}handleTimeout_(){this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,this.trigger("bandwidthupdate"),this.trigger("timeout")}segmentRequestFinished_(error,simpleSegment,result){if(this.callQueue_.length)return void this.callQueue_.push(this.segmentRequestFinished_.bind(this,error,simpleSegment,result));if(this.saveTransferStats_(simpleSegment.stats),!this.pendingSegment_)return;if(simpleSegment.requestId!==this.pendingSegment_.requestId)return;if(error){if(this.pendingSegment_=null,this.state="READY",error.code===REQUEST_ERRORS_ABORTED)return;return this.pause(),error.code===REQUEST_ERRORS_TIMEOUT?void this.handleTimeout_():(this.mediaRequestsErrored+=1,this.error(error),void this.trigger("error"))}const segmentInfo=this.pendingSegment_;this.saveBandwidthRelatedStats_(segmentInfo.duration,simpleSegment.stats),segmentInfo.endOfAllRequests=simpleSegment.endOfAllRequests,result.gopInfo&&(this.gopBuffer_=((buffer,gops,replace)=>{if(!gops.length)return buffer;if(replace)return gops.slice();const start=gops[0].pts;let i=0;for(;i=start);i++);return buffer.slice(0,i).concat(gops)})(this.gopBuffer_,result.gopInfo,this.safeAppend_)),this.state="APPENDING",this.trigger("appending"),this.waitForAppendsToComplete_(segmentInfo)}setTimeMapping_(timeline){const timelineMapping=this.syncController_.mappingForTimeline(timeline);null!==timelineMapping&&(this.timeMapping_=timelineMapping)}updateMediaSecondsLoaded_(segment){"number"==typeof segment.start&&"number"==typeof segment.end?this.mediaSecondsLoaded+=segment.end-segment.start:this.mediaSecondsLoaded+=segment.duration}shouldUpdateTransmuxerTimestampOffset_(timestampOffset){return null!==timestampOffset&&("main"===this.loaderType_&×tampOffset!==this.sourceUpdater_.videoTimestampOffset()||!this.audioDisabled_&×tampOffset!==this.sourceUpdater_.audioTimestampOffset())}trueSegmentStart_(_ref70){let{currentStart:currentStart,playlist:playlist,mediaIndex:mediaIndex,firstVideoFrameTimeForData:firstVideoFrameTimeForData,currentVideoTimestampOffset:currentVideoTimestampOffset,useVideoTimingInfo:useVideoTimingInfo,videoTimingInfo:videoTimingInfo,audioTimingInfo:audioTimingInfo}=_ref70;if(void 0!==currentStart)return currentStart;if(!useVideoTimingInfo)return audioTimingInfo.start;const previousSegment=playlist.segments[mediaIndex-1];return 0!==mediaIndex&&previousSegment&&void 0!==previousSegment.start&&previousSegment.end===firstVideoFrameTimeForData+currentVideoTimestampOffset?videoTimingInfo.start:firstVideoFrameTimeForData}waitForAppendsToComplete_(segmentInfo){const trackInfo=this.getCurrentMediaInfo_(segmentInfo);if(!trackInfo)return this.error({message:"No starting media returned, likely due to an unsupported media format.",playlistExclusionDuration:1/0}),void this.trigger("error");const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo,waitForVideo="main"===this.loaderType_&&hasVideo,waitForAudio=!this.audioDisabled_&&hasAudio&&!isMuxed;if(segmentInfo.waitingOnAppends=0,!segmentInfo.hasAppendedData_)return segmentInfo.timingInfo||"number"!=typeof segmentInfo.timestampOffset||(this.isPendingTimestampOffset_=!0),segmentInfo.timingInfo={start:0},segmentInfo.waitingOnAppends++,this.isPendingTimestampOffset_||(this.updateSourceBufferTimestampOffset_(segmentInfo),this.processMetadataQueue_()),void this.checkAppendsDone_(segmentInfo);waitForVideo&&segmentInfo.waitingOnAppends++,waitForAudio&&segmentInfo.waitingOnAppends++,waitForVideo&&this.sourceUpdater_.videoQueueCallback(this.checkAppendsDone_.bind(this,segmentInfo)),waitForAudio&&this.sourceUpdater_.audioQueueCallback(this.checkAppendsDone_.bind(this,segmentInfo))}checkAppendsDone_(segmentInfo){this.checkForAbort_(segmentInfo.requestId)||(segmentInfo.waitingOnAppends--,0===segmentInfo.waitingOnAppends&&this.handleAppendsDone_())}checkForIllegalMediaSwitch(trackInfo){const illegalMediaSwitchError=((loaderType,startingMedia,trackInfo)=>"main"===loaderType&&startingMedia&&trackInfo?trackInfo.hasAudio||trackInfo.hasVideo?startingMedia.hasVideo&&!trackInfo.hasVideo?"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.":!startingMedia.hasVideo&&trackInfo.hasVideo?"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.getCurrentMediaInfo_(),trackInfo);return!!illegalMediaSwitchError&&(this.error({message:illegalMediaSwitchError,playlistExclusionDuration:1/0}),this.trigger("error"),!0)}updateSourceBufferTimestampOffset_(segmentInfo){if(null===segmentInfo.timestampOffset||"number"!=typeof segmentInfo.timingInfo.start||segmentInfo.changedTimestampOffset||"main"!==this.loaderType_)return;let didChange=!1;segmentInfo.timestampOffset-=this.getSegmentStartTimeForTimestampOffsetCalculation_({videoTimingInfo:segmentInfo.segment.videoTimingInfo,audioTimingInfo:segmentInfo.segment.audioTimingInfo,timingInfo:segmentInfo.timingInfo}),segmentInfo.changedTimestampOffset=!0,segmentInfo.timestampOffset!==this.sourceUpdater_.videoTimestampOffset()&&(this.sourceUpdater_.videoTimestampOffset(segmentInfo.timestampOffset),didChange=!0),segmentInfo.timestampOffset!==this.sourceUpdater_.audioTimestampOffset()&&(this.sourceUpdater_.audioTimestampOffset(segmentInfo.timestampOffset),didChange=!0),didChange&&this.trigger("timestampoffset")}getSegmentStartTimeForTimestampOffsetCalculation_(_ref71){let{videoTimingInfo:videoTimingInfo,audioTimingInfo:audioTimingInfo,timingInfo:timingInfo}=_ref71;return this.useDtsForTimestampOffset_?videoTimingInfo&&"number"==typeof videoTimingInfo.transmuxedDecodeStart?videoTimingInfo.transmuxedDecodeStart:audioTimingInfo&&"number"==typeof audioTimingInfo.transmuxedDecodeStart?audioTimingInfo.transmuxedDecodeStart:timingInfo.start:timingInfo.start}updateTimingInfoEnd_(segmentInfo){segmentInfo.timingInfo=segmentInfo.timingInfo||{};const trackInfo=this.getMediaInfo_(),prioritizedTimingInfo="main"===this.loaderType_&&trackInfo&&trackInfo.hasVideo&&segmentInfo.videoTimingInfo?segmentInfo.videoTimingInfo:segmentInfo.audioTimingInfo;prioritizedTimingInfo&&(segmentInfo.timingInfo.end="number"==typeof prioritizedTimingInfo.end?prioritizedTimingInfo.end:prioritizedTimingInfo.start+segmentInfo.duration)}handleAppendsDone_(){if(this.pendingSegment_&&this.trigger("appendsdone"),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());const segmentInfo=this.pendingSegment_;this.updateTimingInfoEnd_(segmentInfo),this.shouldSaveSegmentTimingInfo_&&this.syncController_.saveSegmentTimingInfo({segmentInfo:segmentInfo,shouldSaveTimelineMapping:"main"===this.loaderType_});const segmentDurationMessage=getTroublesomeSegmentDurationMessage(segmentInfo,this.sourceType_);if(segmentDurationMessage&&("warn"===segmentDurationMessage.severity?videojs.log.warn(segmentDurationMessage.message):this.logger_(segmentDurationMessage.message)),this.recordThroughput_(segmentInfo),this.pendingSegment_=null,this.state="READY",segmentInfo.isSyncRequest&&(this.trigger("syncinfoupdate"),!segmentInfo.hasAppendedData_))return void this.logger_("Throwing away un-appended sync request ".concat(segmentInfoString(segmentInfo)));this.logger_("Appended ".concat(segmentInfoString(segmentInfo))),this.addSegmentMetadataCue_(segmentInfo),this.fetchAtBuffer_=!0,this.currentTimeline_!==segmentInfo.timeline&&(this.timelineChangeController_.lastTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:segmentInfo.timeline}),"main"!==this.loaderType_||this.audioDisabled_||this.timelineChangeController_.lastTimelineChange({type:"audio",from:this.currentTimeline_,to:segmentInfo.timeline})),this.currentTimeline_=segmentInfo.timeline,this.trigger("syncinfoupdate");const segment=segmentInfo.segment,part=segmentInfo.part,badSegmentGuess=segment.end&&this.currentTime_()-segment.end>3*segmentInfo.playlist.targetDuration,badPartGuess=part&&part.end&&this.currentTime_()-part.end>3*segmentInfo.playlist.partTargetDuration;if(badSegmentGuess||badPartGuess)return this.logger_("bad ".concat(badSegmentGuess?"segment":"part"," ").concat(segmentInfoString(segmentInfo))),void this.resetEverything();null!==this.mediaIndex&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.mediaIndex=segmentInfo.mediaIndex,this.partIndex=segmentInfo.partIndex,this.isEndOfStream_(segmentInfo.mediaIndex,segmentInfo.playlist,segmentInfo.partIndex)&&this.endOfStream(),this.trigger("appended"),segmentInfo.hasAppendedData_&&this.mediaAppends++,this.paused()||this.monitorBuffer_()}recordThroughput_(segmentInfo){if(segmentInfo.duration<.016666666666666666)return void this.logger_("Ignoring segment's throughput because its duration of ".concat(segmentInfo.duration)+" is less than the min to record ".concat(.016666666666666666));const rate=this.throughput.rate,segmentProcessingTime=Date.now()-segmentInfo.endOfAllRequests+1,segmentProcessingThroughput=Math.floor(segmentInfo.byteLength/segmentProcessingTime*8*1e3);this.throughput.rate+=(segmentProcessingThroughput-rate)/++this.throughput.count}addSegmentMetadataCue_(segmentInfo){if(!this.segmentMetadataTrack_)return;const segment=segmentInfo.segment,start=segment.start,end=segment.end;if(!finite(start)||!finite(end))return;removeCuesFromTrack(start,end,this.segmentMetadataTrack_);const Cue=window.WebKitDataCue||window.VTTCue,value={custom:segment.custom,dateTimeObject:segment.dateTimeObject,dateTimeString:segment.dateTimeString,bandwidth:segmentInfo.playlist.attributes.BANDWIDTH,resolution:segmentInfo.playlist.attributes.RESOLUTION,codecs:segmentInfo.playlist.attributes.CODECS,byteLength:segmentInfo.byteLength,uri:segmentInfo.uri,timeline:segmentInfo.timeline,playlist:segmentInfo.playlist.id,start:start,end:end},cue=new Cue(start,end,JSON.stringify(value));cue.value=value,this.segmentMetadataTrack_.addCue(cue)}}function noop(){}const toTitleCase=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toUpperCase()))},bufferTypes=["video","audio"],updating=(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];return sourceBuffer&&sourceBuffer.updating||sourceUpdater.queuePending[type]},shiftQueue=(type,sourceUpdater)=>{if(0===sourceUpdater.queue.length)return;let queueIndex=0,queueEntry=sourceUpdater.queue[queueIndex];if("mediaSource"!==queueEntry.type){if("mediaSource"!==type&&sourceUpdater.ready()&&"closed"!==sourceUpdater.mediaSource.readyState&&!updating(type,sourceUpdater)){if(queueEntry.type!==type){if(queueIndex=((type,queue)=>{for(let i=0;i{const buffer=sourceUpdater["".concat(type,"Buffer")],titleType=toTitleCase(type);buffer&&(buffer.removeEventListener("updateend",sourceUpdater["on".concat(titleType,"UpdateEnd_")]),buffer.removeEventListener("error",sourceUpdater["on".concat(titleType,"Error_")]),sourceUpdater.codecs[type]=null,sourceUpdater["".concat(type,"Buffer")]=null)},inSourceBuffers=(mediaSource,sourceBuffer)=>mediaSource&&sourceBuffer&&-1!==Array.prototype.indexOf.call(mediaSource.sourceBuffers,sourceBuffer),actions_appendBuffer=(bytes,segmentInfo,onError)=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Appending segment ".concat(segmentInfo.mediaIndex,"'s ").concat(bytes.length," bytes to ").concat(type,"Buffer"));try{sourceBuffer.appendBuffer(bytes)}catch(e){sourceUpdater.logger_("Error with code ".concat(e.code," ")+(22===e.code?"(QUOTA_EXCEEDED_ERR) ":"")+"when appending segment ".concat(segmentInfo.mediaIndex," to ").concat(type,"Buffer")),sourceUpdater.queuePending[type]=null,onError(e)}}},actions_remove=(start,end)=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Removing ".concat(start," to ").concat(end," from ").concat(type,"Buffer"));try{sourceBuffer.remove(start,end)}catch(e){sourceUpdater.logger_("Remove ".concat(start," to ").concat(end," from ").concat(type,"Buffer failed"))}}},actions_timestampOffset=offset=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)&&(sourceUpdater.logger_("Setting ".concat(type,"timestampOffset to ").concat(offset)),sourceBuffer.timestampOffset=offset)},actions_callback=callback=>(type,sourceUpdater)=>{callback()},actions_endOfStream=error=>sourceUpdater=>{if("open"===sourceUpdater.mediaSource.readyState){sourceUpdater.logger_("Calling mediaSource endOfStream(".concat(error||"",")"));try{sourceUpdater.mediaSource.endOfStream(error)}catch(e){videojs.log.warn("Failed to call media source endOfStream",e)}}},actions_duration=duration=>sourceUpdater=>{sourceUpdater.logger_("Setting mediaSource duration to ".concat(duration));try{sourceUpdater.mediaSource.duration=duration}catch(e){videojs.log.warn("Failed to set media source duration",e)}},actions_abort=()=>(type,sourceUpdater)=>{if("open"!==sourceUpdater.mediaSource.readyState)return;const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("calling abort on ".concat(type,"Buffer"));try{sourceBuffer.abort()}catch(e){videojs.log.warn("Failed to abort on ".concat(type,"Buffer"),e)}}},actions_addSourceBuffer=(type,codec)=>sourceUpdater=>{const titleType=toTitleCase(type),mime=getMimeForCodec(codec);sourceUpdater.logger_("Adding ".concat(type,"Buffer with codec ").concat(codec," to mediaSource"));const sourceBuffer=sourceUpdater.mediaSource.addSourceBuffer(mime);sourceBuffer.addEventListener("updateend",sourceUpdater["on".concat(titleType,"UpdateEnd_")]),sourceBuffer.addEventListener("error",sourceUpdater["on".concat(titleType,"Error_")]),sourceUpdater.codecs[type]=codec,sourceUpdater["".concat(type,"Buffer")]=sourceBuffer},actions_removeSourceBuffer=type=>sourceUpdater=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(cleanupBuffer(type,sourceUpdater),inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Removing ".concat(type,"Buffer with codec ").concat(sourceUpdater.codecs[type]," from mediaSource"));try{sourceUpdater.mediaSource.removeSourceBuffer(sourceBuffer)}catch(e){videojs.log.warn("Failed to removeSourceBuffer ".concat(type,"Buffer"),e)}}},actions_changeType=codec=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")],mime=getMimeForCodec(codec);inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)&&sourceUpdater.codecs[type]!==codec&&(sourceUpdater.logger_("changing ".concat(type,"Buffer codec from ").concat(sourceUpdater.codecs[type]," to ").concat(codec)),sourceBuffer.changeType(mime),sourceUpdater.codecs[type]=codec)},pushQueue=_ref72=>{let{type:type,sourceUpdater:sourceUpdater,action:action,doneFn:doneFn,name:name}=_ref72;sourceUpdater.queue.push({type:type,action:action,doneFn:doneFn,name:name}),shiftQueue(type,sourceUpdater)},onUpdateend=(type,sourceUpdater)=>e=>{if(sourceUpdater.queuePending[type]){const doneFn=sourceUpdater.queuePending[type].doneFn;sourceUpdater.queuePending[type]=null,doneFn&&doneFn(sourceUpdater["".concat(type,"Error_")])}shiftQueue(type,sourceUpdater)};class SourceUpdater extends videojs.EventTarget{constructor(mediaSource){super(),this.mediaSource=mediaSource,this.sourceopenListener_=()=>shiftQueue("mediaSource",this),this.mediaSource.addEventListener("sourceopen",this.sourceopenListener_),this.logger_=logger("SourceUpdater"),this.audioTimestampOffset_=0,this.videoTimestampOffset_=0,this.queue=[],this.queuePending={audio:null,video:null},this.delayedAudioAppendQueue_=[],this.videoAppendQueued_=!1,this.codecs={},this.onVideoUpdateEnd_=onUpdateend("video",this),this.onAudioUpdateEnd_=onUpdateend("audio",this),this.onVideoError_=e=>{this.videoError_=e},this.onAudioError_=e=>{this.audioError_=e},this.createdSourceBuffers_=!1,this.initializedEme_=!1,this.triggeredReady_=!1}initializedEme(){this.initializedEme_=!0,this.triggerReady()}hasCreatedSourceBuffers(){return this.createdSourceBuffers_}hasInitializedAnyEme(){return this.initializedEme_}ready(){return this.hasCreatedSourceBuffers()&&this.hasInitializedAnyEme()}createSourceBuffers(codecs){this.hasCreatedSourceBuffers()||(this.addOrChangeSourceBuffers(codecs),this.createdSourceBuffers_=!0,this.trigger("createdsourcebuffers"),this.triggerReady())}triggerReady(){this.ready()&&!this.triggeredReady_&&(this.triggeredReady_=!0,this.trigger("ready"))}addSourceBuffer(type,codec){pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_addSourceBuffer(type,codec),name:"addSourceBuffer"})}abort(type){pushQueue({type:type,sourceUpdater:this,action:actions_abort(type),name:"abort"})}removeSourceBuffer(type){this.canRemoveSourceBuffer()?pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_removeSourceBuffer(type),name:"removeSourceBuffer"}):videojs.log.error("removeSourceBuffer is not supported!")}canRemoveSourceBuffer(){return!videojs.browser.IE_VERSION&&!videojs.browser.IS_FIREFOX&&window.MediaSource&&window.MediaSource.prototype&&"function"==typeof window.MediaSource.prototype.removeSourceBuffer}static canChangeType(){return window.SourceBuffer&&window.SourceBuffer.prototype&&"function"==typeof window.SourceBuffer.prototype.changeType}canChangeType(){return this.constructor.canChangeType()}changeType(type,codec){this.canChangeType()?pushQueue({type:type,sourceUpdater:this,action:actions_changeType(codec),name:"changeType"}):videojs.log.error("changeType is not supported!")}addOrChangeSourceBuffers(codecs){if(!codecs||"object"!=typeof codecs||0===Object.keys(codecs).length)throw new Error("Cannot addOrChangeSourceBuffers to undefined codecs");Object.keys(codecs).forEach((type=>{const codec=codecs[type];if(!this.hasCreatedSourceBuffers())return this.addSourceBuffer(type,codec);this.canChangeType()&&this.changeType(type,codec)}))}appendBuffer(options,doneFn){const{segmentInfo:segmentInfo,type:type,bytes:bytes}=options;if(this.processedAppend_=!0,"audio"===type&&this.videoBuffer&&!this.videoAppendQueued_)return this.delayedAudioAppendQueue_.push([options,doneFn]),void this.logger_("delayed audio append of ".concat(bytes.length," until video append"));if(pushQueue({type:type,sourceUpdater:this,action:actions_appendBuffer(bytes,segmentInfo||{mediaIndex:-1},doneFn),doneFn:doneFn,name:"appendBuffer"}),"video"===type){if(this.videoAppendQueued_=!0,!this.delayedAudioAppendQueue_.length)return;const queue=this.delayedAudioAppendQueue_.slice();this.logger_("queuing delayed audio ".concat(queue.length," appendBuffers")),this.delayedAudioAppendQueue_.length=0,queue.forEach((que=>{this.appendBuffer.apply(this,que)}))}}audioBuffered(){return inSourceBuffers(this.mediaSource,this.audioBuffer)&&this.audioBuffer.buffered?this.audioBuffer.buffered:createTimeRanges()}videoBuffered(){return inSourceBuffers(this.mediaSource,this.videoBuffer)&&this.videoBuffer.buffered?this.videoBuffer.buffered:createTimeRanges()}buffered(){const video=inSourceBuffers(this.mediaSource,this.videoBuffer)?this.videoBuffer:null,audio=inSourceBuffers(this.mediaSource,this.audioBuffer)?this.audioBuffer:null;return audio&&!video?this.audioBuffered():video&&!audio?this.videoBuffered():function(bufferA,bufferB){let start=null,end=null,arity=0;const extents=[],ranges=[];if(!(bufferA&&bufferA.length&&bufferB&&bufferB.length))return createTimeRanges();let count=bufferA.length;for(;count--;)extents.push({time:bufferA.start(count),type:"start"}),extents.push({time:bufferA.end(count),type:"end"});for(count=bufferB.length;count--;)extents.push({time:bufferB.start(count),type:"start"}),extents.push({time:bufferB.end(count),type:"end"});for(extents.sort((function(a,b){return a.time-b.time})),count=0;count1&&void 0!==arguments[1]?arguments[1]:noop;pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_duration(duration),name:"duration",doneFn:doneFn})}endOfStream(){let error=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,doneFn=arguments.length>1&&void 0!==arguments[1]?arguments[1]:noop;"string"!=typeof error&&(error=void 0),pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_endOfStream(error),name:"endOfStream",doneFn:doneFn})}removeAudio(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:noop;this.audioBuffered().length&&0!==this.audioBuffered().end(0)?pushQueue({type:"audio",sourceUpdater:this,action:actions_remove(start,end),doneFn:done,name:"remove"}):done()}removeVideo(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:noop;this.videoBuffered().length&&0!==this.videoBuffered().end(0)?pushQueue({type:"video",sourceUpdater:this,action:actions_remove(start,end),doneFn:done,name:"remove"}):done()}updating(){return!(!updating("audio",this)&&!updating("video",this))}audioTimestampOffset(offset){return void 0!==offset&&this.audioBuffer&&this.audioTimestampOffset_!==offset&&(pushQueue({type:"audio",sourceUpdater:this,action:actions_timestampOffset(offset),name:"timestampOffset"}),this.audioTimestampOffset_=offset),this.audioTimestampOffset_}videoTimestampOffset(offset){return void 0!==offset&&this.videoBuffer&&this.videoTimestampOffset!==offset&&(pushQueue({type:"video",sourceUpdater:this,action:actions_timestampOffset(offset),name:"timestampOffset"}),this.videoTimestampOffset_=offset),this.videoTimestampOffset_}audioQueueCallback(callback){this.audioBuffer&&pushQueue({type:"audio",sourceUpdater:this,action:actions_callback(callback),name:"callback"})}videoQueueCallback(callback){this.videoBuffer&&pushQueue({type:"video",sourceUpdater:this,action:actions_callback(callback),name:"callback"})}dispose(){this.trigger("dispose"),bufferTypes.forEach((type=>{this.abort(type),this.canRemoveSourceBuffer()?this.removeSourceBuffer(type):this["".concat(type,"QueueCallback")]((()=>cleanupBuffer(type,this)))})),this.videoAppendQueued_=!1,this.delayedAudioAppendQueue_.length=0,this.sourceopenListener_&&this.mediaSource.removeEventListener("sourceopen",this.sourceopenListener_),this.off()}}const uint8ToUtf8=uintArray=>decodeURIComponent(escape(String.fromCharCode.apply(null,uintArray))),VTT_LINE_TERMINATORS=new Uint8Array("\n\n".split("").map((char=>char.charCodeAt(0))));class NoVttJsError extends Error{constructor(){super("Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.")}}class VTTSegmentLoader extends SegmentLoader{constructor(settings){super(settings,arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}),this.mediaSource_=null,this.subtitlesTrack_=null,this.loaderType_="subtitle",this.featuresNativeTextTracks_=settings.featuresNativeTextTracks,this.loadVttJs=settings.loadVttJs,this.shouldSaveSegmentTimingInfo_=!1}createTransmuxer_(){return null}buffered_(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues||!this.subtitlesTrack_.cues.length)return createTimeRanges();const cues=this.subtitlesTrack_.cues;return createTimeRanges([[cues[0].startTime,cues[cues.length-1].startTime]])}initSegmentForMap(map){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!map)return null;const id=initSegmentId(map);let storedMap=this.initSegments_[id];if(set&&!storedMap&&map.bytes){const combinedByteLength=VTT_LINE_TERMINATORS.byteLength+map.bytes.byteLength,combinedSegment=new Uint8Array(combinedByteLength);combinedSegment.set(map.bytes),combinedSegment.set(VTT_LINE_TERMINATORS,map.bytes.byteLength),this.initSegments_[id]=storedMap={resolvedUri:map.resolvedUri,byterange:map.byterange,bytes:combinedSegment}}return storedMap||map}couldBeginLoading_(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()}init_(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}track(track){return void 0===track||(this.subtitlesTrack_=track,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_}remove(start,end){removeCuesFromTrack(start,end,this.subtitlesTrack_)}fillBuffer_(){const segmentInfo=this.chooseNextRequest_();if(segmentInfo){if(null===this.syncController_.timestampOffsetForTimeline(segmentInfo.timeline)){const checkTimestampOffset=()=>{this.state="READY",this.paused()||this.monitorBuffer_()};return this.syncController_.one("timestampoffset",checkTimestampOffset),void(this.state="WAITING_ON_TIMELINE")}this.loadSegment_(segmentInfo)}}timestampOffsetForSegment_(){return null}chooseNextRequest_(){return this.skipEmptySegments_(super.chooseNextRequest_())}skipEmptySegments_(segmentInfo){for(;segmentInfo&&segmentInfo.segment.empty;){if(segmentInfo.mediaIndex+1>=segmentInfo.playlist.segments.length){segmentInfo=null;break}segmentInfo=this.generateSegmentInfo_({playlist:segmentInfo.playlist,mediaIndex:segmentInfo.mediaIndex+1,startOfSegment:segmentInfo.startOfSegment+segmentInfo.duration,isSyncRequest:segmentInfo.isSyncRequest})}return segmentInfo}stopForError(error){this.error(error),this.state="READY",this.pause(),this.trigger("error")}segmentRequestFinished_(error,simpleSegment,result){if(!this.subtitlesTrack_)return void(this.state="READY");if(this.saveTransferStats_(simpleSegment.stats),!this.pendingSegment_)return this.state="READY",void(this.mediaRequestsAborted+=1);if(error)return error.code===REQUEST_ERRORS_TIMEOUT&&this.handleTimeout_(),error.code===REQUEST_ERRORS_ABORTED?this.mediaRequestsAborted+=1:this.mediaRequestsErrored+=1,void this.stopForError(error);const segmentInfo=this.pendingSegment_;this.saveBandwidthRelatedStats_(segmentInfo.duration,simpleSegment.stats),simpleSegment.key&&this.segmentKey(simpleSegment.key,!0),this.state="APPENDING",this.trigger("appending");const segment=segmentInfo.segment;if(segment.map&&(segment.map.bytes=simpleSegment.map.bytes),segmentInfo.bytes=simpleSegment.bytes,"function"!=typeof window.WebVTT&&"function"==typeof this.loadVttJs)return this.state="WAITING_ON_VTTJS",void this.loadVttJs().then((()=>this.segmentRequestFinished_(error,simpleSegment,result)),(()=>this.stopForError({message:"Error loading vtt.js"})));segment.requested=!0;try{this.parseVTTCues_(segmentInfo)}catch(e){return void this.stopForError({message:e.message})}if(this.updateTimeMapping_(segmentInfo,this.syncController_.timelines[segmentInfo.timeline],this.playlist_),segmentInfo.cues.length?segmentInfo.timingInfo={start:segmentInfo.cues[0].startTime,end:segmentInfo.cues[segmentInfo.cues.length-1].endTime}:segmentInfo.timingInfo={start:segmentInfo.startOfSegment,end:segmentInfo.startOfSegment+segmentInfo.duration},segmentInfo.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");segmentInfo.byteLength=segmentInfo.bytes.byteLength,this.mediaSecondsLoaded+=segment.duration,segmentInfo.cues.forEach((cue=>{this.subtitlesTrack_.addCue(this.featuresNativeTextTracks_?new window.VTTCue(cue.startTime,cue.endTime,cue.text):cue)})),function(track){const cues=track.cues;if(cues)for(let i=0;i1&&duplicates.push(cues[j]));duplicates.length&&duplicates.forEach((dupe=>track.removeCue(dupe)))}}(this.subtitlesTrack_),this.handleAppendsDone_()}handleData_(){}updateTimingInfoEnd_(){}parseVTTCues_(segmentInfo){let decoder,decodeBytesToString=!1;if("function"!=typeof window.WebVTT)throw new NoVttJsError;"function"==typeof window.TextDecoder?decoder=new window.TextDecoder("utf8"):(decoder=window.WebVTT.StringDecoder(),decodeBytesToString=!0);const parser=new window.WebVTT.Parser(window,window.vttjs,decoder);if(segmentInfo.cues=[],segmentInfo.timestampmap={MPEGTS:0,LOCAL:0},parser.oncue=segmentInfo.cues.push.bind(segmentInfo.cues),parser.ontimestampmap=map=>{segmentInfo.timestampmap=map},parser.onparsingerror=error=>{videojs.log.warn("Error encountered when parsing cues: "+error.message)},segmentInfo.segment.map){let mapData=segmentInfo.segment.map.bytes;decodeBytesToString&&(mapData=uint8ToUtf8(mapData)),parser.parse(mapData)}let segmentData=segmentInfo.bytes;decodeBytesToString&&(segmentData=uint8ToUtf8(segmentData)),parser.parse(segmentData),parser.flush()}updateTimeMapping_(segmentInfo,mappingObj,playlist){const segment=segmentInfo.segment;if(!mappingObj)return;if(!segmentInfo.cues.length)return void(segment.empty=!0);const timestampmap=segmentInfo.timestampmap,diff=timestampmap.MPEGTS/clock_1-timestampmap.LOCAL+mappingObj.mapping;if(segmentInfo.cues.forEach((cue=>{cue.startTime+=diff,cue.endTime+=diff})),!playlist.syncInfo){const firstStart=segmentInfo.cues[0].startTime,lastStart=segmentInfo.cues[segmentInfo.cues.length-1].startTime;playlist.syncInfo={mediaSequence:playlist.mediaSequence+segmentInfo.mediaIndex,time:Math.min(firstStart,lastStart-segment.duration)}}}}const findAdCue=function(track,mediaTime){const cues=track.cues;for(let i=0;i=cue.adStartTime&&mediaTime<=cue.adEndTime)return cue}return null},syncPointStrategies=[{name:"VOD",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{if(duration!==1/0){return{time:0,segmentIndex:0,partIndex:null}}return null}},{name:"ProgramDateTime",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{if(!Object.keys(syncController.timelineToDatetimeMappings).length)return null;let syncPoint=null,lastDistance=null;const partsAndSegments=getPartsAndSegments(playlist);currentTime=currentTime||0;for(let i=0;i{let syncPoint=null,lastDistance=null;currentTime=currentTime||0;const partsAndSegments=getPartsAndSegments(playlist);for(let i=0;i=distance)&&(lastDistance=distance,syncPoint={time:start,segmentIndex:partAndSegment.segmentIndex,partIndex:partAndSegment.partIndex})}}return syncPoint}},{name:"Discontinuity",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{let syncPoint=null;if(currentTime=currentTime||0,playlist.discontinuityStarts&&playlist.discontinuityStarts.length){let lastDistance=null;for(let i=0;i=distance)&&(lastDistance=distance,syncPoint={time:discontinuitySync.time,segmentIndex:segmentIndex,partIndex:null})}}}return syncPoint}},{name:"Playlist",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{if(playlist.syncInfo){return{time:playlist.syncInfo.time,segmentIndex:playlist.syncInfo.mediaSequence-playlist.mediaSequence,partIndex:null}}return null}}];class SyncController extends videojs.EventTarget{constructor(){super(),this.timelines=[],this.discontinuities=[],this.timelineToDatetimeMappings={},this.logger_=logger("SyncController")}getSyncPoint(playlist,duration,currentTimeline,currentTime){const syncPoints=this.runStrategies_(playlist,duration,currentTimeline,currentTime);return syncPoints.length?this.selectSyncPoint_(syncPoints,{key:"time",value:currentTime}):null}getExpiredTime(playlist,duration){if(!playlist||!playlist.segments)return null;const syncPoints=this.runStrategies_(playlist,duration,playlist.discontinuitySequence,0);if(!syncPoints.length)return null;const syncPoint=this.selectSyncPoint_(syncPoints,{key:"segmentIndex",value:0});return syncPoint.segmentIndex>0&&(syncPoint.time*=-1),Math.abs(syncPoint.time+sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:syncPoint.segmentIndex,endIndex:0}))}runStrategies_(playlist,duration,currentTimeline,currentTime){const syncPoints=[];for(let i=0;i86400)videojs.log.warn("Not saving expired segment info. Media sequence gap ".concat(mediaSequenceDiff," is too large."));else for(let i=mediaSequenceDiff-1;i>=0;i--){const lastRemovedSegment=oldPlaylist.segments[i];if(lastRemovedSegment&&void 0!==lastRemovedSegment.start){newPlaylist.syncInfo={mediaSequence:oldPlaylist.mediaSequence+i,time:lastRemovedSegment.start},this.logger_("playlist refresh sync: [time:".concat(newPlaylist.syncInfo.time,",")+" mediaSequence: ".concat(newPlaylist.syncInfo.mediaSequence,"]")),this.trigger("syncinfoupdate");break}}}setDateTimeMappingForStart(playlist){if(this.timelineToDatetimeMappings={},playlist.segments&&playlist.segments.length&&playlist.segments[0].dateTimeObject){const firstSegment=playlist.segments[0],playlistTimestamp=firstSegment.dateTimeObject.getTime()/1e3;this.timelineToDatetimeMappings[firstSegment.timeline]=-playlistTimestamp}}saveSegmentTimingInfo(_ref73){let{segmentInfo:segmentInfo,shouldSaveTimelineMapping:shouldSaveTimelineMapping}=_ref73;const didCalculateSegmentTimeMapping=this.calculateSegmentTimeMapping_(segmentInfo,segmentInfo.timingInfo,shouldSaveTimelineMapping),segment=segmentInfo.segment;didCalculateSegmentTimeMapping&&(this.saveDiscontinuitySyncInfo_(segmentInfo),segmentInfo.playlist.syncInfo||(segmentInfo.playlist.syncInfo={mediaSequence:segmentInfo.playlist.mediaSequence+segmentInfo.mediaIndex,time:segment.start}));const dateTime=segment.dateTimeObject;segment.discontinuity&&shouldSaveTimelineMapping&&dateTime&&(this.timelineToDatetimeMappings[segment.timeline]=-dateTime.getTime()/1e3)}timestampOffsetForTimeline(timeline){return void 0===this.timelines[timeline]?null:this.timelines[timeline].time}mappingForTimeline(timeline){return void 0===this.timelines[timeline]?null:this.timelines[timeline].mapping}calculateSegmentTimeMapping_(segmentInfo,timingInfo,shouldSaveTimelineMapping){const segment=segmentInfo.segment,part=segmentInfo.part;let start,end,mappingObj=this.timelines[segmentInfo.timeline];if("number"==typeof segmentInfo.timestampOffset)mappingObj={time:segmentInfo.startOfSegment,mapping:segmentInfo.startOfSegment-timingInfo.start},shouldSaveTimelineMapping&&(this.timelines[segmentInfo.timeline]=mappingObj,this.trigger("timestampoffset"),this.logger_("time mapping for timeline ".concat(segmentInfo.timeline,": ")+"[time: ".concat(mappingObj.time,"] [mapping: ").concat(mappingObj.mapping,"]"))),start=segmentInfo.startOfSegment,end=timingInfo.end+mappingObj.mapping;else{if(!mappingObj)return!1;start=timingInfo.start+mappingObj.mapping,end=timingInfo.end+mappingObj.mapping}return part&&(part.start=start,part.end=end),(!segment.start||startaccuracy){let time;time=mediaIndexDiff<0?segment.start-sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:segmentInfo.mediaIndex,endIndex:segmentIndex}):segment.end+sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:segmentInfo.mediaIndex+1,endIndex:segmentIndex}),this.discontinuities[discontinuity]={time:time,accuracy:accuracy}}}}dispose(){this.trigger("dispose"),this.off()}}class TimelineChangeController extends videojs.EventTarget{constructor(){super(),this.pendingTimelineChanges_={},this.lastTimelineChanges_={}}clearPendingTimelineChange(type){this.pendingTimelineChanges_[type]=null,this.trigger("pendingtimelinechange")}pendingTimelineChange(_ref74){let{type:type,from:from,to:to}=_ref74;return"number"==typeof from&&"number"==typeof to&&(this.pendingTimelineChanges_[type]={type:type,from:from,to:to},this.trigger("pendingtimelinechange")),this.pendingTimelineChanges_[type]}lastTimelineChange(_ref75){let{type:type,from:from,to:to}=_ref75;return"number"==typeof from&&"number"==typeof to&&(this.lastTimelineChanges_[type]={type:type,from:from,to:to},delete this.pendingTimelineChanges_[type],this.trigger("timelinechange")),this.lastTimelineChanges_[type]}dispose(){this.trigger("dispose"),this.pendingTimelineChanges_={},this.lastTimelineChanges_={},this.off()}}const workerCode=transform(getWorkerString((function(){var Stream=function(){function Stream(){this.listeners={}}var _proto=Stream.prototype;return _proto.on=function(type,listener){this.listeners[type]||(this.listeners[type]=[]),this.listeners[type].push(listener)},_proto.off=function(type,listener){if(!this.listeners[type])return!1;var index=this.listeners[type].indexOf(listener);return this.listeners[type]=this.listeners[type].slice(0),this.listeners[type].splice(index,1),index>-1},_proto.trigger=function(type){var callbacks=this.listeners[type];if(callbacks)if(2===arguments.length)for(var length=callbacks.length,i=0;i0&&(timeoutTimer=setTimeout((function(){if(!aborted){aborted=!0,xhr.abort("timeout");var e=new Error("XMLHttpRequest timeout");e.code="ETIMEDOUT",errorFunc(e)}}),options.timeout)),xhr.setRequestHeader)for(key in headers)headers.hasOwnProperty(key)&&xhr.setRequestHeader(key,headers[key]);else if(options.headers&&!function(obj){for(var i in obj)if(obj.hasOwnProperty(i))return!1;return!0}(options.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in options&&(xhr.responseType=options.responseType),"beforeSend"in options&&"function"==typeof options.beforeSend&&options.beforeSend(xhr),xhr.send(body||null),xhr}createXHR.XMLHttpRequest=window_1.XMLHttpRequest||function(){},createXHR.XDomainRequest="withCredentials"in new createXHR.XMLHttpRequest?createXHR.XMLHttpRequest:window_1.XDomainRequest,function(array,iterator){for(var i=0;i0&&(window.console&&window.console.groupCollapsed&&window.console.groupCollapsed("Text Track parsing errors for ".concat(track.src)),errors.forEach((error=>log$1.error(error))),window.console&&window.console.groupEnd&&window.console.groupEnd()),parser.flush()},loadTrack=function(src,track){const opts={uri:src},crossOrigin=isCrossOrigin(src);crossOrigin&&(opts.cors=crossOrigin);const withCredentials="use-credentials"===track.tech_.crossOrigin();withCredentials&&(opts.withCredentials=withCredentials),lib(opts,bind_(this,(function(err,response,responseBody){if(err)return log$1.error(err,response);track.loaded_=!0,"function"!=typeof window.WebVTT?track.tech_&&track.tech_.any(["vttjsloaded","vttjserror"],(event=>{if("vttjserror"!==event.type)return parseCues(responseBody,track);log$1.error("vttjs failed to load, stopping trying to process ".concat(track.src))})):parseCues(responseBody,track)})))};class TextTrack extends Track{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!options.tech)throw new Error("A tech was not provided.");const settings=merge$2(options,{kind:TextTrackKind[options.kind]||"subtitles",language:options.language||options.srclang||""});let mode=TextTrackMode[settings.mode]||"disabled";const default_=settings.default;"metadata"!==settings.kind&&"chapters"!==settings.kind||(mode="hidden"),super(settings),this.tech_=settings.tech,this.cues_=[],this.activeCues_=[],this.preload_=!1!==this.tech_.preloadTextTracks;const cues=new TextTrackCueList(this.cues_),activeCues=new TextTrackCueList(this.activeCues_);let changed=!1;this.timeupdateHandler=bind_(this,(function(){let event=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.tech_.isDisposed()||(this.tech_.isReady_?(this.activeCues=this.activeCues,changed&&(this.trigger("cuechange"),changed=!1),"timeupdate"!==event.type&&(this.rvf_=this.tech_.requestVideoFrameCallback(this.timeupdateHandler))):"timeupdate"!==event.type&&(this.rvf_=this.tech_.requestVideoFrameCallback(this.timeupdateHandler)))}));this.tech_.one("dispose",(()=>{this.stopTracking()})),"disabled"!==mode&&this.startTracking(),Object.defineProperties(this,{default:{get:()=>default_,set(){}},mode:{get:()=>mode,set(newMode){TextTrackMode[newMode]&&mode!==newMode&&(mode=newMode,this.preload_||"disabled"===mode||0!==this.cues.length||loadTrack(this.src,this),this.stopTracking(),"disabled"!==mode&&this.startTracking(),this.trigger("modechange"))}},cues:{get(){return this.loaded_?cues:null},set(){}},activeCues:{get(){if(!this.loaded_)return null;if(0===this.cues.length)return activeCues;const ct=this.tech_.currentTime(),active=[];for(let i=0,l=this.cues.length;i=ct&&active.push(cue)}if(changed=!1,active.length!==this.activeCues_.length)changed=!0;else for(let i=0;i0&&void 0!==arguments[0]?arguments[0]:{};const settings=merge$2(options,{kind:AudioTrackKind[options.kind]||""});super(settings);let enabled=!1;Object.defineProperty(this,"enabled",{get:()=>enabled,set(newEnabled){"boolean"==typeof newEnabled&&newEnabled!==enabled&&(enabled=newEnabled,this.trigger("enabledchange"))}}),settings.enabled&&(this.enabled=settings.enabled),this.loaded_=!0}}class VideoTrack extends Track{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const settings=merge$2(options,{kind:VideoTrackKind[options.kind]||""});super(settings);let selected=!1;Object.defineProperty(this,"selected",{get:()=>selected,set(newSelected){"boolean"==typeof newSelected&&newSelected!==selected&&(selected=newSelected,this.trigger("selectedchange"))}}),settings.selected&&(this.selected=settings.selected)}}class HTMLTrackElement extends EventTarget$2{constructor(){let readyState,options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super();const track=new TextTrack(options);this.kind=track.kind,this.src=track.src,this.srclang=track.language,this.label=track.label,this.default=track.default,Object.defineProperties(this,{readyState:{get:()=>readyState},track:{get:()=>track}}),readyState=HTMLTrackElement.NONE,track.addEventListener("loadeddata",(()=>{readyState=HTMLTrackElement.LOADED,this.trigger({type:"load",target:this})}))}}HTMLTrackElement.prototype.allowedEvents_={load:"load"},HTMLTrackElement.NONE=0,HTMLTrackElement.LOADING=1,HTMLTrackElement.LOADED=2,HTMLTrackElement.ERROR=3;const NORMAL={audio:{ListClass:class extends TrackList{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];for(let i=tracks.length-1;i>=0;i--)if(tracks[i].enabled){disableOthers$1(tracks,tracks[i]);break}super(tracks),this.changing_=!1}addTrack(track){track.enabled&&disableOthers$1(this,track),super.addTrack(track),track.addEventListener&&(track.enabledChange_=()=>{this.changing_||(this.changing_=!0,disableOthers$1(this,track),this.changing_=!1,this.trigger("change"))},track.addEventListener("enabledchange",track.enabledChange_))}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&rtrack.enabledChange_&&(rtrack.removeEventListener("enabledchange",rtrack.enabledChange_),rtrack.enabledChange_=null)}},TrackClass:AudioTrack,capitalName:"Audio"},video:{ListClass:class extends TrackList{constructor(){let tracks=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];for(let i=tracks.length-1;i>=0;i--)if(tracks[i].selected){disableOthers(tracks,tracks[i]);break}super(tracks),this.changing_=!1,Object.defineProperty(this,"selectedIndex",{get(){for(let i=0;i{this.changing_||(this.changing_=!0,disableOthers(this,track),this.changing_=!1,this.trigger("change"))},track.addEventListener("selectedchange",track.selectedChange_))}removeTrack(rtrack){super.removeTrack(rtrack),rtrack.removeEventListener&&rtrack.selectedChange_&&(rtrack.removeEventListener("selectedchange",rtrack.selectedChange_),rtrack.selectedChange_=null)}},TrackClass:VideoTrack,capitalName:"Video"},text:{ListClass:TextTrackList,TrackClass:TextTrack,capitalName:"Text"}};Object.keys(NORMAL).forEach((function(type){NORMAL[type].getterName="".concat(type,"Tracks"),NORMAL[type].privateName="".concat(type,"Tracks_")}));const REMOTE={remoteText:{ListClass:TextTrackList,TrackClass:TextTrack,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:class{constructor(){let trackElements=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.trackElements_=[],Object.defineProperty(this,"length",{get(){return this.trackElements_.length}});for(let i=0,length=trackElements.length;i59?computeSeconds(m[1],m[2],0,m[4]):computeSeconds(0,m[1],m[2],m[4]):null}function Settings(){this.values=_objCreate(null)}function parseOptions(input,callback,keyValueDelim,groupDelim){var groups=groupDelim?input.split(groupDelim):[input];for(var i in groups)if("string"==typeof groups[i]){var kv=groups[i].split(keyValueDelim);if(2===kv.length)callback(kv[0].trim(),kv[1].trim())}}function parseCue(input,cue,regionList){var oInput=input;function consumeTimeStamp(){var ts=parseTimeStamp(input);if(null===ts)throw new ParsingError(ParsingError.Errors.BadTimeStamp,"Malformed timestamp: "+oInput);return input=input.replace(/^[^\sa-zA-Z-]+/,""),ts}function skipWhitespace(){input=input.replace(/^\s+/,"")}if(skipWhitespace(),cue.startTime=consumeTimeStamp(),skipWhitespace(),"--\x3e"!==input.substr(0,3))throw new ParsingError(ParsingError.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+oInput);input=input.substr(3),skipWhitespace(),cue.endTime=consumeTimeStamp(),skipWhitespace(),function(input,cue){var settings=new Settings;parseOptions(input,(function(k,v){switch(k){case"region":for(var i=regionList.length-1;i>=0;i--)if(regionList[i].id===v){settings.set(k,regionList[i].region);break}break;case"vertical":settings.alt(k,v,["rl","lr"]);break;case"line":var vals=v.split(","),vals0=vals[0];settings.integer(k,vals0),settings.percent(k,vals0)&&settings.set("snapToLines",!1),settings.alt(k,vals0,["auto"]),2===vals.length&&settings.alt("lineAlign",vals[1],["start","center","end"]);break;case"position":vals=v.split(","),settings.percent(k,vals[0]),2===vals.length&&settings.alt("positionAlign",vals[1],["start","center","end"]);break;case"size":settings.percent(k,v);break;case"align":settings.alt(k,v,["start","center","end","left","right"])}}),/:/,/\s/),cue.region=settings.get("region",null),cue.vertical=settings.get("vertical","");try{cue.line=settings.get("line","auto")}catch(e){}cue.lineAlign=settings.get("lineAlign","start"),cue.snapToLines=settings.get("snapToLines",!0),cue.size=settings.get("size",100);try{cue.align=settings.get("align","center")}catch(e){cue.align=settings.get("align","middle")}try{cue.position=settings.get("position","auto")}catch(e){cue.position=settings.get("position",{start:0,left:0,center:50,middle:50,end:100,right:100},cue.align)}cue.positionAlign=settings.get("positionAlign",{start:"start",left:"start",center:"center",middle:"center",end:"end",right:"end"},cue.align)}(input,cue)}ParsingError.prototype=_objCreate(Error.prototype),ParsingError.prototype.constructor=ParsingError,ParsingError.Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},Settings.prototype={set:function(k,v){this.get(k)||""===v||(this.values[k]=v)},get:function(k,dflt,defaultKey){return defaultKey?this.has(k)?this.values[k]:dflt[defaultKey]:this.has(k)?this.values[k]:dflt},has:function(k){return k in this.values},alt:function(k,v,a){for(var n=0;n=0&&v<=100)&&(this.set(k,v),!0)}};var TEXTAREA_ELEMENT=document_1.createElement&&document_1.createElement("textarea"),TAG_NAME={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},DEFAULT_COLOR_CLASS={white:"rgba(255,255,255,1)",lime:"rgba(0,255,0,1)",cyan:"rgba(0,255,255,1)",red:"rgba(255,0,0,1)",yellow:"rgba(255,255,0,1)",magenta:"rgba(255,0,255,1)",blue:"rgba(0,0,255,1)",black:"rgba(0,0,0,1)"},TAG_ANNOTATION={v:"title",lang:"lang"},NEEDS_PARENT={rt:"ruby"};function parseContent(window,input){function nextToken(){if(!input)return null;var result,m=input.match(/^([^<]*)(<[^>]*>?)?/);return result=m[1]?m[1]:m[2],input=input.substr(result.length),result}function shouldAdd(current,element){return!NEEDS_PARENT[element.localName]||NEEDS_PARENT[element.localName]===current.localName}function createElement(type,annotation){var tagName=TAG_NAME[type];if(!tagName)return null;var element=window.document.createElement(tagName),name=TAG_ANNOTATION[type];return name&&annotation&&(element[name]=annotation.trim()),element}for(var t,s,rootDiv=window.document.createElement("div"),current=rootDiv,tagStack=[];null!==(t=nextToken());)if("<"!==t[0])current.appendChild(window.document.createTextNode((s=t,TEXTAREA_ELEMENT.innerHTML=s,s=TEXTAREA_ELEMENT.textContent,TEXTAREA_ELEMENT.textContent="",s)));else{if("/"===t[1]){tagStack.length&&tagStack[tagStack.length-1]===t.substr(2).replace(">","")&&(tagStack.pop(),current=current.parentNode);continue}var node,ts=parseTimeStamp(t.substr(1,t.length-2));if(ts){node=window.document.createProcessingInstruction("timestamp",ts),current.appendChild(node);continue}var m=t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!m)continue;if(!(node=createElement(m[1],m[3])))continue;if(!shouldAdd(current,node))continue;if(m[2]){var classes=m[2].split(".");classes.forEach((function(cl){var bgColor=/^bg_/.test(cl),colorName=bgColor?cl.slice(3):cl;if(DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)){var propName=bgColor?"background-color":"color",propValue=DEFAULT_COLOR_CLASS[colorName];node.style[propName]=propValue}})),node.className=classes.join(" ")}tagStack.push(m[1]),current.appendChild(node),current=node}return rootDiv}var strongRTLRanges=[[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 isStrongRTLChar(charCode){for(var i=0;i=currentRange[0]&&charCode<=currentRange[1])return!0}return!1}function determineBidi(cueDiv){var nodeStack=[],text="";if(!cueDiv||!cueDiv.childNodes)return"ltr";function pushNodes(nodeStack,node){for(var i=node.childNodes.length-1;i>=0;i--)nodeStack.push(node.childNodes[i])}function nextTextNode(nodeStack){if(!nodeStack||!nodeStack.length)return null;var node=nodeStack.pop(),text=node.textContent||node.innerText;if(text){var m=text.match(/^.*(\n|\r)/);return m?(nodeStack.length=0,m[0]):text}return"ruby"===node.tagName?nextTextNode(nodeStack):node.childNodes?(pushNodes(nodeStack,node),nextTextNode(nodeStack)):void 0}for(pushNodes(nodeStack,cueDiv);text=nextTextNode(nodeStack);)for(var i=0;i=0&&cue.line<=100))return cue.line;if(!cue.track||!cue.track.textTrackList||!cue.track.textTrackList.mediaElement)return-1;for(var track=cue.track,trackList=track.textTrackList,count=0,i=0;imaxPosition&&(position=position<0?-1:1,position*=Math.ceil(maxPosition/step)*step),linePos<0&&(position+=""===cue.vertical?containerBox.height:containerBox.width,axis=axis.reverse()),boxPosition.move(initialAxis,position)}else{var calculatedPercentage=boxPosition.lineHeight/containerBox.height*100;switch(cue.lineAlign){case"center":linePos-=calculatedPercentage/2;break;case"end":linePos-=calculatedPercentage}switch(cue.vertical){case"":styleBox.applyStyles({top:styleBox.formatStyle(linePos,"%")});break;case"rl":styleBox.applyStyles({left:styleBox.formatStyle(linePos,"%")});break;case"lr":styleBox.applyStyles({right:styleBox.formatStyle(linePos,"%")})}axis=["+y","-x","+x","-y"],boxPosition=new BoxPosition(styleBox)}var bestPosition=function(b,axis){for(var bestPosition,specifiedPosition=new BoxPosition(b),percentage=1,i=0;ip&&(bestPosition=new BoxPosition(b),percentage=p),b=new BoxPosition(specifiedPosition)}return bestPosition||specifiedPosition}(boxPosition,axis);styleBox.move(bestPosition.toCSSCompatValues(containerBox))}function WebVTT$1(){}StyleBox.prototype.applyStyles=function(styles,div){for(var prop in div=div||this.div,styles)styles.hasOwnProperty(prop)&&(div.style[prop]=styles[prop])},StyleBox.prototype.formatStyle=function(val,unit){return 0===val?0:val+unit},CueStyleBox.prototype=_objCreate(StyleBox.prototype),CueStyleBox.prototype.constructor=CueStyleBox,BoxPosition.prototype.move=function(axis,toMove){switch(toMove=void 0!==toMove?toMove:this.lineHeight,axis){case"+x":this.left+=toMove,this.right+=toMove;break;case"-x":this.left-=toMove,this.right-=toMove;break;case"+y":this.top+=toMove,this.bottom+=toMove;break;case"-y":this.top-=toMove,this.bottom-=toMove}},BoxPosition.prototype.overlaps=function(b2){return this.leftb2.left&&this.topb2.top},BoxPosition.prototype.overlapsAny=function(boxes){for(var i=0;i=container.top&&this.bottom<=container.bottom&&this.left>=container.left&&this.right<=container.right},BoxPosition.prototype.overlapsOppositeAxis=function(container,axis){switch(axis){case"+x":return this.leftcontainer.right;case"+y":return this.topcontainer.bottom}},BoxPosition.prototype.intersectPercentage=function(b2){return Math.max(0,Math.min(this.right,b2.right)-Math.max(this.left,b2.left))*Math.max(0,Math.min(this.bottom,b2.bottom)-Math.max(this.top,b2.top))/(this.height*this.width)},BoxPosition.prototype.toCSSCompatValues=function(reference){return{top:this.top-reference.top,bottom:reference.bottom-this.bottom,left:this.left-reference.left,right:reference.right-this.right,height:this.height,width:this.width}},BoxPosition.getSimpleBoxPosition=function(obj){var height=obj.div?obj.div.offsetHeight:obj.tagName?obj.offsetHeight:0,width=obj.div?obj.div.offsetWidth:obj.tagName?obj.offsetWidth:0,top=obj.div?obj.div.offsetTop:obj.tagName?obj.offsetTop:0;return{left:(obj=obj.div?obj.div.getBoundingClientRect():obj.tagName?obj.getBoundingClientRect():obj).left,right:obj.right,top:obj.top||top,height:obj.height||height,bottom:obj.bottom||top+(obj.height||height),width:obj.width||width}},WebVTT$1.StringDecoder=function(){return{decode:function(data){if(!data)return"";if("string"!=typeof data)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(data))}}},WebVTT$1.convertCueToDOMTree=function(window,cuetext){return window&&cuetext?parseContent(window,cuetext):null};WebVTT$1.processCues=function(window,cues,overlay){if(!window||!cues||!overlay)return null;for(;overlay.firstChild;)overlay.removeChild(overlay.firstChild);var paddedOverlay=window.document.createElement("div");if(paddedOverlay.style.position="absolute",paddedOverlay.style.left="0",paddedOverlay.style.right="0",paddedOverlay.style.top="0",paddedOverlay.style.bottom="0",paddedOverlay.style.margin="1.5%",overlay.appendChild(paddedOverlay),function(cues){for(var i=0;i100)throw new Error("Position must be between 0 and 100.");_position=value,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return _positionAlign},set:function(value){var setting=findAlignSetting(value);setting?(_positionAlign=setting,this.hasBeenReset=!0):console.warn("positionAlign: an invalid or illegal string was specified.")}},size:{enumerable:!0,get:function(){return _size},set:function(value){if(value<0||value>100)throw new Error("Size must be between 0 and 100.");_size=value,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return _align},set:function(value){var setting=findAlignSetting(value);if(!setting)throw new SyntaxError("align: an invalid or illegal alignment string was specified.");_align=setting,this.hasBeenReset=!0}}}),this.displayState=void 0}VTTCue.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var vttcue=VTTCue,scrollSetting={"":!0,up:!0};function isValidPercentValue(value){return"number"==typeof value&&value>=0&&value<=100}var vttregion=function(){var _width=100,_lines=3,_regionAnchorX=0,_regionAnchorY=100,_viewportAnchorX=0,_viewportAnchorY=100,_scroll="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return _width},set:function(value){if(!isValidPercentValue(value))throw new Error("Width must be between 0 and 100.");_width=value}},lines:{enumerable:!0,get:function(){return _lines},set:function(value){if("number"!=typeof value)throw new TypeError("Lines must be set to a number.");_lines=value}},regionAnchorY:{enumerable:!0,get:function(){return _regionAnchorY},set:function(value){if(!isValidPercentValue(value))throw new Error("RegionAnchorX must be between 0 and 100.");_regionAnchorY=value}},regionAnchorX:{enumerable:!0,get:function(){return _regionAnchorX},set:function(value){if(!isValidPercentValue(value))throw new Error("RegionAnchorY must be between 0 and 100.");_regionAnchorX=value}},viewportAnchorY:{enumerable:!0,get:function(){return _viewportAnchorY},set:function(value){if(!isValidPercentValue(value))throw new Error("ViewportAnchorY must be between 0 and 100.");_viewportAnchorY=value}},viewportAnchorX:{enumerable:!0,get:function(){return _viewportAnchorX},set:function(value){if(!isValidPercentValue(value))throw new Error("ViewportAnchorX must be between 0 and 100.");_viewportAnchorX=value}},scroll:{enumerable:!0,get:function(){return _scroll},set:function(value){var setting=function(value){return"string"==typeof value&&!!scrollSetting[value.toLowerCase()]&&value.toLowerCase()}(value);!1===setting?console.warn("Scroll: an invalid or illegal string was specified."):_scroll=setting}}})},browserIndex=createCommonjsModule((function(module){var vttjs=module.exports={WebVTT:vtt,VTTCue:vttcue,VTTRegion:vttregion};window_1.vttjs=vttjs,window_1.WebVTT=vttjs.WebVTT;var cueShim=vttjs.VTTCue,regionShim=vttjs.VTTRegion,nativeVTTCue=window_1.VTTCue,nativeVTTRegion=window_1.VTTRegion;vttjs.shim=function(){window_1.VTTCue=cueShim,window_1.VTTRegion=regionShim},vttjs.restore=function(){window_1.VTTCue=nativeVTTCue,window_1.VTTRegion=nativeVTTRegion},window_1.VTTCue||vttjs.shim()}));browserIndex.WebVTT,browserIndex.VTTCue,browserIndex.VTTRegion;class Tech extends Component$1{constructor(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},ready=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};options.reportTouchActivity=!1,super(null,options,ready),this.onDurationChange_=e=>this.onDurationChange(e),this.trackProgress_=e=>this.trackProgress(e),this.trackCurrentTime_=e=>this.trackCurrentTime(e),this.stopTrackingCurrentTime_=e=>this.stopTrackingCurrentTime(e),this.disposeSourceHandler_=e=>this.disposeSourceHandler(e),this.queuedHanders_=new Set,this.hasStarted_=!1,this.on("playing",(function(){this.hasStarted_=!0})),this.on("loadstart",(function(){this.hasStarted_=!1})),ALL.names.forEach((name=>{const props=ALL[name];options&&options[props.getterName]&&(this[props.privateName]=options[props.getterName])})),this.featuresProgressEvents||this.manualProgressOn(),this.featuresTimeupdateEvents||this.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach((track=>{!1===options["native".concat(track,"Tracks")]&&(this["featuresNative".concat(track,"Tracks")]=!1)})),!1===options.nativeCaptions||!1===options.nativeTextTracks?this.featuresNativeTextTracks=!1:!0!==options.nativeCaptions&&!0!==options.nativeTextTracks||(this.featuresNativeTextTracks=!0),this.featuresNativeTextTracks||this.emulateTextTracks(),this.preloadTextTracks=!1!==options.preloadTextTracks,this.autoRemoteTextTracks_=new ALL.text.ListClass,this.initTrackListeners(),options.nativeControlsForTouch||this.emitTapEvents(),this.constructor&&(this.name_=this.constructor.name||"Unknown Tech")}triggerSourceset(src){this.isReady_||this.one("ready",(()=>this.setTimeout((()=>this.triggerSourceset(src)),1))),this.trigger({src:src,type:"sourceset"})}manualProgressOn(){this.on("durationchange",this.onDurationChange_),this.manualProgress=!0,this.one("ready",this.trackProgress_)}manualProgressOff(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange_)}trackProgress(event){this.stopTrackingProgress(),this.progressInterval=this.setInterval(bind_(this,(function(){const numBufferedPercent=this.bufferedPercent();this.bufferedPercent_!==numBufferedPercent&&this.trigger("progress"),this.bufferedPercent_=numBufferedPercent,1===numBufferedPercent&&this.stopTrackingProgress()})),500)}onDurationChange(event){this.duration_=this.duration()}buffered(){return createTimeRanges$1(0,0)}bufferedPercent(){return bufferedPercent(this.buffered(),this.duration_)}stopTrackingProgress(){this.clearInterval(this.progressInterval)}manualTimeUpdatesOn(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime_),this.on("pause",this.stopTrackingCurrentTime_)}manualTimeUpdatesOff(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime_),this.off("pause",this.stopTrackingCurrentTime_)}trackCurrentTime(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval((function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}),250)}stopTrackingCurrentTime(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}dispose(){this.clearTracks(NORMAL.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),super.dispose()}clearTracks(types){(types=[].concat(types)).forEach((type=>{const list=this["".concat(type,"Tracks")]()||[];let i=list.length;for(;i--;){const track=list[i];"text"===type&&this.removeRemoteTextTrack(track),list.removeTrack(track)}}))}cleanupAutoTextTracks(){const list=this.autoRemoteTextTracks_||[];let i=list.length;for(;i--;){const track=list[i];this.removeRemoteTextTrack(track)}}reset(){}crossOrigin(){}setCrossOrigin(){}error(err){return void 0!==err&&(this.error_=new MediaError(err),this.trigger("error")),this.error_}played(){return this.hasStarted_?createTimeRanges$1(0,0):createTimeRanges$1()}play(){}setScrubbing(_isScrubbing){}scrubbing(){}setCurrentTime(_seconds){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})}initTrackListeners(){NORMAL.names.forEach((name=>{const props=NORMAL[name],trackListChanges=()=>{this.trigger("".concat(name,"trackchange"))},tracks=this[props.getterName]();tracks.addEventListener("removetrack",trackListChanges),tracks.addEventListener("addtrack",trackListChanges),this.on("dispose",(()=>{tracks.removeEventListener("removetrack",trackListChanges),tracks.removeEventListener("addtrack",trackListChanges)}))}))}addWebVttScript_(){if(!window.WebVTT)if(document.body.contains(this.el())){if(!this.options_["vtt.js"]&&isPlain(browserIndex)&&Object.keys(browserIndex).length>0)return void this.trigger("vttjsloaded");const script=document.createElement("script");script.src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",script.onload=()=>{this.trigger("vttjsloaded")},script.onerror=()=>{this.trigger("vttjserror")},this.on("dispose",(()=>{script.onload=null,script.onerror=null})),window.WebVTT=!0,this.el().parentNode.appendChild(script)}else this.ready(this.addWebVttScript_)}emulateTextTracks(){const tracks=this.textTracks(),remoteTracks=this.remoteTextTracks(),handleAddTrack=e=>tracks.addTrack(e.track),handleRemoveTrack=e=>tracks.removeTrack(e.track);remoteTracks.on("addtrack",handleAddTrack),remoteTracks.on("removetrack",handleRemoveTrack),this.addWebVttScript_();const updateDisplay=()=>this.trigger("texttrackchange"),textTracksChanges=()=>{updateDisplay();for(let i=0;i4&&void 0!==arguments[4]?arguments[4]:{};const tracks=self.textTracks();options.kind=kind,label&&(options.label=label),language&&(options.language=language),options.tech=self;const track=new ALL.text.TrackClass(options);return tracks.addTrack(track),track}(this,kind,label,language)}createRemoteTextTrack(options){const track=merge$2(options,{tech:this});return new REMOTE.remoteTextEl.TrackClass(track)}addRemoteTextTrack(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},manualCleanup=arguments.length>1?arguments[1]:void 0;const htmlTrackElement=this.createRemoteTextTrack(options);return"boolean"!=typeof manualCleanup&&(manualCleanup=!1),this.remoteTextTrackEls().addTrackElement_(htmlTrackElement),this.remoteTextTracks().addTrack(htmlTrackElement.track),!1===manualCleanup&&this.ready((()=>this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track))),htmlTrackElement}removeRemoteTextTrack(track){const trackElement=this.remoteTextTrackEls().getTrackElementByTrack_(track);this.remoteTextTrackEls().removeTrackElement_(trackElement),this.remoteTextTracks().removeTrack(track),this.autoRemoteTextTracks_.removeTrack(track)}getVideoPlaybackQuality(){return{}}requestPictureInPicture(){return Promise.reject()}disablePictureInPicture(){return!0}setDisablePictureInPicture(){}requestVideoFrameCallback(cb){const id=newGUID();return!this.isReady_||this.paused()?(this.queuedHanders_.add(id),this.one("playing",(()=>{this.queuedHanders_.has(id)&&(this.queuedHanders_.delete(id),cb())}))):this.requestNamedAnimationFrame(id,cb),id}cancelVideoFrameCallback(id){this.queuedHanders_.has(id)?this.queuedHanders_.delete(id):this.cancelNamedAnimationFrame(id)}setPoster(){}playsinline(){}setPlaysinline(){}overrideNativeAudioTracks(override){}overrideNativeVideoTracks(override){}canPlayType(_type){return""}static canPlayType(_type){return""}static canPlaySource(srcObj,options){return Tech.canPlayType(srcObj.type)}static isTech(component){return component.prototype instanceof Tech||component instanceof Tech||component===Tech}static registerTech(name,tech){if(Tech.techs_||(Tech.techs_={}),!Tech.isTech(tech))throw new Error("Tech ".concat(name," must be a Tech"));if(!Tech.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!Tech.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return name=toTitleCase$1(name),Tech.techs_[name]=tech,Tech.techs_[toLowerCase(name)]=tech,"Tech"!==name&&Tech.defaultTechOrder_.push(name),tech}static getTech(name){if(name)return Tech.techs_&&Tech.techs_[name]?Tech.techs_[name]:(name=toTitleCase$1(name),window&&window.videojs&&window.videojs[name]?(log$1.warn("The ".concat(name," tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)")),window.videojs[name]):void 0)}}ALL.names.forEach((function(name){const props=ALL[name];Tech.prototype[props.getterName]=function(){return this[props.privateName]=this[props.privateName]||new props.ListClass,this[props.privateName]}})),Tech.prototype.featuresVolumeControl=!0,Tech.prototype.featuresMuteControl=!0,Tech.prototype.featuresFullscreenResize=!1,Tech.prototype.featuresPlaybackRate=!1,Tech.prototype.featuresProgressEvents=!1,Tech.prototype.featuresSourceset=!1,Tech.prototype.featuresTimeupdateEvents=!1,Tech.prototype.featuresNativeTextTracks=!1,Tech.prototype.featuresVideoFrameCallback=!1,Tech.withSourceHandlers=function(_Tech){_Tech.registerSourceHandler=function(handler,index){let handlers=_Tech.sourceHandlers;handlers||(handlers=_Tech.sourceHandlers=[]),void 0===index&&(index=handlers.length),handlers.splice(index,0,handler)},_Tech.canPlayType=function(type){const handlers=_Tech.sourceHandlers||[];let can;for(let i=0;isetSourceHelper(src,middlewares[src.type],next,player)),1)}function mediate(middleware,tech,method){let arg=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;const callMethod="call"+toTitleCase$1(method),middlewareValue=middleware.reduce(middlewareIterator(callMethod),arg),terminated=middlewareValue===TERMINATOR,returnValue=terminated?null:tech[method](middlewareValue);return executeRight(middleware,method,returnValue,terminated),returnValue}const allowedGetters={buffered:1,currentTime:1,duration:1,muted:1,played:1,paused:1,seekable:1,volume:1,ended:1},allowedSetters={setCurrentTime:1,setMuted:1,setVolume:1},allowedMediators={play:1,pause:1};function middlewareIterator(method){return(value,mw)=>value===TERMINATOR?TERMINATOR:mw[method]?mw[method](value):value}function executeRight(mws,method,value,terminated){for(let i=mws.length-1;i>=0;i--){const mw=mws[i];mw[method]&&mw[method](terminated,value)}}function getOrCreateFactory(player,mwFactory){const mws=middlewareInstances[player.id()];let mw=null;if(null==mws)return mw=mwFactory(player),middlewareInstances[player.id()]=[[mwFactory,mw]],mw;for(let i=0;i0&&void 0!==arguments[0]?arguments[0]:{},middleware=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],next=arguments.length>2?arguments[2]:void 0,player=arguments.length>3?arguments[3]:void 0,acc=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],lastRun=arguments.length>5&&void 0!==arguments[5]&&arguments[5];const[mwFactory,...mwrest]=middleware;if("string"==typeof mwFactory)setSourceHelper(src,middlewares[mwFactory],next,player,acc,lastRun);else if(mwFactory){const mw=getOrCreateFactory(player,mwFactory);if(!mw.setSource)return acc.push(mw),setSourceHelper(src,mwrest,next,player,acc,lastRun);mw.setSource(Object.assign({},src),(function(err,_src){if(err)return setSourceHelper(src,mwrest,next,player,acc,lastRun);acc.push(mw),setSourceHelper(_src,src.type===_src.type?mwrest:middlewares[_src.type],next,player,acc,lastRun)}))}else mwrest.length?setSourceHelper(src,mwrest,next,player,acc,lastRun):lastRun?next(src,acc):setSourceHelper(src,middlewares["*"],next,player,acc,!0)}const MimetypesKind={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",caf:"audio/x-caf",flac:"audio/flac",oga:"audio/ogg",wav:"audio/wav",m3u8:"application/x-mpegURL",mpd:"application/dash+xml",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"},getMimetype=function(){let src=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const ext=getFileExtension(src),mimetype=MimetypesKind[ext.toLowerCase()];return mimetype||""},filterSource=function(src){if(Array.isArray(src)){let newsrc=[];src.forEach((function(srcobj){srcobj=filterSource(srcobj),Array.isArray(srcobj)?newsrc=newsrc.concat(srcobj):isObject$1(srcobj)&&newsrc.push(srcobj)})),src=newsrc}else src="string"==typeof src&&src.trim()?[fixSource({src:src})]:isObject$1(src)&&"string"==typeof src.src&&src.src&&src.src.trim()?[fixSource(src)]:[];return src};function fixSource(src){if(!src.type){const mimetype=getMimetype(src.src);mimetype&&(src.type=mimetype)}return src}Component$1.registerComponent("MediaLoader",class extends Component$1{constructor(player,options,ready){if(super(player,merge$2({createEl:!1},options),ready),options.playerOptions.sources&&0!==options.playerOptions.sources.length)player.src(options.playerOptions.sources);else for(let i=0,j=options.playerOptions.techOrder;ithis.handleMouseOver(e),this.handleMouseOut_=e=>this.handleMouseOut(e),this.handleClick_=e=>this.handleClick(e),this.handleKeyDown_=e=>this.handleKeyDown(e),this.emitTapEvents(),this.enable()}createEl(){let tag=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};props=Object.assign({className:this.buildCSSClass(),tabIndex:0},props),"button"===tag&&log$1.error("Creating a ClickableComponent with an HTML element of ".concat(tag," is not supported; use a Button instead.")),attributes=Object.assign({role:"button"},attributes),this.tabIndex_=props.tabIndex;const el=createEl(tag,props,attributes);return this.player_.options_.experimentalSvgIcons||el.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(el),el}dispose(){this.controlTextEl_=null,super.dispose()}createControlTextEl(el){return this.controlTextEl_=createEl("span",{className:"vjs-control-text"},{"aria-live":"polite"}),el&&el.appendChild(this.controlTextEl_),this.controlText(this.controlText_,el),this.controlTextEl_}controlText(text){let el=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.el();if(void 0===text)return this.controlText_||"Need Text";const localizedText=this.localize(text);this.controlText_=text,textContent(this.controlTextEl_,localizedText),this.nonIconControl||this.player_.options_.noUITitleAttributes||el.setAttribute("title",localizedText)}buildCSSClass(){return"vjs-control vjs-button ".concat(super.buildCSSClass())}enable(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),void 0!==this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick_),this.on("keydown",this.handleKeyDown_))}disable(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),void 0!==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_)}handleLanguagechange(){this.controlText(this.controlText_)}handleClick(event){this.options_.clickHandler&&this.options_.clickHandler.call(this,arguments)}handleKeyDown(event){keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter")?(event.preventDefault(),event.stopPropagation(),this.trigger("click")):super.handleKeyDown(event)}}Component$1.registerComponent("ClickableComponent",ClickableComponent);class PosterImage extends ClickableComponent{constructor(player,options){super(player,options),this.update(),this.update_=e=>this.update(e),player.on("posterchange",this.update_)}dispose(){this.player().off("posterchange",this.update_),super.dispose()}createEl(){return createEl("div",{className:"vjs-poster"})}crossOrigin(value){if(void 0===value)return this.$("img")?this.$("img").crossOrigin:this.player_.tech_&&this.player_.tech_.isReady_?this.player_.crossOrigin():this.player_.options_.crossOrigin||this.player_.options_.crossorigin||null;null===value||"anonymous"===value||"use-credentials"===value?this.$("img")&&(this.$("img").crossOrigin=value):this.player_.log.warn('crossOrigin must be null, "anonymous" or "use-credentials", given "'.concat(value,'"'))}update(event){const url=this.player().poster();this.setSrc(url),url?this.show():this.hide()}setSrc(url){url?(this.$("img")||this.el_.appendChild(createEl("picture",{className:"vjs-poster",tabIndex:-1},{},createEl("img",{loading:"lazy",crossOrigin:this.crossOrigin()},{alt:""}))),this.$("img").src=url):this.el_.textContent=""}handleClick(event){this.player_.controls()&&(this.player_.tech(!0)&&this.player_.tech(!0).focus(),this.player_.paused()?silencePromise(this.player_.play()):this.player_.pause())}}PosterImage.prototype.crossorigin=PosterImage.prototype.crossOrigin,Component$1.registerComponent("PosterImage",PosterImage);const fontMap={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 constructColor(color,opacity){let hex;if(4===color.length)hex=color[1]+color[1]+color[2]+color[2]+color[3]+color[3];else{if(7!==color.length)throw new Error("Invalid color code provided, "+color+"; must be formatted as e.g. #f0e or #f604e2.");hex=color.slice(1)}return"rgba("+parseInt(hex.slice(0,2),16)+","+parseInt(hex.slice(2,4),16)+","+parseInt(hex.slice(4,6),16)+","+opacity+")"}function tryUpdateStyle(el,style,rule){try{el.style[style]=rule}catch(e){return}}function getCSSPositionValue(position){return position?"".concat(position,"px"):""}Component$1.registerComponent("TextTrackDisplay",class extends Component$1{constructor(player,options,ready){super(player,options,ready);const updateDisplayHandler=e=>{this.updateDisplayOverlay(),this.updateDisplay(e)};player.on("loadstart",(e=>this.toggleDisplay(e))),player.on("texttrackchange",(e=>this.updateDisplay(e))),player.on("loadedmetadata",(e=>{this.updateDisplayOverlay(),this.preselectTrack(e)})),player.ready(bind_(this,(function(){if(player.tech_&&player.tech_.featuresNativeTextTracks)return void this.hide();player.on("fullscreenchange",updateDisplayHandler),player.on("playerresize",updateDisplayHandler);const screenOrientation=window.screen.orientation||window,changeOrientationEvent=window.screen.orientation?"change":"orientationchange";screenOrientation.addEventListener(changeOrientationEvent,updateDisplayHandler),player.on("dispose",(()=>screenOrientation.removeEventListener(changeOrientationEvent,updateDisplayHandler)));const tracks=this.options_.playerOptions.tracks||[];for(let i=0;i.1&&(playerAspectRatio>videoAspectRatio?insetInlineMatch=Math.round((playerWidth-playerHeight*videoAspectRatio)/2):insetBlockMatch=Math.round((playerHeight-playerWidth/videoAspectRatio)/2)),tryUpdateStyle(this.el_,"insetInline",getCSSPositionValue(insetInlineMatch)),tryUpdateStyle(this.el_,"insetBlock",getCSSPositionValue(insetBlockMatch))}updateDisplayState(track){const overrides=this.player_.textTrackSettings.getValues(),cues=track.activeCues;let i=cues.length;for(;i--;){const cue=cues[i];if(!cue)continue;const cueDiv=cue.displayState;if(overrides.color&&(cueDiv.firstChild.style.color=overrides.color),overrides.textOpacity&&tryUpdateStyle(cueDiv.firstChild,"color",constructColor(overrides.color||"#fff",overrides.textOpacity)),overrides.backgroundColor&&(cueDiv.firstChild.style.backgroundColor=overrides.backgroundColor),overrides.backgroundOpacity&&tryUpdateStyle(cueDiv.firstChild,"backgroundColor",constructColor(overrides.backgroundColor||"#000",overrides.backgroundOpacity)),overrides.windowColor&&(overrides.windowOpacity?tryUpdateStyle(cueDiv,"backgroundColor",constructColor(overrides.windowColor,overrides.windowOpacity)):cueDiv.style.backgroundColor=overrides.windowColor),overrides.edgeStyle&&("dropshadow"===overrides.edgeStyle?cueDiv.firstChild.style.textShadow="2px 2px 3px ".concat("#222",", 2px 2px 4px ").concat("#222",", 2px 2px 5px ").concat("#222"):"raised"===overrides.edgeStyle?cueDiv.firstChild.style.textShadow="1px 1px ".concat("#222",", 2px 2px ").concat("#222",", 3px 3px ").concat("#222"):"depressed"===overrides.edgeStyle?cueDiv.firstChild.style.textShadow="1px 1px ".concat("#ccc",", 0 1px ").concat("#ccc",", -1px -1px ").concat("#222",", 0 -1px ").concat("#222"):"uniform"===overrides.edgeStyle&&(cueDiv.firstChild.style.textShadow="0 0 4px ".concat("#222",", 0 0 4px ").concat("#222",", 0 0 4px ").concat("#222",", 0 0 4px ").concat("#222"))),overrides.fontPercent&&1!==overrides.fontPercent){const fontSize=window.parseFloat(cueDiv.style.fontSize);cueDiv.style.fontSize=fontSize*overrides.fontPercent+"px",cueDiv.style.height="auto",cueDiv.style.top="auto"}overrides.fontFamily&&"default"!==overrides.fontFamily&&("small-caps"===overrides.fontFamily?cueDiv.firstChild.style.fontVariant="small-caps":cueDiv.firstChild.style.fontFamily=fontMap[overrides.fontFamily])}}updateForTrack(tracks){if(Array.isArray(tracks)||(tracks=[tracks]),"function"!=typeof window.WebVTT||tracks.every((track=>!track.activeCues)))return;const cues=[];for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};tag="button",props=Object.assign({className:this.buildCSSClass()},props),attributes=Object.assign({type:"button"},attributes);const el=createEl("button",props,attributes);return this.player_.options_.experimentalSvgIcons||el.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(el),el}addChild(child){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const className=this.constructor.name;return log$1.warn("Adding an actionable (user controllable) child to a Button (".concat(className,") is not supported; use a ClickableComponent instead.")),Component$1.prototype.addChild.call(this,child,options)}enable(){super.enable(),this.el_.removeAttribute("disabled")}disable(){super.disable(),this.el_.setAttribute("disabled","disabled")}handleKeyDown(event){keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter")?event.stopPropagation():super.handleKeyDown(event)}}Component$1.registerComponent("Button",Button);class BigPlayButton extends Button{constructor(player,options){super(player,options),this.mouseused_=!1,this.setIcon("play"),this.on("mousedown",(e=>this.handleMouseDown(e)))}buildCSSClass(){return"vjs-big-play-button"}handleClick(event){const playPromise=this.player_.play();if(this.mouseused_&&"clientX"in event&&"clientY"in event)return silencePromise(playPromise),void(this.player_.tech(!0)&&this.player_.tech(!0).focus());const cb=this.player_.getChild("controlBar"),playToggle=cb&&cb.getChild("playToggle");if(!playToggle)return void this.player_.tech(!0).focus();const playFocus=()=>playToggle.focus();isPromise(playPromise)?playPromise.then(playFocus,(()=>{})):this.setTimeout(playFocus,1)}handleKeyDown(event){this.mouseused_=!1,super.handleKeyDown(event)}handleMouseDown(event){this.mouseused_=!0}}BigPlayButton.prototype.controlText_="Play Video",Component$1.registerComponent("BigPlayButton",BigPlayButton);Component$1.registerComponent("CloseButton",class extends Button{constructor(player,options){super(player,options),this.setIcon("cancel"),this.controlText(options&&options.controlText||this.localize("Close"))}buildCSSClass(){return"vjs-close-button ".concat(super.buildCSSClass())}handleClick(event){this.trigger({type:"close",bubbles:!1})}handleKeyDown(event){keycode.isEventKey(event,"Esc")?(event.preventDefault(),event.stopPropagation(),this.trigger("click")):super.handleKeyDown(event)}});class PlayToggle extends Button{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(player,options),options.replay=void 0===options.replay||options.replay,this.setIcon("play"),this.on(player,"play",(e=>this.handlePlay(e))),this.on(player,"pause",(e=>this.handlePause(e))),options.replay&&this.on(player,"ended",(e=>this.handleEnded(e)))}buildCSSClass(){return"vjs-play-control ".concat(super.buildCSSClass())}handleClick(event){this.player_.paused()?silencePromise(this.player_.play()):this.player_.pause()}handleSeeked(event){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(event):this.handlePlay(event)}handlePlay(event){this.removeClass("vjs-ended","vjs-paused"),this.addClass("vjs-playing"),this.setIcon("pause"),this.controlText("Pause")}handlePause(event){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.setIcon("play"),this.controlText("Play")}handleEnded(event){this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.setIcon("replay"),this.controlText("Replay"),this.one(this.player_,"seeked",(e=>this.handleSeeked(e)))}}PlayToggle.prototype.controlText_="Play",Component$1.registerComponent("PlayToggle",PlayToggle);class TimeDisplay extends Component$1{constructor(player,options){super(player,options),this.on(player,["timeupdate","ended","seeking"],(e=>this.update(e))),this.updateTextNode_()}createEl(){const className=this.buildCSSClass(),el=super.createEl("div",{className:"".concat(className," vjs-time-control vjs-control")}),span=createEl("span",{className:"vjs-control-text",textContent:"".concat(this.localize(this.labelText_)," ")},{role:"presentation"});return el.appendChild(span),this.contentEl_=createEl("span",{className:"".concat(className,"-display")},{role:"presentation"}),el.appendChild(this.contentEl_),el}dispose(){this.contentEl_=null,this.textNode_=null,super.dispose()}update(event){(this.player_.options_.enableSmoothSeeking||"seeking"!==event.type)&&this.updateContent(event)}updateTextNode_(){let time=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;time=formatTime(time),this.formattedTime_!==time&&(this.formattedTime_=time,this.requestNamedAnimationFrame("TimeDisplay#updateTextNode_",(()=>{if(!this.contentEl_)return;let oldNode=this.textNode_;oldNode&&this.contentEl_.firstChild!==oldNode&&(oldNode=null,log$1.warn("TimeDisplay#updateTextnode_: Prevented replacement of text node element since it was no longer a child of this node. Appending a new node instead.")),this.textNode_=document.createTextNode(this.formattedTime_),this.textNode_&&(oldNode?this.contentEl_.replaceChild(this.textNode_,oldNode):this.contentEl_.appendChild(this.textNode_))})))}updateContent(event){}}TimeDisplay.prototype.labelText_="Time",TimeDisplay.prototype.controlText_="Time",Component$1.registerComponent("TimeDisplay",TimeDisplay);class CurrentTimeDisplay extends TimeDisplay{buildCSSClass(){return"vjs-current-time"}updateContent(event){let time;time=this.player_.ended()?this.player_.duration():this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),this.updateTextNode_(time)}}CurrentTimeDisplay.prototype.labelText_="Current Time",CurrentTimeDisplay.prototype.controlText_="Current Time",Component$1.registerComponent("CurrentTimeDisplay",CurrentTimeDisplay);class DurationDisplay extends TimeDisplay{constructor(player,options){super(player,options);const updateContent=e=>this.updateContent(e);this.on(player,"durationchange",updateContent),this.on(player,"loadstart",updateContent),this.on(player,"loadedmetadata",updateContent)}buildCSSClass(){return"vjs-duration"}updateContent(event){const duration=this.player_.duration();this.updateTextNode_(duration)}}DurationDisplay.prototype.labelText_="Duration",DurationDisplay.prototype.controlText_="Duration",Component$1.registerComponent("DurationDisplay",DurationDisplay);Component$1.registerComponent("TimeDivider",class extends Component$1{createEl(){const el=super.createEl("div",{className:"vjs-time-control vjs-time-divider"},{"aria-hidden":!0}),div=super.createEl("div"),span=super.createEl("span",{textContent:"/"});return div.appendChild(span),el.appendChild(div),el}});class RemainingTimeDisplay extends TimeDisplay{constructor(player,options){super(player,options),this.on(player,"durationchange",(e=>this.updateContent(e)))}buildCSSClass(){return"vjs-remaining-time"}createEl(){const el=super.createEl();return!1!==this.options_.displayNegative&&el.insertBefore(createEl("span",{},{"aria-hidden":!0},"-"),this.contentEl_),el}updateContent(event){if("number"!=typeof this.player_.duration())return;let time;time=this.player_.ended()?0:this.player_.remainingTimeDisplay?this.player_.remainingTimeDisplay():this.player_.remainingTime(),this.updateTextNode_(time)}}RemainingTimeDisplay.prototype.labelText_="Remaining Time",RemainingTimeDisplay.prototype.controlText_="Remaining Time",Component$1.registerComponent("RemainingTimeDisplay",RemainingTimeDisplay);Component$1.registerComponent("LiveDisplay",class extends Component$1{constructor(player,options){super(player,options),this.updateShowing(),this.on(this.player(),"durationchange",(e=>this.updateShowing(e)))}createEl(){const el=super.createEl("div",{className:"vjs-live-control vjs-control"});return this.contentEl_=createEl("div",{className:"vjs-live-display"},{"aria-live":"off"}),this.contentEl_.appendChild(createEl("span",{className:"vjs-control-text",textContent:"".concat(this.localize("Stream Type")," ")})),this.contentEl_.appendChild(document.createTextNode(this.localize("LIVE"))),el.appendChild(this.contentEl_),el}dispose(){this.contentEl_=null,super.dispose()}updateShowing(event){this.player().duration()===1/0?this.show():this.hide()}});class SeekToLive extends Button{constructor(player,options){super(player,options),this.updateLiveEdgeStatus(),this.player_.liveTracker&&(this.updateLiveEdgeStatusHandler_=e=>this.updateLiveEdgeStatus(e),this.on(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_))}createEl(){const el=super.createEl("button",{className:"vjs-seek-to-live-control vjs-control"});return this.setIcon("circle",el),this.textEl_=createEl("span",{className:"vjs-seek-to-live-text",textContent:this.localize("LIVE")},{"aria-hidden":"true"}),el.appendChild(this.textEl_),el}updateLiveEdgeStatus(){!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"))}handleClick(){this.player_.liveTracker.seekToLiveEdge()}dispose(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_),this.textEl_=null,super.dispose()}}function clamp(number,min,max){return number=Number(number),Math.min(max,Math.max(min,isNaN(number)?min:number))}SeekToLive.prototype.controlText_="Seek to live, currently playing live",Component$1.registerComponent("SeekToLive",SeekToLive);var Num=Object.freeze({__proto__:null,clamp:clamp});class Slider extends Component$1{constructor(player,options){super(player,options),this.handleMouseDown_=e=>this.handleMouseDown(e),this.handleMouseUp_=e=>this.handleMouseUp(e),this.handleKeyDown_=e=>this.handleKeyDown(e),this.handleClick_=e=>this.handleClick(e),this.handleMouseMove_=e=>this.handleMouseMove(e),this.update_=e=>this.update(e),this.bar=this.getChild(this.options_.barName),this.vertical(!!this.options_.vertical),this.enable()}enabled(){return this.enabled_}enable(){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)}disable(){if(!this.enabled())return;const doc=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(doc,"mousemove",this.handleMouseMove_),this.off(doc,"mouseup",this.handleMouseUp_),this.off(doc,"touchmove",this.handleMouseMove_),this.off(doc,"touchend",this.handleMouseUp_),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1}createEl(type){let props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return props.className=props.className+" vjs-slider",props=Object.assign({tabIndex:0},props),attributes=Object.assign({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100},attributes),super.createEl(type,props,attributes)}handleMouseDown(event){const doc=this.bar.el_.ownerDocument;"mousedown"===event.type&&event.preventDefault(),"touchstart"!==event.type||IS_CHROME||event.preventDefault(),blockTextSelection(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(doc,"mousemove",this.handleMouseMove_),this.on(doc,"mouseup",this.handleMouseUp_),this.on(doc,"touchmove",this.handleMouseMove_),this.on(doc,"touchend",this.handleMouseUp_),this.handleMouseMove(event,!0)}handleMouseMove(event){}handleMouseUp(event){const doc=this.bar.el_.ownerDocument;unblockTextSelection(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(doc,"mousemove",this.handleMouseMove_),this.off(doc,"mouseup",this.handleMouseUp_),this.off(doc,"touchmove",this.handleMouseMove_),this.off(doc,"touchend",this.handleMouseUp_),this.update()}update(){if(!this.el_||!this.bar)return;const progress=this.getProgress();return progress===this.progress_||(this.progress_=progress,this.requestNamedAnimationFrame("Slider#update",(()=>{const sizeKey=this.vertical()?"height":"width";this.bar.el().style[sizeKey]=(100*progress).toFixed(2)+"%"}))),progress}getProgress(){return Number(clamp(this.getPercent(),0,1).toFixed(4))}calculateDistance(event){const position=getPointerPosition(this.el_,event);return this.vertical()?position.y:position.x}handleKeyDown(event){keycode.isEventKey(event,"Left")||keycode.isEventKey(event,"Down")?(event.preventDefault(),event.stopPropagation(),this.stepBack()):keycode.isEventKey(event,"Right")||keycode.isEventKey(event,"Up")?(event.preventDefault(),event.stopPropagation(),this.stepForward()):super.handleKeyDown(event)}handleClick(event){event.stopPropagation(),event.preventDefault()}vertical(bool){if(void 0===bool)return this.vertical_||!1;this.vertical_=!!bool,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")}}Component$1.registerComponent("Slider",Slider);const percentify=(time,end)=>clamp(time/end*100,0,100).toFixed(2)+"%";Component$1.registerComponent("LoadProgressBar",class extends Component$1{constructor(player,options){super(player,options),this.partEls_=[],this.on(player,"progress",(e=>this.update(e)))}createEl(){const el=super.createEl("div",{className:"vjs-load-progress"}),wrapper=createEl("span",{className:"vjs-control-text"}),loadedText=createEl("span",{textContent:this.localize("Loaded")}),separator=document.createTextNode(": ");return this.percentageEl_=createEl("span",{className:"vjs-control-text-loaded-percentage",textContent:"0%"}),el.appendChild(wrapper),wrapper.appendChild(loadedText),wrapper.appendChild(separator),wrapper.appendChild(this.percentageEl_),el}dispose(){this.partEls_=null,this.percentageEl_=null,super.dispose()}update(event){this.requestNamedAnimationFrame("LoadProgressBar#update",(()=>{const liveTracker=this.player_.liveTracker,buffered=this.player_.buffered(),duration=liveTracker&&liveTracker.isLive()?liveTracker.seekableEnd():this.player_.duration(),bufferedEnd=this.player_.bufferedEnd(),children=this.partEls_,percent=percentify(bufferedEnd,duration);this.percent_!==percent&&(this.el_.style.width=percent,textContent(this.percentageEl_,percent),this.percent_=percent);for(let i=0;ibuffered.length;i--)this.el_.removeChild(children[i-1]);children.length=buffered.length}))}});Component$1.registerComponent("TimeTooltip",class extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})}update(seekBarRect,seekBarPoint,content){const tooltipRect=findPosition(this.el_),playerRect=getBoundingClientRect(this.player_.el()),seekBarPointPx=seekBarRect.width*seekBarPoint;if(!playerRect||!tooltipRect)return;const spaceLeftOfPoint=seekBarRect.left-playerRect.left+seekBarPointPx,spaceRightOfPoint=seekBarRect.width-seekBarPointPx+(playerRect.right-seekBarRect.right);let pullTooltipBy=tooltipRect.width/2;spaceLeftOfPointtooltipRect.width&&(pullTooltipBy=tooltipRect.width),pullTooltipBy=Math.round(pullTooltipBy),this.el_.style.right="-".concat(pullTooltipBy,"px"),this.write(content)}write(content){textContent(this.el_,content)}updateTime(seekBarRect,seekBarPoint,time,cb){this.requestNamedAnimationFrame("TimeTooltip#updateTime",(()=>{let content;const duration=this.player_.duration();if(this.player_.liveTracker&&this.player_.liveTracker.isLive()){const liveWindow=this.player_.liveTracker.liveWindow(),secondsBehind=liveWindow-seekBarPoint*liveWindow;content=(secondsBehind<1?"":"-")+formatTime(secondsBehind,liveWindow)}else content=formatTime(time,duration);this.update(seekBarRect,seekBarPoint,content),cb&&cb()}))}});class PlayProgressBar extends Component$1{constructor(player,options){super(player,options),this.setIcon("circle"),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})}update(seekBarRect,seekBarPoint){const timeTooltip=this.getChild("timeTooltip");if(!timeTooltip)return;const time=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();timeTooltip.updateTime(seekBarRect,seekBarPoint,time)}}PlayProgressBar.prototype.options_={children:[]},IS_IOS||IS_ANDROID||PlayProgressBar.prototype.options_.children.push("timeTooltip"),Component$1.registerComponent("PlayProgressBar",PlayProgressBar);class MouseTimeDisplay extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-mouse-display"})}update(seekBarRect,seekBarPoint){const time=seekBarPoint*this.player_.duration();this.getChild("timeTooltip").updateTime(seekBarRect,seekBarPoint,time,(()=>{this.el_.style.left="".concat(seekBarRect.width*seekBarPoint,"px")}))}}MouseTimeDisplay.prototype.options_={children:["timeTooltip"]},Component$1.registerComponent("MouseTimeDisplay",MouseTimeDisplay);class SeekBar extends Slider{constructor(player,options){super(player,options),this.setEventHandlers_()}setEventHandlers_(){this.update_=bind_(this,this.update),this.update=throttle(this.update_,30),this.on(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.enableIntervalHandler_=e=>this.enableInterval_(e),this.disableIntervalHandler_=e=>this.disableInterval_(e),this.on(this.player_,["playing"],this.enableIntervalHandler_),this.on(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.on(document,"visibilitychange",this.toggleVisibility_)}toggleVisibility_(e){"hidden"===document.visibilityState?(this.cancelNamedAnimationFrame("SeekBar#update"),this.cancelNamedAnimationFrame("Slider#update"),this.disableInterval_(e)):(this.player_.ended()||this.player_.paused()||this.enableInterval_(),this.update())}enableInterval_(){this.updateInterval||(this.updateInterval=this.setInterval(this.update,30))}disableInterval_(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&e&&"ended"!==e.type||this.updateInterval&&(this.clearInterval(this.updateInterval),this.updateInterval=null)}createEl(){return super.createEl("div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})}update(event){if("hidden"===document.visibilityState)return;const percent=super.update();return this.requestNamedAnimationFrame("SeekBar#update",(()=>{const currentTime=this.player_.ended()?this.player_.duration():this.getCurrentTime_(),liveTracker=this.player_.liveTracker;let duration=this.player_.duration();liveTracker&&liveTracker.isLive()&&(duration=this.player_.liveTracker.liveCurrentTime()),this.percent_!==percent&&(this.el_.setAttribute("aria-valuenow",(100*percent).toFixed(2)),this.percent_=percent),this.currentTime_===currentTime&&this.duration_===duration||(this.el_.setAttribute("aria-valuetext",this.localize("progress bar timing: currentTime={1} duration={2}",[formatTime(currentTime,duration),formatTime(duration,duration)],"{1} of {2}")),this.currentTime_=currentTime,this.duration_=duration),this.bar&&this.bar.update(getBoundingClientRect(this.el()),this.getProgress())})),percent}userSeek_(ct){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&this.player_.liveTracker.nextSeekedFromUser(),this.player_.currentTime(ct)}getCurrentTime_(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()}getPercent(){const currentTime=this.getCurrentTime_();let percent;const liveTracker=this.player_.liveTracker;return liveTracker&&liveTracker.isLive()?(percent=(currentTime-liveTracker.seekableStart())/liveTracker.liveWindow(),liveTracker.atLiveEdge()&&(percent=1)):percent=currentTime/this.player_.duration(),percent}handleMouseDown(event){isSingleLeftClick(event)&&(event.stopPropagation(),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),super.handleMouseDown(event))}handleMouseMove(event){let newTime,mouseDown=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!isSingleLeftClick(event)||isNaN(this.player_.duration()))return;mouseDown||this.player_.scrubbing()||this.player_.scrubbing(!0);const distance=this.calculateDistance(event),liveTracker=this.player_.liveTracker;if(liveTracker&&liveTracker.isLive()){if(distance>=.99)return void liveTracker.seekToLiveEdge();const seekableStart=liveTracker.seekableStart(),seekableEnd=liveTracker.liveCurrentTime();if(newTime=seekableStart+distance*liveTracker.liveWindow(),newTime>=seekableEnd&&(newTime=seekableEnd),newTime<=seekableStart&&(newTime=seekableStart+.1),newTime===1/0)return}else newTime=distance*this.player_.duration(),newTime===this.player_.duration()&&(newTime-=.1);this.userSeek_(newTime),this.player_.options_.enableSmoothSeeking&&this.update()}enable(){super.enable();const mouseTimeDisplay=this.getChild("mouseTimeDisplay");mouseTimeDisplay&&mouseTimeDisplay.show()}disable(){super.disable();const mouseTimeDisplay=this.getChild("mouseTimeDisplay");mouseTimeDisplay&&mouseTimeDisplay.hide()}handleMouseUp(event){super.handleMouseUp(event),event&&event.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying?silencePromise(this.player_.play()):this.update_()}stepForward(){this.userSeek_(this.player_.currentTime()+5)}stepBack(){this.userSeek_(this.player_.currentTime()-5)}handleAction(event){this.player_.paused()?this.player_.play():this.player_.pause()}handleKeyDown(event){const liveTracker=this.player_.liveTracker;if(keycode.isEventKey(event,"Space")||keycode.isEventKey(event,"Enter"))event.preventDefault(),event.stopPropagation(),this.handleAction(event);else if(keycode.isEventKey(event,"Home"))event.preventDefault(),event.stopPropagation(),this.userSeek_(0);else if(keycode.isEventKey(event,"End"))event.preventDefault(),event.stopPropagation(),liveTracker&&liveTracker.isLive()?this.userSeek_(liveTracker.liveCurrentTime()):this.userSeek_(this.player_.duration());else if(/^[0-9]$/.test(keycode(event))){event.preventDefault(),event.stopPropagation();const gotoFraction=10*(keycode.codes[keycode(event)]-keycode.codes[0])/100;liveTracker&&liveTracker.isLive()?this.userSeek_(liveTracker.seekableStart()+liveTracker.liveWindow()*gotoFraction):this.userSeek_(this.player_.duration()*gotoFraction)}else keycode.isEventKey(event,"PgDn")?(event.preventDefault(),event.stopPropagation(),this.userSeek_(this.player_.currentTime()-60)):keycode.isEventKey(event,"PgUp")?(event.preventDefault(),event.stopPropagation(),this.userSeek_(this.player_.currentTime()+60)):super.handleKeyDown(event)}dispose(){this.disableInterval_(),this.off(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.update),this.off(this.player_,["playing"],this.enableIntervalHandler_),this.off(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.off(document,"visibilitychange",this.toggleVisibility_),super.dispose()}}SeekBar.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},IS_IOS||IS_ANDROID||SeekBar.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),Component$1.registerComponent("SeekBar",SeekBar);class ProgressControl extends Component$1{constructor(player,options){super(player,options),this.handleMouseMove=throttle(bind_(this,this.handleMouseMove),30),this.throttledHandleMouseSeek=throttle(bind_(this,this.handleMouseSeek),30),this.handleMouseUpHandler_=e=>this.handleMouseUp(e),this.handleMouseDownHandler_=e=>this.handleMouseDown(e),this.enable()}createEl(){return super.createEl("div",{className:"vjs-progress-control vjs-control"})}handleMouseMove(event){const seekBar=this.getChild("seekBar");if(!seekBar)return;const playProgressBar=seekBar.getChild("playProgressBar"),mouseTimeDisplay=seekBar.getChild("mouseTimeDisplay");if(!playProgressBar&&!mouseTimeDisplay)return;const seekBarEl=seekBar.el(),seekBarRect=findPosition(seekBarEl);let seekBarPoint=getPointerPosition(seekBarEl,event).x;seekBarPoint=clamp(seekBarPoint,0,1),mouseTimeDisplay&&mouseTimeDisplay.update(seekBarRect,seekBarPoint),playProgressBar&&playProgressBar.update(seekBarRect,seekBar.getProgress())}handleMouseSeek(event){const seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseMove(event)}enabled(){return this.enabled_}disable(){if(this.children().forEach((child=>child.disable&&child.disable())),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDownHandler_),this.off(this.el_,"mousemove",this.handleMouseMove),this.removeListenersAddedOnMousedownAndTouchstart(),this.addClass("disabled"),this.enabled_=!1,this.player_.scrubbing())){const seekBar=this.getChild("seekBar");this.player_.scrubbing(!1),seekBar.videoWasPlaying&&silencePromise(this.player_.play())}}enable(){this.children().forEach((child=>child.enable&&child.enable())),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDownHandler_),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)}removeListenersAddedOnMousedownAndTouchstart(){const doc=this.el_.ownerDocument;this.off(doc,"mousemove",this.throttledHandleMouseSeek),this.off(doc,"touchmove",this.throttledHandleMouseSeek),this.off(doc,"mouseup",this.handleMouseUpHandler_),this.off(doc,"touchend",this.handleMouseUpHandler_)}handleMouseDown(event){const doc=this.el_.ownerDocument,seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseDown(event),this.on(doc,"mousemove",this.throttledHandleMouseSeek),this.on(doc,"touchmove",this.throttledHandleMouseSeek),this.on(doc,"mouseup",this.handleMouseUpHandler_),this.on(doc,"touchend",this.handleMouseUpHandler_)}handleMouseUp(event){const seekBar=this.getChild("seekBar");seekBar&&seekBar.handleMouseUp(event),this.removeListenersAddedOnMousedownAndTouchstart()}}ProgressControl.prototype.options_={children:["seekBar"]},Component$1.registerComponent("ProgressControl",ProgressControl);class PictureInPictureToggle extends Button{constructor(player,options){super(player,options),this.setIcon("picture-in-picture-enter"),this.on(player,["enterpictureinpicture","leavepictureinpicture"],(e=>this.handlePictureInPictureChange(e))),this.on(player,["disablepictureinpicturechanged","loadedmetadata"],(e=>this.handlePictureInPictureEnabledChange(e))),this.on(player,["loadedmetadata","audioonlymodechange","audiopostermodechange"],(()=>this.handlePictureInPictureAudioModeChange())),this.disable()}buildCSSClass(){return"vjs-picture-in-picture-control vjs-hidden ".concat(super.buildCSSClass())}handlePictureInPictureAudioModeChange(){"audio"===this.player_.currentType().substring(0,5)||this.player_.audioPosterMode()||this.player_.audioOnlyMode()?(this.player_.isInPictureInPicture()&&this.player_.exitPictureInPicture(),this.hide()):this.show()}handlePictureInPictureEnabledChange(){document.pictureInPictureEnabled&&!1===this.player_.disablePictureInPicture()||this.player_.options_.enableDocumentPictureInPicture&&"documentPictureInPicture"in window?this.enable():this.disable()}handlePictureInPictureChange(event){this.player_.isInPictureInPicture()?(this.setIcon("picture-in-picture-exit"),this.controlText("Exit Picture-in-Picture")):(this.setIcon("picture-in-picture-enter"),this.controlText("Picture-in-Picture")),this.handlePictureInPictureEnabledChange()}handleClick(event){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()}show(){"function"==typeof document.exitPictureInPicture&&super.show()}}PictureInPictureToggle.prototype.controlText_="Picture-in-Picture",Component$1.registerComponent("PictureInPictureToggle",PictureInPictureToggle);class FullscreenToggle extends Button{constructor(player,options){super(player,options),this.setIcon("fullscreen-enter"),this.on(player,"fullscreenchange",(e=>this.handleFullscreenChange(e))),!1===document[player.fsApi_.fullscreenEnabled]&&this.disable()}buildCSSClass(){return"vjs-fullscreen-control ".concat(super.buildCSSClass())}handleFullscreenChange(event){this.player_.isFullscreen()?(this.controlText("Exit Fullscreen"),this.setIcon("fullscreen-exit")):(this.controlText("Fullscreen"),this.setIcon("fullscreen-enter"))}handleClick(event){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()}}FullscreenToggle.prototype.controlText_="Fullscreen",Component$1.registerComponent("FullscreenToggle",FullscreenToggle);Component$1.registerComponent("VolumeLevel",class extends Component$1{createEl(){const el=super.createEl("div",{className:"vjs-volume-level"});return this.setIcon("circle",el),el.appendChild(super.createEl("span",{className:"vjs-control-text"})),el}});Component$1.registerComponent("VolumeLevelTooltip",class extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-volume-tooltip"},{"aria-hidden":"true"})}update(rangeBarRect,rangeBarPoint,vertical,content){if(!vertical){const tooltipRect=getBoundingClientRect(this.el_),playerRect=getBoundingClientRect(this.player_.el()),volumeBarPointPx=rangeBarRect.width*rangeBarPoint;if(!playerRect||!tooltipRect)return;const spaceLeftOfPoint=rangeBarRect.left-playerRect.left+volumeBarPointPx,spaceRightOfPoint=rangeBarRect.width-volumeBarPointPx+(playerRect.right-rangeBarRect.right);let pullTooltipBy=tooltipRect.width/2;spaceLeftOfPointtooltipRect.width&&(pullTooltipBy=tooltipRect.width),this.el_.style.right="-".concat(pullTooltipBy,"px")}this.write("".concat(content,"%"))}write(content){textContent(this.el_,content)}updateVolume(rangeBarRect,rangeBarPoint,vertical,volume,cb){this.requestNamedAnimationFrame("VolumeLevelTooltip#updateVolume",(()=>{this.update(rangeBarRect,rangeBarPoint,vertical,volume.toFixed(0)),cb&&cb()}))}});class MouseVolumeLevelDisplay extends Component$1{constructor(player,options){super(player,options),this.update=throttle(bind_(this,this.update),30)}createEl(){return super.createEl("div",{className:"vjs-mouse-display"})}update(rangeBarRect,rangeBarPoint,vertical){const volume=100*rangeBarPoint;this.getChild("volumeLevelTooltip").updateVolume(rangeBarRect,rangeBarPoint,vertical,volume,(()=>{vertical?this.el_.style.bottom="".concat(rangeBarRect.height*rangeBarPoint,"px"):this.el_.style.left="".concat(rangeBarRect.width*rangeBarPoint,"px")}))}}MouseVolumeLevelDisplay.prototype.options_={children:["volumeLevelTooltip"]},Component$1.registerComponent("MouseVolumeLevelDisplay",MouseVolumeLevelDisplay);class VolumeBar extends Slider{constructor(player,options){super(player,options),this.on("slideractive",(e=>this.updateLastVolume_(e))),this.on(player,"volumechange",(e=>this.updateARIAAttributes(e))),player.ready((()=>this.updateARIAAttributes()))}createEl(){return super.createEl("div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})}handleMouseDown(event){isSingleLeftClick(event)&&super.handleMouseDown(event)}handleMouseMove(event){const mouseVolumeLevelDisplay=this.getChild("mouseVolumeLevelDisplay");if(mouseVolumeLevelDisplay){const volumeBarEl=this.el(),volumeBarRect=getBoundingClientRect(volumeBarEl),vertical=this.vertical();let volumeBarPoint=getPointerPosition(volumeBarEl,event);volumeBarPoint=vertical?volumeBarPoint.y:volumeBarPoint.x,volumeBarPoint=clamp(volumeBarPoint,0,1),mouseVolumeLevelDisplay.update(volumeBarRect,volumeBarPoint,vertical)}isSingleLeftClick(event)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(event)))}checkMuted(){this.player_.muted()&&this.player_.muted(!1)}getPercent(){return this.player_.muted()?0:this.player_.volume()}stepForward(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)}stepBack(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)}updateARIAAttributes(event){const ariaValue=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",ariaValue),this.el_.setAttribute("aria-valuetext",ariaValue+"%")}volumeAsPercentage_(){return Math.round(100*this.player_.volume())}updateLastVolume_(){const volumeBeforeDrag=this.player_.volume();this.one("sliderinactive",(()=>{0===this.player_.volume()&&this.player_.lastVolume_(volumeBeforeDrag)}))}}VolumeBar.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},IS_IOS||IS_ANDROID||VolumeBar.prototype.options_.children.splice(0,0,"mouseVolumeLevelDisplay"),VolumeBar.prototype.playerEvent="volumechange",Component$1.registerComponent("VolumeBar",VolumeBar);class VolumeControl extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};options.vertical=options.vertical||!1,(void 0===options.volumeBar||isPlain(options.volumeBar))&&(options.volumeBar=options.volumeBar||{},options.volumeBar.vertical=options.vertical),super(player,options),function(self,player){player.tech_&&!player.tech_.featuresVolumeControl&&self.addClass("vjs-hidden"),self.on(player,"loadstart",(function(){player.tech_.featuresVolumeControl?self.removeClass("vjs-hidden"):self.addClass("vjs-hidden")}))}(this,player),this.throttledHandleMouseMove=throttle(bind_(this,this.handleMouseMove),30),this.handleMouseUpHandler_=e=>this.handleMouseUp(e),this.on("mousedown",(e=>this.handleMouseDown(e))),this.on("touchstart",(e=>this.handleMouseDown(e))),this.on("mousemove",(e=>this.handleMouseMove(e))),this.on(this.volumeBar,["focus","slideractive"],(()=>{this.volumeBar.addClass("vjs-slider-active"),this.addClass("vjs-slider-active"),this.trigger("slideractive")})),this.on(this.volumeBar,["blur","sliderinactive"],(()=>{this.volumeBar.removeClass("vjs-slider-active"),this.removeClass("vjs-slider-active"),this.trigger("sliderinactive")}))}createEl(){let orientationClass="vjs-volume-horizontal";return this.options_.vertical&&(orientationClass="vjs-volume-vertical"),super.createEl("div",{className:"vjs-volume-control vjs-control ".concat(orientationClass)})}handleMouseDown(event){const doc=this.el_.ownerDocument;this.on(doc,"mousemove",this.throttledHandleMouseMove),this.on(doc,"touchmove",this.throttledHandleMouseMove),this.on(doc,"mouseup",this.handleMouseUpHandler_),this.on(doc,"touchend",this.handleMouseUpHandler_)}handleMouseUp(event){const doc=this.el_.ownerDocument;this.off(doc,"mousemove",this.throttledHandleMouseMove),this.off(doc,"touchmove",this.throttledHandleMouseMove),this.off(doc,"mouseup",this.handleMouseUpHandler_),this.off(doc,"touchend",this.handleMouseUpHandler_)}handleMouseMove(event){this.volumeBar.handleMouseMove(event)}}VolumeControl.prototype.options_={children:["volumeBar"]},Component$1.registerComponent("VolumeControl",VolumeControl);class MuteToggle extends Button{constructor(player,options){super(player,options),function(self,player){player.tech_&&!player.tech_.featuresMuteControl&&self.addClass("vjs-hidden"),self.on(player,"loadstart",(function(){player.tech_.featuresMuteControl?self.removeClass("vjs-hidden"):self.addClass("vjs-hidden")}))}(this,player),this.on(player,["loadstart","volumechange"],(e=>this.update(e)))}buildCSSClass(){return"vjs-mute-control ".concat(super.buildCSSClass())}handleClick(event){const vol=this.player_.volume(),lastVolume=this.player_.lastVolume_();if(0===vol){const volumeToSet=lastVolume<.1?.1:lastVolume;this.player_.volume(volumeToSet),this.player_.muted(!1)}else this.player_.muted(!this.player_.muted())}update(event){this.updateIcon_(),this.updateControlText_()}updateIcon_(){const vol=this.player_.volume();let level=3;this.setIcon("volume-high"),IS_IOS&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===vol||this.player_.muted()?(this.setIcon("volume-mute"),level=0):vol<.33?(this.setIcon("volume-low"),level=1):vol<.67&&(this.setIcon("volume-medium"),level=2),removeClass(this.el_,[0,1,2,3].reduce(((str,i)=>str+"".concat(i?" ":"","vjs-vol-").concat(i)),"")),addClass(this.el_,"vjs-vol-".concat(level))}updateControlText_(){const text=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==text&&this.controlText(text)}}MuteToggle.prototype.controlText_="Mute",Component$1.registerComponent("MuteToggle",MuteToggle);class VolumePanel extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};void 0!==options.inline?options.inline=options.inline:options.inline=!0,(void 0===options.volumeControl||isPlain(options.volumeControl))&&(options.volumeControl=options.volumeControl||{},options.volumeControl.vertical=!options.inline),super(player,options),this.handleKeyPressHandler_=e=>this.handleKeyPress(e),this.on(player,["loadstart"],(e=>this.volumePanelState_(e))),this.on(this.muteToggle,"keyup",(e=>this.handleKeyPress(e))),this.on(this.volumeControl,"keyup",(e=>this.handleVolumeControlKeyUp(e))),this.on("keydown",(e=>this.handleKeyPress(e))),this.on("mouseover",(e=>this.handleMouseOver(e))),this.on("mouseout",(e=>this.handleMouseOut(e))),this.on(this.volumeControl,["slideractive"],this.sliderActive_),this.on(this.volumeControl,["sliderinactive"],this.sliderInactive_)}sliderActive_(){this.addClass("vjs-slider-active")}sliderInactive_(){this.removeClass("vjs-slider-active")}volumePanelState_(){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")}createEl(){let orientationClass="vjs-volume-panel-horizontal";return this.options_.inline||(orientationClass="vjs-volume-panel-vertical"),super.createEl("div",{className:"vjs-volume-panel vjs-control ".concat(orientationClass)})}dispose(){this.handleMouseOut(),super.dispose()}handleVolumeControlKeyUp(event){keycode.isEventKey(event,"Esc")&&this.muteToggle.focus()}handleMouseOver(event){this.addClass("vjs-hover"),on(document,"keyup",this.handleKeyPressHandler_)}handleMouseOut(event){this.removeClass("vjs-hover"),off(document,"keyup",this.handleKeyPressHandler_)}handleKeyPress(event){keycode.isEventKey(event,"Esc")&&this.handleMouseOut()}}VolumePanel.prototype.options_={children:["muteToggle","volumeControl"]},Component$1.registerComponent("VolumePanel",VolumePanel);class SkipForward extends Button{constructor(player,options){super(player,options),this.validOptions=[5,10,30],this.skipTime=this.getSkipForwardTime(),this.skipTime&&this.validOptions.includes(this.skipTime)?(this.setIcon("forward-".concat(this.skipTime)),this.controlText(this.localize("Skip forward {1} seconds",[this.skipTime])),this.show()):this.hide()}getSkipForwardTime(){const playerOptions=this.options_.playerOptions;return playerOptions.controlBar&&playerOptions.controlBar.skipButtons&&playerOptions.controlBar.skipButtons.forward}buildCSSClass(){return"vjs-skip-forward-".concat(this.getSkipForwardTime()," ").concat(super.buildCSSClass())}handleClick(event){if(isNaN(this.player_.duration()))return;const currentVideoTime=this.player_.currentTime(),liveTracker=this.player_.liveTracker,duration=liveTracker&&liveTracker.isLive()?liveTracker.seekableEnd():this.player_.duration();let newTime;newTime=currentVideoTime+this.skipTime<=duration?currentVideoTime+this.skipTime:duration,this.player_.currentTime(newTime)}handleLanguagechange(){this.controlText(this.localize("Skip forward {1} seconds",[this.skipTime]))}}SkipForward.prototype.controlText_="Skip Forward",Component$1.registerComponent("SkipForward",SkipForward);class SkipBackward extends Button{constructor(player,options){super(player,options),this.validOptions=[5,10,30],this.skipTime=this.getSkipBackwardTime(),this.skipTime&&this.validOptions.includes(this.skipTime)?(this.setIcon("replay-".concat(this.skipTime)),this.controlText(this.localize("Skip backward {1} seconds",[this.skipTime])),this.show()):this.hide()}getSkipBackwardTime(){const playerOptions=this.options_.playerOptions;return playerOptions.controlBar&&playerOptions.controlBar.skipButtons&&playerOptions.controlBar.skipButtons.backward}buildCSSClass(){return"vjs-skip-backward-".concat(this.getSkipBackwardTime()," ").concat(super.buildCSSClass())}handleClick(event){const currentVideoTime=this.player_.currentTime(),liveTracker=this.player_.liveTracker,seekableStart=liveTracker&&liveTracker.isLive()&&liveTracker.seekableStart();let newTime;newTime=seekableStart&¤tVideoTime-this.skipTime<=seekableStart?seekableStart:currentVideoTime>=this.skipTime?currentVideoTime-this.skipTime:0,this.player_.currentTime(newTime)}handleLanguagechange(){this.controlText(this.localize("Skip backward {1} seconds",[this.skipTime]))}}SkipBackward.prototype.controlText_="Skip Backward",Component$1.registerComponent("SkipBackward",SkipBackward);class Menu extends Component$1{constructor(player,options){super(player,options),options&&(this.menuButton_=options.menuButton),this.focusedChild_=-1,this.on("keydown",(e=>this.handleKeyDown(e))),this.boundHandleBlur_=e=>this.handleBlur(e),this.boundHandleTapClick_=e=>this.handleTapClick(e)}addEventListenerForItem(component){component instanceof Component$1&&(this.on(component,"blur",this.boundHandleBlur_),this.on(component,["tap","click"],this.boundHandleTapClick_))}removeEventListenerForItem(component){component instanceof Component$1&&(this.off(component,"blur",this.boundHandleBlur_),this.off(component,["tap","click"],this.boundHandleTapClick_))}removeChild(component){"string"==typeof component&&(component=this.getChild(component)),this.removeEventListenerForItem(component),super.removeChild(component)}addItem(component){const childComponent=this.addChild(component);childComponent&&this.addEventListenerForItem(childComponent)}createEl(){const contentElType=this.options_.contentElType||"ul";this.contentEl_=createEl(contentElType,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");const el=super.createEl("div",{append:this.contentEl_,className:"vjs-menu"});return el.appendChild(this.contentEl_),on(el,"click",(function(event){event.preventDefault(),event.stopImmediatePropagation()})),el}dispose(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,super.dispose()}handleBlur(event){const relatedTarget=event.relatedTarget||document.activeElement;if(!this.children().some((element=>element.el()===relatedTarget))){const btn=this.menuButton_;btn&&btn.buttonPressed_&&relatedTarget!==btn.el().firstChild&&btn.unpressButton()}}handleTapClick(event){if(this.menuButton_){this.menuButton_.unpressButton();const childComponents=this.children();if(!Array.isArray(childComponents))return;const foundComponent=childComponents.filter((component=>component.el()===event.target))[0];if(!foundComponent)return;"CaptionSettingsMenuItem"!==foundComponent.name()&&this.menuButton_.focus()}}handleKeyDown(event){keycode.isEventKey(event,"Left")||keycode.isEventKey(event,"Down")?(event.preventDefault(),event.stopPropagation(),this.stepForward()):(keycode.isEventKey(event,"Right")||keycode.isEventKey(event,"Up"))&&(event.preventDefault(),event.stopPropagation(),this.stepBack())}stepForward(){let stepChild=0;void 0!==this.focusedChild_&&(stepChild=this.focusedChild_+1),this.focus(stepChild)}stepBack(){let stepChild=0;void 0!==this.focusedChild_&&(stepChild=this.focusedChild_-1),this.focus(stepChild)}focus(){let item=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;const children=this.children().slice();children.length&&children[0].hasClass("vjs-menu-title")&&children.shift(),children.length>0&&(item<0?item=0:item>=children.length&&(item=children.length-1),this.focusedChild_=item,children[item].el_.focus())}}Component$1.registerComponent("Menu",Menu);class MenuButton extends Component$1{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(player,options),this.menuButton_=new Button(player,options),this.menuButton_.controlText(this.controlText_),this.menuButton_.el_.setAttribute("aria-haspopup","true");const buttonClass=Button.prototype.buildCSSClass();this.menuButton_.el_.className=this.buildCSSClass()+" "+buttonClass,this.menuButton_.removeClass("vjs-control"),this.addChild(this.menuButton_),this.update(),this.enabled_=!0;const handleClick=e=>this.handleClick(e);this.handleMenuKeyUp_=e=>this.handleMenuKeyUp(e),this.on(this.menuButton_,"tap",handleClick),this.on(this.menuButton_,"click",handleClick),this.on(this.menuButton_,"keydown",(e=>this.handleKeyDown(e))),this.on(this.menuButton_,"mouseenter",(()=>{this.addClass("vjs-hover"),this.menu.show(),on(document,"keyup",this.handleMenuKeyUp_)})),this.on("mouseleave",(e=>this.handleMouseLeave(e))),this.on("keydown",(e=>this.handleSubmenuKeyDown(e)))}update(){const menu=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=menu,this.addChild(menu),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?(this.hide(),this.menu.contentEl_.removeAttribute("role")):(this.show(),this.menu.contentEl_.setAttribute("role","menu"))}createMenu(){const menu=new Menu(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title){const titleEl=createEl("li",{className:"vjs-menu-title",textContent:toTitleCase$1(this.options_.title),tabIndex:-1}),titleComponent=new Component$1(this.player_,{el:titleEl});menu.addItem(titleComponent)}if(this.items=this.createItems(),this.items)for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:this.menuButton_.el();return this.menuButton_.controlText(text,el)}dispose(){this.handleMouseLeave(),super.dispose()}handleClick(event){this.buttonPressed_?this.unpressButton():this.pressButton()}handleMouseLeave(event){this.removeClass("vjs-hover"),off(document,"keyup",this.handleMenuKeyUp_)}focus(){this.menuButton_.focus()}blur(){this.menuButton_.blur()}handleKeyDown(event){keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab")?(this.buttonPressed_&&this.unpressButton(),keycode.isEventKey(event,"Tab")||(event.preventDefault(),this.menuButton_.focus())):(keycode.isEventKey(event,"Up")||keycode.isEventKey(event,"Down"))&&(this.buttonPressed_||(event.preventDefault(),this.pressButton()))}handleMenuKeyUp(event){(keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab"))&&this.removeClass("vjs-hover")}handleSubmenuKeyPress(event){this.handleSubmenuKeyDown(event)}handleSubmenuKeyDown(event){(keycode.isEventKey(event,"Esc")||keycode.isEventKey(event,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),keycode.isEventKey(event,"Tab")||(event.preventDefault(),this.menuButton_.focus()))}pressButton(){if(this.enabled_){if(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),IS_IOS&&isInFrame())return;this.menu.focus()}}unpressButton(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))}disable(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()}enable(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()}}Component$1.registerComponent("MenuButton",MenuButton);class TrackButton extends MenuButton{constructor(player,options){const tracks=options.tracks;if(super(player,options),this.items.length<=1&&this.hide(),!tracks)return;const updateHandler=bind_(this,this.update);tracks.addEventListener("removetrack",updateHandler),tracks.addEventListener("addtrack",updateHandler),tracks.addEventListener("labelchange",updateHandler),this.player_.on("ready",updateHandler),this.player_.on("dispose",(function(){tracks.removeEventListener("removetrack",updateHandler),tracks.removeEventListener("addtrack",updateHandler),tracks.removeEventListener("labelchange",updateHandler)}))}}Component$1.registerComponent("TrackButton",TrackButton);const MenuKeys=["Tab","Esc","Up","Down","Right","Left"];class MenuItem extends ClickableComponent{constructor(player,options){super(player,options),this.selectable=options.selectable,this.isSelected_=options.selected||!1,this.multiSelectable=options.multiSelectable,this.selected(this.isSelected_),this.selectable?this.multiSelectable?this.el_.setAttribute("role","menuitemcheckbox"):this.el_.setAttribute("role","menuitemradio"):this.el_.setAttribute("role","menuitem")}createEl(type,props,attrs){this.nonIconControl=!0;const el=super.createEl("li",Object.assign({className:"vjs-menu-item",tabIndex:-1},props),attrs),menuItemEl=createEl("span",{className:"vjs-menu-item-text",textContent:this.localize(this.options_.label)});return this.player_.options_.experimentalSvgIcons?el.appendChild(menuItemEl):el.replaceChild(menuItemEl,el.querySelector(".vjs-icon-placeholder")),el}handleKeyDown(event){MenuKeys.some((key=>keycode.isEventKey(event,key)))||super.handleKeyDown(event)}handleClick(event){this.selected(!0)}selected(selected){this.selectable&&(selected?(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))}}Component$1.registerComponent("MenuItem",MenuItem);class TextTrackMenuItem extends MenuItem{constructor(player,options){var _this3;const track=options.track,tracks=player.textTracks();options.label=track.label||track.language||"Unknown",options.selected="showing"===track.mode,super(player,options),_this3=this,this.track=track,this.kinds=(options.kinds||[options.kind||this.track.kind]).filter(Boolean);const changeHandler=function(){for(var _len17=arguments.length,args=new Array(_len17),_key17=0;_key17<_len17;_key17++)args[_key17]=arguments[_key17];_this3.handleTracksChange.apply(_this3,args)},selectedLanguageChangeHandler=function(){for(var _len18=arguments.length,args=new Array(_len18),_key18=0;_key18<_len18;_key18++)args[_key18]=arguments[_key18];_this3.handleSelectedLanguageChange.apply(_this3,args)};if(player.on(["loadstart","texttrackchange"],changeHandler),tracks.addEventListener("change",changeHandler),tracks.addEventListener("selectedlanguagechange",selectedLanguageChangeHandler),this.on("dispose",(function(){player.off(["loadstart","texttrackchange"],changeHandler),tracks.removeEventListener("change",changeHandler),tracks.removeEventListener("selectedlanguagechange",selectedLanguageChangeHandler)})),void 0===tracks.onchange){let event;this.on(["tap","click"],(function(){if("object"!=typeof window.Event)try{event=new window.Event("change")}catch(err){}event||(event=document.createEvent("Event"),event.initEvent("change",!0,!0)),tracks.dispatchEvent(event)}))}this.handleTracksChange()}handleClick(event){const referenceTrack=this.track,tracks=this.player_.textTracks();if(super.handleClick(event),tracks)for(let i=0;i-1&&"showing"===track.mode){shouldBeSelected=!1;break}}shouldBeSelected!==this.isSelected_&&this.selected(shouldBeSelected)}handleSelectedLanguageChange(event){const tracks=this.player().textTracks();let allHidden=!0;for(let i=0,l=tracks.length;i-1&&"showing"===track.mode){allHidden=!1;break}}allHidden&&(this.player_.cache_.selectedLanguage={enabled:!1})}handleLanguagechange(){this.$(".vjs-menu-item-text").textContent=this.player_.localize(this.options_.label),super.handleLanguagechange()}}Component$1.registerComponent("OffTextTrackMenuItem",OffTextTrackMenuItem);class TextTrackButton extends TrackButton{constructor(player){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};options.tracks=player.textTracks(),super(player,options)}createItems(){let label,items=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],TrackMenuItem=arguments.length>1&&void 0!==arguments[1]?arguments[1]:TextTrackMenuItem;this.label_&&(label="".concat(this.label_," off")),items.push(new OffTextTrackMenuItem(this.player_,{kinds:this.kinds_,kind:this.kind_,label:label})),this.hideThreshold_+=1;const tracks=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(let i=0;i-1){const item=new TrackMenuItem(this.player_,{track:track,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1});item.addClass("vjs-".concat(track.kind,"-menu-item")),items.push(item)}}return items}}Component$1.registerComponent("TextTrackButton",TextTrackButton);class ChaptersTrackMenuItem extends MenuItem{constructor(player,options){const track=options.track,cue=options.cue,currentTime=player.currentTime();options.selectable=!0,options.multiSelectable=!1,options.label=cue.text,options.selected=cue.startTime<=currentTime&¤tTime{this.items.forEach((item=>{item.selected(this.track_.activeCues[0]===item.cue)}))}}buildCSSClass(){return"vjs-chapters-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-chapters-button ".concat(super.buildWrapperCSSClass())}update(event){if(event&&event.track&&"chapters"!==event.track.kind)return;const track=this.findChaptersTrack();track!==this.track_?(this.setTrack(track),super.update()):(!this.items||track&&track.cues&&track.cues.length!==this.items.length)&&super.update()}setTrack(track){if(this.track_!==track){if(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_){const remoteTextTrackEl=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);remoteTextTrackEl&&remoteTextTrackEl.removeEventListener("load",this.updateHandler_),this.track_.removeEventListener("cuechange",this.selectCurrentItem_),this.track_=null}if(this.track_=track,this.track_){this.track_.mode="hidden";const remoteTextTrackEl=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);remoteTextTrackEl&&remoteTextTrackEl.addEventListener("load",this.updateHandler_),this.track_.addEventListener("cuechange",this.selectCurrentItem_)}}}findChaptersTrack(){const tracks=this.player_.textTracks()||[];for(let i=tracks.length-1;i>=0;i--){const track=tracks[i];if(track.kind===this.kind_)return track}}getMenuCaption(){return this.track_&&this.track_.label?this.track_.label:this.localize(toTitleCase$1(this.kind_))}createMenu(){return this.options_.title=this.getMenuCaption(),super.createMenu()}createItems(){const items=[];if(!this.track_)return items;const cues=this.track_.cues;if(!cues)return items;for(let i=0,l=cues.length;i1&&void 0!==arguments[1]?arguments[1]:{}),this.label_="subtitles",this.setIcon("subtitles"),["en","en-us","en-ca","fr-ca"].indexOf(this.player_.language_)>-1&&(this.label_="captions",this.setIcon("captions")),this.menuButton_.controlText(toTitleCase$1(this.label_))}buildCSSClass(){return"vjs-subs-caps-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-subs-caps-button ".concat(super.buildWrapperCSSClass())}createItems(){let items=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(items.push(new CaptionSettingsMenuItem(this.player_,{kind:this.label_})),this.hideThreshold_+=1),items=super.createItems(items,SubsCapsMenuItem),items}}SubsCapsButton.prototype.kinds_=["captions","subtitles"],SubsCapsButton.prototype.controlText_="Subtitles",Component$1.registerComponent("SubsCapsButton",SubsCapsButton);class AudioTrackMenuItem extends MenuItem{constructor(player,options){var _this4;const track=options.track,tracks=player.audioTracks();options.label=track.label||track.language||"Unknown",options.selected=track.enabled,super(player,options),_this4=this,this.track=track,this.addClass("vjs-".concat(track.kind,"-menu-item"));const changeHandler=function(){for(var _len19=arguments.length,args=new Array(_len19),_key19=0;_key19<_len19;_key19++)args[_key19]=arguments[_key19];_this4.handleTracksChange.apply(_this4,args)};tracks.addEventListener("change",changeHandler),this.on("dispose",(()=>{tracks.removeEventListener("change",changeHandler)}))}createEl(type,props,attrs){const el=super.createEl(type,props,attrs),parentSpan=el.querySelector(".vjs-menu-item-text");return["main-desc","description"].indexOf(this.options_.track.kind)>=0&&(parentSpan.appendChild(createEl("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),parentSpan.appendChild(createEl("span",{className:"vjs-control-text",textContent:" "+this.localize("Descriptions")}))),el}handleClick(event){if(super.handleClick(event),this.track.enabled=!0,this.player_.tech_.featuresNativeAudioTracks){const tracks=this.player_.audioTracks();for(let i=0;i1&&void 0!==arguments[1]?arguments[1]:{};options.tracks=player.audioTracks(),super(player,options),this.setIcon("audio")}buildCSSClass(){return"vjs-audio-button ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-audio-button ".concat(super.buildWrapperCSSClass())}createItems(){let items=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.hideThreshold_=1;const tracks=this.player_.audioTracks();for(let i=0;ithis.update(e)))}handleClick(event){super.handleClick(),this.player().playbackRate(this.rate)}update(event){this.selected(this.player().playbackRate()===this.rate)}}PlaybackRateMenuItem.prototype.contentElType="button",Component$1.registerComponent("PlaybackRateMenuItem",PlaybackRateMenuItem);class PlaybackRateMenuButton extends MenuButton{constructor(player,options){super(player,options),this.menuButton_.el_.setAttribute("aria-describedby",this.labelElId_),this.updateVisibility(),this.updateLabel(),this.on(player,"loadstart",(e=>this.updateVisibility(e))),this.on(player,"ratechange",(e=>this.updateLabel(e))),this.on(player,"playbackrateschange",(e=>this.handlePlaybackRateschange(e)))}createEl(){const el=super.createEl();return this.labelElId_="vjs-playback-rate-value-label-"+this.id_,this.labelEl_=createEl("div",{className:"vjs-playback-rate-value",id:this.labelElId_,textContent:"1x"}),el.appendChild(this.labelEl_),el}dispose(){this.labelEl_=null,super.dispose()}buildCSSClass(){return"vjs-playback-rate ".concat(super.buildCSSClass())}buildWrapperCSSClass(){return"vjs-playback-rate ".concat(super.buildWrapperCSSClass())}createItems(){const rates=this.playbackRates(),items=[];for(let i=rates.length-1;i>=0;i--)items.push(new PlaybackRateMenuItem(this.player(),{rate:rates[i]+"x"}));return items}handlePlaybackRateschange(event){this.update()}playbackRates(){const player=this.player();return player.playbackRates&&player.playbackRates()||[]}playbackRateSupported(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&this.playbackRates().length>0}updateVisibility(event){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")}updateLabel(event){this.playbackRateSupported()&&(this.labelEl_.textContent=this.player().playbackRate()+"x")}}PlaybackRateMenuButton.prototype.controlText_="Playback Rate",Component$1.registerComponent("PlaybackRateMenuButton",PlaybackRateMenuButton);class Spacer extends Component$1{buildCSSClass(){return"vjs-spacer ".concat(super.buildCSSClass())}createEl(){let tag=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",props=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},attributes=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return props.className||(props.className=this.buildCSSClass()),super.createEl(tag,props,attributes)}}Component$1.registerComponent("Spacer",Spacer);Component$1.registerComponent("CustomControlSpacer",class extends Spacer{buildCSSClass(){return"vjs-custom-control-spacer ".concat(super.buildCSSClass())}createEl(){return super.createEl("div",{className:this.buildCSSClass(),textContent:" "})}});class ControlBar extends Component$1{createEl(){return super.createEl("div",{className:"vjs-control-bar",dir:"ltr"})}}ControlBar.prototype.options_={children:["playToggle","skipBackward","skipForward","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","pictureInPictureToggle","fullscreenToggle"]},Component$1.registerComponent("ControlBar",ControlBar);class ErrorDisplay extends ModalDialog{constructor(player,options){super(player,options),this.on(player,"error",(e=>{this.close(),this.open(e)}))}buildCSSClass(){return"vjs-error-display ".concat(super.buildCSSClass())}content(){const error=this.player().error();return error?this.localize(error.message):""}}ErrorDisplay.prototype.options_=Object.assign({},ModalDialog.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),Component$1.registerComponent("ErrorDisplay",ErrorDisplay);const COLOR_BLACK=["#000","Black"],COLOR_BLUE=["#00F","Blue"],COLOR_CYAN=["#0FF","Cyan"],COLOR_GREEN=["#0F0","Green"],COLOR_MAGENTA=["#F0F","Magenta"],COLOR_RED=["#F00","Red"],COLOR_WHITE=["#FFF","White"],COLOR_YELLOW=["#FF0","Yellow"],OPACITY_OPAQUE=["1","Opaque"],OPACITY_SEMI=["0.5","Semi-Transparent"],OPACITY_TRANS=["0","Transparent"],selectConfigs={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[COLOR_BLACK,COLOR_WHITE,COLOR_RED,COLOR_GREEN,COLOR_BLUE,COLOR_YELLOW,COLOR_MAGENTA,COLOR_CYAN]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Opacity",options:[OPACITY_OPAQUE,OPACITY_SEMI,OPACITY_TRANS]},color:{selector:".vjs-text-color > select",id:"captions-foreground-color-%s",label:"Color",options:[COLOR_WHITE,COLOR_BLACK,COLOR_RED,COLOR_GREEN,COLOR_BLUE,COLOR_YELLOW,COLOR_MAGENTA,COLOR_CYAN]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Drop shadow"]]},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:v=>"1.00"===v?null:Number(v)},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Opacity",options:[OPACITY_OPAQUE,OPACITY_SEMI]},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:"Opacity",options:[OPACITY_TRANS,OPACITY_SEMI,OPACITY_OPAQUE]}};function parseOptionValue(value,parser){if(parser&&(value=parser(value)),value&&"none"!==value)return value}selectConfigs.windowColor.options=selectConfigs.backgroundColor.options;Component$1.registerComponent("TextTrackSettings",class extends ModalDialog{constructor(player,options){options.temporary=!1,super(player,options),this.updateDisplay=this.updateDisplay.bind(this),this.fill(),this.hasBeenOpened_=this.hasBeenFilled_=!0,this.endDialog=createEl("p",{className:"vjs-control-text",textContent:this.localize("End of dialog window.")}),this.el().appendChild(this.endDialog),this.setDefaults(),void 0===options.persistTextTrackSettings&&(this.options_.persistTextTrackSettings=this.options_.playerOptions.persistTextTrackSettings),this.on(this.$(".vjs-done-button"),"click",(()=>{this.saveSettings(),this.close()})),this.on(this.$(".vjs-default-button"),"click",(()=>{this.setDefaults(),this.updateDisplay()})),each(selectConfigs,(config=>{this.on(this.$(config.selector),"change",this.updateDisplay)})),this.options_.persistTextTrackSettings&&this.restoreSettings()}dispose(){this.endDialog=null,super.dispose()}createElSelect_(key){let legendId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",type=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"label";const config=selectConfigs[key],id=config.id.replace("%s",this.id_),selectLabelledbyIds=[legendId,id].join(" ").trim(),guid="vjs_select_".concat(newGUID());return["<".concat(type,' id="').concat(id,'"').concat("label"===type?' for="'.concat(guid,'" class="vjs-label"'):"",">"),this.localize(config.label),""),'").join("")}createElFgColor_(){const legendId="captions-text-legend-".concat(this.id_);return['
',''),this.localize("Text"),"",'',this.createElSelect_("color",legendId),"",'',this.createElSelect_("textOpacity",legendId),"","
"].join("")}createElBgColor_(){const legendId="captions-background-".concat(this.id_);return['
',''),this.localize("Text Background"),"",'',this.createElSelect_("backgroundColor",legendId),"",'',this.createElSelect_("backgroundOpacity",legendId),"","
"].join("")}createElWinColor_(){const legendId="captions-window-".concat(this.id_);return['
',''),this.localize("Caption Area Background"),"",'',this.createElSelect_("windowColor",legendId),"",'',this.createElSelect_("windowOpacity",legendId),"","
"].join("")}createElColors_(){return createEl("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})}createElFont_(){return createEl("div",{className:"vjs-track-settings-font",innerHTML:['
',this.createElSelect_("fontPercent","","legend"),"
",'
',this.createElSelect_("edgeStyle","","legend"),"
",'
',this.createElSelect_("fontFamily","","legend"),"
"].join("")})}createElControls_(){const defaultsDescription=this.localize("restore all settings to the default values");return createEl("div",{className:"vjs-track-settings-controls",innerHTML:['",'")].join("")})}content(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]}label(){return this.localize("Caption Settings Dialog")}description(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")}buildCSSClass(){return super.buildCSSClass()+" vjs-text-track-settings"}getValues(){return reduce(selectConfigs,((accum,config,key)=>{const value=(el=this.$(config.selector),parser=config.parser,parseOptionValue(el.options[el.options.selectedIndex].value,parser));var el,parser;return void 0!==value&&(accum[key]=value),accum}),{})}setValues(values){each(selectConfigs,((config,key)=>{!function(el,value,parser){if(value)for(let i=0;i{const index=config.hasOwnProperty("default")?config.default:0;this.$(config.selector).selectedIndex=index}))}restoreSettings(){let values;try{values=JSON.parse(window.localStorage.getItem("vjs-text-track-settings"))}catch(err){log$1.warn(err)}values&&this.setValues(values)}saveSettings(){if(!this.options_.persistTextTrackSettings)return;const values=this.getValues();try{Object.keys(values).length?window.localStorage.setItem("vjs-text-track-settings",JSON.stringify(values)):window.localStorage.removeItem("vjs-text-track-settings")}catch(err){log$1.warn(err)}}updateDisplay(){const ttDisplay=this.player_.getChild("textTrackDisplay");ttDisplay&&ttDisplay.updateDisplay()}conditionalBlur_(){this.previouslyActiveEl_=null;const cb=this.player_.controlBar,subsCapsBtn=cb&&cb.subsCapsButton,ccBtn=cb&&cb.captionsButton;subsCapsBtn?subsCapsBtn.focus():ccBtn&&ccBtn.focus()}handleLanguagechange(){this.fill()}});Component$1.registerComponent("ResizeManager",class extends Component$1{constructor(player,options){let RESIZE_OBSERVER_AVAILABLE=options.ResizeObserver||window.ResizeObserver;null===options.ResizeObserver&&(RESIZE_OBSERVER_AVAILABLE=!1);super(player,merge$2({createEl:!RESIZE_OBSERVER_AVAILABLE,reportTouchActivity:!1},options)),this.ResizeObserver=options.ResizeObserver||window.ResizeObserver,this.loadListener_=null,this.resizeObserver_=null,this.debouncedHandler_=debounce((()=>{this.resizeHandler()}),100,!1,this),RESIZE_OBSERVER_AVAILABLE?(this.resizeObserver_=new this.ResizeObserver(this.debouncedHandler_),this.resizeObserver_.observe(player.el())):(this.loadListener_=()=>{if(!this.el_||!this.el_.contentWindow)return;const debouncedHandler_=this.debouncedHandler_;let unloadListener_=this.unloadListener_=function(){off(this,"resize",debouncedHandler_),off(this,"unload",unloadListener_),unloadListener_=null};on(this.el_.contentWindow,"unload",unloadListener_),on(this.el_.contentWindow,"resize",debouncedHandler_)},this.one("load",this.loadListener_))}createEl(){return super.createEl("iframe",{className:"vjs-resize-manager",tabIndex:-1,title:this.localize("No content")},{"aria-hidden":"true"})}resizeHandler(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")}dispose(){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,super.dispose()}});const defaults={trackingThreshold:20,liveTolerance:15};Component$1.registerComponent("LiveTracker",class extends Component$1{constructor(player,options){super(player,merge$2(defaults,options,{createEl:!1})),this.trackLiveHandler_=()=>this.trackLive_(),this.handlePlay_=e=>this.handlePlay(e),this.handleFirstTimeupdate_=e=>this.handleFirstTimeupdate(e),this.handleSeeked_=e=>this.handleSeeked(e),this.seekToLiveEdge_=e=>this.seekToLiveEdge(e),this.reset_(),this.on(this.player_,"durationchange",(e=>this.handleDurationchange(e))),this.on(this.player_,"canplay",(()=>this.toggleTracking()))}trackLive_(){const seekable=this.player_.seekable();if(!seekable||!seekable.length)return;const newTime=Number(window.performance.now().toFixed(4)),deltaTime=-1===this.lastTime_?0:(newTime-this.lastTime_)/1e3;this.lastTime_=newTime,this.pastSeekEnd_=this.pastSeekEnd()+deltaTime;const liveCurrentTime=this.liveCurrentTime(),currentTime=this.player_.currentTime();let isBehind=this.player_.paused()||this.seekedBehindLive_||Math.abs(liveCurrentTime-currentTime)>this.options_.liveTolerance;this.timeupdateSeen_&&liveCurrentTime!==1/0||(isBehind=!1),isBehind!==this.behindLiveEdge_&&(this.behindLiveEdge_=isBehind,this.trigger("liveedgechange"))}handleDurationchange(){this.toggleTracking()}toggleTracking(){this.player_.duration()===1/0&&this.liveWindow()>=this.options_.trackingThreshold?(this.player_.options_.liveui&&this.player_.addClass("vjs-liveui"),this.startTracking()):(this.player_.removeClass("vjs-liveui"),this.stopTracking())}startTracking(){this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLiveHandler_,30),this.trackLive_(),this.on(this.player_,["play","pause"],this.trackLiveHandler_),this.timeupdateSeen_?this.on(this.player_,"seeked",this.handleSeeked_):(this.one(this.player_,"play",this.handlePlay_),this.one(this.player_,"timeupdate",this.handleFirstTimeupdate_)))}handleFirstTimeupdate(){this.timeupdateSeen_=!0,this.on(this.player_,"seeked",this.handleSeeked_)}handleSeeked(){const timeDiff=Math.abs(this.liveCurrentTime()-this.player_.currentTime());this.seekedBehindLive_=this.nextSeekedFromUser_&&timeDiff>2,this.nextSeekedFromUser_=!1,this.trackLive_()}handlePlay(){this.one(this.player_,"timeupdate",this.seekToLiveEdge_)}reset_(){this.lastTime_=-1,this.pastSeekEnd_=0,this.lastSeekEnd_=-1,this.behindLiveEdge_=!0,this.timeupdateSeen_=!1,this.seekedBehindLive_=!1,this.nextSeekedFromUser_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.off(this.player_,["play","pause"],this.trackLiveHandler_),this.off(this.player_,"seeked",this.handleSeeked_),this.off(this.player_,"play",this.handlePlay_),this.off(this.player_,"timeupdate",this.handleFirstTimeupdate_),this.off(this.player_,"timeupdate",this.seekToLiveEdge_)}nextSeekedFromUser(){this.nextSeekedFromUser_=!0}stopTracking(){this.isTracking()&&(this.reset_(),this.trigger("liveedgechange"))}seekableEnd(){const seekable=this.player_.seekable(),seekableEnds=[];let i=seekable?seekable.length:0;for(;i--;)seekableEnds.push(seekable.end(i));return seekableEnds.length?seekableEnds.sort()[seekableEnds.length-1]:1/0}seekableStart(){const seekable=this.player_.seekable(),seekableStarts=[];let i=seekable?seekable.length:0;for(;i--;)seekableStarts.push(seekable.start(i));return seekableStarts.length?seekableStarts.sort()[0]:0}liveWindow(){const liveCurrentTime=this.liveCurrentTime();return liveCurrentTime===1/0?0:liveCurrentTime-this.seekableStart()}isLive(){return this.isTracking()}atLiveEdge(){return!this.behindLiveEdge()}liveCurrentTime(){return this.pastSeekEnd()+this.seekableEnd()}pastSeekEnd(){const seekableEnd=this.seekableEnd();return-1!==this.lastSeekEnd_&&seekableEnd!==this.lastSeekEnd_&&(this.pastSeekEnd_=0),this.lastSeekEnd_=seekableEnd,this.pastSeekEnd_}behindLiveEdge(){return this.behindLiveEdge_}isTracking(){return"number"==typeof this.trackingInterval_}seekToLiveEdge(){this.seekedBehindLive_=!1,this.atLiveEdge()||(this.nextSeekedFromUser_=!1,this.player_.currentTime(this.liveCurrentTime()))}dispose(){this.stopTracking(),super.dispose()}});Component$1.registerComponent("TitleBar",class extends Component$1{constructor(player,options){super(player,options),this.on("statechanged",(e=>this.updateDom_())),this.updateDom_()}createEl(){return this.els={title:createEl("div",{className:"vjs-title-bar-title",id:"vjs-title-bar-title-".concat(newGUID())}),description:createEl("div",{className:"vjs-title-bar-description",id:"vjs-title-bar-description-".concat(newGUID())})},createEl("div",{className:"vjs-title-bar"},{},values$1(this.els))}updateDom_(){const tech=this.player_.tech_,techEl=tech&&tech.el_,techAriaAttrs={title:"aria-labelledby",description:"aria-describedby"};["title","description"].forEach((k=>{const value=this.state[k],el=this.els[k],techAriaAttr=techAriaAttrs[k];emptyEl(el),value&&textContent(el,value),techEl&&(techEl.removeAttribute(techAriaAttr),value&&techEl.setAttribute(techAriaAttr,el.id))})),this.state.title||this.state.description?this.show():this.hide()}update(options){this.setState(options)}dispose(){const tech=this.player_.tech_,techEl=tech&&tech.el_;techEl&&(techEl.removeAttribute("aria-labelledby"),techEl.removeAttribute("aria-describedby")),super.dispose(),this.els=null}});const sourcesetLoad=tech=>{const el=tech.el();if(el.hasAttribute("src"))return tech.triggerSourceset(el.src),!0;const sources=tech.$$("source"),srcUrls=[];let src="";if(!sources.length)return!1;for(let i=0;i{let descriptor={};for(let i=0;igetDescriptor([tech.el(),window.HTMLMediaElement.prototype,window.Element.prototype,innerHTMLDescriptorPolyfill],"innerHTML"))(tech),appendWrapper=appendFn=>function(){for(var _len20=arguments.length,args=new Array(_len20),_key20=0;_key20<_len20;_key20++)args[_key20]=arguments[_key20];const retval=appendFn.apply(el,args);return sourcesetLoad(tech),retval};["append","appendChild","insertAdjacentHTML"].forEach((k=>{el[k]&&(old[k]=el[k],el[k]=appendWrapper(old[k]))})),Object.defineProperty(el,"innerHTML",merge$2(innerDescriptor,{set:appendWrapper(innerDescriptor.set)})),el.resetSourceWatch_=()=>{el.resetSourceWatch_=null,Object.keys(old).forEach((k=>{el[k]=old[k]})),Object.defineProperty(el,"innerHTML",innerDescriptor)},tech.one("sourceset",el.resetSourceWatch_)},srcDescriptorPolyfill=Object.defineProperty({},"src",{get(){return this.hasAttribute("src")?getAbsoluteURL(window.Element.prototype.getAttribute.call(this,"src")):""},set(v){return window.Element.prototype.setAttribute.call(this,"src",v),v}}),setupSourceset=function(tech){if(!tech.featuresSourceset)return;const el=tech.el();if(el.resetSourceset_)return;const srcDescriptor=(tech=>getDescriptor([tech.el(),window.HTMLMediaElement.prototype,srcDescriptorPolyfill],"src"))(tech),oldSetAttribute=el.setAttribute,oldLoad=el.load;Object.defineProperty(el,"src",merge$2(srcDescriptor,{set:v=>{const retval=srcDescriptor.set.call(el,v);return tech.triggerSourceset(el.src),retval}})),el.setAttribute=(n,v)=>{const retval=oldSetAttribute.call(el,n,v);return/src/i.test(n)&&tech.triggerSourceset(el.src),retval},el.load=()=>{const retval=oldLoad.call(el);return sourcesetLoad(tech)||(tech.triggerSourceset(""),firstSourceWatch(tech)),retval},el.currentSrc?tech.triggerSourceset(el.currentSrc):sourcesetLoad(tech)||firstSourceWatch(tech),el.resetSourceset_=()=>{el.resetSourceset_=null,el.load=oldLoad,el.setAttribute=oldSetAttribute,Object.defineProperty(el,"src",srcDescriptor),el.resetSourceWatch_&&el.resetSourceWatch_()}};class Html5 extends Tech{constructor(options,ready){super(options,ready);const source=options.source;let crossoriginTracks=!1;if(this.featuresVideoFrameCallback=this.featuresVideoFrameCallback&&"VIDEO"===this.el_.tagName,source&&(this.el_.currentSrc!==source.src||options.tag&&3===options.tag.initNetworkState_)?this.setSource(source):this.handleLateInit_(this.el_),options.enableSourceset&&this.setupSourcesetHandling_(),this.isScrubbing_=!1,this.el_.hasChildNodes()){const nodes=this.el_.childNodes;let nodesLength=nodes.length;const removeNodes=[];for(;nodesLength--;){const node=nodes[nodesLength];"track"===node.nodeName.toLowerCase()&&(this.featuresNativeTextTracks?(this.remoteTextTrackEls().addTrackElement_(node),this.remoteTextTracks().addTrack(node.track),this.textTracks().addTrack(node.track),crossoriginTracks||this.el_.hasAttribute("crossorigin")||!isCrossOrigin(node.src)||(crossoriginTracks=!0)):removeNodes.push(node))}for(let i=0;i{metadataTracksPreFullscreenState=[];for(let i=0;itextTracks.removeEventListener("change",takeMetadataTrackSnapshot)));const restoreTrackMode=()=>{for(let i=0;i{textTracks.removeEventListener("change",takeMetadataTrackSnapshot),textTracks.removeEventListener("change",restoreTrackMode),textTracks.addEventListener("change",restoreTrackMode)})),this.on("webkitendfullscreen",(()=>{textTracks.removeEventListener("change",takeMetadataTrackSnapshot),textTracks.addEventListener("change",takeMetadataTrackSnapshot),textTracks.removeEventListener("change",restoreTrackMode)}))}overrideNative_(type,override){if(override!==this["featuresNative".concat(type,"Tracks")])return;const lowerCaseType=type.toLowerCase();this["".concat(lowerCaseType,"TracksListeners_")]&&Object.keys(this["".concat(lowerCaseType,"TracksListeners_")]).forEach((eventName=>{this.el()["".concat(lowerCaseType,"Tracks")].removeEventListener(eventName,this["".concat(lowerCaseType,"TracksListeners_")][eventName])})),this["featuresNative".concat(type,"Tracks")]=!override,this["".concat(lowerCaseType,"TracksListeners_")]=null,this.proxyNativeTracksForType_(lowerCaseType)}overrideNativeAudioTracks(override){this.overrideNative_("Audio",override)}overrideNativeVideoTracks(override){this.overrideNative_("Video",override)}proxyNativeTracksForType_(name){const props=NORMAL[name],elTracks=this.el()[props.getterName],techTracks=this[props.getterName]();if(!this["featuresNative".concat(props.capitalName,"Tracks")]||!elTracks||!elTracks.addEventListener)return;const listeners={change:e=>{const event={type:"change",target:techTracks,currentTarget:techTracks,srcElement:techTracks};techTracks.trigger(event),"text"===name&&this[REMOTE.remoteText.getterName]().trigger(event)},addtrack(e){techTracks.addTrack(e.track)},removetrack(e){techTracks.removeTrack(e.track)}},removeOldTracks=function(){const removeTracks=[];for(let i=0;i{const listener=listeners[eventName];elTracks.addEventListener(eventName,listener),this.on("dispose",(e=>elTracks.removeEventListener(eventName,listener)))})),this.on("loadstart",removeOldTracks),this.on("dispose",(e=>this.off("loadstart",removeOldTracks)))}proxyNativeTracks_(){NORMAL.names.forEach((name=>{this.proxyNativeTracksForType_(name)}))}createEl(){let el=this.options_.tag;if(!el||!this.options_.playerElIngest&&!this.movingMediaElementInDOM){if(el){const clone=el.cloneNode(!0);el.parentNode&&el.parentNode.insertBefore(clone,el),Html5.disposeMediaElement(el),el=clone}else{el=document.createElement("video");const attributes=merge$2({},this.options_.tag&&getAttributes(this.options_.tag));TOUCH_ENABLED&&!0===this.options_.nativeControlsForTouch||delete attributes.controls,setAttributes(el,Object.assign(attributes,{id:this.options_.techId,class:"vjs-tech"}))}el.playerId=this.options_.playerId}void 0!==this.options_.preload&&setAttribute(el,"preload",this.options_.preload),void 0!==this.options_.disablePictureInPicture&&(el.disablePictureInPicture=this.options_.disablePictureInPicture);const settingsAttrs=["loop","muted","playsinline","autoplay"];for(let i=0;i=2&&eventsToTrigger.push("loadeddata"),el.readyState>=3&&eventsToTrigger.push("canplay"),el.readyState>=4&&eventsToTrigger.push("canplaythrough"),this.ready((function(){eventsToTrigger.forEach((function(type){this.trigger(type)}),this)}))}setScrubbing(isScrubbing){this.isScrubbing_=isScrubbing}scrubbing(){return this.isScrubbing_}setCurrentTime(seconds){try{this.isScrubbing_&&this.el_.fastSeek&&IS_ANY_SAFARI?this.el_.fastSeek(seconds):this.el_.currentTime=seconds}catch(e){log$1(e,"Video is not ready. (Video.js)")}}duration(){if(this.el_.duration===1/0&&IS_ANDROID&&IS_CHROME&&0===this.el_.currentTime){const checkProgress=()=>{this.el_.currentTime>0&&(this.el_.duration===1/0&&this.trigger("durationchange"),this.off("timeupdate",checkProgress))};return this.on("timeupdate",checkProgress),NaN}return this.el_.duration||NaN}width(){return this.el_.offsetWidth}height(){return this.el_.offsetHeight}proxyWebkitFullscreen_(){if(!("webkitDisplayingFullscreen"in this.el_))return;const endFn=function(){this.trigger("fullscreenchange",{isFullscreen:!1}),this.el_.controls&&!this.options_.nativeControlsForTouch&&this.controls()&&(this.el_.controls=!1)},beginFn=function(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",endFn),this.trigger("fullscreenchange",{isFullscreen:!0,nativeIOSFullscreen:!0}))};this.on("webkitbeginfullscreen",beginFn),this.on("dispose",(()=>{this.off("webkitbeginfullscreen",beginFn),this.off("webkitendfullscreen",endFn)}))}supportsFullScreen(){return"function"==typeof this.el_.webkitEnterFullScreen}enterFullScreen(){const video=this.el_;if(video.paused&&video.networkState<=video.HAVE_METADATA)silencePromise(this.el_.play()),this.setTimeout((function(){video.pause();try{video.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}}),0);else try{video.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}}exitFullScreen(){this.el_.webkitDisplayingFullscreen?this.el_.webkitExitFullScreen():this.trigger("fullscreenerror",new Error("The video is not fullscreen"))}requestPictureInPicture(){return this.el_.requestPictureInPicture()}requestVideoFrameCallback(cb){return this.featuresVideoFrameCallback&&!this.el_.webkitKeys?this.el_.requestVideoFrameCallback(cb):super.requestVideoFrameCallback(cb)}cancelVideoFrameCallback(id){this.featuresVideoFrameCallback&&!this.el_.webkitKeys?this.el_.cancelVideoFrameCallback(id):super.cancelVideoFrameCallback(id)}src(src){if(void 0===src)return this.el_.src;this.setSrc(src)}reset(){Html5.resetMediaElement(this.el_)}currentSrc(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc}setControls(val){this.el_.controls=!!val}addTextTrack(kind,label,language){return this.featuresNativeTextTracks?this.el_.addTextTrack(kind,label,language):super.addTextTrack(kind,label,language)}createRemoteTextTrack(options){if(!this.featuresNativeTextTracks)return super.createRemoteTextTrack(options);const htmlTrackElement=document.createElement("track");return options.kind&&(htmlTrackElement.kind=options.kind),options.label&&(htmlTrackElement.label=options.label),(options.language||options.srclang)&&(htmlTrackElement.srclang=options.language||options.srclang),options.default&&(htmlTrackElement.default=options.default),options.id&&(htmlTrackElement.id=options.id),options.src&&(htmlTrackElement.src=options.src),htmlTrackElement}addRemoteTextTrack(options,manualCleanup){const htmlTrackElement=super.addRemoteTextTrack(options,manualCleanup);return this.featuresNativeTextTracks&&this.el().appendChild(htmlTrackElement),htmlTrackElement}removeRemoteTextTrack(track){if(super.removeRemoteTextTrack(track),this.featuresNativeTextTracks){const tracks=this.$$("track");let i=tracks.length;for(;i--;)track!==tracks[i]&&track!==tracks[i].track||this.el().removeChild(tracks[i])}}getVideoPlaybackQuality(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();const videoPlaybackQuality={};return void 0!==this.el().webkitDroppedFrameCount&&void 0!==this.el().webkitDecodedFrameCount&&(videoPlaybackQuality.droppedVideoFrames=this.el().webkitDroppedFrameCount,videoPlaybackQuality.totalVideoFrames=this.el().webkitDecodedFrameCount),window.performance&&(videoPlaybackQuality.creationTime=window.performance.now()),videoPlaybackQuality}}defineLazyProperty(Html5,"TEST_VID",(function(){if(!isReal())return;const video=document.createElement("video"),track=document.createElement("track");return track.kind="captions",track.srclang="en",track.label="English",video.appendChild(track),video})),Html5.isSupported=function(){try{Html5.TEST_VID.volume=.5}catch(e){return!1}return!(!Html5.TEST_VID||!Html5.TEST_VID.canPlayType)},Html5.canPlayType=function(type){return Html5.TEST_VID.canPlayType(type)},Html5.canPlaySource=function(srcObj,options){return Html5.canPlayType(srcObj.type)},Html5.canControlVolume=function(){try{const volume=Html5.TEST_VID.volume;Html5.TEST_VID.volume=volume/2+.1;const canControl=volume!==Html5.TEST_VID.volume;return canControl&&IS_IOS?(window.setTimeout((()=>{Html5&&Html5.prototype&&(Html5.prototype.featuresVolumeControl=volume!==Html5.TEST_VID.volume)})),!1):canControl}catch(e){return!1}},Html5.canMuteVolume=function(){try{const muted=Html5.TEST_VID.muted;return Html5.TEST_VID.muted=!muted,Html5.TEST_VID.muted?setAttribute(Html5.TEST_VID,"muted","muted"):removeAttribute(Html5.TEST_VID,"muted"),muted!==Html5.TEST_VID.muted}catch(e){return!1}},Html5.canControlPlaybackRate=function(){if(IS_ANDROID&&IS_CHROME&&CHROME_VERSION<58)return!1;try{const playbackRate=Html5.TEST_VID.playbackRate;return Html5.TEST_VID.playbackRate=playbackRate/2+.1,playbackRate!==Html5.TEST_VID.playbackRate}catch(e){return!1}},Html5.canOverrideAttributes=function(){try{const noop=()=>{};Object.defineProperty(document.createElement("video"),"src",{get:noop,set:noop}),Object.defineProperty(document.createElement("audio"),"src",{get:noop,set:noop}),Object.defineProperty(document.createElement("video"),"innerHTML",{get:noop,set:noop}),Object.defineProperty(document.createElement("audio"),"innerHTML",{get:noop,set:noop})}catch(e){return!1}return!0},Html5.supportsNativeTextTracks=function(){return IS_ANY_SAFARI||IS_IOS&&IS_CHROME},Html5.supportsNativeVideoTracks=function(){return!(!Html5.TEST_VID||!Html5.TEST_VID.videoTracks)},Html5.supportsNativeAudioTracks=function(){return!(!Html5.TEST_VID||!Html5.TEST_VID.audioTracks)},Html5.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],[["featuresMuteControl","canMuteVolume"],["featuresPlaybackRate","canControlPlaybackRate"],["featuresSourceset","canOverrideAttributes"],["featuresNativeTextTracks","supportsNativeTextTracks"],["featuresNativeVideoTracks","supportsNativeVideoTracks"],["featuresNativeAudioTracks","supportsNativeAudioTracks"]].forEach((function(_ref5){let[key,fn]=_ref5;defineLazyProperty(Html5.prototype,key,(()=>Html5[fn]()),!0)})),Html5.prototype.featuresVolumeControl=Html5.canControlVolume(),Html5.prototype.movingMediaElementInDOM=!IS_IOS,Html5.prototype.featuresFullscreenResize=!0,Html5.prototype.featuresProgressEvents=!0,Html5.prototype.featuresTimeupdateEvents=!0,Html5.prototype.featuresVideoFrameCallback=!(!Html5.TEST_VID||!Html5.TEST_VID.requestVideoFrameCallback),Html5.disposeMediaElement=function(el){if(el){for(el.parentNode&&el.parentNode.removeChild(el);el.hasChildNodes();)el.removeChild(el.firstChild);el.removeAttribute("src"),"function"==typeof el.load&&function(){try{el.load()}catch(e){}}()}},Html5.resetMediaElement=function(el){if(!el)return;const sources=el.querySelectorAll("source");let i=sources.length;for(;i--;)el.removeChild(sources[i]);el.removeAttribute("src"),"function"==typeof el.load&&function(){try{el.load()}catch(e){}}()},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]||this.el_.hasAttribute(prop)}})),["muted","defaultMuted","autoplay","loop","playsinline"].forEach((function(prop){Html5.prototype["set"+toTitleCase$1(prop)]=function(v){this.el_[prop]=v,v?this.el_.setAttribute(prop,prop):this.el_.removeAttribute(prop)}})),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","disablePictureInPicture","played","networkState","readyState","videoWidth","videoHeight","crossOrigin"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]}})),["volume","src","poster","preload","playbackRate","defaultPlaybackRate","disablePictureInPicture","crossOrigin"].forEach((function(prop){Html5.prototype["set"+toTitleCase$1(prop)]=function(v){this.el_[prop]=v}})),["pause","load","play"].forEach((function(prop){Html5.prototype[prop]=function(){return this.el_[prop]()}})),Tech.withSourceHandlers(Html5),Html5.nativeSourceHandler={},Html5.nativeSourceHandler.canPlayType=function(type){try{return Html5.TEST_VID.canPlayType(type)}catch(e){return""}},Html5.nativeSourceHandler.canHandleSource=function(source,options){if(source.type)return Html5.nativeSourceHandler.canPlayType(source.type);if(source.src){const ext=getFileExtension(source.src);return Html5.nativeSourceHandler.canPlayType("video/".concat(ext))}return""},Html5.nativeSourceHandler.handleSource=function(source,tech,options){tech.setSrc(source.src)},Html5.nativeSourceHandler.dispose=function(){},Html5.registerSourceHandler(Html5.nativeSourceHandler),Tech.registerTech("Html5",Html5);const TECH_EVENTS_RETRIGGER=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],TECH_EVENTS_QUEUE={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},BREAKPOINT_ORDER=["tiny","xsmall","small","medium","large","xlarge","huge"],BREAKPOINT_CLASSES={};BREAKPOINT_ORDER.forEach((k=>{const v="x"===k.charAt(0)?"x-".concat(k.substring(1)):k;BREAKPOINT_CLASSES[k]="vjs-layout-".concat(v)}));const DEFAULT_BREAKPOINTS={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0};class Player extends Component$1{constructor(tag,options,ready){if(tag.id=tag.id||options.id||"vjs_video_".concat(newGUID()),(options=Object.assign(Player.getTagSettings(tag),options)).initChildren=!1,options.createEl=!1,options.evented=!1,options.reportTouchActivity=!1,!options.language){const closest=tag.closest("[lang]");closest&&(options.language=closest.getAttribute("lang"))}if(super(null,options,ready),this.boundDocumentFullscreenChange_=e=>this.documentFullscreenChange_(e),this.boundFullWindowOnEscKey_=e=>this.fullWindowOnEscKey(e),this.boundUpdateStyleEl_=e=>this.updateStyleEl_(e),this.boundApplyInitTime_=e=>this.applyInitTime_(e),this.boundUpdateCurrentBreakpoint_=e=>this.updateCurrentBreakpoint_(e),this.boundHandleTechClick_=e=>this.handleTechClick_(e),this.boundHandleTechDoubleClick_=e=>this.handleTechDoubleClick_(e),this.boundHandleTechTouchStart_=e=>this.handleTechTouchStart_(e),this.boundHandleTechTouchMove_=e=>this.handleTechTouchMove_(e),this.boundHandleTechTouchEnd_=e=>this.handleTechTouchEnd_(e),this.boundHandleTechTap_=e=>this.handleTechTap_(e),this.isFullscreen_=!1,this.log=createLogger(this.id_),this.fsApi_=FullscreenApi,this.isPosterFromTech_=!1,this.queuedCallbacks_=[],this.isReady_=!1,this.hasStarted_=!1,this.userActive_=!1,this.debugEnabled_=!1,this.audioOnlyMode_=!1,this.audioPosterMode_=!1,this.audioOnlyCache_={playerHeight:null,hiddenChildren:[]},!this.options_||!this.options_.techOrder||!this.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(this.tag=tag,this.tagAttributes=tag&&getAttributes(tag),this.language(this.options_.language),options.languages){const languagesToLower={};Object.getOwnPropertyNames(options.languages).forEach((function(name){languagesToLower[name.toLowerCase()]=options.languages[name]})),this.languages_=languagesToLower}else this.languages_=Player.prototype.options_.languages;this.resetCache_(),this.poster_=options.poster||"",this.controls_=!!options.controls,tag.controls=!1,tag.removeAttribute("controls"),this.changingSrc_=!1,this.playCallbacks_=[],this.playTerminatedQueue_=[],tag.hasAttribute("autoplay")?this.autoplay(!0):this.autoplay(this.options_.autoplay),options.plugins&&Object.keys(options.plugins).forEach((name=>{if("function"!=typeof this[name])throw new Error('plugin "'.concat(name,'" does not exist'))})),this.scrubbing_=!1,this.el_=this.createEl(),evented(this,{eventBusKey:"el_"}),this.fsApi_.requestFullscreen&&(on(document,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),this.on(this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_)),this.fluid_&&this.on(["playerreset","resize"],this.boundUpdateStyleEl_);const playerOptionsCopy=merge$2(this.options_);if(options.plugins&&Object.keys(options.plugins).forEach((name=>{this[name](options.plugins[name])})),options.debug&&this.debug(!0),this.options_.playerOptions=playerOptionsCopy,this.middleware_=[],this.playbackRates(options.playbackRates),options.experimentalSvgIcons){const parsedSVG=(new window.DOMParser).parseFromString('\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n',"image/svg+xml");if(parsedSVG.querySelector("parsererror"))log$1.warn("Failed to load SVG Icons. Falling back to Font Icons."),this.options_.experimentalSvgIcons=null;else{const sprite=parsedSVG.documentElement;sprite.style.display="none",this.el_.appendChild(sprite),this.addClass("vjs-svg-icons-enabled")}}this.initChildren(),this.isAudio("audio"===tag.nodeName.toLowerCase()),this.controls()?this.addClass("vjs-controls-enabled"):this.addClass("vjs-controls-disabled"),this.el_.setAttribute("role","region"),this.isAudio()?this.el_.setAttribute("aria-label",this.localize("Audio Player")):this.el_.setAttribute("aria-label",this.localize("Video Player")),this.isAudio()&&this.addClass("vjs-audio"),TOUCH_ENABLED&&this.addClass("vjs-touch-enabled"),IS_IOS||this.addClass("vjs-workinghover"),Player.players[this.id_]=this;const majorVersion="8.10.0".split(".")[0];this.addClass("vjs-v".concat(majorVersion)),this.userActive(!0),this.reportUserActivity(),this.one("play",(e=>this.listenForUserActivity_(e))),this.on("keydown",(e=>this.handleKeyDown(e))),this.on("languagechange",(e=>this.handleLanguagechange(e))),this.breakpoints(this.options_.breakpoints),this.responsive(this.options_.responsive),this.on("ready",(()=>{this.audioPosterMode(this.options_.audioPosterMode),this.audioOnlyMode(this.options_.audioOnlyMode)}))}dispose(){this.trigger("dispose"),this.off("dispose"),off(document,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),off(document,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),Player.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),middlewareInstances[this.id()]=null,ALL.names.forEach((name=>{const list=this[ALL[name].getterName]();list&&list.off&&list.off()})),super.dispose({restoreEl:this.options_.restoreEl})}createEl(){let el,tag=this.tag,playerElIngest=this.playerElIngest_=tag.parentNode&&tag.parentNode.hasAttribute&&tag.parentNode.hasAttribute("data-vjs-player");const divEmbed="video-js"===this.tag.tagName.toLowerCase();playerElIngest?el=this.el_=tag.parentNode:divEmbed||(el=this.el_=super.createEl("div"));const attrs=getAttributes(tag);if(divEmbed){for(el=this.el_=tag,tag=this.tag=document.createElement("video");el.children.length;)tag.appendChild(el.firstChild);hasClass(el,"video-js")||addClass(el,"video-js"),el.appendChild(tag),playerElIngest=this.playerElIngest_=el,Object.keys(el).forEach((k=>{try{tag[k]=el[k]}catch(e){}}))}if(tag.setAttribute("tabindex","-1"),attrs.tabindex="-1",IS_CHROME&&IS_WINDOWS&&(tag.setAttribute("role","application"),attrs.role="application"),tag.removeAttribute("width"),tag.removeAttribute("height"),"width"in attrs&&delete attrs.width,"height"in attrs&&delete attrs.height,Object.getOwnPropertyNames(attrs).forEach((function(attr){divEmbed&&"class"===attr||el.setAttribute(attr,attrs[attr]),divEmbed&&tag.setAttribute(attr,attrs[attr])})),tag.playerId=tag.id,tag.id+="_html5_api",tag.className="vjs-tech",tag.player=el.player=this,this.addClass("vjs-paused"),!0!==window.VIDEOJS_NO_DYNAMIC_STYLE){this.styleEl_=createStyleElement("vjs-styles-dimensions");const defaultsStyleEl=$(".vjs-styles-defaults"),head=$("head");head.insertBefore(this.styleEl_,defaultsStyleEl?defaultsStyleEl.nextSibling:head.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),this.crossOrigin(this.options_.crossOrigin||this.options_.crossorigin);const links=tag.getElementsByTagName("a");for(let i=0;i{this.on(["playerreset","resize"],this.boundUpdateStyleEl_)},isEvented(target=this)?callback():(target.eventedCallbacks||(target.eventedCallbacks=[]),target.eventedCallbacks.push(callback))):this.removeClass("vjs-fluid"),this.updateStyleEl_()}fill(bool){if(void 0===bool)return!!this.fill_;this.fill_=!!bool,bool?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")}aspectRatio(ratio){if(void 0===ratio)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(ratio))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=ratio,this.fluid(!0),this.updateStyleEl_()}updateStyleEl_(){if(!0===window.VIDEOJS_NO_DYNAMIC_STYLE){const width="number"==typeof this.width_?this.width_:this.options_.width,height="number"==typeof this.height_?this.height_:this.options_.height,techEl=this.tech_&&this.tech_.el();return void(techEl&&(width>=0&&(techEl.width=width),height>=0&&(techEl.height=height)))}let width,height,aspectRatio,idClass;aspectRatio=void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:this.videoWidth()>0?this.videoWidth()+":"+this.videoHeight():"16:9";const ratioParts=aspectRatio.split(":"),ratioMultiplier=ratioParts[1]/ratioParts[0];width=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/ratioMultiplier:this.videoWidth()||300,height=void 0!==this.height_?this.height_:width*ratioMultiplier,idClass=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(idClass),setTextContent(this.styleEl_,"\n .".concat(idClass," {\n width: ").concat(width,"px;\n height: ").concat(height,"px;\n }\n\n .").concat(idClass,".vjs-fluid:not(.vjs-audio-only-mode) {\n padding-top: ").concat(100*ratioMultiplier,"%;\n }\n "))}loadTech_(techName,source){this.tech_&&this.unloadTech_();const titleTechName=toTitleCase$1(techName),camelTechName=techName.charAt(0).toLowerCase()+techName.slice(1);"Html5"!==titleTechName&&this.tag&&(Tech.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=titleTechName,this.isReady_=!1;let autoplay=this.autoplay();("string"==typeof this.autoplay()||!0===this.autoplay()&&this.options_.normalizeAutoplay)&&(autoplay=!1);const techOptions={source:source,autoplay:autoplay,nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:"".concat(this.id(),"_").concat(camelTechName,"_api"),playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,disablePictureInPicture:this.options_.disablePictureInPicture,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};ALL.names.forEach((name=>{const props=ALL[name];techOptions[props.getterName]=this[props.privateName]})),Object.assign(techOptions,this.options_[titleTechName]),Object.assign(techOptions,this.options_[camelTechName]),Object.assign(techOptions,this.options_[techName.toLowerCase()]),this.tag&&(techOptions.tag=this.tag),source&&source.src===this.cache_.src&&this.cache_.currentTime>0&&(techOptions.startTime=this.cache_.currentTime);const TechClass=Tech.getTech(techName);if(!TechClass)throw new Error("No Tech named '".concat(titleTechName,"' exists! '").concat(titleTechName,"' should be registered using videojs.registerTech()'"));this.tech_=new TechClass(techOptions),this.tech_.ready(bind_(this,this.handleTechReady_),!0),textTrackConverter_jsonToTextTracks(this.textTracksJson_||[],this.tech_),TECH_EVENTS_RETRIGGER.forEach((event=>{this.on(this.tech_,event,(e=>this["handleTech".concat(toTitleCase$1(event),"_")](e)))})),Object.keys(TECH_EVENTS_QUEUE).forEach((event=>{this.on(this.tech_,event,(eventObj=>{0===this.tech_.playbackRate()&&this.tech_.seeking()?this.queuedCallbacks_.push({callback:this["handleTech".concat(TECH_EVENTS_QUEUE[event],"_")].bind(this),event:eventObj}):this["handleTech".concat(TECH_EVENTS_QUEUE[event],"_")](eventObj)}))})),this.on(this.tech_,"loadstart",(e=>this.handleTechLoadStart_(e))),this.on(this.tech_,"sourceset",(e=>this.handleTechSourceset_(e))),this.on(this.tech_,"waiting",(e=>this.handleTechWaiting_(e))),this.on(this.tech_,"ended",(e=>this.handleTechEnded_(e))),this.on(this.tech_,"seeking",(e=>this.handleTechSeeking_(e))),this.on(this.tech_,"play",(e=>this.handleTechPlay_(e))),this.on(this.tech_,"pause",(e=>this.handleTechPause_(e))),this.on(this.tech_,"durationchange",(e=>this.handleTechDurationChange_(e))),this.on(this.tech_,"fullscreenchange",((e,data)=>this.handleTechFullscreenChange_(e,data))),this.on(this.tech_,"fullscreenerror",((e,err)=>this.handleTechFullscreenError_(e,err))),this.on(this.tech_,"enterpictureinpicture",(e=>this.handleTechEnterPictureInPicture_(e))),this.on(this.tech_,"leavepictureinpicture",(e=>this.handleTechLeavePictureInPicture_(e))),this.on(this.tech_,"error",(e=>this.handleTechError_(e))),this.on(this.tech_,"posterchange",(e=>this.handleTechPosterChange_(e))),this.on(this.tech_,"textdata",(e=>this.handleTechTextData_(e))),this.on(this.tech_,"ratechange",(e=>this.handleTechRateChange_(e))),this.on(this.tech_,"loadedmetadata",this.boundUpdateStyleEl_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===titleTechName&&this.tag||prependTo(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)}unloadTech_(){ALL.names.forEach((name=>{const props=ALL[name];this[props.privateName]=this[props.getterName]()})),this.textTracksJson_=textTrackConverter_textTracksToJson(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1}tech(safety){return void 0===safety&&log$1.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_}version(){return{"video.js":"8.10.0"}}addTechControlsListeners_(){this.removeTechControlsListeners_(),this.on(this.tech_,"click",this.boundHandleTechClick_),this.on(this.tech_,"dblclick",this.boundHandleTechDoubleClick_),this.on(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.on(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.on(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.on(this.tech_,"tap",this.boundHandleTechTap_)}removeTechControlsListeners_(){this.off(this.tech_,"tap",this.boundHandleTechTap_),this.off(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.off(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.off(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.off(this.tech_,"click",this.boundHandleTechClick_),this.off(this.tech_,"dblclick",this.boundHandleTechDoubleClick_)}handleTechReady_(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()}handleTechLoadStart_(){this.removeClass("vjs-ended","vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):this.trigger("loadstart"),this.manualAutoplay_(!0===this.autoplay()&&this.options_.normalizeAutoplay?"play":this.autoplay())}manualAutoplay_(type){if(!this.tech_||"string"!=typeof type)return;const resolveMuted=()=>{const previouslyMuted=this.muted();this.muted(!0);const restoreMuted=()=>{this.muted(previouslyMuted)};this.playTerminatedQueue_.push(restoreMuted);const mutedPromise=this.play();if(isPromise(mutedPromise))return mutedPromise.catch((err=>{throw restoreMuted(),new Error("Rejection at manualAutoplay. Restoring muted value. ".concat(err||""))}))};let promise;return"any"!==type||this.muted()?promise="muted"!==type||this.muted()?this.play():resolveMuted():(promise=this.play(),isPromise(promise)&&(promise=promise.catch(resolveMuted))),isPromise(promise)?promise.then((()=>{this.trigger({type:"autoplay-success",autoplay:type})})).catch((()=>{this.trigger({type:"autoplay-failure",autoplay:type})})):void 0}updateSourceCaches_(){let srcObj=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",src=srcObj,type="";"string"!=typeof src&&(src=srcObj.src,type=srcObj.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],src&&!type&&(type=((player,src)=>{if(!src)return"";if(player.cache_.source.src===src&&player.cache_.source.type)return player.cache_.source.type;const matchingSources=player.cache_.sources.filter((s=>s.src===src));if(matchingSources.length)return matchingSources[0].type;const sources=player.$$("source");for(let i=0;is.src&&s.src===src)),sourceElSources=[],sourceEls=this.$$("source"),matchingSourceEls=[];for(let i=0;ithis.updateSourceCaches_(src);const playerSrc=this.currentSource().src,eventSrc=event.src;playerSrc&&!/^blob:/.test(playerSrc)&&/^blob:/.test(eventSrc)&&(!this.lastSource_||this.lastSource_.tech!==eventSrc&&this.lastSource_.player!==playerSrc)&&(updateSourceCaches=()=>{}),updateSourceCaches(eventSrc),event.src||this.tech_.any(["sourceset","loadstart"],(e=>{if("sourceset"===e.type)return;const techSrc=this.techGet_("currentSrc");this.lastSource_.tech=techSrc,this.updateSourceCaches_(techSrc)}))}this.lastSource_={player:this.currentSource().src,tech:event.src},this.trigger({src:event.src,type:"sourceset"})}hasStarted(request){if(void 0===request)return this.hasStarted_;request!==this.hasStarted_&&(this.hasStarted_=request,this.hasStarted_?this.addClass("vjs-has-started"):this.removeClass("vjs-has-started"))}handleTechPlay_(){this.removeClass("vjs-ended","vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")}handleTechRateChange_(){this.tech_.playbackRate()>0&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach((queued=>queued.callback(queued.event))),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")}handleTechWaiting_(){this.addClass("vjs-waiting"),this.trigger("waiting");const timeWhenWaiting=this.currentTime(),timeUpdateListener=()=>{timeWhenWaiting!==this.currentTime()&&(this.removeClass("vjs-waiting"),this.off("timeupdate",timeUpdateListener))};this.on("timeupdate",timeUpdateListener)}handleTechCanPlay_(){this.removeClass("vjs-waiting"),this.trigger("canplay")}handleTechCanPlayThrough_(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")}handleTechPlaying_(){this.removeClass("vjs-waiting"),this.trigger("playing")}handleTechSeeking_(){this.addClass("vjs-seeking"),this.trigger("seeking")}handleTechSeeked_(){this.removeClass("vjs-seeking","vjs-ended"),this.trigger("seeked")}handleTechPause_(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")}handleTechEnded_(){this.addClass("vjs-ended"),this.removeClass("vjs-waiting"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")}handleTechDurationChange_(){this.duration(this.techGet_("duration"))}handleTechClick_(event){this.controls_&&(void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.click&&!1===this.options_.userActions.click||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.click?this.options_.userActions.click.call(this,event):this.paused()?silencePromise(this.play()):this.pause()))}handleTechDoubleClick_(event){if(!this.controls_)return;Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),(el=>el.contains(event.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,event):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen())}handleTechTap_(){this.userActive(!this.userActive())}handleTechTouchStart_(){this.userWasActive=this.userActive()}handleTechTouchMove_(){this.userWasActive&&this.reportUserActivity()}handleTechTouchEnd_(event){event.cancelable&&event.preventDefault()}toggleFullscreenClass_(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")}documentFullscreenChange_(e){const targetPlayer=e.target.player;if(targetPlayer&&targetPlayer!==this)return;const el=this.el();let isFs=document[this.fsApi_.fullscreenElement]===el;!isFs&&el.matches&&(isFs=el.matches(":"+this.fsApi_.fullscreen)),this.isFullscreen(isFs)}handleTechFullscreenChange_(event,data){data&&(data.nativeIOSFullscreen&&(this.addClass("vjs-ios-native-fs"),this.tech_.one("webkitendfullscreen",(()=>{this.removeClass("vjs-ios-native-fs")}))),this.isFullscreen(data.isFullscreen))}handleTechFullscreenError_(event,err){this.trigger("fullscreenerror",err)}togglePictureInPictureClass_(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")}handleTechEnterPictureInPicture_(event){this.isInPictureInPicture(!0)}handleTechLeavePictureInPicture_(event){this.isInPictureInPicture(!1)}handleTechError_(){const error=this.tech_.error();error&&this.error(error)}handleTechTextData_(){let data=null;arguments.length>1&&(data=arguments[1]),this.trigger("textdata",data)}getCache(){return this.cache_}resetCache_(){this.cache_={currentTime:0,initTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],playbackRates:[],volume:1}}techCall_(method,arg){this.ready((function(){if(method in allowedSetters)return function(middleware,tech,method,arg){return tech[method](middleware.reduce(middlewareIterator(method),arg))}(this.middleware_,this.tech_,method,arg);if(method in allowedMediators)return mediate(this.middleware_,this.tech_,method,arg);try{this.tech_&&this.tech_[method](arg)}catch(e){throw log$1(e),e}}),!0)}techGet_(method){if(this.tech_&&this.tech_.isReady_){if(method in allowedGetters)return function(middleware,tech,method){return middleware.reduceRight(middlewareIterator(method),tech[method]())}(this.middleware_,this.tech_,method);if(method in allowedMediators)return mediate(this.middleware_,this.tech_,method);try{return this.tech_[method]()}catch(e){if(void 0===this.tech_[method])throw log$1("Video.js: ".concat(method," method not defined for ").concat(this.techName_," playback technology."),e),e;if("TypeError"===e.name)throw log$1("Video.js: ".concat(method," unavailable on ").concat(this.techName_," playback technology element."),e),this.tech_.isReady_=!1,e;throw log$1(e),e}}}play(){return new Promise((resolve=>{this.play_(resolve)}))}play_(){let callback=arguments.length>0&&void 0!==arguments[0]?arguments[0]:silencePromise;this.playCallbacks_.push(callback);const isSrcReady=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc())),isSafariOrIOS=Boolean(IS_ANY_SAFARI||IS_IOS);if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!isSrcReady)return this.waitToPlay_=e=>{this.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(!isSrcReady&&isSafariOrIOS&&this.load());const val=this.techGet_("play");isSafariOrIOS&&this.hasClass("vjs-ended")&&this.resetProgressBar_(),null===val?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(val)}runPlayTerminatedQueue_(){const queue=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],queue.forEach((function(q){q()}))}runPlayCallbacks_(val){const callbacks=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],callbacks.forEach((function(cb){cb(val)}))}pause(){this.techCall_("pause")}paused(){return!1!==this.techGet_("paused")}played(){return this.techGet_("played")||createTimeRanges$1(0,0)}scrubbing(isScrubbing){if(void 0===isScrubbing)return this.scrubbing_;this.scrubbing_=!!isScrubbing,this.techCall_("setScrubbing",this.scrubbing_),isScrubbing?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")}currentTime(seconds){return void 0===seconds?(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime):(seconds<0&&(seconds=0),this.isReady_&&!this.changingSrc_&&this.tech_&&this.tech_.isReady_?(this.techCall_("setCurrentTime",seconds),this.cache_.initTime=0,void(isFinite(seconds)&&(this.cache_.currentTime=Number(seconds)))):(this.cache_.initTime=seconds,this.off("canplay",this.boundApplyInitTime_),void this.one("canplay",this.boundApplyInitTime_)))}applyInitTime_(){this.currentTime(this.cache_.initTime)}duration(seconds){if(void 0===seconds)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(seconds=parseFloat(seconds))<0&&(seconds=1/0),seconds!==this.cache_.duration&&(this.cache_.duration=seconds,seconds===1/0?this.addClass("vjs-live"):this.removeClass("vjs-live"),isNaN(seconds)||this.trigger("durationchange"))}remainingTime(){return this.duration()-this.currentTime()}remainingTimeDisplay(){return Math.floor(this.duration())-Math.floor(this.currentTime())}buffered(){let buffered=this.techGet_("buffered");return buffered&&buffered.length||(buffered=createTimeRanges$1(0,0)),buffered}seekable(){let seekable=this.techGet_("seekable");return seekable&&seekable.length||(seekable=createTimeRanges$1(0,0)),seekable}seeking(){return this.techGet_("seeking")}ended(){return this.techGet_("ended")}networkState(){return this.techGet_("networkState")}readyState(){return this.techGet_("readyState")}bufferedPercent(){return bufferedPercent(this.buffered(),this.duration())}bufferedEnd(){const buffered=this.buffered(),duration=this.duration();let end=buffered.end(buffered.length-1);return end>duration&&(end=duration),end}volume(percentAsDecimal){let vol;return void 0!==percentAsDecimal?(vol=Math.max(0,Math.min(1,percentAsDecimal)),this.cache_.volume=vol,this.techCall_("setVolume",vol),void(vol>0&&this.lastVolume_(vol))):(vol=parseFloat(this.techGet_("volume")),isNaN(vol)?1:vol)}muted(muted){if(void 0===muted)return this.techGet_("muted")||!1;this.techCall_("setMuted",muted)}defaultMuted(defaultMuted){return void 0!==defaultMuted&&this.techCall_("setDefaultMuted",defaultMuted),this.techGet_("defaultMuted")||!1}lastVolume_(percentAsDecimal){if(void 0===percentAsDecimal||0===percentAsDecimal)return this.cache_.lastVolume;this.cache_.lastVolume=percentAsDecimal}supportsFullScreen(){return this.techGet_("supportsFullScreen")||!1}isFullscreen(isFS){if(void 0!==isFS){const oldValue=this.isFullscreen_;return this.isFullscreen_=Boolean(isFS),this.isFullscreen_!==oldValue&&this.fsApi_.prefixed&&this.trigger("fullscreenchange"),void this.toggleFullscreenClass_()}return this.isFullscreen_}requestFullscreen(fullscreenOptions){this.isInPictureInPicture()&&this.exitPictureInPicture();const self=this;return new Promise(((resolve,reject)=>{function offHandler(){self.off("fullscreenerror",errorHandler),self.off("fullscreenchange",changeHandler)}function changeHandler(){offHandler(),resolve()}function errorHandler(e,err){offHandler(),reject(err)}self.one("fullscreenchange",changeHandler),self.one("fullscreenerror",errorHandler);const promise=self.requestFullscreenHelper_(fullscreenOptions);promise&&(promise.then(offHandler,offHandler),promise.then(resolve,reject))}))}requestFullscreenHelper_(fullscreenOptions){let fsOptions;if(this.fsApi_.prefixed||(fsOptions=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==fullscreenOptions&&(fsOptions=fullscreenOptions)),this.fsApi_.requestFullscreen){const promise=this.el_[this.fsApi_.requestFullscreen](fsOptions);return promise&&promise.then((()=>this.isFullscreen(!0)),(()=>this.isFullscreen(!1))),promise}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("enterFullScreen"):this.enterFullWindow()}exitFullscreen(){const self=this;return new Promise(((resolve,reject)=>{function offHandler(){self.off("fullscreenerror",errorHandler),self.off("fullscreenchange",changeHandler)}function changeHandler(){offHandler(),resolve()}function errorHandler(e,err){offHandler(),reject(err)}self.one("fullscreenchange",changeHandler),self.one("fullscreenerror",errorHandler);const promise=self.exitFullscreenHelper_();promise&&(promise.then(offHandler,offHandler),promise.then(resolve,reject))}))}exitFullscreenHelper_(){if(this.fsApi_.requestFullscreen){const promise=document[this.fsApi_.exitFullscreen]();return promise&&silencePromise(promise.then((()=>this.isFullscreen(!1)))),promise}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("exitFullScreen"):this.exitFullWindow()}enterFullWindow(){this.isFullscreen(!0),this.isFullWindow=!0,this.docOrigOverflow=document.documentElement.style.overflow,on(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow="hidden",addClass(document.body,"vjs-full-window"),this.trigger("enterFullWindow")}fullWindowOnEscKey(event){keycode.isEventKey(event,"Esc")&&!0===this.isFullscreen()&&(this.isFullWindow?this.exitFullWindow():this.exitFullscreen())}exitFullWindow(){this.isFullscreen(!1),this.isFullWindow=!1,off(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow=this.docOrigOverflow,removeClass(document.body,"vjs-full-window"),this.trigger("exitFullWindow")}disablePictureInPicture(value){if(void 0===value)return this.techGet_("disablePictureInPicture");this.techCall_("setDisablePictureInPicture",value),this.options_.disablePictureInPicture=value,this.trigger("disablepictureinpicturechanged")}isInPictureInPicture(isPiP){return void 0!==isPiP?(this.isInPictureInPicture_=!!isPiP,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_}requestPictureInPicture(){if(this.options_.enableDocumentPictureInPicture&&window.documentPictureInPicture){const pipContainer=document.createElement(this.el().tagName);return pipContainer.classList=this.el().classList,pipContainer.classList.add("vjs-pip-container"),this.posterImage&&pipContainer.appendChild(this.posterImage.el().cloneNode(!0)),this.titleBar&&pipContainer.appendChild(this.titleBar.el().cloneNode(!0)),pipContainer.appendChild(createEl("p",{className:"vjs-pip-text"},{},this.localize("Playing in picture-in-picture"))),window.documentPictureInPicture.requestWindow({width:this.videoWidth(),height:this.videoHeight()}).then((pipWindow=>(copyStyleSheetsToWindow(pipWindow),this.el_.parentNode.insertBefore(pipContainer,this.el_),pipWindow.document.body.appendChild(this.el_),pipWindow.document.body.classList.add("vjs-pip-window"),this.player_.isInPictureInPicture(!0),this.player_.trigger("enterpictureinpicture"),pipWindow.addEventListener("pagehide",(event=>{const pipVideo=event.target.querySelector(".video-js");pipContainer.parentNode.replaceChild(pipVideo,pipContainer),this.player_.isInPictureInPicture(!1),this.player_.trigger("leavepictureinpicture")})),pipWindow)))}return"pictureInPictureEnabled"in document&&!1===this.disablePictureInPicture()?this.techGet_("requestPictureInPicture"):Promise.reject("No PiP mode is available")}exitPictureInPicture(){return window.documentPictureInPicture&&window.documentPictureInPicture.window?(window.documentPictureInPicture.window.close(),Promise.resolve()):"pictureInPictureEnabled"in document?document.exitPictureInPicture():void 0}handleKeyDown(event){const{userActions:userActions}=this.options_;if(!userActions||!userActions.hotkeys)return;(el=>{const tagName=el.tagName.toLowerCase();if(el.isContentEditable)return!0;if("input"===tagName)return-1===["button","checkbox","hidden","radio","reset","submit"].indexOf(el.type);return-1!==["textarea"].indexOf(tagName)})(this.el_.ownerDocument.activeElement)||("function"==typeof userActions.hotkeys?userActions.hotkeys.call(this,event):this.handleHotkeys(event))}handleHotkeys(event){const hotkeys=this.options_.userActions?this.options_.userActions.hotkeys:{},{fullscreenKey:fullscreenKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"f")),muteKey:muteKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"m")),playPauseKey:playPauseKey=(keydownEvent=>keycode.isEventKey(keydownEvent,"k")||keycode.isEventKey(keydownEvent,"Space"))}=hotkeys;if(fullscreenKey.call(this,event)){event.preventDefault(),event.stopPropagation();const FSToggle=Component$1.getComponent("FullscreenToggle");!1!==document[this.fsApi_.fullscreenEnabled]&&FSToggle.prototype.handleClick.call(this,event)}else if(muteKey.call(this,event)){event.preventDefault(),event.stopPropagation();Component$1.getComponent("MuteToggle").prototype.handleClick.call(this,event)}else if(playPauseKey.call(this,event)){event.preventDefault(),event.stopPropagation();Component$1.getComponent("PlayToggle").prototype.handleClick.call(this,event)}}canPlayType(type){let can;for(let i=0,j=this.options_.techOrder;i[techName,Tech.getTech(techName)])).filter((_ref6=>{let[techName,tech]=_ref6;return tech?tech.isSupported():(log$1.error('The "'.concat(techName,'" tech is undefined. Skipped browser support check for that tech.')),!1)})),findFirstPassingTechSourcePair=function(outerArray,innerArray,tester){let found;return outerArray.some((outerChoice=>innerArray.some((innerChoice=>{if(found=tester(outerChoice,innerChoice),found)return!0})))),found};let foundSourceAndTech;const finder=(_ref7,source)=>{let[techName,tech]=_ref7;if(tech.canPlaySource(source,this.options_[techName.toLowerCase()]))return{source:source,tech:techName}};var fn;return foundSourceAndTech=this.options_.sourceOrder?findFirstPassingTechSourcePair(sources,techs,(fn=finder,(a,b)=>fn(b,a))):findFirstPassingTechSourcePair(techs,sources,finder),foundSourceAndTech||!1}handleSrc_(source,isRetry){if(void 0===source)return this.cache_.src||"";this.resetRetryOnError_&&this.resetRetryOnError_();const sources=filterSource(source);if(sources.length){if(this.changingSrc_=!0,isRetry||(this.cache_.sources=sources),this.updateSourceCaches_(sources[0]),setSource(this,sources[0],((middlewareSource,mws)=>{this.middleware_=mws,isRetry||(this.cache_.sources=sources),this.updateSourceCaches_(middlewareSource);if(this.src_(middlewareSource))return sources.length>1?this.handleSrc_(sources.slice(1)):(this.changingSrc_=!1,this.setTimeout((function(){this.error({code:4,message:this.options_.notSupportedMessage})}),0),void this.triggerReady());var middleware,tech;middleware=mws,tech=this.tech_,middleware.forEach((mw=>mw.setTech&&mw.setTech(tech)))})),sources.length>1){const retry=()=>{this.error(null),this.handleSrc_(sources.slice(1),!0)},stopListeningForErrors=()=>{this.off("error",retry)};this.one("error",retry),this.one("playing",stopListeningForErrors),this.resetRetryOnError_=()=>{this.off("error",retry),this.off("playing",stopListeningForErrors)}}}else this.setTimeout((function(){this.error({code:4,message:this.options_.notSupportedMessage})}),0)}src(source){return this.handleSrc_(source,!1)}src_(source){const sourceTech=this.selectSource([source]);return!sourceTech||(titleCaseEquals(sourceTech.tech,this.techName_)?(this.ready((function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",source):this.techCall_("src",source.src),this.changingSrc_=!1}),!0),!1):(this.changingSrc_=!0,this.loadTech_(sourceTech.tech,sourceTech.source),this.tech_.ready((()=>{this.changingSrc_=!1})),!1))}load(){this.tech_&&this.tech_.vhs?this.src(this.currentSource()):this.techCall_("load")}reset(){if(this.paused())this.doReset_();else{silencePromise(this.play().then((()=>this.doReset_())))}}doReset_(){this.tech_&&this.tech_.clearTracks("text"),this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),this.error(null),this.titleBar&&this.titleBar.update({title:void 0,description:void 0}),isEvented(this)&&this.trigger("playerreset")}resetControlBarUI_(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()}resetProgressBar_(){this.currentTime(0);const{currentTimeDisplay:currentTimeDisplay,durationDisplay:durationDisplay,progressControl:progressControl,remainingTimeDisplay:remainingTimeDisplay}=this.controlBar||{},{seekBar:seekBar}=progressControl||{};currentTimeDisplay&¤tTimeDisplay.updateContent(),durationDisplay&&durationDisplay.updateContent(),remainingTimeDisplay&&remainingTimeDisplay.updateContent(),seekBar&&(seekBar.update(),seekBar.loadProgressBar&&seekBar.loadProgressBar.update())}resetPlaybackRate_(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()}resetVolumeBar_(){this.volume(1),this.trigger("volumechange")}currentSources(){const source=this.currentSource(),sources=[];return 0!==Object.keys(source).length&&sources.push(source),this.cache_.sources||sources}currentSource(){return this.cache_.source||{}}currentSrc(){return this.currentSource()&&this.currentSource().src||""}currentType(){return this.currentSource()&&this.currentSource().type||""}preload(value){return void 0!==value?(this.techCall_("setPreload",value),void(this.options_.preload=value)):this.techGet_("preload")}autoplay(value){if(void 0===value)return this.options_.autoplay||!1;let techAutoplay;"string"==typeof value&&/(any|play|muted)/.test(value)||!0===value&&this.options_.normalizeAutoplay?(this.options_.autoplay=value,this.manualAutoplay_("string"==typeof value?value:"play"),techAutoplay=!1):this.options_.autoplay=!!value,techAutoplay=void 0===techAutoplay?this.options_.autoplay:techAutoplay,this.tech_&&this.techCall_("setAutoplay",techAutoplay)}playsinline(value){return void 0!==value&&(this.techCall_("setPlaysinline",value),this.options_.playsinline=value),this.techGet_("playsinline")}loop(value){return void 0!==value?(this.techCall_("setLoop",value),void(this.options_.loop=value)):this.techGet_("loop")}poster(src){if(void 0===src)return this.poster_;src||(src=""),src!==this.poster_&&(this.poster_=src,this.techCall_("setPoster",src),this.isPosterFromTech_=!1,this.trigger("posterchange"))}handleTechPosterChange_(){if((!this.poster_||this.options_.techCanOverridePoster)&&this.tech_&&this.tech_.poster){const newPoster=this.tech_.poster()||"";newPoster!==this.poster_&&(this.poster_=newPoster,this.isPosterFromTech_=!0,this.trigger("posterchange"))}}controls(bool){if(void 0===bool)return!!this.controls_;bool=!!bool,this.controls_!==bool&&(this.controls_=bool,this.usingNativeControls()&&this.techCall_("setControls",bool),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_()))}usingNativeControls(bool){if(void 0===bool)return!!this.usingNativeControls_;bool=!!bool,this.usingNativeControls_!==bool&&(this.usingNativeControls_=bool,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))}error(err){if(void 0===err)return this.error_||null;if(hooks("beforeerror").forEach((hookFunction=>{const newErr=hookFunction(this,err);isObject$1(newErr)&&!Array.isArray(newErr)||"string"==typeof newErr||"number"==typeof newErr||null===newErr?err=newErr:this.log.error("please return a value that MediaError expects in beforeerror hooks")})),this.options_.suppressNotSupportedError&&err&&4===err.code){const triggerSuppressedError=function(){this.error(err)};return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],triggerSuppressedError),void this.one("loadstart",(function(){this.off(["click","touchstart"],triggerSuppressedError)}))}if(null===err)return this.error_=null,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new MediaError(err),this.addClass("vjs-error"),log$1.error("(CODE:".concat(this.error_.code," ").concat(MediaError.errorTypes[this.error_.code],")"),this.error_.message,this.error_),this.trigger("error"),hooks("error").forEach((hookFunction=>hookFunction(this,this.error_)))}reportUserActivity(event){this.userActivity_=!0}userActive(bool){if(void 0===bool)return this.userActive_;if((bool=!!bool)!==this.userActive_){if(this.userActive_=bool,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")}}listenForUserActivity_(){let mouseInProgress,lastMoveX,lastMoveY;const handleActivity=bind_(this,this.reportUserActivity),handleMouseUpAndMouseLeave=function(event){handleActivity(),this.clearInterval(mouseInProgress)};this.on("mousedown",(function(){handleActivity(),this.clearInterval(mouseInProgress),mouseInProgress=this.setInterval(handleActivity,250)})),this.on("mousemove",(function(e){e.screenX===lastMoveX&&e.screenY===lastMoveY||(lastMoveX=e.screenX,lastMoveY=e.screenY,handleActivity())})),this.on("mouseup",handleMouseUpAndMouseLeave),this.on("mouseleave",handleMouseUpAndMouseLeave);const controlBar=this.getChild("controlBar");let inactivityTimeout;!controlBar||IS_IOS||IS_ANDROID||(controlBar.on("mouseenter",(function(event){0!==this.player().options_.inactivityTimeout&&(this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout),this.player().options_.inactivityTimeout=0})),controlBar.on("mouseleave",(function(event){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout}))),this.on("keydown",handleActivity),this.on("keyup",handleActivity);this.setInterval((function(){if(!this.userActivity_)return;this.userActivity_=!1,this.userActive(!0),this.clearTimeout(inactivityTimeout);const timeout=this.options_.inactivityTimeout;timeout<=0||(inactivityTimeout=this.setTimeout((function(){this.userActivity_||this.userActive(!1)}),timeout))}),250)}playbackRate(rate){if(void 0===rate)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",rate)}defaultPlaybackRate(rate){return void 0!==rate?this.techCall_("setDefaultPlaybackRate",rate):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1}isAudio(bool){if(void 0===bool)return!!this.isAudio_;this.isAudio_=!!bool}enableAudioOnlyUI_(){this.addClass("vjs-audio-only-mode");const playerChildren=this.children(),controlBar=this.getChild("ControlBar"),controlBarHeight=controlBar&&controlBar.currentHeight();playerChildren.forEach((child=>{child!==controlBar&&child.el_&&!child.hasClass("vjs-hidden")&&(child.hide(),this.audioOnlyCache_.hiddenChildren.push(child))})),this.audioOnlyCache_.playerHeight=this.currentHeight(),this.height(controlBarHeight),this.trigger("audioonlymodechange")}disableAudioOnlyUI_(){this.removeClass("vjs-audio-only-mode"),this.audioOnlyCache_.hiddenChildren.forEach((child=>child.show())),this.height(this.audioOnlyCache_.playerHeight),this.trigger("audioonlymodechange")}audioOnlyMode(value){if("boolean"!=typeof value||value===this.audioOnlyMode_)return this.audioOnlyMode_;if(this.audioOnlyMode_=value,value){const exitPromises=[];return this.isInPictureInPicture()&&exitPromises.push(this.exitPictureInPicture()),this.isFullscreen()&&exitPromises.push(this.exitFullscreen()),this.audioPosterMode()&&exitPromises.push(this.audioPosterMode(!1)),Promise.all(exitPromises).then((()=>this.enableAudioOnlyUI_()))}return Promise.resolve().then((()=>this.disableAudioOnlyUI_()))}enablePosterModeUI_(){(this.tech_&&this.tech_).hide(),this.addClass("vjs-audio-poster-mode"),this.trigger("audiopostermodechange")}disablePosterModeUI_(){(this.tech_&&this.tech_).show(),this.removeClass("vjs-audio-poster-mode"),this.trigger("audiopostermodechange")}audioPosterMode(value){if("boolean"!=typeof value||value===this.audioPosterMode_)return this.audioPosterMode_;if(this.audioPosterMode_=value,value){if(this.audioOnlyMode()){return this.audioOnlyMode(!1).then((()=>{this.enablePosterModeUI_()}))}return Promise.resolve().then((()=>{this.enablePosterModeUI_()}))}return Promise.resolve().then((()=>{this.disablePosterModeUI_()}))}addTextTrack(kind,label,language){if(this.tech_)return this.tech_.addTextTrack(kind,label,language)}addRemoteTextTrack(options,manualCleanup){if(this.tech_)return this.tech_.addRemoteTextTrack(options,manualCleanup)}removeRemoteTextTrack(){let obj=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{track:track}=obj;if(track||(track=obj),this.tech_)return this.tech_.removeRemoteTextTrack(track)}getVideoPlaybackQuality(){return this.techGet_("getVideoPlaybackQuality")}videoWidth(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0}videoHeight(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0}language(code){if(void 0===code)return this.language_;this.language_!==String(code).toLowerCase()&&(this.language_=String(code).toLowerCase(),isEvented(this)&&this.trigger("languagechange"))}languages(){return merge$2(Player.prototype.options_.languages,this.languages_)}toJSON(){const options=merge$2(this.options_),tracks=options.tracks;options.tracks=[];for(let i=0;i{this.removeChild(modal)})),modal.open(),modal}updateCurrentBreakpoint_(){if(!this.responsive())return;const currentBreakpoint=this.currentBreakpoint(),currentWidth=this.currentWidth();for(let i=0;ithis.addRemoteTextTrack(tt,!1))),this.titleBar&&this.titleBar.update({title:title,description:description||artist||""}),this.ready(ready)}getMedia(){if(!this.cache_.media){const poster=this.poster(),media={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),(tt=>({kind:tt.kind,label:tt.label,language:tt.language,src:tt.src})))};return poster&&(media.poster=poster,media.artwork=[{src:media.poster,type:getMimetype(media.poster)}]),media}return merge$2(this.cache_.media)}static getTagSettings(tag){const baseOptions={sources:[],tracks:[]},tagOptions=getAttributes(tag),dataSetup=tagOptions["data-setup"];if(hasClass(tag,"vjs-fill")&&(tagOptions.fill=!0),hasClass(tag,"vjs-fluid")&&(tagOptions.fluid=!0),null!==dataSetup){const[err,data]=tuple(dataSetup||"{}");err&&log$1.error(err),Object.assign(tagOptions,data)}if(Object.assign(baseOptions,tagOptions),tag.hasChildNodes()){const children=tag.childNodes;for(let i=0,j=children.length;i"number"==typeof rate))&&(this.cache_.playbackRates=newRates,this.trigger("playbackrateschange"))}}ALL.names.forEach((function(name){const props=ALL[name];Player.prototype[props.getterName]=function(){return this.tech_?this.tech_[props.getterName]():(this[props.privateName]=this[props.privateName]||new props.ListClass,this[props.privateName])}})),Player.prototype.crossorigin=Player.prototype.crossOrigin,Player.players={};const navigator=window.navigator;Player.prototype.options_={techOrder:Tech.defaultTechOrder_,html5:{},enableSourceset:!0,inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","titleBar","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:navigator&&(navigator.languages&&navigator.languages[0]||navigator.userLanguage||navigator.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",normalizeAutoplay:!1,fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1,audioOnlyMode:!1,audioPosterMode:!1,enableSmoothSeeking:!1},TECH_EVENTS_RETRIGGER.forEach((function(event){Player.prototype["handleTech".concat(toTitleCase$1(event),"_")]=function(){return this.trigger(event)}})),Component$1.registerComponent("Player",Player);const pluginStorage={},pluginExists=name=>pluginStorage.hasOwnProperty(name),getPlugin=name=>pluginExists(name)?pluginStorage[name]:void 0,markPluginAsActive=(player,name)=>{player.activePlugins_=player.activePlugins_||{},player.activePlugins_[name]=!0},triggerSetupEvent=(player,hash,before)=>{const eventName=(before?"before":"")+"pluginsetup";player.trigger(eventName,hash),player.trigger(eventName+":"+hash.name,hash)},createPluginFactory=(name,PluginSubClass)=>(PluginSubClass.prototype.name=name,function(){triggerSetupEvent(this,{name:name,plugin:PluginSubClass,instance:null},!0);for(var _len21=arguments.length,args=new Array(_len21),_key21=0;_key21<_len21;_key21++)args[_key21]=arguments[_key21];const instance=new PluginSubClass(...[this,...args]);return this[name]=()=>instance,triggerSetupEvent(this,instance.getEventHash()),instance});class Plugin{constructor(player){if(this.constructor===Plugin)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=player,this.log||(this.log=this.player.log.createLogger(this.name)),evented(this),delete this.trigger,stateful(this,this.constructor.defaultState),markPluginAsActive(player,this.name),this.dispose=this.dispose.bind(this),player.on("dispose",this.dispose)}version(){return this.constructor.VERSION}getEventHash(){let hash=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return hash.name=this.name,hash.plugin=this.constructor,hash.instance=this,hash}trigger(event){let hash=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return trigger(this.eventBusEl_,event,this.getEventHash(hash))}handleStateChanged(e){}dispose(){const{name:name,player:player}=this;this.trigger("dispose"),this.off(),player.off("dispose",this.dispose),player.activePlugins_[name]=!1,this.player=this.state=null,player[name]=createPluginFactory(name,pluginStorage[name])}static isBasic(plugin){const p="string"==typeof plugin?getPlugin(plugin):plugin;return"function"==typeof p&&!Plugin.prototype.isPrototypeOf(p.prototype)}static registerPlugin(name,plugin){if("string"!=typeof name)throw new Error('Illegal plugin name, "'.concat(name,'", must be a string, was ').concat(typeof name,"."));if(pluginExists(name))log$1.warn('A plugin named "'.concat(name,'" already exists. You may want to avoid re-registering plugins!'));else if(Player.prototype.hasOwnProperty(name))throw new Error('Illegal plugin name, "'.concat(name,'", cannot share a name with an existing player method!'));if("function"!=typeof plugin)throw new Error('Illegal plugin for "'.concat(name,'", must be a function, was ').concat(typeof plugin,"."));return pluginStorage[name]=plugin,"plugin"!==name&&(Plugin.isBasic(plugin)?Player.prototype[name]=function(name,plugin){const basicPluginWrapper=function(){triggerSetupEvent(this,{name:name,plugin:plugin,instance:null},!0);const instance=plugin.apply(this,arguments);return markPluginAsActive(this,name),triggerSetupEvent(this,{name:name,plugin:plugin,instance:instance}),instance};return Object.keys(plugin).forEach((function(prop){basicPluginWrapper[prop]=plugin[prop]})),basicPluginWrapper}(name,plugin):Player.prototype[name]=createPluginFactory(name,plugin)),plugin}static deregisterPlugin(name){if("plugin"===name)throw new Error("Cannot de-register base plugin.");pluginExists(name)&&(delete pluginStorage[name],delete Player.prototype[name])}static getPlugins(){let result;return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:Object.keys(pluginStorage)).forEach((name=>{const plugin=getPlugin(name);plugin&&(result=result||{},result[name]=plugin)})),result}static getPluginVersion(name){const plugin=getPlugin(name);return plugin&&plugin.VERSION||""}}function deprecateForMajor(major,oldName,newName,fn){return function(message,fn){let warned=!1;return function(){warned||log$1.warn(message),warned=!0;for(var _len22=arguments.length,args=new Array(_len22),_key22=0;_key22<_len22;_key22++)args[_key22]=arguments[_key22];return fn.apply(this,args)}}("".concat(oldName," is deprecated and will be removed in ").concat(major,".0; please use ").concat(newName," instead."),fn)}Plugin.getPlugin=getPlugin,Plugin.BASE_PLUGIN_NAME="plugin",Plugin.registerPlugin("plugin",Plugin),Player.prototype.usingPlugin=function(name){return!!this.activePlugins_&&!0===this.activePlugins_[name]},Player.prototype.hasPlugin=function(name){return!!pluginExists(name)};const normalizeId=id=>0===id.indexOf("#")?id.slice(1):id;function videojs(id,options,ready){let player=videojs.getPlayer(id);if(player)return options&&log$1.warn('Player "'.concat(id,'" is already initialised. Options will not be applied.')),ready&&player.ready(ready),player;const el="string"==typeof id?$("#"+normalizeId(id)):id;if(!isEl(el))throw new TypeError("The element or ID supplied is not valid. (videojs)");const rootNode="getRootNode"in el&&el.getRootNode()instanceof window.ShadowRoot?el.getRootNode():el.ownerDocument.body;el.ownerDocument.defaultView&&rootNode.contains(el)||log$1.warn("The element supplied is not included in the DOM"),!0===(options=options||{}).restoreEl&&(options.restoreEl=(el.parentNode&&el.parentNode.hasAttribute("data-vjs-player")?el.parentNode:el).cloneNode(!0)),hooks("beforesetup").forEach((hookFunction=>{const opts=hookFunction(el,merge$2(options));isObject$1(opts)&&!Array.isArray(opts)?options=merge$2(options,opts):log$1.error("please return an object in beforesetup hooks")}));const PlayerComponent=Component$1.getComponent("Player");return player=new PlayerComponent(el,options,ready),hooks("setup").forEach((hookFunction=>hookFunction(player))),player}if(videojs.hooks_=hooks_,videojs.hooks=hooks,videojs.hook=function(type,fn){hooks(type,fn)},videojs.hookOnce=function(type,fn){hooks(type,[].concat(fn).map((original=>{const wrapper=function(){return removeHook(type,wrapper),original(...arguments)};return wrapper})))},videojs.removeHook=removeHook,!0!==window.VIDEOJS_NO_DYNAMIC_STYLE&&isReal()){let style=$(".vjs-styles-defaults");if(!style){style=createStyleElement("vjs-styles-defaults");const head=$("head");head&&head.insertBefore(style,head.firstChild),setTextContent(style,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid:not(.vjs-audio-only-mode) {\n padding-top: 56.25%\n }\n ")}}autoSetupTimeout(1,videojs),videojs.VERSION="8.10.0",videojs.options=Player.prototype.options_,videojs.getPlayers=()=>Player.players,videojs.getPlayer=id=>{const players=Player.players;let tag;if("string"==typeof id){const nId=normalizeId(id),player=players[nId];if(player)return player;tag=$("#"+nId)}else tag=id;if(isEl(tag)){const{player:player,playerId:playerId}=tag;if(player||players[playerId])return player||players[playerId]}},videojs.getAllPlayers=()=>Object.keys(Player.players).map((k=>Player.players[k])).filter(Boolean),videojs.players=Player.players,videojs.getComponent=Component$1.getComponent,videojs.registerComponent=(name,comp)=>(Tech.isTech(comp)&&log$1.warn("The ".concat(name," tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)")),Component$1.registerComponent.call(Component$1,name,comp)),videojs.getTech=Tech.getTech,videojs.registerTech=Tech.registerTech,videojs.use=function(type,middleware){middlewares[type]=middlewares[type]||[],middlewares[type].push(middleware)},Object.defineProperty(videojs,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(videojs.middleware,"TERMINATOR",{value:TERMINATOR,writeable:!1,enumerable:!0}),videojs.browser=browser,videojs.obj=Obj,videojs.mergeOptions=deprecateForMajor(9,"videojs.mergeOptions","videojs.obj.merge",merge$2),videojs.defineLazyProperty=deprecateForMajor(9,"videojs.defineLazyProperty","videojs.obj.defineLazyProperty",defineLazyProperty),videojs.bind=deprecateForMajor(9,"videojs.bind","native Function.prototype.bind",bind_),videojs.registerPlugin=Plugin.registerPlugin,videojs.deregisterPlugin=Plugin.deregisterPlugin,videojs.plugin=(name,plugin)=>(log$1.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),Plugin.registerPlugin(name,plugin)),videojs.getPlugins=Plugin.getPlugins,videojs.getPlugin=Plugin.getPlugin,videojs.getPluginVersion=Plugin.getPluginVersion,videojs.addLanguage=function(code,data){return code=(""+code).toLowerCase(),videojs.options.languages=merge$2(videojs.options.languages,{[code]:data}),videojs.options.languages[code]},videojs.log=log$1,videojs.createLogger=createLogger,videojs.time=Time,videojs.createTimeRange=deprecateForMajor(9,"videojs.createTimeRange","videojs.time.createTimeRanges",createTimeRanges$1),videojs.createTimeRanges=deprecateForMajor(9,"videojs.createTimeRanges","videojs.time.createTimeRanges",createTimeRanges$1),videojs.formatTime=deprecateForMajor(9,"videojs.formatTime","videojs.time.formatTime",formatTime),videojs.setFormatTime=deprecateForMajor(9,"videojs.setFormatTime","videojs.time.setFormatTime",setFormatTime),videojs.resetFormatTime=deprecateForMajor(9,"videojs.resetFormatTime","videojs.time.resetFormatTime",resetFormatTime),videojs.parseUrl=deprecateForMajor(9,"videojs.parseUrl","videojs.url.parseUrl",parseUrl),videojs.isCrossOrigin=deprecateForMajor(9,"videojs.isCrossOrigin","videojs.url.isCrossOrigin",isCrossOrigin),videojs.EventTarget=EventTarget$2,videojs.any=any,videojs.on=on,videojs.one=one,videojs.off=off,videojs.trigger=trigger,videojs.xhr=lib,videojs.TextTrack=TextTrack,videojs.AudioTrack=AudioTrack,videojs.VideoTrack=VideoTrack,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach((k=>{videojs[k]=function(){return log$1.warn("videojs.".concat(k,"() is deprecated; use videojs.dom.").concat(k,"() instead")),Dom[k].apply(null,arguments)}})),videojs.computedStyle=deprecateForMajor(9,"videojs.computedStyle","videojs.dom.computedStyle",computedStyle),videojs.dom=Dom,videojs.fn=Fn,videojs.num=Num,videojs.str=Str,videojs.url=Url,createCommonjsModule((function(module,exports){ +/*! @name videojs-contrib-quality-levels @version 4.0.0 @license Apache-2.0 */ +module.exports=function(videojs){function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var videojs__default=_interopDefaultLegacy(videojs);class QualityLevel{constructor(representation){let level=this;return level.id=representation.id,level.label=level.id,level.width=representation.width,level.height=representation.height,level.bitrate=representation.bandwidth,level.frameRate=representation.frameRate,level.enabled_=representation.enabled,Object.defineProperty(level,"enabled",{get:()=>level.enabled_(),set(enable){level.enabled_(enable)}}),level}}class QualityLevelList extends videojs__default.default.EventTarget{constructor(){super();let list=this;return list.levels_=[],list.selectedIndex_=-1,Object.defineProperty(list,"selectedIndex",{get:()=>list.selectedIndex_}),Object.defineProperty(list,"length",{get:()=>list.levels_.length}),list[Symbol.iterator]=()=>list.levels_.values(),list}addQualityLevel(representation){let qualityLevel=this.getQualityLevelById(representation.id);if(qualityLevel)return qualityLevel;const index=this.levels_.length;return qualityLevel=new QualityLevel(representation),""+index in this||Object.defineProperty(this,index,{get(){return this.levels_[index]}}),this.levels_.push(qualityLevel),this.trigger({qualityLevel:qualityLevel,type:"addqualitylevel"}),qualityLevel}removeQualityLevel(qualityLevel){let removed=null;for(let i=0,l=this.length;ii&&this.selectedIndex_--;break}return removed&&this.trigger({qualityLevel:qualityLevel,type:"removequalitylevel"}),removed}getQualityLevelById(id){for(let i=0,l=this.length;iqualityLevelList,player.qualityLevels.VERSION=version,qualityLevelList},qualityLevels=function(options){return initPlugin(this,videojs__default.default.obj.merge({},options))};return videojs__default.default.registerPlugin("qualityLevels",qualityLevels),qualityLevels.VERSION=version,qualityLevels}(videojs)}));var urlToolkit=createCommonjsModule((function(module,exports){var URL_REGEX,FIRST_SEGMENT_REGEX,SLASH_DOT_REGEX,SLASH_DOT_DOT_REGEX,URLToolkit;URL_REGEX=/^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/,FIRST_SEGMENT_REGEX=/^(?=([^\/?#]*))\1([^]*)$/,SLASH_DOT_REGEX=/(?:\/|^)\.(?=\/)/g,SLASH_DOT_DOT_REGEX=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,URLToolkit={buildAbsoluteURL:function(baseURL,relativeURL,opts){if(opts=opts||{},baseURL=baseURL.trim(),!(relativeURL=relativeURL.trim())){if(!opts.alwaysNormalize)return baseURL;var basePartsForNormalise=URLToolkit.parseURL(baseURL);if(!basePartsForNormalise)throw new Error("Error trying to parse base URL.");return basePartsForNormalise.path=URLToolkit.normalizePath(basePartsForNormalise.path),URLToolkit.buildURLFromParts(basePartsForNormalise)}var relativeParts=URLToolkit.parseURL(relativeURL);if(!relativeParts)throw new Error("Error trying to parse relative URL.");if(relativeParts.scheme)return opts.alwaysNormalize?(relativeParts.path=URLToolkit.normalizePath(relativeParts.path),URLToolkit.buildURLFromParts(relativeParts)):relativeURL;var baseParts=URLToolkit.parseURL(baseURL);if(!baseParts)throw new Error("Error trying to parse base URL.");if(!baseParts.netLoc&&baseParts.path&&"/"!==baseParts.path[0]){var pathParts=FIRST_SEGMENT_REGEX.exec(baseParts.path);baseParts.netLoc=pathParts[1],baseParts.path=pathParts[2]}baseParts.netLoc&&!baseParts.path&&(baseParts.path="/");var builtParts={scheme:baseParts.scheme,netLoc:relativeParts.netLoc,path:null,params:relativeParts.params,query:relativeParts.query,fragment:relativeParts.fragment};if(!relativeParts.netLoc&&(builtParts.netLoc=baseParts.netLoc,"/"!==relativeParts.path[0]))if(relativeParts.path){var baseURLPath=baseParts.path,newPath=baseURLPath.substring(0,baseURLPath.lastIndexOf("/")+1)+relativeParts.path;builtParts.path=URLToolkit.normalizePath(newPath)}else builtParts.path=baseParts.path,relativeParts.params||(builtParts.params=baseParts.params,relativeParts.query||(builtParts.query=baseParts.query));return null===builtParts.path&&(builtParts.path=opts.alwaysNormalize?URLToolkit.normalizePath(relativeParts.path):relativeParts.path),URLToolkit.buildURLFromParts(builtParts)},parseURL:function(url){var parts=URL_REGEX.exec(url);return parts?{scheme:parts[1]||"",netLoc:parts[2]||"",path:parts[3]||"",params:parts[4]||"",query:parts[5]||"",fragment:parts[6]||""}:null},normalizePath:function(path){for(path=path.split("").reverse().join("").replace(SLASH_DOT_REGEX,"");path.length!==(path=path.replace(SLASH_DOT_DOT_REGEX,"")).length;);return path.split("").reverse().join("")},buildURLFromParts:function(parts){return parts.scheme+parts.netLoc+parts.path+parts.params+parts.query+parts.fragment}},module.exports=URLToolkit})),resolveUrl$1=function(baseUrl,relativeUrl){if(/^[a-z]+:/i.test(relativeUrl))return relativeUrl;/^data:/.test(baseUrl)&&(baseUrl=window.location&&window.location.href||"");var nativeURL="function"==typeof window.URL,protocolLess=/^\/\//.test(baseUrl),removeLocation=!window.location&&!/\/\//i.test(baseUrl);if(nativeURL?baseUrl=new window.URL(baseUrl,window.location||"http://example.com"):/\/\//i.test(baseUrl)||(baseUrl=urlToolkit.buildAbsoluteURL(window.location&&window.location.href||"",baseUrl)),nativeURL){var newUrl=new URL(relativeUrl,baseUrl);return removeLocation?newUrl.href.slice("http://example.com".length):protocolLess?newUrl.href.slice(newUrl.protocol.length):newUrl.href}return urlToolkit.buildAbsoluteURL(baseUrl,relativeUrl)},Stream=function(){function Stream(){this.listeners={}}var _proto=Stream.prototype;return _proto.on=function(type,listener){this.listeners[type]||(this.listeners[type]=[]),this.listeners[type].push(listener)},_proto.off=function(type,listener){if(!this.listeners[type])return!1;var index=this.listeners[type].indexOf(listener);return this.listeners[type]=this.listeners[type].slice(0),this.listeners[type].splice(index,1),index>-1},_proto.trigger=function(type){var callbacks=this.listeners[type];if(callbacks)if(2===arguments.length)for(var length=callbacks.length,i=0;i-1;nextNewline=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,nextNewline)),this.buffer=this.buffer.substring(nextNewline+1)}}const TAB=String.fromCharCode(9),parseByterange=function(byterangeString){const match=/([0-9.]*)?@?([0-9.]*)?/.exec(byterangeString||""),result={};return match[1]&&(result.length=parseInt(match[1],10)),match[2]&&(result.offset=parseInt(match[2],10)),result},parseAttributes$1=function(attributes){const result={};if(!attributes)return result;const attrs=attributes.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))'));let attr,i=attrs.length;for(;i--;)""!==attrs[i]&&(attr=/([^=]*)=(.*)/.exec(attrs[i]).slice(1),attr[0]=attr[0].replace(/^\s+|\s+$/g,""),attr[1]=attr[1].replace(/^\s+|\s+$/g,""),attr[1]=attr[1].replace(/^['"](.*)['"]$/g,"$1"),result[attr[0]]=attr[1]);return result};class ParseStream extends Stream{constructor(){super(),this.customParsers=[],this.tagMappers=[]}push(line){let match,event;if(0===(line=line.trim()).length)return;if("#"!==line[0])return void this.trigger("data",{type:"uri",uri:line});this.tagMappers.reduce(((acc,mapper)=>{const mappedLine=mapper(line);return mappedLine===line?acc:acc.concat([mappedLine])}),[line]).forEach((newLine=>{for(let i=0;iline),this.customParsers.push((line=>{if(expression.exec(line))return this.trigger("data",{type:"custom",data:dataParser(line),customType:customType,segment:segment}),!0}))}addTagMapper(_ref9){let{expression:expression,map:map}=_ref9;this.tagMappers.push((line=>expression.test(line)?map(line):line))}}const camelCaseKeys=function(attributes){const result={};return Object.keys(attributes).forEach((function(key){var str;result[(str=key,str.toLowerCase().replace(/-(\w)/g,(a=>a[1].toUpperCase())))]=attributes[key]})),result},setHoldBack=function(manifest){const{serverControl:serverControl,targetDuration:targetDuration,partTargetDuration:partTargetDuration}=manifest;if(!serverControl)return;const tag="#EXT-X-SERVER-CONTROL",hb="holdBack",phb="partHoldBack",minTargetDuration=targetDuration&&3*targetDuration,minPartDuration=partTargetDuration&&2*partTargetDuration;targetDuration&&!serverControl.hasOwnProperty(hb)&&(serverControl[hb]=minTargetDuration,this.trigger("info",{message:"".concat(tag," defaulting HOLD-BACK to targetDuration * 3 (").concat(minTargetDuration,").")})),minTargetDuration&&serverControl[hb]{currentUri.uri||!currentUri.parts&&!currentUri.preloadHints||(!currentUri.map&¤tMap&&(currentUri.map=currentMap),!currentUri.key&&key&&(currentUri.key=key),currentUri.timeline||"number"!=typeof currentTimeline||(currentUri.timeline=currentTimeline),this.manifest.preloadSegment=currentUri)})),this.parseStream.on("data",(function(entry){let mediaGroup,rendition;({tag(){({version(){entry.version&&(this.manifest.version=entry.version)},"allow-cache"(){this.manifest.allowCache=entry.allowed,"allowed"in entry||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange(){const byterange={};"length"in entry&&(currentUri.byterange=byterange,byterange.length=entry.length,"offset"in entry||(entry.offset=lastByterangeEnd)),"offset"in entry&&(currentUri.byterange=byterange,byterange.offset=entry.offset),lastByterangeEnd=byterange.offset+byterange.length},endlist(){this.manifest.endList=!0},inf(){"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"})),entry.title&&(currentUri.title=entry.title),entry.duration>0&&(currentUri.duration=entry.duration),0===entry.duration&&(currentUri.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=uris},key(){if(entry.attributes)if("NONE"!==entry.attributes.METHOD)if(entry.attributes.URI){if("com.apple.streamingkeydelivery"===entry.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:entry.attributes});if("com.microsoft.playready"===entry.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.microsoft.playready"]={uri:entry.attributes.URI});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===entry.attributes.KEYFORMAT){return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(entry.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===entry.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==entry.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):entry.attributes.KEYID&&"0x"===entry.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:entry.attributes.KEYFORMAT,keyId:entry.attributes.KEYID.substring(2)},pssh:decodeB64ToUint8Array$1(entry.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}))}entry.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),key={method:entry.attributes.METHOD||"AES-128",uri:entry.attributes.URI},void 0!==entry.attributes.IV&&(key.iv=entry.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else key=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence"(){isFinite(entry.number)?this.manifest.mediaSequence=entry.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+entry.number})},"discontinuity-sequence"(){isFinite(entry.number)?(this.manifest.discontinuitySequence=entry.number,currentTimeline=entry.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+entry.number})},"playlist-type"(){/VOD|EVENT/.test(entry.playlistType)?this.manifest.playlistType=entry.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+entry.playlist})},map(){currentMap={},entry.uri&&(currentMap.uri=entry.uri),entry.byterange&&(currentMap.byterange=entry.byterange),key&&(currentMap.key=key)},"stream-inf"(){this.manifest.playlists=uris,this.manifest.mediaGroups=this.manifest.mediaGroups||defaultMediaGroups,entry.attributes?(currentUri.attributes||(currentUri.attributes={}),_extends$1(currentUri.attributes,entry.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||defaultMediaGroups,!(entry.attributes&&entry.attributes.TYPE&&entry.attributes["GROUP-ID"]&&entry.attributes.NAME))return void this.trigger("warn",{message:"ignoring incomplete or missing media group"});const mediaGroupType=this.manifest.mediaGroups[entry.attributes.TYPE];mediaGroupType[entry.attributes["GROUP-ID"]]=mediaGroupType[entry.attributes["GROUP-ID"]]||{},mediaGroup=mediaGroupType[entry.attributes["GROUP-ID"]],rendition={default:/yes/i.test(entry.attributes.DEFAULT)},rendition.default?rendition.autoselect=!0:rendition.autoselect=/yes/i.test(entry.attributes.AUTOSELECT),entry.attributes.LANGUAGE&&(rendition.language=entry.attributes.LANGUAGE),entry.attributes.URI&&(rendition.uri=entry.attributes.URI),entry.attributes["INSTREAM-ID"]&&(rendition.instreamId=entry.attributes["INSTREAM-ID"]),entry.attributes.CHARACTERISTICS&&(rendition.characteristics=entry.attributes.CHARACTERISTICS),entry.attributes.FORCED&&(rendition.forced=/yes/i.test(entry.attributes.FORCED)),mediaGroup[entry.attributes.NAME]=rendition},discontinuity(){currentTimeline+=1,currentUri.discontinuity=!0,this.manifest.discontinuityStarts.push(uris.length)},"program-date-time"(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=entry.dateTimeString,this.manifest.dateTimeObject=entry.dateTimeObject),currentUri.dateTimeString=entry.dateTimeString,currentUri.dateTimeObject=entry.dateTimeObject;const{lastProgramDateTime:lastProgramDateTime}=this;this.lastProgramDateTime=new Date(entry.dateTimeString).getTime(),null===lastProgramDateTime&&this.manifest.segments.reduceRight(((programDateTime,segment)=>(segment.programDateTime=programDateTime-1e3*segment.duration,segment.programDateTime)),this.lastProgramDateTime)},targetduration(){!isFinite(entry.duration)||entry.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+entry.duration}):(this.manifest.targetDuration=entry.duration,setHoldBack.call(this,this.manifest))},start(){entry.attributes&&!isNaN(entry.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:entry.attributes["TIME-OFFSET"],precise:entry.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out"(){currentUri.cueOut=entry.data},"cue-out-cont"(){currentUri.cueOutCont=entry.data},"cue-in"(){currentUri.cueIn=entry.data},skip(){this.manifest.skip=camelCaseKeys(entry.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",entry.attributes,["SKIPPED-SEGMENTS"])},part(){hasParts=!0;const segmentIndex=this.manifest.segments.length,part=camelCaseKeys(entry.attributes);currentUri.parts=currentUri.parts||[],currentUri.parts.push(part),part.byterange&&(part.byterange.hasOwnProperty("offset")||(part.byterange.offset=lastPartByterangeEnd),lastPartByterangeEnd=part.byterange.offset+part.byterange.length);const partIndex=currentUri.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #".concat(partIndex," for segment #").concat(segmentIndex),entry.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach(((r,i)=>{r.hasOwnProperty("lastPart")||this.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #".concat(i," lacks required attribute(s): LAST-PART")})}))},"server-control"(){const attrs=this.manifest.serverControl=camelCaseKeys(entry.attributes);attrs.hasOwnProperty("canBlockReload")||(attrs.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),setHoldBack.call(this,this.manifest),attrs.canSkipDateranges&&!attrs.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"})},"preload-hint"(){const segmentIndex=this.manifest.segments.length,hint=camelCaseKeys(entry.attributes),isPart=hint.type&&"PART"===hint.type;currentUri.preloadHints=currentUri.preloadHints||[],currentUri.preloadHints.push(hint),hint.byterange&&(hint.byterange.hasOwnProperty("offset")||(hint.byterange.offset=isPart?lastPartByterangeEnd:0,isPart&&(lastPartByterangeEnd=hint.byterange.offset+hint.byterange.length)));const index=currentUri.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #".concat(index," for segment #").concat(segmentIndex),entry.attributes,["TYPE","URI"]),hint.type)for(let i=0;idateRangeToFind.id===dateRange.id));this.manifest.dateRanges[dateRangeWithSameId]=_extends$1(this.manifest.dateRanges[dateRangeWithSameId],dateRange),dateRangeTags[dateRange.id]=_extends$1(dateRangeTags[dateRange.id],dateRange),this.manifest.dateRanges.pop()}else dateRangeTags[dateRange.id]=dateRange},"independent-segments"(){this.manifest.independentSegments=!0},"content-steering"(){this.manifest.contentSteering=camelCaseKeys(entry.attributes),this.warnOnMissingAttributes_("#EXT-X-CONTENT-STEERING",entry.attributes,["SERVER-URI"])}}[entry.tagType]||noop).call(self)},uri(){currentUri.uri=entry.uri,uris.push(currentUri),this.manifest.targetDuration&&!("duration"in currentUri)&&(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),currentUri.duration=this.manifest.targetDuration),key&&(currentUri.key=key),currentUri.timeline=currentTimeline,currentMap&&(currentUri.map=currentMap),lastPartByterangeEnd=0,null!==this.lastProgramDateTime&&(currentUri.programDateTime=this.lastProgramDateTime,this.lastProgramDateTime+=1e3*currentUri.duration),currentUri={}},comment(){},custom(){entry.segment?(currentUri.custom=currentUri.custom||{},currentUri.custom[entry.customType]=entry.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[entry.customType]=entry.data)}})[entry.type].call(self)}))}warnOnMissingAttributes_(identifier,attributes,required){const missing=[];required.forEach((function(key){attributes.hasOwnProperty(key)||missing.push(key)})),missing.length&&this.trigger("warn",{message:"".concat(identifier," lacks required attribute(s): ").concat(missing.join(", "))})}push(chunk){this.lineStream.push(chunk)}end(){this.lineStream.push("\n"),this.manifest.dateRanges.length&&null===this.lastProgramDateTime&&this.trigger("warn",{message:"A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag"}),this.lastProgramDateTime=null,this.trigger("end")}addParser(options){this.parseStream.addParser(options)}addTagMapper(options){this.parseStream.addTagMapper(options)}}var a,b,regexs={mp4:/^(av0?1|avc0?[1234]|vp0?9|flac|opus|mp3|mp4a|mp4v|stpp.ttml.im1t)/,webm:/^(vp0?[89]|av0?1|opus|vorbis)/,ogg:/^(vp0?[89]|theora|flac|opus|vorbis)/,video:/^(av0?1|avc0?[1234]|vp0?[89]|hvc1|hev1|theora|mp4v)/,audio:/^(mp4a|flac|vorbis|opus|ac-[34]|ec-3|alac|mp3|speex|aac)/,text:/^(stpp.ttml.im1t)/,muxerVideo:/^(avc0?1)/,muxerAudio:/^(mp4a)/,muxerText:/a^/},mediaTypes=["video","audio","text"],upperMediaTypes=["Video","Audio","Text"],translateLegacyCodec=function(codec){return codec?codec.replace(/avc1\.(\d+)\.(\d+)/i,(function(orig,profile,avcLevel){return"avc1."+("00"+Number(profile).toString(16)).slice(-2)+"00"+("00"+Number(avcLevel).toString(16)).slice(-2)})):codec},parseCodecs=function(codecString){void 0===codecString&&(codecString="");var codecs=codecString.split(","),result=[];return codecs.forEach((function(codec){var codecType;codec=codec.trim(),mediaTypes.forEach((function(name){var match=regexs[name].exec(codec.toLowerCase());if(match&&!(match.length<=1)){codecType=name;var type=codec.substring(0,match[1].length),details=codec.replace(type,"");result.push({type:type,details:details,mediaType:name})}})),codecType||result.push({type:codec,details:"",mediaType:"unknown"})})),result},isAudioCodec=function(codec){return void 0===codec&&(codec=""),regexs.audio.test(codec.trim().toLowerCase())},getMimeForCodec=function(codecString){if(codecString&&"string"==typeof codecString){var codec,codecs=codecString.toLowerCase().split(",").map((function(c){return translateLegacyCodec(c.trim())})),type="video";1===codecs.length&&isAudioCodec(codecs[0])?type="audio":1===codecs.length&&(void 0===(codec=codecs[0])&&(codec=""),regexs.text.test(codec.trim().toLowerCase()))&&(type="application");var container="mp4";return codecs.every((function(c){return regexs.mp4.test(c)}))?container="mp4":codecs.every((function(c){return regexs.webm.test(c)}))?container="webm":codecs.every((function(c){return regexs.ogg.test(c)}))&&(container="ogg"),type+"/"+container+';codecs="'+codecString+'"'}},browserSupportsCodec=function(codecString){return void 0===codecString&&(codecString=""),window.MediaSource&&window.MediaSource.isTypeSupported&&window.MediaSource.isTypeSupported(getMimeForCodec(codecString))||!1},muxerSupportsCodec=function(codecString){return void 0===codecString&&(codecString=""),codecString.toLowerCase().split(",").every((function(codec){codec=codec.trim();for(var i=0;imax&&(number-=max,number-=max,number-=BigInt(2))}return Number(number)},numberToBytes=function(number,_temp2){var _ref2$le=(void 0===_temp2?{}:_temp2).le,le=void 0!==_ref2$le&&_ref2$le;("bigint"!=typeof number&&"number"!=typeof number||"number"==typeof number&&number!=number)&&(number=0);for(var byteCount=function(x){return Math.ceil(function(x){return x.toString(2).length}(x)/8)}(number=BigInt(number)),bytes=new Uint8Array(new ArrayBuffer(byteCount)),i=0;i=b.length&&fn.call(b,(function(bByte,i){return bByte===(mask[i]?mask[i]&a[offset+i]:a[offset+i])}))};function decodeB64ToUint8Array(b64Text){for(var s,decodedString=(s=b64Text,window.atob?window.atob(s):Buffer.from(s,"base64").toString("binary")),array=new Uint8Array(decodedString.length),i=0;i=0))throw new DOMException(NOT_FOUND_ERR,new Error(el.tagName+"@"+attr));for(var lastIndex=list.length-1;i"==c&&">")||"&"==c&&"&"||'"'==c&&"""||"&#"+c.charCodeAt()+";"}function _visitNode(node,callback){if(callback(node))return!0;if(node=node.firstChild)do{if(_visitNode(node,callback))return!0}while(node=node.nextSibling)}function Document(){this.ownerDocument=this}function _onRemoveAttribute(doc,el,newAttr,remove){doc&&doc._inc++,newAttr.namespaceURI===NAMESPACE$2.XMLNS&&delete el._nsMap[newAttr.prefix?newAttr.localName:""]}function _onUpdateChild(doc,el,newChild){if(doc&&doc._inc){doc._inc++;var cs=el.childNodes;if(newChild)cs[cs.length++]=newChild;else{for(var child=el.firstChild,i=0;child;)cs[i++]=child,child=child.nextSibling;cs.length=i,delete cs[cs.length]}}}function _removeChild(parentNode,child){var previous=child.previousSibling,next=child.nextSibling;return previous?previous.nextSibling=next:parentNode.firstChild=next,next?next.previousSibling=previous:parentNode.lastChild=previous,child.parentNode=null,child.previousSibling=null,child.nextSibling=null,_onUpdateChild(parentNode.ownerDocument,parentNode),child}function isDocTypeNode(node){return node&&node.nodeType===Node.DOCUMENT_TYPE_NODE}function isElementNode(node){return node&&node.nodeType===Node.ELEMENT_NODE}function isTextNode(node){return node&&node.nodeType===Node.TEXT_NODE}function isElementInsertionPossible(doc,child){var parentChildNodes=doc.childNodes||[];if(find(parentChildNodes,isElementNode)||isDocTypeNode(child))return!1;var docTypeNode=find(parentChildNodes,isDocTypeNode);return!(child&&docTypeNode&&parentChildNodes.indexOf(docTypeNode)>parentChildNodes.indexOf(child))}function isElementReplacementPossible(doc,child){var parentChildNodes=doc.childNodes||[];if(find(parentChildNodes,(function(node){return isElementNode(node)&&node!==child})))return!1;var docTypeNode=find(parentChildNodes,isDocTypeNode);return!(child&&docTypeNode&&parentChildNodes.indexOf(docTypeNode)>parentChildNodes.indexOf(child))}function assertPreInsertionValidity1to5(parent,node,child){if(!function(node){return node&&(node.nodeType===Node.DOCUMENT_NODE||node.nodeType===Node.DOCUMENT_FRAGMENT_NODE||node.nodeType===Node.ELEMENT_NODE)}(parent))throw new DOMException(HIERARCHY_REQUEST_ERR,"Unexpected parent node type "+parent.nodeType);if(child&&child.parentNode!==parent)throw new DOMException(NOT_FOUND_ERR,"child not in parent");if(!function(node){return node&&(isElementNode(node)||isTextNode(node)||isDocTypeNode(node)||node.nodeType===Node.DOCUMENT_FRAGMENT_NODE||node.nodeType===Node.COMMENT_NODE||node.nodeType===Node.PROCESSING_INSTRUCTION_NODE)}(node)||isDocTypeNode(node)&&parent.nodeType!==Node.DOCUMENT_NODE)throw new DOMException(HIERARCHY_REQUEST_ERR,"Unexpected node type "+node.nodeType+" for parent node type "+parent.nodeType)}function assertPreInsertionValidityInDocument(parent,node,child){var parentChildNodes=parent.childNodes||[],nodeChildNodes=node.childNodes||[];if(node.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var nodeChildElements=nodeChildNodes.filter(isElementNode);if(nodeChildElements.length>1||find(nodeChildNodes,isTextNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"More than one element or text in fragment");if(1===nodeChildElements.length&&!isElementInsertionPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Element in fragment can not be inserted before doctype")}if(isElementNode(node)&&!isElementInsertionPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one element can be added and only after doctype");if(isDocTypeNode(node)){if(find(parentChildNodes,isDocTypeNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one doctype is allowed");var parentElementChild=find(parentChildNodes,isElementNode);if(child&&parentChildNodes.indexOf(parentElementChild)1||find(nodeChildNodes,isTextNode))throw new DOMException(HIERARCHY_REQUEST_ERR,"More than one element or text in fragment");if(1===nodeChildElements.length&&!isElementReplacementPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Element in fragment can not be inserted before doctype")}if(isElementNode(node)&&!isElementReplacementPossible(parent,child))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one element can be added and only after doctype");if(isDocTypeNode(node)){function hasDoctypeChildThatIsNotChild(node){return isDocTypeNode(node)&&node!==child}if(find(parentChildNodes,hasDoctypeChildThatIsNotChild))throw new DOMException(HIERARCHY_REQUEST_ERR,"Only one doctype is allowed");var parentElementChild=find(parentChildNodes,isElementNode);if(child&&parentChildNodes.indexOf(parentElementChild)=0;nsi--){if(""===(namespace=visibleNamespaces[nsi]).prefix&&namespace.namespace===node.namespaceURI){defaultNS=namespace.namespace;break}}if(defaultNS!==node.namespaceURI)for(nsi=visibleNamespaces.length-1;nsi>=0;nsi--){var namespace;if((namespace=visibleNamespaces[nsi]).namespace===node.namespaceURI){namespace.prefix&&(prefixedNodeName=namespace.prefix+":"+nodeName);break}}}buf.push("<",prefixedNodeName);for(var i=0;i"),isHTML&&/^script$/i.test(nodeName))for(;child;)child.data?buf.push(child.data):serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;else for(;child;)serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;buf.push("")}else buf.push("/>");return;case DOCUMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(child=node.firstChild;child;)serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces.slice()),child=child.nextSibling;return;case ATTRIBUTE_NODE:return addSerializedAttribute(buf,node.name,node.value);case TEXT_NODE:return buf.push(node.data.replace(/[<&>]/g,_xmlEncoder));case CDATA_SECTION_NODE:return buf.push("");case COMMENT_NODE:return buf.push("\x3c!--",node.data,"--\x3e");case DOCUMENT_TYPE_NODE:var pubid=node.publicId,sysid=node.systemId;if(buf.push("");else if(sysid&&"."!=sysid)buf.push(" SYSTEM ",sysid,">");else{var sub=node.internalSubset;sub&&buf.push(" [",sub,"]"),buf.push(">")}return;case PROCESSING_INSTRUCTION_NODE:return buf.push("");case ENTITY_REFERENCE_NODE:return buf.push("&",node.nodeName,";");default:buf.push("??",node.nodeName)}}function importNode(doc,node,deep){var node2;switch(node.nodeType){case ELEMENT_NODE:(node2=node.cloneNode(!1)).ownerDocument=doc;case DOCUMENT_FRAGMENT_NODE:break;case ATTRIBUTE_NODE:deep=!0}if(node2||(node2=node.cloneNode(!1)),node2.ownerDocument=doc,node2.parentNode=null,deep)for(var child=node.firstChild;child;)node2.appendChild(importNode(doc,child,deep)),child=child.nextSibling;return node2}function cloneNode(doc,node,deep){var node2=new node.constructor;for(var n in node)if(Object.prototype.hasOwnProperty.call(node,n)){var v=node[n];"object"!=typeof v&&v!=node2[n]&&(node2[n]=v)}switch(node.childNodes&&(node2.childNodes=new NodeList),node2.ownerDocument=doc,node2.nodeType){case ELEMENT_NODE:var attrs=node.attributes,attrs2=node2.attributes=new NamedNodeMap,len=attrs.length;attrs2._ownerElement=node2;for(var i=0;i=0&&index0},lookupPrefix:function(namespaceURI){for(var el=this;el;){var map=el._nsMap;if(map)for(var n in map)if(Object.prototype.hasOwnProperty.call(map,n)&&map[n]===namespaceURI)return n;el=el.nodeType==ATTRIBUTE_NODE?el.ownerDocument:el.parentNode}return null},lookupNamespaceURI:function(prefix){for(var el=this;el;){var map=el._nsMap;if(map&&Object.prototype.hasOwnProperty.call(map,prefix))return map[prefix];el=el.nodeType==ATTRIBUTE_NODE?el.ownerDocument:el.parentNode}return null},isDefaultNamespace:function(namespaceURI){return null==this.lookupPrefix(namespaceURI)}},copy(NodeType,Node),copy(NodeType,Node.prototype),Document.prototype={nodeName:"#document",nodeType:DOCUMENT_NODE,doctype:null,documentElement:null,_inc:1,insertBefore:function(newChild,refChild){if(newChild.nodeType==DOCUMENT_FRAGMENT_NODE){for(var child=newChild.firstChild;child;){var next=child.nextSibling;this.insertBefore(child,refChild),child=next}return newChild}return _insertBefore(this,newChild,refChild),newChild.ownerDocument=this,null===this.documentElement&&newChild.nodeType===ELEMENT_NODE&&(this.documentElement=newChild),newChild},removeChild:function(oldChild){return this.documentElement==oldChild&&(this.documentElement=null),_removeChild(this,oldChild)},replaceChild:function(newChild,oldChild){_insertBefore(this,newChild,oldChild,assertPreReplacementValidityInDocument),newChild.ownerDocument=this,oldChild&&this.removeChild(oldChild),isElementNode(newChild)&&(this.documentElement=newChild)},importNode:function(importedNode,deep){return importNode(this,importedNode,deep)},getElementById:function(id){var rtv=null;return _visitNode(this.documentElement,(function(node){if(node.nodeType==ELEMENT_NODE&&node.getAttribute("id")==id)return rtv=node,!0})),rtv},getElementsByClassName:function(classNames){var classNamesSet=toOrderedSet(classNames);return new LiveNodeList(this,(function(base){var ls=[];return classNamesSet.length>0&&_visitNode(base.documentElement,(function(node){if(node!==base&&node.nodeType===ELEMENT_NODE){var nodeClassNames=node.getAttribute("class");if(nodeClassNames){var matches=classNames===nodeClassNames;if(!matches){var nodeClassNamesSet=toOrderedSet(nodeClassNames);matches=classNamesSet.every((list=nodeClassNamesSet,function(element){return list&&-1!==list.indexOf(element)}))}matches&&ls.push(node)}}var list})),ls}))},createElement:function(tagName){var node=new Element;return node.ownerDocument=this,node.nodeName=tagName,node.tagName=tagName,node.localName=tagName,node.childNodes=new NodeList,(node.attributes=new NamedNodeMap)._ownerElement=node,node},createDocumentFragment:function(){var node=new DocumentFragment;return node.ownerDocument=this,node.childNodes=new NodeList,node},createTextNode:function(data){var node=new Text;return node.ownerDocument=this,node.appendData(data),node},createComment:function(data){var node=new Comment;return node.ownerDocument=this,node.appendData(data),node},createCDATASection:function(data){var node=new CDATASection;return node.ownerDocument=this,node.appendData(data),node},createProcessingInstruction:function(target,data){var node=new ProcessingInstruction;return node.ownerDocument=this,node.tagName=node.nodeName=node.target=target,node.nodeValue=node.data=data,node},createAttribute:function(name){var node=new Attr;return node.ownerDocument=this,node.name=name,node.nodeName=name,node.localName=name,node.specified=!0,node},createEntityReference:function(name){var node=new EntityReference;return node.ownerDocument=this,node.nodeName=name,node},createElementNS:function(namespaceURI,qualifiedName){var node=new Element,pl=qualifiedName.split(":"),attrs=node.attributes=new NamedNodeMap;return node.childNodes=new NodeList,node.ownerDocument=this,node.nodeName=qualifiedName,node.tagName=qualifiedName,node.namespaceURI=namespaceURI,2==pl.length?(node.prefix=pl[0],node.localName=pl[1]):node.localName=qualifiedName,attrs._ownerElement=node,node},createAttributeNS:function(namespaceURI,qualifiedName){var node=new Attr,pl=qualifiedName.split(":");return node.ownerDocument=this,node.nodeName=qualifiedName,node.name=qualifiedName,node.namespaceURI=namespaceURI,node.specified=!0,2==pl.length?(node.prefix=pl[0],node.localName=pl[1]):node.localName=qualifiedName,node}},_extends(Document,Node),Element.prototype={nodeType:ELEMENT_NODE,hasAttribute:function(name){return null!=this.getAttributeNode(name)},getAttribute:function(name){var attr=this.getAttributeNode(name);return attr&&attr.value||""},getAttributeNode:function(name){return this.attributes.getNamedItem(name)},setAttribute:function(name,value){var attr=this.ownerDocument.createAttribute(name);attr.value=attr.nodeValue=""+value,this.setAttributeNode(attr)},removeAttribute:function(name){var attr=this.getAttributeNode(name);attr&&this.removeAttributeNode(attr)},appendChild:function(newChild){return newChild.nodeType===DOCUMENT_FRAGMENT_NODE?this.insertBefore(newChild,null):function(parentNode,newChild){return newChild.parentNode&&newChild.parentNode.removeChild(newChild),newChild.parentNode=parentNode,newChild.previousSibling=parentNode.lastChild,newChild.nextSibling=null,newChild.previousSibling?newChild.previousSibling.nextSibling=newChild:parentNode.firstChild=newChild,parentNode.lastChild=newChild,_onUpdateChild(parentNode.ownerDocument,parentNode,newChild),newChild}(this,newChild)},setAttributeNode:function(newAttr){return this.attributes.setNamedItem(newAttr)},setAttributeNodeNS:function(newAttr){return this.attributes.setNamedItemNS(newAttr)},removeAttributeNode:function(oldAttr){return this.attributes.removeNamedItem(oldAttr.nodeName)},removeAttributeNS:function(namespaceURI,localName){var old=this.getAttributeNodeNS(namespaceURI,localName);old&&this.removeAttributeNode(old)},hasAttributeNS:function(namespaceURI,localName){return null!=this.getAttributeNodeNS(namespaceURI,localName)},getAttributeNS:function(namespaceURI,localName){var attr=this.getAttributeNodeNS(namespaceURI,localName);return attr&&attr.value||""},setAttributeNS:function(namespaceURI,qualifiedName,value){var attr=this.ownerDocument.createAttributeNS(namespaceURI,qualifiedName);attr.value=attr.nodeValue=""+value,this.setAttributeNode(attr)},getAttributeNodeNS:function(namespaceURI,localName){return this.attributes.getNamedItemNS(namespaceURI,localName)},getElementsByTagName:function(tagName){return new LiveNodeList(this,(function(base){var ls=[];return _visitNode(base,(function(node){node===base||node.nodeType!=ELEMENT_NODE||"*"!==tagName&&node.tagName!=tagName||ls.push(node)})),ls}))},getElementsByTagNameNS:function(namespaceURI,localName){return new LiveNodeList(this,(function(base){var ls=[];return _visitNode(base,(function(node){node===base||node.nodeType!==ELEMENT_NODE||"*"!==namespaceURI&&node.namespaceURI!==namespaceURI||"*"!==localName&&node.localName!=localName||ls.push(node)})),ls}))}},Document.prototype.getElementsByTagName=Element.prototype.getElementsByTagName,Document.prototype.getElementsByTagNameNS=Element.prototype.getElementsByTagNameNS,_extends(Element,Node),Attr.prototype.nodeType=ATTRIBUTE_NODE,_extends(Attr,Node),CharacterData.prototype={data:"",substringData:function(offset,count){return this.data.substring(offset,offset+count)},appendData:function(text){text=this.data+text,this.nodeValue=this.data=text,this.length=text.length},insertData:function(offset,text){this.replaceData(offset,0,text)},appendChild:function(newChild){throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])},deleteData:function(offset,count){this.replaceData(offset,count,"")},replaceData:function(offset,count,text){text=this.data.substring(0,offset)+text+this.data.substring(offset+count),this.nodeValue=this.data=text,this.length=text.length}},_extends(CharacterData,Node),Text.prototype={nodeName:"#text",nodeType:TEXT_NODE,splitText:function(offset){var text=this.data,newText=text.substring(offset);text=text.substring(0,offset),this.data=this.nodeValue=text,this.length=text.length;var newNode=this.ownerDocument.createTextNode(newText);return this.parentNode&&this.parentNode.insertBefore(newNode,this.nextSibling),newNode}},_extends(Text,CharacterData),Comment.prototype={nodeName:"#comment",nodeType:COMMENT_NODE},_extends(Comment,CharacterData),CDATASection.prototype={nodeName:"#cdata-section",nodeType:CDATA_SECTION_NODE},_extends(CDATASection,CharacterData),DocumentType.prototype.nodeType=DOCUMENT_TYPE_NODE,_extends(DocumentType,Node),Notation.prototype.nodeType=NOTATION_NODE,_extends(Notation,Node),Entity.prototype.nodeType=ENTITY_NODE,_extends(Entity,Node),EntityReference.prototype.nodeType=ENTITY_REFERENCE_NODE,_extends(EntityReference,Node),DocumentFragment.prototype.nodeName="#document-fragment",DocumentFragment.prototype.nodeType=DOCUMENT_FRAGMENT_NODE,_extends(DocumentFragment,Node),ProcessingInstruction.prototype.nodeType=PROCESSING_INSTRUCTION_NODE,_extends(ProcessingInstruction,Node),XMLSerializer.prototype.serializeToString=function(node,isHtml,nodeFilter){return nodeSerializeToString.call(node,isHtml,nodeFilter)},Node.prototype.toString=nodeSerializeToString;try{if(Object.defineProperty){function getTextContent(node){switch(node.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:var buf=[];for(node=node.firstChild;node;)7!==node.nodeType&&8!==node.nodeType&&buf.push(getTextContent(node)),node=node.nextSibling;return buf.join("");default:return node.nodeValue}}Object.defineProperty(LiveNodeList.prototype,"length",{get:function(){return _updateLiveList(this),this.$$length}}),Object.defineProperty(Node.prototype,"textContent",{get:function(){return getTextContent(this)},set:function(data){switch(this.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(data||String(data))&&this.appendChild(this.ownerDocument.createTextNode(data));break;default:this.data=data,this.value=data,this.nodeValue=data}}}),__set__=function(object,key,value){object["$$"+key]=value}}}catch(e){}var dom={DocumentType:DocumentType,DOMException:DOMException,DOMImplementation:DOMImplementation$1,Element:Element,Node:Node,NodeList:NodeList,XMLSerializer:XMLSerializer},entities=createCommonjsModule((function(module,exports){var freeze=conventions.freeze;exports.XML_ENTITIES=freeze({amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}),exports.HTML_ENTITIES=freeze({Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",AMP:"&",amp:"&",And:"⩓",and:"∧",andand:"⩕",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsd:"∡",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",ap:"≈",apacir:"⩯",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",Barwed:"⌆",barwed:"⌅",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",Because:"∵",because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxDL:"╗",boxDl:"╖",boxdL:"╕",boxdl:"┐",boxDR:"╔",boxDr:"╓",boxdR:"╒",boxdr:"┌",boxH:"═",boxh:"─",boxHD:"╦",boxHd:"╤",boxhD:"╥",boxhd:"┬",boxHU:"╩",boxHu:"╧",boxhU:"╨",boxhu:"┴",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxUL:"╝",boxUl:"╜",boxuL:"╛",boxul:"┘",boxUR:"╚",boxUr:"╙",boxuR:"╘",boxur:"└",boxV:"║",boxv:"│",boxVH:"╬",boxVh:"╫",boxvH:"╪",boxvh:"┼",boxVL:"╣",boxVl:"╢",boxvL:"╡",boxvl:"┤",boxVR:"╠",boxVr:"╟",boxvR:"╞",boxvr:"├",bprime:"‵",Breve:"˘",breve:"˘",brvbar:"¦",Bscr:"ℬ",bscr:"𝒷",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsol:"\\",bsolb:"⧅",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",Cap:"⋒",cap:"∩",capand:"⩄",capbrcup:"⩉",capcap:"⩋",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",CenterDot:"·",centerdot:"·",Cfr:"ℭ",cfr:"𝔠",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",cir:"○",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",Colon:"∷",colon:":",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",Conint:"∯",conint:"∮",ContourIntegral:"∮",Copf:"ℂ",copf:"𝕔",coprod:"∐",Coproduct:"∐",COPY:"©",copy:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",Cross:"⨯",cross:"✗",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",Cup:"⋓",cup:"∪",cupbrcap:"⩈",CupCap:"≍",cupcap:"⩆",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",Dagger:"‡",dagger:"†",daleth:"ℸ",Darr:"↡",dArr:"⇓",darr:"↓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",DD:"ⅅ",dd:"ⅆ",ddagger:"‡",ddarr:"⇊",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",Diamond:"⋄",diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrow:"↓",Downarrow:"⇓",downarrow:"↓",DownArrowBar:"⤓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVector:"↽",DownLeftVectorBar:"⥖",DownRightTeeVector:"⥟",DownRightVector:"⇁",DownRightVectorBar:"⥗",DownTee:"⊤",DownTeeArrow:"↧",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",ecir:"≖",Ecirc:"Ê",ecirc:"ê",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",eDot:"≑",edot:"ė",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp:" ",emsp13:" ",emsp14:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",Escr:"ℰ",escr:"ℯ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",ExponentialE:"ⅇ",exponentiale:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",ForAll:"∀",forall:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",Fscr:"ℱ",fscr:"𝒻",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",gE:"≧",ge:"≥",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",ges:"⩾",gescc:"⪩",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",Gg:"⋙",gg:"≫",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gl:"≷",gla:"⪥",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gnE:"≩",gne:"⪈",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",Gt:"≫",GT:">",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",hArr:"⇔",harr:"↔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",Hfr:"ℌ",hfr:"𝔥",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",Hopf:"ℍ",hopf:"𝕙",horbar:"―",HorizontalLine:"─",Hscr:"ℋ",hscr:"𝒽",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",Ifr:"ℑ",ifr:"𝔦",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Im:"ℑ",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒",in:"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",Int:"∬",int:"∫",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",Iscr:"ℐ",iscr:"𝒾",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",Lang:"⟪",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",Larr:"↞",lArr:"⇐",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",lAtail:"⤛",latail:"⤙",late:"⪭",lates:"⪭︀",lBarr:"⤎",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",lE:"≦",le:"≤",LeftAngleBracket:"⟨",LeftArrow:"←",Leftarrow:"⇐",leftarrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",Ll:"⋘",ll:"≪",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lnE:"≨",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftarrow:"⟵",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longleftrightarrow:"⟷",longmapsto:"⟼",LongRightArrow:"⟶",Longrightarrow:"⟹",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",Lscr:"ℒ",lscr:"𝓁",Lsh:"↰",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",Lt:"≪",LT:"<",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",Mscr:"ℳ",mscr:"𝓂",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",ne:"≠",nearhk:"⤤",neArr:"⇗",nearr:"↗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlArr:"⇍",nlarr:"↚",nldr:"‥",nlE:"≦̸",nle:"≰",nLeftarrow:"⇍",nleftarrow:"↚",nLeftrightarrow:"⇎",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",Nopf:"ℕ",nopf:"𝕟",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nRightarrow:"⇏",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nVDash:"⊯",nVdash:"⊮",nvDash:"⊭",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwArr:"⇖",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",ocir:"⊚",Ocirc:"Ô",ocirc:"ô",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",Or:"⩔",or:"∨",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",Otimes:"⨷",otimes:"⊗",otimesas:"⨶",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",Popf:"ℙ",popf:"𝕡",pound:"£",Pr:"⪻",pr:"≺",prap:"⪷",prcue:"≼",prE:"⪳",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",Prime:"″",prime:"′",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",Qopf:"ℚ",qopf:"𝕢",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",QUOT:'"',quot:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",Rang:"⟫",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",Rarr:"↠",rArr:"⇒",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",rAtail:"⤜",ratail:"⤚",ratio:"∶",rationals:"ℚ",RBarr:"⤐",rBarr:"⤏",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",REG:"®",reg:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",Rfr:"ℜ",rfr:"𝔯",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrow:"→",Rightarrow:"⇒",rightarrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",Ropf:"ℝ",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",Rscr:"ℛ",rscr:"𝓇",Rsh:"↱",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",Sc:"⪼",sc:"≻",scap:"⪸",Scaron:"Š",scaron:"š",sccue:"≽",scE:"⪴",sce:"⪰",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",seArr:"⇘",searr:"↘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",Square:"□",square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",Sub:"⋐",sub:"⊂",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",Subset:"⋐",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",Sum:"∑",sum:"∑",sung:"♪",Sup:"⋑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",Supset:"⋑",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swArr:"⇙",swarr:"↙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",Therefore:"∴",therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",Tilde:"∼",tilde:"˜",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",TRADE:"™",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",Uarr:"↟",uArr:"⇑",uarr:"↑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrow:"↑",Uparrow:"⇑",uparrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",Updownarrow:"⇕",updownarrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",upsi:"υ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",vArr:"⇕",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",Vbar:"⫫",vBar:"⫨",vBarv:"⫩",Vcy:"В",vcy:"в",VDash:"⊫",Vdash:"⊩",vDash:"⊨",vdash:"⊢",Vdashl:"⫦",Vee:"⋁",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",Verbar:"‖",verbar:"|",Vert:"‖",vert:"|",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",Wedge:"⋀",wedge:"∧",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",Xi:"Ξ",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",Yuml:"Ÿ",yuml:"ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",Zfr:"ℨ",zfr:"𝔷",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",Zopf:"ℤ",zopf:"𝕫",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}),exports.entityMap=exports.HTML_ENTITIES}));entities.XML_ENTITIES,entities.HTML_ENTITIES,entities.entityMap;var NAMESPACE$1=conventions.NAMESPACE,nameStartChar=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,nameChar=new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"),tagNamePattern=new RegExp("^"+nameStartChar.source+nameChar.source+"*(?::"+nameStartChar.source+nameChar.source+"*)?$");function ParseError$1(message,locator){this.message=message,this.locator=locator,Error.captureStackTrace&&Error.captureStackTrace(this,ParseError$1)}function XMLReader$1(){}function copyLocator(f,t){return t.lineNumber=f.lineNumber,t.columnNumber=f.columnNumber,t}function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){function addAttribute(qname,value,startIndex){el.attributeNames.hasOwnProperty(qname)&&errorHandler.fatalError("Attribute "+qname+" redefined"),el.addValue(qname,value.replace(/[\t\n\r]/g," ").replace(/&#?\w+;/g,entityReplacer),startIndex)}for(var attrName,p=++start,s=0;;){var c=source.charAt(p);switch(c){case"=":if(1===s)attrName=source.slice(start,p),s=3;else{if(2!==s)throw new Error("attribute equal must after attrName");s=3}break;case"'":case'"':if(3===s||1===s){if(1===s&&(errorHandler.warning('attribute value must after "="'),attrName=source.slice(start,p)),start=p+1,!((p=source.indexOf(c,start))>0))throw new Error("attribute value no end '"+c+"' match");addAttribute(attrName,value=source.slice(start,p),start-1),s=5}else{if(4!=s)throw new Error('attribute value must after "="');addAttribute(attrName,value=source.slice(start,p),start),errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+")!!"),start=p+1,s=5}break;case"/":switch(s){case 0:el.setTagName(source.slice(start,p));case 5:case 6:case 7:s=7,el.closed=!0;case 4:case 1:break;case 2:el.closed=!0;break;default:throw new Error("attribute invalid close char('/')")}break;case"":return errorHandler.error("unexpected end of input"),0==s&&el.setTagName(source.slice(start,p)),p;case">":switch(s){case 0:el.setTagName(source.slice(start,p));case 5:case 6:case 7:break;case 4:case 1:"/"===(value=source.slice(start,p)).slice(-1)&&(el.closed=!0,value=value.slice(0,-1));case 2:2===s&&(value=attrName),4==s?(errorHandler.warning('attribute "'+value+'" missed quot(")!'),addAttribute(attrName,value,start)):(NAMESPACE$1.isHTML(currentNSMap[""])&&value.match(/^(?:disabled|checked|selected)$/i)||errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!'),addAttribute(value,value,start));break;case 3:throw new Error("attribute value missed!!")}return p;case"€":c=" ";default:if(c<=" ")switch(s){case 0:el.setTagName(source.slice(start,p)),s=6;break;case 1:attrName=source.slice(start,p),s=2;break;case 4:var value=source.slice(start,p);errorHandler.warning('attribute "'+value+'" missed quot(")!!'),addAttribute(attrName,value,start);case 5:s=6}else switch(s){case 2:el.tagName,NAMESPACE$1.isHTML(currentNSMap[""])&&attrName.match(/^(?:disabled|checked|selected)$/i)||errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!'),addAttribute(attrName,attrName,start),start=p,s=1;break;case 5:errorHandler.warning('attribute space is required"'+attrName+'"!!');case 6:s=1,start=p;break;case 3:s=4,start=p;break;case 7:throw new Error("elements closed character '/' and '>' must be connected to")}}p++}}function appendElement$1(el,domBuilder,currentNSMap){for(var tagName=el.tagName,localNSMap=null,i=el.length;i--;){var a=el[i],qName=a.qName,value=a.value;if((nsp=qName.indexOf(":"))>0)var prefix=a.prefix=qName.slice(0,nsp),localName=qName.slice(nsp+1),nsPrefix="xmlns"===prefix&&localName;else localName=qName,prefix=null,nsPrefix="xmlns"===qName&&"";a.localName=localName,!1!==nsPrefix&&(null==localNSMap&&(localNSMap={},_copy(currentNSMap,currentNSMap={})),currentNSMap[nsPrefix]=localNSMap[nsPrefix]=value,a.uri=NAMESPACE$1.XMLNS,domBuilder.startPrefixMapping(nsPrefix,value))}for(i=el.length;i--;){(prefix=(a=el[i]).prefix)&&("xml"===prefix&&(a.uri=NAMESPACE$1.XML),"xmlns"!==prefix&&(a.uri=currentNSMap[prefix||""]))}var nsp;(nsp=tagName.indexOf(":"))>0?(prefix=el.prefix=tagName.slice(0,nsp),localName=el.localName=tagName.slice(nsp+1)):(prefix=null,localName=el.localName=tagName);var ns=el.uri=currentNSMap[prefix||""];if(domBuilder.startElement(ns,localName,tagName,el),!el.closed)return el.currentNSMap=currentNSMap,el.localNSMap=localNSMap,!0;if(domBuilder.endElement(ns,localName,tagName),localNSMap)for(prefix in localNSMap)Object.prototype.hasOwnProperty.call(localNSMap,prefix)&&domBuilder.endPrefixMapping(prefix)}function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){if(/^(?:script|textarea)$/i.test(tagName)){var elEndStart=source.indexOf("",elStartEnd),text=source.substring(elStartEnd+1,elEndStart);if(/[&<]/.test(text))return/^script$/i.test(tagName)?(domBuilder.characters(text,0,text.length),elEndStart):(text=text.replace(/&#?\w+;/g,entityReplacer),domBuilder.characters(text,0,text.length),elEndStart)}return elStartEnd+1}function fixSelfClosed(source,elStartEnd,tagName,closeMap){var pos=closeMap[tagName];return null==pos&&((pos=source.lastIndexOf(""))start?(domBuilder.comment(source,start+4,end-start-4),end+3):(errorHandler.error("Unclosed comment"),-1):-1;if("CDATA["==source.substr(start+3,6)){var end=source.indexOf("]]>",start+9);return domBuilder.startCDATA(),domBuilder.characters(source,start+9,end-start-9),domBuilder.endCDATA(),end+3}var matchs=function(source,start){var match,buf=[],reg=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;reg.lastIndex=start,reg.exec(source);for(;match=reg.exec(source);)if(buf.push(match),match[1])return buf}(source,start),len=matchs.length;if(len>1&&/!doctype/i.test(matchs[0][0])){var name=matchs[1][0],pubid=!1,sysid=!1;len>3&&(/^public$/i.test(matchs[2][0])?(pubid=matchs[3][0],sysid=len>4&&matchs[4][0]):/^system$/i.test(matchs[2][0])&&(sysid=matchs[3][0]));var lastMatch=matchs[len-1];return domBuilder.startDTD(name,pubid,sysid),domBuilder.endDTD(),lastMatch.index+lastMatch[0].length}return-1}function parseInstruction(source,start,domBuilder){var end=source.indexOf("?>",start);if(end){var match=source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);return match?(match[0].length,domBuilder.processingInstruction(match[1],match[2]),end+2):-1}return-1}function ElementAttributes(){this.attributeNames={}}ParseError$1.prototype=new Error,ParseError$1.prototype.name=ParseError$1.name,XMLReader$1.prototype={parse:function(source,defaultNSMap,entityMap){var domBuilder=this.domBuilder;domBuilder.startDocument(),_copy(defaultNSMap,defaultNSMap={}),function(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){function fixedFromCharCode(code){if(code>65535){var surrogate1=55296+((code-=65536)>>10),surrogate2=56320+(1023&code);return String.fromCharCode(surrogate1,surrogate2)}return String.fromCharCode(code)}function entityReplacer(a){var k=a.slice(1,-1);return Object.hasOwnProperty.call(entityMap,k)?entityMap[k]:"#"===k.charAt(0)?fixedFromCharCode(parseInt(k.substr(1).replace("x","0x"))):(errorHandler.error("entity not found:"+a),a)}function appendText(end){if(end>start){var xt=source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);locator&&position(start),domBuilder.characters(xt,0,end-start),start=end}}function position(p,m){for(;p>=lineEnd&&(m=linePattern.exec(source));)lineStart=m.index,lineEnd=lineStart+m[0].length,locator.lineNumber++;locator.columnNumber=p-lineStart+1}var lineStart=0,lineEnd=0,linePattern=/.*(?:\r\n?|\n)|.*$/g,locator=domBuilder.locator,parseStack=[{currentNSMap:defaultNSMapCopy}],closeMap={},start=0;for(;;){try{var tagStart=source.indexOf("<",start);if(tagStart<0){if(!source.substr(start).match(/^\s*$/)){var doc=domBuilder.doc,text=doc.createTextNode(source.substr(start));doc.appendChild(text),domBuilder.currentElement=text}return}switch(tagStart>start&&appendText(tagStart),source.charAt(tagStart+1)){case"/":var end=source.indexOf(">",tagStart+3),tagName=source.substring(tagStart+2,end).replace(/[ \t\n\r]+$/g,""),config=parseStack.pop();end<0?(tagName=source.substring(tagStart+2).replace(/[\s<].*/,""),errorHandler.error("end tag name: "+tagName+" is not complete:"+config.tagName),end=tagStart+1+tagName.length):tagName.match(/\sstart?start=end:appendText(Math.max(tagStart,start)+1)}}(source,defaultNSMap,entityMap,domBuilder,this.errorHandler),domBuilder.endDocument()}},ElementAttributes.prototype={setTagName:function(tagName){if(!tagNamePattern.test(tagName))throw new Error("invalid tagName:"+tagName);this.tagName=tagName},addValue:function(qName,value,offset){if(!tagNamePattern.test(qName))throw new Error("invalid attribute:"+qName);this.attributeNames[qName]=this.length,this[this.length++]={qName:qName,value:value,offset:offset}},length:0,getLocalName:function(i){return this[i].localName},getLocator:function(i){return this[i].locator},getQName:function(i){return this[i].qName},getURI:function(i){return this[i].uri},getValue:function(i){return this[i].value}};var sax={XMLReader:XMLReader$1,ParseError:ParseError$1},DOMImplementation=dom.DOMImplementation,NAMESPACE=conventions.NAMESPACE,ParseError=sax.ParseError,XMLReader=sax.XMLReader;function normalizeLineEndings(input){return input.replace(/\r[\n\u0085]/g,"\n").replace(/[\r\u0085\u2028]/g,"\n")}function DOMParser$1(options){this.options=options||{locator:{}}}function DOMHandler(){this.cdata=!1}function position(locator,node){node.lineNumber=locator.lineNumber,node.columnNumber=locator.columnNumber}function _locator(l){if(l)return"\n@"+(l.systemId||"")+"#[line:"+l.lineNumber+",col:"+l.columnNumber+"]"}function _toString(chars,start,length){return"string"==typeof chars?chars.substr(start,length):chars.length>=start+length||start?new java.lang.String(chars,start,length)+"":chars}function appendElement(hander,node){hander.currentElement?hander.currentElement.appendChild(node):hander.doc.appendChild(node)}DOMParser$1.prototype.parseFromString=function(source,mimeType){var options=this.options,sax=new XMLReader,domBuilder=options.domBuilder||new DOMHandler,errorHandler=options.errorHandler,locator=options.locator,defaultNSMap=options.xmlns||{},isHTML=/\/x?html?$/.test(mimeType),entityMap=isHTML?entities.HTML_ENTITIES:entities.XML_ENTITIES;locator&&domBuilder.setDocumentLocator(locator),sax.errorHandler=function(errorImpl,domBuilder,locator){if(!errorImpl){if(domBuilder instanceof DOMHandler)return domBuilder;errorImpl=domBuilder}var errorHandler={},isCallback=errorImpl instanceof Function;function build(key){var fn=errorImpl[key];!fn&&isCallback&&(fn=2==errorImpl.length?function(msg){errorImpl(key,msg)}:errorImpl),errorHandler[key]=fn&&function(msg){fn("[xmldom "+key+"]\t"+msg+_locator(locator))}||function(){}}return locator=locator||{},build("warning"),build("error"),build("fatalError"),errorHandler}(errorHandler,domBuilder,locator),sax.domBuilder=options.domBuilder||domBuilder,isHTML&&(defaultNSMap[""]=NAMESPACE.HTML),defaultNSMap.xml=defaultNSMap.xml||NAMESPACE.XML;var normalize=options.normalizeLineEndings||normalizeLineEndings;return source&&"string"==typeof source?sax.parse(normalize(source),defaultNSMap,entityMap):sax.errorHandler.error("invalid doc source"),domBuilder.doc},DOMHandler.prototype={startDocument:function(){this.doc=(new DOMImplementation).createDocument(null,null,null),this.locator&&(this.doc.documentURI=this.locator.systemId)},startElement:function(namespaceURI,localName,qName,attrs){var doc=this.doc,el=doc.createElementNS(namespaceURI,qName||localName),len=attrs.length;appendElement(this,el),this.currentElement=el,this.locator&&position(this.locator,el);for(var i=0;i!!obj&&"object"==typeof obj,merge$1=function(){for(var _len23=arguments.length,objects=new Array(_len23),_key23=0;_key23<_len23;_key23++)objects[_key23]=arguments[_key23];return objects.reduce(((result,source)=>("object"!=typeof source||Object.keys(source).forEach((key=>{Array.isArray(result[key])&&Array.isArray(source[key])?result[key]=result[key].concat(source[key]):isObject(result[key])&&isObject(source[key])?result[key]=merge$1(result[key],source[key]):result[key]=source[key]})),result)),{})},values=o=>Object.keys(o).map((k=>o[k])),flatten=lists=>lists.reduce(((x,y)=>x.concat(y)),[]),from=list=>{if(!list.length)return[];const result=[];for(let i=0;i{let{baseUrl:baseUrl="",source:source="",range:range="",indexRange:indexRange=""}=_ref10;const segment={uri:source,resolvedUri:resolveUrl$1(baseUrl||"",source)};if(range||indexRange){const ranges=(range||indexRange).split("-");let length,startRange=window.BigInt?window.BigInt(ranges[0]):parseInt(ranges[0],10),endRange=window.BigInt?window.BigInt(ranges[1]):parseInt(ranges[1],10);startRange(endNumber&&"number"!=typeof endNumber&&(endNumber=parseInt(endNumber,10)),isNaN(endNumber)?null:endNumber),segmentRange={static(attributes){const{duration:duration,timescale:timescale=1,sourceDuration:sourceDuration,periodDuration:periodDuration}=attributes,endNumber=parseEndNumber(attributes.endNumber),segmentDuration=duration/timescale;return"number"==typeof endNumber?{start:0,end:endNumber}:"number"==typeof periodDuration?{start:0,end:periodDuration/segmentDuration}:{start:0,end:sourceDuration/segmentDuration}},dynamic(attributes){const{NOW:NOW,clientOffset:clientOffset,availabilityStartTime:availabilityStartTime,timescale:timescale=1,duration:duration,periodStart:periodStart=0,minimumUpdatePeriod:minimumUpdatePeriod=0,timeShiftBufferDepth:timeShiftBufferDepth=1/0}=attributes,endNumber=parseEndNumber(attributes.endNumber),now=(NOW+clientOffset)/1e3,periodStartWC=availabilityStartTime+periodStart,periodDuration=now+minimumUpdatePeriod-periodStartWC,segmentCount=Math.ceil(periodDuration*timescale/duration),availableStart=Math.floor((now-periodStartWC-timeShiftBufferDepth)*timescale/duration),availableEnd=Math.floor((now-periodStartWC)*timescale/duration);return{start:Math.max(0,availableStart),end:"number"==typeof endNumber?endNumber:Math.min(segmentCount,availableEnd)}}},parseByDuration=attributes=>{const{type:type,duration:duration,timescale:timescale=1,periodDuration:periodDuration,sourceDuration:sourceDuration}=attributes,{start:start,end:end}=segmentRange[type](attributes),segments=((start,end)=>{const result=[];for(let i=start;inumber=>{const{duration:duration,timescale:timescale=1,periodStart:periodStart,startNumber:startNumber=1}=attributes;return{number:startNumber+number,duration:duration/timescale,timeline:periodStart,time:number*duration}})(attributes));if("static"===type){const index=segments.length-1,sectionDuration="number"==typeof periodDuration?periodDuration:sourceDuration;segments[index].duration=sectionDuration-duration/timescale*index}return segments},segmentsFromBase=attributes=>{const{baseUrl:baseUrl,initialization:initialization={},sourceDuration:sourceDuration,indexRange:indexRange="",periodStart:periodStart,presentationTime:presentationTime,number:number=0,duration:duration}=attributes;if(!baseUrl)throw new Error(errors_NO_BASE_URL);const initSegment=urlTypeToSegment({baseUrl:baseUrl,source:initialization.sourceURL,range:initialization.range}),segment=urlTypeToSegment({baseUrl:baseUrl,source:baseUrl,indexRange:indexRange});if(segment.map=initSegment,duration){const segmentTimeInfo=parseByDuration(attributes);segmentTimeInfo.length&&(segment.duration=segmentTimeInfo[0].duration,segment.timeline=segmentTimeInfo[0].timeline)}else sourceDuration&&(segment.duration=sourceDuration,segment.timeline=periodStart);return segment.presentationTime=presentationTime||periodStart,segment.number=number,[segment]},addSidxSegmentsToPlaylist$1=(playlist,sidx,baseUrl)=>{const initSegment=playlist.sidx.map?playlist.sidx.map:null,sourceDuration=playlist.sidx.duration,timeline=playlist.timeline||0,sidxByteRange=playlist.sidx.byterange,sidxEnd=sidxByteRange.offset+sidxByteRange.length,timescale=sidx.timescale,mediaReferences=sidx.references.filter((r=>1!==r.referenceType)),segments=[],type=playlist.endList?"static":"dynamic",periodStart=playlist.sidx.timeline;let startIndex,presentationTime=periodStart,number=playlist.mediaSequence||0;startIndex="bigint"==typeof sidx.firstOffset?window.BigInt(sidxEnd)+sidx.firstOffset:sidxEnd+sidx.firstOffset;for(let i=0;i{return(lists=timelineStarts,keyFunction=_ref11=>{let{timeline:timeline}=_ref11;return timeline},values(lists.reduce(((acc,list)=>(list.forEach((el=>{acc[keyFunction(el)]=el})),acc)),{}))).sort(((a,b)=>a.timeline>b.timeline?1:-1));var lists,keyFunction},getMediaGroupPlaylists=manifest=>{let mediaGroupPlaylists=[];var master,callback;return master=manifest,callback=(properties,type,group,label)=>{mediaGroupPlaylists=mediaGroupPlaylists.concat(properties.playlists||[])},SUPPORTED_MEDIA_TYPES.forEach((function(mediaType){for(var groupKey in master.mediaGroups[mediaType])for(var labelKey in master.mediaGroups[mediaType][groupKey]){var mediaProperties=master.mediaGroups[mediaType][groupKey][labelKey];callback(mediaProperties,mediaType,groupKey,labelKey)}})),mediaGroupPlaylists},updateMediaSequenceForPlaylist=_ref12=>{let{playlist:playlist,mediaSequence:mediaSequence}=_ref12;playlist.mediaSequence=mediaSequence,playlist.segments.forEach(((segment,index)=>{segment.number=playlist.mediaSequence+index}))},positionManifestOnTimeline=_ref15=>{let{oldManifest:oldManifest,newManifest:newManifest}=_ref15;const oldPlaylists=oldManifest.playlists.concat(getMediaGroupPlaylists(oldManifest)),newPlaylists=newManifest.playlists.concat(getMediaGroupPlaylists(newManifest));return newManifest.timelineStarts=getUniqueTimelineStarts([oldManifest.timelineStarts,newManifest.timelineStarts]),(_ref13=>{let{oldPlaylists:oldPlaylists,newPlaylists:newPlaylists,timelineStarts:timelineStarts}=_ref13;newPlaylists.forEach((playlist=>{playlist.discontinuitySequence=timelineStarts.findIndex((function(_ref14){let{timeline:timeline}=_ref14;return timeline===playlist.timeline}));const oldPlaylist=((playlists,name)=>{for(let i=0;ioldPlaylist.timeline||oldPlaylist.segments.length&&playlist.timeline>oldPlaylist.segments[oldPlaylist.segments.length-1].timeline)&&playlist.discontinuitySequence--);oldPlaylist.segments[oldMatchingSegmentIndex].discontinuity&&!firstNewSegment.discontinuity&&(firstNewSegment.discontinuity=!0,playlist.discontinuityStarts.unshift(0),playlist.discontinuitySequence--),updateMediaSequenceForPlaylist({playlist:playlist,mediaSequence:oldPlaylist.segments[oldMatchingSegmentIndex].number})}))})({oldPlaylists:oldPlaylists,newPlaylists:newPlaylists,timelineStarts:newManifest.timelineStarts}),newManifest},generateSidxKey=sidx=>sidx&&sidx.uri+"-"+(byterange=>{let endRange;return endRange="bigint"==typeof byterange.offset||"bigint"==typeof byterange.length?window.BigInt(byterange.offset)+window.BigInt(byterange.length)-window.BigInt(1):byterange.offset+byterange.length-1,"".concat(byterange.offset,"-").concat(endRange)})(sidx.byterange),mergeDiscontiguousPlaylists=playlists=>{const playlistsByBaseUrl=playlists.reduce((function(acc,cur){return acc[cur.attributes.baseUrl]||(acc[cur.attributes.baseUrl]=[]),acc[cur.attributes.baseUrl].push(cur),acc}),{});let allPlaylists=[];return Object.values(playlistsByBaseUrl).forEach((playlistGroup=>{const mergedPlaylists=values(playlistGroup.reduce(((acc,playlist)=>{const name=playlist.attributes.id+(playlist.attributes.lang||"");return acc[name]?(playlist.segments&&(playlist.segments[0]&&(playlist.segments[0].discontinuity=!0),acc[name].segments.push(...playlist.segments)),playlist.attributes.contentProtection&&(acc[name].attributes.contentProtection=playlist.attributes.contentProtection)):(acc[name]=playlist,acc[name].attributes.timelineStarts=[]),acc[name].attributes.timelineStarts.push({start:playlist.attributes.periodStart,timeline:playlist.attributes.periodStart}),acc}),{}));allPlaylists=allPlaylists.concat(mergedPlaylists)})),allPlaylists.map((playlist=>{var l,key;return playlist.discontinuityStarts=(l=playlist.segments||[],key="discontinuity",l.reduce(((a,e,i)=>(e[key]&&a.push(i),a)),[])),playlist}))},addSidxSegmentsToPlaylist=(playlist,sidxMapping)=>{const sidxKey=generateSidxKey(playlist.sidx),sidxMatch=sidxKey&&sidxMapping[sidxKey]&&sidxMapping[sidxKey].sidx;return sidxMatch&&addSidxSegmentsToPlaylist$1(playlist,sidxMatch,playlist.sidx.resolvedUri),playlist},addSidxSegmentsToPlaylists=function(playlists){let sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!Object.keys(sidxMapping).length)return playlists;for(const i in playlists)playlists[i]=addSidxSegmentsToPlaylist(playlists[i],sidxMapping);return playlists},formatAudioPlaylist=(_ref16,isAudioOnly)=>{let{attributes:attributes,segments:segments,sidx:sidx,mediaSequence:mediaSequence,discontinuitySequence:discontinuitySequence,discontinuityStarts:discontinuityStarts}=_ref16;const playlist={attributes:{NAME:attributes.id,BANDWIDTH:attributes.bandwidth,CODECS:attributes.codecs,"PROGRAM-ID":1},uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",targetDuration:attributes.duration,discontinuitySequence:discontinuitySequence,discontinuityStarts:discontinuityStarts,timelineStarts:attributes.timelineStarts,mediaSequence:mediaSequence,segments:segments};return attributes.contentProtection&&(playlist.contentProtection=attributes.contentProtection),attributes.serviceLocation&&(playlist.attributes.serviceLocation=attributes.serviceLocation),sidx&&(playlist.sidx=sidx),isAudioOnly&&(playlist.attributes.AUDIO="audio",playlist.attributes.SUBTITLES="subs"),playlist},formatVttPlaylist=_ref17=>{let{attributes:attributes,segments:segments,mediaSequence:mediaSequence,discontinuityStarts:discontinuityStarts,discontinuitySequence:discontinuitySequence}=_ref17;void 0===segments&&(segments=[{uri:attributes.baseUrl,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",duration:attributes.sourceDuration,number:0}],attributes.duration=attributes.sourceDuration);const m3u8Attributes={NAME:attributes.id,BANDWIDTH:attributes.bandwidth,"PROGRAM-ID":1};attributes.codecs&&(m3u8Attributes.CODECS=attributes.codecs);const vttPlaylist={attributes:m3u8Attributes,uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",targetDuration:attributes.duration,timelineStarts:attributes.timelineStarts,discontinuityStarts:discontinuityStarts,discontinuitySequence:discontinuitySequence,mediaSequence:mediaSequence,segments:segments};return attributes.serviceLocation&&(vttPlaylist.attributes.serviceLocation=attributes.serviceLocation),vttPlaylist},formatVideoPlaylist=_ref18=>{let{attributes:attributes,segments:segments,sidx:sidx,discontinuityStarts:discontinuityStarts}=_ref18;const playlist={attributes:{NAME:attributes.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:attributes.width,height:attributes.height},CODECS:attributes.codecs,BANDWIDTH:attributes.bandwidth,"PROGRAM-ID":1},uri:"",endList:"static"===attributes.type,timeline:attributes.periodStart,resolvedUri:attributes.baseUrl||"",targetDuration:attributes.duration,discontinuityStarts:discontinuityStarts,timelineStarts:attributes.timelineStarts,segments:segments};return attributes.frameRate&&(playlist.attributes["FRAME-RATE"]=attributes.frameRate),attributes.contentProtection&&(playlist.contentProtection=attributes.contentProtection),attributes.serviceLocation&&(playlist.attributes.serviceLocation=attributes.serviceLocation),sidx&&(playlist.sidx=sidx),playlist},videoOnly=_ref19=>{let{attributes:attributes}=_ref19;return"video/mp4"===attributes.mimeType||"video/webm"===attributes.mimeType||"video"===attributes.contentType},audioOnly=_ref20=>{let{attributes:attributes}=_ref20;return"audio/mp4"===attributes.mimeType||"audio/webm"===attributes.mimeType||"audio"===attributes.contentType},vttOnly=_ref21=>{let{attributes:attributes}=_ref21;return"text/vtt"===attributes.mimeType||"text"===attributes.contentType},flattenMediaGroupPlaylists=mediaGroupObject=>mediaGroupObject?Object.keys(mediaGroupObject).reduce(((acc,label)=>{const labelContents=mediaGroupObject[label];return acc.concat(labelContents.playlists)}),[]):[],toM3u8=_ref23=>{let{dashPlaylists:dashPlaylists,locations:locations,contentSteering:contentSteering,sidxMapping:sidxMapping={},previousManifest:previousManifest,eventStream:eventStream}=_ref23;if(!dashPlaylists.length)return{};const{sourceDuration:duration,type:type,suggestedPresentationDelay:suggestedPresentationDelay,minimumUpdatePeriod:minimumUpdatePeriod}=dashPlaylists[0].attributes,videoPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist),audioPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly)),vttPlaylists=mergeDiscontiguousPlaylists(dashPlaylists.filter(vttOnly)),captions=dashPlaylists.map((playlist=>playlist.attributes.captionServices)).filter(Boolean),manifest={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:"",duration:duration,playlists:addSidxSegmentsToPlaylists(videoPlaylists,sidxMapping)};minimumUpdatePeriod>=0&&(manifest.minimumUpdatePeriod=1e3*minimumUpdatePeriod),locations&&(manifest.locations=locations),contentSteering&&(manifest.contentSteering=contentSteering),"dynamic"===type&&(manifest.suggestedPresentationDelay=suggestedPresentationDelay),eventStream&&eventStream.length>0&&(manifest.eventStream=eventStream);const isAudioOnly=0===manifest.playlists.length,organizedAudioGroup=audioPlaylists.length?function(playlists){let mainPlaylist,sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},isAudioOnly=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const formattedPlaylists=playlists.reduce(((a,playlist)=>{const role=playlist.attributes.role&&playlist.attributes.role.value||"",language=playlist.attributes.lang||"";let label=playlist.attributes.label||"main";if(language&&!playlist.attributes.label){const roleLabel=role?" (".concat(role,")"):"";label="".concat(playlist.attributes.lang).concat(roleLabel)}a[label]||(a[label]={language:language,autoselect:!0,default:"main"===role,playlists:[],uri:""});const formatted=addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist,isAudioOnly),sidxMapping);return a[label].playlists.push(formatted),void 0===mainPlaylist&&"main"===role&&(mainPlaylist=playlist,mainPlaylist.default=!0),a}),{});mainPlaylist||(formattedPlaylists[Object.keys(formattedPlaylists)[0]].default=!0);return formattedPlaylists}(audioPlaylists,sidxMapping,isAudioOnly):null,organizedVttGroup=vttPlaylists.length?function(playlists){let sidxMapping=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return playlists.reduce(((a,playlist)=>{const label=playlist.attributes.label||playlist.attributes.lang||"text";return a[label]||(a[label]={language:label,default:!1,autoselect:!1,playlists:[],uri:""}),a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist),sidxMapping)),a}),{})}(vttPlaylists,sidxMapping):null,formattedPlaylists=videoPlaylists.concat(flattenMediaGroupPlaylists(organizedAudioGroup),flattenMediaGroupPlaylists(organizedVttGroup)),playlistTimelineStarts=formattedPlaylists.map((_ref24=>{let{timelineStarts:timelineStarts}=_ref24;return timelineStarts}));var playlists,timelineStarts;return manifest.timelineStarts=getUniqueTimelineStarts(playlistTimelineStarts),playlists=formattedPlaylists,timelineStarts=manifest.timelineStarts,playlists.forEach((playlist=>{playlist.mediaSequence=0,playlist.discontinuitySequence=timelineStarts.findIndex((function(_ref22){let{timeline:timeline}=_ref22;return timeline===playlist.timeline})),playlist.segments&&playlist.segments.forEach(((segment,index)=>{segment.number=index}))})),organizedAudioGroup&&(manifest.mediaGroups.AUDIO.audio=organizedAudioGroup),organizedVttGroup&&(manifest.mediaGroups.SUBTITLES.subs=organizedVttGroup),captions.length&&(manifest.mediaGroups["CLOSED-CAPTIONS"].cc=captions.reduce(((svcObj,svc)=>svc?(svc.forEach((service=>{const{channel:channel,language:language}=service;svcObj[language]={autoselect:!1,default:!1,instreamId:channel,language:language},service.hasOwnProperty("aspectRatio")&&(svcObj[language].aspectRatio=service.aspectRatio),service.hasOwnProperty("easyReader")&&(svcObj[language].easyReader=service.easyReader),service.hasOwnProperty("3D")&&(svcObj[language]["3D"]=service["3D"])})),svcObj):svcObj),{})),previousManifest?positionManifestOnTimeline({oldManifest:previousManifest,newManifest:manifest}):manifest},getLiveRValue=(attributes,time,duration)=>{const{NOW:NOW,clientOffset:clientOffset,availabilityStartTime:availabilityStartTime,timescale:timescale=1,periodStart:periodStart=0,minimumUpdatePeriod:minimumUpdatePeriod=0}=attributes,periodDuration=(NOW+clientOffset)/1e3+minimumUpdatePeriod-(availabilityStartTime+periodStart);return Math.ceil((periodDuration*timescale-time)/duration)},parseByTimeline=(attributes,segmentTimeline)=>{const{type:type,minimumUpdatePeriod:minimumUpdatePeriod=0,media:media="",sourceDuration:sourceDuration,timescale:timescale=1,startNumber:startNumber=1,periodStart:timeline}=attributes,segments=[];let time=-1;for(let sIndex=0;sIndextime&&(time=segmentTime),repeat<0){const nextS=sIndex+1;count=nextS===segmentTimeline.length?"dynamic"===type&&minimumUpdatePeriod>0&&media.indexOf("$Number$")>0?getLiveRValue(attributes,time,duration):(sourceDuration*timescale-time)/duration:(segmentTimeline[nextS].t-time)/duration}else count=repeat+1;const end=startNumber+segments.length+count;let number=startNumber+segments.length;for(;numberurl.replace(identifierPattern,(values=>(match,identifier,format,width)=>{if("$$"===match)return"$";if(void 0===values[identifier])return match;const value=""+values[identifier];return"RepresentationID"===identifier?value:(width=format?parseInt(width,10):1,value.length>=width?value:"".concat(new Array(width-value.length+1).join("0")).concat(value))})(values)),segmentsFromTemplate=(attributes,segmentTimeline)=>{const templateValues={RepresentationID:attributes.id,Bandwidth:attributes.bandwidth||0},{initialization:initialization={sourceURL:"",range:""}}=attributes,mapSegment=urlTypeToSegment({baseUrl:attributes.baseUrl,source:constructTemplateUrl(initialization.sourceURL,templateValues),range:initialization.range}),segments=((attributes,segmentTimeline)=>attributes.duration||segmentTimeline?attributes.duration?parseByDuration(attributes):parseByTimeline(attributes,segmentTimeline):[{number:attributes.startNumber||1,duration:attributes.sourceDuration,time:0,timeline:attributes.periodStart}])(attributes,segmentTimeline);return segments.map((segment=>{templateValues.Number=segment.number,templateValues.Time=segment.time;const uri=constructTemplateUrl(attributes.media||"",templateValues),timescale=attributes.timescale||1,presentationTimeOffset=attributes.presentationTimeOffset||0,presentationTime=attributes.periodStart+(segment.time-presentationTimeOffset)/timescale;return{uri:uri,timeline:segment.timeline,duration:segment.duration,resolvedUri:resolveUrl$1(attributes.baseUrl||"",uri),map:mapSegment,number:segment.number,presentationTime:presentationTime}}))},segmentsFromList=(attributes,segmentTimeline)=>{const{duration:duration,segmentUrls:segmentUrls=[],periodStart:periodStart}=attributes;if(!duration&&!segmentTimeline||duration&&segmentTimeline)throw new Error(errors_SEGMENT_TIME_UNSPECIFIED);const segmentUrlMap=segmentUrls.map((segmentUrlObject=>((attributes,segmentUrl)=>{const{baseUrl:baseUrl,initialization:initialization={}}=attributes,initSegment=urlTypeToSegment({baseUrl:baseUrl,source:initialization.sourceURL,range:initialization.range}),segment=urlTypeToSegment({baseUrl:baseUrl,source:segmentUrl.media,range:segmentUrl.mediaRange});return segment.map=initSegment,segment})(attributes,segmentUrlObject)));let segmentTimeInfo;duration&&(segmentTimeInfo=parseByDuration(attributes)),segmentTimeline&&(segmentTimeInfo=parseByTimeline(attributes,segmentTimeline));return segmentTimeInfo.map(((segmentTime,index)=>{if(segmentUrlMap[index]){const segment=segmentUrlMap[index],timescale=attributes.timescale||1,presentationTimeOffset=attributes.presentationTimeOffset||0;return segment.timeline=segmentTime.timeline,segment.duration=segmentTime.duration,segment.number=segmentTime.number,segment.presentationTime=periodStart+(segmentTime.time-presentationTimeOffset)/timescale,segment}})).filter((segment=>segment))},generateSegments=_ref25=>{let segmentAttributes,segmentsFn,{attributes:attributes,segmentInfo:segmentInfo}=_ref25;segmentInfo.template?(segmentsFn=segmentsFromTemplate,segmentAttributes=merge$1(attributes,segmentInfo.template)):segmentInfo.base?(segmentsFn=segmentsFromBase,segmentAttributes=merge$1(attributes,segmentInfo.base)):segmentInfo.list&&(segmentsFn=segmentsFromList,segmentAttributes=merge$1(attributes,segmentInfo.list));const segmentsInfo={attributes:attributes};if(!segmentsFn)return segmentsInfo;const segments=segmentsFn(segmentAttributes,segmentInfo.segmentTimeline);if(segmentAttributes.duration){const{duration:duration,timescale:timescale=1}=segmentAttributes;segmentAttributes.duration=duration/timescale}else segments.length?segmentAttributes.duration=segments.reduce(((max,segment)=>Math.max(max,Math.ceil(segment.duration))),0):segmentAttributes.duration=0;return segmentsInfo.attributes=segmentAttributes,segmentsInfo.segments=segments,segmentInfo.base&&segmentAttributes.indexRange&&(segmentsInfo.sidx=segments[0],segmentsInfo.segments=[]),segmentsInfo},toPlaylists=representations=>representations.map(generateSegments),findChildren=(element,name)=>from(element.childNodes).filter((_ref26=>{let{tagName:tagName}=_ref26;return tagName===name})),getContent=element=>element.textContent.trim(),parseDuration=str=>{const match=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(str);if(!match)return 0;const[year,month,day,hour,minute,second]=match.slice(1);return 31536e3*parseFloat(year||0)+2592e3*parseFloat(month||0)+86400*parseFloat(day||0)+3600*parseFloat(hour||0)+60*parseFloat(minute||0)+parseFloat(second||0)},parsers={mediaPresentationDuration:value=>parseDuration(value),availabilityStartTime(value){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(str=value)&&(str+="Z"),Date.parse(str)/1e3;var str},minimumUpdatePeriod:value=>parseDuration(value),suggestedPresentationDelay:value=>parseDuration(value),type:value=>value,timeShiftBufferDepth:value=>parseDuration(value),start:value=>parseDuration(value),width:value=>parseInt(value,10),height:value=>parseInt(value,10),bandwidth:value=>parseInt(value,10),frameRate:value=>(value=>parseFloat(value.split("/").reduce(((prev,current)=>prev/current))))(value),startNumber:value=>parseInt(value,10),timescale:value=>parseInt(value,10),presentationTimeOffset:value=>parseInt(value,10),duration(value){const parsedValue=parseInt(value,10);return isNaN(parsedValue)?parseDuration(value):parsedValue},d:value=>parseInt(value,10),t:value=>parseInt(value,10),r:value=>parseInt(value,10),presentationTime:value=>parseInt(value,10),DEFAULT:value=>value},parseAttributes=el=>el&&el.attributes?from(el.attributes).reduce(((a,e)=>{const parseFn=parsers[e.name]||parsers.DEFAULT;return a[e.name]=parseFn(e.value),a}),{}):{},keySystemsMap={"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","urn:mpeg:dash:mp4protection:2011":"mp4protection"},buildBaseUrls=(references,baseUrlElements)=>baseUrlElements.length?flatten(references.map((function(reference){return baseUrlElements.map((function(baseUrlElement){const initialBaseUrl=getContent(baseUrlElement),resolvedBaseUrl=resolveUrl$1(reference.baseUrl,initialBaseUrl),finalBaseUrl=merge$1(parseAttributes(baseUrlElement),{baseUrl:resolvedBaseUrl});return resolvedBaseUrl!==initialBaseUrl&&!finalBaseUrl.serviceLocation&&reference.serviceLocation&&(finalBaseUrl.serviceLocation=reference.serviceLocation),finalBaseUrl}))}))):references,getSegmentInformation=adaptationSet=>{const segmentTemplate=findChildren(adaptationSet,"SegmentTemplate")[0],segmentList=findChildren(adaptationSet,"SegmentList")[0],segmentUrls=segmentList&&findChildren(segmentList,"SegmentURL").map((s=>merge$1({tag:"SegmentURL"},parseAttributes(s)))),segmentBase=findChildren(adaptationSet,"SegmentBase")[0],segmentTimelineParentNode=segmentList||segmentTemplate,segmentTimeline=segmentTimelineParentNode&&findChildren(segmentTimelineParentNode,"SegmentTimeline")[0],segmentInitializationParentNode=segmentList||segmentBase||segmentTemplate,segmentInitialization=segmentInitializationParentNode&&findChildren(segmentInitializationParentNode,"Initialization")[0],template=segmentTemplate&&parseAttributes(segmentTemplate);template&&segmentInitialization?template.initialization=segmentInitialization&&parseAttributes(segmentInitialization):template&&template.initialization&&(template.initialization={sourceURL:template.initialization});const segmentInfo={template:template,segmentTimeline:segmentTimeline&&findChildren(segmentTimeline,"S").map((s=>parseAttributes(s))),list:segmentList&&merge$1(parseAttributes(segmentList),{segmentUrls:segmentUrls,initialization:parseAttributes(segmentInitialization)}),base:segmentBase&&merge$1(parseAttributes(segmentBase),{initialization:parseAttributes(segmentInitialization)})};return Object.keys(segmentInfo).forEach((key=>{segmentInfo[key]||delete segmentInfo[key]})),segmentInfo},toEventStream=period=>flatten(findChildren(period.node,"EventStream").map((eventStream=>{const eventStreamAttributes=parseAttributes(eventStream),schemeIdUri=eventStreamAttributes.schemeIdUri;return findChildren(eventStream,"Event").map((event=>{const eventAttributes=parseAttributes(event),presentationTime=eventAttributes.presentationTime||0,timescale=eventStreamAttributes.timescale||1,duration=eventAttributes.duration||0,start=presentationTime/timescale+period.attributes.start;return{schemeIdUri:schemeIdUri,value:eventStreamAttributes.value,id:eventAttributes.id,start:start,end:start+duration/timescale,messageData:getContent(event)||eventAttributes.messageData,contentEncoding:eventStreamAttributes.contentEncoding,presentationTimeOffset:eventStreamAttributes.presentationTimeOffset||0}}))}))),toRepresentations=(periodAttributes,periodBaseUrls,periodSegmentInfo)=>adaptationSet=>{const adaptationSetAttributes=parseAttributes(adaptationSet),adaptationSetBaseUrls=buildBaseUrls(periodBaseUrls,findChildren(adaptationSet,"BaseURL")),role=findChildren(adaptationSet,"Role")[0],roleAttributes={role:parseAttributes(role)};let attrs=merge$1(periodAttributes,adaptationSetAttributes,roleAttributes);const accessibility=findChildren(adaptationSet,"Accessibility")[0],captionServices=(service=>{if("urn:scte:dash:cc:cea-608:2015"===service.schemeIdUri)return("string"!=typeof service.value?[]:service.value.split(";")).map((value=>{let channel,language;return language=value,/^CC\d=/.test(value)?[channel,language]=value.split("="):/^CC\d$/.test(value)&&(channel=value),{channel:channel,language:language}}));if("urn:scte:dash:cc:cea-708:2015"===service.schemeIdUri)return("string"!=typeof service.value?[]:service.value.split(";")).map((value=>{const flags={channel:void 0,language:void 0,aspectRatio:1,easyReader:0,"3D":0};if(/=/.test(value)){const[channel,opts=""]=value.split("=");flags.channel=channel,flags.language=value,opts.split(",").forEach((opt=>{const[name,val]=opt.split(":");"lang"===name?flags.language=val:"er"===name?flags.easyReader=Number(val):"war"===name?flags.aspectRatio=Number(val):"3D"===name&&(flags["3D"]=Number(val))}))}else flags.language=value;return flags.channel&&(flags.channel="SERVICE"+flags.channel),flags}))})(parseAttributes(accessibility));captionServices&&(attrs=merge$1(attrs,{captionServices:captionServices}));const label=findChildren(adaptationSet,"Label")[0];if(label&&label.childNodes.length){const labelVal=label.childNodes[0].nodeValue.trim();attrs=merge$1(attrs,{label:labelVal})}const contentProtection=findChildren(adaptationSet,"ContentProtection").reduce(((acc,node)=>{const attributes=parseAttributes(node);attributes.schemeIdUri&&(attributes.schemeIdUri=attributes.schemeIdUri.toLowerCase());const keySystem=keySystemsMap[attributes.schemeIdUri];if(keySystem){acc[keySystem]={attributes:attributes};const psshNode=findChildren(node,"cenc:pssh")[0];if(psshNode){const pssh=getContent(psshNode);acc[keySystem].pssh=pssh&&decodeB64ToUint8Array(pssh)}}return acc}),{});Object.keys(contentProtection).length&&(attrs=merge$1(attrs,{contentProtection:contentProtection}));const segmentInfo=getSegmentInformation(adaptationSet),representations=findChildren(adaptationSet,"Representation"),adaptationSetSegmentInfo=merge$1(periodSegmentInfo,segmentInfo);return flatten(representations.map(((adaptationSetAttributes,adaptationSetBaseUrls,adaptationSetSegmentInfo)=>representation=>{const repBaseUrlElements=findChildren(representation,"BaseURL"),repBaseUrls=buildBaseUrls(adaptationSetBaseUrls,repBaseUrlElements),attributes=merge$1(adaptationSetAttributes,parseAttributes(representation)),representationSegmentInfo=getSegmentInformation(representation);return repBaseUrls.map((baseUrl=>({segmentInfo:merge$1(adaptationSetSegmentInfo,representationSegmentInfo),attributes:merge$1(attributes,baseUrl)})))})(attrs,adaptationSetBaseUrls,adaptationSetSegmentInfo)))},toAdaptationSets=(mpdAttributes,mpdBaseUrls)=>(period,index)=>{const periodBaseUrls=buildBaseUrls(mpdBaseUrls,findChildren(period.node,"BaseURL")),periodAttributes=merge$1(mpdAttributes,{periodStart:period.attributes.start});"number"==typeof period.attributes.duration&&(periodAttributes.periodDuration=period.attributes.duration);const adaptationSets=findChildren(period.node,"AdaptationSet"),periodSegmentInfo=getSegmentInformation(period.node);return flatten(adaptationSets.map(toRepresentations(periodAttributes,periodBaseUrls,periodSegmentInfo)))},generateContentSteeringInformation=(contentSteeringNodes,eventHandler)=>{if(contentSteeringNodes.length>1&&eventHandler({type:"warn",message:"The MPD manifest should contain no more than one ContentSteering tag"}),!contentSteeringNodes.length)return null;const infoFromContentSteeringTag=merge$1({serverURL:getContent(contentSteeringNodes[0])},parseAttributes(contentSteeringNodes[0]));return infoFromContentSteeringTag.queryBeforeStart="true"===infoFromContentSteeringTag.queryBeforeStart,infoFromContentSteeringTag},getPeriodStart=_ref27=>{let{attributes:attributes,priorPeriodAttributes:priorPeriodAttributes,mpdType:mpdType}=_ref27;return"number"==typeof attributes.start?attributes.start:priorPeriodAttributes&&"number"==typeof priorPeriodAttributes.start&&"number"==typeof priorPeriodAttributes.duration?priorPeriodAttributes.start+priorPeriodAttributes.duration:priorPeriodAttributes||"static"!==mpdType?null:0},inheritAttributes=function(mpd){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{manifestUri:manifestUri="",NOW:NOW=Date.now(),clientOffset:clientOffset=0,eventHandler:eventHandler=function(){}}=options,periodNodes=findChildren(mpd,"Period");if(!periodNodes.length)throw new Error(errors_INVALID_NUMBER_OF_PERIOD);const locations=findChildren(mpd,"Location"),mpdAttributes=parseAttributes(mpd),mpdBaseUrls=buildBaseUrls([{baseUrl:manifestUri}],findChildren(mpd,"BaseURL")),contentSteeringNodes=findChildren(mpd,"ContentSteering");mpdAttributes.type=mpdAttributes.type||"static",mpdAttributes.sourceDuration=mpdAttributes.mediaPresentationDuration||0,mpdAttributes.NOW=NOW,mpdAttributes.clientOffset=clientOffset,locations.length&&(mpdAttributes.locations=locations.map(getContent));const periods=[];return periodNodes.forEach(((node,index)=>{const attributes=parseAttributes(node),priorPeriod=periods[index-1];attributes.start=getPeriodStart({attributes:attributes,priorPeriodAttributes:priorPeriod?priorPeriod.attributes:null,mpdType:mpdAttributes.type}),periods.push({node:node,attributes:attributes})})),{locations:mpdAttributes.locations,contentSteeringInfo:generateContentSteeringInformation(contentSteeringNodes,eventHandler),representationInfo:flatten(periods.map(toAdaptationSets(mpdAttributes,mpdBaseUrls))),eventStream:flatten(periods.map(toEventStream))}},stringToMpdXml=manifestString=>{if(""===manifestString)throw new Error(errors_DASH_EMPTY_MANIFEST);const parser=new DOMParser;let xml,mpd;try{xml=parser.parseFromString(manifestString,"application/xml"),mpd=xml&&"MPD"===xml.documentElement.tagName?xml.documentElement:null}catch(e){}if(!mpd||mpd&&mpd.getElementsByTagName("parsererror").length>0)throw new Error(errors_DASH_INVALID_XML);return mpd},parseUTCTiming=manifestString=>(mpd=>{const UTCTimingNode=findChildren(mpd,"UTCTiming")[0];if(!UTCTimingNode)return null;const attributes=parseAttributes(UTCTimingNode);switch(attributes.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":attributes.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":attributes.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":attributes.method="DIRECT",attributes.value=Date.parse(attributes.value);break;default:throw new Error(errors_UNSUPPORTED_UTC_TIMING_SCHEME)}return attributes})(stringToMpdXml(manifestString));var MAX_UINT32=Math.pow(2,32),getUint64=function(uint8){var value,dv=new DataView(uint8.buffer,uint8.byteOffset,uint8.byteLength);return dv.getBigUint64?(value=dv.getBigUint64(0))0;i+=12,referenceCount--)result.references.push({referenceType:(128&data[i])>>>7,referencedSize:2147483647&view.getUint32(i),subsegmentDuration:view.getUint32(i+4),startsWithSap:!!(128&data[i+8]),sapType:(112&data[i+8])>>>4,sapDeltaTime:268435455&view.getUint32(i+8)});return result},ID3=toUint8([73,68,51]),getId3Offset=function getId3Offset(bytes,offset){return void 0===offset&&(offset=0),(bytes=toUint8(bytes)).length-offset<10||!bytesMatch(bytes,ID3,{offset:offset})?offset:(offset+=function(bytes,offset){void 0===offset&&(offset=0);var flags=(bytes=toUint8(bytes))[offset+5],returnSize=bytes[offset+6]<<21|bytes[offset+7]<<14|bytes[offset+8]<<7|bytes[offset+9];return(16&flags)>>4?returnSize+20:returnSize+10}(bytes,offset),getId3Offset(bytes,offset))},normalizePath$1=function(path){return"string"==typeof path?stringToBytes(path):path},findBox=function findBox(bytes,paths,complete){void 0===complete&&(complete=!1),paths=function(paths){return Array.isArray(paths)?paths.map((function(p){return normalizePath$1(p)})):[normalizePath$1(paths)]}(paths),bytes=toUint8(bytes);var results=[];if(!paths.length)return results;for(var i=0;i>>0,type=bytes.subarray(i+4,i+8);if(0===size)break;var end=i+size;if(end>bytes.length){if(complete)break;end=bytes.length}var data=bytes.subarray(i+8,end);bytesMatch(type,paths[0])&&(1===paths.length?results.push(data):results.push.apply(results,findBox(data,paths.slice(1),complete))),i=end}return results},EBML_TAGS={EBML:toUint8([26,69,223,163]),DocType:toUint8([66,130]),Segment:toUint8([24,83,128,103]),SegmentInfo:toUint8([21,73,169,102]),Tracks:toUint8([22,84,174,107]),Track:toUint8([174]),TrackNumber:toUint8([215]),DefaultDuration:toUint8([35,227,131]),TrackEntry:toUint8([174]),TrackType:toUint8([131]),FlagDefault:toUint8([136]),CodecID:toUint8([134]),CodecPrivate:toUint8([99,162]),VideoTrack:toUint8([224]),AudioTrack:toUint8([225]),Cluster:toUint8([31,67,182,117]),Timestamp:toUint8([231]),TimestampScale:toUint8([42,215,177]),BlockGroup:toUint8([160]),BlockDuration:toUint8([155]),Block:toUint8([161]),SimpleBlock:toUint8([163])},LENGTH_TABLE=[128,64,32,16,8,4,2,1],getvint=function(bytes,offset,removeLength,signed){void 0===removeLength&&(removeLength=!0),void 0===signed&&(signed=!1);var length=function(byte){for(var len=1,i=0;i=bytes.length)return bytes.length;var innerid=getvint(bytes,offset,!1);if(bytesMatch(id.bytes,innerid.bytes))return offset;var dataHeader=getvint(bytes,offset+innerid.length);return getInfinityDataSize(id,bytes,offset+dataHeader.length+dataHeader.value+innerid.length)},findEbml=function findEbml(bytes,paths){paths=function(paths){return Array.isArray(paths)?paths.map((function(p){return normalizePath(p)})):[normalizePath(paths)]}(paths),bytes=toUint8(bytes);var results=[];if(!paths.length)return results;for(var i=0;ibytes.length?bytes.length:dataStart+dataHeader.value,data=bytes.subarray(dataStart,dataEnd);bytesMatch(paths[0],id.bytes)&&(1===paths.length?results.push(data):results=results.concat(findEbml(data,paths.slice(1)))),i+=id.length+dataHeader.length+data.length}return results},NAL_TYPE_ONE=toUint8([0,0,0,1]),NAL_TYPE_TWO=toUint8([0,0,1]),EMULATION_PREVENTION=toUint8([0,0,3]),discardEmulationPreventionBytes=function(bytes){for(var positions=[],i=1;i>1&63),-1!==types.indexOf(nalType)&&(nalStart=i+nalOffset),i+=nalOffset+("h264"===dataType?1:2)}else i++}return bytes.subarray(0,0)},CONSTANTS={webm:toUint8([119,101,98,109]),matroska:toUint8([109,97,116,114,111,115,107,97]),flac:toUint8([102,76,97,67]),ogg:toUint8([79,103,103,83]),ac3:toUint8([11,119]),riff:toUint8([82,73,70,70]),avi:toUint8([65,86,73]),wav:toUint8([87,65,86,69]),"3gp":toUint8([102,116,121,112,51,103]),mp4:toUint8([102,116,121,112]),fmp4:toUint8([115,116,121,112]),mov:toUint8([102,116,121,112,113,116]),moov:toUint8([109,111,111,118]),moof:toUint8([109,111,111,102])},_isLikely={aac:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,[255,16],{offset:offset,mask:[255,22]})},mp3:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,[255,2],{offset:offset,mask:[255,6]})},webm:function(bytes){var docType=findEbml(bytes,[EBML_TAGS.EBML,EBML_TAGS.DocType])[0];return bytesMatch(docType,CONSTANTS.webm)},mkv:function(bytes){var docType=findEbml(bytes,[EBML_TAGS.EBML,EBML_TAGS.DocType])[0];return bytesMatch(docType,CONSTANTS.matroska)},mp4:function(bytes){return!_isLikely["3gp"](bytes)&&!_isLikely.mov(bytes)&&(!(!bytesMatch(bytes,CONSTANTS.mp4,{offset:4})&&!bytesMatch(bytes,CONSTANTS.fmp4,{offset:4}))||(!(!bytesMatch(bytes,CONSTANTS.moof,{offset:4})&&!bytesMatch(bytes,CONSTANTS.moov,{offset:4}))||void 0))},mov:function(bytes){return bytesMatch(bytes,CONSTANTS.mov,{offset:4})},"3gp":function(bytes){return bytesMatch(bytes,CONSTANTS["3gp"],{offset:4})},ac3:function(bytes){var offset=getId3Offset(bytes);return bytesMatch(bytes,CONSTANTS.ac3,{offset:offset})},ts:function(bytes){if(bytes.length<189&&bytes.length>=1)return 71===bytes[0];for(var i=0;i+188req&&req.responseURL&&url!==req.responseURL?req.responseURL:url,logger=source=>videojs.log.debug?videojs.log.debug.bind(videojs,"VHS:","".concat(source," >")):function(){};function merge(){const context=videojs.obj||videojs,fn=context.merge||context.mergeOptions;for(var _len24=arguments.length,args=new Array(_len24),_key24=0;_key24<_len24;_key24++)args[_key24]=arguments[_key24];return fn.apply(context,args)}function createTimeRanges(){const context=videojs.time||videojs,fn=context.createTimeRanges||context.createTimeRanges;for(var _len25=arguments.length,args=new Array(_len25),_key25=0;_key25<_len25;_key25++)args[_key25]=arguments[_key25];return fn.apply(context,args)}const filterRanges=function(timeRanges,predicate){const results=[];let i;if(timeRanges&&timeRanges.length)for(i=0;i=time}))},findNextRange=function(timeRanges,time){return filterRanges(timeRanges,(function(start){return start-.03333333333333333>=time}))},printableRange=range=>{const strArr=[];if(!range||!range.length)return"";for(let i=0;i "+range.end(i));return strArr.join(", ")},timeRangesToArray=timeRanges=>{const timeRangesList=[];for(let i=0;iend||(time+=startTime>start&&startTime<=end?end-startTime:end-start)}return time},segmentDurationWithParts=(playlist,segment)=>{if(!segment.preload)return segment.duration;let result=0;return(segment.parts||[]).forEach((function(p){result+=p.duration})),(segment.preloadHints||[]).forEach((function(p){"PART"===p.type&&(result+=playlist.partTargetDuration)})),result},getPartsAndSegments=playlist=>(playlist.segments||[]).reduce(((acc,segment,si)=>(segment.parts?segment.parts.forEach((function(part,pi){acc.push({duration:part.duration,segmentIndex:si,partIndex:pi,part:part,segment:segment})})):acc.push({duration:segment.duration,segmentIndex:si,partIndex:null,segment:segment,part:null}),acc)),[]),getLastParts=media=>{const lastSegment=media.segments&&media.segments.length&&media.segments[media.segments.length-1];return lastSegment&&lastSegment.parts||[]},getKnownPartCount=_ref28=>{let{preloadSegment:preloadSegment}=_ref28;if(!preloadSegment)return;const{parts:parts,preloadHints:preloadHints}=preloadSegment;let partCount=(preloadHints||[]).reduce(((count,hint)=>count+("PART"===hint.type?1:0)),0);return partCount+=parts&&parts.length?parts.length:0,partCount},liveEdgeDelay=(main,media)=>{if(media.endList)return 0;if(main&&main.suggestedPresentationDelay)return main.suggestedPresentationDelay;const hasParts=getLastParts(media).length>0;return hasParts&&media.serverControl&&media.serverControl.partHoldBack?media.serverControl.partHoldBack:hasParts&&media.partTargetDuration?3*media.partTargetDuration:media.serverControl&&media.serverControl.holdBack?media.serverControl.holdBack:media.targetDuration?3*media.targetDuration:0},intervalDuration=function(playlist,endSequence,expired){if(void 0===endSequence&&(endSequence=playlist.mediaSequence+playlist.segments.length),endSequenceendIndex&&([startIndex,endIndex]=[endIndex,startIndex]),startIndex<0){for(let i=startIndex;iDate.now()},isIncompatible=function(playlist){return playlist.excludeUntil&&playlist.excludeUntil===1/0},isEnabled=function(playlist){const excluded=isExcluded(playlist);return!playlist.disabled&&!excluded},hasAttribute=function(attr,playlist){return playlist.attributes&&playlist.attributes[attr]},isLowestEnabledRendition=(main,media)=>{if(1===main.playlists.length)return!0;const currentBandwidth=media.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===main.playlists.filter((playlist=>!!isEnabled(playlist)&&(playlist.attributes.BANDWIDTH||0)!(!a&&!b||!a&&b||a&&!b)&&(a===b||(!(!a.id||!b.id||a.id!==b.id)||(!(!a.resolvedUri||!b.resolvedUri||a.resolvedUri!==b.resolvedUri)||!(!a.uri||!b.uri||a.uri!==b.uri)))),someAudioVariant=function(main,callback){const AUDIO=main&&main.mediaGroups&&main.mediaGroups.AUDIO||{};let found=!1;for(const groupName in AUDIO){for(const label in AUDIO[groupName])if(found=callback(AUDIO[groupName][label]),found)break;if(found)break}return!!found},isAudioOnly=main=>{if(!main||!main.playlists||!main.playlists.length){return someAudioVariant(main,(variant=>variant.playlists&&variant.playlists.length||variant.uri))}for(let i=0;iisAudioCodec(c))))continue;if(!someAudioVariant(main,(variant=>playlistMatch(playlist,variant))))return!1}return!0};var Playlist={liveEdgeDelay:liveEdgeDelay,duration:duration,seekable:function(playlist,expired,liveEdgePadding){const seekableStart=expired||0;let seekableEnd=playlistEnd(playlist,expired,!0,liveEdgePadding);return null===seekableEnd?createTimeRanges():(seekableEnd0)for(let i=startIndex-1;i>=0;i--){const partAndSegment=partsAndSegments[i];if(time+=partAndSegment.duration,exactManifestTimings){if(time<0)continue}else if(time+.03333333333333333<=0)continue;return{partIndex:partAndSegment.partIndex,segmentIndex:partAndSegment.segmentIndex,startTime:startTime-sumDurations({defaultDuration:playlist.targetDuration,durationList:partsAndSegments,startIndex:startIndex,endIndex:i})}}return{partIndex:partsAndSegments[0]&&partsAndSegments[0].partIndex||null,segmentIndex:partsAndSegments[0]&&partsAndSegments[0].segmentIndex||0,startTime:currentTime}}if(startIndex<0){for(let i=startIndex;i<0;i++)if(time-=playlist.targetDuration,time<0)return{partIndex:partsAndSegments[0]&&partsAndSegments[0].partIndex||null,segmentIndex:partsAndSegments[0]&&partsAndSegments[0].segmentIndex||0,startTime:currentTime};startIndex=0}for(let i=startIndex;i.03333333333333333&&time+.03333333333333333>=0;if(!(0===time)&&!isExtremelyCloseToTheEnd||i===partsAndSegments.length-1){if(exactManifestTimings){if(time>0)continue}else if(time-.03333333333333333>=0)continue;return{partIndex:partAndSegment.partIndex,segmentIndex:partAndSegment.segmentIndex,startTime:startTime+sumDurations({defaultDuration:playlist.targetDuration,durationList:partsAndSegments,startIndex:startIndex,endIndex:i})}}}return{segmentIndex:partsAndSegments[partsAndSegments.length-1].segmentIndex,partIndex:partsAndSegments[partsAndSegments.length-1].partIndex,startTime:currentTime}},isEnabled:isEnabled,isDisabled:function(playlist){return playlist.disabled},isExcluded:isExcluded,isIncompatible:isIncompatible,playlistEnd:playlistEnd,isAes:function(media){for(let i=0;i3&&void 0!==arguments[3]?arguments[3]:0;if(!hasAttribute("BANDWIDTH",playlist))return NaN;const size=segmentDuration*playlist.attributes.BANDWIDTH;return(size-8*bytesReceived)/bandwidth},isLowestEnabledRendition:isLowestEnabledRendition,isAudioOnly:isAudioOnly,playlistMatch:playlistMatch,segmentDurationWithParts:segmentDurationWithParts};const{log:log}=videojs,createPlaylistID=(index,uri)=>"".concat(index,"-").concat(uri),groupID=(type,group,label)=>"placeholder-uri-".concat(type,"-").concat(group,"-").concat(label),forEachMediaGroup=(main,callback)=>{main.mediaGroups&&["AUDIO","SUBTITLES"].forEach((mediaType=>{if(main.mediaGroups[mediaType])for(const groupKey in main.mediaGroups[mediaType])for(const labelKey in main.mediaGroups[mediaType][groupKey]){const mediaProperties=main.mediaGroups[mediaType][groupKey][labelKey];callback(mediaProperties,mediaType,groupKey,labelKey)}}))},setupMediaPlaylist=_ref32=>{let{playlist:playlist,uri:uri,id:id}=_ref32;playlist.id=id,playlist.playlistErrors_=0,uri&&(playlist.uri=uri),playlist.attributes=playlist.attributes||{}},setupMediaPlaylists=main=>{let i=main.playlists.length;for(;i--;){const playlist=main.playlists[i];setupMediaPlaylist({playlist:playlist,id:createPlaylistID(i,playlist.uri)}),playlist.resolvedUri=resolveUrl(main.uri,playlist.uri),main.playlists[playlist.id]=playlist,main.playlists[playlist.uri]=playlist,playlist.attributes.BANDWIDTH||log.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute.")}},resolveMediaGroupUris=main=>{forEachMediaGroup(main,(properties=>{properties.uri&&(properties.resolvedUri=resolveUrl(main.uri,properties.uri))}))},addPropertiesToMain=function(main,uri){let createGroupID=arguments.length>2&&void 0!==arguments[2]?arguments[2]:groupID;main.uri=uri;for(let i=0;i{if(!properties.playlists||!properties.playlists.length){if(audioOnlyMain&&"AUDIO"===mediaType&&!properties.uri)for(let i=0;i0&&void 0!==arguments[0]?arguments[0]:[];if(null!==this.offset_)return;if(!segments.length)return;const[firstSegment]=segments;void 0!==firstSegment.programDateTime&&(this.offset_=firstSegment.programDateTime/1e3)}setPendingDateRanges(){let dateRanges=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];if(!dateRanges.length)return;const[dateRange]=dateRanges,startTime=dateRange.startDate.getTime();this.trimProcessedDateRanges_(startTime),this.pendingDateRanges_=dateRanges.reduce(((map,pendingDateRange)=>(map.set(pendingDateRange.id,pendingDateRange),map)),new Map)}processDateRange(dateRange){this.pendingDateRanges_.delete(dateRange.id),this.processedDateRanges_.set(dateRange.id,dateRange)}getDateRangesToProcess(){if(null===this.offset_)return[];const dateRangeClasses={},dateRangesToProcess=[];this.pendingDateRanges_.forEach(((dateRange,id)=>{if(!this.processedDateRanges_.has(id)&&(dateRange.startTime=dateRange.startDate.getTime()/1e3-this.offset_,dateRange.processDateRange=()=>this.processDateRange(dateRange),dateRangesToProcess.push(dateRange),dateRange.class))if(dateRangeClasses[dateRange.class]){const length=dateRangeClasses[dateRange.class].push(dateRange);dateRange.classListIndex=length-1}else dateRangeClasses[dateRange.class]=[dateRange],dateRange.classListIndex=0}));for(const dateRange of dateRangesToProcess){const classList=dateRangeClasses[dateRange.class]||[];dateRange.endDate?dateRange.endTime=dateRange.endDate.getTime()/1e3-this.offset_:dateRange.endOnNext&&classList[dateRange.classListIndex+1]?dateRange.endTime=classList[dateRange.classListIndex+1].startTime:dateRange.duration?dateRange.endTime=dateRange.startTime+dateRange.duration:dateRange.plannedDuration?dateRange.endTime=dateRange.startTime+dateRange.plannedDuration:dateRange.endTime=dateRange.startTime}return dateRangesToProcess}trimProcessedDateRanges_(startTime){new Map(this.processedDateRanges_).forEach(((dateRange,id)=>{dateRange.startDate.getTime(){if(!a)return b;const result=merge(a,b);if(a.preloadHints&&!b.preloadHints&&delete result.preloadHints,a.parts&&!b.parts)delete result.parts;else if(a.parts&&b.parts)for(let i=0;i{const oldSegments=original.slice(),newSegments=update.slice();offset=offset||0;const result=[];let currentMap;for(let newIndex=0;newIndex{!segment.resolvedUri&&segment.uri&&(segment.resolvedUri=resolveUrl(baseUri,segment.uri)),segment.key&&!segment.key.resolvedUri&&(segment.key.resolvedUri=resolveUrl(baseUri,segment.key.uri)),segment.map&&!segment.map.resolvedUri&&(segment.map.resolvedUri=resolveUrl(baseUri,segment.map.uri)),segment.map&&segment.map.key&&!segment.map.key.resolvedUri&&(segment.map.key.resolvedUri=resolveUrl(baseUri,segment.map.key.uri)),segment.parts&&segment.parts.length&&segment.parts.forEach((p=>{p.resolvedUri||(p.resolvedUri=resolveUrl(baseUri,p.uri))})),segment.preloadHints&&segment.preloadHints.length&&segment.preloadHints.forEach((p=>{p.resolvedUri||(p.resolvedUri=resolveUrl(baseUri,p.uri))}))},getAllSegments=function(media){const segments=media.segments||[],preloadSegment=media.preloadSegment;if(preloadSegment&&preloadSegment.parts&&preloadSegment.parts.length){if(preloadSegment.preloadHints)for(let i=0;ia===b||a.segments&&b.segments&&a.segments.length===b.segments.length&&a.endList===b.endList&&a.mediaSequence===b.mediaSequence&&a.preloadSegment===b.preloadSegment,updateMain$1=function(main,newMedia){let unchangedCheck=arguments.length>2&&void 0!==arguments[2]?arguments[2]:isPlaylistUnchanged;const result=merge(main,{}),oldMedia=result.playlists[newMedia.id];if(!oldMedia)return null;if(unchangedCheck(oldMedia,newMedia))return null;newMedia.segments=getAllSegments(newMedia);const mergedPlaylist=merge(oldMedia,newMedia);if(mergedPlaylist.preloadSegment&&!newMedia.preloadSegment&&delete mergedPlaylist.preloadSegment,oldMedia.segments){if(newMedia.skip){newMedia.segments=newMedia.segments||[];for(let i=0;i{resolveSegmentUris(segment,mergedPlaylist.resolvedUri)}));for(let i=0;i{if(properties.playlists)for(let i=0;i{const segments=media.segments||[],lastSegment=segments[segments.length-1],lastPart=lastSegment&&lastSegment.parts&&lastSegment.parts[lastSegment.parts.length-1],lastDuration=lastPart&&lastPart.duration||lastSegment&&lastSegment.duration;return update&&lastDuration?1e3*lastDuration:500*(media.partTargetDuration||media.targetDuration||10)};class PlaylistLoader extends EventTarget$1{constructor(src,vhs){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(super(),!src)throw new Error("A non-empty playlist URL or object is required");this.logger_=logger("PlaylistLoader");const{withCredentials:withCredentials=!1}=options;this.src=src,this.vhs_=vhs,this.withCredentials=withCredentials,this.addDateRangesToTextTrack_=options.addDateRangesToTextTrack;const vhsOptions=vhs.options_;this.customTagParsers=vhsOptions&&vhsOptions.customTagParsers||[],this.customTagMappers=vhsOptions&&vhsOptions.customTagMappers||[],this.llhls=vhsOptions&&vhsOptions.llhls,this.dateRangesStorage_=new DateRangesStorage,this.state="HAVE_NOTHING",this.handleMediaupdatetimeout_=this.handleMediaupdatetimeout_.bind(this),this.on("mediaupdatetimeout",this.handleMediaupdatetimeout_),this.on("loadedplaylist",this.handleLoadedPlaylist_.bind(this))}handleLoadedPlaylist_(){const mediaPlaylist=this.media();if(!mediaPlaylist)return;this.dateRangesStorage_.setOffset(mediaPlaylist.segments),this.dateRangesStorage_.setPendingDateRanges(mediaPlaylist.dateRanges);const availableDateRanges=this.dateRangesStorage_.getDateRangesToProcess();availableDateRanges.length&&this.addDateRangesToTextTrack_&&this.addDateRangesToTextTrack_(availableDateRanges)}handleMediaupdatetimeout_(){if("HAVE_METADATA"!==this.state)return;const media=this.media();let uri=resolveUrl(this.main.uri,media.uri);this.llhls&&(uri=((uri,media)=>{if(media.endList||!media.serverControl)return uri;const parameters={};if(media.serverControl.canBlockReload){const{preloadSegment:preloadSegment}=media;let nextMSN=media.mediaSequence+media.segments.length;if(preloadSegment){const parts=preloadSegment.parts||[],nextPart=getKnownPartCount(media)-1;nextPart>-1&&nextPart!==parts.length-1&&(parameters._HLS_part=nextPart),(nextPart>-1||parts.length)&&nextMSN--}parameters._HLS_msn=nextMSN}if(media.serverControl&&media.serverControl.canSkipUntil&&(parameters._HLS_skip=media.serverControl.canSkipDateranges?"v2":"YES"),Object.keys(parameters).length){const parsedUri=new window.URL(uri);["_HLS_skip","_HLS_msn","_HLS_part"].forEach((function(name){parameters.hasOwnProperty(name)&&parsedUri.searchParams.set(name,parameters[name])})),uri=parsedUri.toString()}return uri})(uri,media)),this.state="HAVE_CURRENT_METADATA",this.request=this.vhs_.xhr({uri:uri,withCredentials:this.withCredentials},((error,req)=>{if(this.request)return error?this.playlistRequestError(this.request,this.media(),"HAVE_METADATA"):void this.haveMetadata({playlistString:this.request.responseText,url:this.media().uri,id:this.media().id})}))}playlistRequestError(xhr,playlist,startingState){const{uri:uri,id:id}=playlist;this.request=null,startingState&&(this.state=startingState),this.error={playlist:this.main.playlists[id],status:xhr.status,message:"HLS playlist request error at URL: ".concat(uri,"."),responseText:xhr.responseText,code:xhr.status>=500?4:2},this.trigger("error")}parseManifest_(_ref33){let{url:url,manifestString:manifestString}=_ref33;return(_ref31=>{let{onwarn:onwarn,oninfo:oninfo,manifestString:manifestString,customTagParsers:customTagParsers=[],customTagMappers:customTagMappers=[],llhls:llhls}=_ref31;const parser=new Parser;onwarn&&parser.on("warn",onwarn),oninfo&&parser.on("info",oninfo),customTagParsers.forEach((customParser=>parser.addParser(customParser))),customTagMappers.forEach((mapper=>parser.addTagMapper(mapper))),parser.push(manifestString),parser.end();const manifest=parser.manifest;if(llhls||(["preloadSegment","skip","serverControl","renditionReports","partInf","partTargetDuration"].forEach((function(k){manifest.hasOwnProperty(k)&&delete manifest[k]})),manifest.segments&&manifest.segments.forEach((function(segment){["parts","preloadHints"].forEach((function(k){segment.hasOwnProperty(k)&&delete segment[k]}))}))),!manifest.targetDuration){let targetDuration=10;manifest.segments&&manifest.segments.length&&(targetDuration=manifest.segments.reduce(((acc,s)=>Math.max(acc,s.duration)),0)),onwarn&&onwarn({message:"manifest has no targetDuration defaulting to ".concat(targetDuration)}),manifest.targetDuration=targetDuration}const parts=getLastParts(manifest);if(parts.length&&!manifest.partTargetDuration){const partTargetDuration=parts.reduce(((acc,p)=>Math.max(acc,p.duration)),0);onwarn&&(onwarn({message:"manifest has no partTargetDuration defaulting to ".concat(partTargetDuration)}),log.error("LL-HLS manifest has parts but lacks required #EXT-X-PART-INF:PART-TARGET value. See https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-09#section-4.4.3.7. Playback is not guaranteed.")),manifest.partTargetDuration=partTargetDuration}return manifest})({onwarn:_ref34=>{let{message:message}=_ref34;return this.logger_("m3u8-parser warn for ".concat(url,": ").concat(message))},oninfo:_ref35=>{let{message:message}=_ref35;return this.logger_("m3u8-parser info for ".concat(url,": ").concat(message))},manifestString:manifestString,customTagParsers:this.customTagParsers,customTagMappers:this.customTagMappers,llhls:this.llhls})}haveMetadata(_ref36){let{playlistString:playlistString,playlistObject:playlistObject,url:url,id:id}=_ref36;this.request=null,this.state="HAVE_METADATA";const playlist=playlistObject||this.parseManifest_({url:url,manifestString:playlistString});playlist.lastRequest=Date.now(),setupMediaPlaylist({playlist:playlist,uri:url,id:id});const update=updateMain$1(this.main,playlist);this.targetDuration=playlist.partTargetDuration||playlist.targetDuration,this.pendingMedia_=null,update?(this.main=update,this.media_=this.main.playlists[id]):this.trigger("playlistunchanged"),this.updateMediaUpdateTimeout_(refreshDelay(this.media(),!!update)),this.trigger("loadedplaylist")}dispose(){this.trigger("dispose"),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),window.clearTimeout(this.finalRenditionTimeout),this.dateRangesStorage_=new DateRangesStorage,this.off()}stopRequest(){if(this.request){const oldRequest=this.request;this.request=null,oldRequest.onreadystatechange=null,oldRequest.abort()}}media(playlist,shouldDelay){if(!playlist)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof playlist){if(!this.main.playlists[playlist])throw new Error("Unknown playlist URI: "+playlist);playlist=this.main.playlists[playlist]}if(window.clearTimeout(this.finalRenditionTimeout),shouldDelay){const delay=(playlist.partTargetDuration||playlist.targetDuration)/2*1e3||5e3;return void(this.finalRenditionTimeout=window.setTimeout(this.media.bind(this,playlist,!1),delay))}const startingState=this.state,mediaChange=!this.media_||playlist.id!==this.media_.id,mainPlaylistRef=this.main.playlists[playlist.id];if(mainPlaylistRef&&mainPlaylistRef.endList||playlist.endList&&playlist.segments.length)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=playlist,void(mediaChange&&(this.trigger("mediachanging"),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")));if(this.updateMediaUpdateTimeout_(refreshDelay(playlist,!0)),mediaChange){if(this.state="SWITCHING_MEDIA",this.request){if(playlist.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.pendingMedia_=playlist,this.request=this.vhs_.xhr({uri:playlist.resolvedUri,withCredentials:this.withCredentials},((error,req)=>{if(this.request){if(playlist.lastRequest=Date.now(),playlist.resolvedUri=resolveManifestRedirect(playlist.resolvedUri,req),error)return this.playlistRequestError(this.request,playlist,startingState);this.haveMetadata({playlistString:req.responseText,url:playlist.uri,id:playlist.id}),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")}}))}}pause(){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.stopRequest(),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MAIN_MANIFEST":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")}load(shouldDelay){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null);const media=this.media();if(shouldDelay){const delay=media?(media.partTargetDuration||media.targetDuration)/2*1e3:5e3;this.mediaUpdateTimeout=window.setTimeout((()=>{this.mediaUpdateTimeout=null,this.load()}),delay)}else this.started?media&&!media.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()}updateMediaUpdateTimeout_(delay){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.media()&&!this.media().endList&&(this.mediaUpdateTimeout=window.setTimeout((()=>{this.mediaUpdateTimeout=null,this.trigger("mediaupdatetimeout"),this.updateMediaUpdateTimeout_(delay)}),delay))}start(){if(this.started=!0,"object"==typeof this.src)return this.src.uri||(this.src.uri=window.location.href),this.src.resolvedUri=this.src.uri,void setTimeout((()=>{this.setupInitialPlaylist(this.src)}),0);this.request=this.vhs_.xhr({uri:this.src,withCredentials:this.withCredentials},((error,req)=>{if(!this.request)return;if(this.request=null,error)return this.error={status:req.status,message:"HLS playlist request error at URL: ".concat(this.src,"."),responseText:req.responseText,code:2},"HAVE_NOTHING"===this.state&&(this.started=!1),this.trigger("error");this.src=resolveManifestRedirect(this.src,req);const manifest=this.parseManifest_({manifestString:req.responseText,url:this.src});this.setupInitialPlaylist(manifest)}))}srcUri(){return"string"==typeof this.src?this.src:this.src.uri}setupInitialPlaylist(manifest){if(this.state="HAVE_MAIN_MANIFEST",manifest.playlists)return this.main=manifest,addPropertiesToMain(this.main,this.srcUri()),manifest.playlists.forEach((playlist=>{playlist.segments=getAllSegments(playlist),playlist.segments.forEach((segment=>{resolveSegmentUris(segment,playlist.resolvedUri)}))})),this.trigger("loadedplaylist"),void(this.request||this.media(this.main.playlists[0]));const uri=this.srcUri()||window.location.href;this.main=((media,uri)=>{const id=createPlaylistID(0,uri),main={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:window.location.href,resolvedUri:window.location.href,playlists:[{uri:uri,id:id,resolvedUri:uri,attributes:{}}]};return main.playlists[id]=main.playlists[0],main.playlists[uri]=main.playlists[0],main})(0,uri),this.haveMetadata({playlistObject:manifest,url:uri,id:this.main.playlists[0].id}),this.trigger("loadedmetadata")}updateOrDeleteClone(clone,isUpdate){const main=this.main,pathway=clone.ID;let i=main.playlists.length;for(;i--;){const p=main.playlists[i];if(p.attributes["PATHWAY-ID"]===pathway){const oldPlaylistUri=p.resolvedUri,oldPlaylistId=p.id;if(isUpdate){const newPlaylistUri=this.createCloneURI_(p.resolvedUri,clone),newPlaylistId=createPlaylistID(pathway,newPlaylistUri),attributes=this.createCloneAttributes_(pathway,p.attributes),updatedPlaylist=this.createClonePlaylist_(p,newPlaylistId,clone,attributes);main.playlists[i]=updatedPlaylist,main.playlists[newPlaylistId]=updatedPlaylist,main.playlists[newPlaylistUri]=updatedPlaylist}else main.playlists.splice(i,1);delete main.playlists[oldPlaylistId],delete main.playlists[oldPlaylistUri]}}this.updateOrDeleteCloneMedia(clone,isUpdate)}updateOrDeleteCloneMedia(clone,isUpdate){const main=this.main,id=clone.ID;["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((mediaType=>{if(main.mediaGroups[mediaType]&&main.mediaGroups[mediaType][id])for(const groupKey in main.mediaGroups[mediaType])if(groupKey===id){for(const labelKey in main.mediaGroups[mediaType][groupKey]){main.mediaGroups[mediaType][groupKey][labelKey].playlists.forEach(((p,i)=>{const oldMediaPlaylist=main.playlists[p.id],oldPlaylistId=oldMediaPlaylist.id,oldPlaylistUri=oldMediaPlaylist.resolvedUri;delete main.playlists[oldPlaylistId],delete main.playlists[oldPlaylistUri]}))}delete main.mediaGroups[mediaType][groupKey]}})),isUpdate&&this.createClonedMediaGroups_(clone)}addClonePathway(clone){let basePlaylist=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const main=this.main,index=main.playlists.length,uri=this.createCloneURI_(basePlaylist.resolvedUri,clone),playlistId=createPlaylistID(clone.ID,uri),attributes=this.createCloneAttributes_(clone.ID,basePlaylist.attributes),playlist=this.createClonePlaylist_(basePlaylist,playlistId,clone,attributes);main.playlists[index]=playlist,main.playlists[playlistId]=playlist,main.playlists[uri]=playlist,this.createClonedMediaGroups_(clone)}createClonedMediaGroups_(clone){const id=clone.ID,baseID=clone["BASE-ID"],main=this.main;["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((mediaType=>{if(main.mediaGroups[mediaType]&&!main.mediaGroups[mediaType][id])for(const groupKey in main.mediaGroups[mediaType])if(groupKey===baseID){main.mediaGroups[mediaType][id]={};for(const labelKey in main.mediaGroups[mediaType][groupKey]){const oldMedia=main.mediaGroups[mediaType][groupKey][labelKey];main.mediaGroups[mediaType][id][labelKey]=_extends$1({},oldMedia);const newMedia=main.mediaGroups[mediaType][id][labelKey],newUri=this.createCloneURI_(oldMedia.resolvedUri,clone);newMedia.resolvedUri=newUri,newMedia.uri=newUri,newMedia.playlists=[],oldMedia.playlists.forEach(((p,i)=>{const oldMediaPlaylist=main.playlists[p.id],group=groupID(mediaType,id,labelKey),newPlaylistID=createPlaylistID(id,group);if(oldMediaPlaylist&&!main.playlists[newPlaylistID]){const newMediaPlaylist=this.createClonePlaylist_(oldMediaPlaylist,newPlaylistID,clone),newPlaylistUri=newMediaPlaylist.resolvedUri;main.playlists[newPlaylistID]=newMediaPlaylist,main.playlists[newPlaylistUri]=newMediaPlaylist}newMedia.playlists[i]=this.createClonePlaylist_(p,newPlaylistID,clone)}))}}}))}createClonePlaylist_(basePlaylist,id,clone,attributes){const uri=this.createCloneURI_(basePlaylist.resolvedUri,clone),newProps={resolvedUri:uri,uri:uri,id:id};return basePlaylist.segments&&(newProps.segments=[]),attributes&&(newProps.attributes=attributes),merge(basePlaylist,newProps)}createCloneURI_(baseURI,clone){const uri=new URL(baseURI);uri.hostname=clone["URI-REPLACEMENT"].HOST;const params=clone["URI-REPLACEMENT"].PARAMS;for(const key of Object.keys(params))uri.searchParams.set(key,params[key]);return uri.href}createCloneAttributes_(id,oldAttributes){const attributes={"PATHWAY-ID":id};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((mediaType=>{oldAttributes[mediaType]&&(attributes[mediaType]=id)})),attributes}getKeyIdSet(playlist){if(playlist.contentProtection){const keyIds=new Set;for(const keysystem in playlist.contentProtection){const keyId=playlist.contentProtection[keysystem].attributes.keyId;keyId&&keyIds.add(keyId.toLowerCase())}return keyIds}}}const{xhr:videojsXHR}=videojs,callbackWrapper=function(request,error,response,callback){const reqResponse="arraybuffer"===request.responseType?request.response:request.responseText;!error&&reqResponse&&(request.responseTime=Date.now(),request.roundTripTime=request.responseTime-request.requestTime,request.bytesReceived=reqResponse.byteLength||reqResponse.length,request.bandwidth||(request.bandwidth=Math.floor(request.bytesReceived/request.roundTripTime*8*1e3))),response.headers&&(request.responseHeaders=response.headers),error&&"ETIMEDOUT"===error.code&&(request.timedout=!0),error||request.aborted||200===response.statusCode||206===response.statusCode||0===response.statusCode||(error=new Error("XHR Failed with a response of: "+(request&&(reqResponse||request.responseText)))),callback(error,request)},xhrFactory=function(){const xhr=function XhrFunction(options,callback){options=merge({timeout:45e3},options);const beforeRequest=XhrFunction.beforeRequest||videojs.Vhs.xhr.beforeRequest,_requestCallbackSet=XhrFunction._requestCallbackSet||videojs.Vhs.xhr._requestCallbackSet||new Set,_responseCallbackSet=XhrFunction._responseCallbackSet||videojs.Vhs.xhr._responseCallbackSet;beforeRequest&&"function"==typeof beforeRequest&&(videojs.log.warn("beforeRequest is deprecated, use onRequest instead."),_requestCallbackSet.add(beforeRequest));const xhrMethod=!0===videojs.Vhs.xhr.original?videojsXHR:videojs.Vhs.xhr,beforeRequestOptions=((requestSet,options)=>{if(!requestSet||!requestSet.size)return;let newOptions=options;return requestSet.forEach((requestCallback=>{newOptions=requestCallback(newOptions)})),newOptions})(_requestCallbackSet,options);_requestCallbackSet.delete(beforeRequest);const request=xhrMethod(beforeRequestOptions||options,(function(error,response){return((responseSet,request,error,response)=>{responseSet&&responseSet.size&&responseSet.forEach((responseCallback=>{responseCallback(request,error,response)}))})(_responseCallbackSet,request,error,response),callbackWrapper(request,error,response,callback)})),originalAbort=request.abort;return request.abort=function(){return request.aborted=!0,originalAbort.apply(request,arguments)},request.uri=options.uri,request.requestTime=Date.now(),request};return xhr.original=!0,xhr},segmentXhrHeaders=function(segment){const headers={};return segment.byterange&&(headers.Range=function(byterange){let byterangeEnd;const byterangeStart=byterange.offset;return byterangeEnd="bigint"==typeof byterange.offset||"bigint"==typeof byterange.length?window.BigInt(byterange.offset)+window.BigInt(byterange.length)-window.BigInt(1):byterange.offset+byterange.length-1,"bytes="+byterangeStart+"-"+byterangeEnd}(segment.byterange)),headers},textRange=function(range,i){return range.start(i)+"-"+range.end(i)},formatHexString=function(e,i){const value=e.toString(16);return"00".substring(0,2-value.length)+value+(i%2?" ":"")},formatAsciiString=function(e){return e>=32&&e<126?String.fromCharCode(e):"."},createTransferableMessage=function(message){const transferable={};return Object.keys(message).forEach((key=>{const value=message[key];isArrayBufferView(value)?transferable[key]={bytes:value.buffer,byteOffset:value.byteOffset,byteLength:value.byteLength}:transferable[key]=value})),transferable},initSegmentId=function(initSegment){const byterange=initSegment.byterange||{length:1/0,offset:0};return[byterange.length,byterange.offset,initSegment.resolvedUri].join(",")},segmentKeyId=function(key){return key.resolvedUri},hexDump=data=>{const bytes=Array.prototype.slice.call(data);let hex,ascii,result="";for(let j=0;j{let{bytes:bytes}=_ref37;return hexDump(bytes)},textRanges:ranges=>{let i,result="";for(i=0;i{let{playlist:playlist,time:time,callback:callback}=_ref38;if(!callback)throw new Error("getProgramTime: callback must be provided");if(!playlist||void 0===time)return callback({message:"getProgramTime: playlist and time must be provided"});const matchedSegment=((time,playlist)=>{if(!playlist||!playlist.segments||0===playlist.segments.length)return null;let segment,segmentEnd=0;for(let i=0;isegmentEnd){if(time>segmentEnd+.25*lastSegment.duration)return null;segment=lastSegment}return{segment:segment,estimatedStart:segment.videoTimingInfo?segment.videoTimingInfo.transmuxedPresentationStart:segmentEnd-segment.duration,type:segment.videoTimingInfo?"accurate":"estimate"}})(time,playlist);if(!matchedSegment)return callback({message:"valid programTime was not found"});if("estimate"===matchedSegment.type)return callback({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:matchedSegment.estimatedStart});const programTimeObject={mediaSeconds:time},programTime=((playerTime,segment)=>{if(!segment.dateTimeObject)return null;const transmuxerPrependedSeconds=segment.videoTimingInfo.transmuxerPrependedSeconds,offsetFromSegmentStart=playerTime-(segment.videoTimingInfo.transmuxedPresentationStart+transmuxerPrependedSeconds);return new Date(segment.dateTimeObject.getTime()+1e3*offsetFromSegmentStart)})(time,matchedSegment.segment);return programTime&&(programTimeObject.programDateTime=programTime.toISOString()),callback(null,programTimeObject)},seekToProgramTime=_ref39=>{let{programTime:programTime,playlist:playlist,retryCount:retryCount=2,seekTo:seekTo,pauseAfterSeek:pauseAfterSeek=!0,tech:tech,callback:callback}=_ref39;if(!callback)throw new Error("seekToProgramTime: callback must be provided");if(void 0===programTime||!playlist||!seekTo)return callback({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"});if(!playlist.endList&&!tech.hasStarted_)return callback({message:"player must be playing a live stream to start buffering"});if(!(playlist=>{if(!playlist.segments||0===playlist.segments.length)return!1;for(let i=0;i{let dateTimeObject;try{dateTimeObject=new Date(programTime)}catch(e){return null}if(!playlist||!playlist.segments||0===playlist.segments.length)return null;let segment=playlist.segments[0];if(dateTimeObjectnew Date(lastSegmentStart.getTime()+1e3*lastSegmentDuration)?null:(dateTimeObject>new Date(lastSegmentStart)&&(segment=lastSegment),{segment:segment,estimatedStart:segment.videoTimingInfo?segment.videoTimingInfo.transmuxedPresentationStart:Playlist.duration(playlist,playlist.mediaSequence+playlist.segments.indexOf(segment)),type:segment.videoTimingInfo?"accurate":"estimate"})})(programTime,playlist);if(!matchedSegment)return callback({message:"".concat(programTime," was not found in the stream")});const segment=matchedSegment.segment,mediaOffset=((comparisonTimeStamp,programTime)=>{let segmentDateTime,programDateTime;try{segmentDateTime=new Date(comparisonTimeStamp),programDateTime=new Date(programTime)}catch(e){}const segmentTimeEpoch=segmentDateTime.getTime();return(programDateTime.getTime()-segmentTimeEpoch)/1e3})(segment.dateTimeObject,programTime);if("estimate"===matchedSegment.type)return 0===retryCount?callback({message:"".concat(programTime," is not buffered yet. Try again")}):(seekTo(matchedSegment.estimatedStart+mediaOffset),void tech.one("seeked",(()=>{seekToProgramTime({programTime:programTime,playlist:playlist,retryCount:retryCount-1,seekTo:seekTo,pauseAfterSeek:pauseAfterSeek,tech:tech,callback:callback})})));const seekToTime=segment.start+mediaOffset;tech.one("seeked",(()=>callback(null,tech.currentTime()))),pauseAfterSeek&&tech.pause(),seekTo(seekToTime)},callbackOnCompleted=(request,cb)=>{if(4===request.readyState)return cb()},containerRequest=(uri,xhr,cb)=>{let id3Offset,bytes=[],finished=!1;const endRequestAndCallback=function(err,req,type,_bytes){return req.abort(),finished=!0,cb(err,req,type,_bytes)},progressListener=function(error,request){if(finished)return;if(error)return endRequestAndCallback(error,request,"",bytes);const newPart=request.responseText.substring(bytes&&bytes.byteLength||0,request.responseText.length);if(bytes=function(){for(var _len=arguments.length,buffers=new Array(_len),_key=0;_key<_len;_key++)buffers[_key]=arguments[_key];if(buffers=buffers.filter((function(b){return b&&(b.byteLength||b.length)&&"string"!=typeof b})),buffers.length<=1)return toUint8(buffers[0]);var totalLen=buffers.reduce((function(total,buf,i){return total+(buf.byteLength||buf.length)}),0),tempBuffer=new Uint8Array(totalLen),offset=0;return buffers.forEach((function(buf){buf=toUint8(buf),tempBuffer.set(buf,offset),offset+=buf.byteLength})),tempBuffer}(bytes,stringToBytes(newPart,!0)),id3Offset=id3Offset||getId3Offset(bytes),bytes.length<10||id3Offset&&bytes.lengthendRequestAndCallback(error,request,"",bytes)));const type=detectContainerForBytes(bytes);return"ts"===type&&bytes.length<188||!type&&bytes.length<376?callbackOnCompleted(request,(()=>endRequestAndCallback(error,request,"",bytes))):endRequestAndCallback(null,request,type,bytes)},options={uri:uri,beforeSend(request){request.overrideMimeType("text/plain; charset=x-user-defined"),request.addEventListener("progress",(function(_ref40){let{total:total,loaded:loaded}=_ref40;return callbackWrapper(request,null,{statusCode:request.status},progressListener)}))}},request=xhr(options,(function(error,response){return callbackWrapper(request,error,response,progressListener)}));return request},{EventTarget:EventTarget}=videojs,dashPlaylistUnchanged=function(a,b){if(!isPlaylistUnchanged(a,b))return!1;if(a.sidx&&b.sidx&&(a.sidx.offset!==b.sidx.offset||a.sidx.length!==b.sidx.length))return!1;if(!a.sidx&&b.sidx||a.sidx&&!b.sidx)return!1;if(a.segments&&!b.segments||!a.segments&&b.segments)return!1;if(!a.segments&&!b.segments)return!0;for(let i=0;i{const playlistId=playlist.attributes.NAME||label;return"placeholder-uri-".concat(type,"-").concat(group,"-").concat(playlistId)},parseMainXml=_ref41=>{let{mainXml:mainXml,srcUrl:srcUrl,clientOffset:clientOffset,sidxMapping:sidxMapping,previousManifest:previousManifest}=_ref41;const manifest=function(manifestString){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const parsedManifestInfo=inheritAttributes(stringToMpdXml(manifestString),options),playlists=toPlaylists(parsedManifestInfo.representationInfo);return toM3u8({dashPlaylists:playlists,locations:parsedManifestInfo.locations,contentSteering:parsedManifestInfo.contentSteeringInfo,sidxMapping:options.sidxMapping,previousManifest:options.previousManifest,eventStream:parsedManifestInfo.eventStream})}(mainXml,{manifestUri:srcUrl,clientOffset:clientOffset,sidxMapping:sidxMapping,previousManifest:previousManifest});return addPropertiesToMain(manifest,srcUrl,dashGroupId),manifest},updateMain=(oldMain,newMain,sidxMapping)=>{let noChanges=!0,update=merge(oldMain,{duration:newMain.duration,minimumUpdatePeriod:newMain.minimumUpdatePeriod,timelineStarts:newMain.timelineStarts});for(let i=0;i{if(properties.playlists&&properties.playlists.length){const id=properties.playlists[0].id,playlistUpdate=updateMain$1(update,properties.playlists[0],dashPlaylistUnchanged);playlistUpdate&&(update=playlistUpdate,label in update.mediaGroups[type][group]||(update.mediaGroups[type][group][label]=properties),update.mediaGroups[type][group][label].playlists[0]=update.playlists[id],noChanges=!1)}})),((update,newMain)=>{forEachMediaGroup(update,((properties,type,group,label)=>{label in newMain.mediaGroups[type][group]||delete update.mediaGroups[type][group][label]}))})(update,newMain),newMain.minimumUpdatePeriod!==oldMain.minimumUpdatePeriod&&(noChanges=!1),noChanges?null:update},equivalentSidx=(a,b)=>(Boolean(!a.map&&!b.map)||Boolean(a.map&&b.map&&a.map.byterange.offset===b.map.byterange.offset&&a.map.byterange.length===b.map.byterange.length))&&a.uri===b.uri&&a.byterange.offset===b.byterange.offset&&a.byterange.length===b.byterange.length,compareSidxEntry=(playlists,oldSidxMapping)=>{const newSidxMapping={};for(const id in playlists){const currentSidxInfo=playlists[id].sidx;if(currentSidxInfo){const key=generateSidxKey(currentSidxInfo);if(!oldSidxMapping[key])break;const savedSidxInfo=oldSidxMapping[key].sidxInfo;equivalentSidx(savedSidxInfo,currentSidxInfo)&&(newSidxMapping[key]=oldSidxMapping[key])}}return newSidxMapping};class DashPlaylistLoader extends EventTarget{constructor(srcUrlOrPlaylist,vhs){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},mainPlaylistLoader=arguments.length>3?arguments[3]:void 0;super(),this.mainPlaylistLoader_=mainPlaylistLoader||this,mainPlaylistLoader||(this.isMain_=!0);const{withCredentials:withCredentials=!1}=options;if(this.vhs_=vhs,this.withCredentials=withCredentials,this.addMetadataToTextTrack=options.addMetadataToTextTrack,!srcUrlOrPlaylist)throw new Error("A non-empty playlist URL or object is required");this.on("minimumUpdatePeriod",(()=>{this.refreshXml_()})),this.on("mediaupdatetimeout",(()=>{this.refreshMedia_(this.media().id)})),this.state="HAVE_NOTHING",this.loadedPlaylists_={},this.logger_=logger("DashPlaylistLoader"),this.isMain_?(this.mainPlaylistLoader_.srcUrl=srcUrlOrPlaylist,this.mainPlaylistLoader_.sidxMapping_={}):this.childPlaylist_=srcUrlOrPlaylist}requestErrored_(err,request,startingState){return!this.request||(this.request=null,err?(this.error="object"!=typeof err||err instanceof Error?{status:request.status,message:"DASH request error at URL: "+request.uri,response:request.response,code:2}:err,startingState&&(this.state=startingState),this.trigger("error"),!0):void 0)}addSidxSegments_(playlist,startingState,cb){const sidxKey=playlist.sidx&&generateSidxKey(playlist.sidx);if(!playlist.sidx||!sidxKey||this.mainPlaylistLoader_.sidxMapping_[sidxKey])return void(this.mediaRequest_=window.setTimeout((()=>cb(!1)),0));const uri=resolveManifestRedirect(playlist.sidx.resolvedUri),fin=(err,request)=>{if(this.requestErrored_(err,request,startingState))return;const sidxMapping=this.mainPlaylistLoader_.sidxMapping_;let sidx;try{sidx=parseSidx_1(toUint8(request.response).subarray(8))}catch(e){return void this.requestErrored_(e,request,startingState)}return sidxMapping[sidxKey]={sidxInfo:playlist.sidx,sidx:sidx},addSidxSegmentsToPlaylist$1(playlist,sidx,playlist.sidx.resolvedUri),cb(!0)};this.request=containerRequest(uri,this.vhs_.xhr,((err,request,container,bytes)=>{if(err)return fin(err,request);if(!container||"mp4"!==container)return fin({status:request.status,message:"Unsupported ".concat(container||"unknown"," container type for sidx segment at URL: ").concat(uri),response:"",playlist:playlist,internal:!0,playlistExclusionDuration:1/0,code:2},request);const{offset:offset,length:length}=playlist.sidx.byterange;if(bytes.length>=length+offset)return fin(err,{response:bytes.subarray(offset,offset+length),status:request.status,uri:request.uri});this.request=this.vhs_.xhr({uri:uri,responseType:"arraybuffer",headers:segmentXhrHeaders({byterange:playlist.sidx.byterange})},fin)}))}dispose(){this.trigger("dispose"),this.stopRequest(),this.loadedPlaylists_={},window.clearTimeout(this.minimumUpdatePeriodTimeout_),window.clearTimeout(this.mediaRequest_),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.mediaRequest_=null,this.minimumUpdatePeriodTimeout_=null,this.mainPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.mainPlaylistLoader_.createMupOnMedia_),this.mainPlaylistLoader_.createMupOnMedia_=null),this.off()}hasPendingRequest(){return this.request||this.mediaRequest_}stopRequest(){if(this.request){const oldRequest=this.request;this.request=null,oldRequest.onreadystatechange=null,oldRequest.abort()}}media(playlist){if(!playlist)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);const startingState=this.state;if("string"==typeof playlist){if(!this.mainPlaylistLoader_.main.playlists[playlist])throw new Error("Unknown playlist URI: "+playlist);playlist=this.mainPlaylistLoader_.main.playlists[playlist]}const mediaChange=!this.media_||playlist.id!==this.media_.id;if(mediaChange&&this.loadedPlaylists_[playlist.id]&&this.loadedPlaylists_[playlist.id].endList)return this.state="HAVE_METADATA",this.media_=playlist,void(mediaChange&&(this.trigger("mediachanging"),this.trigger("mediachange")));mediaChange&&(this.media_&&this.trigger("mediachanging"),this.addSidxSegments_(playlist,startingState,(sidxChanged=>{this.haveMetadata({startingState:startingState,playlist:playlist})})))}haveMetadata(_ref42){let{startingState:startingState,playlist:playlist}=_ref42;this.state="HAVE_METADATA",this.loadedPlaylists_[playlist.id]=playlist,this.mediaRequest_=null,this.refreshMedia_(playlist.id),"HAVE_MAIN_MANIFEST"===startingState?this.trigger("loadedmetadata"):this.trigger("mediachange")}pause(){this.mainPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.mainPlaylistLoader_.createMupOnMedia_),this.mainPlaylistLoader_.createMupOnMedia_=null),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.isMain_&&(window.clearTimeout(this.mainPlaylistLoader_.minimumUpdatePeriodTimeout_),this.mainPlaylistLoader_.minimumUpdatePeriodTimeout_=null),"HAVE_NOTHING"===this.state&&(this.started=!1)}load(isFinalRendition){window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null;const media=this.media();if(isFinalRendition){const delay=media?media.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=window.setTimeout((()=>this.load()),delay)}else this.started?media&&!media.endList?(this.isMain_&&!this.minimumUpdatePeriodTimeout_&&(this.trigger("minimumUpdatePeriod"),this.updateMinimumUpdatePeriodTimeout_()),this.trigger("mediaupdatetimeout")):this.trigger("loadedplaylist"):this.start()}start(){this.started=!0,this.isMain_?this.requestMain_(((req,mainChanged)=>{this.haveMain_(),this.hasPendingRequest()||this.media_||this.media(this.mainPlaylistLoader_.main.playlists[0])})):this.mediaRequest_=window.setTimeout((()=>this.haveMain_()),0)}requestMain_(cb){this.request=this.vhs_.xhr({uri:this.mainPlaylistLoader_.srcUrl,withCredentials:this.withCredentials},((error,req)=>{if(this.requestErrored_(error,req))return void("HAVE_NOTHING"===this.state&&(this.started=!1));const mainChanged=req.responseText!==this.mainPlaylistLoader_.mainXml_;return this.mainPlaylistLoader_.mainXml_=req.responseText,req.responseHeaders&&req.responseHeaders.date?this.mainLoaded_=Date.parse(req.responseHeaders.date):this.mainLoaded_=Date.now(),this.mainPlaylistLoader_.srcUrl=resolveManifestRedirect(this.mainPlaylistLoader_.srcUrl,req),mainChanged?(this.handleMain_(),void this.syncClientServerClock_((()=>cb(req,mainChanged)))):cb(req,mainChanged)}))}syncClientServerClock_(done){const utcTiming=parseUTCTiming(this.mainPlaylistLoader_.mainXml_);return null===utcTiming?(this.mainPlaylistLoader_.clientOffset_=this.mainLoaded_-Date.now(),done()):"DIRECT"===utcTiming.method?(this.mainPlaylistLoader_.clientOffset_=utcTiming.value-Date.now(),done()):void(this.request=this.vhs_.xhr({uri:resolveUrl(this.mainPlaylistLoader_.srcUrl,utcTiming.value),method:utcTiming.method,withCredentials:this.withCredentials},((error,req)=>{if(!this.request)return;if(error)return this.mainPlaylistLoader_.clientOffset_=this.mainLoaded_-Date.now(),done();let serverTime;serverTime="HEAD"===utcTiming.method?req.responseHeaders&&req.responseHeaders.date?Date.parse(req.responseHeaders.date):this.mainLoaded_:Date.parse(req.responseText),this.mainPlaylistLoader_.clientOffset_=serverTime-Date.now(),done()})))}haveMain_(){this.state="HAVE_MAIN_MANIFEST",this.isMain_?this.trigger("loadedplaylist"):this.media_||this.media(this.childPlaylist_)}handleMain_(){this.mediaRequest_=null;const oldMain=this.mainPlaylistLoader_.main;let newMain=parseMainXml({mainXml:this.mainPlaylistLoader_.mainXml_,srcUrl:this.mainPlaylistLoader_.srcUrl,clientOffset:this.mainPlaylistLoader_.clientOffset_,sidxMapping:this.mainPlaylistLoader_.sidxMapping_,previousManifest:oldMain});oldMain&&(newMain=updateMain(oldMain,newMain,this.mainPlaylistLoader_.sidxMapping_)),this.mainPlaylistLoader_.main=newMain||oldMain;const location=this.mainPlaylistLoader_.main.locations&&this.mainPlaylistLoader_.main.locations[0];return location&&location!==this.mainPlaylistLoader_.srcUrl&&(this.mainPlaylistLoader_.srcUrl=location),(!oldMain||newMain&&newMain.minimumUpdatePeriod!==oldMain.minimumUpdatePeriod)&&this.updateMinimumUpdatePeriodTimeout_(),this.addEventStreamToMetadataTrack_(newMain),Boolean(newMain)}updateMinimumUpdatePeriodTimeout_(){const mpl=this.mainPlaylistLoader_;mpl.createMupOnMedia_&&(mpl.off("loadedmetadata",mpl.createMupOnMedia_),mpl.createMupOnMedia_=null),mpl.minimumUpdatePeriodTimeout_&&(window.clearTimeout(mpl.minimumUpdatePeriodTimeout_),mpl.minimumUpdatePeriodTimeout_=null);let mup=mpl.main&&mpl.main.minimumUpdatePeriod;0===mup&&(mpl.media()?mup=1e3*mpl.media().targetDuration:(mpl.createMupOnMedia_=mpl.updateMinimumUpdatePeriodTimeout_,mpl.one("loadedmetadata",mpl.createMupOnMedia_))),"number"!=typeof mup||mup<=0?mup<0&&this.logger_("found invalid minimumUpdatePeriod of ".concat(mup,", not setting a timeout")):this.createMUPTimeout_(mup)}createMUPTimeout_(mup){const mpl=this.mainPlaylistLoader_;mpl.minimumUpdatePeriodTimeout_=window.setTimeout((()=>{mpl.minimumUpdatePeriodTimeout_=null,mpl.trigger("minimumUpdatePeriod"),mpl.createMUPTimeout_(mup)}),mup)}refreshXml_(){this.requestMain_(((req,mainChanged)=>{mainChanged&&(this.media_&&(this.media_=this.mainPlaylistLoader_.main.playlists[this.media_.id]),this.mainPlaylistLoader_.sidxMapping_=((main,oldSidxMapping)=>{let mediaGroupSidx=compareSidxEntry(main.playlists,oldSidxMapping);return forEachMediaGroup(main,((properties,mediaType,groupKey,labelKey)=>{if(properties.playlists&&properties.playlists.length){const playlists=properties.playlists;mediaGroupSidx=merge(mediaGroupSidx,compareSidxEntry(playlists,oldSidxMapping))}})),mediaGroupSidx})(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.sidxMapping_),this.addSidxSegments_(this.media(),this.state,(sidxChanged=>{this.refreshMedia_(this.media().id)})))}))}refreshMedia_(mediaID){if(!mediaID)throw new Error("refreshMedia_ must take a media id");this.media_&&this.isMain_&&this.handleMain_();const playlists=this.mainPlaylistLoader_.main.playlists,mediaChanged=!this.media_||this.media_!==playlists[mediaID];if(mediaChanged?this.media_=playlists[mediaID]:this.trigger("playlistunchanged"),!this.mediaUpdateTimeout){const createMediaUpdateTimeout=()=>{this.media().endList||(this.mediaUpdateTimeout=window.setTimeout((()=>{this.trigger("mediaupdatetimeout"),createMediaUpdateTimeout()}),refreshDelay(this.media(),Boolean(mediaChanged))))};createMediaUpdateTimeout()}this.trigger("loadedplaylist")}addEventStreamToMetadataTrack_(newMain){if(newMain&&this.mainPlaylistLoader_.main.eventStream){const metadataArray=this.mainPlaylistLoader_.main.eventStream.map((eventStreamNode=>({cueTime:eventStreamNode.start,frames:[{data:eventStreamNode.messageData}]})));this.addMetadataToTextTrack("EventStream",metadataArray,this.mainPlaylistLoader_.main.duration)}}getKeyIdSet(playlist){if(playlist.contentProtection){const keyIds=new Set;for(const keysystem in playlist.contentProtection){const defaultKID=playlist.contentProtection[keysystem].attributes["cenc:default_KID"];defaultKID&&keyIds.add(defaultKID.replace(/-/g,"").toLowerCase())}return keyIds}}}var Config={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,BACK_BUFFER_LENGTH:30,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:16,BUFFER_LOW_WATER_LINE_RATE:1,BUFFER_HIGH_WATER_LINE:30};const browserWorkerPolyFill=function(workerObj){return workerObj.on=workerObj.addEventListener,workerObj.off=workerObj.removeEventListener,workerObj},factory=function(code){return function(){const objectUrl=function(str){try{return URL.createObjectURL(new Blob([str],{type:"application/javascript"}))}catch(e){const blob=new BlobBuilder;return blob.append(str),URL.createObjectURL(blob.getBlob())}}(code),worker=browserWorkerPolyFill(new Worker(objectUrl));worker.objURL=objectUrl;const terminate=worker.terminate;return worker.on=worker.addEventListener,worker.off=worker.removeEventListener,worker.terminate=function(){return URL.revokeObjectURL(objectUrl),terminate.call(this)},worker}},transform=function(code){return"var browserWorkerPolyFill = ".concat(browserWorkerPolyFill.toString(),";\n")+"browserWorkerPolyFill(self);\n"+code},getWorkerString=function(fn){return fn.toString().replace(/^function.+?{/,"").slice(0,-1)},workerCode$1=transform(getWorkerString((function(){var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},Stream$8=function(){this.init=function(){var listeners={};this.on=function(type,listener){listeners[type]||(listeners[type]=[]),listeners[type]=listeners[type].concat(listener)},this.off=function(type,listener){var index;return!!listeners[type]&&(index=listeners[type].indexOf(listener),listeners[type]=listeners[type].slice(),listeners[type].splice(index,1),index>-1)},this.trigger=function(type){var callbacks,i,length,args;if(callbacks=listeners[type])if(2===arguments.length)for(length=callbacks.length,i=0;i>>1,track.samplingfrequencyindex<<7|track.channelcount<<3,6,1,2]))},hdlr=function(type){return box(types.hdlr,HDLR_TYPES[type])},mdhd=function(track){var result=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,track.duration>>>24&255,track.duration>>>16&255,track.duration>>>8&255,255&track.duration,85,196,0,0]);return track.samplerate&&(result[12]=track.samplerate>>>24&255,result[13]=track.samplerate>>>16&255,result[14]=track.samplerate>>>8&255,result[15]=255&track.samplerate),box(types.mdhd,result)},mdia=function(track){return box(types.mdia,mdhd(track),hdlr(track.type),minf(track))},mfhd=function(sequenceNumber){return box(types.mfhd,new Uint8Array([0,0,0,0,(4278190080&sequenceNumber)>>24,(16711680&sequenceNumber)>>16,(65280&sequenceNumber)>>8,255&sequenceNumber]))},minf=function(track){return box(types.minf,"video"===track.type?box(types.vmhd,VMHD):box(types.smhd,SMHD),dinf(),stbl(track))},moof=function(sequenceNumber,tracks){for(var trackFragments=[],i=tracks.length;i--;)trackFragments[i]=traf(tracks[i]);return box.apply(null,[types.moof,mfhd(sequenceNumber)].concat(trackFragments))},moov=function(tracks){for(var i=tracks.length,boxes=[];i--;)boxes[i]=trak(tracks[i]);return box.apply(null,[types.moov,mvhd(4294967295)].concat(boxes).concat(mvex(tracks)))},mvex=function(tracks){for(var i=tracks.length,boxes=[];i--;)boxes[i]=trex(tracks[i]);return box.apply(null,[types.mvex].concat(boxes))},mvhd=function(duration){var bytes=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&duration)>>24,(16711680&duration)>>16,(65280&duration)>>8,255&duration,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 box(types.mvhd,bytes)},sdtp=function(track){var flags,i,samples=track.samples||[],bytes=new Uint8Array(4+samples.length);for(i=0;i>>8),sequenceParameterSets.push(255&sps[i].byteLength),sequenceParameterSets=sequenceParameterSets.concat(Array.prototype.slice.call(sps[i]));for(i=0;i>>8),pictureParameterSets.push(255&pps[i].byteLength),pictureParameterSets=pictureParameterSets.concat(Array.prototype.slice.call(pps[i]));if(avc1Box=[types.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&track.width)>>8,255&track.width,(65280&track.height)>>8,255&track.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]),box(types.avcC,new Uint8Array([1,track.profileIdc,track.profileCompatibility,track.levelIdc,255].concat([sps.length],sequenceParameterSets,[pps.length],pictureParameterSets))),box(types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],track.sarRatio){var hSpacing=track.sarRatio[0],vSpacing=track.sarRatio[1];avc1Box.push(box(types.pasp,new Uint8Array([(4278190080&hSpacing)>>24,(16711680&hSpacing)>>16,(65280&hSpacing)>>8,255&hSpacing,(4278190080&vSpacing)>>24,(16711680&vSpacing)>>16,(65280&vSpacing)>>8,255&vSpacing])))}return box.apply(null,avc1Box)},audioSample=function(track){return box(types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&track.channelcount)>>8,255&track.channelcount,(65280&track.samplesize)>>8,255&track.samplesize,0,0,0,0,(65280&track.samplerate)>>8,255&track.samplerate,0,0]),esds(track))},tkhd=function(track){var result=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,0,(4278190080&track.duration)>>24,(16711680&track.duration)>>16,(65280&track.duration)>>8,255&track.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&track.width)>>8,255&track.width,0,0,(65280&track.height)>>8,255&track.height,0,0]);return box(types.tkhd,result)},traf=function(track){var trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun,sampleDependencyTable,upperWordBaseMediaDecodeTime,lowerWordBaseMediaDecodeTime;return trackFragmentHeader=box(types.tfhd,new Uint8Array([0,0,0,58,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),upperWordBaseMediaDecodeTime=Math.floor(track.baseMediaDecodeTime/MAX_UINT32),lowerWordBaseMediaDecodeTime=Math.floor(track.baseMediaDecodeTime%MAX_UINT32),trackFragmentDecodeTime=box(types.tfdt,new Uint8Array([1,0,0,0,upperWordBaseMediaDecodeTime>>>24&255,upperWordBaseMediaDecodeTime>>>16&255,upperWordBaseMediaDecodeTime>>>8&255,255&upperWordBaseMediaDecodeTime,lowerWordBaseMediaDecodeTime>>>24&255,lowerWordBaseMediaDecodeTime>>>16&255,lowerWordBaseMediaDecodeTime>>>8&255,255&lowerWordBaseMediaDecodeTime])),92,"audio"===track.type?(trackFragmentRun=trun$1(track,92),box(types.traf,trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun)):(sampleDependencyTable=sdtp(track),trackFragmentRun=trun$1(track,sampleDependencyTable.length+92),box(types.traf,trackFragmentHeader,trackFragmentDecodeTime,trackFragmentRun,sampleDependencyTable))},trak=function(track){return track.duration=track.duration||4294967295,box(types.trak,tkhd(track),mdia(track))},trex=function(track){var result=new Uint8Array([0,0,0,0,(4278190080&track.id)>>24,(16711680&track.id)>>16,(65280&track.id)>>8,255&track.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==track.type&&(result[result.length-1]=0),box(types.trex,result)},trunHeader=function(samples,offset){var durationPresent=0,sizePresent=0,flagsPresent=0,compositionTimeOffset=0;return samples.length&&(void 0!==samples[0].duration&&(durationPresent=1),void 0!==samples[0].size&&(sizePresent=2),void 0!==samples[0].flags&&(flagsPresent=4),void 0!==samples[0].compositionTimeOffset&&(compositionTimeOffset=8)),[0,0,durationPresent|sizePresent|flagsPresent|compositionTimeOffset,1,(4278190080&samples.length)>>>24,(16711680&samples.length)>>>16,(65280&samples.length)>>>8,255&samples.length,(4278190080&offset)>>>24,(16711680&offset)>>>16,(65280&offset)>>>8,255&offset]},videoTrun=function(track,offset){var bytesOffest,bytes,header,samples,sample,i;for(offset+=20+16*(samples=track.samples||[]).length,header=trunHeader(samples,offset),(bytes=new Uint8Array(header.length+16*samples.length)).set(header),bytesOffest=header.length,i=0;i>>24,bytes[bytesOffest++]=(16711680&sample.duration)>>>16,bytes[bytesOffest++]=(65280&sample.duration)>>>8,bytes[bytesOffest++]=255&sample.duration,bytes[bytesOffest++]=(4278190080&sample.size)>>>24,bytes[bytesOffest++]=(16711680&sample.size)>>>16,bytes[bytesOffest++]=(65280&sample.size)>>>8,bytes[bytesOffest++]=255&sample.size,bytes[bytesOffest++]=sample.flags.isLeading<<2|sample.flags.dependsOn,bytes[bytesOffest++]=sample.flags.isDependedOn<<6|sample.flags.hasRedundancy<<4|sample.flags.paddingValue<<1|sample.flags.isNonSyncSample,bytes[bytesOffest++]=61440&sample.flags.degradationPriority,bytes[bytesOffest++]=15&sample.flags.degradationPriority,bytes[bytesOffest++]=(4278190080&sample.compositionTimeOffset)>>>24,bytes[bytesOffest++]=(16711680&sample.compositionTimeOffset)>>>16,bytes[bytesOffest++]=(65280&sample.compositionTimeOffset)>>>8,bytes[bytesOffest++]=255&sample.compositionTimeOffset;return box(types.trun,bytes)},audioTrun=function(track,offset){var bytes,bytesOffest,header,samples,sample,i;for(offset+=20+8*(samples=track.samples||[]).length,header=trunHeader(samples,offset),(bytes=new Uint8Array(header.length+8*samples.length)).set(header),bytesOffest=header.length,i=0;i>>24,bytes[bytesOffest++]=(16711680&sample.duration)>>>16,bytes[bytesOffest++]=(65280&sample.duration)>>>8,bytes[bytesOffest++]=255&sample.duration,bytes[bytesOffest++]=(4278190080&sample.size)>>>24,bytes[bytesOffest++]=(16711680&sample.size)>>>16,bytes[bytesOffest++]=(65280&sample.size)>>>8,bytes[bytesOffest++]=255&sample.size;return box(types.trun,bytes)},trun$1=function(track,offset){return"audio"===track.type?audioTrun(track,offset):videoTrun(track,offset)};var silence,secondsToVideoTs,secondsToAudioTs,videoTsToSeconds,audioTsToSeconds,audioTsToVideoTs,videoTsToAudioTs,metadataTsToSeconds,mp4Generator={ftyp:ftyp=function(){return box(types.ftyp,MAJOR_BRAND,MINOR_VERSION,MAJOR_BRAND,AVC1_BRAND)},mdat:function(data){return box(types.mdat,data)},moof:moof,moov:moov,initSegment:function(tracks){var result,fileType=ftyp(),movie=moov(tracks);return(result=new Uint8Array(fileType.byteLength+movie.byteLength)).set(fileType),result.set(movie,fileType.byteLength),result}},sampleForFrame=function(frame,dataOffset){var sample={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return sample.dataOffset=dataOffset,sample.compositionTimeOffset=frame.pts-frame.dts,sample.duration=frame.duration,sample.size=4*frame.length,sample.size+=frame.byteLength,frame.keyFrame&&(sample.flags.dependsOn=2,sample.flags.isNonSyncSample=0),sample},frameUtils$1={groupNalsIntoFrames:function(nalUnits){var i,currentNal,currentFrame=[],frames=[];for(frames.byteLength=0,frames.nalCount=0,frames.duration=0,currentFrame.byteLength=0,i=0;i1&&(currentGop=gops.shift(),gops.byteLength-=currentGop.byteLength,gops.nalCount-=currentGop.nalCount,gops[0][0].dts=currentGop.dts,gops[0][0].pts=currentGop.pts,gops[0][0].duration+=currentGop.duration),gops},generateSampleTable:function(gops,baseDataOffset){var h,i,sample,currentGop,currentFrame,dataOffset=baseDataOffset||0,samples=[];for(h=0;hclock$1.ONE_SECOND_IN_TS/2))){for((silentFrame=coneOfSilence()[track.samplerate])||(silentFrame=frames[0].data),i=0;i=earliestAllowedDts?adtsFrames:(track.minSegmentDts=1/0,adtsFrames.filter((function(currentFrame){return currentFrame.dts>=earliestAllowedDts&&(track.minSegmentDts=Math.min(track.minSegmentDts,currentFrame.dts),track.minSegmentPts=track.minSegmentDts,!0)})))},generateSampleTable:function(frames){var i,currentFrame,samples=[];for(i=0;i=this.virtualRowCount&&"function"==typeof this.beforeRowOverflow&&this.beforeRowOverflow(pts),this.rows.length>0&&(this.rows.push(""),this.rowIdx++);this.rows.length>this.virtualRowCount;)this.rows.shift(),this.rowIdx--},Cea708Window.prototype.isEmpty=function(){return 0===this.rows.length||1===this.rows.length&&""===this.rows[0]},Cea708Window.prototype.addText=function(text){this.rows[this.rowIdx]+=text},Cea708Window.prototype.backspace=function(){if(!this.isEmpty()){var row=this.rows[this.rowIdx];this.rows[this.rowIdx]=row.substr(0,row.length-1)}};var Cea708Service=function(serviceNum,encoding,stream){this.serviceNum=serviceNum,this.text="",this.currentWindow=new Cea708Window(-1),this.windows=[],this.stream=stream,"string"==typeof encoding&&this.createTextDecoder(encoding)};Cea708Service.prototype.init=function(pts,beforeRowOverflow){this.startPts=pts;for(var win=0;win<8;win++)this.windows[win]=new Cea708Window(win),"function"==typeof beforeRowOverflow&&(this.windows[win].beforeRowOverflow=beforeRowOverflow)},Cea708Service.prototype.setCurrentWindow=function(windowNum){this.currentWindow=this.windows[windowNum]},Cea708Service.prototype.createTextDecoder=function(encoding){if("undefined"==typeof TextDecoder)this.stream.trigger("log",{level:"warn",message:"The `encoding` option is unsupported without TextDecoder support"});else try{this.textDecoder_=new TextDecoder(encoding)}catch(error){this.stream.trigger("log",{level:"warn",message:"TextDecoder could not be created with "+encoding+" encoding. "+error})}};var Cea708Stream=function(options){options=options||{},Cea708Stream.prototype.init.call(this);var serviceProps,self=this,captionServices=options.captionServices||{},captionServiceEncodings={};Object.keys(captionServices).forEach((serviceName=>{serviceProps=captionServices[serviceName],/^SERVICE/.test(serviceName)&&(captionServiceEncodings[serviceName]=serviceProps.encoding)})),this.serviceEncodings=captionServiceEncodings,this.current708Packet=null,this.services={},this.push=function(packet){3===packet.type?(self.new708Packet(),self.add708Bytes(packet)):(null===self.current708Packet&&self.new708Packet(),self.add708Bytes(packet))}};Cea708Stream.prototype=new Stream$7,Cea708Stream.prototype.new708Packet=function(){null!==this.current708Packet&&this.push708Packet(),this.current708Packet={data:[],ptsVals:[]}},Cea708Stream.prototype.add708Bytes=function(packet){var data=packet.ccData,byte0=data>>>8,byte1=255&data;this.current708Packet.ptsVals.push(packet.pts),this.current708Packet.data.push(byte0),this.current708Packet.data.push(byte1)},Cea708Stream.prototype.push708Packet=function(){var packet708=this.current708Packet,packetData=packet708.data,serviceNum=null,blockSize=null,i=0,b=packetData[i++];for(packet708.seq=b>>6,packet708.sizeCode=63&b;i>5)&&blockSize>0&&(serviceNum=b=packetData[i++]),this.pushServiceBlock(serviceNum,i,blockSize),blockSize>0&&(i+=blockSize-1)},Cea708Stream.prototype.pushServiceBlock=function(serviceNum,start,size){var b,i=start,packetData=this.current708Packet.data,service=this.services[serviceNum];for(service||(service=this.initService(serviceNum,i));i("0"+(255&byte).toString(16)).slice(-2))).join("");char=String.fromCharCode(parseInt(unicode,16))}else newCode=CHARACTER_TRANSLATION_708[code=extended|currentByte]||code,char=4096&code&&code===newCode?"":String.fromCharCode(newCode);return win.pendingNewLine&&!win.isEmpty()&&win.newLine(this.getPts(i)),win.pendingNewLine=!1,win.addText(char),i},Cea708Stream.prototype.multiByteCharacter=function(i,service){var packetData=this.current708Packet.data,firstByte=packetData[i+1],secondByte=packetData[i+2];return within708TextBlock(firstByte)&&within708TextBlock(secondByte)&&(i=this.handleText(++i,service,{isMultiByte:!0})),i},Cea708Stream.prototype.setCurrentWindow=function(i,service){var windowNum=7&this.current708Packet.data[i];return service.setCurrentWindow(windowNum),i},Cea708Stream.prototype.defineWindow=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],windowNum=7&b;service.setCurrentWindow(windowNum);var win=service.currentWindow;return b=packetData[++i],win.visible=(32&b)>>5,win.rowLock=(16&b)>>4,win.columnLock=(8&b)>>3,win.priority=7&b,b=packetData[++i],win.relativePositioning=(128&b)>>7,win.anchorVertical=127&b,b=packetData[++i],win.anchorHorizontal=b,b=packetData[++i],win.anchorPoint=(240&b)>>4,win.rowCount=15&b,b=packetData[++i],win.columnCount=63&b,b=packetData[++i],win.windowStyle=(56&b)>>3,win.penStyle=7&b,win.virtualRowCount=win.rowCount+1,i},Cea708Stream.prototype.setWindowAttributes=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],winAttr=service.currentWindow.winAttr;return b=packetData[++i],winAttr.fillOpacity=(192&b)>>6,winAttr.fillRed=(48&b)>>4,winAttr.fillGreen=(12&b)>>2,winAttr.fillBlue=3&b,b=packetData[++i],winAttr.borderType=(192&b)>>6,winAttr.borderRed=(48&b)>>4,winAttr.borderGreen=(12&b)>>2,winAttr.borderBlue=3&b,b=packetData[++i],winAttr.borderType+=(128&b)>>5,winAttr.wordWrap=(64&b)>>6,winAttr.printDirection=(48&b)>>4,winAttr.scrollDirection=(12&b)>>2,winAttr.justify=3&b,b=packetData[++i],winAttr.effectSpeed=(240&b)>>4,winAttr.effectDirection=(12&b)>>2,winAttr.displayEffect=3&b,i},Cea708Stream.prototype.flushDisplayed=function(pts,service){for(var displayedText=[],winId=0;winId<8;winId++)service.windows[winId].visible&&!service.windows[winId].isEmpty()&&displayedText.push(service.windows[winId].getText());service.endPts=pts,service.text=displayedText.join("\n\n"),this.pushCaption(service),service.startPts=pts},Cea708Stream.prototype.pushCaption=function(service){""!==service.text&&(this.trigger("data",{startPts:service.startPts,endPts:service.endPts,text:service.text,stream:"cc708_"+service.serviceNum}),service.text="",service.startPts=service.endPts)},Cea708Stream.prototype.displayWindows=function(i,service){var b=this.current708Packet.data[++i],pts=this.getPts(i);this.flushDisplayed(pts,service);for(var winId=0;winId<8;winId++)b&1<>4,penAttr.offset=(12&b)>>2,penAttr.penSize=3&b,b=packetData[++i],penAttr.italics=(128&b)>>7,penAttr.underline=(64&b)>>6,penAttr.edgeType=(56&b)>>3,penAttr.fontStyle=7&b,i},Cea708Stream.prototype.setPenColor=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],penColor=service.currentWindow.penColor;return b=packetData[++i],penColor.fgOpacity=(192&b)>>6,penColor.fgRed=(48&b)>>4,penColor.fgGreen=(12&b)>>2,penColor.fgBlue=3&b,b=packetData[++i],penColor.bgOpacity=(192&b)>>6,penColor.bgRed=(48&b)>>4,penColor.bgGreen=(12&b)>>2,penColor.bgBlue=3&b,b=packetData[++i],penColor.edgeRed=(48&b)>>4,penColor.edgeGreen=(12&b)>>2,penColor.edgeBlue=3&b,i},Cea708Stream.prototype.setPenLocation=function(i,service){var packetData=this.current708Packet.data,b=packetData[i],penLoc=service.currentWindow.penLoc;return service.currentWindow.pendingNewLine=!0,b=packetData[++i],penLoc.row=15&b,b=packetData[++i],penLoc.column=63&b,i},Cea708Stream.prototype.reset=function(i,service){var pts=this.getPts(i);return this.flushDisplayed(pts,service),this.initService(service.serviceNum,i)};var CHARACTER_TRANSLATION={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},getCharFromCode=function(code){return null===code?"":(code=CHARACTER_TRANSLATION[code]||code,String.fromCharCode(code))},ROWS=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],createDisplayBuffer=function(){for(var result=[],i=15;i--;)result.push({text:"",indent:0,offset:0});return result},Cea608Stream=function(field,dataChannel){Cea608Stream.prototype.init.call(this),this.field_=field||0,this.dataChannel_=dataChannel||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(packet){var data,swap,char0,char1,text;if((data=32639&packet.ccData)!==this.lastControlCode_){if(4096==(61440&data)?this.lastControlCode_=data:data!==this.PADDING_&&(this.lastControlCode_=null),char0=data>>>8,char1=255&data,data!==this.PADDING_)if(data===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(data===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(packet.pts),this.flushDisplayed(packet.pts),swap=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=swap,this.startPts_=packet.pts;else if(data===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(packet.pts);else if(data===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(packet.pts);else if(data===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(packet.pts);else if(data===this.CARRIAGE_RETURN_)this.clearFormatting(packet.pts),this.flushDisplayed(packet.pts),this.shiftRowsUp_(),this.startPts_=packet.pts;else if(data===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_].text=this.nonDisplayed_[this.row_].text.slice(0,-1):this.displayed_[this.row_].text=this.displayed_[this.row_].text.slice(0,-1);else if(data===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(packet.pts),this.displayed_=createDisplayBuffer();else if(data===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=createDisplayBuffer();else if(data===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(packet.pts),this.displayed_=createDisplayBuffer()),this.mode_="paintOn",this.startPts_=packet.pts;else if(this.isSpecialCharacter(char0,char1))text=getCharFromCode((char0=(3&char0)<<8)|char1),this[this.mode_](packet.pts,text),this.column_++;else if(this.isExtCharacter(char0,char1))"popOn"===this.mode_?this.nonDisplayed_[this.row_].text=this.nonDisplayed_[this.row_].text.slice(0,-1):this.displayed_[this.row_].text=this.displayed_[this.row_].text.slice(0,-1),text=getCharFromCode((char0=(3&char0)<<8)|char1),this[this.mode_](packet.pts,text),this.column_++;else if(this.isMidRowCode(char0,char1))this.clearFormatting(packet.pts),this[this.mode_](packet.pts," "),this.column_++,14==(14&char1)&&this.addFormatting(packet.pts,["i"]),1==(1&char1)&&this.addFormatting(packet.pts,["u"]);else if(this.isOffsetControlCode(char0,char1)){const offset=3&char1;this.nonDisplayed_[this.row_].offset=offset,this.column_+=offset}else if(this.isPAC(char0,char1)){var row=ROWS.indexOf(7968&data);if("rollUp"===this.mode_&&(row-this.rollUpRows_+1<0&&(row=this.rollUpRows_-1),this.setRollUp(packet.pts,row)),row!==this.row_&&(this.clearFormatting(packet.pts),this.row_=row),1&char1&&-1===this.formatting_.indexOf("u")&&this.addFormatting(packet.pts,["u"]),16==(16&data)){const indentations=(14&data)>>1;this.column_=4*indentations,this.nonDisplayed_[this.row_].indent+=indentations}this.isColorPAC(char1)&&14==(14&char1)&&this.addFormatting(packet.pts,["i"])}else this.isNormalChar(char0)&&(0===char1&&(char1=null),text=getCharFromCode(char0),text+=getCharFromCode(char1),this[this.mode_](packet.pts,text),this.column_+=text.length)}else this.lastControlCode_=null}};Cea608Stream.prototype=new Stream$7,Cea608Stream.prototype.flushDisplayed=function(pts){const logWarning=index=>{this.trigger("log",{level:"warn",message:"Skipping a malformed 608 caption at index "+index+"."})},content=[];this.displayed_.forEach(((row,i)=>{if(row&&row.text&&row.text.length){try{row.text=row.text.trim()}catch(e){logWarning(i)}row.text.length&&content.push({text:row.text,line:i+1,position:10+Math.min(70,10*row.indent)+2.5*row.offset})}else null==row&&logWarning(i)})),content.length&&this.trigger("data",{startPts:this.startPts_,endPts:pts,content:content,stream:this.name_})},Cea608Stream.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=createDisplayBuffer(),this.nonDisplayed_=createDisplayBuffer(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Cea608Stream.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_},Cea608Stream.prototype.isSpecialCharacter=function(char0,char1){return char0===this.EXT_&&char1>=48&&char1<=63},Cea608Stream.prototype.isExtCharacter=function(char0,char1){return(char0===this.EXT_+1||char0===this.EXT_+2)&&char1>=32&&char1<=63},Cea608Stream.prototype.isMidRowCode=function(char0,char1){return char0===this.EXT_&&char1>=32&&char1<=47},Cea608Stream.prototype.isOffsetControlCode=function(char0,char1){return char0===this.OFFSET_&&char1>=33&&char1<=35},Cea608Stream.prototype.isPAC=function(char0,char1){return char0>=this.BASE_&&char0=64&&char1<=127},Cea608Stream.prototype.isColorPAC=function(char1){return char1>=64&&char1<=79||char1>=96&&char1<=127},Cea608Stream.prototype.isNormalChar=function(char){return char>=32&&char<=127},Cea608Stream.prototype.setRollUp=function(pts,newBaseRow){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(pts),this.nonDisplayed_=createDisplayBuffer(),this.displayed_=createDisplayBuffer()),void 0!==newBaseRow&&newBaseRow!==this.row_)for(var i=0;i"}),"");this[this.mode_](pts,text)},Cea608Stream.prototype.clearFormatting=function(pts){if(this.formatting_.length){var text=this.formatting_.reverse().reduce((function(text,format){return text+""}),"");this.formatting_=[],this[this.mode_](pts,text)}},Cea608Stream.prototype.popOn=function(pts,text){var baseRow=this.nonDisplayed_[this.row_].text;baseRow+=text,this.nonDisplayed_[this.row_].text=baseRow},Cea608Stream.prototype.rollUp=function(pts,text){var baseRow=this.displayed_[this.row_].text;baseRow+=text,this.displayed_[this.row_].text=baseRow},Cea608Stream.prototype.shiftRowsUp_=function(){var i;for(i=0;ireference&&(direction=-1);Math.abs(reference-value)>4294967296;)value+=8589934592*direction;return value},TimestampRolloverStream$1=function(type){var lastDTS,referenceDTS;TimestampRolloverStream$1.prototype.init.call(this),this.type_=type||"shared",this.push=function(data){"metadata"!==data.type?"shared"!==this.type_&&data.type!==this.type_||(void 0===referenceDTS&&(referenceDTS=data.dts),data.dts=handleRollover$1(data.dts,referenceDTS),data.pts=handleRollover$1(data.pts,referenceDTS),lastDTS=data.dts,this.trigger("data",data)):this.trigger("data",data)},this.flush=function(){referenceDTS=lastDTS,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.discontinuity=function(){referenceDTS=void 0,lastDTS=void 0},this.reset=function(){this.discontinuity(),this.trigger("reset")}};TimestampRolloverStream$1.prototype=new Stream$6;var MetadataStream,timestampRolloverStream={TimestampRolloverStream:TimestampRolloverStream$1,handleRollover:handleRollover$1},typedArray_typedArrayIndexOf=(typedArray,element,fromIndex)=>{if(!typedArray)return-1;for(var currentIndex=fromIndex;currentIndex>>2;size*=4,size+=3&d[7],frame.timeStamp=size,void 0===tag.pts&&void 0===tag.dts&&(tag.pts=frame.timeStamp,tag.dts=frame.timeStamp),this.trigger("timestamp",frame)}tag.frames.push(frame),frameStart+=10,frameStart+=frameSize}while(frameStart>>4>1&&(offset+=packet[offset]+1),0===result.pid)result.type="pat",parsePsi(packet.subarray(offset),result),this.trigger("data",result);else if(result.pid===this.pmtPid)for(result.type="pmt",parsePsi(packet.subarray(offset),result),this.trigger("data",result);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([packet,offset,result]):this.processPes_(packet,offset,result)},this.processPes_=function(packet,offset,result){result.pid===this.programMapTable.video?result.streamType=StreamTypes$2.H264_STREAM_TYPE:result.pid===this.programMapTable.audio?result.streamType=StreamTypes$2.ADTS_STREAM_TYPE:result.streamType=this.programMapTable["timed-metadata"][result.pid],result.type="pes",result.data=packet.subarray(offset),this.trigger("data",result)}},TransportParseStream.prototype=new Stream$4,TransportParseStream.STREAM_TYPES={h264:27,adts:15},ElementaryStream=function(){var programMapTable,self=this,segmentHadPmt=!1,video={data:[],size:0},audio={data:[],size:0},timedMetadata={data:[],size:0},flushStream=function(stream,type,forceFlush){var packetFlushable,fragment,packetData=new Uint8Array(stream.size),event={type:type},i=0,offset=0;if(stream.data.length&&!(stream.size<9)){for(event.trackId=stream.data[0].pid,i=0;i>>3,pes.pts*=4,pes.pts+=(6&payload[13])>>>1,pes.dts=pes.pts,64&ptsDtsFlags&&(pes.dts=(14&payload[14])<<27|(255&payload[15])<<20|(254&payload[16])<<12|(255&payload[17])<<5|(254&payload[18])>>>3,pes.dts*=4,pes.dts+=(6&payload[18])>>>1)),pes.data=payload.subarray(9+payload[8]))}(packetData,event),packetFlushable="video"===type||event.packetLength<=stream.size,(forceFlush||packetFlushable)&&(stream.size=0,stream.data.length=0),packetFlushable&&self.trigger("data",event)}};ElementaryStream.prototype.init.call(this),this.push=function(data){({pat:function(){},pes:function(){var stream,streamType;switch(data.streamType){case StreamTypes$2.H264_STREAM_TYPE:stream=video,streamType="video";break;case StreamTypes$2.ADTS_STREAM_TYPE:stream=audio,streamType="audio";break;case StreamTypes$2.METADATA_STREAM_TYPE:stream=timedMetadata,streamType="timed-metadata";break;default:return}data.payloadUnitStartIndicator&&flushStream(stream,streamType,!0),stream.data.push(data),stream.size+=data.data.byteLength},pmt:function(){var event={type:"metadata",tracks:[]};null!==(programMapTable=data.programMapTable).video&&event.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.video,codec:"avc",type:"video"}),null!==programMapTable.audio&&event.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.audio,codec:"adts",type:"audio"}),segmentHadPmt=!0,self.trigger("data",event)}})[data.type]()},this.reset=function(){video.size=0,video.data.length=0,audio.size=0,audio.data.length=0,this.trigger("reset")},this.flushStreams_=function(){flushStream(video,"video"),flushStream(audio,"audio"),flushStream(timedMetadata,"timed-metadata")},this.flush=function(){if(!segmentHadPmt&&programMapTable){var pmt={type:"metadata",tracks:[]};null!==programMapTable.video&&pmt.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.video,codec:"avc",type:"video"}),null!==programMapTable.audio&&pmt.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+programMapTable.audio,codec:"adts",type:"audio"}),self.trigger("data",pmt)}segmentHadPmt=!1,this.flushStreams_(),this.trigger("done")}},ElementaryStream.prototype=new Stream$4;var m2ts$1={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:TransportPacketStream,TransportParseStream:TransportParseStream,ElementaryStream:ElementaryStream,TimestampRolloverStream:TimestampRolloverStream,CaptionStream:CaptionStream$1.CaptionStream,Cea608Stream:CaptionStream$1.Cea608Stream,Cea708Stream:CaptionStream$1.Cea708Stream,MetadataStream:metadataStream};for(var type in StreamTypes$2)StreamTypes$2.hasOwnProperty(type)&&(m2ts$1[type]=StreamTypes$2[type]);var AdtsStream$1,m2ts_1=m2ts$1,ONE_SECOND_IN_TS$2=clock$2.ONE_SECOND_IN_TS,ADTS_SAMPLING_FREQUENCIES$1=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(AdtsStream$1=function(handlePartialSegments){var buffer,frameNum=0;AdtsStream$1.prototype.init.call(this),this.skipWarn_=function(start,end){this.trigger("log",{level:"warn",message:"adts skiping bytes ".concat(start," to ").concat(end," in frame ").concat(frameNum," outside syncword")})},this.push=function(packet){var frameLength,protectionSkipBytes,oldBuffer,sampleCount,adtsFrameDuration,i=0;if(handlePartialSegments||(frameNum=0),"audio"===packet.type){var skip;for(buffer&&buffer.length?(oldBuffer=buffer,(buffer=new Uint8Array(oldBuffer.byteLength+packet.data.byteLength)).set(oldBuffer),buffer.set(packet.data,oldBuffer.byteLength)):buffer=packet.data;i+7>5,adtsFrameDuration=(sampleCount=1024*(1+(3&buffer[i+6])))*ONE_SECOND_IN_TS$2/ADTS_SAMPLING_FREQUENCIES$1[(60&buffer[i+2])>>>2],buffer.byteLength-i>>6&3),channelcount:(1&buffer[i+2])<<2|(192&buffer[i+3])>>>6,samplerate:ADTS_SAMPLING_FREQUENCIES$1[(60&buffer[i+2])>>>2],samplingfrequencyindex:(60&buffer[i+2])>>>2,samplesize:16,data:buffer.subarray(i+7+protectionSkipBytes,i+frameLength)}),frameNum++,i+=frameLength}else"number"!=typeof skip&&(skip=i),i++;"number"==typeof skip&&(this.skipWarn_(skip,i),skip=null),buffer=buffer.subarray(i)}},this.flush=function(){frameNum=0,this.trigger("done")},this.reset=function(){buffer=void 0,this.trigger("reset")},this.endTimeline=function(){buffer=void 0,this.trigger("endedtimeline")}}).prototype=new stream;var ExpGolomb$1,adts=AdtsStream$1;ExpGolomb$1=function(workingData){var workingBytesAvailable=workingData.byteLength,workingWord=0,workingBitsAvailable=0;this.length=function(){return 8*workingBytesAvailable},this.bitsAvailable=function(){return 8*workingBytesAvailable+workingBitsAvailable},this.loadWord=function(){var position=workingData.byteLength-workingBytesAvailable,workingBytes=new Uint8Array(4),availableBytes=Math.min(4,workingBytesAvailable);if(0===availableBytes)throw new Error("no bytes available");workingBytes.set(workingData.subarray(position,position+availableBytes)),workingWord=new DataView(workingBytes.buffer).getUint32(0),workingBitsAvailable=8*availableBytes,workingBytesAvailable-=availableBytes},this.skipBits=function(count){var skipBytes;workingBitsAvailable>count?(workingWord<<=count,workingBitsAvailable-=count):(count-=workingBitsAvailable,count-=8*(skipBytes=Math.floor(count/8)),workingBytesAvailable-=skipBytes,this.loadWord(),workingWord<<=count,workingBitsAvailable-=count)},this.readBits=function(size){var bits=Math.min(workingBitsAvailable,size),valu=workingWord>>>32-bits;return(workingBitsAvailable-=bits)>0?workingWord<<=bits:workingBytesAvailable>0&&this.loadWord(),(bits=size-bits)>0?valu<>>leadingZeroCount))return workingWord<<=leadingZeroCount,workingBitsAvailable-=leadingZeroCount,leadingZeroCount;return this.loadWord(),leadingZeroCount+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var clz=this.skipLeadingZeros();return this.readBits(clz+1)-1},this.readExpGolomb=function(){var valu=this.readUnsignedExpGolomb();return 1&valu?1+valu>>>1:-1*(valu>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()};var H264Stream$1,NalByteStream,PROFILES_WITH_OPTIONAL_SPS_DATA,Stream$2=stream,ExpGolomb=ExpGolomb$1;(NalByteStream=function(){var i,buffer,syncPoint=0;NalByteStream.prototype.init.call(this),this.push=function(data){var swapBuffer;buffer?((swapBuffer=new Uint8Array(buffer.byteLength+data.data.byteLength)).set(buffer),swapBuffer.set(data.data,buffer.byteLength),buffer=swapBuffer):buffer=data.data;for(var len=buffer.byteLength;syncPoint3&&this.trigger("data",buffer.subarray(syncPoint+3)),buffer=null,syncPoint=0,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")}}).prototype=new Stream$2,PROFILES_WITH_OPTIONAL_SPS_DATA={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},H264Stream$1=function(){var self,trackId,currentPts,currentDts,discardEmulationPreventionBytes,readSequenceParameterSet,skipScalingList,nalByteStream=new NalByteStream;H264Stream$1.prototype.init.call(this),self=this,this.push=function(packet){"video"===packet.type&&(trackId=packet.trackId,currentPts=packet.pts,currentDts=packet.dts,nalByteStream.push(packet))},nalByteStream.on("data",(function(data){var event={trackId:trackId,pts:currentPts,dts:currentDts,data:data,nalUnitTypeCode:31&data[0]};switch(event.nalUnitTypeCode){case 5:event.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:event.nalUnitType="sei_rbsp",event.escapedRBSP=discardEmulationPreventionBytes(data.subarray(1));break;case 7:event.nalUnitType="seq_parameter_set_rbsp",event.escapedRBSP=discardEmulationPreventionBytes(data.subarray(1)),event.config=readSequenceParameterSet(event.escapedRBSP);break;case 8:event.nalUnitType="pic_parameter_set_rbsp";break;case 9:event.nalUnitType="access_unit_delimiter_rbsp"}self.trigger("data",event)})),nalByteStream.on("done",(function(){self.trigger("done")})),nalByteStream.on("partialdone",(function(){self.trigger("partialdone")})),nalByteStream.on("reset",(function(){self.trigger("reset")})),nalByteStream.on("endedtimeline",(function(){self.trigger("endedtimeline")})),this.flush=function(){nalByteStream.flush()},this.partialFlush=function(){nalByteStream.partialFlush()},this.reset=function(){nalByteStream.reset()},this.endTimeline=function(){nalByteStream.endTimeline()},skipScalingList=function(count,expGolombDecoder){var j,lastScale=8,nextScale=8;for(j=0;j=0?returnSize:0,(16&header[byteIndex+5])>>4?returnSize+20:returnSize+10},getId3Offset=function(data,offset){return data.length-offset<10||data[offset]!=="I".charCodeAt(0)||data[offset+1]!=="D".charCodeAt(0)||data[offset+2]!=="3".charCodeAt(0)?offset:(offset+=parseId3TagSize(data,offset),getId3Offset(data,offset))},parseSyncSafeInteger=function(data){return data[0]<<21|data[1]<<14|data[2]<<7|data[3]},utils={isLikelyAacData:function(data){var offset=getId3Offset(data,0);return data.length>=offset+2&&255==(255&data[offset])&&240==(240&data[offset+1])&&16==(22&data[offset+1])},parseId3TagSize:parseId3TagSize,parseAdtsSize:function(header,byteIndex){var lowThree=(224&header[byteIndex+5])>>5,middle=header[byteIndex+4]<<3;return 6144&header[byteIndex+3]|middle|lowThree},parseType:function(header,byteIndex){return header[byteIndex]==="I".charCodeAt(0)&&header[byteIndex+1]==="D".charCodeAt(0)&&header[byteIndex+2]==="3".charCodeAt(0)?"timed-metadata":!0&header[byteIndex]&&240==(240&header[byteIndex+1])?"audio":null},parseSampleRate:function(packet){for(var i=0;i+5>>2];i++}return null},parseAacTimestamp:function(packet){var frameStart,frameSize,frame;frameStart=10,64&packet[5]&&(frameStart+=4,frameStart+=parseSyncSafeInteger(packet.subarray(10,14)));do{if((frameSize=parseSyncSafeInteger(packet.subarray(frameStart+4,frameStart+8)))<1)return null;if("PRIV"===String.fromCharCode(packet[frameStart],packet[frameStart+1],packet[frameStart+2],packet[frameStart+3])){frame=packet.subarray(frameStart+10,frameStart+frameSize+10);for(var i=0;i>>2;return size*=4,size+=3&d[7]}break}}frameStart+=10,frameStart+=frameSize}while(frameStart=3;)if(everything[byteIndex]!=="I".charCodeAt(0)||everything[byteIndex+1]!=="D".charCodeAt(0)||everything[byteIndex+2]!=="3".charCodeAt(0))if(255!=(255&everything[byteIndex])||240!=(240&everything[byteIndex+1]))byteIndex++;else{if(everything.length-byteIndex<7)break;if(byteIndex+(frameSize=aacUtils.parseAdtsSize(everything,byteIndex))>everything.length)break;packet={type:"audio",data:everything.subarray(byteIndex,byteIndex+frameSize),pts:timeStamp,dts:timeStamp},this.trigger("data",packet),byteIndex+=frameSize}else{if(everything.length-byteIndex<10)break;if(byteIndex+(frameSize=aacUtils.parseId3TagSize(everything,byteIndex))>everything.length)break;chunk={type:"timed-metadata",data:everything.subarray(byteIndex,byteIndex+frameSize)},this.trigger("data",chunk),byteIndex+=frameSize}bytesLeft=everything.length-byteIndex,everything=bytesLeft>0?everything.subarray(byteIndex):new Uint8Array},this.reset=function(){everything=new Uint8Array,this.trigger("reset")},this.endTimeline=function(){everything=new Uint8Array,this.trigger("endedtimeline")}}).prototype=new stream;var VideoSegmentStream,AudioSegmentStream,Transmuxer,CoalesceStream,Stream=stream,mp4=mp4Generator,frameUtils=frameUtils$1,audioFrameUtils=audioFrameUtils$1,trackDecodeInfo=trackDecodeInfo$1,m2ts=m2ts_1,clock=clock$2,AdtsStream=adts,H264Stream=h264.H264Stream,AacStream=AacStream$1,isLikelyAacData=utils.isLikelyAacData,ONE_SECOND_IN_TS$1=clock$2.ONE_SECOND_IN_TS,AUDIO_PROPERTIES=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],VIDEO_PROPERTIES=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"],retriggerForStream=function(key,event){event.stream=key,this.trigger("log",event)},addPipelineLogRetriggers=function(transmuxer,pipeline){for(var keys=Object.keys(pipeline),i=0;i=-1e4&&dtsDistance<=45e3&&(!nearestGopObj||nearestDistance>dtsDistance)&&(nearestGopObj=currentGopObj,nearestDistance=dtsDistance));return nearestGopObj?nearestGopObj.gop:null},this.alignGopsAtStart_=function(gops){var alignIndex,gopIndex,align,gop,byteLength,nalCount,duration,alignedGops;for(byteLength=gops.byteLength,nalCount=gops.nalCount,duration=gops.duration,alignIndex=gopIndex=0;alignIndexalign.pts?alignIndex++:(gopIndex++,byteLength-=gop.byteLength,nalCount-=gop.nalCount,duration-=gop.duration);return 0===gopIndex?gops:gopIndex===gops.length?null:((alignedGops=gops.slice(gopIndex)).byteLength=byteLength,alignedGops.duration=duration,alignedGops.nalCount=nalCount,alignedGops.pts=alignedGops[0].pts,alignedGops.dts=alignedGops[0].dts,alignedGops)},this.alignGopsAtEnd_=function(gops){var alignIndex,gopIndex,align,gop,alignEndIndex,matchFound,trimIndex;for(alignIndex=gopsToAlignWith.length-1,gopIndex=gops.length-1,alignEndIndex=null,matchFound=!1;alignIndex>=0&&gopIndex>=0;){if(align=gopsToAlignWith[alignIndex],gop=gops[gopIndex],align.pts===gop.pts){matchFound=!0;break}align.pts>gop.pts?alignIndex--:(alignIndex===gopsToAlignWith.length-1&&(alignEndIndex=gopIndex),gopIndex--)}if(!matchFound&&null===alignEndIndex)return null;if(0===(trimIndex=matchFound?gopIndex:alignEndIndex))return gops;var alignedGops=gops.slice(trimIndex),metadata=alignedGops.reduce((function(total,gop){return total.byteLength+=gop.byteLength,total.duration+=gop.duration,total.nalCount+=gop.nalCount,total}),{byteLength:0,duration:0,nalCount:0});return alignedGops.byteLength=metadata.byteLength,alignedGops.duration=metadata.duration,alignedGops.nalCount=metadata.nalCount,alignedGops.pts=alignedGops[0].pts,alignedGops.dts=alignedGops[0].dts,alignedGops},this.alignGopsWith=function(newGopsToAlignWith){gopsToAlignWith=newGopsToAlignWith}},VideoSegmentStream.prototype=new Stream,CoalesceStream=function(options,metadataStream){this.numberOfTracks=0,this.metadataStream=metadataStream,void 0!==(options=options||{}).remux?this.remuxTracks=!!options.remux:this.remuxTracks=!0,"boolean"==typeof options.keepOriginalTimestamps?this.keepOriginalTimestamps=options.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,CoalesceStream.prototype.init.call(this),this.push=function(output){return output.content||output.text?this.pendingCaptions.push(output):output.frames?this.pendingMetadata.push(output):(this.pendingTracks.push(output.track),this.pendingBytes+=output.boxes.byteLength,"video"===output.track.type&&(this.videoTrack=output.track,this.pendingBoxes.push(output.boxes)),void("audio"===output.track.type&&(this.audioTrack=output.track,this.pendingBoxes.unshift(output.boxes))))}},CoalesceStream.prototype=new Stream,CoalesceStream.prototype.flush=function(flushSource){var caption,id3,initSegment,i,offset=0,event={captions:[],captionStreams:{},metadata:[],info:{}},timelineStartPts=0;if(this.pendingTracks.length=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(timelineStartPts=this.videoTrack.timelineStartInfo.pts,VIDEO_PROPERTIES.forEach((function(prop){event.info[prop]=this.videoTrack[prop]}),this)):this.audioTrack&&(timelineStartPts=this.audioTrack.timelineStartInfo.pts,AUDIO_PROPERTIES.forEach((function(prop){event.info[prop]=this.audioTrack[prop]}),this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?event.type=this.pendingTracks[0].type:event.type="combined",this.emittedTracks+=this.pendingTracks.length,initSegment=mp4.initSegment(this.pendingTracks),event.initSegment=new Uint8Array(initSegment.byteLength),event.initSegment.set(initSegment),event.data=new Uint8Array(this.pendingBytes),i=0;i=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},CoalesceStream.prototype.setRemux=function(val){this.remuxTracks=val},(Transmuxer=function(options){var videoTrack,audioTrack,self=this,hasFlushed=!0;Transmuxer.prototype.init.call(this),options=options||{},this.baseMediaDecodeTime=options.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var pipeline={};this.transmuxPipeline_=pipeline,pipeline.type="aac",pipeline.metadataStream=new m2ts.MetadataStream,pipeline.aacStream=new AacStream,pipeline.audioTimestampRolloverStream=new m2ts.TimestampRolloverStream("audio"),pipeline.timedMetadataTimestampRolloverStream=new m2ts.TimestampRolloverStream("timed-metadata"),pipeline.adtsStream=new AdtsStream,pipeline.coalesceStream=new CoalesceStream(options,pipeline.metadataStream),pipeline.headOfPipeline=pipeline.aacStream,pipeline.aacStream.pipe(pipeline.audioTimestampRolloverStream).pipe(pipeline.adtsStream),pipeline.aacStream.pipe(pipeline.timedMetadataTimestampRolloverStream).pipe(pipeline.metadataStream).pipe(pipeline.coalesceStream),pipeline.metadataStream.on("timestamp",(function(frame){pipeline.aacStream.setTimestamp(frame.timeStamp)})),pipeline.aacStream.on("data",(function(data){"timed-metadata"!==data.type&&"audio"!==data.type||pipeline.audioSegmentStream||(audioTrack=audioTrack||{timelineStartInfo:{baseMediaDecodeTime:self.baseMediaDecodeTime},codec:"adts",type:"audio"},pipeline.coalesceStream.numberOfTracks++,pipeline.audioSegmentStream=new AudioSegmentStream(audioTrack,options),pipeline.audioSegmentStream.on("log",self.getLogTrigger_("audioSegmentStream")),pipeline.audioSegmentStream.on("timingInfo",self.trigger.bind(self,"audioTimingInfo")),pipeline.adtsStream.pipe(pipeline.audioSegmentStream).pipe(pipeline.coalesceStream),self.trigger("trackinfo",{hasAudio:!!audioTrack,hasVideo:!!videoTrack}))})),pipeline.coalesceStream.on("data",this.trigger.bind(this,"data")),pipeline.coalesceStream.on("done",this.trigger.bind(this,"done")),addPipelineLogRetriggers(this,pipeline)},this.setupTsPipeline=function(){var pipeline={};this.transmuxPipeline_=pipeline,pipeline.type="ts",pipeline.metadataStream=new m2ts.MetadataStream,pipeline.packetStream=new m2ts.TransportPacketStream,pipeline.parseStream=new m2ts.TransportParseStream,pipeline.elementaryStream=new m2ts.ElementaryStream,pipeline.timestampRolloverStream=new m2ts.TimestampRolloverStream,pipeline.adtsStream=new AdtsStream,pipeline.h264Stream=new H264Stream,pipeline.captionStream=new m2ts.CaptionStream(options),pipeline.coalesceStream=new CoalesceStream(options,pipeline.metadataStream),pipeline.headOfPipeline=pipeline.packetStream,pipeline.packetStream.pipe(pipeline.parseStream).pipe(pipeline.elementaryStream).pipe(pipeline.timestampRolloverStream),pipeline.timestampRolloverStream.pipe(pipeline.h264Stream),pipeline.timestampRolloverStream.pipe(pipeline.adtsStream),pipeline.timestampRolloverStream.pipe(pipeline.metadataStream).pipe(pipeline.coalesceStream),pipeline.h264Stream.pipe(pipeline.captionStream).pipe(pipeline.coalesceStream),pipeline.elementaryStream.on("data",(function(data){var i;if("metadata"===data.type){for(i=data.tracks.length;i--;)videoTrack||"video"!==data.tracks[i].type?audioTrack||"audio"!==data.tracks[i].type||((audioTrack=data.tracks[i]).timelineStartInfo.baseMediaDecodeTime=self.baseMediaDecodeTime):(videoTrack=data.tracks[i]).timelineStartInfo.baseMediaDecodeTime=self.baseMediaDecodeTime;videoTrack&&!pipeline.videoSegmentStream&&(pipeline.coalesceStream.numberOfTracks++,pipeline.videoSegmentStream=new VideoSegmentStream(videoTrack,options),pipeline.videoSegmentStream.on("log",self.getLogTrigger_("videoSegmentStream")),pipeline.videoSegmentStream.on("timelineStartInfo",(function(timelineStartInfo){audioTrack&&!options.keepOriginalTimestamps&&(audioTrack.timelineStartInfo=timelineStartInfo,pipeline.audioSegmentStream.setEarliestDts(timelineStartInfo.dts-self.baseMediaDecodeTime))})),pipeline.videoSegmentStream.on("processedGopsInfo",self.trigger.bind(self,"gopInfo")),pipeline.videoSegmentStream.on("segmentTimingInfo",self.trigger.bind(self,"videoSegmentTimingInfo")),pipeline.videoSegmentStream.on("baseMediaDecodeTime",(function(baseMediaDecodeTime){audioTrack&&pipeline.audioSegmentStream.setVideoBaseMediaDecodeTime(baseMediaDecodeTime)})),pipeline.videoSegmentStream.on("timingInfo",self.trigger.bind(self,"videoTimingInfo")),pipeline.h264Stream.pipe(pipeline.videoSegmentStream).pipe(pipeline.coalesceStream)),audioTrack&&!pipeline.audioSegmentStream&&(pipeline.coalesceStream.numberOfTracks++,pipeline.audioSegmentStream=new AudioSegmentStream(audioTrack,options),pipeline.audioSegmentStream.on("log",self.getLogTrigger_("audioSegmentStream")),pipeline.audioSegmentStream.on("timingInfo",self.trigger.bind(self,"audioTimingInfo")),pipeline.audioSegmentStream.on("segmentTimingInfo",self.trigger.bind(self,"audioSegmentTimingInfo")),pipeline.adtsStream.pipe(pipeline.audioSegmentStream).pipe(pipeline.coalesceStream)),self.trigger("trackinfo",{hasAudio:!!audioTrack,hasVideo:!!videoTrack})}})),pipeline.coalesceStream.on("data",this.trigger.bind(this,"data")),pipeline.coalesceStream.on("id3Frame",(function(id3Frame){id3Frame.dispatchType=pipeline.metadataStream.dispatchType,self.trigger("id3Frame",id3Frame)})),pipeline.coalesceStream.on("caption",this.trigger.bind(this,"caption")),pipeline.coalesceStream.on("done",this.trigger.bind(this,"done")),addPipelineLogRetriggers(this,pipeline)},this.setBaseMediaDecodeTime=function(baseMediaDecodeTime){var pipeline=this.transmuxPipeline_;options.keepOriginalTimestamps||(this.baseMediaDecodeTime=baseMediaDecodeTime),audioTrack&&(audioTrack.timelineStartInfo.dts=void 0,audioTrack.timelineStartInfo.pts=void 0,trackDecodeInfo.clearDtsInfo(audioTrack),pipeline.audioTimestampRolloverStream&&pipeline.audioTimestampRolloverStream.discontinuity()),videoTrack&&(pipeline.videoSegmentStream&&(pipeline.videoSegmentStream.gopCache_=[]),videoTrack.timelineStartInfo.dts=void 0,videoTrack.timelineStartInfo.pts=void 0,trackDecodeInfo.clearDtsInfo(videoTrack),pipeline.captionStream.reset()),pipeline.timestampRolloverStream&&pipeline.timestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(timestamp){audioTrack&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(timestamp)},this.setRemux=function(val){var pipeline=this.transmuxPipeline_;options.remux=val,pipeline&&pipeline.coalesceStream&&pipeline.coalesceStream.setRemux(val)},this.alignGopsWith=function(gopsToAlignWith){videoTrack&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(gopsToAlignWith)},this.getLogTrigger_=function(key){var self=this;return function(event){event.stream=key,self.trigger("log",event)}},this.push=function(data){if(hasFlushed){var isAac=isLikelyAacData(data);isAac&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():isAac||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),hasFlushed=!1}this.transmuxPipeline_.headOfPipeline.push(data)},this.flush=function(){hasFlushed=!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 Stream;var win,startTime,getTracks,getTimescaleFromMediaHeader,getEmsgID3,transmuxer={Transmuxer:Transmuxer,VideoSegmentStream:VideoSegmentStream,AudioSegmentStream:AudioSegmentStream,AUDIO_PROPERTIES:AUDIO_PROPERTIES,VIDEO_PROPERTIES:VIDEO_PROPERTIES,generateSegmentTimingInfo:generateSegmentTimingInfo},bin_toUnsigned=function(value){return value>>>0},parseType_1=function(buffer){var result="";return result+=String.fromCharCode(buffer[0]),result+=String.fromCharCode(buffer[1]),result+=String.fromCharCode(buffer[2]),result+=String.fromCharCode(buffer[3])},toUnsigned$2=bin_toUnsigned,parseType$2=parseType_1,findBox$2=function(data,path){var i,size,type,end,subresults,results=[];if(!path.length)return null;for(i=0;i1?i+size:data.byteLength,type===path[0]&&(1===path.length?results.push(data.subarray(i+8,end)):(subresults=findBox$2(data.subarray(i+8,end),path.slice(1))).length&&(results=results.concat(subresults))),i=end;return results},toUnsigned$1=bin_toUnsigned,getUint64$2=numbers.getUint64,parseTfdt$2=function(data){var result={version:data[0],flags:new Uint8Array(data.subarray(1,4))};return 1===result.version?result.baseMediaDecodeTime=getUint64$2(data.subarray(4)):result.baseMediaDecodeTime=toUnsigned$1(data[4]<<24|data[5]<<16|data[6]<<8|data[7]),result},parseSampleFlags=function(flags){return{isLeading:(12&flags[0])>>>2,dependsOn:3&flags[0],isDependedOn:(192&flags[1])>>>6,hasRedundancy:(48&flags[1])>>>4,paddingValue:(14&flags[1])>>>1,isNonSyncSample:1&flags[1],degradationPriority:flags[2]<<8|flags[3]}},parseTrun$2=function(data){var sample,result={version:data[0],flags:new Uint8Array(data.subarray(1,4)),samples:[]},view=new DataView(data.buffer,data.byteOffset,data.byteLength),dataOffsetPresent=1&result.flags[2],firstSampleFlagsPresent=4&result.flags[2],sampleDurationPresent=1&result.flags[1],sampleSizePresent=2&result.flags[1],sampleFlagsPresent=4&result.flags[1],sampleCompositionTimeOffsetPresent=8&result.flags[1],sampleCount=view.getUint32(4),offset=8;for(dataOffsetPresent&&(result.dataOffset=view.getInt32(offset),offset+=4),firstSampleFlagsPresent&&sampleCount&&(sample={flags:parseSampleFlags(data.subarray(offset,offset+4))},offset+=4,sampleDurationPresent&&(sample.duration=view.getUint32(offset),offset+=4),sampleSizePresent&&(sample.size=view.getUint32(offset),offset+=4),sampleCompositionTimeOffsetPresent&&(1===result.version?sample.compositionTimeOffset=view.getInt32(offset):sample.compositionTimeOffset=view.getUint32(offset),offset+=4),result.samples.push(sample),sampleCount--);sampleCount--;)sample={},sampleDurationPresent&&(sample.duration=view.getUint32(offset),offset+=4),sampleSizePresent&&(sample.size=view.getUint32(offset),offset+=4),sampleFlagsPresent&&(sample.flags=parseSampleFlags(data.subarray(offset,offset+4)),offset+=4),sampleCompositionTimeOffsetPresent&&(1===result.version?sample.compositionTimeOffset=view.getInt32(offset):sample.compositionTimeOffset=view.getUint32(offset),offset+=4),result.samples.push(sample);return result},parseTfhd$2=function(data){var i,view=new DataView(data.buffer,data.byteOffset,data.byteLength),result={version:data[0],flags:new Uint8Array(data.subarray(1,4)),trackId:view.getUint32(4)},baseDataOffsetPresent=1&result.flags[2],sampleDescriptionIndexPresent=2&result.flags[2],defaultSampleDurationPresent=8&result.flags[2],defaultSampleSizePresent=16&result.flags[2],defaultSampleFlagsPresent=32&result.flags[2],durationIsEmpty=65536&result.flags[0],defaultBaseIsMoof=131072&result.flags[0];return i=8,baseDataOffsetPresent&&(i+=4,result.baseDataOffset=view.getUint32(12),i+=4),sampleDescriptionIndexPresent&&(result.sampleDescriptionIndex=view.getUint32(i),i+=4),defaultSampleDurationPresent&&(result.defaultSampleDuration=view.getUint32(i),i+=4),defaultSampleSizePresent&&(result.defaultSampleSize=view.getUint32(i),i+=4),defaultSampleFlagsPresent&&(result.defaultSampleFlags=view.getUint32(i)),durationIsEmpty&&(result.durationIsEmpty=!0),!baseDataOffsetPresent&&defaultBaseIsMoof&&(result.baseDataOffsetIsMoof=!0),result},discardEmulationPreventionBytes=(win="undefined"!=typeof window?window:void 0!==commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{},captionPacketParser.discardEmulationPreventionBytes),CaptionStream=captionStream.CaptionStream,findBox$1=findBox$2,parseTfdt$1=parseTfdt$2,parseTrun$1=parseTrun$2,parseTfhd$1=parseTfhd$2,window$2=win,mapToSample=function(offset,samples){for(var approximateOffset=offset,i=0;i0?parseTfdt$1(tfdt[0]).baseMediaDecodeTime:0,truns=findBox$1(traf,["trun"]);videoTrackId===trackId&&truns.length>0&&(samples=function(truns,baseMediaDecodeTime,tfhd){var currentDts=baseMediaDecodeTime,defaultSampleDuration=tfhd.defaultSampleDuration||0,defaultSampleSize=tfhd.defaultSampleSize||0,trackId=tfhd.trackId,allSamples=[];return truns.forEach((function(trun){var samples=parseTrun$1(trun).samples;samples.forEach((function(sample){void 0===sample.duration&&(sample.duration=defaultSampleDuration),void 0===sample.size&&(sample.size=defaultSampleSize),sample.trackId=trackId,sample.dts=currentDts,void 0===sample.compositionTimeOffset&&(sample.compositionTimeOffset=0),"bigint"==typeof currentDts?(sample.pts=currentDts+window$2.BigInt(sample.compositionTimeOffset),currentDts+=window$2.BigInt(sample.duration)):(sample.pts=currentDts+sample.compositionTimeOffset,currentDts+=sample.duration)})),allSamples=allSamples.concat(samples)})),allSamples}(truns,baseMediaDecodeTime,headerInfo),result=function(avcStream,samples,trackId){var seiNal,i,length,lastMatchedSample,avcView=new DataView(avcStream.buffer,avcStream.byteOffset,avcStream.byteLength),result={logs:[],seiNals:[]};for(i=0;i+40;){var cachedSegment=segmentCache.shift();this.parse(cachedSegment,videoTrackIds,timescales)}return parsedData=function(segment,trackId,timescale){if(null===trackId)return null;var trackNals=parseCaptionNals(segment,trackId)[trackId]||{};return{seiNals:trackNals.seiNals,logs:trackNals.logs,timescale:timescale}}(segment,trackId,timescale),parsedData&&parsedData.logs&&(parsedCaptions.logs=parsedCaptions.logs.concat(parsedData.logs)),null!==parsedData&&parsedData.seiNals?(this.pushNals(parsedData.seiNals),this.flushStream(),parsedCaptions):parsedCaptions.logs.length?{logs:parsedCaptions.logs,captions:[],captionStreams:[]}:null},this.pushNals=function(nals){if(!this.isInitialized()||!nals||0===nals.length)return null;nals.forEach((function(nal){captionStream.push(nal)}))},this.flushStream=function(){if(!this.isInitialized())return null;parsingPartial?captionStream.partialFlush():captionStream.flush()},this.clearParsedCaptions=function(){parsedCaptions.captions=[],parsedCaptions.captionStreams={},parsedCaptions.logs=[]},this.resetCaptionStream=function(){if(!this.isInitialized())return null;captionStream.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){segmentCache=[],trackId=null,timescale=null,parsedCaptions?this.clearParsedCaptions():parsedCaptions={captions:[],captionStreams:{},logs:[]},this.resetCaptionStream()},this.reset()},uint8ToCString=function(data){for(var index=0,curChar=String.fromCharCode(data[index]),retString="";"\0"!==curChar;)retString+=curChar,index++,curChar=String.fromCharCode(data[index]);return retString+=curChar},getUint64$1=numbers.getUint64,isValidEmsgBox=function(version,emsg){var hasScheme="\0"!==emsg.scheme_id_uri,isValidV0Box=0===version&&isDefined(emsg.presentation_time_delta)&&hasScheme,isValidV1Box=1===version&&isDefined(emsg.presentation_time)&&hasScheme;return!(version>1)&&isValidV0Box||isValidV1Box},isDefined=function(data){return void 0!==data||null!==data},emsg$1={parseEmsgBox:function(boxData){var scheme_id_uri,value,timescale,presentation_time,presentation_time_delta,event_duration,id,offset=4,version=boxData[0];if(0===version)offset+=(scheme_id_uri=uint8ToCString(boxData.subarray(offset))).length,offset+=(value=uint8ToCString(boxData.subarray(offset))).length,timescale=(dv=new DataView(boxData.buffer)).getUint32(offset),offset+=4,presentation_time_delta=dv.getUint32(offset),offset+=4,event_duration=dv.getUint32(offset),offset+=4,id=dv.getUint32(offset),offset+=4;else if(1===version){var dv;timescale=(dv=new DataView(boxData.buffer)).getUint32(offset),offset+=4,presentation_time=getUint64$1(boxData.subarray(offset)),offset+=8,event_duration=dv.getUint32(offset),offset+=4,id=dv.getUint32(offset),offset+=4,offset+=(scheme_id_uri=uint8ToCString(boxData.subarray(offset))).length,offset+=(value=uint8ToCString(boxData.subarray(offset))).length}var emsgBox={scheme_id_uri:scheme_id_uri,value:value,timescale:timescale||1,presentation_time:presentation_time,presentation_time_delta:presentation_time_delta,event_duration:event_duration,id:id,message_data:new Uint8Array(boxData.subarray(offset,boxData.byteLength))};return isValidEmsgBox(version,emsgBox)?emsgBox:void 0},scaleTime:function(presentationTime,timescale,timeDelta,offset){return presentationTime||0===presentationTime?presentationTime/timescale:offset+timeDelta/timescale}},toUnsigned=bin_toUnsigned,toHexString=function(value){return("00"+value.toString(16)).slice(-2)},findBox=findBox$2,parseType$1=parseType_1,emsg=emsg$1,parseTfhd=parseTfhd$2,parseTrun=parseTrun$2,parseTfdt=parseTfdt$2,getUint64=numbers.getUint64,window$1=win,parseId3Frames=parseId3.parseId3Frames;startTime=function(timescale,fragment){var lowestTime=findBox(fragment,["moof","traf"]).reduce((function(acc,traf){var baseTime,tfhd=findBox(traf,["tfhd"])[0],id=toUnsigned(tfhd[4]<<24|tfhd[5]<<16|tfhd[6]<<8|tfhd[7]),scale=timescale[id]||9e4,tfdt=findBox(traf,["tfdt"])[0],dv=new DataView(tfdt.buffer,tfdt.byteOffset,tfdt.byteLength);let seconds;return"bigint"==typeof(baseTime=1===tfdt[0]?getUint64(tfdt.subarray(4,12)):dv.getUint32(4))?seconds=baseTime/window$1.BigInt(scale):"number"!=typeof baseTime||isNaN(baseTime)||(seconds=baseTime/scale),seconds11?(track.codec+=".",track.codec+=toHexString(codecConfig[9]),track.codec+=toHexString(codecConfig[10]),track.codec+=toHexString(codecConfig[11])):track.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(track.codec)?(codecConfig=codecBox.subarray(28),"esds"===parseType$1(codecConfig.subarray(4,8))&&codecConfig.length>20&&0!==codecConfig[19]?(track.codec+="."+toHexString(codecConfig[19]),track.codec+="."+toHexString(codecConfig[20]>>>2&63).replace(/^0/,"")):track.codec="mp4a.40.2"):track.codec=track.codec.toLowerCase())}var mdhd=findBox(trak,["mdia","mdhd"])[0];mdhd&&(track.timescale=getTimescaleFromMediaHeader(mdhd)),tracks.push(track)})),tracks},getEmsgID3=function(segmentData){let offset=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;var emsgBoxes=findBox(segmentData,["emsg"]);return emsgBoxes.map((data=>{var parsedBox=emsg.parseEmsgBox(new Uint8Array(data)),parsedId3Frames=parseId3Frames(parsedBox.message_data);return{cueTime:emsg.scaleTime(parsedBox.presentation_time,parsedBox.timescale,parsedBox.presentation_time_delta,offset),duration:emsg.scaleTime(parsedBox.event_duration,parsedBox.timescale),frames:parsedId3Frames}}))};var probe$2_startTime=startTime,probe$2_tracks=getTracks,probe$2_getEmsgID3=getEmsgID3,StreamTypes$1=streamTypes,parsePid=function(packet){var pid=31&packet[1];return pid<<=8,pid|=packet[2]},parsePayloadUnitStartIndicator=function(packet){return!!(64&packet[1])},parseAdaptionField=function(packet){var offset=0;return(48&packet[3])>>>4>1&&(offset+=packet[4]+1),offset},parseNalUnitType=function(type){switch(type){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}},probe$1={parseType:function(packet,pmtPid){var pid=parsePid(packet);return 0===pid?"pat":pid===pmtPid?"pmt":pmtPid?"pes":null},parsePat:function(packet){var pusi=parsePayloadUnitStartIndicator(packet),offset=4+parseAdaptionField(packet);return pusi&&(offset+=packet[offset]+1),(31&packet[offset+10])<<8|packet[offset+11]},parsePmt:function(packet){var programMapTable={},pusi=parsePayloadUnitStartIndicator(packet),payloadOffset=4+parseAdaptionField(packet);if(pusi&&(payloadOffset+=packet[payloadOffset]+1),1&packet[payloadOffset+5]){var tableEnd;tableEnd=3+((15&packet[payloadOffset+1])<<8|packet[payloadOffset+2])-4;for(var offset=12+((15&packet[payloadOffset+10])<<8|packet[payloadOffset+11]);offset=packet.byteLength)return null;var ptsDtsFlags,pes=null;return 192&(ptsDtsFlags=packet[offset+7])&&((pes={}).pts=(14&packet[offset+9])<<27|(255&packet[offset+10])<<20|(254&packet[offset+11])<<12|(255&packet[offset+12])<<5|(254&packet[offset+13])>>>3,pes.pts*=4,pes.pts+=(6&packet[offset+13])>>>1,pes.dts=pes.pts,64&ptsDtsFlags&&(pes.dts=(14&packet[offset+14])<<27|(255&packet[offset+15])<<20|(254&packet[offset+16])<<12|(255&packet[offset+17])<<5|(254&packet[offset+18])>>>3,pes.dts*=4,pes.dts+=(6&packet[offset+18])>>>1)),pes},videoPacketContainsKeyFrame:function(packet){for(var offset=4+parseAdaptionField(packet),frameBuffer=packet.subarray(offset),frameI=0,frameSyncPoint=0,foundKeyFrame=!1;frameSyncPoint3&&"slice_layer_without_partitioning_rbsp_idr"===parseNalUnitType(31&frameBuffer[frameSyncPoint+3])&&(foundKeyFrame=!0),foundKeyFrame}},StreamTypes=streamTypes,handleRollover=timestampRolloverStream.handleRollover,probe={};probe.ts=probe$1,probe.aac=utils;var ONE_SECOND_IN_TS=clock$2.ONE_SECOND_IN_TS,parseAudioPes_=function(bytes,pmt,result){for(var packet,pesType,pusi,parsed,startIndex=0,endIndex=188,endLoop=!1;endIndex<=bytes.byteLength;)if(71!==bytes[startIndex]||71!==bytes[endIndex]&&endIndex!==bytes.byteLength)startIndex++,endIndex++;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"audio"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="audio",result.audio.push(parsed),endLoop=!0);if(endLoop)break;startIndex+=188,endIndex+=188}for(startIndex=(endIndex=bytes.byteLength)-188,endLoop=!1;startIndex>=0;)if(71!==bytes[startIndex]||71!==bytes[endIndex]&&endIndex!==bytes.byteLength)startIndex--,endIndex--;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"audio"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="audio",result.audio.push(parsed),endLoop=!0);if(endLoop)break;startIndex-=188,endIndex-=188}},parseVideoPes_=function(bytes,pmt,result){for(var packet,pesType,pusi,parsed,frame,i,pes,startIndex=0,endIndex=188,endLoop=!1,currentFrame={data:[],size:0};endIndex=0;)if(71!==bytes[startIndex]||71!==bytes[endIndex])startIndex--,endIndex--;else{if(packet=bytes.subarray(startIndex,endIndex),"pes"===probe.ts.parseType(packet,pmt.pid))pesType=probe.ts.parsePesType(packet,pmt.table),pusi=probe.ts.parsePayloadUnitStartIndicator(packet),"video"===pesType&&pusi&&(parsed=probe.ts.parsePesTime(packet))&&(parsed.type="video",result.video.push(parsed),endLoop=!0);if(endLoop)break;startIndex-=188,endIndex-=188}},inspectTs_=function(bytes){var pmt={pid:null,table:null},result={};for(var pid in function(bytes,pmt){for(var packet,startIndex=0,endIndex=188;endIndex=3;){switch(probe.aac.parseType(bytes,byteIndex)){case"timed-metadata":if(bytes.length-byteIndex<10){endLoop=!0;break}if((frameSize=probe.aac.parseId3TagSize(bytes,byteIndex))>bytes.length){endLoop=!0;break}null===timestamp&&(packet=bytes.subarray(byteIndex,byteIndex+frameSize),timestamp=probe.aac.parseAacTimestamp(packet)),byteIndex+=frameSize;break;case"audio":if(bytes.length-byteIndex<7){endLoop=!0;break}if((frameSize=probe.aac.parseAdtsSize(bytes,byteIndex))>bytes.length){endLoop=!0;break}null===sampleRate&&(packet=bytes.subarray(byteIndex,byteIndex+frameSize),sampleRate=probe.aac.parseSampleRate(packet)),audioCount++,byteIndex+=frameSize;break;default:byteIndex++}if(endLoop)return null}if(null===sampleRate||null===timestamp)return null;var audioTimescale=ONE_SECOND_IN_TS/sampleRate;return{audio:[{type:"audio",dts:timestamp,pts:timestamp},{type:"audio",dts:timestamp+1024*audioCount*audioTimescale,pts:timestamp+1024*audioCount*audioTimescale}]}}(bytes):inspectTs_(bytes),result&&(result.audio||result.video)?(function(segmentInfo,baseTimestamp){if(segmentInfo.audio&&segmentInfo.audio.length){var audioBaseTimestamp=baseTimestamp;(void 0===audioBaseTimestamp||isNaN(audioBaseTimestamp))&&(audioBaseTimestamp=segmentInfo.audio[0].dts),segmentInfo.audio.forEach((function(info){info.dts=handleRollover(info.dts,audioBaseTimestamp),info.pts=handleRollover(info.pts,audioBaseTimestamp),info.dtsTime=info.dts/ONE_SECOND_IN_TS,info.ptsTime=info.pts/ONE_SECOND_IN_TS}))}if(segmentInfo.video&&segmentInfo.video.length){var videoBaseTimestamp=baseTimestamp;if((void 0===videoBaseTimestamp||isNaN(videoBaseTimestamp))&&(videoBaseTimestamp=segmentInfo.video[0].dts),segmentInfo.video.forEach((function(info){info.dts=handleRollover(info.dts,videoBaseTimestamp),info.pts=handleRollover(info.pts,videoBaseTimestamp),info.dtsTime=info.dts/ONE_SECOND_IN_TS,info.ptsTime=info.pts/ONE_SECOND_IN_TS})),segmentInfo.firstKeyFrame){var frame=segmentInfo.firstKeyFrame;frame.dts=handleRollover(frame.dts,videoBaseTimestamp),frame.pts=handleRollover(frame.pts,videoBaseTimestamp),frame.dtsTime=frame.dts/ONE_SECOND_IN_TS,frame.ptsTime=frame.pts/ONE_SECOND_IN_TS}}}(result,baseTimestamp),result):null};class MessageHandlers{constructor(self,options){this.options=options||{},this.self=self,this.init()}init(){this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new transmuxer.Transmuxer(this.options),function(self,transmuxer){transmuxer.on("data",(function(segment){const initArray=segment.initSegment;segment.initSegment={data:initArray.buffer,byteOffset:initArray.byteOffset,byteLength:initArray.byteLength};const typedArray=segment.data;segment.data=typedArray.buffer,self.postMessage({action:"data",segment:segment,byteOffset:typedArray.byteOffset,byteLength:typedArray.byteLength},[segment.data])})),transmuxer.on("done",(function(data){self.postMessage({action:"done"})})),transmuxer.on("gopInfo",(function(gopInfo){self.postMessage({action:"gopInfo",gopInfo:gopInfo})})),transmuxer.on("videoSegmentTimingInfo",(function(timingInfo){const videoSegmentTimingInfo={start:{decode:clock$2.videoTsToSeconds(timingInfo.start.dts),presentation:clock$2.videoTsToSeconds(timingInfo.start.pts)},end:{decode:clock$2.videoTsToSeconds(timingInfo.end.dts),presentation:clock$2.videoTsToSeconds(timingInfo.end.pts)},baseMediaDecodeTime:clock$2.videoTsToSeconds(timingInfo.baseMediaDecodeTime)};timingInfo.prependedContentDuration&&(videoSegmentTimingInfo.prependedContentDuration=clock$2.videoTsToSeconds(timingInfo.prependedContentDuration)),self.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:videoSegmentTimingInfo})})),transmuxer.on("audioSegmentTimingInfo",(function(timingInfo){const audioSegmentTimingInfo={start:{decode:clock$2.videoTsToSeconds(timingInfo.start.dts),presentation:clock$2.videoTsToSeconds(timingInfo.start.pts)},end:{decode:clock$2.videoTsToSeconds(timingInfo.end.dts),presentation:clock$2.videoTsToSeconds(timingInfo.end.pts)},baseMediaDecodeTime:clock$2.videoTsToSeconds(timingInfo.baseMediaDecodeTime)};timingInfo.prependedContentDuration&&(audioSegmentTimingInfo.prependedContentDuration=clock$2.videoTsToSeconds(timingInfo.prependedContentDuration)),self.postMessage({action:"audioSegmentTimingInfo",audioSegmentTimingInfo:audioSegmentTimingInfo})})),transmuxer.on("id3Frame",(function(id3Frame){self.postMessage({action:"id3Frame",id3Frame:id3Frame})})),transmuxer.on("caption",(function(caption){self.postMessage({action:"caption",caption:caption})})),transmuxer.on("trackinfo",(function(trackInfo){self.postMessage({action:"trackinfo",trackInfo:trackInfo})})),transmuxer.on("audioTimingInfo",(function(audioTimingInfo){self.postMessage({action:"audioTimingInfo",audioTimingInfo:{start:clock$2.videoTsToSeconds(audioTimingInfo.start),end:clock$2.videoTsToSeconds(audioTimingInfo.end)}})})),transmuxer.on("videoTimingInfo",(function(videoTimingInfo){self.postMessage({action:"videoTimingInfo",videoTimingInfo:{start:clock$2.videoTsToSeconds(videoTimingInfo.start),end:clock$2.videoTsToSeconds(videoTimingInfo.end)}})})),transmuxer.on("log",(function(log){self.postMessage({action:"log",log:log})}))}(this.self,this.transmuxer)}pushMp4Captions(data){this.captionParser||(this.captionParser=new captionParser,this.captionParser.init());const segment=new Uint8Array(data.data,data.byteOffset,data.byteLength),parsed=this.captionParser.parse(segment,data.trackIds,data.timescales);this.self.postMessage({action:"mp4Captions",captions:parsed&&parsed.captions||[],logs:parsed&&parsed.logs||[],data:segment.buffer},[segment.buffer])}probeMp4StartTime(_ref43){let{timescales:timescales,data:data}=_ref43;const startTime=probe$2_startTime(timescales,data);this.self.postMessage({action:"probeMp4StartTime",startTime:startTime,data:data},[data.buffer])}probeMp4Tracks(_ref44){let{data:data}=_ref44;const tracks=probe$2_tracks(data);this.self.postMessage({action:"probeMp4Tracks",tracks:tracks,data:data},[data.buffer])}probeEmsgID3(_ref45){let{data:data,offset:offset}=_ref45;const id3Frames=probe$2_getEmsgID3(data,offset);this.self.postMessage({action:"probeEmsgID3",id3Frames:id3Frames,emsgData:data},[data.buffer])}probeTs(_ref46){let{data:data,baseStartTime:baseStartTime}=_ref46;const tsStartTime="number"!=typeof baseStartTime||isNaN(baseStartTime)?void 0:baseStartTime*clock$2.ONE_SECOND_IN_TS,timeInfo=tsInspector_inspect(data,tsStartTime);let result=null;timeInfo&&(result={hasVideo:timeInfo.video&&2===timeInfo.video.length||!1,hasAudio:timeInfo.audio&&2===timeInfo.audio.length||!1},result.hasVideo&&(result.videoStart=timeInfo.video[0].ptsTime),result.hasAudio&&(result.audioStart=timeInfo.audio[0].ptsTime)),this.self.postMessage({action:"probeTs",result:result,data:data},[data.buffer])}clearAllMp4Captions(){this.captionParser&&this.captionParser.clearAllCaptions()}clearParsedMp4Captions(){this.captionParser&&this.captionParser.clearParsedCaptions()}push(data){const segment=new Uint8Array(data.data,data.byteOffset,data.byteLength);this.transmuxer.push(segment)}reset(){this.transmuxer.reset()}setTimestampOffset(data){const timestampOffset=data.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(clock$2.secondsToVideoTs(timestampOffset)))}setAudioAppendStart(data){this.transmuxer.setAudioAppendStart(Math.ceil(clock$2.secondsToVideoTs(data.appendStart)))}setRemux(data){this.transmuxer.setRemux(data.remux)}flush(data){this.transmuxer.flush(),self.postMessage({action:"done",type:"transmuxed"})}endTimeline(){this.transmuxer.endTimeline(),self.postMessage({action:"endedtimeline",type:"transmuxed"})}alignGopsWith(data){this.transmuxer.alignGopsWith(data.gopsToAlignWith.slice())}}self.onmessage=function(event){"init"===event.data.action&&event.data.options?this.messageHandlers=new MessageHandlers(self,event.data.options):(this.messageHandlers||(this.messageHandlers=new MessageHandlers(self)),event.data&&event.data.action&&"init"!==event.data.action&&this.messageHandlers[event.data.action]&&this.messageHandlers[event.data.action](event.data))}})));var TransmuxWorker=factory(workerCode$1);const processTransmux=options=>{const{transmuxer:transmuxer,bytes:bytes,audioAppendStart:audioAppendStart,gopsToAlignWith:gopsToAlignWith,remux:remux,onData:onData,onTrackInfo:onTrackInfo,onAudioTimingInfo:onAudioTimingInfo,onVideoTimingInfo:onVideoTimingInfo,onVideoSegmentTimingInfo:onVideoSegmentTimingInfo,onAudioSegmentTimingInfo:onAudioSegmentTimingInfo,onId3:onId3,onCaptions:onCaptions,onDone:onDone,onEndedTimeline:onEndedTimeline,onTransmuxerLog:onTransmuxerLog,isEndOfTimeline:isEndOfTimeline}=options,transmuxedData={buffer:[]};let waitForEndedTimelineEvent=isEndOfTimeline;if(transmuxer.onmessage=event=>{transmuxer.currentTransmux===options&&("data"===event.data.action&&((event,transmuxedData,callback)=>{const{type:type,initSegment:initSegment,captions:captions,captionStreams:captionStreams,metadata:metadata,videoFrameDtsTime:videoFrameDtsTime,videoFramePtsTime:videoFramePtsTime}=event.data.segment;transmuxedData.buffer.push({captions:captions,captionStreams:captionStreams,metadata:metadata});const boxes=event.data.segment.boxes||{data:event.data.segment.data},result={type:type,data:new Uint8Array(boxes.data,boxes.data.byteOffset,boxes.data.byteLength),initSegment:new Uint8Array(initSegment.data,initSegment.byteOffset,initSegment.byteLength)};void 0!==videoFrameDtsTime&&(result.videoFrameDtsTime=videoFrameDtsTime),void 0!==videoFramePtsTime&&(result.videoFramePtsTime=videoFramePtsTime),callback(result)})(event,transmuxedData,onData),"trackinfo"===event.data.action&&onTrackInfo(event.data.trackInfo),"gopInfo"===event.data.action&&((event,transmuxedData)=>{transmuxedData.gopInfo=event.data.gopInfo})(event,transmuxedData),"audioTimingInfo"===event.data.action&&onAudioTimingInfo(event.data.audioTimingInfo),"videoTimingInfo"===event.data.action&&onVideoTimingInfo(event.data.videoTimingInfo),"videoSegmentTimingInfo"===event.data.action&&onVideoSegmentTimingInfo(event.data.videoSegmentTimingInfo),"audioSegmentTimingInfo"===event.data.action&&onAudioSegmentTimingInfo(event.data.audioSegmentTimingInfo),"id3Frame"===event.data.action&&onId3([event.data.id3Frame],event.data.id3Frame.dispatchType),"caption"===event.data.action&&onCaptions(event.data.caption),"endedtimeline"===event.data.action&&(waitForEndedTimelineEvent=!1,onEndedTimeline()),"log"===event.data.action&&onTransmuxerLog(event.data.log),"transmuxed"===event.data.type&&(waitForEndedTimelineEvent||(transmuxer.onmessage=null,(_ref47=>{let{transmuxedData:transmuxedData,callback:callback}=_ref47;transmuxedData.buffer=[],callback(transmuxedData)})({transmuxedData:transmuxedData,callback:onDone}),dequeue(transmuxer))))},audioAppendStart&&transmuxer.postMessage({action:"setAudioAppendStart",appendStart:audioAppendStart}),Array.isArray(gopsToAlignWith)&&transmuxer.postMessage({action:"alignGopsWith",gopsToAlignWith:gopsToAlignWith}),void 0!==remux&&transmuxer.postMessage({action:"setRemux",remux:remux}),bytes.byteLength){const buffer=bytes instanceof ArrayBuffer?bytes:bytes.buffer,byteOffset=bytes instanceof ArrayBuffer?0:bytes.byteOffset;transmuxer.postMessage({action:"push",data:buffer,byteOffset:byteOffset,byteLength:bytes.byteLength},[buffer])}isEndOfTimeline&&transmuxer.postMessage({action:"endTimeline"}),transmuxer.postMessage({action:"flush"})},dequeue=transmuxer=>{transmuxer.currentTransmux=null,transmuxer.transmuxQueue.length&&(transmuxer.currentTransmux=transmuxer.transmuxQueue.shift(),"function"==typeof transmuxer.currentTransmux?transmuxer.currentTransmux():processTransmux(transmuxer.currentTransmux))},processAction=(transmuxer,action)=>{transmuxer.postMessage({action:action}),dequeue(transmuxer)},enqueueAction=(action,transmuxer)=>{if(!transmuxer.currentTransmux)return transmuxer.currentTransmux=action,void processAction(transmuxer,action);transmuxer.transmuxQueue.push(processAction.bind(null,transmuxer,action))},transmux=options=>{if(!options.transmuxer.currentTransmux)return options.transmuxer.currentTransmux=options,void processTransmux(options);options.transmuxer.transmuxQueue.push(options)};var segmentTransmuxer_reset=transmuxer=>{enqueueAction("reset",transmuxer)},segmentTransmuxer_createTransmuxer=options=>{const transmuxer=new TransmuxWorker;transmuxer.currentTransmux=null,transmuxer.transmuxQueue=[];const term=transmuxer.terminate;return transmuxer.terminate=()=>(transmuxer.currentTransmux=null,transmuxer.transmuxQueue.length=0,term.call(transmuxer)),transmuxer.postMessage({action:"init",options:options}),transmuxer};const workerCallback=function(options){const transmuxer=options.transmuxer,endAction=options.endAction||options.action,callback=options.callback,message=_extends$1({},options,{endAction:null,transmuxer:null,callback:null}),listenForEndEvent=event=>{event.data.action===endAction&&(transmuxer.removeEventListener("message",listenForEndEvent),event.data.data&&(event.data.data=new Uint8Array(event.data.data,options.byteOffset||0,options.byteLength||event.data.data.byteLength),options.data&&(options.data=event.data.data)),callback(event.data))};if(transmuxer.addEventListener("message",listenForEndEvent),options.data){const isArrayBuffer=options.data instanceof ArrayBuffer;message.byteOffset=isArrayBuffer?0:options.data.byteOffset,message.byteLength=options.data.byteLength;const transfers=[isArrayBuffer?options.data:options.data.buffer];transmuxer.postMessage(message,transfers)}else transmuxer.postMessage(message)},REQUEST_ERRORS_FAILURE=2,REQUEST_ERRORS_TIMEOUT=-101,REQUEST_ERRORS_ABORTED=-102,abortAll=activeXhrs=>{activeXhrs.forEach((xhr=>{xhr.abort()}))},handleErrors=(error,request)=>request.timedout?{status:request.status,message:"HLS request timed-out at URL: "+request.uri,code:REQUEST_ERRORS_TIMEOUT,xhr:request}:request.aborted?{status:request.status,message:"HLS request aborted at URL: "+request.uri,code:REQUEST_ERRORS_ABORTED,xhr:request}:error?{status:request.status,message:"HLS request errored at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request}:"arraybuffer"===request.responseType&&0===request.response.byteLength?{status:request.status,message:"Empty HLS response at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request}:null,handleKeyResponse=(segment,objects,finishProcessingFn)=>(error,request)=>{const response=request.response,errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);if(16!==response.byteLength)return finishProcessingFn({status:request.status,message:"Invalid HLS key at URL: "+request.uri,code:REQUEST_ERRORS_FAILURE,xhr:request},segment);const view=new DataView(response),bytes=new Uint32Array([view.getUint32(0),view.getUint32(4),view.getUint32(8),view.getUint32(12)]);for(let i=0;i{const type=detectContainerForBytes(segment.map.bytes);if("mp4"!==type){const uri=segment.map.resolvedUri||segment.map.uri;return callback({internal:!0,message:"Found unsupported ".concat(type||"unknown"," container for initialization segment at URL: ").concat(uri),code:REQUEST_ERRORS_FAILURE})}workerCallback({action:"probeMp4Tracks",data:segment.map.bytes,transmuxer:segment.transmuxer,callback:_ref48=>{let{tracks:tracks,data:data}=_ref48;return segment.map.bytes=data,tracks.forEach((function(track){segment.map.tracks=segment.map.tracks||{},segment.map.tracks[track.type]||(segment.map.tracks[track.type]=track,"number"==typeof track.id&&track.timescale&&(segment.map.timescales=segment.map.timescales||{},segment.map.timescales[track.id]=track.timescale))})),callback(null)}})},handleSegmentResponse=_ref50=>{let{segment:segment,finishProcessingFn:finishProcessingFn,responseType:responseType}=_ref50;return(error,request)=>{const errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);const newBytes="arraybuffer"!==responseType&&request.responseText?(string=>{const view=new Uint8Array(new ArrayBuffer(string.length));for(let i=0;i({bandwidth:request.bandwidth,bytesReceived:request.bytesReceived||0,roundTripTime:request.roundTripTime||0}))(request),segment.key?segment.encryptedBytes=new Uint8Array(newBytes):segment.bytes=new Uint8Array(newBytes),finishProcessingFn(null,segment)}},transmuxAndNotify=_ref51=>{let{segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref51;const fmp4Tracks=segment.map&&segment.map.tracks||{},isMuxed=Boolean(fmp4Tracks.audio&&fmp4Tracks.video);let audioStartFn=timingInfoFn.bind(null,segment,"audio","start");const audioEndFn=timingInfoFn.bind(null,segment,"audio","end");let videoStartFn=timingInfoFn.bind(null,segment,"video","start");const videoEndFn=timingInfoFn.bind(null,segment,"video","end");workerCallback({action:"probeTs",transmuxer:segment.transmuxer,data:bytes,baseStartTime:segment.baseStartTime,callback:data=>{segment.bytes=bytes=data.data;const probeResult=data.result;probeResult&&(trackInfoFn(segment,{hasAudio:probeResult.hasAudio,hasVideo:probeResult.hasVideo,isMuxed:isMuxed}),trackInfoFn=null),transmux({bytes:bytes,transmuxer:segment.transmuxer,audioAppendStart:segment.audioAppendStart,gopsToAlignWith:segment.gopsToAlignWith,remux:isMuxed,onData:result=>{result.type="combined"===result.type?"video":result.type,dataFn(segment,result)},onTrackInfo:trackInfo=>{trackInfoFn&&(isMuxed&&(trackInfo.isMuxed=!0),trackInfoFn(segment,trackInfo))},onAudioTimingInfo:audioTimingInfo=>{audioStartFn&&void 0!==audioTimingInfo.start&&(audioStartFn(audioTimingInfo.start),audioStartFn=null),audioEndFn&&void 0!==audioTimingInfo.end&&audioEndFn(audioTimingInfo.end)},onVideoTimingInfo:videoTimingInfo=>{videoStartFn&&void 0!==videoTimingInfo.start&&(videoStartFn(videoTimingInfo.start),videoStartFn=null),videoEndFn&&void 0!==videoTimingInfo.end&&videoEndFn(videoTimingInfo.end)},onVideoSegmentTimingInfo:videoSegmentTimingInfo=>{videoSegmentTimingInfoFn(videoSegmentTimingInfo)},onAudioSegmentTimingInfo:audioSegmentTimingInfo=>{audioSegmentTimingInfoFn(audioSegmentTimingInfo)},onId3:(id3Frames,dispatchType)=>{id3Fn(segment,id3Frames,dispatchType)},onCaptions:captions=>{captionsFn(segment,[captions])},isEndOfTimeline:isEndOfTimeline,onEndedTimeline:()=>{endedTimelineFn()},onTransmuxerLog:onTransmuxerLog,onDone:result=>{doneFn&&(result.type="combined"===result.type?"video":result.type,doneFn(null,segment,result))}})}})},handleSegmentBytes=_ref52=>{let{segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref52,bytesAsUint8Array=new Uint8Array(bytes);if(function(bytes){return findBox(bytes,["moof"]).length>0}(bytesAsUint8Array)){segment.isFmp4=!0;const{tracks:tracks}=segment.map,trackInfo={isFmp4:!0,hasVideo:!!tracks.video,hasAudio:!!tracks.audio};tracks.audio&&tracks.audio.codec&&"enca"!==tracks.audio.codec&&(trackInfo.audioCodec=tracks.audio.codec),tracks.video&&tracks.video.codec&&"encv"!==tracks.video.codec&&(trackInfo.videoCodec=tracks.video.codec),tracks.video&&tracks.audio&&(trackInfo.isMuxed=!0),trackInfoFn(segment,trackInfo);const finishLoading=(captions,id3Frames)=>{dataFn(segment,{data:bytesAsUint8Array,type:trackInfo.hasAudio&&!trackInfo.isMuxed?"audio":"video"}),id3Frames&&id3Frames.length&&id3Fn(segment,id3Frames),captions&&captions.length&&captionsFn(segment,captions),doneFn(null,segment,{})};workerCallback({action:"probeMp4StartTime",timescales:segment.map.timescales,data:bytesAsUint8Array,transmuxer:segment.transmuxer,callback:_ref53=>{let{data:data,startTime:startTime}=_ref53;bytes=data.buffer,segment.bytes=bytesAsUint8Array=data,trackInfo.hasAudio&&!trackInfo.isMuxed&&timingInfoFn(segment,"audio","start",startTime),trackInfo.hasVideo&&timingInfoFn(segment,"video","start",startTime),workerCallback({action:"probeEmsgID3",data:bytesAsUint8Array,transmuxer:segment.transmuxer,offset:startTime,callback:_ref54=>{let{emsgData:emsgData,id3Frames:id3Frames}=_ref54;bytes=emsgData.buffer,segment.bytes=bytesAsUint8Array=emsgData,tracks.video&&emsgData.byteLength&&segment.transmuxer?workerCallback({action:"pushMp4Captions",endAction:"mp4Captions",transmuxer:segment.transmuxer,data:bytesAsUint8Array,timescales:segment.map.timescales,trackIds:[tracks.video.id],callback:message=>{bytes=message.data.buffer,segment.bytes=bytesAsUint8Array=message.data,message.logs.forEach((function(log){onTransmuxerLog(merge(log,{stream:"mp4CaptionParser"}))})),finishLoading(message.captions,id3Frames)}}):finishLoading(void 0,id3Frames)}})}})}else if(segment.transmuxer){if(void 0===segment.container&&(segment.container=detectContainerForBytes(bytesAsUint8Array)),"ts"!==segment.container&&"aac"!==segment.container)return trackInfoFn(segment,{hasAudio:!1,hasVideo:!1}),void doneFn(null,segment,{});transmuxAndNotify({segment:segment,bytes:bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})}else doneFn(null,segment,{})},decrypt=function(_ref55,callback){let{id:id,key:key,encryptedBytes:encryptedBytes,decryptionWorker:decryptionWorker}=_ref55;const decryptionHandler=event=>{if(event.data.source===id){decryptionWorker.removeEventListener("message",decryptionHandler);const decrypted=event.data.decrypted;callback(new Uint8Array(decrypted.bytes,decrypted.byteOffset,decrypted.byteLength))}};let keyBytes;decryptionWorker.addEventListener("message",decryptionHandler),keyBytes=key.bytes.slice?key.bytes.slice():new Uint32Array(Array.prototype.slice.call(key.bytes)),decryptionWorker.postMessage(createTransferableMessage({source:id,encrypted:encryptedBytes,key:keyBytes,iv:key.iv}),[encryptedBytes.buffer,keyBytes.buffer])},waitForCompletion=_ref57=>{let{activeXhrs:activeXhrs,decryptionWorker:decryptionWorker,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref57,count=0,didError=!1;return(error,segment)=>{if(!didError){if(error)return didError=!0,abortAll(activeXhrs),doneFn(error,segment);if(count+=1,count===activeXhrs.length){const segmentFinish=function(){if(segment.encryptedBytes)return(_ref56=>{let{decryptionWorker:decryptionWorker,segment:segment,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref56;decrypt({id:segment.requestId,key:segment.key,encryptedBytes:segment.encryptedBytes,decryptionWorker:decryptionWorker},(decryptedBytes=>{segment.bytes=decryptedBytes,handleSegmentBytes({segment:segment,bytes:segment.bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})}))})({decryptionWorker:decryptionWorker,segment:segment,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog});handleSegmentBytes({segment:segment,bytes:segment.bytes,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog})};if(segment.endOfAllRequests=Date.now(),segment.map&&segment.map.encryptedBytes&&!segment.map.bytes)return decrypt({decryptionWorker:decryptionWorker,id:segment.requestId+"-init",encryptedBytes:segment.map.encryptedBytes,key:segment.map.key},(decryptedBytes=>{segment.map.bytes=decryptedBytes,parseInitSegment(segment,(parseError=>{if(parseError)return abortAll(activeXhrs),doneFn(parseError,segment);segmentFinish()}))}));segmentFinish()}}}},handleProgress=_ref59=>{let{segment:segment,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn}=_ref59;return event=>{if(!event.target.aborted)return segment.stats=merge(segment.stats,(progressEvent=>{const request=progressEvent.target,stats={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-request.requestTime||0};return stats.bytesReceived=progressEvent.loaded,stats.bandwidth=Math.floor(stats.bytesReceived/stats.roundTripTime*8*1e3),stats})(event)),!segment.stats.firstBytesReceivedAt&&segment.stats.bytesReceived&&(segment.stats.firstBytesReceivedAt=Date.now()),progressFn(event,segment)}},mediaSegmentRequest=_ref60=>{let{xhr:xhr,xhrOptions:xhrOptions,decryptionWorker:decryptionWorker,segment:segment,abortFn:abortFn,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog}=_ref60;const activeXhrs=[],finishProcessingFn=waitForCompletion({activeXhrs:activeXhrs,decryptionWorker:decryptionWorker,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn,doneFn:doneFn,onTransmuxerLog:onTransmuxerLog});if(segment.key&&!segment.key.bytes){const objects=[segment.key];segment.map&&!segment.map.bytes&&segment.map.key&&segment.map.key.resolvedUri===segment.key.resolvedUri&&objects.push(segment.map.key);const keyXhr=xhr(merge(xhrOptions,{uri:segment.key.resolvedUri,responseType:"arraybuffer"}),handleKeyResponse(segment,objects,finishProcessingFn));activeXhrs.push(keyXhr)}if(segment.map&&!segment.map.bytes){if(segment.map.key&&(!segment.key||segment.key.resolvedUri!==segment.map.key.resolvedUri)){const mapKeyXhr=xhr(merge(xhrOptions,{uri:segment.map.key.resolvedUri,responseType:"arraybuffer"}),handleKeyResponse(segment,[segment.map.key],finishProcessingFn));activeXhrs.push(mapKeyXhr)}const initSegmentOptions=merge(xhrOptions,{uri:segment.map.resolvedUri,responseType:"arraybuffer",headers:segmentXhrHeaders(segment.map)}),initSegmentRequestCallback=(_ref49=>{let{segment:segment,finishProcessingFn:finishProcessingFn}=_ref49;return(error,request)=>{const errorObj=handleErrors(error,request);if(errorObj)return finishProcessingFn(errorObj,segment);const bytes=new Uint8Array(request.response);if(segment.map.key)return segment.map.encryptedBytes=bytes,finishProcessingFn(null,segment);segment.map.bytes=bytes,parseInitSegment(segment,(function(parseError){if(parseError)return parseError.xhr=request,parseError.status=request.status,finishProcessingFn(parseError,segment);finishProcessingFn(null,segment)}))}})({segment:segment,finishProcessingFn:finishProcessingFn}),initSegmentXhr=xhr(initSegmentOptions,initSegmentRequestCallback);activeXhrs.push(initSegmentXhr)}const segmentRequestOptions=merge(xhrOptions,{uri:segment.part&&segment.part.resolvedUri||segment.resolvedUri,responseType:"arraybuffer",headers:segmentXhrHeaders(segment)}),segmentXhr=xhr(segmentRequestOptions,handleSegmentResponse({segment:segment,finishProcessingFn:finishProcessingFn,responseType:segmentRequestOptions.responseType}));segmentXhr.addEventListener("progress",handleProgress({segment:segment,progressFn:progressFn,trackInfoFn:trackInfoFn,timingInfoFn:timingInfoFn,videoSegmentTimingInfoFn:videoSegmentTimingInfoFn,audioSegmentTimingInfoFn:audioSegmentTimingInfoFn,id3Fn:id3Fn,captionsFn:captionsFn,isEndOfTimeline:isEndOfTimeline,endedTimelineFn:endedTimelineFn,dataFn:dataFn})),activeXhrs.push(segmentXhr);const loadendState={};return activeXhrs.forEach((activeXhr=>{activeXhr.addEventListener("loadend",(_ref58=>{let{loadendState:loadendState,abortFn:abortFn}=_ref58;return event=>{event.target.aborted&&abortFn&&!loadendState.calledAbortFn&&(abortFn(),loadendState.calledAbortFn=!0)}})({loadendState:loadendState,abortFn:abortFn}))})),()=>abortAll(activeXhrs)},logFn$1=logger("CodecUtils"),isMaat=(main,media)=>{const mediaAttributes=media.attributes||{};return main&&main.mediaGroups&&main.mediaGroups.AUDIO&&mediaAttributes.AUDIO&&main.mediaGroups.AUDIO[mediaAttributes.AUDIO]},unwrapCodecList=function(codecList){const codecs={};return codecList.forEach((_ref61=>{let{mediaType:mediaType,type:type,details:details}=_ref61;codecs[mediaType]=codecs[mediaType]||[],codecs[mediaType].push(translateLegacyCodec("".concat(type).concat(details)))})),Object.keys(codecs).forEach((function(mediaType){if(codecs[mediaType].length>1)return logFn$1("multiple ".concat(mediaType," codecs found as attributes: ").concat(codecs[mediaType].join(", "),". Setting playlist codecs to null so that we wait for mux.js to probe segments for real codecs.")),void(codecs[mediaType]=null);codecs[mediaType]=codecs[mediaType][0]})),codecs},codecCount=function(codecObj){let count=0;return codecObj.audio&&count++,codecObj.video&&count++,count},codecsForPlaylist=function(main,media){const mediaAttributes=media.attributes||{},codecInfo=unwrapCodecList(function(media){const mediaAttributes=media.attributes||{};if(mediaAttributes.CODECS)return parseCodecs(mediaAttributes.CODECS)}(media)||[]);if(isMaat(main,media)&&!codecInfo.audio&&!((main,media)=>{if(!isMaat(main,media))return!0;const mediaAttributes=media.attributes||{},audioGroup=main.mediaGroups.AUDIO[mediaAttributes.AUDIO];for(const groupId in audioGroup)if(!audioGroup[groupId].uri&&!audioGroup[groupId].playlists)return!0;return!1})(main,media)){const defaultCodecs=unwrapCodecList(function(master,audioGroupId){if(!master.mediaGroups.AUDIO||!audioGroupId)return null;var audioGroup=master.mediaGroups.AUDIO[audioGroupId];if(!audioGroup)return null;for(var name in audioGroup){var audioType=audioGroup[name];if(audioType.default&&audioType.playlists)return parseCodecs(audioType.playlists[0].attributes.CODECS)}return null}(main,mediaAttributes.AUDIO)||[]);defaultCodecs.audio&&(codecInfo.audio=defaultCodecs.audio)}return codecInfo},logFn=logger("PlaylistSelector"),representationToString=function(representation){if(!representation||!representation.playlist)return;const playlist=representation.playlist;return JSON.stringify({id:playlist.id,bandwidth:representation.bandwidth,width:representation.width,height:representation.height,codecs:playlist.attributes&&playlist.attributes.CODECS||""})},safeGetComputedStyle=function(el,property){if(!el)return"";const result=window.getComputedStyle(el);return result?result[property]:""},stableSort=function(array,sortFn){const newArray=array.slice();array.sort((function(left,right){const cmp=sortFn(left,right);return 0===cmp?newArray.indexOf(left)-newArray.indexOf(right):cmp}))},comparePlaylistBandwidth=function(left,right){let leftBandwidth,rightBandwidth;return left.attributes.BANDWIDTH&&(leftBandwidth=left.attributes.BANDWIDTH),leftBandwidth=leftBandwidth||window.Number.MAX_VALUE,right.attributes.BANDWIDTH&&(rightBandwidth=right.attributes.BANDWIDTH),rightBandwidth=rightBandwidth||window.Number.MAX_VALUE,leftBandwidth-rightBandwidth};let simpleSelector=function(main,playerBandwidth,playerWidth,playerHeight,limitRenditionByPlayerDimensions,playlistController){if(!main)return;const options={bandwidth:playerBandwidth,width:playerWidth,height:playerHeight,limitRenditionByPlayerDimensions:limitRenditionByPlayerDimensions};let playlists=main.playlists;Playlist.isAudioOnly(main)&&(playlists=playlistController.getAudioTrackPlaylists_(),options.audioOnly=!0);let sortedPlaylistReps=playlists.map((playlist=>{let bandwidth;const width=playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.width,height=playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.height;return bandwidth=playlist.attributes&&playlist.attributes.BANDWIDTH,bandwidth=bandwidth||window.Number.MAX_VALUE,{bandwidth:bandwidth,width:width,height:height,playlist:playlist}}));stableSort(sortedPlaylistReps,((left,right)=>left.bandwidth-right.bandwidth)),sortedPlaylistReps=sortedPlaylistReps.filter((rep=>!Playlist.isIncompatible(rep.playlist)));let enabledPlaylistReps=sortedPlaylistReps.filter((rep=>Playlist.isEnabled(rep.playlist)));enabledPlaylistReps.length||(enabledPlaylistReps=sortedPlaylistReps.filter((rep=>!Playlist.isDisabled(rep.playlist))));const bandwidthPlaylistReps=enabledPlaylistReps.filter((rep=>rep.bandwidth*Config.BANDWIDTH_VARIANCErep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0];if(!1===limitRenditionByPlayerDimensions){const chosenRep=bandwidthBestRep||enabledPlaylistReps[0]||sortedPlaylistReps[0];if(chosenRep&&chosenRep.playlist){let type="sortedPlaylistReps";return bandwidthBestRep&&(type="bandwidthBestRep"),enabledPlaylistReps[0]&&(type="enabledPlaylistReps"),logFn("choosing ".concat(representationToString(chosenRep)," using ").concat(type," with options"),options),chosenRep.playlist}return logFn("could not choose a playlist with options",options),null}const haveResolution=bandwidthPlaylistReps.filter((rep=>rep.width&&rep.height));stableSort(haveResolution,((left,right)=>left.width-right.width));const resolutionBestRepList=haveResolution.filter((rep=>rep.width===playerWidth&&rep.height===playerHeight));highestRemainingBandwidthRep=resolutionBestRepList[resolutionBestRepList.length-1];const resolutionBestRep=resolutionBestRepList.filter((rep=>rep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0];let resolutionPlusOneList,resolutionPlusOneSmallest,resolutionPlusOneRep,leastPixelDiffRep;if(resolutionBestRep||(resolutionPlusOneList=haveResolution.filter((rep=>rep.width>playerWidth||rep.height>playerHeight)),resolutionPlusOneSmallest=resolutionPlusOneList.filter((rep=>rep.width===resolutionPlusOneList[0].width&&rep.height===resolutionPlusOneList[0].height)),highestRemainingBandwidthRep=resolutionPlusOneSmallest[resolutionPlusOneSmallest.length-1],resolutionPlusOneRep=resolutionPlusOneSmallest.filter((rep=>rep.bandwidth===highestRemainingBandwidthRep.bandwidth))[0]),playlistController.leastPixelDiffSelector){const leastPixelDiffList=haveResolution.map((rep=>(rep.pixelDiff=Math.abs(rep.width-playerWidth)+Math.abs(rep.height-playerHeight),rep)));stableSort(leastPixelDiffList,((left,right)=>left.pixelDiff===right.pixelDiff?right.bandwidth-left.bandwidth:left.pixelDiff-right.pixelDiff)),leastPixelDiffRep=leastPixelDiffList[0]}const chosenRep=leastPixelDiffRep||resolutionPlusOneRep||resolutionBestRep||bandwidthBestRep||enabledPlaylistReps[0]||sortedPlaylistReps[0];if(chosenRep&&chosenRep.playlist){let type="sortedPlaylistReps";return leastPixelDiffRep?type="leastPixelDiffRep":resolutionPlusOneRep?type="resolutionPlusOneRep":resolutionBestRep?type="resolutionBestRep":bandwidthBestRep?type="bandwidthBestRep":enabledPlaylistReps[0]&&(type="enabledPlaylistReps"),logFn("choosing ".concat(representationToString(chosenRep)," using ").concat(type," with options"),options),chosenRep.playlist}return logFn("could not choose a playlist with options",options),null};const lastBandwidthSelector=function(){const pixelRatio=this.useDevicePixelRatio&&window.devicePixelRatio||1;return simpleSelector(this.playlists.main,this.systemBandwidth,parseInt(safeGetComputedStyle(this.tech_.el(),"width"),10)*pixelRatio,parseInt(safeGetComputedStyle(this.tech_.el(),"height"),10)*pixelRatio,this.limitRenditionByPlayerDimensions,this.playlistController_)},addMetadata=_ref63=>{let{inbandTextTracks:inbandTextTracks,metadataArray:metadataArray,timestampOffset:timestampOffset,videoDuration:videoDuration}=_ref63;if(!metadataArray)return;const Cue=window.WebKitDataCue||window.VTTCue,metadataTrack=inbandTextTracks.metadataTrack_;if(!metadataTrack)return;if(metadataArray.forEach((metadata=>{const time=metadata.cueTime+timestampOffset;!("number"!=typeof time||window.isNaN(time)||time<0)&&time<1/0&&metadata.frames&&metadata.frames.length&&metadata.frames.forEach((frame=>{const cue=new Cue(time,time,frame.value||frame.url||frame.data||"");cue.frame=frame,cue.value=frame,function(cue){Object.defineProperties(cue.frame,{id:{get:()=>(videojs.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),cue.value.key)},value:{get:()=>(videojs.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),cue.value.data)},privateData:{get:()=>(videojs.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),cue.value.data)}})}(cue),metadataTrack.addCue(cue)}))})),!metadataTrack.cues||!metadataTrack.cues.length)return;const cues=metadataTrack.cues,cuesArray=[];for(let i=0;i{const timeSlot=obj[cue.startTime]||[];return timeSlot.push(cue),obj[cue.startTime]=timeSlot,obj}),{}),sortedStartTimes=Object.keys(cuesGroupedByStartTime).sort(((a,b)=>Number(a)-Number(b)));sortedStartTimes.forEach(((startTime,idx)=>{const cueGroup=cuesGroupedByStartTime[startTime],finiteDuration=isFinite(videoDuration)?videoDuration:startTime,nextTime=Number(sortedStartTimes[idx+1])||finiteDuration;cueGroup.forEach((cue=>{cue.endTime=nextTime}))}))},dateRangeAttr={id:"ID",class:"CLASS",startDate:"START-DATE",duration:"DURATION",endDate:"END-DATE",endOnNext:"END-ON-NEXT",plannedDuration:"PLANNED-DURATION",scte35Out:"SCTE35-OUT",scte35In:"SCTE35-IN"},dateRangeKeysToOmit=new Set(["id","class","startDate","duration","endDate","endOnNext","startTime","endTime","processDateRange"]),createMetadataTrackIfNotExists=(inbandTextTracks,dispatchType,tech)=>{inbandTextTracks.metadataTrack_||(inbandTextTracks.metadataTrack_=tech.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,videojs.browser.IS_ANY_SAFARI||(inbandTextTracks.metadataTrack_.inBandMetadataTrackDispatchType=dispatchType))},removeCuesFromTrack=function(start,end,track){let i,cue;if(track&&track.cues)for(i=track.cues.length;i--;)cue=track.cues[i],cue.startTime>=start&&cue.endTime<=end&&track.removeCue(cue)},finite=num=>"number"==typeof num&&isFinite(num),segmentInfoString=segmentInfo=>{const{startOfSegment:startOfSegment,duration:duration,segment:segment,part:part,playlist:{mediaSequence:seq,id:id,segments:segments=[]},mediaIndex:index,partIndex:partIndex,timeline:timeline}=segmentInfo,segmentLen=segments.length-1;let selection="mediaIndex/partIndex increment";segmentInfo.getMediaInfoForTime?selection="getMediaInfoForTime (".concat(segmentInfo.getMediaInfoForTime,")"):segmentInfo.isSyncRequest&&(selection="getSyncSegmentCandidate (isSyncRequest)"),segmentInfo.independent&&(selection+=" with independent ".concat(segmentInfo.independent));const hasPartIndex="number"==typeof partIndex,name=segmentInfo.segment.uri?"segment":"pre-segment",zeroBasedPartCount=hasPartIndex?getKnownPartCount({preloadSegment:segment})-1:0;return"".concat(name," [").concat(seq+index,"/").concat(seq+segmentLen,"]")+(hasPartIndex?" part [".concat(partIndex,"/").concat(zeroBasedPartCount,"]"):"")+" segment start/end [".concat(segment.start," => ").concat(segment.end,"]")+(hasPartIndex?" part start/end [".concat(part.start," => ").concat(part.end,"]"):"")+" startOfSegment [".concat(startOfSegment,"]")+" duration [".concat(duration,"]")+" timeline [".concat(timeline,"]")+" selected by [".concat(selection,"]")+" playlist [".concat(id,"]")},timingInfoPropertyForMedia=mediaType=>"".concat(mediaType,"TimingInfo"),shouldWaitForTimelineChange=_ref66=>{let{timelineChangeController:timelineChangeController,currentTimeline:currentTimeline,segmentTimeline:segmentTimeline,loaderType:loaderType,audioDisabled:audioDisabled}=_ref66;if(currentTimeline===segmentTimeline)return!1;if("audio"===loaderType){const lastMainTimelineChange=timelineChangeController.lastTimelineChange({type:"main"});return!lastMainTimelineChange||lastMainTimelineChange.to!==segmentTimeline}if("main"===loaderType&&audioDisabled){const pendingAudioTimelineChange=timelineChangeController.pendingTimelineChange({type:"audio"});return!pendingAudioTimelineChange||pendingAudioTimelineChange.to!==segmentTimeline}return!1},segmentTooLong=_ref67=>{let{segmentDuration:segmentDuration,maxDuration:maxDuration}=_ref67;return!!segmentDuration&&Math.round(segmentDuration)>maxDuration+.03333333333333333},getTroublesomeSegmentDurationMessage=(segmentInfo,sourceType)=>{if("hls"!==sourceType)return null;const segmentDuration=(timingInfos=>{let maxDuration=0;return["video","audio"].forEach((function(type){const typeTimingInfo=timingInfos["".concat(type,"TimingInfo")];if(!typeTimingInfo)return;const{start:start,end:end}=typeTimingInfo;let duration;"bigint"==typeof start||"bigint"==typeof end?duration=window.BigInt(end)-window.BigInt(start):"number"==typeof start&&"number"==typeof end&&(duration=end-start),void 0!==duration&&duration>maxDuration&&(maxDuration=duration)})),"bigint"==typeof maxDuration&&maxDurationthis.trigger("syncinfoupdate"),this.syncController_.on("syncinfoupdate",this.triggerSyncInfoUpdate_),this.mediaSource_.addEventListener("sourceopen",(()=>{this.isEndOfStream_()||(this.ended_=!1)})),this.fetchAtBuffer_=!1,this.logger_=logger("SegmentLoader[".concat(this.loaderType_,"]")),Object.defineProperty(this,"state",{get(){return this.state_},set(newState){newState!==this.state_&&(this.logger_("".concat(this.state_," -> ").concat(newState)),this.state_=newState,this.trigger("statechange"))}}),this.sourceUpdater_.on("ready",(()=>{this.hasEnoughInfoToAppend_()&&this.processCallQueue_()})),"main"===this.loaderType_&&this.timelineChangeController_.on("pendingtimelinechange",(()=>{this.hasEnoughInfoToAppend_()&&this.processCallQueue_()})),"audio"===this.loaderType_&&this.timelineChangeController_.on("timelinechange",(()=>{this.hasEnoughInfoToLoad_()&&this.processLoadQueue_(),this.hasEnoughInfoToAppend_()&&this.processCallQueue_()}))}createTransmuxer_(){return segmentTransmuxer_createTransmuxer({remux:!1,alignGopsAtEnd:this.safeAppend_,keepOriginalTimestamps:!0,parse708captions:this.parse708captions_,captionServices:this.captionServices_})}resetStats_(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0,this.mediaAppends=0}dispose(){this.trigger("dispose"),this.state="DISPOSED",this.pause(),this.abort_(),this.transmuxer_&&this.transmuxer_.terminate(),this.resetStats_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.syncController_&&this.triggerSyncInfoUpdate_&&this.syncController_.off("syncinfoupdate",this.triggerSyncInfoUpdate_),this.off()}setAudio(enable){this.audioDisabled_=!enable,enable?this.appendInitSegment_.audio=!0:this.sourceUpdater_.removeAudio(0,this.duration_())}abort(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)}abort_(){this.pendingSegment_&&this.pendingSegment_.abortRequests&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.timelineChangeController_.clearPendingTimelineChange(this.loaderType_),this.waitingOnRemove_=!1,window.clearTimeout(this.quotaExceededErrorRetryTimeout_),this.quotaExceededErrorRetryTimeout_=null}checkForAbort_(requestId){return"APPENDING"!==this.state||this.pendingSegment_?!this.pendingSegment_||this.pendingSegment_.requestId!==requestId:(this.state="READY",!0)}error(error){return void 0!==error&&(this.logger_("error occurred:",error),this.error_=error),this.pendingSegment_=null,this.error_}endOfStream(){this.ended_=!0,this.transmuxer_&&segmentTransmuxer_reset(this.transmuxer_),this.gopBuffer_.length=0,this.pause(),this.trigger("ended")}buffered_(){const trackInfo=this.getMediaInfo_();if(!this.sourceUpdater_||!trackInfo)return createTimeRanges();if("main"===this.loaderType_){const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo;if(hasVideo&&hasAudio&&!this.audioDisabled_&&!isMuxed)return this.sourceUpdater_.buffered();if(hasVideo)return this.sourceUpdater_.videoBuffered()}return this.sourceUpdater_.audioBuffered()}initSegmentForMap(map){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!map)return null;const id=initSegmentId(map);let storedMap=this.initSegments_[id];return set&&!storedMap&&map.bytes&&(this.initSegments_[id]=storedMap={resolvedUri:map.resolvedUri,byterange:map.byterange,bytes:map.bytes,tracks:map.tracks,timescales:map.timescales}),storedMap||map}segmentKey(key){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!key)return null;const id=segmentKeyId(key);let storedKey=this.keyCache_[id];this.cacheEncryptionKeys_&&set&&!storedKey&&key.bytes&&(this.keyCache_[id]=storedKey={resolvedUri:key.resolvedUri,bytes:key.bytes});const result={resolvedUri:(storedKey||key).resolvedUri};return storedKey&&(result.bytes=storedKey.bytes),result}couldBeginLoading_(){return this.playlist_&&!this.paused()}load(){if(this.monitorBuffer_(),this.playlist_)return"INIT"===this.state&&this.couldBeginLoading_()?this.init_():void(!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY"))}init_(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}playlist(newPlaylist){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!newPlaylist)return;const oldPlaylist=this.playlist_,segmentInfo=this.pendingSegment_;this.playlist_=newPlaylist,this.xhrOptions_=options,"INIT"===this.state&&(newPlaylist.syncInfo={mediaSequence:newPlaylist.mediaSequence,time:0},"main"===this.loaderType_&&this.syncController_.setDateTimeMappingForStart(newPlaylist));let oldId=null;if(oldPlaylist&&(oldPlaylist.id?oldId=oldPlaylist.id:oldPlaylist.uri&&(oldId=oldPlaylist.uri)),this.logger_("playlist update [".concat(oldId," => ").concat(newPlaylist.id||newPlaylist.uri,"]")),this.syncController_.updateMediaSequenceMap(newPlaylist,this.currentTime_(),this.loaderType_),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!oldPlaylist||oldPlaylist.uri!==newPlaylist.uri){if(null!==this.mediaIndex){!newPlaylist.endList&&"number"==typeof newPlaylist.partTargetDuration?this.resetLoader():this.resyncLoader()}return this.currentMediaInfo_=void 0,void this.trigger("playlistupdate")}const mediaSequenceDiff=newPlaylist.mediaSequence-oldPlaylist.mediaSequence;if(this.logger_("live window shift [".concat(mediaSequenceDiff,"]")),null!==this.mediaIndex)if(this.mediaIndex-=mediaSequenceDiff,this.mediaIndex<0)this.mediaIndex=null,this.partIndex=null;else{const segment=this.playlist_.segments[this.mediaIndex];if(this.partIndex&&(!segment.parts||!segment.parts.length||!segment.parts[this.partIndex])){const mediaIndex=this.mediaIndex;this.logger_("currently processing part (index ".concat(this.partIndex,") no longer exists.")),this.resetLoader(),this.mediaIndex=mediaIndex}}segmentInfo&&(segmentInfo.mediaIndex-=mediaSequenceDiff,segmentInfo.mediaIndex<0?(segmentInfo.mediaIndex=null,segmentInfo.partIndex=null):(segmentInfo.mediaIndex>=0&&(segmentInfo.segment=newPlaylist.segments[segmentInfo.mediaIndex]),segmentInfo.partIndex>=0&&segmentInfo.segment.parts&&(segmentInfo.part=segmentInfo.segment.parts[segmentInfo.partIndex]))),this.syncController_.saveExpiredSegmentInfo(oldPlaylist,newPlaylist)}pause(){this.checkBufferTimeout_&&(window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)}paused(){return null===this.checkBufferTimeout_}resetEverything(done){this.ended_=!1,this.activeInitSegmentId_=null,this.appendInitSegment_={audio:!0,video:!0},this.resetLoader(),this.remove(0,1/0,done),this.transmuxer_&&(this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.transmuxer_.postMessage({action:"reset"}))}resetLoader(){this.fetchAtBuffer_=!1,this.resyncLoader()}resyncLoader(){this.transmuxer_&&segmentTransmuxer_reset(this.transmuxer_),this.mediaIndex=null,this.partIndex=null,this.syncPoint_=null,this.isPendingTimestampOffset_=!1,this.shouldForceTimestampOffsetAfterResync_=!0,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})}remove(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>{},force=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(end===1/0&&(end=this.duration_()),end<=start)return void this.logger_("skipping remove because end ${end} is <= start ${start}");if(!this.sourceUpdater_||!this.getMediaInfo_())return void this.logger_("skipping remove because no source updater or starting media info");let removesRemaining=1;const removeFinished=()=>{removesRemaining--,0===removesRemaining&&done()};!force&&this.audioDisabled_||(removesRemaining++,this.sourceUpdater_.removeAudio(start,end,removeFinished)),(force||"main"===this.loaderType_)&&(this.gopBuffer_=((buffer,start,end,mapping)=>{const startPts=Math.ceil((start-mapping)*clock_1),endPts=Math.ceil((end-mapping)*clock_1),updatedBuffer=buffer.slice();let i=buffer.length;for(;i--&&!(buffer[i].pts<=endPts););if(-1===i)return updatedBuffer;let j=i+1;for(;j--&&!(buffer[j].pts<=startPts););return j=Math.max(j,0),updatedBuffer.splice(j,i-j+1),updatedBuffer})(this.gopBuffer_,start,end,this.timeMapping_),removesRemaining++,this.sourceUpdater_.removeVideo(start,end,removeFinished));for(const track in this.inbandTextTracks_)removeCuesFromTrack(start,end,this.inbandTextTracks_[track]);removeCuesFromTrack(start,end,this.segmentMetadataTrack_),removeFinished()}monitorBuffer_(){this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),1)}monitorBufferTick_(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),500)}fillBuffer_(){if(this.sourceUpdater_.updating())return;const segmentInfo=this.chooseNextRequest_();segmentInfo&&("number"==typeof segmentInfo.timestampOffset&&(this.isPendingTimestampOffset_=!1,this.timelineChangeController_.pendingTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:segmentInfo.timeline})),this.loadSegment_(segmentInfo))}isEndOfStream_(){let mediaIndex=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.mediaIndex,playlist=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.playlist_,partIndex=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.partIndex;if(!playlist||!this.mediaSource_)return!1;const segment="number"==typeof mediaIndex&&playlist.segments[mediaIndex],appendedLastSegment=mediaIndex+1===playlist.segments.length,appendedLastPart=!segment||!segment.parts||partIndex+1===segment.parts.length;return playlist.endList&&"open"===this.mediaSource_.readyState&&appendedLastSegment&&appendedLastPart}chooseNextRequest_(){const buffered=this.buffered_(),bufferedEnd=lastBufferedEnd(buffered)||0,bufferedTime=timeAheadOf(buffered,this.currentTime_()),preloaded=!this.hasPlayed_()&&bufferedTime>=1,haveEnoughBuffer=bufferedTime>=this.goalBufferLength_(),segments=this.playlist_.segments;if(!segments.length||preloaded||haveEnoughBuffer)return null;this.syncPoint_=this.syncPoint_||this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_(),this.loaderType_);const next={partIndex:null,mediaIndex:null,startOfSegment:null,playlist:this.playlist_,isSyncRequest:Boolean(!this.syncPoint_)};if(next.isSyncRequest)next.mediaIndex=function(currentTimeline,segments,targetTime){segments=segments||[];const timelineSegments=[];let time=0;for(let i=0;itargetTime))return i}return 0===timelineSegments.length?0:timelineSegments[timelineSegments.length-1]}(this.currentTimeline_,segments,bufferedEnd),this.logger_("choose next request. Can not find sync point. Fallback to media Index: ".concat(next.mediaIndex));else if(null!==this.mediaIndex){const segment=segments[this.mediaIndex],partIndex="number"==typeof this.partIndex?this.partIndex:-1;next.startOfSegment=segment.end?segment.end:bufferedEnd,segment.parts&&segment.parts[partIndex+1]?(next.mediaIndex=this.mediaIndex,next.partIndex=partIndex+1):next.mediaIndex=this.mediaIndex+1}else{const{segmentIndex:segmentIndex,startTime:startTime,partIndex:partIndex}=Playlist.getMediaInfoForTime({exactManifestTimings:this.exactManifestTimings,playlist:this.playlist_,currentTime:this.fetchAtBuffer_?bufferedEnd:this.currentTime_(),startingPartIndex:this.syncPoint_.partIndex,startingSegmentIndex:this.syncPoint_.segmentIndex,startTime:this.syncPoint_.time});next.getMediaInfoForTime=this.fetchAtBuffer_?"bufferedEnd ".concat(bufferedEnd):"currentTime ".concat(this.currentTime_()),next.mediaIndex=segmentIndex,next.startOfSegment=startTime,next.partIndex=partIndex,this.logger_("choose next request. Playlist switched and we have a sync point. Media Index: ".concat(next.mediaIndex," "))}const nextSegment=segments[next.mediaIndex];let nextPart=nextSegment&&"number"==typeof next.partIndex&&nextSegment.parts&&nextSegment.parts[next.partIndex];if(!nextSegment||"number"==typeof next.partIndex&&!nextPart)return null;"number"!=typeof next.partIndex&&nextSegment.parts&&(next.partIndex=0,nextPart=nextSegment.parts[0]);const hasIndependentSegments=this.vhs_.playlists&&this.vhs_.playlists.main&&this.vhs_.playlists.main.independentSegments||this.playlist_.independentSegments;if(!bufferedTime&&nextPart&&!hasIndependentSegments&&!nextPart.independent)if(0===next.partIndex){const lastSegment=segments[next.mediaIndex-1],lastSegmentLastPart=lastSegment.parts&&lastSegment.parts.length&&lastSegment.parts[lastSegment.parts.length-1];lastSegmentLastPart&&lastSegmentLastPart.independent&&(next.mediaIndex-=1,next.partIndex=lastSegment.parts.length-1,next.independent="previous segment")}else nextSegment.parts[next.partIndex-1].independent&&(next.partIndex-=1,next.independent="previous part");const ended=this.mediaSource_&&"ended"===this.mediaSource_.readyState;return next.mediaIndex>=segments.length-1&&ended&&!this.seeking_()?null:(this.shouldForceTimestampOffsetAfterResync_&&(this.shouldForceTimestampOffsetAfterResync_=!1,next.forceTimestampOffset=!0,this.logger_("choose next request. Force timestamp offset after loader resync")),this.generateSegmentInfo_(next))}generateSegmentInfo_(options){const{independent:independent,playlist:playlist,mediaIndex:mediaIndex,startOfSegment:startOfSegment,isSyncRequest:isSyncRequest,partIndex:partIndex,forceTimestampOffset:forceTimestampOffset,getMediaInfoForTime:getMediaInfoForTime}=options,segment=playlist.segments[mediaIndex],part="number"==typeof partIndex&&segment.parts[partIndex],segmentInfo={requestId:"segment-loader-"+Math.random(),uri:part&&part.resolvedUri||segment.resolvedUri,mediaIndex:mediaIndex,partIndex:part?partIndex:null,isSyncRequest:isSyncRequest,startOfSegment:startOfSegment,playlist:playlist,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:segment.timeline,duration:part&&part.duration||segment.duration,segment:segment,part:part,byteLength:0,transmuxer:this.transmuxer_,getMediaInfoForTime:getMediaInfoForTime,independent:independent},overrideCheck=void 0!==forceTimestampOffset?forceTimestampOffset:this.isPendingTimestampOffset_;segmentInfo.timestampOffset=this.timestampOffsetForSegment_({segmentTimeline:segment.timeline,currentTimeline:this.currentTimeline_,startOfSegment:startOfSegment,buffered:this.buffered_(),overrideCheck:overrideCheck});const audioBufferedEnd=lastBufferedEnd(this.sourceUpdater_.audioBuffered());return"number"==typeof audioBufferedEnd&&(segmentInfo.audioAppendStart=audioBufferedEnd-this.sourceUpdater_.audioTimestampOffset()),this.sourceUpdater_.videoBuffered().length&&(segmentInfo.gopsToAlignWith=((buffer,currentTime,mapping)=>{if(null==currentTime||!buffer.length)return[];const currentTimePts=Math.ceil((currentTime-mapping+3)*clock_1);let i;for(i=0;icurrentTimePts);i++);return buffer.slice(i)})(this.gopBuffer_,this.currentTime_()-this.sourceUpdater_.videoTimestampOffset(),this.timeMapping_)),segmentInfo}timestampOffsetForSegment_(options){return(_ref65=>{let{segmentTimeline:segmentTimeline,currentTimeline:currentTimeline,startOfSegment:startOfSegment,buffered:buffered,overrideCheck:overrideCheck}=_ref65;return overrideCheck||segmentTimeline!==currentTimeline?segmentTimeline2&&void 0!==arguments[2]?arguments[2]:1;return((buffered.length?buffered.end(buffered.length-1):0)-currentTime)/playbackRate}(this.buffered_(),currentTime,this.vhs_.tech_.playbackRate())-1;if(requestTimeRemaining<=timeUntilRebuffer$1)return;const switchCandidate=function(settings){const{main:main,currentTime:currentTime,bandwidth:bandwidth,duration:duration,segmentDuration:segmentDuration,timeUntilRebuffer:timeUntilRebuffer,currentTimeline:currentTimeline,syncController:syncController}=settings,compatiblePlaylists=main.playlists.filter((playlist=>!Playlist.isIncompatible(playlist)));let enabledPlaylists=compatiblePlaylists.filter(Playlist.isEnabled);enabledPlaylists.length||(enabledPlaylists=compatiblePlaylists.filter((playlist=>!Playlist.isDisabled(playlist))));const rebufferingEstimates=enabledPlaylists.filter(Playlist.hasAttribute.bind(null,"BANDWIDTH")).map((playlist=>{const numRequests=syncController.getSyncPoint(playlist,duration,currentTimeline,currentTime)?1:2;return{playlist:playlist,rebufferingImpact:Playlist.estimateSegmentRequestTime(segmentDuration,bandwidth,playlist)*numRequests-timeUntilRebuffer}})),noRebufferingPlaylists=rebufferingEstimates.filter((estimate=>estimate.rebufferingImpact<=0));return stableSort(noRebufferingPlaylists,((a,b)=>comparePlaylistBandwidth(b.playlist,a.playlist))),noRebufferingPlaylists.length?noRebufferingPlaylists[0]:(stableSort(rebufferingEstimates,((a,b)=>a.rebufferingImpact-b.rebufferingImpact)),rebufferingEstimates[0]||null)}({main:this.vhs_.playlists.main,currentTime:currentTime,bandwidth:measuredBandwidth,duration:this.duration_(),segmentDuration:segmentDuration,timeUntilRebuffer:timeUntilRebuffer$1,currentTimeline:this.currentTimeline_,syncController:this.syncController_});if(!switchCandidate)return;const timeSavedBySwitching=requestTimeRemaining-timeUntilRebuffer$1-switchCandidate.rebufferingImpact;let minimumTimeSaving=.5;timeUntilRebuffer$1<=.03333333333333333&&(minimumTimeSaving=1),!switchCandidate.playlist||switchCandidate.playlist.uri===this.playlist_.uri||timeSavedBySwitching{captionTracks[caption.stream]=captionTracks[caption.stream]||{startTime:1/0,captions:[],endTime:0};const captionTrack=captionTracks[caption.stream];captionTrack.startTime=Math.min(captionTrack.startTime,caption.startTime+timestampOffset),captionTrack.endTime=Math.max(captionTrack.endTime,caption.endTime+timestampOffset),captionTrack.captions.push(caption)})),Object.keys(captionTracks).forEach((trackName=>{const{startTime:startTime,endTime:endTime,captions:captions}=captionTracks[trackName],inbandTextTracks=this.inbandTextTracks_;this.logger_("adding cues from ".concat(startTime," -> ").concat(endTime," for ").concat(trackName)),function(inbandTextTracks,tech,captionStream){if(!inbandTextTracks[captionStream]){tech.trigger({type:"usage",name:"vhs-608"});let instreamId=captionStream;/^cc708_/.test(captionStream)&&(instreamId="SERVICE"+captionStream.split("_")[1]);const track=tech.textTracks().getTrackById(instreamId);if(track)inbandTextTracks[captionStream]=track;else{let label=captionStream,language=captionStream,def=!1;const captionService=(tech.options_.vhs&&tech.options_.vhs.captionServices||{})[instreamId];captionService&&(label=captionService.label,language=captionService.language,def=captionService.default),inbandTextTracks[captionStream]=tech.addRemoteTextTrack({kind:"captions",id:instreamId,default:def,label:label,language:language},!1).track}}}(inbandTextTracks,this.vhs_.tech_,trackName),removeCuesFromTrack(startTime,endTime,inbandTextTracks[trackName]),function(_ref62){let{inbandTextTracks:inbandTextTracks,captionArray:captionArray,timestampOffset:timestampOffset}=_ref62;if(!captionArray)return;const Cue=window.WebKitDataCue||window.VTTCue;captionArray.forEach((caption=>{const track=caption.stream;caption.content?caption.content.forEach((value=>{const cue=new Cue(caption.startTime+timestampOffset,caption.endTime+timestampOffset,value.text);cue.line=value.line,cue.align="left",cue.position=value.position,cue.positionAlign="line-left",inbandTextTracks[track].addCue(cue)})):inbandTextTracks[track].addCue(new Cue(caption.startTime+timestampOffset,caption.endTime+timestampOffset,caption.text))}))}({captionArray:captions,inbandTextTracks:inbandTextTracks,timestampOffset:timestampOffset})})),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})}handleId3_(simpleSegment,id3Frames,dispatchType){if(this.earlyAbortWhenNeeded_(simpleSegment.stats),this.checkForAbort_(simpleSegment.requestId))return;this.pendingSegment_.hasAppendedData_?this.addMetadataToTextTrack(dispatchType,id3Frames,this.duration_()):this.metadataQueue_.id3.push(this.handleId3_.bind(this,simpleSegment,id3Frames,dispatchType))}processMetadataQueue_(){this.metadataQueue_.id3.forEach((fn=>fn())),this.metadataQueue_.caption.forEach((fn=>fn())),this.metadataQueue_.id3=[],this.metadataQueue_.caption=[]}processCallQueue_(){const callQueue=this.callQueue_;this.callQueue_=[],callQueue.forEach((fun=>fun()))}processLoadQueue_(){const loadQueue=this.loadQueue_;this.loadQueue_=[],loadQueue.forEach((fun=>fun()))}hasEnoughInfoToLoad_(){if("audio"!==this.loaderType_)return!0;const segmentInfo=this.pendingSegment_;return!!segmentInfo&&(!this.getCurrentMediaInfo_()||!shouldWaitForTimelineChange({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:segmentInfo.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))}getCurrentMediaInfo_(){let segmentInfo=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.pendingSegment_;return segmentInfo&&segmentInfo.trackInfo||this.currentMediaInfo_}getMediaInfo_(){let segmentInfo=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.pendingSegment_;return this.getCurrentMediaInfo_(segmentInfo)||this.startingMediaInfo_}getPendingSegmentPlaylist(){return this.pendingSegment_?this.pendingSegment_.playlist:null}hasEnoughInfoToAppend_(){if(!this.sourceUpdater_.ready())return!1;if(this.waitingOnRemove_||this.quotaExceededErrorRetryTimeout_)return!1;const segmentInfo=this.pendingSegment_,trackInfo=this.getCurrentMediaInfo_();if(!segmentInfo||!trackInfo)return!1;const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo;return!(hasVideo&&!segmentInfo.videoTimingInfo)&&(!(hasAudio&&!this.audioDisabled_&&!isMuxed&&!segmentInfo.audioTimingInfo)&&!shouldWaitForTimelineChange({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:segmentInfo.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))}handleData_(simpleSegment,result){if(this.earlyAbortWhenNeeded_(simpleSegment.stats),this.checkForAbort_(simpleSegment.requestId))return;if(this.callQueue_.length||!this.hasEnoughInfoToAppend_())return void this.callQueue_.push(this.handleData_.bind(this,simpleSegment,result));const segmentInfo=this.pendingSegment_;if(this.setTimeMapping_(segmentInfo.timeline),this.updateMediaSecondsLoaded_(segmentInfo.part||segmentInfo.segment),"closed"!==this.mediaSource_.readyState){if(simpleSegment.map&&(simpleSegment.map=this.initSegmentForMap(simpleSegment.map,!0),segmentInfo.segment.map=simpleSegment.map),simpleSegment.key&&this.segmentKey(simpleSegment.key,!0),segmentInfo.isFmp4=simpleSegment.isFmp4,segmentInfo.timingInfo=segmentInfo.timingInfo||{},segmentInfo.isFmp4)this.trigger("fmp4"),segmentInfo.timingInfo.start=segmentInfo[timingInfoPropertyForMedia(result.type)].start;else{const trackInfo=this.getCurrentMediaInfo_(),useVideoTimingInfo="main"===this.loaderType_&&trackInfo&&trackInfo.hasVideo;let firstVideoFrameTimeForData;useVideoTimingInfo&&(firstVideoFrameTimeForData=segmentInfo.videoTimingInfo.start),segmentInfo.timingInfo.start=this.trueSegmentStart_({currentStart:segmentInfo.timingInfo.start,playlist:segmentInfo.playlist,mediaIndex:segmentInfo.mediaIndex,currentVideoTimestampOffset:this.sourceUpdater_.videoTimestampOffset(),useVideoTimingInfo:useVideoTimingInfo,firstVideoFrameTimeForData:firstVideoFrameTimeForData,videoTimingInfo:segmentInfo.videoTimingInfo,audioTimingInfo:segmentInfo.audioTimingInfo})}if(this.updateAppendInitSegmentStatus(segmentInfo,result.type),this.updateSourceBufferTimestampOffset_(segmentInfo),segmentInfo.isSyncRequest){this.updateTimingInfoEnd_(segmentInfo),this.syncController_.saveSegmentTimingInfo({segmentInfo:segmentInfo,shouldSaveTimelineMapping:"main"===this.loaderType_});const next=this.chooseNextRequest_();if(next.mediaIndex!==segmentInfo.mediaIndex||next.partIndex!==segmentInfo.partIndex)return void this.logger_("sync segment was incorrect, not appending");this.logger_("sync segment was correct, appending")}segmentInfo.hasAppendedData_=!0,this.processMetadataQueue_(),this.appendData_(segmentInfo,result)}}updateAppendInitSegmentStatus(segmentInfo,type){"main"!==this.loaderType_||"number"!=typeof segmentInfo.timestampOffset||segmentInfo.changedTimestampOffset||(this.appendInitSegment_={audio:!0,video:!0}),this.playlistOfLastInitSegment_[type]!==segmentInfo.playlist&&(this.appendInitSegment_[type]=!0)}getInitSegmentAndUpdateState_(_ref68){let{type:type,initSegment:initSegment,map:map,playlist:playlist}=_ref68;if(map){const id=initSegmentId(map);if(this.activeInitSegmentId_===id)return null;initSegment=this.initSegmentForMap(map,!0).bytes,this.activeInitSegmentId_=id}return initSegment&&this.appendInitSegment_[type]?(this.playlistOfLastInitSegment_[type]=playlist,this.appendInitSegment_[type]=!1,this.activeInitSegmentId_=null,initSegment):null}handleQuotaExceededError_(_ref69,error){let{segmentInfo:segmentInfo,type:type,bytes:bytes}=_ref69;const audioBuffered=this.sourceUpdater_.audioBuffered(),videoBuffered=this.sourceUpdater_.videoBuffered();audioBuffered.length>1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the audio buffer: "+timeRangesToArray(audioBuffered).join(", ")),videoBuffered.length>1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the video buffer: "+timeRangesToArray(videoBuffered).join(", "));const audioBufferStart=audioBuffered.length?audioBuffered.start(0):0,audioBufferEnd=audioBuffered.length?audioBuffered.end(audioBuffered.length-1):0,videoBufferStart=videoBuffered.length?videoBuffered.start(0):0,videoBufferEnd=videoBuffered.length?videoBuffered.end(videoBuffered.length-1):0;if(audioBufferEnd-audioBufferStart<=1&&videoBufferEnd-videoBufferStart<=1)return this.logger_("On QUOTA_EXCEEDED_ERR, single segment too large to append to buffer, triggering an error. "+"Appended byte length: ".concat(bytes.byteLength,", ")+"audio buffer: ".concat(timeRangesToArray(audioBuffered).join(", "),", ")+"video buffer: ".concat(timeRangesToArray(videoBuffered).join(", "),", ")),this.error({message:"Quota exceeded error with append of a single segment of content",excludeUntil:1/0}),void this.trigger("error");this.waitingOnRemove_=!0,this.callQueue_.push(this.appendToSourceBuffer_.bind(this,{segmentInfo:segmentInfo,type:type,bytes:bytes}));const timeToRemoveUntil=this.currentTime_()-1;this.logger_("On QUOTA_EXCEEDED_ERR, removing audio/video from 0 to ".concat(timeToRemoveUntil)),this.remove(0,timeToRemoveUntil,(()=>{this.logger_("On QUOTA_EXCEEDED_ERR, retrying append in ".concat(1,"s")),this.waitingOnRemove_=!1,this.quotaExceededErrorRetryTimeout_=window.setTimeout((()=>{this.logger_("On QUOTA_EXCEEDED_ERR, re-processing call queue"),this.quotaExceededErrorRetryTimeout_=null,this.processCallQueue_()}),1e3)}),!0)}handleAppendError_(_ref70,error){let{segmentInfo:segmentInfo,type:type,bytes:bytes}=_ref70;error&&(22!==error.code?(this.logger_("Received non QUOTA_EXCEEDED_ERR on append",error),this.error("".concat(type," append of ").concat(bytes.length,"b failed for segment ")+"#".concat(segmentInfo.mediaIndex," in playlist ").concat(segmentInfo.playlist.id)),this.trigger("appenderror")):this.handleQuotaExceededError_({segmentInfo:segmentInfo,type:type,bytes:bytes}))}appendToSourceBuffer_(_ref71){let{segmentInfo:segmentInfo,type:type,initSegment:initSegment,data:data,bytes:bytes}=_ref71;if(!bytes){const segments=[data];let byteLength=data.byteLength;initSegment&&(segments.unshift(initSegment),byteLength+=initSegment.byteLength),bytes=(segmentObj=>{let tempBuffer,offset=0;return segmentObj.bytes&&(tempBuffer=new Uint8Array(segmentObj.bytes),segmentObj.segments.forEach((segment=>{tempBuffer.set(segment,offset),offset+=segment.byteLength}))),tempBuffer})({bytes:byteLength,segments:segments})}this.sourceUpdater_.appendBuffer({segmentInfo:segmentInfo,type:type,bytes:bytes},this.handleAppendError_.bind(this,{segmentInfo:segmentInfo,type:type,bytes:bytes}))}handleSegmentTimingInfo_(type,requestId,segmentTimingInfo){if(!this.pendingSegment_||requestId!==this.pendingSegment_.requestId)return;const segment=this.pendingSegment_.segment,timingInfoProperty="".concat(type,"TimingInfo");segment[timingInfoProperty]||(segment[timingInfoProperty]={}),segment[timingInfoProperty].transmuxerPrependedSeconds=segmentTimingInfo.prependedContentDuration||0,segment[timingInfoProperty].transmuxedPresentationStart=segmentTimingInfo.start.presentation,segment[timingInfoProperty].transmuxedDecodeStart=segmentTimingInfo.start.decode,segment[timingInfoProperty].transmuxedPresentationEnd=segmentTimingInfo.end.presentation,segment[timingInfoProperty].transmuxedDecodeEnd=segmentTimingInfo.end.decode,segment[timingInfoProperty].baseMediaDecodeTime=segmentTimingInfo.baseMediaDecodeTime}appendData_(segmentInfo,result){const{type:type,data:data}=result;if(!data||!data.byteLength)return;if("audio"===type&&this.audioDisabled_)return;const initSegment=this.getInitSegmentAndUpdateState_({type:type,initSegment:result.initSegment,playlist:segmentInfo.playlist,map:segmentInfo.isFmp4?segmentInfo.segment.map:null});this.appendToSourceBuffer_({segmentInfo:segmentInfo,type:type,initSegment:initSegment,data:data})}loadSegment_(segmentInfo){this.state="WAITING",this.pendingSegment_=segmentInfo,this.trimBackBuffer_(segmentInfo),"number"==typeof segmentInfo.timestampOffset&&this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.hasEnoughInfoToLoad_()?this.updateTransmuxerAndRequestSegment_(segmentInfo):this.loadQueue_.push((()=>{const options=_extends$1({},segmentInfo,{forceTimestampOffset:!0});_extends$1(segmentInfo,this.generateSegmentInfo_(options)),this.isPendingTimestampOffset_=!1,this.updateTransmuxerAndRequestSegment_(segmentInfo)}))}updateTransmuxerAndRequestSegment_(segmentInfo){this.shouldUpdateTransmuxerTimestampOffset_(segmentInfo.timestampOffset)&&(this.gopBuffer_.length=0,segmentInfo.gopsToAlignWith=[],this.timeMapping_=0,this.transmuxer_.postMessage({action:"reset"}),this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:segmentInfo.timestampOffset}));const simpleSegment=this.createSimplifiedSegmentObj_(segmentInfo),isEndOfStream=this.isEndOfStream_(segmentInfo.mediaIndex,segmentInfo.playlist,segmentInfo.partIndex),isWalkingForward=null!==this.mediaIndex,isDiscontinuity=segmentInfo.timeline!==this.currentTimeline_&&segmentInfo.timeline>0,isEndOfTimeline=isEndOfStream||isWalkingForward&&isDiscontinuity;this.logger_("Requesting ".concat(segmentInfoString(segmentInfo))),simpleSegment.map&&!simpleSegment.map.bytes&&(this.logger_("going to request init segment."),this.appendInitSegment_={video:!0,audio:!0}),segmentInfo.abortRequests=mediaSegmentRequest({xhr:this.vhs_.xhr,xhrOptions:this.xhrOptions_,decryptionWorker:this.decrypter_,segment:simpleSegment,abortFn:this.handleAbort_.bind(this,segmentInfo),progressFn:this.handleProgress_.bind(this),trackInfoFn:this.handleTrackInfo_.bind(this),timingInfoFn:this.handleTimingInfo_.bind(this),videoSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"video",segmentInfo.requestId),audioSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"audio",segmentInfo.requestId),captionsFn:this.handleCaptions_.bind(this),isEndOfTimeline:isEndOfTimeline,endedTimelineFn:()=>{this.logger_("received endedtimeline callback")},id3Fn:this.handleId3_.bind(this),dataFn:this.handleData_.bind(this),doneFn:this.segmentRequestFinished_.bind(this),onTransmuxerLog:_ref72=>{let{message:message,level:level,stream:stream}=_ref72;this.logger_("".concat(segmentInfoString(segmentInfo)," logged from transmuxer stream ").concat(stream," as a ").concat(level,": ").concat(message))}})}trimBackBuffer_(segmentInfo){const removeToTime=((seekable,currentTime,targetDuration)=>{let trimTime=currentTime-Config.BACK_BUFFER_LENGTH;seekable.length&&(trimTime=Math.max(trimTime,seekable.start(0)));const maxTrimTime=currentTime-targetDuration;return Math.min(maxTrimTime,trimTime)})(this.seekable_(),this.currentTime_(),this.playlist_.targetDuration||10);removeToTime>0&&this.remove(0,removeToTime)}createSimplifiedSegmentObj_(segmentInfo){const segment=segmentInfo.segment,part=segmentInfo.part,simpleSegment={resolvedUri:part?part.resolvedUri:segment.resolvedUri,byterange:part?part.byterange:segment.byterange,requestId:segmentInfo.requestId,transmuxer:segmentInfo.transmuxer,audioAppendStart:segmentInfo.audioAppendStart,gopsToAlignWith:segmentInfo.gopsToAlignWith,part:segmentInfo.part},previousSegment=segmentInfo.playlist.segments[segmentInfo.mediaIndex-1];if(previousSegment&&previousSegment.timeline===segment.timeline&&(previousSegment.videoTimingInfo?simpleSegment.baseStartTime=previousSegment.videoTimingInfo.transmuxedDecodeEnd:previousSegment.audioTimingInfo&&(simpleSegment.baseStartTime=previousSegment.audioTimingInfo.transmuxedDecodeEnd)),segment.key){const iv=segment.key.iv||new Uint32Array([0,0,0,segmentInfo.mediaIndex+segmentInfo.playlist.mediaSequence]);simpleSegment.key=this.segmentKey(segment.key),simpleSegment.key.iv=iv}return segment.map&&(simpleSegment.map=this.initSegmentForMap(segment.map)),simpleSegment}saveTransferStats_(stats){this.mediaRequests+=1,stats&&(this.mediaBytesTransferred+=stats.bytesReceived,this.mediaTransferDuration+=stats.roundTripTime)}saveBandwidthRelatedStats_(duration,stats){this.pendingSegment_.byteLength=stats.bytesReceived,duration<.016666666666666666?this.logger_("Ignoring segment's bandwidth because its duration of ".concat(duration)+" is less than the min to record ".concat(.016666666666666666)):(this.bandwidth=stats.bandwidth,this.roundTrip=stats.roundTripTime)}handleTimeout_(){this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,this.trigger("bandwidthupdate"),this.trigger("timeout")}segmentRequestFinished_(error,simpleSegment,result){if(this.callQueue_.length)return void this.callQueue_.push(this.segmentRequestFinished_.bind(this,error,simpleSegment,result));if(this.saveTransferStats_(simpleSegment.stats),!this.pendingSegment_)return;if(simpleSegment.requestId!==this.pendingSegment_.requestId)return;if(error){if(this.pendingSegment_=null,this.state="READY",error.code===REQUEST_ERRORS_ABORTED)return;return this.pause(),error.code===REQUEST_ERRORS_TIMEOUT?void this.handleTimeout_():(this.mediaRequestsErrored+=1,this.error(error),void this.trigger("error"))}const segmentInfo=this.pendingSegment_;this.saveBandwidthRelatedStats_(segmentInfo.duration,simpleSegment.stats),segmentInfo.endOfAllRequests=simpleSegment.endOfAllRequests,result.gopInfo&&(this.gopBuffer_=((buffer,gops,replace)=>{if(!gops.length)return buffer;if(replace)return gops.slice();const start=gops[0].pts;let i=0;for(;i=start);i++);return buffer.slice(0,i).concat(gops)})(this.gopBuffer_,result.gopInfo,this.safeAppend_)),this.state="APPENDING",this.trigger("appending"),this.waitForAppendsToComplete_(segmentInfo)}setTimeMapping_(timeline){const timelineMapping=this.syncController_.mappingForTimeline(timeline);null!==timelineMapping&&(this.timeMapping_=timelineMapping)}updateMediaSecondsLoaded_(segment){"number"==typeof segment.start&&"number"==typeof segment.end?this.mediaSecondsLoaded+=segment.end-segment.start:this.mediaSecondsLoaded+=segment.duration}shouldUpdateTransmuxerTimestampOffset_(timestampOffset){return null!==timestampOffset&&("main"===this.loaderType_&×tampOffset!==this.sourceUpdater_.videoTimestampOffset()||!this.audioDisabled_&×tampOffset!==this.sourceUpdater_.audioTimestampOffset())}trueSegmentStart_(_ref73){let{currentStart:currentStart,playlist:playlist,mediaIndex:mediaIndex,firstVideoFrameTimeForData:firstVideoFrameTimeForData,currentVideoTimestampOffset:currentVideoTimestampOffset,useVideoTimingInfo:useVideoTimingInfo,videoTimingInfo:videoTimingInfo,audioTimingInfo:audioTimingInfo}=_ref73;if(void 0!==currentStart)return currentStart;if(!useVideoTimingInfo)return audioTimingInfo.start;const previousSegment=playlist.segments[mediaIndex-1];return 0!==mediaIndex&&previousSegment&&void 0!==previousSegment.start&&previousSegment.end===firstVideoFrameTimeForData+currentVideoTimestampOffset?videoTimingInfo.start:firstVideoFrameTimeForData}waitForAppendsToComplete_(segmentInfo){const trackInfo=this.getCurrentMediaInfo_(segmentInfo);if(!trackInfo)return this.error({message:"No starting media returned, likely due to an unsupported media format.",playlistExclusionDuration:1/0}),void this.trigger("error");const{hasAudio:hasAudio,hasVideo:hasVideo,isMuxed:isMuxed}=trackInfo,waitForVideo="main"===this.loaderType_&&hasVideo,waitForAudio=!this.audioDisabled_&&hasAudio&&!isMuxed;if(segmentInfo.waitingOnAppends=0,!segmentInfo.hasAppendedData_)return segmentInfo.timingInfo||"number"!=typeof segmentInfo.timestampOffset||(this.isPendingTimestampOffset_=!0),segmentInfo.timingInfo={start:0},segmentInfo.waitingOnAppends++,this.isPendingTimestampOffset_||(this.updateSourceBufferTimestampOffset_(segmentInfo),this.processMetadataQueue_()),void this.checkAppendsDone_(segmentInfo);waitForVideo&&segmentInfo.waitingOnAppends++,waitForAudio&&segmentInfo.waitingOnAppends++,waitForVideo&&this.sourceUpdater_.videoQueueCallback(this.checkAppendsDone_.bind(this,segmentInfo)),waitForAudio&&this.sourceUpdater_.audioQueueCallback(this.checkAppendsDone_.bind(this,segmentInfo))}checkAppendsDone_(segmentInfo){this.checkForAbort_(segmentInfo.requestId)||(segmentInfo.waitingOnAppends--,0===segmentInfo.waitingOnAppends&&this.handleAppendsDone_())}checkForIllegalMediaSwitch(trackInfo){const illegalMediaSwitchError=((loaderType,startingMedia,trackInfo)=>"main"===loaderType&&startingMedia&&trackInfo?trackInfo.hasAudio||trackInfo.hasVideo?startingMedia.hasVideo&&!trackInfo.hasVideo?"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.":!startingMedia.hasVideo&&trackInfo.hasVideo?"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.getCurrentMediaInfo_(),trackInfo);return!!illegalMediaSwitchError&&(this.error({message:illegalMediaSwitchError,playlistExclusionDuration:1/0}),this.trigger("error"),!0)}updateSourceBufferTimestampOffset_(segmentInfo){if(null===segmentInfo.timestampOffset||"number"!=typeof segmentInfo.timingInfo.start||segmentInfo.changedTimestampOffset||"main"!==this.loaderType_)return;let didChange=!1;segmentInfo.timestampOffset-=this.getSegmentStartTimeForTimestampOffsetCalculation_({videoTimingInfo:segmentInfo.segment.videoTimingInfo,audioTimingInfo:segmentInfo.segment.audioTimingInfo,timingInfo:segmentInfo.timingInfo}),segmentInfo.changedTimestampOffset=!0,segmentInfo.timestampOffset!==this.sourceUpdater_.videoTimestampOffset()&&(this.sourceUpdater_.videoTimestampOffset(segmentInfo.timestampOffset),didChange=!0),segmentInfo.timestampOffset!==this.sourceUpdater_.audioTimestampOffset()&&(this.sourceUpdater_.audioTimestampOffset(segmentInfo.timestampOffset),didChange=!0),didChange&&this.trigger("timestampoffset")}getSegmentStartTimeForTimestampOffsetCalculation_(_ref74){let{videoTimingInfo:videoTimingInfo,audioTimingInfo:audioTimingInfo,timingInfo:timingInfo}=_ref74;return this.useDtsForTimestampOffset_?videoTimingInfo&&"number"==typeof videoTimingInfo.transmuxedDecodeStart?videoTimingInfo.transmuxedDecodeStart:audioTimingInfo&&"number"==typeof audioTimingInfo.transmuxedDecodeStart?audioTimingInfo.transmuxedDecodeStart:timingInfo.start:timingInfo.start}updateTimingInfoEnd_(segmentInfo){segmentInfo.timingInfo=segmentInfo.timingInfo||{};const trackInfo=this.getMediaInfo_(),prioritizedTimingInfo="main"===this.loaderType_&&trackInfo&&trackInfo.hasVideo&&segmentInfo.videoTimingInfo?segmentInfo.videoTimingInfo:segmentInfo.audioTimingInfo;prioritizedTimingInfo&&(segmentInfo.timingInfo.end="number"==typeof prioritizedTimingInfo.end?prioritizedTimingInfo.end:prioritizedTimingInfo.start+segmentInfo.duration)}handleAppendsDone_(){if(this.pendingSegment_&&this.trigger("appendsdone"),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());const segmentInfo=this.pendingSegment_;this.updateTimingInfoEnd_(segmentInfo),this.shouldSaveSegmentTimingInfo_&&this.syncController_.saveSegmentTimingInfo({segmentInfo:segmentInfo,shouldSaveTimelineMapping:"main"===this.loaderType_});const segmentDurationMessage=getTroublesomeSegmentDurationMessage(segmentInfo,this.sourceType_);if(segmentDurationMessage&&("warn"===segmentDurationMessage.severity?videojs.log.warn(segmentDurationMessage.message):this.logger_(segmentDurationMessage.message)),this.recordThroughput_(segmentInfo),this.pendingSegment_=null,this.state="READY",segmentInfo.isSyncRequest&&(this.trigger("syncinfoupdate"),!segmentInfo.hasAppendedData_))return void this.logger_("Throwing away un-appended sync request ".concat(segmentInfoString(segmentInfo)));this.logger_("Appended ".concat(segmentInfoString(segmentInfo))),this.addSegmentMetadataCue_(segmentInfo),this.fetchAtBuffer_=!0,this.currentTimeline_!==segmentInfo.timeline&&(this.timelineChangeController_.lastTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:segmentInfo.timeline}),"main"!==this.loaderType_||this.audioDisabled_||this.timelineChangeController_.lastTimelineChange({type:"audio",from:this.currentTimeline_,to:segmentInfo.timeline})),this.currentTimeline_=segmentInfo.timeline,this.trigger("syncinfoupdate");const segment=segmentInfo.segment,part=segmentInfo.part,badSegmentGuess=segment.end&&this.currentTime_()-segment.end>3*segmentInfo.playlist.targetDuration,badPartGuess=part&&part.end&&this.currentTime_()-part.end>3*segmentInfo.playlist.partTargetDuration;if(badSegmentGuess||badPartGuess)return this.logger_("bad ".concat(badSegmentGuess?"segment":"part"," ").concat(segmentInfoString(segmentInfo))),void this.resetEverything();null!==this.mediaIndex&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.mediaIndex=segmentInfo.mediaIndex,this.partIndex=segmentInfo.partIndex,this.isEndOfStream_(segmentInfo.mediaIndex,segmentInfo.playlist,segmentInfo.partIndex)&&this.endOfStream(),this.trigger("appended"),segmentInfo.hasAppendedData_&&this.mediaAppends++,this.paused()||this.monitorBuffer_()}recordThroughput_(segmentInfo){if(segmentInfo.duration<.016666666666666666)return void this.logger_("Ignoring segment's throughput because its duration of ".concat(segmentInfo.duration)+" is less than the min to record ".concat(.016666666666666666));const rate=this.throughput.rate,segmentProcessingTime=Date.now()-segmentInfo.endOfAllRequests+1,segmentProcessingThroughput=Math.floor(segmentInfo.byteLength/segmentProcessingTime*8*1e3);this.throughput.rate+=(segmentProcessingThroughput-rate)/++this.throughput.count}addSegmentMetadataCue_(segmentInfo){if(!this.segmentMetadataTrack_)return;const segment=segmentInfo.segment,start=segment.start,end=segment.end;if(!finite(start)||!finite(end))return;removeCuesFromTrack(start,end,this.segmentMetadataTrack_);const Cue=window.WebKitDataCue||window.VTTCue,value={custom:segment.custom,dateTimeObject:segment.dateTimeObject,dateTimeString:segment.dateTimeString,programDateTime:segment.programDateTime,bandwidth:segmentInfo.playlist.attributes.BANDWIDTH,resolution:segmentInfo.playlist.attributes.RESOLUTION,codecs:segmentInfo.playlist.attributes.CODECS,byteLength:segmentInfo.byteLength,uri:segmentInfo.uri,timeline:segmentInfo.timeline,playlist:segmentInfo.playlist.id,start:start,end:end},cue=new Cue(start,end,JSON.stringify(value));cue.value=value,this.segmentMetadataTrack_.addCue(cue)}}function noop(){}const toTitleCase=function(string){return"string"!=typeof string?string:string.replace(/./,(w=>w.toUpperCase()))},bufferTypes=["video","audio"],updating=(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];return sourceBuffer&&sourceBuffer.updating||sourceUpdater.queuePending[type]},shiftQueue=(type,sourceUpdater)=>{if(0===sourceUpdater.queue.length)return;let queueIndex=0,queueEntry=sourceUpdater.queue[queueIndex];if("mediaSource"!==queueEntry.type){if("mediaSource"!==type&&sourceUpdater.ready()&&"closed"!==sourceUpdater.mediaSource.readyState&&!updating(type,sourceUpdater)){if(queueEntry.type!==type){if(queueIndex=((type,queue)=>{for(let i=0;i{const buffer=sourceUpdater["".concat(type,"Buffer")],titleType=toTitleCase(type);buffer&&(buffer.removeEventListener("updateend",sourceUpdater["on".concat(titleType,"UpdateEnd_")]),buffer.removeEventListener("error",sourceUpdater["on".concat(titleType,"Error_")]),sourceUpdater.codecs[type]=null,sourceUpdater["".concat(type,"Buffer")]=null)},inSourceBuffers=(mediaSource,sourceBuffer)=>mediaSource&&sourceBuffer&&-1!==Array.prototype.indexOf.call(mediaSource.sourceBuffers,sourceBuffer),actions_appendBuffer=(bytes,segmentInfo,onError)=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Appending segment ".concat(segmentInfo.mediaIndex,"'s ").concat(bytes.length," bytes to ").concat(type,"Buffer"));try{sourceBuffer.appendBuffer(bytes)}catch(e){sourceUpdater.logger_("Error with code ".concat(e.code," ")+(22===e.code?"(QUOTA_EXCEEDED_ERR) ":"")+"when appending segment ".concat(segmentInfo.mediaIndex," to ").concat(type,"Buffer")),sourceUpdater.queuePending[type]=null,onError(e)}}},actions_remove=(start,end)=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Removing ".concat(start," to ").concat(end," from ").concat(type,"Buffer"));try{sourceBuffer.remove(start,end)}catch(e){sourceUpdater.logger_("Remove ".concat(start," to ").concat(end," from ").concat(type,"Buffer failed"))}}},actions_timestampOffset=offset=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)&&(sourceUpdater.logger_("Setting ".concat(type,"timestampOffset to ").concat(offset)),sourceBuffer.timestampOffset=offset)},actions_callback=callback=>(type,sourceUpdater)=>{callback()},actions_endOfStream=error=>sourceUpdater=>{if("open"===sourceUpdater.mediaSource.readyState){sourceUpdater.logger_("Calling mediaSource endOfStream(".concat(error||"",")"));try{sourceUpdater.mediaSource.endOfStream(error)}catch(e){videojs.log.warn("Failed to call media source endOfStream",e)}}},actions_duration=duration=>sourceUpdater=>{sourceUpdater.logger_("Setting mediaSource duration to ".concat(duration));try{sourceUpdater.mediaSource.duration=duration}catch(e){videojs.log.warn("Failed to set media source duration",e)}},actions_abort=()=>(type,sourceUpdater)=>{if("open"!==sourceUpdater.mediaSource.readyState)return;const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("calling abort on ".concat(type,"Buffer"));try{sourceBuffer.abort()}catch(e){videojs.log.warn("Failed to abort on ".concat(type,"Buffer"),e)}}},actions_addSourceBuffer=(type,codec)=>sourceUpdater=>{const titleType=toTitleCase(type),mime=getMimeForCodec(codec);sourceUpdater.logger_("Adding ".concat(type,"Buffer with codec ").concat(codec," to mediaSource"));const sourceBuffer=sourceUpdater.mediaSource.addSourceBuffer(mime);sourceBuffer.addEventListener("updateend",sourceUpdater["on".concat(titleType,"UpdateEnd_")]),sourceBuffer.addEventListener("error",sourceUpdater["on".concat(titleType,"Error_")]),sourceUpdater.codecs[type]=codec,sourceUpdater["".concat(type,"Buffer")]=sourceBuffer},actions_removeSourceBuffer=type=>sourceUpdater=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")];if(cleanupBuffer(type,sourceUpdater),inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)){sourceUpdater.logger_("Removing ".concat(type,"Buffer with codec ").concat(sourceUpdater.codecs[type]," from mediaSource"));try{sourceUpdater.mediaSource.removeSourceBuffer(sourceBuffer)}catch(e){videojs.log.warn("Failed to removeSourceBuffer ".concat(type,"Buffer"),e)}}},actions_changeType=codec=>(type,sourceUpdater)=>{const sourceBuffer=sourceUpdater["".concat(type,"Buffer")],mime=getMimeForCodec(codec);if(inSourceBuffers(sourceUpdater.mediaSource,sourceBuffer)&&sourceUpdater.codecs[type]!==codec){sourceUpdater.logger_("changing ".concat(type,"Buffer codec from ").concat(sourceUpdater.codecs[type]," to ").concat(codec));try{sourceBuffer.changeType(mime),sourceUpdater.codecs[type]=codec}catch(e){videojs.log.warn("Failed to changeType on ".concat(type,"Buffer"),e)}}},pushQueue=_ref75=>{let{type:type,sourceUpdater:sourceUpdater,action:action,doneFn:doneFn,name:name}=_ref75;sourceUpdater.queue.push({type:type,action:action,doneFn:doneFn,name:name}),shiftQueue(type,sourceUpdater)},onUpdateend=(type,sourceUpdater)=>e=>{if(sourceUpdater.queuePending[type]){const doneFn=sourceUpdater.queuePending[type].doneFn;sourceUpdater.queuePending[type]=null,doneFn&&doneFn(sourceUpdater["".concat(type,"Error_")])}shiftQueue(type,sourceUpdater)};class SourceUpdater extends videojs.EventTarget{constructor(mediaSource){super(),this.mediaSource=mediaSource,this.sourceopenListener_=()=>shiftQueue("mediaSource",this),this.mediaSource.addEventListener("sourceopen",this.sourceopenListener_),this.logger_=logger("SourceUpdater"),this.audioTimestampOffset_=0,this.videoTimestampOffset_=0,this.queue=[],this.queuePending={audio:null,video:null},this.delayedAudioAppendQueue_=[],this.videoAppendQueued_=!1,this.codecs={},this.onVideoUpdateEnd_=onUpdateend("video",this),this.onAudioUpdateEnd_=onUpdateend("audio",this),this.onVideoError_=e=>{this.videoError_=e},this.onAudioError_=e=>{this.audioError_=e},this.createdSourceBuffers_=!1,this.initializedEme_=!1,this.triggeredReady_=!1}initializedEme(){this.initializedEme_=!0,this.triggerReady()}hasCreatedSourceBuffers(){return this.createdSourceBuffers_}hasInitializedAnyEme(){return this.initializedEme_}ready(){return this.hasCreatedSourceBuffers()&&this.hasInitializedAnyEme()}createSourceBuffers(codecs){this.hasCreatedSourceBuffers()||(this.addOrChangeSourceBuffers(codecs),this.createdSourceBuffers_=!0,this.trigger("createdsourcebuffers"),this.triggerReady())}triggerReady(){this.ready()&&!this.triggeredReady_&&(this.triggeredReady_=!0,this.trigger("ready"))}addSourceBuffer(type,codec){pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_addSourceBuffer(type,codec),name:"addSourceBuffer"})}abort(type){pushQueue({type:type,sourceUpdater:this,action:actions_abort(type),name:"abort"})}removeSourceBuffer(type){this.canRemoveSourceBuffer()?pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_removeSourceBuffer(type),name:"removeSourceBuffer"}):videojs.log.error("removeSourceBuffer is not supported!")}canRemoveSourceBuffer(){return!videojs.browser.IS_FIREFOX&&window.MediaSource&&window.MediaSource.prototype&&"function"==typeof window.MediaSource.prototype.removeSourceBuffer}static canChangeType(){return window.SourceBuffer&&window.SourceBuffer.prototype&&"function"==typeof window.SourceBuffer.prototype.changeType}canChangeType(){return this.constructor.canChangeType()}changeType(type,codec){this.canChangeType()?pushQueue({type:type,sourceUpdater:this,action:actions_changeType(codec),name:"changeType"}):videojs.log.error("changeType is not supported!")}addOrChangeSourceBuffers(codecs){if(!codecs||"object"!=typeof codecs||0===Object.keys(codecs).length)throw new Error("Cannot addOrChangeSourceBuffers to undefined codecs");Object.keys(codecs).forEach((type=>{const codec=codecs[type];if(!this.hasCreatedSourceBuffers())return this.addSourceBuffer(type,codec);this.canChangeType()&&this.changeType(type,codec)}))}appendBuffer(options,doneFn){const{segmentInfo:segmentInfo,type:type,bytes:bytes}=options;if(this.processedAppend_=!0,"audio"===type&&this.videoBuffer&&!this.videoAppendQueued_)return this.delayedAudioAppendQueue_.push([options,doneFn]),void this.logger_("delayed audio append of ".concat(bytes.length," until video append"));if(pushQueue({type:type,sourceUpdater:this,action:actions_appendBuffer(bytes,segmentInfo||{mediaIndex:-1},doneFn),doneFn:doneFn,name:"appendBuffer"}),"video"===type){if(this.videoAppendQueued_=!0,!this.delayedAudioAppendQueue_.length)return;const queue=this.delayedAudioAppendQueue_.slice();this.logger_("queuing delayed audio ".concat(queue.length," appendBuffers")),this.delayedAudioAppendQueue_.length=0,queue.forEach((que=>{this.appendBuffer.apply(this,que)}))}}audioBuffered(){return inSourceBuffers(this.mediaSource,this.audioBuffer)&&this.audioBuffer.buffered?this.audioBuffer.buffered:createTimeRanges()}videoBuffered(){return inSourceBuffers(this.mediaSource,this.videoBuffer)&&this.videoBuffer.buffered?this.videoBuffer.buffered:createTimeRanges()}buffered(){const video=inSourceBuffers(this.mediaSource,this.videoBuffer)?this.videoBuffer:null,audio=inSourceBuffers(this.mediaSource,this.audioBuffer)?this.audioBuffer:null;return audio&&!video?this.audioBuffered():video&&!audio?this.videoBuffered():function(bufferA,bufferB){let start=null,end=null,arity=0;const extents=[],ranges=[];if(!(bufferA&&bufferA.length&&bufferB&&bufferB.length))return createTimeRanges();let count=bufferA.length;for(;count--;)extents.push({time:bufferA.start(count),type:"start"}),extents.push({time:bufferA.end(count),type:"end"});for(count=bufferB.length;count--;)extents.push({time:bufferB.start(count),type:"start"}),extents.push({time:bufferB.end(count),type:"end"});for(extents.sort((function(a,b){return a.time-b.time})),count=0;count1&&void 0!==arguments[1]?arguments[1]:noop;pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_duration(duration),name:"duration",doneFn:doneFn})}endOfStream(){let error=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,doneFn=arguments.length>1&&void 0!==arguments[1]?arguments[1]:noop;"string"!=typeof error&&(error=void 0),pushQueue({type:"mediaSource",sourceUpdater:this,action:actions_endOfStream(error),name:"endOfStream",doneFn:doneFn})}removeAudio(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:noop;this.audioBuffered().length&&0!==this.audioBuffered().end(0)?pushQueue({type:"audio",sourceUpdater:this,action:actions_remove(start,end),doneFn:done,name:"remove"}):done()}removeVideo(start,end){let done=arguments.length>2&&void 0!==arguments[2]?arguments[2]:noop;this.videoBuffered().length&&0!==this.videoBuffered().end(0)?pushQueue({type:"video",sourceUpdater:this,action:actions_remove(start,end),doneFn:done,name:"remove"}):done()}updating(){return!(!updating("audio",this)&&!updating("video",this))}audioTimestampOffset(offset){return void 0!==offset&&this.audioBuffer&&this.audioTimestampOffset_!==offset&&(pushQueue({type:"audio",sourceUpdater:this,action:actions_timestampOffset(offset),name:"timestampOffset"}),this.audioTimestampOffset_=offset),this.audioTimestampOffset_}videoTimestampOffset(offset){return void 0!==offset&&this.videoBuffer&&this.videoTimestampOffset!==offset&&(pushQueue({type:"video",sourceUpdater:this,action:actions_timestampOffset(offset),name:"timestampOffset"}),this.videoTimestampOffset_=offset),this.videoTimestampOffset_}audioQueueCallback(callback){this.audioBuffer&&pushQueue({type:"audio",sourceUpdater:this,action:actions_callback(callback),name:"callback"})}videoQueueCallback(callback){this.videoBuffer&&pushQueue({type:"video",sourceUpdater:this,action:actions_callback(callback),name:"callback"})}dispose(){this.trigger("dispose"),bufferTypes.forEach((type=>{this.abort(type),this.canRemoveSourceBuffer()?this.removeSourceBuffer(type):this["".concat(type,"QueueCallback")]((()=>cleanupBuffer(type,this)))})),this.videoAppendQueued_=!1,this.delayedAudioAppendQueue_.length=0,this.sourceopenListener_&&this.mediaSource.removeEventListener("sourceopen",this.sourceopenListener_),this.off()}}const uint8ToUtf8=uintArray=>decodeURIComponent(escape(String.fromCharCode.apply(null,uintArray))),VTT_LINE_TERMINATORS=new Uint8Array("\n\n".split("").map((char=>char.charCodeAt(0))));class NoVttJsError extends Error{constructor(){super("Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.")}}class VTTSegmentLoader extends SegmentLoader{constructor(settings){super(settings,arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}),this.mediaSource_=null,this.subtitlesTrack_=null,this.loaderType_="subtitle",this.featuresNativeTextTracks_=settings.featuresNativeTextTracks,this.loadVttJs=settings.loadVttJs,this.shouldSaveSegmentTimingInfo_=!1}createTransmuxer_(){return null}buffered_(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues||!this.subtitlesTrack_.cues.length)return createTimeRanges();const cues=this.subtitlesTrack_.cues;return createTimeRanges([[cues[0].startTime,cues[cues.length-1].startTime]])}initSegmentForMap(map){let set=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!map)return null;const id=initSegmentId(map);let storedMap=this.initSegments_[id];if(set&&!storedMap&&map.bytes){const combinedByteLength=VTT_LINE_TERMINATORS.byteLength+map.bytes.byteLength,combinedSegment=new Uint8Array(combinedByteLength);combinedSegment.set(map.bytes),combinedSegment.set(VTT_LINE_TERMINATORS,map.bytes.byteLength),this.initSegments_[id]=storedMap={resolvedUri:map.resolvedUri,byterange:map.byterange,bytes:combinedSegment}}return storedMap||map}couldBeginLoading_(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()}init_(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()}track(track){return void 0===track||(this.subtitlesTrack_=track,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_}remove(start,end){removeCuesFromTrack(start,end,this.subtitlesTrack_)}fillBuffer_(){const segmentInfo=this.chooseNextRequest_();if(segmentInfo){if(null===this.syncController_.timestampOffsetForTimeline(segmentInfo.timeline)){const checkTimestampOffset=()=>{this.state="READY",this.paused()||this.monitorBuffer_()};return this.syncController_.one("timestampoffset",checkTimestampOffset),void(this.state="WAITING_ON_TIMELINE")}this.loadSegment_(segmentInfo)}}timestampOffsetForSegment_(){return null}chooseNextRequest_(){return this.skipEmptySegments_(super.chooseNextRequest_())}skipEmptySegments_(segmentInfo){for(;segmentInfo&&segmentInfo.segment.empty;){if(segmentInfo.mediaIndex+1>=segmentInfo.playlist.segments.length){segmentInfo=null;break}segmentInfo=this.generateSegmentInfo_({playlist:segmentInfo.playlist,mediaIndex:segmentInfo.mediaIndex+1,startOfSegment:segmentInfo.startOfSegment+segmentInfo.duration,isSyncRequest:segmentInfo.isSyncRequest})}return segmentInfo}stopForError(error){this.error(error),this.state="READY",this.pause(),this.trigger("error")}segmentRequestFinished_(error,simpleSegment,result){if(!this.subtitlesTrack_)return void(this.state="READY");if(this.saveTransferStats_(simpleSegment.stats),!this.pendingSegment_)return this.state="READY",void(this.mediaRequestsAborted+=1);if(error)return error.code===REQUEST_ERRORS_TIMEOUT&&this.handleTimeout_(),error.code===REQUEST_ERRORS_ABORTED?this.mediaRequestsAborted+=1:this.mediaRequestsErrored+=1,void this.stopForError(error);const segmentInfo=this.pendingSegment_;this.saveBandwidthRelatedStats_(segmentInfo.duration,simpleSegment.stats),simpleSegment.key&&this.segmentKey(simpleSegment.key,!0),this.state="APPENDING",this.trigger("appending");const segment=segmentInfo.segment;if(segment.map&&(segment.map.bytes=simpleSegment.map.bytes),segmentInfo.bytes=simpleSegment.bytes,"function"!=typeof window.WebVTT&&"function"==typeof this.loadVttJs)return this.state="WAITING_ON_VTTJS",void this.loadVttJs().then((()=>this.segmentRequestFinished_(error,simpleSegment,result)),(()=>this.stopForError({message:"Error loading vtt.js"})));segment.requested=!0;try{this.parseVTTCues_(segmentInfo)}catch(e){return void this.stopForError({message:e.message})}if(this.updateTimeMapping_(segmentInfo,this.syncController_.timelines[segmentInfo.timeline],this.playlist_),segmentInfo.cues.length?segmentInfo.timingInfo={start:segmentInfo.cues[0].startTime,end:segmentInfo.cues[segmentInfo.cues.length-1].endTime}:segmentInfo.timingInfo={start:segmentInfo.startOfSegment,end:segmentInfo.startOfSegment+segmentInfo.duration},segmentInfo.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");segmentInfo.byteLength=segmentInfo.bytes.byteLength,this.mediaSecondsLoaded+=segment.duration,segmentInfo.cues.forEach((cue=>{this.subtitlesTrack_.addCue(this.featuresNativeTextTracks_?new window.VTTCue(cue.startTime,cue.endTime,cue.text):cue)})),function(track){const cues=track.cues;if(!cues)return;const uniqueCues={};for(let i=cues.length-1;i>=0;i--){const cue=cues[i],cueKey="".concat(cue.startTime,"-").concat(cue.endTime,"-").concat(cue.text);uniqueCues[cueKey]?track.removeCue(cue):uniqueCues[cueKey]=cue}}(this.subtitlesTrack_),this.handleAppendsDone_()}handleData_(){}updateTimingInfoEnd_(){}parseVTTCues_(segmentInfo){let decoder,decodeBytesToString=!1;if("function"!=typeof window.WebVTT)throw new NoVttJsError;"function"==typeof window.TextDecoder?decoder=new window.TextDecoder("utf8"):(decoder=window.WebVTT.StringDecoder(),decodeBytesToString=!0);const parser=new window.WebVTT.Parser(window,window.vttjs,decoder);if(segmentInfo.cues=[],segmentInfo.timestampmap={MPEGTS:0,LOCAL:0},parser.oncue=segmentInfo.cues.push.bind(segmentInfo.cues),parser.ontimestampmap=map=>{segmentInfo.timestampmap=map},parser.onparsingerror=error=>{videojs.log.warn("Error encountered when parsing cues: "+error.message)},segmentInfo.segment.map){let mapData=segmentInfo.segment.map.bytes;decodeBytesToString&&(mapData=uint8ToUtf8(mapData)),parser.parse(mapData)}let segmentData=segmentInfo.bytes;decodeBytesToString&&(segmentData=uint8ToUtf8(segmentData)),parser.parse(segmentData),parser.flush()}updateTimeMapping_(segmentInfo,mappingObj,playlist){const segment=segmentInfo.segment;if(!mappingObj)return;if(!segmentInfo.cues.length)return void(segment.empty=!0);const{MPEGTS:MPEGTS,LOCAL:LOCAL}=segmentInfo.timestampmap,diff=MPEGTS/clock_1-LOCAL+mappingObj.mapping;if(segmentInfo.cues.forEach((cue=>{const duration=cue.endTime-cue.startTime,startTime=0===MPEGTS?cue.startTime+diff:this.handleRollover_(cue.startTime+diff,mappingObj.time);cue.startTime=Math.max(startTime,0),cue.endTime=Math.max(startTime+duration,0)})),!playlist.syncInfo){const firstStart=segmentInfo.cues[0].startTime,lastStart=segmentInfo.cues[segmentInfo.cues.length-1].startTime;playlist.syncInfo={mediaSequence:playlist.mediaSequence+segmentInfo.mediaIndex,time:Math.min(firstStart,lastStart-segment.duration)}}}handleRollover_(value,reference){if(null===reference)return value;let valueIn90khz=value*clock_1;const referenceIn90khz=reference*clock_1;let offset;for(offset=referenceIn90khz4294967296;)valueIn90khz+=offset;return valueIn90khz/clock_1}}const findAdCue=function(track,mediaTime){const cues=track.cues;for(let i=0;i=cue.adStartTime&&mediaTime<=cue.adEndTime)return cue}return null},syncPointStrategies=[{name:"VOD",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{if(duration!==1/0){return{time:0,segmentIndex:0,partIndex:null}}return null}},{name:"MediaSequence",run:(syncController,playlist,duration,currentTimeline,currentTime,type)=>{if(!type)return null;const mediaSequenceMap=syncController.getMediaSequenceMap(type);if(!mediaSequenceMap||0===mediaSequenceMap.size)return null;if(void 0===playlist.mediaSequence||!Array.isArray(playlist.segments)||!playlist.segments.length)return null;let currentMediaSequence=playlist.mediaSequence,segmentIndex=0;for(const segment of playlist.segments){const range=mediaSequenceMap.get(currentMediaSequence);if(!range)break;if(currentTime>=range.start&¤tTime=start&¤tTime{if(!Object.keys(syncController.timelineToDatetimeMappings).length)return null;let syncPoint=null,lastDistance=null;const partsAndSegments=getPartsAndSegments(playlist);currentTime=currentTime||0;for(let i=0;i{let syncPoint=null,lastDistance=null;currentTime=currentTime||0;const partsAndSegments=getPartsAndSegments(playlist);for(let i=0;i=distance)&&(lastDistance=distance,syncPoint={time:start,segmentIndex:partAndSegment.segmentIndex,partIndex:partAndSegment.partIndex})}}return syncPoint}},{name:"Discontinuity",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{let syncPoint=null;if(currentTime=currentTime||0,playlist.discontinuityStarts&&playlist.discontinuityStarts.length){let lastDistance=null;for(let i=0;i=distance)&&(lastDistance=distance,syncPoint={time:discontinuitySync.time,segmentIndex:segmentIndex,partIndex:null})}}}return syncPoint}},{name:"Playlist",run:(syncController,playlist,duration,currentTimeline,currentTime)=>{if(playlist.syncInfo){return{time:playlist.syncInfo.time,segmentIndex:playlist.syncInfo.mediaSequence-playlist.mediaSequence,partIndex:null}}return null}}];class SyncController extends videojs.EventTarget{constructor(){super(),this.timelines=[],this.discontinuities=[],this.timelineToDatetimeMappings={},this.mediaSequenceStorage_=new Map,this.logger_=logger("SyncController")}getMediaSequenceMap(type){return this.mediaSequenceStorage_.get(type)}updateMediaSequenceMap(playlist,currentTime,type){if(void 0===playlist.mediaSequence||!Array.isArray(playlist.segments)||!playlist.segments.length)return;const currentMap=this.getMediaSequenceMap(type),result=new Map;let currentBaseTime,currentMediaSequence=playlist.mediaSequence;currentMap?currentMap.has(playlist.mediaSequence)?currentBaseTime=currentMap.get(playlist.mediaSequence).start:(this.logger_("MediaSequence sync for ".concat(type," segment loader - received a gap between playlists.\nFallback base time to: ").concat(currentTime,".\nReceived media sequence: ").concat(currentMediaSequence,".\nCurrent map: "),currentMap),currentBaseTime=currentTime):currentBaseTime=0,this.logger_("MediaSequence sync for ".concat(type," segment loader.\nReceived media sequence: ").concat(currentMediaSequence,".\nbase time is ").concat(currentBaseTime,"\nCurrent map: "),currentMap),playlist.segments.forEach((segment=>{const start=currentBaseTime,end=start+segment.duration,range={start:start,end:end};result.set(currentMediaSequence,range),currentMediaSequence++,currentBaseTime=end})),this.mediaSequenceStorage_.set(type,result)}getSyncPoint(playlist,duration,currentTimeline,currentTime,type){if(duration!==1/0){return syncPointStrategies.find((_ref76=>{let{name:name}=_ref76;return"VOD"===name})).run(this,playlist,duration)}const syncPoints=this.runStrategies_(playlist,duration,currentTimeline,currentTime,type);if(!syncPoints.length)return null;for(const syncPointInfo of syncPoints){const{syncPoint:syncPoint,strategy:strategy}=syncPointInfo,{segmentIndex:segmentIndex,time:time}=syncPoint;if(segmentIndex<0)continue;const start=time,end=start+playlist.segments[segmentIndex].duration;if(this.logger_("Strategy: ".concat(strategy,". Current time: ").concat(currentTime,". selected segment: ").concat(segmentIndex,". Time: [").concat(start," -> ").concat(end,"]}")),currentTime>=start&¤tTime0&&(syncPoint.time*=-1),Math.abs(syncPoint.time+sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:syncPoint.segmentIndex,endIndex:0}))}runStrategies_(playlist,duration,currentTimeline,currentTime,type){const syncPoints=[];for(let i=0;i86400)videojs.log.warn("Not saving expired segment info. Media sequence gap ".concat(mediaSequenceDiff," is too large."));else for(let i=mediaSequenceDiff-1;i>=0;i--){const lastRemovedSegment=oldPlaylist.segments[i];if(lastRemovedSegment&&void 0!==lastRemovedSegment.start){newPlaylist.syncInfo={mediaSequence:oldPlaylist.mediaSequence+i,time:lastRemovedSegment.start},this.logger_("playlist refresh sync: [time:".concat(newPlaylist.syncInfo.time,",")+" mediaSequence: ".concat(newPlaylist.syncInfo.mediaSequence,"]")),this.trigger("syncinfoupdate");break}}}setDateTimeMappingForStart(playlist){if(this.timelineToDatetimeMappings={},playlist.segments&&playlist.segments.length&&playlist.segments[0].dateTimeObject){const firstSegment=playlist.segments[0],playlistTimestamp=firstSegment.dateTimeObject.getTime()/1e3;this.timelineToDatetimeMappings[firstSegment.timeline]=-playlistTimestamp}}saveSegmentTimingInfo(_ref77){let{segmentInfo:segmentInfo,shouldSaveTimelineMapping:shouldSaveTimelineMapping}=_ref77;const didCalculateSegmentTimeMapping=this.calculateSegmentTimeMapping_(segmentInfo,segmentInfo.timingInfo,shouldSaveTimelineMapping),segment=segmentInfo.segment;didCalculateSegmentTimeMapping&&(this.saveDiscontinuitySyncInfo_(segmentInfo),segmentInfo.playlist.syncInfo||(segmentInfo.playlist.syncInfo={mediaSequence:segmentInfo.playlist.mediaSequence+segmentInfo.mediaIndex,time:segment.start}));const dateTime=segment.dateTimeObject;segment.discontinuity&&shouldSaveTimelineMapping&&dateTime&&(this.timelineToDatetimeMappings[segment.timeline]=-dateTime.getTime()/1e3)}timestampOffsetForTimeline(timeline){return void 0===this.timelines[timeline]?null:this.timelines[timeline].time}mappingForTimeline(timeline){return void 0===this.timelines[timeline]?null:this.timelines[timeline].mapping}calculateSegmentTimeMapping_(segmentInfo,timingInfo,shouldSaveTimelineMapping){const segment=segmentInfo.segment,part=segmentInfo.part;let start,end,mappingObj=this.timelines[segmentInfo.timeline];if("number"==typeof segmentInfo.timestampOffset)mappingObj={time:segmentInfo.startOfSegment,mapping:segmentInfo.startOfSegment-timingInfo.start},shouldSaveTimelineMapping&&(this.timelines[segmentInfo.timeline]=mappingObj,this.trigger("timestampoffset"),this.logger_("time mapping for timeline ".concat(segmentInfo.timeline,": ")+"[time: ".concat(mappingObj.time,"] [mapping: ").concat(mappingObj.mapping,"]"))),start=segmentInfo.startOfSegment,end=timingInfo.end+mappingObj.mapping;else{if(!mappingObj)return!1;start=timingInfo.start+mappingObj.mapping,end=timingInfo.end+mappingObj.mapping}return part&&(part.start=start,part.end=end),(!segment.start||startaccuracy){let time;time=mediaIndexDiff<0?segment.start-sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:segmentInfo.mediaIndex,endIndex:segmentIndex}):segment.end+sumDurations({defaultDuration:playlist.targetDuration,durationList:playlist.segments,startIndex:segmentInfo.mediaIndex+1,endIndex:segmentIndex}),this.discontinuities[discontinuity]={time:time,accuracy:accuracy}}}}dispose(){this.trigger("dispose"),this.off()}}class TimelineChangeController extends videojs.EventTarget{constructor(){super(),this.pendingTimelineChanges_={},this.lastTimelineChanges_={}}clearPendingTimelineChange(type){this.pendingTimelineChanges_[type]=null,this.trigger("pendingtimelinechange")}pendingTimelineChange(_ref78){let{type:type,from:from,to:to}=_ref78;return"number"==typeof from&&"number"==typeof to&&(this.pendingTimelineChanges_[type]={type:type,from:from,to:to},this.trigger("pendingtimelinechange")),this.pendingTimelineChanges_[type]}lastTimelineChange(_ref79){let{type:type,from:from,to:to}=_ref79;return"number"==typeof from&&"number"==typeof to&&(this.lastTimelineChanges_[type]={type:type,from:from,to:to},delete this.pendingTimelineChanges_[type],this.trigger("timelinechange")),this.lastTimelineChanges_[type]}dispose(){this.trigger("dispose"),this.pendingTimelineChanges_={},this.lastTimelineChanges_={},this.off()}}const workerCode=transform(getWorkerString((function(){var Stream=function(){function Stream(){this.listeners={}}var _proto=Stream.prototype;return _proto.on=function(type,listener){this.listeners[type]||(this.listeners[type]=[]),this.listeners[type].push(listener)},_proto.off=function(type,listener){if(!this.listeners[type])return!1;var index=this.listeners[type].indexOf(listener);return this.listeners[type]=this.listeners[type].slice(0),this.listeners[type].splice(index,1),index>-1},_proto.trigger=function(type){var callbacks=this.listeners[type];if(callbacks)if(2===arguments.length)for(var length=callbacks.length,i=0;i>7))^i]=i;for(x=xInv=0;!sbox[x];x^=x2||1,xInv=th[xInv]||1)for(s=xInv^xInv<<1^xInv<<2^xInv<<3^xInv<<4,s=s>>8^255&s^99,sbox[x]=s,sboxInv[s]=x,x8=d[x4=d[x2=d[x]]],tDec=16843009*x8^65537*x4^257*x2^16843008*x,tEnc=257*d[s]^16843008*s,i=0;i<4;i++)encTable[i][x]=tEnc=tEnc<<24^tEnc>>>8,decTable[i][s]=tDec=tDec<<24^tDec>>>8;for(i=0;i<5;i++)encTable[i]=encTable[i].slice(0),decTable[i]=decTable[i].slice(0);return tables}()),this._tables=[[aesTables[0][0].slice(),aesTables[0][1].slice(),aesTables[0][2].slice(),aesTables[0][3].slice(),aesTables[0][4].slice()],[aesTables[1][0].slice(),aesTables[1][1].slice(),aesTables[1][2].slice(),aesTables[1][3].slice(),aesTables[1][4].slice()]];const sbox=this._tables[0][4],decTable=this._tables[1],keyLen=key.length;let rcon=1;if(4!==keyLen&&6!==keyLen&&8!==keyLen)throw new Error("Invalid aes key size");const encKey=key.slice(0),decKey=[];for(this._key=[encKey,decKey],i=keyLen;i<4*keyLen+28;i++)tmp=encKey[i-1],(i%keyLen==0||8===keyLen&&i%keyLen==4)&&(tmp=sbox[tmp>>>24]<<24^sbox[tmp>>16&255]<<16^sbox[tmp>>8&255]<<8^sbox[255&tmp],i%keyLen==0&&(tmp=tmp<<8^tmp>>>24^rcon<<24,rcon=rcon<<1^283*(rcon>>7))),encKey[i]=encKey[i-keyLen]^tmp;for(j=0;i;j++,i--)tmp=encKey[3&j?i:i-4],decKey[j]=i<=4||j<4?tmp:decTable[0][sbox[tmp>>>24]]^decTable[1][sbox[tmp>>16&255]]^decTable[2][sbox[tmp>>8&255]]^decTable[3][sbox[255&tmp]]}decrypt(encrypted0,encrypted1,encrypted2,encrypted3,out,offset){const key=this._key[1];let a2,b2,c2,a=encrypted0^key[0],b=encrypted3^key[1],c=encrypted2^key[2],d=encrypted1^key[3];const nInnerRounds=key.length/4-2;let i,kIndex=4;const table=this._tables[1],table0=table[0],table1=table[1],table2=table[2],table3=table[3],sbox=table[4];for(i=0;i>>24]^table1[b>>16&255]^table2[c>>8&255]^table3[255&d]^key[kIndex],b2=table0[b>>>24]^table1[c>>16&255]^table2[d>>8&255]^table3[255&a]^key[kIndex+1],c2=table0[c>>>24]^table1[d>>16&255]^table2[a>>8&255]^table3[255&b]^key[kIndex+2],d=table0[d>>>24]^table1[a>>16&255]^table2[b>>8&255]^table3[255&c]^key[kIndex+3],kIndex+=4,a=a2,b=b2,c=c2;for(i=0;i<4;i++)out[(3&-i)+offset]=sbox[a>>>24]<<24^sbox[b>>16&255]<<16^sbox[c>>8&255]<<8^sbox[255&d]^key[kIndex++],a2=a,a=b,b=c,c=d,d=a2}}class AsyncStream extends Stream{constructor(){super(Stream),this.jobs=[],this.delay=1,this.timeout_=null}processJob_(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null}push(job){this.jobs.push(job),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))}}const ntoh=function(word){return word<<24|(65280&word)<<8|(16711680&word)>>8|word>>>24};class Decrypter{constructor(encrypted,key,initVector,done){const step=Decrypter.STEP,encrypted32=new Int32Array(encrypted.buffer),decrypted=new Uint8Array(encrypted.byteLength);let i=0;for(this.asyncStream_=new AsyncStream,this.asyncStream_.push(this.decryptChunk_(encrypted32.subarray(i,i+step),key,initVector,decrypted)),i=step;i>2),decipher=new AES(Array.prototype.slice.call(key)),decrypted=new Uint8Array(encrypted.byteLength),decrypted32=new Int32Array(decrypted.buffer);let init0,init1,init2,init3,encrypted0,encrypted1,encrypted2,encrypted3,wordIx;for(init0=initVector[0],init1=initVector[1],init2=initVector[2],init3=initVector[3],wordIx=0;wordIx{const value=message[key];var obj;obj=value,("function"===ArrayBuffer.isView?ArrayBuffer.isView(obj):obj&&obj.buffer instanceof ArrayBuffer)?transferable[key]={bytes:value.buffer,byteOffset:value.byteOffset,byteLength:value.byteLength}:transferable[key]=value})),transferable};self.onmessage=function(event){const data=event.data,encrypted=new Uint8Array(data.encrypted.bytes,data.encrypted.byteOffset,data.encrypted.byteLength),key=new Uint32Array(data.key.bytes,data.key.byteOffset,data.key.byteLength/4),iv=new Uint32Array(data.iv.bytes,data.iv.byteOffset,data.iv.byteLength/4);new Decrypter(encrypted,key,iv,(function(err,bytes){self.postMessage(createTransferableMessage({source:data.source,decrypted:bytes}),[bytes.buffer])}))}})));var Decrypter=factory(workerCode);const audioTrackKind_=properties=>{let kind=properties.default?"main":"alternative";return properties.characteristics&&properties.characteristics.indexOf("public.accessibility.describes-video")>=0&&(kind="main-desc"),kind},stopLoaders=(segmentLoader,mediaType)=>{segmentLoader.abort(),segmentLoader.pause(),mediaType&&mediaType.activePlaylistLoader&&(mediaType.activePlaylistLoader.pause(),mediaType.activePlaylistLoader=null)},startLoaders=(playlistLoader,mediaType)=>{mediaType.activePlaylistLoader=playlistLoader,playlistLoader.load()},onError={AUDIO:(type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType},excludePlaylist:excludePlaylist}=settings;stopLoaders(segmentLoader,mediaType);const activeTrack=mediaType.activeTrack(),activeGroup=mediaType.activeGroup(),id=(activeGroup.filter((group=>group.default))[0]||activeGroup[0]).id,defaultTrack=mediaType.tracks[id];if(activeTrack!==defaultTrack){videojs.log.warn("Problem encountered loading the alternate audio track.Switching back to default.");for(const trackId in mediaType.tracks)mediaType.tracks[trackId].enabled=mediaType.tracks[trackId]===defaultTrack;mediaType.onTrackChanged()}else excludePlaylist({error:{message:"Problem encountered loading the default audio track."}})},SUBTITLES:(type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType}}=settings;videojs.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),stopLoaders(segmentLoader,mediaType);const track=mediaType.activeTrack();track&&(track.mode="disabled"),mediaType.onTrackChanged()}},setupListeners={AUDIO:(type,playlistLoader,settings)=>{if(!playlistLoader)return;const{tech:tech,requestOptions:requestOptions,segmentLoaders:{[type]:segmentLoader}}=settings;playlistLoader.on("loadedmetadata",(()=>{const media=playlistLoader.media();segmentLoader.playlist(media,requestOptions),(!tech.paused()||media.endList&&"none"!==tech.preload())&&segmentLoader.load()})),playlistLoader.on("loadedplaylist",(()=>{segmentLoader.playlist(playlistLoader.media(),requestOptions),tech.paused()||segmentLoader.load()})),playlistLoader.on("error",onError[type](type,settings))},SUBTITLES:(type,playlistLoader,settings)=>{const{tech:tech,requestOptions:requestOptions,segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType}}=settings;playlistLoader.on("loadedmetadata",(()=>{const media=playlistLoader.media();segmentLoader.playlist(media,requestOptions),segmentLoader.track(mediaType.activeTrack()),(!tech.paused()||media.endList&&"none"!==tech.preload())&&segmentLoader.load()})),playlistLoader.on("loadedplaylist",(()=>{segmentLoader.playlist(playlistLoader.media(),requestOptions),tech.paused()||segmentLoader.load()})),playlistLoader.on("error",onError[type](type,settings))}},initialize={AUDIO:(type,settings)=>{const{vhs:vhs,sourceType:sourceType,segmentLoaders:{[type]:segmentLoader},requestOptions:requestOptions,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks,logger_:logger_}},mainPlaylistLoader:mainPlaylistLoader}=settings,audioOnlyMain=isAudioOnly(mainPlaylistLoader.main);mediaGroups[type]&&0!==Object.keys(mediaGroups[type]).length||(mediaGroups[type]={main:{default:{default:!0}}},audioOnlyMain&&(mediaGroups[type].main.default.playlists=mainPlaylistLoader.main.playlists));for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){let playlistLoader,properties=mediaGroups[type][groupId][variantLabel];if(audioOnlyMain?(logger_("AUDIO group '".concat(groupId,"' label '").concat(variantLabel,"' is a main playlist")),properties.isMainPlaylist=!0,playlistLoader=null):playlistLoader="vhs-json"===sourceType&&properties.playlists?new PlaylistLoader(properties.playlists[0],vhs,requestOptions):properties.resolvedUri?new PlaylistLoader(properties.resolvedUri,vhs,requestOptions):properties.playlists&&"dash"===sourceType?new DashPlaylistLoader(properties.playlists[0],vhs,requestOptions,mainPlaylistLoader):null,properties=merge({id:variantLabel,playlistLoader:playlistLoader},properties),setupListeners[type](type,properties.playlistLoader,settings),groups[groupId].push(properties),void 0===tracks[variantLabel]){const track=new videojs.AudioTrack({id:variantLabel,kind:audioTrackKind_(properties),enabled:!1,language:properties.language,default:properties.default,label:variantLabel});tracks[variantLabel]=track}}}segmentLoader.on("error",onError[type](type,settings))},SUBTITLES:(type,settings)=>{const{tech:tech,vhs:vhs,sourceType:sourceType,segmentLoaders:{[type]:segmentLoader},requestOptions:requestOptions,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks}},mainPlaylistLoader:mainPlaylistLoader}=settings;for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){if(mediaGroups[type][groupId][variantLabel].forced)continue;let playlistLoader,properties=mediaGroups[type][groupId][variantLabel];if("hls"===sourceType)playlistLoader=new PlaylistLoader(properties.resolvedUri,vhs,requestOptions);else if("dash"===sourceType){if(!properties.playlists.filter((p=>p.excludeUntil!==1/0)).length)return;playlistLoader=new DashPlaylistLoader(properties.playlists[0],vhs,requestOptions,mainPlaylistLoader)}else"vhs-json"===sourceType&&(playlistLoader=new PlaylistLoader(properties.playlists?properties.playlists[0]:properties.resolvedUri,vhs,requestOptions));if(properties=merge({id:variantLabel,playlistLoader:playlistLoader},properties),setupListeners[type](type,properties.playlistLoader,settings),groups[groupId].push(properties),void 0===tracks[variantLabel]){const track=tech.addRemoteTextTrack({id:variantLabel,kind:"subtitles",default:properties.default&&properties.autoselect,language:properties.language,label:variantLabel},!1).track;tracks[variantLabel]=track}}}segmentLoader.on("error",onError[type](type,settings))},"CLOSED-CAPTIONS":(type,settings)=>{const{tech:tech,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks}}}=settings;for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){const properties=mediaGroups[type][groupId][variantLabel];if(!/^(?:CC|SERVICE)/.test(properties.instreamId))continue;const captionServices=tech.options_.vhs&&tech.options_.vhs.captionServices||{};let newProps={label:variantLabel,language:properties.language,instreamId:properties.instreamId,default:properties.default&&properties.autoselect};if(captionServices[newProps.instreamId]&&(newProps=merge(newProps,captionServices[newProps.instreamId])),void 0===newProps.default&&delete newProps.default,groups[groupId].push(merge({id:variantLabel},properties)),void 0===tracks[variantLabel]){const track=tech.addRemoteTextTrack({id:newProps.instreamId,kind:"captions",default:newProps.default,language:newProps.language,label:newProps.label},!1).track;tracks[variantLabel]=track}}}}},groupMatch=(list,media)=>{for(let i=0;i()=>{const{mediaTypes:{[type]:{tracks:tracks}}}=settings;for(const id in tracks)if(tracks[id].enabled)return tracks[id];return null},SUBTITLES:(type,settings)=>()=>{const{mediaTypes:{[type]:{tracks:tracks}}}=settings;for(const id in tracks)if("showing"===tracks[id].mode||"hidden"===tracks[id].mode)return tracks[id];return null}},setupMediaGroups=settings=>{["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((type=>{initialize[type](type,settings)}));const{mediaTypes:mediaTypes,mainPlaylistLoader:mainPlaylistLoader,tech:tech,vhs:vhs,segmentLoaders:{AUDIO:audioSegmentLoader,main:mainSegmentLoader}}=settings;["AUDIO","SUBTITLES"].forEach((type=>{mediaTypes[type].activeGroup=((type,settings)=>track=>{const{mainPlaylistLoader:mainPlaylistLoader,mediaTypes:{[type]:{groups:groups}}}=settings,media=mainPlaylistLoader.media();if(!media)return null;let variants=null;media.attributes[type]&&(variants=groups[media.attributes[type]]);const groupKeys=Object.keys(groups);if(!variants)if("AUDIO"===type&&groupKeys.length>1&&isAudioOnly(settings.main))for(let i=0;iprops.id===track.id))[0]||null})(type,settings),mediaTypes[type].activeTrack=activeTrack[type](type,settings),mediaTypes[type].onGroupChanged=((type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader,main:mainSegmentLoader},mediaTypes:{[type]:mediaType}}=settings,activeTrack=mediaType.activeTrack(),activeGroup=mediaType.getActiveGroup(),previousActiveLoader=mediaType.activePlaylistLoader,lastGroup=mediaType.lastGroup_;activeGroup&&lastGroup&&activeGroup.id===lastGroup.id||(mediaType.lastGroup_=activeGroup,mediaType.lastTrack_=activeTrack,stopLoaders(segmentLoader,mediaType),activeGroup&&!activeGroup.isMainPlaylist&&(activeGroup.playlistLoader?(segmentLoader.resyncLoader(),startLoaders(activeGroup.playlistLoader,mediaType)):previousActiveLoader&&mainSegmentLoader.resetEverything()))})(type,settings),mediaTypes[type].onGroupChanging=((type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType}}=settings;mediaType.lastGroup_=null,segmentLoader.abort(),segmentLoader.pause()})(type,settings),mediaTypes[type].onTrackChanged=((type,settings)=>()=>{const{mainPlaylistLoader:mainPlaylistLoader,segmentLoaders:{[type]:segmentLoader,main:mainSegmentLoader},mediaTypes:{[type]:mediaType}}=settings,activeTrack=mediaType.activeTrack(),activeGroup=mediaType.getActiveGroup(),previousActiveLoader=mediaType.activePlaylistLoader,lastTrack=mediaType.lastTrack_;if((!lastTrack||!activeTrack||lastTrack.id!==activeTrack.id)&&(mediaType.lastGroup_=activeGroup,mediaType.lastTrack_=activeTrack,stopLoaders(segmentLoader,mediaType),activeGroup)){if(activeGroup.isMainPlaylist){if(!activeTrack||!lastTrack||activeTrack.id===lastTrack.id)return;const pc=settings.vhs.playlistController_,newPlaylist=pc.selectPlaylist();if(pc.media()===newPlaylist)return;return mediaType.logger_("track change. Switching main audio from ".concat(lastTrack.id," to ").concat(activeTrack.id)),mainPlaylistLoader.pause(),mainSegmentLoader.resetEverything(),void pc.fastQualityChange_(newPlaylist)}if("AUDIO"===type){if(!activeGroup.playlistLoader)return mainSegmentLoader.setAudio(!0),void mainSegmentLoader.resetEverything();segmentLoader.setAudio(!0),mainSegmentLoader.setAudio(!1)}previousActiveLoader!==activeGroup.playlistLoader?(segmentLoader.track&&segmentLoader.track(activeTrack),segmentLoader.resetEverything(),startLoaders(activeGroup.playlistLoader,mediaType)):startLoaders(activeGroup.playlistLoader,mediaType)}})(type,settings),mediaTypes[type].getActiveGroup=((type,_ref76)=>{let{mediaTypes:mediaTypes}=_ref76;return()=>{const activeTrack_=mediaTypes[type].activeTrack();return activeTrack_?mediaTypes[type].activeGroup(activeTrack_):null}})(type,settings)}));const audioGroup=mediaTypes.AUDIO.activeGroup();if(audioGroup){const groupId=(audioGroup.filter((group=>group.default))[0]||audioGroup[0]).id;mediaTypes.AUDIO.tracks[groupId].enabled=!0,mediaTypes.AUDIO.onGroupChanged(),mediaTypes.AUDIO.onTrackChanged();mediaTypes.AUDIO.getActiveGroup().playlistLoader?(mainSegmentLoader.setAudio(!1),audioSegmentLoader.setAudio(!0)):mainSegmentLoader.setAudio(!0)}mainPlaylistLoader.on("mediachange",(()=>{["AUDIO","SUBTITLES"].forEach((type=>mediaTypes[type].onGroupChanged()))})),mainPlaylistLoader.on("mediachanging",(()=>{["AUDIO","SUBTITLES"].forEach((type=>mediaTypes[type].onGroupChanging()))}));const onAudioTrackChanged=()=>{mediaTypes.AUDIO.onTrackChanged(),tech.trigger({type:"usage",name:"vhs-audio-change"})};tech.audioTracks().addEventListener("change",onAudioTrackChanged),tech.remoteTextTracks().addEventListener("change",mediaTypes.SUBTITLES.onTrackChanged),vhs.on("dispose",(()=>{tech.audioTracks().removeEventListener("change",onAudioTrackChanged),tech.remoteTextTracks().removeEventListener("change",mediaTypes.SUBTITLES.onTrackChanged)})),tech.clearTracks("audio");for(const id in mediaTypes.AUDIO.tracks)tech.audioTracks().addTrack(mediaTypes.AUDIO.tracks[id])};let Vhs$1;const loaderStats=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred","mediaAppends"],sumLoaderStat=function(stat){return this.audioSegmentLoader_[stat]+this.mainSegmentLoader_[stat]};class PlaylistController extends videojs.EventTarget{constructor(options){super();const{src:src,withCredentials:withCredentials,tech:tech,bandwidth:bandwidth,externVhs:externVhs,useCueTags:useCueTags,playlistExclusionDuration:playlistExclusionDuration,enableLowInitialPlaylist:enableLowInitialPlaylist,sourceType:sourceType,cacheEncryptionKeys:cacheEncryptionKeys,bufferBasedABR:bufferBasedABR,leastPixelDiffSelector:leastPixelDiffSelector,captionServices:captionServices}=options;if(!src)throw new Error("A non-empty playlist URL or JSON manifest string is required");let{maxPlaylistRetries:maxPlaylistRetries}=options;null==maxPlaylistRetries&&(maxPlaylistRetries=1/0),Vhs$1=externVhs,this.bufferBasedABR=Boolean(bufferBasedABR),this.leastPixelDiffSelector=Boolean(leastPixelDiffSelector),this.withCredentials=withCredentials,this.tech_=tech,this.vhs_=tech.vhs,this.sourceType_=sourceType,this.useCueTags_=useCueTags,this.playlistExclusionDuration=playlistExclusionDuration,this.maxPlaylistRetries=maxPlaylistRetries,this.enableLowInitialPlaylist=enableLowInitialPlaylist,this.useCueTags_&&(this.cueTagsTrack_=this.tech_.addTextTrack("metadata","ad-cues"),this.cueTagsTrack_.inBandMetadataTrackDispatchType=""),this.requestOptions_={withCredentials:withCredentials,maxPlaylistRetries:maxPlaylistRetries,timeout:null},this.on("error",this.pauseLoading),this.mediaTypes_=(()=>{const mediaTypes={};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((type=>{mediaTypes[type]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:noop,activeTrack:noop,getActiveGroup:noop,onGroupChanged:noop,onTrackChanged:noop,lastTrack_:null,logger_:logger("MediaGroups[".concat(type,"]"))}})),mediaTypes})(),this.mediaSource=new window.MediaSource,this.handleDurationChange_=this.handleDurationChange_.bind(this),this.handleSourceOpen_=this.handleSourceOpen_.bind(this),this.handleSourceEnded_=this.handleSourceEnded_.bind(this),this.mediaSource.addEventListener("durationchange",this.handleDurationChange_),this.mediaSource.addEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.addEventListener("sourceended",this.handleSourceEnded_),this.seekable_=createTimeRanges(),this.hasPlayed_=!1,this.syncController_=new SyncController(options),this.segmentMetadataTrack_=tech.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,this.decrypter_=new Decrypter,this.sourceUpdater_=new SourceUpdater(this.mediaSource),this.inbandTextTracks_={},this.timelineChangeController_=new TimelineChangeController;const segmentLoaderSettings={vhs:this.vhs_,parse708captions:options.parse708captions,useDtsForTimestampOffset:options.useDtsForTimestampOffset,captionServices:captionServices,mediaSource:this.mediaSource,currentTime:this.tech_.currentTime.bind(this.tech_),seekable:()=>this.seekable(),seeking:()=>this.tech_.seeking(),duration:()=>this.duration(),hasPlayed:()=>this.hasPlayed_,goalBufferLength:()=>this.goalBufferLength(),bandwidth:bandwidth,syncController:this.syncController_,decrypter:this.decrypter_,sourceType:this.sourceType_,inbandTextTracks:this.inbandTextTracks_,cacheEncryptionKeys:cacheEncryptionKeys,sourceUpdater:this.sourceUpdater_,timelineChangeController:this.timelineChangeController_,exactManifestTimings:options.exactManifestTimings};this.mainPlaylistLoader_="dash"===this.sourceType_?new DashPlaylistLoader(src,this.vhs_,this.requestOptions_):new PlaylistLoader(src,this.vhs_,this.requestOptions_),this.setupMainPlaylistLoaderListeners_(),this.mainSegmentLoader_=new SegmentLoader(merge(segmentLoaderSettings,{segmentMetadataTrack:this.segmentMetadataTrack_,loaderType:"main"}),options),this.audioSegmentLoader_=new SegmentLoader(merge(segmentLoaderSettings,{loaderType:"audio"}),options),this.subtitleSegmentLoader_=new VTTSegmentLoader(merge(segmentLoaderSettings,{loaderType:"vtt",featuresNativeTextTracks:this.tech_.featuresNativeTextTracks,loadVttJs:()=>new Promise(((resolve,reject)=>{function onLoad(){tech.off("vttjserror",onError),resolve()}function onError(){tech.off("vttjsloaded",onLoad),reject()}tech.one("vttjsloaded",onLoad),tech.one("vttjserror",onError),tech.addWebVttScript_()}))}),options),this.setupSegmentLoaderListeners_(),this.bufferBasedABR&&(this.mainPlaylistLoader_.one("loadedplaylist",(()=>this.startABRTimer_())),this.tech_.on("pause",(()=>this.stopABRTimer_())),this.tech_.on("play",(()=>this.startABRTimer_()))),loaderStats.forEach((stat=>{this[stat+"_"]=sumLoaderStat.bind(this,stat)})),this.logger_=logger("pc"),this.triggeredFmp4Usage=!1,"none"===this.tech_.preload()?(this.loadOnPlay_=()=>{this.loadOnPlay_=null,this.mainPlaylistLoader_.load()},this.tech_.one("play",this.loadOnPlay_)):this.mainPlaylistLoader_.load(),this.timeToLoadedData__=-1,this.mainAppendsToLoadedData__=-1,this.audioAppendsToLoadedData__=-1;const event="none"===this.tech_.preload()?"play":"loadstart";this.tech_.one(event,(()=>{const timeToLoadedDataStart=Date.now();this.tech_.one("loadeddata",(()=>{this.timeToLoadedData__=Date.now()-timeToLoadedDataStart,this.mainAppendsToLoadedData__=this.mainSegmentLoader_.mediaAppends,this.audioAppendsToLoadedData__=this.audioSegmentLoader_.mediaAppends}))}))}mainAppendsToLoadedData_(){return this.mainAppendsToLoadedData__}audioAppendsToLoadedData_(){return this.audioAppendsToLoadedData__}appendsToLoadedData_(){const main=this.mainAppendsToLoadedData_(),audio=this.audioAppendsToLoadedData_();return-1===main||-1===audio?-1:main+audio}timeToLoadedData_(){return this.timeToLoadedData__}checkABR_(){let reason=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"abr";const nextPlaylist=this.selectPlaylist();nextPlaylist&&this.shouldSwitchToMedia_(nextPlaylist)&&this.switchMedia_(nextPlaylist,reason)}switchMedia_(playlist,cause,delay){const oldMedia=this.media(),oldId=oldMedia&&(oldMedia.id||oldMedia.uri),newId=playlist.id||playlist.uri;oldId&&oldId!==newId&&(this.logger_("switch media ".concat(oldId," -> ").concat(newId," from ").concat(cause)),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-".concat(cause)})),this.mainPlaylistLoader_.media(playlist,delay)}startABRTimer_(){this.stopABRTimer_(),this.abrTimer_=window.setInterval((()=>this.checkABR_()),250)}stopABRTimer_(){this.tech_.scrubbing&&this.tech_.scrubbing()||(window.clearInterval(this.abrTimer_),this.abrTimer_=null)}getAudioTrackPlaylists_(){const main=this.main(),defaultPlaylists=main&&main.playlists||[];if(!main||!main.mediaGroups||!main.mediaGroups.AUDIO)return defaultPlaylists;const AUDIO=main.mediaGroups.AUDIO,groupKeys=Object.keys(AUDIO);let track;if(Object.keys(this.mediaTypes_.AUDIO.groups).length)track=this.mediaTypes_.AUDIO.activeTrack();else{const defaultGroup=AUDIO.main||groupKeys.length&&AUDIO[groupKeys[0]];for(const label in defaultGroup)if(defaultGroup[label].default){track={label:label};break}}if(!track)return defaultPlaylists;const playlists=[];for(const group in AUDIO)if(AUDIO[group][track.label]){const properties=AUDIO[group][track.label];if(properties.playlists&&properties.playlists.length)playlists.push.apply(playlists,properties.playlists);else if(properties.uri)playlists.push(properties);else if(main.playlists.length)for(let i=0;i{const media=this.mainPlaylistLoader_.media(),requestTimeout=1.5*media.targetDuration*1e3;isLowestEnabledRendition(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.media())?this.requestOptions_.timeout=0:this.requestOptions_.timeout=requestTimeout,media.endList&&"none"!==this.tech_.preload()&&(this.mainSegmentLoader_.playlist(media,this.requestOptions_),this.mainSegmentLoader_.load()),setupMediaGroups({sourceType:this.sourceType_,segmentLoaders:{AUDIO:this.audioSegmentLoader_,SUBTITLES:this.subtitleSegmentLoader_,main:this.mainSegmentLoader_},tech:this.tech_,requestOptions:this.requestOptions_,mainPlaylistLoader:this.mainPlaylistLoader_,vhs:this.vhs_,main:this.main(),mediaTypes:this.mediaTypes_,excludePlaylist:this.excludePlaylist.bind(this)}),this.triggerPresenceUsage_(this.main(),media),this.setupFirstPlay(),!this.mediaTypes_.AUDIO.activePlaylistLoader||this.mediaTypes_.AUDIO.activePlaylistLoader.media()?this.trigger("selectedinitialmedia"):this.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",(()=>{this.trigger("selectedinitialmedia")}))})),this.mainPlaylistLoader_.on("loadedplaylist",(()=>{this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_);let updatedPlaylist=this.mainPlaylistLoader_.media();if(!updatedPlaylist){let selectedMedia;if(this.excludeUnsupportedVariants_(),this.enableLowInitialPlaylist&&(selectedMedia=this.selectInitialPlaylist()),selectedMedia||(selectedMedia=this.selectPlaylist()),!selectedMedia||!this.shouldSwitchToMedia_(selectedMedia))return;this.initialMedia_=selectedMedia,this.switchMedia_(this.initialMedia_,"initial");if(!("vhs-json"===this.sourceType_&&this.initialMedia_.segments))return;updatedPlaylist=this.initialMedia_}this.handleUpdatedMediaPlaylist(updatedPlaylist)})),this.mainPlaylistLoader_.on("error",(()=>{const error=this.mainPlaylistLoader_.error;this.excludePlaylist({playlistToExclude:error.playlist,error:error})})),this.mainPlaylistLoader_.on("mediachanging",(()=>{this.mainSegmentLoader_.abort(),this.mainSegmentLoader_.pause()})),this.mainPlaylistLoader_.on("mediachange",(()=>{const media=this.mainPlaylistLoader_.media(),requestTimeout=1.5*media.targetDuration*1e3;isLowestEnabledRendition(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.media())?this.requestOptions_.timeout=0:this.requestOptions_.timeout=requestTimeout,this.mainPlaylistLoader_.load(),this.mainSegmentLoader_.playlist(media,this.requestOptions_),this.mainSegmentLoader_.load(),this.tech_.trigger({type:"mediachange",bubbles:!0})})),this.mainPlaylistLoader_.on("playlistunchanged",(()=>{const updatedPlaylist=this.mainPlaylistLoader_.media();if("playlist-unchanged"===updatedPlaylist.lastExcludeReason_)return;this.stuckAtPlaylistEnd_(updatedPlaylist)&&(this.excludePlaylist({error:{message:"Playlist no longer updating.",reason:"playlist-unchanged"}}),this.tech_.trigger("playliststuck"))})),this.mainPlaylistLoader_.on("renditiondisabled",(()=>{this.tech_.trigger({type:"usage",name:"vhs-rendition-disabled"})})),this.mainPlaylistLoader_.on("renditionenabled",(()=>{this.tech_.trigger({type:"usage",name:"vhs-rendition-enabled"})}))}handleUpdatedMediaPlaylist(updatedPlaylist){this.useCueTags_&&this.updateAdCues_(updatedPlaylist),this.mainSegmentLoader_.playlist(updatedPlaylist,this.requestOptions_),this.updateDuration(!updatedPlaylist.endList),this.tech_.paused()||(this.mainSegmentLoader_.load(),this.audioSegmentLoader_&&this.audioSegmentLoader_.load())}triggerPresenceUsage_(main,media){const mediaGroups=main.mediaGroups||{};let defaultDemuxed=!0;const audioGroupKeys=Object.keys(mediaGroups.AUDIO);for(const mediaGroup in mediaGroups.AUDIO)for(const label in mediaGroups.AUDIO[mediaGroup]){mediaGroups.AUDIO[mediaGroup][label].uri||(defaultDemuxed=!1)}defaultDemuxed&&this.tech_.trigger({type:"usage",name:"vhs-demuxed"}),Object.keys(mediaGroups.SUBTITLES).length&&this.tech_.trigger({type:"usage",name:"vhs-webvtt"}),Vhs$1.Playlist.isAes(media)&&this.tech_.trigger({type:"usage",name:"vhs-aes"}),audioGroupKeys.length&&Object.keys(mediaGroups.AUDIO[audioGroupKeys[0]]).length>1&&this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.useCueTags_&&this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"})}shouldSwitchToMedia_(nextPlaylist){const currentPlaylist=this.mainPlaylistLoader_.media()||this.mainPlaylistLoader_.pendingMedia_,currentTime=this.tech_.currentTime(),bufferLowWaterLine=this.bufferLowWaterLine(),bufferHighWaterLine=this.bufferHighWaterLine();return function(_ref77){let{currentPlaylist:currentPlaylist,buffered:buffered,currentTime:currentTime,nextPlaylist:nextPlaylist,bufferLowWaterLine:bufferLowWaterLine,bufferHighWaterLine:bufferHighWaterLine,duration:duration,bufferBasedABR:bufferBasedABR,log:log}=_ref77;if(!nextPlaylist)return videojs.log.warn("We received no playlist to switch to. Please check your stream."),!1;const sharedLogLine="allowing switch ".concat(currentPlaylist&¤tPlaylist.id||"null"," -> ").concat(nextPlaylist.id);if(!currentPlaylist)return log("".concat(sharedLogLine," as current playlist is not set")),!0;if(nextPlaylist.id===currentPlaylist.id)return!1;const isBuffered=Boolean(findRange(buffered,currentTime).length);if(!currentPlaylist.endList)return isBuffered||"number"!=typeof currentPlaylist.partTargetDuration?(log("".concat(sharedLogLine," as current playlist is live")),!0):(log("not ".concat(sharedLogLine," as current playlist is live llhls, but currentTime isn't in buffered.")),!1);const forwardBuffer=timeAheadOf(buffered,currentTime),maxBufferLowWaterLine=bufferBasedABR?Config.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:Config.MAX_BUFFER_LOW_WATER_LINE;if(durationcurrBandwidth)&&forwardBuffer>=bufferLowWaterLine){let logLine="".concat(sharedLogLine," as forwardBuffer >= bufferLowWaterLine (").concat(forwardBuffer," >= ").concat(bufferLowWaterLine,")");return bufferBasedABR&&(logLine+=" and next bandwidth > current bandwidth (".concat(nextBandwidth," > ").concat(currBandwidth,")")),log(logLine),!0}return log("not ".concat(sharedLogLine," as no switching criteria met")),!1}({buffered:this.tech_.buffered(),currentTime:currentTime,currentPlaylist:currentPlaylist,nextPlaylist:nextPlaylist,bufferLowWaterLine:bufferLowWaterLine,bufferHighWaterLine:bufferHighWaterLine,duration:this.duration(),bufferBasedABR:this.bufferBasedABR,log:this.logger_})}setupSegmentLoaderListeners_(){this.mainSegmentLoader_.on("bandwidthupdate",(()=>{this.checkABR_("bandwidthupdate"),this.tech_.trigger("bandwidthupdate")})),this.mainSegmentLoader_.on("timeout",(()=>{this.bufferBasedABR&&this.mainSegmentLoader_.load()})),this.bufferBasedABR||this.mainSegmentLoader_.on("progress",(()=>{this.trigger("progress")})),this.mainSegmentLoader_.on("error",(()=>{const error=this.mainSegmentLoader_.error();this.excludePlaylist({playlistToExclude:error.playlist,error:error})})),this.mainSegmentLoader_.on("appenderror",(()=>{this.error=this.mainSegmentLoader_.error_,this.trigger("error")})),this.mainSegmentLoader_.on("syncinfoupdate",(()=>{this.onSyncInfoUpdate_()})),this.mainSegmentLoader_.on("timestampoffset",(()=>{this.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"})})),this.audioSegmentLoader_.on("syncinfoupdate",(()=>{this.onSyncInfoUpdate_()})),this.audioSegmentLoader_.on("appenderror",(()=>{this.error=this.audioSegmentLoader_.error_,this.trigger("error")})),this.mainSegmentLoader_.on("ended",(()=>{this.logger_("main segment loader ended"),this.onEndOfStream()})),this.mainSegmentLoader_.on("earlyabort",(event=>{this.bufferBasedABR||(this.delegateLoaders_("all",["abort"]),this.excludePlaylist({error:{message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},playlistExclusionDuration:120}))}));const updateCodecs=()=>{if(!this.sourceUpdater_.hasCreatedSourceBuffers())return this.tryToCreateSourceBuffers_();const codecs=this.getCodecsOrExclude_();codecs&&this.sourceUpdater_.addOrChangeSourceBuffers(codecs)};this.mainSegmentLoader_.on("trackinfo",updateCodecs),this.audioSegmentLoader_.on("trackinfo",updateCodecs),this.mainSegmentLoader_.on("fmp4",(()=>{this.triggeredFmp4Usage||(this.tech_.trigger({type:"usage",name:"vhs-fmp4"}),this.triggeredFmp4Usage=!0)})),this.audioSegmentLoader_.on("fmp4",(()=>{this.triggeredFmp4Usage||(this.tech_.trigger({type:"usage",name:"vhs-fmp4"}),this.triggeredFmp4Usage=!0)})),this.audioSegmentLoader_.on("ended",(()=>{this.logger_("audioSegmentLoader ended"),this.onEndOfStream()}))}mediaSecondsLoaded_(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)}load(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()}fastQualityChange_(){let media=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectPlaylist();media!==this.mainPlaylistLoader_.media()?(this.switchMedia_(media,"fast-quality"),this.mainSegmentLoader_.resetEverything((()=>{videojs.browser.IE_VERSION||videojs.browser.IS_EDGE?this.tech_.setCurrentTime(this.tech_.currentTime()+.04):this.tech_.setCurrentTime(this.tech_.currentTime())}))):this.logger_("skipping fastQualityChange because new media is same as old")}play(){if(this.setupFirstPlay())return;this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();const seekable=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime(){this.trigger("firstplay"),this.tech_.setCurrentTime(seekable.end(0)),this.hasPlayed_=!0})),!1;this.trigger("firstplay"),this.tech_.setCurrentTime(seekable.end(0))}return this.hasPlayed_=!0,this.load(),!0}handleSourceOpen_(){if(this.tryToCreateSourceBuffers_(),this.tech_.autoplay()){const playPromise=this.tech_.play();void 0!==playPromise&&"function"==typeof playPromise.then&&playPromise.then(null,(e=>{}))}this.trigger("sourceopen")}handleSourceEnded_(){if(!this.inbandTextTracks_.metadataTrack_)return;const cues=this.inbandTextTracks_.metadataTrack_.cues;if(!cues||!cues.length)return;const duration=this.duration();cues[cues.length-1].endTime=isNaN(duration)||Math.abs(duration)===1/0?Number.MAX_VALUE:duration}handleDurationChange_(){this.tech_.trigger("durationchange")}onEndOfStream(){let isEndOfStream=this.mainSegmentLoader_.ended_;if(this.mediaTypes_.AUDIO.activePlaylistLoader){const mainMediaInfo=this.mainSegmentLoader_.getCurrentMediaInfo_();isEndOfStream=!mainMediaInfo||mainMediaInfo.hasVideo?isEndOfStream&&this.audioSegmentLoader_.ended_:this.audioSegmentLoader_.ended_}isEndOfStream&&(this.stopABRTimer_(),this.sourceUpdater_.endOfStream())}stuckAtPlaylistEnd_(playlist){if(!this.seekable().length)return!1;const expired=this.syncController_.getExpiredTime(playlist,this.duration());if(null===expired)return!1;const absolutePlaylistEnd=Vhs$1.Playlist.playlistEnd(playlist,expired),currentTime=this.tech_.currentTime(),buffered=this.tech_.buffered();if(!buffered.length)return absolutePlaylistEnd-currentTime<=.1;const bufferedEnd=buffered.end(buffered.length-1);return bufferedEnd-currentTime<=.1&&absolutePlaylistEnd-bufferedEnd<=.1}excludePlaylist(_ref78){let{playlistToExclude:playlistToExclude=this.mainPlaylistLoader_.media(),error:error={},playlistExclusionDuration:playlistExclusionDuration}=_ref78;if(playlistToExclude=playlistToExclude||this.mainPlaylistLoader_.media(),playlistExclusionDuration=playlistExclusionDuration||error.playlistExclusionDuration||this.playlistExclusionDuration,!playlistToExclude)return this.error=error,void("open"!==this.mediaSource.readyState?this.trigger("error"):this.sourceUpdater_.endOfStream("network"));playlistToExclude.playlistErrors_++;const playlists=this.mainPlaylistLoader_.main.playlists,enabledPlaylists=playlists.filter(isEnabled),isFinalRendition=1===enabledPlaylists.length&&enabledPlaylists[0]===playlistToExclude;if(1===playlists.length&&playlistExclusionDuration!==1/0)return videojs.log.warn("Problem encountered with playlist ".concat(playlistToExclude.id,". ")+"Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.mainPlaylistLoader_.load(isFinalRendition);if(isFinalRendition){let reincluded=!1;playlists.forEach((playlist=>{if(playlist===playlistToExclude)return;const excludeUntil=playlist.excludeUntil;void 0!==excludeUntil&&excludeUntil!==1/0&&(reincluded=!0,delete playlist.excludeUntil)})),reincluded&&(videojs.log.warn("Removing other playlists from the exclusion list because the last rendition is about to be excluded."),this.tech_.trigger("retryplaylist"))}let excludeUntil;excludeUntil=playlistToExclude.playlistErrors_>this.maxPlaylistRetries?1/0:Date.now()+1e3*playlistExclusionDuration,playlistToExclude.excludeUntil=excludeUntil,error.reason&&(playlistToExclude.lastExcludeReason_=error.reason),this.tech_.trigger("excludeplaylist"),this.tech_.trigger({type:"usage",name:"vhs-rendition-excluded"});const nextPlaylist=this.selectPlaylist();if(!nextPlaylist)return this.error="Playback cannot continue. No available working or supported playlists.",void this.trigger("error");const logFn=error.internal?this.logger_:videojs.log.warn,errorMessage=error.message?" "+error.message:"";logFn("".concat(error.internal?"Internal problem":"Problem"," encountered with playlist ").concat(playlistToExclude.id,".")+"".concat(errorMessage," Switching to playlist ").concat(nextPlaylist.id,".")),nextPlaylist.attributes.AUDIO!==playlistToExclude.attributes.AUDIO&&this.delegateLoaders_("audio",["abort","pause"]),nextPlaylist.attributes.SUBTITLES!==playlistToExclude.attributes.SUBTITLES&&this.delegateLoaders_("subtitle",["abort","pause"]),this.delegateLoaders_("main",["abort","pause"]);const delayDuration=nextPlaylist.targetDuration/2*1e3||5e3,shouldDelay="number"==typeof nextPlaylist.lastRequest&&Date.now()-nextPlaylist.lastRequest<=delayDuration;return this.switchMedia_(nextPlaylist,"exclude",isFinalRendition||shouldDelay)}pauseLoading(){this.delegateLoaders_("all",["abort","pause"]),this.stopABRTimer_()}delegateLoaders_(filter,fnNames){const loaders=[],dontFilterPlaylist="all"===filter;(dontFilterPlaylist||"main"===filter)&&loaders.push(this.mainPlaylistLoader_);const mediaTypes=[];(dontFilterPlaylist||"audio"===filter)&&mediaTypes.push("AUDIO"),(dontFilterPlaylist||"subtitle"===filter)&&(mediaTypes.push("CLOSED-CAPTIONS"),mediaTypes.push("SUBTITLES")),mediaTypes.forEach((mediaType=>{const loader=this.mediaTypes_[mediaType]&&this.mediaTypes_[mediaType].activePlaylistLoader;loader&&loaders.push(loader)})),["main","audio","subtitle"].forEach((name=>{const loader=this["".concat(name,"SegmentLoader_")];!loader||filter!==name&&"all"!==filter||loaders.push(loader)})),loaders.forEach((loader=>fnNames.forEach((fnName=>{"function"==typeof loader[fnName]&&loader[fnName]()}))))}setCurrentTime(currentTime){const buffered=findRange(this.tech_.buffered(),currentTime);return this.mainPlaylistLoader_&&this.mainPlaylistLoader_.media()&&this.mainPlaylistLoader_.media().segments?buffered&&buffered.length?currentTime:(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}duration(){if(!this.mainPlaylistLoader_)return 0;const media=this.mainPlaylistLoader_.media();return media?media.endList?this.mediaSource?this.mediaSource.duration:Vhs$1.Playlist.duration(media):1/0:0}seekable(){return this.seekable_}onSyncInfoUpdate_(){let audioSeekable;if(!this.mainPlaylistLoader_)return;let media=this.mainPlaylistLoader_.media();if(!media)return;let expired=this.syncController_.getExpiredTime(media,this.duration());if(null===expired)return;const main=this.mainPlaylistLoader_.main,mainSeekable=Vhs$1.Playlist.seekable(media,expired,Vhs$1.Playlist.liveEdgeDelay(main,media));if(0===mainSeekable.length)return;if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(media=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),expired=this.syncController_.getExpiredTime(media,this.duration()),null===expired)return;if(audioSeekable=Vhs$1.Playlist.seekable(media,expired,Vhs$1.Playlist.liveEdgeDelay(main,media)),0===audioSeekable.length)return}let oldEnd,oldStart;this.seekable_&&this.seekable_.length&&(oldEnd=this.seekable_.end(0),oldStart=this.seekable_.start(0)),audioSeekable?audioSeekable.start(0)>mainSeekable.end(0)||mainSeekable.start(0)>audioSeekable.end(0)?this.seekable_=mainSeekable:this.seekable_=createTimeRanges([[audioSeekable.start(0)>mainSeekable.start(0)?audioSeekable.start(0):mainSeekable.start(0),audioSeekable.end(0)0&&(duration=Math.max(duration,buffered.end(buffered.length-1))),this.mediaSource.duration!==duration&&this.sourceUpdater_.setDuration(duration)}dispose(){this.trigger("dispose"),this.decrypter_.terminate(),this.mainPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach((type=>{const groups=this.mediaTypes_[type].groups;for(const id in groups)groups[id].forEach((group=>{group.playlistLoader&&group.playlistLoader.dispose()}))})),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off()}main(){return this.mainPlaylistLoader_.main}media(){return this.mainPlaylistLoader_.media()||this.initialMedia_}areMediaTypesKnown_(){const usingAudioLoader=!!this.mediaTypes_.AUDIO.activePlaylistLoader,hasMainMediaInfo=!!this.mainSegmentLoader_.getCurrentMediaInfo_(),hasAudioMediaInfo=!usingAudioLoader||!!this.audioSegmentLoader_.getCurrentMediaInfo_();return!(!hasMainMediaInfo||!hasAudioMediaInfo)}getCodecsOrExclude_(){const media={main:this.mainSegmentLoader_.getCurrentMediaInfo_()||{},audio:this.audioSegmentLoader_.getCurrentMediaInfo_()||{}},playlist=this.mainSegmentLoader_.getPendingSegmentPlaylist()||this.media();media.video=media.main;const playlistCodecs=codecsForPlaylist(this.main(),playlist),codecs={},usingAudioLoader=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(media.main.hasVideo&&(codecs.video=playlistCodecs.video||media.main.videoCodec||"avc1.4d400d"),media.main.isMuxed&&(codecs.video+=",".concat(playlistCodecs.audio||media.main.audioCodec||"mp4a.40.2")),(media.main.hasAudio&&!media.main.isMuxed||media.audio.hasAudio||usingAudioLoader)&&(codecs.audio=playlistCodecs.audio||media.main.audioCodec||media.audio.audioCodec||"mp4a.40.2",media.audio.isFmp4=media.main.hasAudio&&!media.main.isMuxed?media.main.isFmp4:media.audio.isFmp4),!codecs.audio&&!codecs.video)return void this.excludePlaylist({playlistToExclude:playlist,error:{message:"Could not determine codecs for playlist."},playlistExclusionDuration:1/0});const unsupportedCodecs={};let unsupportedAudio;if(["video","audio"].forEach((function(type){if(codecs.hasOwnProperty(type)&&(isFmp4=media[type].isFmp4,codec=codecs[type],!(isFmp4?browserSupportsCodec(codec):muxerSupportsCodec(codec)))){const supporter=media[type].isFmp4?"browser":"muxer";unsupportedCodecs[supporter]=unsupportedCodecs[supporter]||[],unsupportedCodecs[supporter].push(codecs[type]),"audio"===type&&(unsupportedAudio=supporter)}var isFmp4,codec})),usingAudioLoader&&unsupportedAudio&&playlist.attributes.AUDIO){const audioGroup=playlist.attributes.AUDIO;this.main().playlists.forEach((variant=>{(variant.attributes&&variant.attributes.AUDIO)===audioGroup&&variant!==playlist&&(variant.excludeUntil=1/0)})),this.logger_("excluding audio group ".concat(audioGroup," as ").concat(unsupportedAudio,' does not support codec(s): "').concat(codecs.audio,'"'))}if(!Object.keys(unsupportedCodecs).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){const switchMessages=[];if(["video","audio"].forEach((type=>{const newCodec=(parseCodecs(this.sourceUpdater_.codecs[type]||"")[0]||{}).type,oldCodec=(parseCodecs(codecs[type]||"")[0]||{}).type;newCodec&&oldCodec&&newCodec.toLowerCase()!==oldCodec.toLowerCase()&&switchMessages.push('"'.concat(this.sourceUpdater_.codecs[type],'" -> "').concat(codecs[type],'"'))})),switchMessages.length)return void this.excludePlaylist({playlistToExclude:playlist,error:{message:"Codec switching not supported: ".concat(switchMessages.join(", "),"."),internal:!0},playlistExclusionDuration:1/0})}return codecs}{const message=Object.keys(unsupportedCodecs).reduce(((acc,supporter)=>(acc&&(acc+=", "),acc+="".concat(supporter,' does not support codec(s): "').concat(unsupportedCodecs[supporter].join(","),'"'))),"")+".";this.excludePlaylist({playlistToExclude:playlist,error:{internal:!0,message:message},playlistExclusionDuration:1/0})}}tryToCreateSourceBuffers_(){if("open"!==this.mediaSource.readyState||this.sourceUpdater_.hasCreatedSourceBuffers())return;if(!this.areMediaTypesKnown_())return;const codecs=this.getCodecsOrExclude_();if(!codecs)return;this.sourceUpdater_.createSourceBuffers(codecs);const codecString=[codecs.video,codecs.audio].filter(Boolean).join(",");this.excludeIncompatibleVariants_(codecString)}excludeUnsupportedVariants_(){const playlists=this.main().playlists,ids=[];Object.keys(playlists).forEach((key=>{const variant=playlists[key];if(-1!==ids.indexOf(variant.id))return;ids.push(variant.id);const codecs=codecsForPlaylist(this.main,variant),unsupported=[];!codecs.audio||muxerSupportsCodec(codecs.audio)||browserSupportsCodec(codecs.audio)||unsupported.push("audio codec ".concat(codecs.audio)),!codecs.video||muxerSupportsCodec(codecs.video)||browserSupportsCodec(codecs.video)||unsupported.push("video codec ".concat(codecs.video)),codecs.text&&"stpp.ttml.im1t"===codecs.text&&unsupported.push("text codec ".concat(codecs.text)),unsupported.length&&(variant.excludeUntil=1/0,this.logger_("excluding ".concat(variant.id," for unsupported: ").concat(unsupported.join(", "))))}))}excludeIncompatibleVariants_(codecString){const ids=[],playlists=this.main().playlists,codecs=unwrapCodecList(parseCodecs(codecString)),codecCount_=codecCount(codecs),videoDetails=codecs.video&&parseCodecs(codecs.video)[0]||null,audioDetails=codecs.audio&&parseCodecs(codecs.audio)[0]||null;Object.keys(playlists).forEach((key=>{const variant=playlists[key];if(-1!==ids.indexOf(variant.id)||variant.excludeUntil===1/0)return;ids.push(variant.id);const exclusionReasons=[],variantCodecs=codecsForPlaylist(this.mainPlaylistLoader_.main,variant),variantCodecCount=codecCount(variantCodecs);if(variantCodecs.audio||variantCodecs.video){if(variantCodecCount!==codecCount_&&exclusionReasons.push('codec count "'.concat(variantCodecCount,'" !== "').concat(codecCount_,'"')),!this.sourceUpdater_.canChangeType()){const variantVideoDetails=variantCodecs.video&&parseCodecs(variantCodecs.video)[0]||null,variantAudioDetails=variantCodecs.audio&&parseCodecs(variantCodecs.audio)[0]||null;variantVideoDetails&&videoDetails&&variantVideoDetails.type.toLowerCase()!==videoDetails.type.toLowerCase()&&exclusionReasons.push('video codec "'.concat(variantVideoDetails.type,'" !== "').concat(videoDetails.type,'"')),variantAudioDetails&&audioDetails&&variantAudioDetails.type.toLowerCase()!==audioDetails.type.toLowerCase()&&exclusionReasons.push('audio codec "'.concat(variantAudioDetails.type,'" !== "').concat(audioDetails.type,'"'))}exclusionReasons.length&&(variant.excludeUntil=1/0,this.logger_("excluding ".concat(variant.id,": ").concat(exclusionReasons.join(" && "))))}}))}updateAdCues_(media){let offset=0;const seekable=this.seekable();seekable.length&&(offset=seekable.start(0)),function(media,track){let offset=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(!media.segments)return;let cue,mediaTime=offset;for(let i=0;i{const playlist=loader.main.playlists[playlistID],incompatible=isIncompatible(playlist),currentlyEnabled=isEnabled(playlist);return void 0===enable?currentlyEnabled:(enable?delete playlist.disabled:playlist.disabled=!0,enable===currentlyEnabled||incompatible||(changePlaylistFn(),enable?loader.trigger("renditionenabled"):loader.trigger("renditiondisabled")),enable)})}}const timerCancelEvents=["seeking","seeked","pause","playing","error"];class PlaybackWatcher{constructor(options){this.playlistController_=options.playlistController,this.tech_=options.tech,this.seekable=options.seekable,this.allowSeeksWithinUnsafeLiveWindow=options.allowSeeksWithinUnsafeLiveWindow,this.liveRangeSafeTimeDelta=options.liveRangeSafeTimeDelta,this.media=options.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.checkCurrentTimeTimeout_=null,this.logger_=logger("PlaybackWatcher"),this.logger_("initialize");const playHandler=()=>this.monitorCurrentTime_(),canPlayHandler=()=>this.monitorCurrentTime_(),waitingHandler=()=>this.techWaiting_(),cancelTimerHandler=()=>this.resetTimeUpdate_(),pc=this.playlistController_,loaderTypes=["main","subtitle","audio"],loaderChecks={};loaderTypes.forEach((type=>{loaderChecks[type]={reset:()=>this.resetSegmentDownloads_(type),updateend:()=>this.checkSegmentDownloads_(type)},pc["".concat(type,"SegmentLoader_")].on("appendsdone",loaderChecks[type].updateend),pc["".concat(type,"SegmentLoader_")].on("playlistupdate",loaderChecks[type].reset),this.tech_.on(["seeked","seeking"],loaderChecks[type].reset)}));const setSeekingHandlers=fn=>{["main","audio"].forEach((type=>{pc["".concat(type,"SegmentLoader_")][fn]("appended",this.seekingAppendCheck_)}))};this.seekingAppendCheck_=()=>{this.fixesBadSeeks_()&&(this.consecutiveUpdates=0,this.lastRecordedTime=this.tech_.currentTime(),setSeekingHandlers("off"))},this.clearSeekingAppendCheck_=()=>setSeekingHandlers("off"),this.watchForBadSeeking_=()=>{this.clearSeekingAppendCheck_(),setSeekingHandlers("on")},this.tech_.on("seeked",this.clearSeekingAppendCheck_),this.tech_.on("seeking",this.watchForBadSeeking_),this.tech_.on("waiting",waitingHandler),this.tech_.on(timerCancelEvents,cancelTimerHandler),this.tech_.on("canplay",canPlayHandler),this.tech_.one("play",playHandler),this.dispose=()=>{this.clearSeekingAppendCheck_(),this.logger_("dispose"),this.tech_.off("waiting",waitingHandler),this.tech_.off(timerCancelEvents,cancelTimerHandler),this.tech_.off("canplay",canPlayHandler),this.tech_.off("play",playHandler),this.tech_.off("seeking",this.watchForBadSeeking_),this.tech_.off("seeked",this.clearSeekingAppendCheck_),loaderTypes.forEach((type=>{pc["".concat(type,"SegmentLoader_")].off("appendsdone",loaderChecks[type].updateend),pc["".concat(type,"SegmentLoader_")].off("playlistupdate",loaderChecks[type].reset),this.tech_.off(["seeked","seeking"],loaderChecks[type].reset)})),this.checkCurrentTimeTimeout_&&window.clearTimeout(this.checkCurrentTimeTimeout_),this.resetTimeUpdate_()}}monitorCurrentTime_(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&window.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=window.setTimeout(this.monitorCurrentTime_.bind(this),250)}resetSegmentDownloads_(type){const loader=this.playlistController_["".concat(type,"SegmentLoader_")];this["".concat(type,"StalledDownloads_")]>0&&this.logger_("resetting possible stalled download count for ".concat(type," loader")),this["".concat(type,"StalledDownloads_")]=0,this["".concat(type,"Buffered_")]=loader.buffered_()}checkSegmentDownloads_(type){const pc=this.playlistController_,loader=pc["".concat(type,"SegmentLoader_")],buffered=loader.buffered_(),isBufferedDifferent=function(a,b){if(a===b)return!1;if(!a&&b||!b&&a)return!0;if(a.length!==b.length)return!0;for(let i=0;i=buffered.end(buffered.length-1)))return this.techWaiting_();this.consecutiveUpdates>=5&¤tTime===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):currentTime===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=currentTime)}resetTimeUpdate_(){this.consecutiveUpdates=0}fixesBadSeeks_(){if(!this.tech_.seeking())return!1;const seekable=this.seekable(),currentTime=this.tech_.currentTime();let seekTo;if(this.afterSeekableWindow_(seekable,currentTime,this.media(),this.allowSeeksWithinUnsafeLiveWindow)){seekTo=seekable.end(seekable.length-1)}if(this.beforeSeekableWindow_(seekable,currentTime)){const seekableStart=seekable.start(0);seekTo=seekableStart+(seekableStart===seekable.end(0)?0:.1)}if(void 0!==seekTo)return this.logger_("Trying to seek outside of seekable at time ".concat(currentTime," with ")+"seekable range ".concat(printableRange(seekable),". Seeking to ")+"".concat(seekTo,".")),this.tech_.setCurrentTime(seekTo),!0;const sourceUpdater=this.playlistController_.sourceUpdater_,buffered=this.tech_.buffered(),audioBuffered=sourceUpdater.audioBuffer?sourceUpdater.audioBuffered():null,videoBuffered=sourceUpdater.videoBuffer?sourceUpdater.videoBuffered():null,media=this.media(),minAppendedDuration=media.partTargetDuration?media.partTargetDuration:2*(media.targetDuration-.03333333333333333),bufferedToCheck=[audioBuffered,videoBuffered];for(let i=0;i ").concat(currentRange.end(0),"]. Attempting to resume ")+"playback by seeking to the current time."),void this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"})):void 0}techWaiting_(){const seekable=this.seekable(),currentTime=this.tech_.currentTime();if(this.tech_.seeking())return!0;if(this.beforeSeekableWindow_(seekable,currentTime)){const livePoint=seekable.end(seekable.length-1);return this.logger_("Fell out of live window at time ".concat(currentTime,". Seeking to ")+"live point (seekable end) ".concat(livePoint)),this.resetTimeUpdate_(),this.tech_.setCurrentTime(livePoint),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),!0}const sourceUpdater=this.tech_.vhs.playlistController_.sourceUpdater_,buffered=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:sourceUpdater.audioBuffered(),videoBuffered:sourceUpdater.videoBuffered(),currentTime:currentTime}))return this.resetTimeUpdate_(),this.tech_.setCurrentTime(currentTime),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),!0;const nextRange=findNextRange(buffered,currentTime);return nextRange.length>0&&(this.logger_("Stopped at ".concat(currentTime," and seeking to ").concat(nextRange.start(0))),this.resetTimeUpdate_(),this.skipTheGap_(currentTime),!0)}afterSeekableWindow_(seekable,currentTime,playlist){let allowSeeksWithinUnsafeLiveWindow=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!seekable.length)return!1;let allowedEnd=seekable.end(seekable.length-1)+.1;return!playlist.endList&&allowSeeksWithinUnsafeLiveWindow&&(allowedEnd=seekable.end(seekable.length-1)+3*playlist.targetDuration),currentTime>allowedEnd}beforeSeekableWindow_(seekable,currentTime){return!!(seekable.length&&seekable.start(0)>0&¤tTime2)return{start:start,end:end}}return null}}const defaultOptions={errorInterval:30,getSource(next){return next(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},initPlugin=function(player,options){let lastCalled=0,seekTo=0;const localOptions=merge(defaultOptions,options);player.ready((()=>{player.trigger({type:"usage",name:"vhs-error-reload-initialized"})}));const loadedMetadataHandler=function(){seekTo&&player.currentTime(seekTo)},setSource=function(sourceObj){null!=sourceObj&&(seekTo=player.duration()!==1/0&&player.currentTime()||0,player.one("loadedmetadata",loadedMetadataHandler),player.src(sourceObj),player.trigger({type:"usage",name:"vhs-error-reload"}),player.play())},errorHandler=function(){if(Date.now()-lastCalled<1e3*localOptions.errorInterval)player.trigger({type:"usage",name:"vhs-error-reload-canceled"});else{if(localOptions.getSource&&"function"==typeof localOptions.getSource)return lastCalled=Date.now(),localOptions.getSource.call(player,setSource);videojs.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}},cleanupEvents=function(){player.off("loadedmetadata",loadedMetadataHandler),player.off("error",errorHandler),player.off("dispose",cleanupEvents)};player.on("error",errorHandler),player.on("dispose",cleanupEvents),player.reloadSourceOnError=function(newOptions){cleanupEvents(),initPlugin(player,newOptions)}},reloadSourceOnError=function(options){initPlugin(this,options)};const Vhs={PlaylistLoader:PlaylistLoader,Playlist:Playlist,utils:utils,STANDARD_PLAYLIST_SELECTOR:lastBandwidthSelector,INITIAL_PLAYLIST_SELECTOR:function(){const playlists=this.playlists.main.playlists.filter(Playlist.isEnabled);stableSort(playlists,((a,b)=>comparePlaylistBandwidth(a,b)));return playlists.filter((playlist=>!!codecsForPlaylist(this.playlists.main,playlist).video))[0]||null},lastBandwidthSelector:lastBandwidthSelector,movingAverageBandwidthSelector:function(decay){let average=-1,lastSystemBandwidth=-1;if(decay<0||decay>1)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){const pixelRatio=this.useDevicePixelRatio&&window.devicePixelRatio||1;return average<0&&(average=this.systemBandwidth,lastSystemBandwidth=this.systemBandwidth),this.systemBandwidth>0&&this.systemBandwidth!==lastSystemBandwidth&&(average=decay*this.systemBandwidth+(1-decay)*average,lastSystemBandwidth=this.systemBandwidth),simpleSelector(this.playlists.main,average,parseInt(safeGetComputedStyle(this.tech_.el(),"width"),10)*pixelRatio,parseInt(safeGetComputedStyle(this.tech_.el(),"height"),10)*pixelRatio,this.limitRenditionByPlayerDimensions,this.playlistController_)}},comparePlaylistBandwidth:comparePlaylistBandwidth,comparePlaylistResolution:function(left,right){let leftWidth,rightWidth;return left.attributes.RESOLUTION&&left.attributes.RESOLUTION.width&&(leftWidth=left.attributes.RESOLUTION.width),leftWidth=leftWidth||window.Number.MAX_VALUE,right.attributes.RESOLUTION&&right.attributes.RESOLUTION.width&&(rightWidth=right.attributes.RESOLUTION.width),rightWidth=rightWidth||window.Number.MAX_VALUE,leftWidth===rightWidth&&left.attributes.BANDWIDTH&&right.attributes.BANDWIDTH?left.attributes.BANDWIDTH-right.attributes.BANDWIDTH:leftWidth-rightWidth},xhr:xhrFactory()};Object.keys(Config).forEach((prop=>{Object.defineProperty(Vhs,prop,{get:()=>(videojs.log.warn("using Vhs.".concat(prop," is UNSAFE be sure you know what you are doing")),Config[prop]),set(value){videojs.log.warn("using Vhs.".concat(prop," is UNSAFE be sure you know what you are doing")),"number"!=typeof value||value<0?videojs.log.warn("value of Vhs.".concat(prop," must be greater than or equal to 0")):Config[prop]=value}})}));const handleVhsMediaChange=function(qualityLevels,playlistLoader){const newPlaylist=playlistLoader.media();let selectedIndex=-1;for(let i=0;i{let{player:player,sourceKeySystems:sourceKeySystems,audioMedia:audioMedia,mainPlaylists:mainPlaylists}=_ref80;if(!player.eme.initializeMediaKeys)return Promise.resolve();const keySystemsOptionsArr=((playlists,keySystems)=>playlists.reduce(((keySystemsArr,playlist)=>{if(!playlist.contentProtection)return keySystemsArr;const keySystemsOptions=keySystems.reduce(((keySystemsObj,keySystem)=>{const keySystemOptions=playlist.contentProtection[keySystem];return keySystemOptions&&keySystemOptions.pssh&&(keySystemsObj[keySystem]={pssh:keySystemOptions.pssh}),keySystemsObj}),{});return Object.keys(keySystemsOptions).length&&keySystemsArr.push(keySystemsOptions),keySystemsArr}),[]))(audioMedia?mainPlaylists.concat([audioMedia]):mainPlaylists,Object.keys(sourceKeySystems)),initializationFinishedPromises=[],keySessionCreatedPromises=[];return keySystemsOptionsArr.forEach((keySystemsOptions=>{keySessionCreatedPromises.push(new Promise(((resolve,reject)=>{player.tech_.one("keysessioncreated",resolve)}))),initializationFinishedPromises.push(new Promise(((resolve,reject)=>{player.eme.initializeMediaKeys({keySystems:keySystemsOptions},(err=>{err?reject(err):resolve()}))})))})),Promise.race([Promise.all(initializationFinishedPromises),Promise.race(keySessionCreatedPromises)])},setupEmeOptions=_ref81=>{let{player:player,sourceKeySystems:sourceKeySystems,media:media,audioMedia:audioMedia}=_ref81;const sourceOptions=((keySystemOptions,mainPlaylist,audioPlaylist)=>{if(!keySystemOptions)return keySystemOptions;let codecs={};mainPlaylist&&mainPlaylist.attributes&&mainPlaylist.attributes.CODECS&&(codecs=unwrapCodecList(parseCodecs(mainPlaylist.attributes.CODECS))),audioPlaylist&&audioPlaylist.attributes&&audioPlaylist.attributes.CODECS&&(codecs.audio=audioPlaylist.attributes.CODECS);const videoContentType=getMimeForCodec(codecs.video),audioContentType=getMimeForCodec(codecs.audio),keySystemContentTypes={};for(const keySystem in keySystemOptions)keySystemContentTypes[keySystem]={},audioContentType&&(keySystemContentTypes[keySystem].audioContentType=audioContentType),videoContentType&&(keySystemContentTypes[keySystem].videoContentType=videoContentType),mainPlaylist.contentProtection&&mainPlaylist.contentProtection[keySystem]&&mainPlaylist.contentProtection[keySystem].pssh&&(keySystemContentTypes[keySystem].pssh=mainPlaylist.contentProtection[keySystem].pssh),"string"==typeof keySystemOptions[keySystem]&&(keySystemContentTypes[keySystem].url=keySystemOptions[keySystem]);return merge(keySystemOptions,keySystemContentTypes)})(sourceKeySystems,media,audioMedia);return!!sourceOptions&&(player.currentSource().keySystems=sourceOptions,!(sourceOptions&&!player.eme)||(videojs.log.warn("DRM encrypted source cannot be decrypted without a DRM plugin"),!1))},getVhsLocalStorage=()=>{if(!window.localStorage)return null;const storedObject=window.localStorage.getItem("videojs-vhs");if(!storedObject)return null;try{return JSON.parse(storedObject)}catch(e){return null}};Vhs.supportsNativeHls=function(){if(!document||!document.createElement)return!1;const video=document.createElement("video");if(!videojs.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(canItPlay){return/maybe|probably/i.test(video.canPlayType(canItPlay))}))}(),Vhs.supportsNativeDash=!!(document&&document.createElement&&videojs.getTech("Html5").isSupported())&&/maybe|probably/i.test(document.createElement("video").canPlayType("application/dash+xml")),Vhs.supportsTypeNatively=type=>"hls"===type?Vhs.supportsNativeHls:"dash"===type&&Vhs.supportsNativeDash,Vhs.isSupported=function(){return videojs.log.warn("VHS is no longer a tech. Please remove it from your player's techOrder.")};const Component=videojs.getComponent("Component");class VhsHandler extends Component{constructor(source,tech,options){if(super(tech,options.vhs),"number"==typeof options.initialBandwidth&&(this.options_.bandwidth=options.initialBandwidth),this.logger_=logger("VhsHandler"),tech.options_&&tech.options_.playerId){const _player=videojs.getPlayer(tech.options_.playerId);this.player_=_player}if(this.tech_=tech,this.source_=source,this.stats={},this.ignoreNextSeekingEvent_=!1,this.setOptions_(),this.options_.overrideNative&&tech.overrideNativeAudioTracks&&tech.overrideNativeVideoTracks)tech.overrideNativeAudioTracks(!0),tech.overrideNativeVideoTracks(!0);else if(this.options_.overrideNative&&(tech.featuresNativeVideoTracks||tech.featuresNativeAudioTracks))throw new Error("Overriding native VHS requires emulated tracks. See https://git.io/vMpjB");this.on(document,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],(event=>{const fullscreenElement=document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement;fullscreenElement&&fullscreenElement.contains(this.tech_.el())?this.playlistController_.fastQualityChange_():this.playlistController_.checkABR_()})),this.on(this.tech_,"seeking",(function(){this.ignoreNextSeekingEvent_?this.ignoreNextSeekingEvent_=!1:this.setCurrentTime(this.tech_.currentTime())})),this.on(this.tech_,"error",(function(){this.tech_.error()&&this.playlistController_&&this.playlistController_.pauseLoading()})),this.on(this.tech_,"play",this.play)}setOptions_(){if(this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.useDevicePixelRatio=this.options_.useDevicePixelRatio||!1,this.options_.useBandwidthFromLocalStorage=void 0!==this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.useNetworkInformationApi=this.options_.useNetworkInformationApi||!1,this.options_.useDtsForTimestampOffset=this.options_.useDtsForTimestampOffset||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,this.options_.llhls=!1!==this.options_.llhls,this.options_.bufferBasedABR=this.options_.bufferBasedABR||!1,"number"!=typeof this.options_.playlistExclusionDuration&&(this.options_.playlistExclusionDuration=300),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage){const storedObject=getVhsLocalStorage();storedObject&&storedObject.bandwidth&&(this.options_.bandwidth=storedObject.bandwidth,this.tech_.trigger({type:"usage",name:"vhs-bandwidth-from-local-storage"})),storedObject&&storedObject.throughput&&(this.options_.throughput=storedObject.throughput,this.tech_.trigger({type:"usage",name:"vhs-throughput-from-local-storage"}))}"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=Config.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===Config.INITIAL_BANDWIDTH,["withCredentials","useDevicePixelRatio","limitRenditionByPlayerDimensions","bandwidth","customTagParsers","customTagMappers","cacheEncryptionKeys","playlistSelector","initialPlaylistSelector","bufferBasedABR","liveRangeSafeTimeDelta","llhls","useNetworkInformationApi","useDtsForTimestampOffset","exactManifestTimings","leastPixelDiffSelector"].forEach((option=>{void 0!==this.source_[option]&&(this.options_[option]=this.source_[option])})),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions,this.useDevicePixelRatio=this.options_.useDevicePixelRatio}src(src,type){if(!src)return;var dataUri;this.setOptions_(),this.options_.src=0===(dataUri=this.source_.src).toLowerCase().indexOf("data:application/vnd.videojs.vhs+json,")?JSON.parse(dataUri.substring(dataUri.indexOf(",")+1)):dataUri,this.options_.tech=this.tech_,this.options_.externVhs=Vhs,this.options_.sourceType=simpleTypeFromSourceType(type),this.options_.seekTo=time=>{this.tech_.setCurrentTime(time)},this.playlistController_=new PlaylistController(this.options_);const playbackWatcherOptions=merge({liveRangeSafeTimeDelta:.1},this.options_,{seekable:()=>this.seekable(),media:()=>this.playlistController_.media(),playlistController:this.playlistController_});this.playbackWatcher_=new PlaybackWatcher(playbackWatcherOptions),this.playlistController_.on("error",(()=>{const player=videojs.players[this.tech_.options_.playerId];let error=this.playlistController_.error;"object"!=typeof error||error.code?"string"==typeof error&&(error={message:error,code:3}):error.code=3,player.error(error)}));const defaultSelector=this.options_.bufferBasedABR?Vhs.movingAverageBandwidthSelector(.55):Vhs.STANDARD_PLAYLIST_SELECTOR;this.playlistController_.selectPlaylist=this.selectPlaylist?this.selectPlaylist.bind(this):defaultSelector.bind(this),this.playlistController_.selectInitialPlaylist=Vhs.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.playlistController_.mainPlaylistLoader_,this.mediaSource=this.playlistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get(){return this.playlistController_.selectPlaylist},set(selectPlaylist){this.playlistController_.selectPlaylist=selectPlaylist.bind(this)}},throughput:{get(){return this.playlistController_.mainSegmentLoader_.throughput.rate},set(throughput){this.playlistController_.mainSegmentLoader_.throughput.rate=throughput,this.playlistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get(){let playerBandwidthEst=this.playlistController_.mainSegmentLoader_.bandwidth;const networkInformation=window.navigator.connection||window.navigator.mozConnection||window.navigator.webkitConnection;if(this.options_.useNetworkInformationApi&&networkInformation){const networkInfoBandwidthEstBitsPerSec=1e3*networkInformation.downlink*1e3;playerBandwidthEst=networkInfoBandwidthEstBitsPerSec>=1e7&&playerBandwidthEst>=1e7?Math.max(playerBandwidthEst,networkInfoBandwidthEstBitsPerSec):networkInfoBandwidthEstBitsPerSec}return playerBandwidthEst},set(bandwidth){this.playlistController_.mainSegmentLoader_.bandwidth=bandwidth,this.playlistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get(){const invBandwidth=1/(this.bandwidth||1);let invThroughput;invThroughput=this.throughput>0?1/this.throughput:0;return Math.floor(1/(invBandwidth+invThroughput))},set(){videojs.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:()=>this.bandwidth||0,enumerable:!0},mediaRequests:{get:()=>this.playlistController_.mediaRequests_()||0,enumerable:!0},mediaRequestsAborted:{get:()=>this.playlistController_.mediaRequestsAborted_()||0,enumerable:!0},mediaRequestsTimedout:{get:()=>this.playlistController_.mediaRequestsTimedout_()||0,enumerable:!0},mediaRequestsErrored:{get:()=>this.playlistController_.mediaRequestsErrored_()||0,enumerable:!0},mediaTransferDuration:{get:()=>this.playlistController_.mediaTransferDuration_()||0,enumerable:!0},mediaBytesTransferred:{get:()=>this.playlistController_.mediaBytesTransferred_()||0,enumerable:!0},mediaSecondsLoaded:{get:()=>this.playlistController_.mediaSecondsLoaded_()||0,enumerable:!0},mediaAppends:{get:()=>this.playlistController_.mediaAppends_()||0,enumerable:!0},mainAppendsToLoadedData:{get:()=>this.playlistController_.mainAppendsToLoadedData_()||0,enumerable:!0},audioAppendsToLoadedData:{get:()=>this.playlistController_.audioAppendsToLoadedData_()||0,enumerable:!0},appendsToLoadedData:{get:()=>this.playlistController_.appendsToLoadedData_()||0,enumerable:!0},timeToLoadedData:{get:()=>this.playlistController_.timeToLoadedData_()||0,enumerable:!0},buffered:{get:()=>timeRangesToArray(this.tech_.buffered()),enumerable:!0},currentTime:{get:()=>this.tech_.currentTime(),enumerable:!0},currentSource:{get:()=>this.tech_.currentSource_,enumerable:!0},currentTech:{get:()=>this.tech_.name_,enumerable:!0},duration:{get:()=>this.tech_.duration(),enumerable:!0},main:{get:()=>this.playlists.main,enumerable:!0},playerDimensions:{get:()=>this.tech_.currentDimensions(),enumerable:!0},seekable:{get:()=>timeRangesToArray(this.tech_.seekable()),enumerable:!0},timestamp:{get:()=>Date.now(),enumerable:!0},videoPlaybackQuality:{get:()=>this.tech_.getVideoPlaybackQuality(),enumerable:!0}}),this.tech_.one("canplay",this.playlistController_.setupFirstPlay.bind(this.playlistController_)),this.tech_.on("bandwidthupdate",(()=>{this.options_.useBandwidthFromLocalStorage&&(options=>{if(!window.localStorage)return!1;let objectToStore=getVhsLocalStorage();objectToStore=objectToStore?merge(objectToStore,options):options;try{window.localStorage.setItem("videojs-vhs",JSON.stringify(objectToStore))}catch(e){return!1}})({bandwidth:this.bandwidth,throughput:Math.round(this.throughput)})})),this.playlistController_.on("selectedinitialmedia",(()=>{var vhsHandler;(vhsHandler=this).representations=()=>{const main=vhsHandler.playlistController_.main(),playlists=isAudioOnly(main)?vhsHandler.playlistController_.getAudioTrackPlaylists_():main.playlists;return playlists?playlists.filter((media=>!isIncompatible(media))).map(((e,i)=>new Representation(vhsHandler,e,e.id))):[]}})),this.playlistController_.sourceUpdater_.on("createdsourcebuffers",(()=>{this.setupEme_()})),this.on(this.playlistController_,"progress",(function(){this.tech_.trigger("progress")})),this.on(this.playlistController_,"firstplay",(function(){this.ignoreNextSeekingEvent_=!0})),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=window.URL.createObjectURL(this.playlistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_))}createKeySessions_(){const audioPlaylistLoader=this.playlistController_.mediaTypes_.AUDIO.activePlaylistLoader;this.logger_("waiting for EME key session creation"),waitForKeySessionCreation({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:audioPlaylistLoader&&audioPlaylistLoader.media(),mainPlaylists:this.playlists.main.playlists}).then((()=>{this.logger_("created EME key session"),this.playlistController_.sourceUpdater_.initializedEme()})).catch((err=>{this.logger_("error while creating EME key session",err),this.player_.error({message:"Failed to initialize media keys for EME",code:3})}))}handleWaitingForKey_(){this.logger_("waitingforkey fired, attempting to create any new key sessions"),this.createKeySessions_()}setupEme_(){const audioPlaylistLoader=this.playlistController_.mediaTypes_.AUDIO.activePlaylistLoader,didSetupEmeOptions=setupEmeOptions({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:audioPlaylistLoader&&audioPlaylistLoader.media()});this.player_.tech_.on("keystatuschange",(e=>{if("output-restricted"!==e.status)return;const mainPlaylist=this.playlistController_.main();if(!mainPlaylist||!mainPlaylist.playlists)return;const excludedHDPlaylists=[];mainPlaylist.playlists.forEach((playlist=>{playlist&&playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.height>=720&&(!playlist.excludeUntil||playlist.excludeUntil<1/0)&&(playlist.excludeUntil=1/0,excludedHDPlaylists.push(playlist))})),excludedHDPlaylists.length&&(videojs.log.warn('DRM keystatus changed to "output-restricted." Removing the following HD playlists that will most likely fail to play and clearing the buffer. This may be due to HDCP restrictions on the stream and the capabilities of the current device.',...excludedHDPlaylists),this.playlistController_.fastQualityChange_())})),this.handleWaitingForKey_=this.handleWaitingForKey_.bind(this),this.player_.tech_.on("waitingforkey",this.handleWaitingForKey_),11!==videojs.browser.IE_VERSION&&didSetupEmeOptions?this.createKeySessions_():this.playlistController_.sourceUpdater_.initializedEme()}setupQualityLevels_(){const player=videojs.players[this.tech_.options_.playerId];player&&player.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=player.qualityLevels(),this.playlistController_.on("selectedinitialmedia",(()=>{var qualityLevels,vhs;qualityLevels=this.qualityLevels_,(vhs=this).representations().forEach((rep=>{qualityLevels.addQualityLevel(rep)})),handleVhsMediaChange(qualityLevels,vhs.playlists)})),this.playlists.on("mediachange",(()=>{handleVhsMediaChange(this.qualityLevels_,this.playlists)})))}static version(){return{"@videojs/http-streaming":"3.0.2","mux.js":"6.3.0","mpd-parser":"1.0.1","m3u8-parser":"6.0.0","aes-decrypter":"4.0.1"}}version(){return this.constructor.version()}canChangeType(){return SourceUpdater.canChangeType()}play(){this.playlistController_.play()}setCurrentTime(currentTime){this.playlistController_.setCurrentTime(currentTime)}duration(){return this.playlistController_.duration()}seekable(){return this.playlistController_.seekable()}dispose(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.playlistController_&&this.playlistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.mediaSourceUrl_&&window.URL.revokeObjectURL&&(window.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),this.tech_&&this.tech_.off("waitingforkey",this.handleWaitingForKey_),super.dispose()}convertToProgramTime(time,callback){return getProgramTime({playlist:this.playlistController_.media(),time:time,callback:callback})}seekToProgramTime(programTime,callback){let pauseAfterSeek=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],retryCount=arguments.length>3&&void 0!==arguments[3]?arguments[3]:2;return seekToProgramTime({programTime:programTime,playlist:this.playlistController_.media(),retryCount:retryCount,pauseAfterSeek:pauseAfterSeek,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:callback})}}const VhsSourceHandler={name:"videojs-http-streaming",VERSION:"3.0.2",canHandleSource(srcObj){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const localOptions=merge(videojs.options,options);return VhsSourceHandler.canPlayType(srcObj.type,localOptions)},handleSource(source,tech){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const localOptions=merge(videojs.options,options);return tech.vhs=new VhsHandler(source,tech,localOptions),tech.vhs.xhr=xhrFactory(),tech.vhs.src(source.src,source.type),tech.vhs},canPlayType(type,options){const simpleType=simpleTypeFromSourceType(type);if(!simpleType)return"";const overrideNative=VhsSourceHandler.getOverrideNative(options);return!Vhs.supportsTypeNatively(simpleType)||overrideNative?"maybe":""},getOverrideNative(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{vhs:vhs={}}=options,defaultOverrideNative=!(videojs.browser.IS_ANY_SAFARI||videojs.browser.IS_IOS),{overrideNative:overrideNative=defaultOverrideNative}=vhs;return overrideNative}};return browserSupportsCodec("avc1.4d400d,mp4a.40.2")&&videojs.getTech("Html5").registerSourceHandler(VhsSourceHandler,0),videojs.VhsHandler=VhsHandler,videojs.VhsSourceHandler=VhsSourceHandler,videojs.Vhs=Vhs,videojs.use||videojs.registerComponent("Vhs",Vhs),videojs.options.vhs=videojs.options.vhs||{},videojs.getPlugin&&videojs.getPlugin("reloadSourceOnError")||videojs.registerPlugin("reloadSourceOnError",reloadSourceOnError),videojs})); +/*! @name aes-decrypter @version 4.0.1 @license Apache-2.0 */done(null,(padded=decrypted).subarray(0,padded.byteLength-padded[padded.byteLength-1]))}))}static get STEP(){return 32e3}decryptChunk_(encrypted,key,initVector,decrypted){return function(){const bytes=function(encrypted,key,initVector){const encrypted32=new Int32Array(encrypted.buffer,encrypted.byteOffset,encrypted.byteLength>>2),decipher=new AES(Array.prototype.slice.call(key)),decrypted=new Uint8Array(encrypted.byteLength),decrypted32=new Int32Array(decrypted.buffer);let init0,init1,init2,init3,encrypted0,encrypted1,encrypted2,encrypted3,wordIx;for(init0=initVector[0],init1=initVector[1],init2=initVector[2],init3=initVector[3],wordIx=0;wordIx{const value=message[key];var obj;obj=value,("function"===ArrayBuffer.isView?ArrayBuffer.isView(obj):obj&&obj.buffer instanceof ArrayBuffer)?transferable[key]={bytes:value.buffer,byteOffset:value.byteOffset,byteLength:value.byteLength}:transferable[key]=value})),transferable};self.onmessage=function(event){const data=event.data,encrypted=new Uint8Array(data.encrypted.bytes,data.encrypted.byteOffset,data.encrypted.byteLength),key=new Uint32Array(data.key.bytes,data.key.byteOffset,data.key.byteLength/4),iv=new Uint32Array(data.iv.bytes,data.iv.byteOffset,data.iv.byteLength/4);new Decrypter(encrypted,key,iv,(function(err,bytes){self.postMessage(createTransferableMessage({source:data.source,decrypted:bytes}),[bytes.buffer])}))}})));var Decrypter=factory(workerCode);const audioTrackKind_=properties=>{let kind=properties.default?"main":"alternative";return properties.characteristics&&properties.characteristics.indexOf("public.accessibility.describes-video")>=0&&(kind="main-desc"),kind},stopLoaders=(segmentLoader,mediaType)=>{segmentLoader.abort(),segmentLoader.pause(),mediaType&&mediaType.activePlaylistLoader&&(mediaType.activePlaylistLoader.pause(),mediaType.activePlaylistLoader=null)},startLoaders=(playlistLoader,mediaType)=>{mediaType.activePlaylistLoader=playlistLoader,playlistLoader.load()},onError={AUDIO:(type,settings)=>()=>{const{mediaTypes:{[type]:mediaType},excludePlaylist:excludePlaylist}=settings,activeTrack=mediaType.activeTrack(),activeGroup=mediaType.activeGroup(),id=(activeGroup.filter((group=>group.default))[0]||activeGroup[0]).id,defaultTrack=mediaType.tracks[id];if(activeTrack!==defaultTrack){videojs.log.warn("Problem encountered loading the alternate audio track.Switching back to default.");for(const trackId in mediaType.tracks)mediaType.tracks[trackId].enabled=mediaType.tracks[trackId]===defaultTrack;mediaType.onTrackChanged()}else excludePlaylist({error:{message:"Problem encountered loading the default audio track."}})},SUBTITLES:(type,settings)=>()=>{const{mediaTypes:{[type]:mediaType}}=settings;videojs.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track.");const track=mediaType.activeTrack();track&&(track.mode="disabled"),mediaType.onTrackChanged()}},setupListeners={AUDIO:(type,playlistLoader,settings)=>{if(!playlistLoader)return;const{tech:tech,requestOptions:requestOptions,segmentLoaders:{[type]:segmentLoader}}=settings;playlistLoader.on("loadedmetadata",(()=>{const media=playlistLoader.media();segmentLoader.playlist(media,requestOptions),(!tech.paused()||media.endList&&"none"!==tech.preload())&&segmentLoader.load()})),playlistLoader.on("loadedplaylist",(()=>{segmentLoader.playlist(playlistLoader.media(),requestOptions),tech.paused()||segmentLoader.load()})),playlistLoader.on("error",onError[type](type,settings))},SUBTITLES:(type,playlistLoader,settings)=>{const{tech:tech,requestOptions:requestOptions,segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType}}=settings;playlistLoader.on("loadedmetadata",(()=>{const media=playlistLoader.media();segmentLoader.playlist(media,requestOptions),segmentLoader.track(mediaType.activeTrack()),(!tech.paused()||media.endList&&"none"!==tech.preload())&&segmentLoader.load()})),playlistLoader.on("loadedplaylist",(()=>{segmentLoader.playlist(playlistLoader.media(),requestOptions),tech.paused()||segmentLoader.load()})),playlistLoader.on("error",onError[type](type,settings))}},initialize={AUDIO:(type,settings)=>{const{vhs:vhs,sourceType:sourceType,segmentLoaders:{[type]:segmentLoader},requestOptions:requestOptions,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks,logger_:logger_}},mainPlaylistLoader:mainPlaylistLoader}=settings,audioOnlyMain=isAudioOnly(mainPlaylistLoader.main);mediaGroups[type]&&0!==Object.keys(mediaGroups[type]).length||(mediaGroups[type]={main:{default:{default:!0}}},audioOnlyMain&&(mediaGroups[type].main.default.playlists=mainPlaylistLoader.main.playlists));for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){let playlistLoader,properties=mediaGroups[type][groupId][variantLabel];if(audioOnlyMain?(logger_("AUDIO group '".concat(groupId,"' label '").concat(variantLabel,"' is a main playlist")),properties.isMainPlaylist=!0,playlistLoader=null):playlistLoader="vhs-json"===sourceType&&properties.playlists?new PlaylistLoader(properties.playlists[0],vhs,requestOptions):properties.resolvedUri?new PlaylistLoader(properties.resolvedUri,vhs,requestOptions):properties.playlists&&"dash"===sourceType?new DashPlaylistLoader(properties.playlists[0],vhs,requestOptions,mainPlaylistLoader):null,properties=merge({id:variantLabel,playlistLoader:playlistLoader},properties),setupListeners[type](type,properties.playlistLoader,settings),groups[groupId].push(properties),void 0===tracks[variantLabel]){const track=new videojs.AudioTrack({id:variantLabel,kind:audioTrackKind_(properties),enabled:!1,language:properties.language,default:properties.default,label:variantLabel});tracks[variantLabel]=track}}}segmentLoader.on("error",onError[type](type,settings))},SUBTITLES:(type,settings)=>{const{tech:tech,vhs:vhs,sourceType:sourceType,segmentLoaders:{[type]:segmentLoader},requestOptions:requestOptions,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks}},mainPlaylistLoader:mainPlaylistLoader}=settings;for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){if(!vhs.options_.useForcedSubtitles&&mediaGroups[type][groupId][variantLabel].forced)continue;let playlistLoader,properties=mediaGroups[type][groupId][variantLabel];if("hls"===sourceType)playlistLoader=new PlaylistLoader(properties.resolvedUri,vhs,requestOptions);else if("dash"===sourceType){if(!properties.playlists.filter((p=>p.excludeUntil!==1/0)).length)return;playlistLoader=new DashPlaylistLoader(properties.playlists[0],vhs,requestOptions,mainPlaylistLoader)}else"vhs-json"===sourceType&&(playlistLoader=new PlaylistLoader(properties.playlists?properties.playlists[0]:properties.resolvedUri,vhs,requestOptions));if(properties=merge({id:variantLabel,playlistLoader:playlistLoader},properties),setupListeners[type](type,properties.playlistLoader,settings),groups[groupId].push(properties),void 0===tracks[variantLabel]){const track=tech.addRemoteTextTrack({id:variantLabel,kind:"subtitles",default:properties.default&&properties.autoselect,language:properties.language,label:variantLabel},!1).track;tracks[variantLabel]=track}}}segmentLoader.on("error",onError[type](type,settings))},"CLOSED-CAPTIONS":(type,settings)=>{const{tech:tech,main:{mediaGroups:mediaGroups},mediaTypes:{[type]:{groups:groups,tracks:tracks}}}=settings;for(const groupId in mediaGroups[type]){groups[groupId]||(groups[groupId]=[]);for(const variantLabel in mediaGroups[type][groupId]){const properties=mediaGroups[type][groupId][variantLabel];if(!/^(?:CC|SERVICE)/.test(properties.instreamId))continue;const captionServices=tech.options_.vhs&&tech.options_.vhs.captionServices||{};let newProps={label:variantLabel,language:properties.language,instreamId:properties.instreamId,default:properties.default&&properties.autoselect};if(captionServices[newProps.instreamId]&&(newProps=merge(newProps,captionServices[newProps.instreamId])),void 0===newProps.default&&delete newProps.default,groups[groupId].push(merge({id:variantLabel},properties)),void 0===tracks[variantLabel]){const track=tech.addRemoteTextTrack({id:newProps.instreamId,kind:"captions",default:newProps.default,language:newProps.language,label:newProps.label},!1).track;tracks[variantLabel]=track}}}}},groupMatch=(list,media)=>{for(let i=0;i()=>{const{mediaTypes:{[type]:{tracks:tracks}}}=settings;for(const id in tracks)if(tracks[id].enabled)return tracks[id];return null},SUBTITLES:(type,settings)=>()=>{const{mediaTypes:{[type]:{tracks:tracks}}}=settings;for(const id in tracks)if("showing"===tracks[id].mode||"hidden"===tracks[id].mode)return tracks[id];return null}},setupMediaGroups=settings=>{["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((type=>{initialize[type](type,settings)}));const{mediaTypes:mediaTypes,mainPlaylistLoader:mainPlaylistLoader,tech:tech,vhs:vhs,segmentLoaders:{AUDIO:audioSegmentLoader,main:mainSegmentLoader}}=settings;["AUDIO","SUBTITLES"].forEach((type=>{mediaTypes[type].activeGroup=((type,settings)=>track=>{const{mainPlaylistLoader:mainPlaylistLoader,mediaTypes:{[type]:{groups:groups}}}=settings,media=mainPlaylistLoader.media();if(!media)return null;let variants=null;media.attributes[type]&&(variants=groups[media.attributes[type]]);const groupKeys=Object.keys(groups);if(!variants)if("AUDIO"===type&&groupKeys.length>1&&isAudioOnly(settings.main))for(let i=0;iprops.id===track.id))[0]||null})(type,settings),mediaTypes[type].activeTrack=activeTrack[type](type,settings),mediaTypes[type].onGroupChanged=((type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader,main:mainSegmentLoader},mediaTypes:{[type]:mediaType}}=settings,activeTrack=mediaType.activeTrack(),activeGroup=mediaType.getActiveGroup(),previousActiveLoader=mediaType.activePlaylistLoader,lastGroup=mediaType.lastGroup_;activeGroup&&lastGroup&&activeGroup.id===lastGroup.id||(mediaType.lastGroup_=activeGroup,mediaType.lastTrack_=activeTrack,stopLoaders(segmentLoader,mediaType),activeGroup&&!activeGroup.isMainPlaylist&&(activeGroup.playlistLoader?(segmentLoader.resyncLoader(),startLoaders(activeGroup.playlistLoader,mediaType)):previousActiveLoader&&mainSegmentLoader.resetEverything()))})(type,settings),mediaTypes[type].onGroupChanging=((type,settings)=>()=>{const{segmentLoaders:{[type]:segmentLoader},mediaTypes:{[type]:mediaType}}=settings;mediaType.lastGroup_=null,segmentLoader.abort(),segmentLoader.pause()})(type,settings),mediaTypes[type].onTrackChanged=((type,settings)=>()=>{const{mainPlaylistLoader:mainPlaylistLoader,segmentLoaders:{[type]:segmentLoader,main:mainSegmentLoader},mediaTypes:{[type]:mediaType}}=settings,activeTrack=mediaType.activeTrack(),activeGroup=mediaType.getActiveGroup(),previousActiveLoader=mediaType.activePlaylistLoader,lastTrack=mediaType.lastTrack_;if((!lastTrack||!activeTrack||lastTrack.id!==activeTrack.id)&&(mediaType.lastGroup_=activeGroup,mediaType.lastTrack_=activeTrack,stopLoaders(segmentLoader,mediaType),activeGroup)){if(activeGroup.isMainPlaylist){if(!activeTrack||!lastTrack||activeTrack.id===lastTrack.id)return;const pc=settings.vhs.playlistController_,newPlaylist=pc.selectPlaylist();if(pc.media()===newPlaylist)return;return mediaType.logger_("track change. Switching main audio from ".concat(lastTrack.id," to ").concat(activeTrack.id)),mainPlaylistLoader.pause(),mainSegmentLoader.resetEverything(),void pc.fastQualityChange_(newPlaylist)}if("AUDIO"===type){if(!activeGroup.playlistLoader)return mainSegmentLoader.setAudio(!0),void mainSegmentLoader.resetEverything();segmentLoader.setAudio(!0),mainSegmentLoader.setAudio(!1)}previousActiveLoader!==activeGroup.playlistLoader?(segmentLoader.track&&segmentLoader.track(activeTrack),segmentLoader.resetEverything(),startLoaders(activeGroup.playlistLoader,mediaType)):startLoaders(activeGroup.playlistLoader,mediaType)}})(type,settings),mediaTypes[type].getActiveGroup=((type,_ref80)=>{let{mediaTypes:mediaTypes}=_ref80;return()=>{const activeTrack_=mediaTypes[type].activeTrack();return activeTrack_?mediaTypes[type].activeGroup(activeTrack_):null}})(type,settings)}));const audioGroup=mediaTypes.AUDIO.activeGroup();if(audioGroup){const groupId=(audioGroup.filter((group=>group.default))[0]||audioGroup[0]).id;mediaTypes.AUDIO.tracks[groupId].enabled=!0,mediaTypes.AUDIO.onGroupChanged(),mediaTypes.AUDIO.onTrackChanged();mediaTypes.AUDIO.getActiveGroup().playlistLoader?(mainSegmentLoader.setAudio(!1),audioSegmentLoader.setAudio(!0)):mainSegmentLoader.setAudio(!0)}mainPlaylistLoader.on("mediachange",(()=>{["AUDIO","SUBTITLES"].forEach((type=>mediaTypes[type].onGroupChanged()))})),mainPlaylistLoader.on("mediachanging",(()=>{["AUDIO","SUBTITLES"].forEach((type=>mediaTypes[type].onGroupChanging()))}));const onAudioTrackChanged=()=>{mediaTypes.AUDIO.onTrackChanged(),tech.trigger({type:"usage",name:"vhs-audio-change"})};tech.audioTracks().addEventListener("change",onAudioTrackChanged),tech.remoteTextTracks().addEventListener("change",mediaTypes.SUBTITLES.onTrackChanged),vhs.on("dispose",(()=>{tech.audioTracks().removeEventListener("change",onAudioTrackChanged),tech.remoteTextTracks().removeEventListener("change",mediaTypes.SUBTITLES.onTrackChanged)})),tech.clearTracks("audio");for(const id in mediaTypes.AUDIO.tracks)tech.audioTracks().addTrack(mediaTypes.AUDIO.tracks[id])};class SteeringManifest{constructor(){this.priority_=[],this.pathwayClones_=new Map}set version(number){1===number&&(this.version_=number)}set ttl(seconds){this.ttl_=seconds||300}set reloadUri(uri){uri&&(this.reloadUri_=resolveUrl(this.reloadUri_,uri))}set priority(array){array&&array.length&&(this.priority_=array)}set pathwayClones(array){array&&array.length&&(this.pathwayClones_=new Map(array.map((clone=>[clone.ID,clone]))))}get version(){return this.version_}get ttl(){return this.ttl_}get reloadUri(){return this.reloadUri_}get priority(){return this.priority_}get pathwayClones(){return this.pathwayClones_}}class ContentSteeringController extends videojs.EventTarget{constructor(xhr,bandwidth){super(),this.currentPathway=null,this.defaultPathway=null,this.queryBeforeStart=!1,this.availablePathways_=new Set,this.steeringManifest=new SteeringManifest,this.proxyServerUrl_=null,this.manifestType_=null,this.ttlTimeout_=null,this.request_=null,this.currentPathwayClones=new Map,this.nextPathwayClones=new Map,this.excludedSteeringManifestURLs=new Set,this.logger_=logger("Content Steering"),this.xhr_=xhr,this.getBandwidth_=bandwidth}assignTagProperties(baseUrl,steeringTag){this.manifestType_=steeringTag.serverUri?"HLS":"DASH";const steeringUri=steeringTag.serverUri||steeringTag.serverURL;if(!steeringUri)return this.logger_("steering manifest URL is ".concat(steeringUri,", cannot request steering manifest.")),void this.trigger("error");steeringUri.startsWith("data:")?this.decodeDataUriManifest_(steeringUri.substring(steeringUri.indexOf(",")+1)):(this.steeringManifest.reloadUri=resolveUrl(baseUrl,steeringUri),this.defaultPathway=steeringTag.pathwayId||steeringTag.defaultServiceLocation,this.queryBeforeStart=steeringTag.queryBeforeStart,this.proxyServerUrl_=steeringTag.proxyServerURL,this.defaultPathway&&!this.queryBeforeStart&&this.trigger("content-steering"))}requestSteeringManifest(initial){const reloadUri=this.steeringManifest.reloadUri;if(!reloadUri)return;const uri=initial?reloadUri:this.getRequestURI(reloadUri);if(!uri)return this.logger_("No valid content steering manifest URIs. Stopping content steering."),this.trigger("error"),void this.dispose();this.request_=this.xhr_({uri:uri},((error,errorInfo)=>{if(error){if(410===errorInfo.status)return this.logger_("manifest request 410 ".concat(error,".")),this.logger_("There will be no more content steering requests to ".concat(uri," this session.")),void this.excludedSteeringManifestURLs.add(uri);if(429===errorInfo.status){const retrySeconds=errorInfo.responseHeaders["retry-after"];return this.logger_("manifest request 429 ".concat(error,".")),this.logger_("content steering will retry in ".concat(retrySeconds," seconds.")),void this.startTTLTimeout_(parseInt(retrySeconds,10))}return this.logger_("manifest failed to load ".concat(error,".")),void this.startTTLTimeout_()}const steeringManifestJson=JSON.parse(this.request_.responseText);this.assignSteeringProperties_(steeringManifestJson),this.startTTLTimeout_()}))}setProxyServerUrl_(steeringUrl){const steeringUrlObject=new window.URL(steeringUrl),proxyServerUrlObject=new window.URL(this.proxyServerUrl_);return proxyServerUrlObject.searchParams.set("url",encodeURI(steeringUrlObject.toString())),this.setSteeringParams_(proxyServerUrlObject.toString())}decodeDataUriManifest_(dataUri){const steeringManifestJson=JSON.parse(window.atob(dataUri));this.assignSteeringProperties_(steeringManifestJson)}setSteeringParams_(url){const urlObject=new window.URL(url),path=this.getPathway(),networkThroughput=this.getBandwidth_();if(path){const pathwayKey="_".concat(this.manifestType_,"_pathway");urlObject.searchParams.set(pathwayKey,path)}if(networkThroughput){const throughputKey="_".concat(this.manifestType_,"_throughput");urlObject.searchParams.set(throughputKey,networkThroughput)}return urlObject.toString()}assignSteeringProperties_(steeringJson){if(this.steeringManifest.version=steeringJson.VERSION,!this.steeringManifest.version)return this.logger_("manifest version is ".concat(steeringJson.VERSION,", which is not supported.")),void this.trigger("error");this.steeringManifest.ttl=steeringJson.TTL,this.steeringManifest.reloadUri=steeringJson["RELOAD-URI"],this.steeringManifest.priority=steeringJson["PATHWAY-PRIORITY"]||steeringJson["SERVICE-LOCATION-PRIORITY"],this.steeringManifest.pathwayClones=steeringJson["PATHWAY-CLONES"],this.nextPathwayClones=this.steeringManifest.pathwayClones,this.availablePathways_.size||(this.logger_("There are no available pathways for content steering. Ending content steering."),this.trigger("error"),this.dispose());const nextPathway=(pathwaysByPriority=>{for(const path of pathwaysByPriority)if(this.availablePathways_.has(path))return path;return[...this.availablePathways_][0]})(this.steeringManifest.priority);this.currentPathway!==nextPathway&&(this.currentPathway=nextPathway,this.trigger("content-steering"))}getPathway(){return this.currentPathway||this.defaultPathway}getRequestURI(reloadUri){if(!reloadUri)return null;const isExcluded=uri=>this.excludedSteeringManifestURLs.has(uri);if(this.proxyServerUrl_){const proxyURI=this.setProxyServerUrl_(reloadUri);if(!isExcluded(proxyURI))return proxyURI}const steeringURI=this.setSteeringParams_(reloadUri);return isExcluded(steeringURI)?null:steeringURI}startTTLTimeout_(){const ttlMS=1e3*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.steeringManifest.ttl);this.ttlTimeout_=window.setTimeout((()=>{this.requestSteeringManifest()}),ttlMS)}clearTTLTimeout_(){window.clearTimeout(this.ttlTimeout_),this.ttlTimeout_=null}abort(){this.request_&&this.request_.abort(),this.request_=null}dispose(){this.off("content-steering"),this.off("error"),this.abort(),this.clearTTLTimeout_(),this.currentPathway=null,this.defaultPathway=null,this.queryBeforeStart=null,this.proxyServerUrl_=null,this.manifestType_=null,this.ttlTimeout_=null,this.request_=null,this.excludedSteeringManifestURLs=new Set,this.availablePathways_=new Set,this.steeringManifest=new SteeringManifest}addAvailablePathway(pathway){pathway&&this.availablePathways_.add(pathway)}clearAvailablePathways(){this.availablePathways_.clear()}excludePathway(pathway){return this.availablePathways_.delete(pathway)}didDASHTagChange(baseURL,newTag){return!newTag&&this.steeringManifest.reloadUri||newTag&&(resolveUrl(baseURL,newTag.serverURL)!==this.steeringManifest.reloadUri||newTag.defaultServiceLocation!==this.defaultPathway||newTag.queryBeforeStart!==this.queryBeforeStart||newTag.proxyServerURL!==this.proxyServerUrl_)}getAvailablePathways(){return this.availablePathways_}}let Vhs$1;const loaderStats=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred","mediaAppends"],sumLoaderStat=function(stat){return this.audioSegmentLoader_[stat]+this.mainSegmentLoader_[stat]};class PlaylistController extends videojs.EventTarget{constructor(options){super();const{src:src,withCredentials:withCredentials,tech:tech,bandwidth:bandwidth,externVhs:externVhs,useCueTags:useCueTags,playlistExclusionDuration:playlistExclusionDuration,enableLowInitialPlaylist:enableLowInitialPlaylist,sourceType:sourceType,cacheEncryptionKeys:cacheEncryptionKeys,bufferBasedABR:bufferBasedABR,leastPixelDiffSelector:leastPixelDiffSelector,captionServices:captionServices}=options;if(!src)throw new Error("A non-empty playlist URL or JSON manifest string is required");let{maxPlaylistRetries:maxPlaylistRetries}=options;null==maxPlaylistRetries&&(maxPlaylistRetries=1/0),Vhs$1=externVhs,this.bufferBasedABR=Boolean(bufferBasedABR),this.leastPixelDiffSelector=Boolean(leastPixelDiffSelector),this.withCredentials=withCredentials,this.tech_=tech,this.vhs_=tech.vhs,this.sourceType_=sourceType,this.useCueTags_=useCueTags,this.playlistExclusionDuration=playlistExclusionDuration,this.maxPlaylistRetries=maxPlaylistRetries,this.enableLowInitialPlaylist=enableLowInitialPlaylist,this.useCueTags_&&(this.cueTagsTrack_=this.tech_.addTextTrack("metadata","ad-cues"),this.cueTagsTrack_.inBandMetadataTrackDispatchType=""),this.requestOptions_={withCredentials:withCredentials,maxPlaylistRetries:maxPlaylistRetries,timeout:null},this.on("error",this.pauseLoading),this.mediaTypes_=(()=>{const mediaTypes={};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((type=>{mediaTypes[type]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:noop,activeTrack:noop,getActiveGroup:noop,onGroupChanged:noop,onTrackChanged:noop,lastTrack_:null,logger_:logger("MediaGroups[".concat(type,"]"))}})),mediaTypes})(),this.mediaSource=new window.MediaSource,this.handleDurationChange_=this.handleDurationChange_.bind(this),this.handleSourceOpen_=this.handleSourceOpen_.bind(this),this.handleSourceEnded_=this.handleSourceEnded_.bind(this),this.mediaSource.addEventListener("durationchange",this.handleDurationChange_),this.mediaSource.addEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.addEventListener("sourceended",this.handleSourceEnded_),this.seekable_=createTimeRanges(),this.hasPlayed_=!1,this.syncController_=new SyncController(options),this.segmentMetadataTrack_=tech.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,this.decrypter_=new Decrypter,this.sourceUpdater_=new SourceUpdater(this.mediaSource),this.inbandTextTracks_={},this.timelineChangeController_=new TimelineChangeController,this.keyStatusMap_=new Map;const segmentLoaderSettings={vhs:this.vhs_,parse708captions:options.parse708captions,useDtsForTimestampOffset:options.useDtsForTimestampOffset,captionServices:captionServices,mediaSource:this.mediaSource,currentTime:this.tech_.currentTime.bind(this.tech_),seekable:()=>this.seekable(),seeking:()=>this.tech_.seeking(),duration:()=>this.duration(),hasPlayed:()=>this.hasPlayed_,goalBufferLength:()=>this.goalBufferLength(),bandwidth:bandwidth,syncController:this.syncController_,decrypter:this.decrypter_,sourceType:this.sourceType_,inbandTextTracks:this.inbandTextTracks_,cacheEncryptionKeys:cacheEncryptionKeys,sourceUpdater:this.sourceUpdater_,timelineChangeController:this.timelineChangeController_,exactManifestTimings:options.exactManifestTimings,addMetadataToTextTrack:this.addMetadataToTextTrack.bind(this)};this.mainPlaylistLoader_="dash"===this.sourceType_?new DashPlaylistLoader(src,this.vhs_,merge(this.requestOptions_,{addMetadataToTextTrack:this.addMetadataToTextTrack.bind(this)})):new PlaylistLoader(src,this.vhs_,merge(this.requestOptions_,{addDateRangesToTextTrack:this.addDateRangesToTextTrack_.bind(this)})),this.setupMainPlaylistLoaderListeners_(),this.mainSegmentLoader_=new SegmentLoader(merge(segmentLoaderSettings,{segmentMetadataTrack:this.segmentMetadataTrack_,loaderType:"main"}),options),this.audioSegmentLoader_=new SegmentLoader(merge(segmentLoaderSettings,{loaderType:"audio"}),options),this.subtitleSegmentLoader_=new VTTSegmentLoader(merge(segmentLoaderSettings,{loaderType:"vtt",featuresNativeTextTracks:this.tech_.featuresNativeTextTracks,loadVttJs:()=>new Promise(((resolve,reject)=>{function onLoad(){tech.off("vttjserror",onError),resolve()}function onError(){tech.off("vttjsloaded",onLoad),reject()}tech.one("vttjsloaded",onLoad),tech.one("vttjserror",onError),tech.addWebVttScript_()}))}),options);this.contentSteeringController_=new ContentSteeringController(this.vhs_.xhr,(()=>this.mainSegmentLoader_.bandwidth)),this.setupSegmentLoaderListeners_(),this.bufferBasedABR&&(this.mainPlaylistLoader_.one("loadedplaylist",(()=>this.startABRTimer_())),this.tech_.on("pause",(()=>this.stopABRTimer_())),this.tech_.on("play",(()=>this.startABRTimer_()))),loaderStats.forEach((stat=>{this[stat+"_"]=sumLoaderStat.bind(this,stat)})),this.logger_=logger("pc"),this.triggeredFmp4Usage=!1,"none"===this.tech_.preload()?(this.loadOnPlay_=()=>{this.loadOnPlay_=null,this.mainPlaylistLoader_.load()},this.tech_.one("play",this.loadOnPlay_)):this.mainPlaylistLoader_.load(),this.timeToLoadedData__=-1,this.mainAppendsToLoadedData__=-1,this.audioAppendsToLoadedData__=-1;const event="none"===this.tech_.preload()?"play":"loadstart";this.tech_.one(event,(()=>{const timeToLoadedDataStart=Date.now();this.tech_.one("loadeddata",(()=>{this.timeToLoadedData__=Date.now()-timeToLoadedDataStart,this.mainAppendsToLoadedData__=this.mainSegmentLoader_.mediaAppends,this.audioAppendsToLoadedData__=this.audioSegmentLoader_.mediaAppends}))}))}mainAppendsToLoadedData_(){return this.mainAppendsToLoadedData__}audioAppendsToLoadedData_(){return this.audioAppendsToLoadedData__}appendsToLoadedData_(){const main=this.mainAppendsToLoadedData_(),audio=this.audioAppendsToLoadedData_();return-1===main||-1===audio?-1:main+audio}timeToLoadedData_(){return this.timeToLoadedData__}checkABR_(){let reason=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"abr";const nextPlaylist=this.selectPlaylist();nextPlaylist&&this.shouldSwitchToMedia_(nextPlaylist)&&this.switchMedia_(nextPlaylist,reason)}switchMedia_(playlist,cause,delay){const oldMedia=this.media(),oldId=oldMedia&&(oldMedia.id||oldMedia.uri),newId=playlist&&(playlist.id||playlist.uri);oldId&&oldId!==newId&&(this.logger_("switch media ".concat(oldId," -> ").concat(newId," from ").concat(cause)),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-".concat(cause)})),this.mainPlaylistLoader_.media(playlist,delay)}switchMediaForDASHContentSteering_(){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((type=>{const mediaType=this.mediaTypes_[type],activeGroup=mediaType?mediaType.activeGroup():null,pathway=this.contentSteeringController_.getPathway();if(activeGroup&&pathway){const dashMediaPlaylists=(activeGroup.length?activeGroup[0].playlists:activeGroup.playlists).filter((p=>p.attributes.serviceLocation===pathway));dashMediaPlaylists.length&&this.mediaTypes_[type].activePlaylistLoader.media(dashMediaPlaylists[0])}}))}startABRTimer_(){this.stopABRTimer_(),this.abrTimer_=window.setInterval((()=>this.checkABR_()),250)}stopABRTimer_(){this.tech_.scrubbing&&this.tech_.scrubbing()||(window.clearInterval(this.abrTimer_),this.abrTimer_=null)}getAudioTrackPlaylists_(){const main=this.main(),defaultPlaylists=main&&main.playlists||[];if(!main||!main.mediaGroups||!main.mediaGroups.AUDIO)return defaultPlaylists;const AUDIO=main.mediaGroups.AUDIO,groupKeys=Object.keys(AUDIO);let track;if(Object.keys(this.mediaTypes_.AUDIO.groups).length)track=this.mediaTypes_.AUDIO.activeTrack();else{const defaultGroup=AUDIO.main||groupKeys.length&&AUDIO[groupKeys[0]];for(const label in defaultGroup)if(defaultGroup[label].default){track={label:label};break}}if(!track)return defaultPlaylists;const playlists=[];for(const group in AUDIO)if(AUDIO[group][track.label]){const properties=AUDIO[group][track.label];if(properties.playlists&&properties.playlists.length)playlists.push.apply(playlists,properties.playlists);else if(properties.uri)playlists.push(properties);else if(main.playlists.length)for(let i=0;i{const media=this.mainPlaylistLoader_.media(),requestTimeout=1.5*media.targetDuration*1e3;isLowestEnabledRendition(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.media())?this.requestOptions_.timeout=0:this.requestOptions_.timeout=requestTimeout,media.endList&&"none"!==this.tech_.preload()&&(this.mainSegmentLoader_.playlist(media,this.requestOptions_),this.mainSegmentLoader_.load()),setupMediaGroups({sourceType:this.sourceType_,segmentLoaders:{AUDIO:this.audioSegmentLoader_,SUBTITLES:this.subtitleSegmentLoader_,main:this.mainSegmentLoader_},tech:this.tech_,requestOptions:this.requestOptions_,mainPlaylistLoader:this.mainPlaylistLoader_,vhs:this.vhs_,main:this.main(),mediaTypes:this.mediaTypes_,excludePlaylist:this.excludePlaylist.bind(this)}),this.triggerPresenceUsage_(this.main(),media),this.setupFirstPlay(),!this.mediaTypes_.AUDIO.activePlaylistLoader||this.mediaTypes_.AUDIO.activePlaylistLoader.media()?this.trigger("selectedinitialmedia"):this.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",(()=>{this.trigger("selectedinitialmedia")}))})),this.mainPlaylistLoader_.on("loadedplaylist",(()=>{this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_);let updatedPlaylist=this.mainPlaylistLoader_.media();if(!updatedPlaylist){let selectedMedia;if(this.attachContentSteeringListeners_(),this.initContentSteeringController_(),this.excludeUnsupportedVariants_(),this.enableLowInitialPlaylist&&(selectedMedia=this.selectInitialPlaylist()),selectedMedia||(selectedMedia=this.selectPlaylist()),!selectedMedia||!this.shouldSwitchToMedia_(selectedMedia))return;this.initialMedia_=selectedMedia,this.switchMedia_(this.initialMedia_,"initial");if(!("vhs-json"===this.sourceType_&&this.initialMedia_.segments))return;updatedPlaylist=this.initialMedia_}this.handleUpdatedMediaPlaylist(updatedPlaylist)})),this.mainPlaylistLoader_.on("error",(()=>{const error=this.mainPlaylistLoader_.error;this.excludePlaylist({playlistToExclude:error.playlist,error:error})})),this.mainPlaylistLoader_.on("mediachanging",(()=>{this.mainSegmentLoader_.abort(),this.mainSegmentLoader_.pause()})),this.mainPlaylistLoader_.on("mediachange",(()=>{const media=this.mainPlaylistLoader_.media(),requestTimeout=1.5*media.targetDuration*1e3;isLowestEnabledRendition(this.mainPlaylistLoader_.main,this.mainPlaylistLoader_.media())?this.requestOptions_.timeout=0:this.requestOptions_.timeout=requestTimeout,"dash"===this.sourceType_&&this.mainPlaylistLoader_.load(),this.mainSegmentLoader_.pause(),this.mainSegmentLoader_.playlist(media,this.requestOptions_),this.waitingForFastQualityPlaylistReceived_?this.runFastQualitySwitch_():this.mainSegmentLoader_.load(),this.tech_.trigger({type:"mediachange",bubbles:!0})})),this.mainPlaylistLoader_.on("playlistunchanged",(()=>{const updatedPlaylist=this.mainPlaylistLoader_.media();if("playlist-unchanged"===updatedPlaylist.lastExcludeReason_)return;this.stuckAtPlaylistEnd_(updatedPlaylist)&&(this.excludePlaylist({error:{message:"Playlist no longer updating.",reason:"playlist-unchanged"}}),this.tech_.trigger("playliststuck"))})),this.mainPlaylistLoader_.on("renditiondisabled",(()=>{this.tech_.trigger({type:"usage",name:"vhs-rendition-disabled"})})),this.mainPlaylistLoader_.on("renditionenabled",(()=>{this.tech_.trigger({type:"usage",name:"vhs-rendition-enabled"})}))}handleUpdatedMediaPlaylist(updatedPlaylist){this.useCueTags_&&this.updateAdCues_(updatedPlaylist),this.mainSegmentLoader_.pause(),this.mainSegmentLoader_.playlist(updatedPlaylist,this.requestOptions_),this.waitingForFastQualityPlaylistReceived_&&this.runFastQualitySwitch_(),this.updateDuration(!updatedPlaylist.endList),this.tech_.paused()||(this.mainSegmentLoader_.load(),this.audioSegmentLoader_&&this.audioSegmentLoader_.load())}triggerPresenceUsage_(main,media){const mediaGroups=main.mediaGroups||{};let defaultDemuxed=!0;const audioGroupKeys=Object.keys(mediaGroups.AUDIO);for(const mediaGroup in mediaGroups.AUDIO)for(const label in mediaGroups.AUDIO[mediaGroup]){mediaGroups.AUDIO[mediaGroup][label].uri||(defaultDemuxed=!1)}defaultDemuxed&&this.tech_.trigger({type:"usage",name:"vhs-demuxed"}),Object.keys(mediaGroups.SUBTITLES).length&&this.tech_.trigger({type:"usage",name:"vhs-webvtt"}),Vhs$1.Playlist.isAes(media)&&this.tech_.trigger({type:"usage",name:"vhs-aes"}),audioGroupKeys.length&&Object.keys(mediaGroups.AUDIO[audioGroupKeys[0]]).length>1&&this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.useCueTags_&&this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"})}shouldSwitchToMedia_(nextPlaylist){const currentPlaylist=this.mainPlaylistLoader_.media()||this.mainPlaylistLoader_.pendingMedia_,currentTime=this.tech_.currentTime(),bufferLowWaterLine=this.bufferLowWaterLine(),bufferHighWaterLine=this.bufferHighWaterLine();return function(_ref81){let{currentPlaylist:currentPlaylist,buffered:buffered,currentTime:currentTime,nextPlaylist:nextPlaylist,bufferLowWaterLine:bufferLowWaterLine,bufferHighWaterLine:bufferHighWaterLine,duration:duration,bufferBasedABR:bufferBasedABR,log:log}=_ref81;if(!nextPlaylist)return videojs.log.warn("We received no playlist to switch to. Please check your stream."),!1;const sharedLogLine="allowing switch ".concat(currentPlaylist&¤tPlaylist.id||"null"," -> ").concat(nextPlaylist.id);if(!currentPlaylist)return log("".concat(sharedLogLine," as current playlist is not set")),!0;if(nextPlaylist.id===currentPlaylist.id)return!1;const isBuffered=Boolean(findRange(buffered,currentTime).length);if(!currentPlaylist.endList)return isBuffered||"number"!=typeof currentPlaylist.partTargetDuration?(log("".concat(sharedLogLine," as current playlist is live")),!0):(log("not ".concat(sharedLogLine," as current playlist is live llhls, but currentTime isn't in buffered.")),!1);const forwardBuffer=timeAheadOf(buffered,currentTime),maxBufferLowWaterLine=bufferBasedABR?Config.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:Config.MAX_BUFFER_LOW_WATER_LINE;if(durationcurrBandwidth)&&forwardBuffer>=bufferLowWaterLine){let logLine="".concat(sharedLogLine," as forwardBuffer >= bufferLowWaterLine (").concat(forwardBuffer," >= ").concat(bufferLowWaterLine,")");return bufferBasedABR&&(logLine+=" and next bandwidth > current bandwidth (".concat(nextBandwidth," > ").concat(currBandwidth,")")),log(logLine),!0}return log("not ".concat(sharedLogLine," as no switching criteria met")),!1}({buffered:this.tech_.buffered(),currentTime:currentTime,currentPlaylist:currentPlaylist,nextPlaylist:nextPlaylist,bufferLowWaterLine:bufferLowWaterLine,bufferHighWaterLine:bufferHighWaterLine,duration:this.duration(),bufferBasedABR:this.bufferBasedABR,log:this.logger_})}setupSegmentLoaderListeners_(){this.mainSegmentLoader_.on("bandwidthupdate",(()=>{this.checkABR_("bandwidthupdate"),this.tech_.trigger("bandwidthupdate")})),this.mainSegmentLoader_.on("timeout",(()=>{this.bufferBasedABR&&this.mainSegmentLoader_.load()})),this.bufferBasedABR||this.mainSegmentLoader_.on("progress",(()=>{this.trigger("progress")})),this.mainSegmentLoader_.on("error",(()=>{const error=this.mainSegmentLoader_.error();this.excludePlaylist({playlistToExclude:error.playlist,error:error})})),this.mainSegmentLoader_.on("appenderror",(()=>{this.error=this.mainSegmentLoader_.error_,this.trigger("error")})),this.mainSegmentLoader_.on("syncinfoupdate",(()=>{this.onSyncInfoUpdate_()})),this.mainSegmentLoader_.on("timestampoffset",(()=>{this.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"})})),this.audioSegmentLoader_.on("syncinfoupdate",(()=>{this.onSyncInfoUpdate_()})),this.audioSegmentLoader_.on("appenderror",(()=>{this.error=this.audioSegmentLoader_.error_,this.trigger("error")})),this.mainSegmentLoader_.on("ended",(()=>{this.logger_("main segment loader ended"),this.onEndOfStream()})),this.mainSegmentLoader_.on("earlyabort",(event=>{this.bufferBasedABR||(this.delegateLoaders_("all",["abort"]),this.excludePlaylist({error:{message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},playlistExclusionDuration:10}))}));const updateCodecs=()=>{if(!this.sourceUpdater_.hasCreatedSourceBuffers())return this.tryToCreateSourceBuffers_();const codecs=this.getCodecsOrExclude_();codecs&&this.sourceUpdater_.addOrChangeSourceBuffers(codecs)};this.mainSegmentLoader_.on("trackinfo",updateCodecs),this.audioSegmentLoader_.on("trackinfo",updateCodecs),this.mainSegmentLoader_.on("fmp4",(()=>{this.triggeredFmp4Usage||(this.tech_.trigger({type:"usage",name:"vhs-fmp4"}),this.triggeredFmp4Usage=!0)})),this.audioSegmentLoader_.on("fmp4",(()=>{this.triggeredFmp4Usage||(this.tech_.trigger({type:"usage",name:"vhs-fmp4"}),this.triggeredFmp4Usage=!0)})),this.audioSegmentLoader_.on("ended",(()=>{this.logger_("audioSegmentLoader ended"),this.onEndOfStream()}))}mediaSecondsLoaded_(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)}load(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()}fastQualityChange_(){let media=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectPlaylist();media&&media===this.mainPlaylistLoader_.media()?this.logger_("skipping fastQualityChange because new media is same as old"):(this.switchMedia_(media,"fast-quality"),this.waitingForFastQualityPlaylistReceived_=!0)}runFastQualitySwitch_(){this.waitingForFastQualityPlaylistReceived_=!1,this.mainSegmentLoader_.pause(),this.mainSegmentLoader_.resetEverything((()=>{this.tech_.setCurrentTime(this.tech_.currentTime())}))}play(){if(this.setupFirstPlay())return;this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();const seekable=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime(){}))}this.trigger("sourceopen")}handleSourceEnded_(){if(!this.inbandTextTracks_.metadataTrack_)return;const cues=this.inbandTextTracks_.metadataTrack_.cues;if(!cues||!cues.length)return;const duration=this.duration();cues[cues.length-1].endTime=isNaN(duration)||Math.abs(duration)===1/0?Number.MAX_VALUE:duration}handleDurationChange_(){this.tech_.trigger("durationchange")}onEndOfStream(){let isEndOfStream=this.mainSegmentLoader_.ended_;if(this.mediaTypes_.AUDIO.activePlaylistLoader){const mainMediaInfo=this.mainSegmentLoader_.getCurrentMediaInfo_();isEndOfStream=!mainMediaInfo||mainMediaInfo.hasVideo?isEndOfStream&&this.audioSegmentLoader_.ended_:this.audioSegmentLoader_.ended_}isEndOfStream&&(this.stopABRTimer_(),this.sourceUpdater_.endOfStream())}stuckAtPlaylistEnd_(playlist){if(!this.seekable().length)return!1;const expired=this.syncController_.getExpiredTime(playlist,this.duration());if(null===expired)return!1;const absolutePlaylistEnd=Vhs$1.Playlist.playlistEnd(playlist,expired),currentTime=this.tech_.currentTime(),buffered=this.tech_.buffered();if(!buffered.length)return absolutePlaylistEnd-currentTime<=.1;const bufferedEnd=buffered.end(buffered.length-1);return bufferedEnd-currentTime<=.1&&absolutePlaylistEnd-bufferedEnd<=.1}excludePlaylist(_ref82){let{playlistToExclude:playlistToExclude=this.mainPlaylistLoader_.media(),error:error={},playlistExclusionDuration:playlistExclusionDuration}=_ref82;if(playlistToExclude=playlistToExclude||this.mainPlaylistLoader_.media(),playlistExclusionDuration=playlistExclusionDuration||error.playlistExclusionDuration||this.playlistExclusionDuration,!playlistToExclude)return this.error=error,void("open"!==this.mediaSource.readyState?this.trigger("error"):this.sourceUpdater_.endOfStream("network"));playlistToExclude.playlistErrors_++;const playlists=this.mainPlaylistLoader_.main.playlists,enabledPlaylists=playlists.filter(isEnabled),isFinalRendition=1===enabledPlaylists.length&&enabledPlaylists[0]===playlistToExclude;if(1===playlists.length&&playlistExclusionDuration!==1/0)return videojs.log.warn("Problem encountered with playlist ".concat(playlistToExclude.id,". ")+"Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.mainPlaylistLoader_.load(isFinalRendition);if(isFinalRendition){if(this.main().contentSteering){const pathway=this.pathwayAttribute_(playlistToExclude),reIncludeDelay=1e3*this.contentSteeringController_.steeringManifest.ttl;return this.contentSteeringController_.excludePathway(pathway),this.excludeThenChangePathway_(),void setTimeout((()=>{this.contentSteeringController_.addAvailablePathway(pathway)}),reIncludeDelay)}let reincluded=!1;playlists.forEach((playlist=>{if(playlist===playlistToExclude)return;const excludeUntil=playlist.excludeUntil;void 0!==excludeUntil&&excludeUntil!==1/0&&(reincluded=!0,delete playlist.excludeUntil)})),reincluded&&(videojs.log.warn("Removing other playlists from the exclusion list because the last rendition is about to be excluded."),this.tech_.trigger("retryplaylist"))}let excludeUntil;excludeUntil=playlistToExclude.playlistErrors_>this.maxPlaylistRetries?1/0:Date.now()+1e3*playlistExclusionDuration,playlistToExclude.excludeUntil=excludeUntil,error.reason&&(playlistToExclude.lastExcludeReason_=error.reason),this.tech_.trigger("excludeplaylist"),this.tech_.trigger({type:"usage",name:"vhs-rendition-excluded"});const nextPlaylist=this.selectPlaylist();if(!nextPlaylist)return this.error="Playback cannot continue. No available working or supported playlists.",void this.trigger("error");const logFn=error.internal?this.logger_:videojs.log.warn,errorMessage=error.message?" "+error.message:"";logFn("".concat(error.internal?"Internal problem":"Problem"," encountered with playlist ").concat(playlistToExclude.id,".")+"".concat(errorMessage," Switching to playlist ").concat(nextPlaylist.id,".")),nextPlaylist.attributes.AUDIO!==playlistToExclude.attributes.AUDIO&&this.delegateLoaders_("audio",["abort","pause"]),nextPlaylist.attributes.SUBTITLES!==playlistToExclude.attributes.SUBTITLES&&this.delegateLoaders_("subtitle",["abort","pause"]),this.delegateLoaders_("main",["abort","pause"]);const delayDuration=nextPlaylist.targetDuration/2*1e3||5e3,shouldDelay="number"==typeof nextPlaylist.lastRequest&&Date.now()-nextPlaylist.lastRequest<=delayDuration;return this.switchMedia_(nextPlaylist,"exclude",isFinalRendition||shouldDelay)}pauseLoading(){this.delegateLoaders_("all",["abort","pause"]),this.stopABRTimer_()}delegateLoaders_(filter,fnNames){const loaders=[],dontFilterPlaylist="all"===filter;(dontFilterPlaylist||"main"===filter)&&loaders.push(this.mainPlaylistLoader_);const mediaTypes=[];(dontFilterPlaylist||"audio"===filter)&&mediaTypes.push("AUDIO"),(dontFilterPlaylist||"subtitle"===filter)&&(mediaTypes.push("CLOSED-CAPTIONS"),mediaTypes.push("SUBTITLES")),mediaTypes.forEach((mediaType=>{const loader=this.mediaTypes_[mediaType]&&this.mediaTypes_[mediaType].activePlaylistLoader;loader&&loaders.push(loader)})),["main","audio","subtitle"].forEach((name=>{const loader=this["".concat(name,"SegmentLoader_")];!loader||filter!==name&&"all"!==filter||loaders.push(loader)})),loaders.forEach((loader=>fnNames.forEach((fnName=>{"function"==typeof loader[fnName]&&loader[fnName]()}))))}setCurrentTime(currentTime){const buffered=findRange(this.tech_.buffered(),currentTime);return this.mainPlaylistLoader_&&this.mainPlaylistLoader_.media()&&this.mainPlaylistLoader_.media().segments?buffered&&buffered.length?currentTime:(this.mainSegmentLoader_.pause(),this.mainSegmentLoader_.resetEverything(),this.mediaTypes_.AUDIO.activePlaylistLoader&&(this.audioSegmentLoader_.pause(),this.audioSegmentLoader_.resetEverything()),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&(this.subtitleSegmentLoader_.pause(),this.subtitleSegmentLoader_.resetEverything()),void this.load()):0}duration(){if(!this.mainPlaylistLoader_)return 0;const media=this.mainPlaylistLoader_.media();return media?media.endList?this.mediaSource?this.mediaSource.duration:Vhs$1.Playlist.duration(media):1/0:0}seekable(){return this.seekable_}onSyncInfoUpdate_(){let audioSeekable;if(!this.mainPlaylistLoader_)return;let media=this.mainPlaylistLoader_.media();if(!media)return;let expired=this.syncController_.getExpiredTime(media,this.duration());if(null===expired)return;const main=this.mainPlaylistLoader_.main,mainSeekable=Vhs$1.Playlist.seekable(media,expired,Vhs$1.Playlist.liveEdgeDelay(main,media));if(0===mainSeekable.length)return;if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(media=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),expired=this.syncController_.getExpiredTime(media,this.duration()),null===expired)return;if(audioSeekable=Vhs$1.Playlist.seekable(media,expired,Vhs$1.Playlist.liveEdgeDelay(main,media)),0===audioSeekable.length)return}let oldEnd,oldStart;this.seekable_&&this.seekable_.length&&(oldEnd=this.seekable_.end(0),oldStart=this.seekable_.start(0)),audioSeekable?audioSeekable.start(0)>mainSeekable.end(0)||mainSeekable.start(0)>audioSeekable.end(0)?this.seekable_=mainSeekable:this.seekable_=createTimeRanges([[audioSeekable.start(0)>mainSeekable.start(0)?audioSeekable.start(0):mainSeekable.start(0),audioSeekable.end(0)0&&(duration=Math.max(duration,buffered.end(buffered.length-1))),this.mediaSource.duration!==duration&&this.sourceUpdater_.setDuration(duration)}dispose(){this.trigger("dispose"),this.decrypter_.terminate(),this.mainPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.contentSteeringController_.dispose(),this.keyStatusMap_.clear(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach((type=>{const groups=this.mediaTypes_[type].groups;for(const id in groups)groups[id].forEach((group=>{group.playlistLoader&&group.playlistLoader.dispose()}))})),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off()}main(){return this.mainPlaylistLoader_.main}media(){return this.mainPlaylistLoader_.media()||this.initialMedia_}areMediaTypesKnown_(){const usingAudioLoader=!!this.mediaTypes_.AUDIO.activePlaylistLoader,hasMainMediaInfo=!!this.mainSegmentLoader_.getCurrentMediaInfo_(),hasAudioMediaInfo=!usingAudioLoader||!!this.audioSegmentLoader_.getCurrentMediaInfo_();return!(!hasMainMediaInfo||!hasAudioMediaInfo)}getCodecsOrExclude_(){const media={main:this.mainSegmentLoader_.getCurrentMediaInfo_()||{},audio:this.audioSegmentLoader_.getCurrentMediaInfo_()||{}},playlist=this.mainSegmentLoader_.getPendingSegmentPlaylist()||this.media();media.video=media.main;const playlistCodecs=codecsForPlaylist(this.main(),playlist),codecs={},usingAudioLoader=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(media.main.hasVideo&&(codecs.video=playlistCodecs.video||media.main.videoCodec||"avc1.4d400d"),media.main.isMuxed&&(codecs.video+=",".concat(playlistCodecs.audio||media.main.audioCodec||"mp4a.40.2")),(media.main.hasAudio&&!media.main.isMuxed||media.audio.hasAudio||usingAudioLoader)&&(codecs.audio=playlistCodecs.audio||media.main.audioCodec||media.audio.audioCodec||"mp4a.40.2",media.audio.isFmp4=media.main.hasAudio&&!media.main.isMuxed?media.main.isFmp4:media.audio.isFmp4),!codecs.audio&&!codecs.video)return void this.excludePlaylist({playlistToExclude:playlist,error:{message:"Could not determine codecs for playlist."},playlistExclusionDuration:1/0});const unsupportedCodecs={};let unsupportedAudio;if(["video","audio"].forEach((function(type){if(codecs.hasOwnProperty(type)&&(isFmp4=media[type].isFmp4,codec=codecs[type],!(isFmp4?browserSupportsCodec(codec):muxerSupportsCodec(codec)))){const supporter=media[type].isFmp4?"browser":"muxer";unsupportedCodecs[supporter]=unsupportedCodecs[supporter]||[],unsupportedCodecs[supporter].push(codecs[type]),"audio"===type&&(unsupportedAudio=supporter)}var isFmp4,codec})),usingAudioLoader&&unsupportedAudio&&playlist.attributes.AUDIO){const audioGroup=playlist.attributes.AUDIO;this.main().playlists.forEach((variant=>{(variant.attributes&&variant.attributes.AUDIO)===audioGroup&&variant!==playlist&&(variant.excludeUntil=1/0)})),this.logger_("excluding audio group ".concat(audioGroup," as ").concat(unsupportedAudio,' does not support codec(s): "').concat(codecs.audio,'"'))}if(!Object.keys(unsupportedCodecs).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){const switchMessages=[];if(["video","audio"].forEach((type=>{const newCodec=(parseCodecs(this.sourceUpdater_.codecs[type]||"")[0]||{}).type,oldCodec=(parseCodecs(codecs[type]||"")[0]||{}).type;newCodec&&oldCodec&&newCodec.toLowerCase()!==oldCodec.toLowerCase()&&switchMessages.push('"'.concat(this.sourceUpdater_.codecs[type],'" -> "').concat(codecs[type],'"'))})),switchMessages.length)return void this.excludePlaylist({playlistToExclude:playlist,error:{message:"Codec switching not supported: ".concat(switchMessages.join(", "),"."),internal:!0},playlistExclusionDuration:1/0})}return codecs}{const message=Object.keys(unsupportedCodecs).reduce(((acc,supporter)=>(acc&&(acc+=", "),acc+="".concat(supporter,' does not support codec(s): "').concat(unsupportedCodecs[supporter].join(","),'"'))),"")+".";this.excludePlaylist({playlistToExclude:playlist,error:{internal:!0,message:message},playlistExclusionDuration:1/0})}}tryToCreateSourceBuffers_(){if("open"!==this.mediaSource.readyState||this.sourceUpdater_.hasCreatedSourceBuffers())return;if(!this.areMediaTypesKnown_())return;const codecs=this.getCodecsOrExclude_();if(!codecs)return;this.sourceUpdater_.createSourceBuffers(codecs);const codecString=[codecs.video,codecs.audio].filter(Boolean).join(",");this.excludeIncompatibleVariants_(codecString)}excludeUnsupportedVariants_(){const playlists=this.main().playlists,ids=[];Object.keys(playlists).forEach((key=>{const variant=playlists[key];if(-1!==ids.indexOf(variant.id))return;ids.push(variant.id);const codecs=codecsForPlaylist(this.main,variant),unsupported=[];!codecs.audio||muxerSupportsCodec(codecs.audio)||browserSupportsCodec(codecs.audio)||unsupported.push("audio codec ".concat(codecs.audio)),!codecs.video||muxerSupportsCodec(codecs.video)||browserSupportsCodec(codecs.video)||unsupported.push("video codec ".concat(codecs.video)),codecs.text&&"stpp.ttml.im1t"===codecs.text&&unsupported.push("text codec ".concat(codecs.text)),unsupported.length&&(variant.excludeUntil=1/0,this.logger_("excluding ".concat(variant.id," for unsupported: ").concat(unsupported.join(", "))))}))}excludeIncompatibleVariants_(codecString){const ids=[],playlists=this.main().playlists,codecs=unwrapCodecList(parseCodecs(codecString)),codecCount_=codecCount(codecs),videoDetails=codecs.video&&parseCodecs(codecs.video)[0]||null,audioDetails=codecs.audio&&parseCodecs(codecs.audio)[0]||null;Object.keys(playlists).forEach((key=>{const variant=playlists[key];if(-1!==ids.indexOf(variant.id)||variant.excludeUntil===1/0)return;ids.push(variant.id);const exclusionReasons=[],variantCodecs=codecsForPlaylist(this.mainPlaylistLoader_.main,variant),variantCodecCount=codecCount(variantCodecs);if(variantCodecs.audio||variantCodecs.video){if(variantCodecCount!==codecCount_&&exclusionReasons.push('codec count "'.concat(variantCodecCount,'" !== "').concat(codecCount_,'"')),!this.sourceUpdater_.canChangeType()){const variantVideoDetails=variantCodecs.video&&parseCodecs(variantCodecs.video)[0]||null,variantAudioDetails=variantCodecs.audio&&parseCodecs(variantCodecs.audio)[0]||null;variantVideoDetails&&videoDetails&&variantVideoDetails.type.toLowerCase()!==videoDetails.type.toLowerCase()&&exclusionReasons.push('video codec "'.concat(variantVideoDetails.type,'" !== "').concat(videoDetails.type,'"')),variantAudioDetails&&audioDetails&&variantAudioDetails.type.toLowerCase()!==audioDetails.type.toLowerCase()&&exclusionReasons.push('audio codec "'.concat(variantAudioDetails.type,'" !== "').concat(audioDetails.type,'"'))}exclusionReasons.length&&(variant.excludeUntil=1/0,this.logger_("excluding ".concat(variant.id,": ").concat(exclusionReasons.join(" && "))))}}))}updateAdCues_(media){let offset=0;const seekable=this.seekable();seekable.length&&(offset=seekable.start(0)),function(media,track){let offset=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(!media.segments)return;let cue,mediaTime=offset;for(let i=0;i{let{inbandTextTracks:inbandTextTracks,dateRanges:dateRanges}=_ref64;const metadataTrack=inbandTextTracks.metadataTrack_;if(!metadataTrack)return;const Cue=window.WebKitDataCue||window.VTTCue;dateRanges.forEach((dateRange=>{for(const key of Object.keys(dateRange)){if(dateRangeKeysToOmit.has(key))continue;const cue=new Cue(dateRange.startTime,dateRange.endTime,"");cue.id=dateRange.id,cue.type="com.apple.quicktime.HLS",cue.value={key:dateRangeAttr[key],data:dateRange[key]},"scte35Out"!==key&&"scte35In"!==key||(cue.value.data=new Uint8Array(cue.value.data.match(/[\da-f]{2}/gi)).buffer),metadataTrack.addCue(cue)}dateRange.processDateRange()}))})({inbandTextTracks:this.inbandTextTracks_,dateRanges:dateRanges})}addMetadataToTextTrack(dispatchType,metadataArray,videoDuration){const timestampOffset=this.sourceUpdater_.videoBuffer?this.sourceUpdater_.videoTimestampOffset():this.sourceUpdater_.audioTimestampOffset();createMetadataTrackIfNotExists(this.inbandTextTracks_,dispatchType,this.tech_),addMetadata({inbandTextTracks:this.inbandTextTracks_,metadataArray:metadataArray,timestampOffset:timestampOffset,videoDuration:videoDuration})}pathwayAttribute_(playlist){return playlist.attributes["PATHWAY-ID"]||playlist.attributes.serviceLocation}initContentSteeringController_(){const main=this.main();if(main.contentSteering){for(const playlist of main.playlists)this.contentSteeringController_.addAvailablePathway(this.pathwayAttribute_(playlist));this.contentSteeringController_.assignTagProperties(main.uri,main.contentSteering),this.contentSteeringController_.queryBeforeStart?this.contentSteeringController_.requestSteeringManifest(!0):this.tech_.one("canplay",(()=>{this.contentSteeringController_.requestSteeringManifest()}))}}resetContentSteeringController_(){this.contentSteeringController_.clearAvailablePathways(),this.contentSteeringController_.dispose(),this.initContentSteeringController_()}attachContentSteeringListeners_(){this.contentSteeringController_.on("content-steering",this.excludeThenChangePathway_.bind(this)),"dash"===this.sourceType_&&this.mainPlaylistLoader_.on("loadedplaylist",(()=>{const main=this.main();(this.contentSteeringController_.didDASHTagChange(main.uri,main.contentSteering)||(()=>{const availablePathways=this.contentSteeringController_.getAvailablePathways(),newPathways=[];for(const playlist of main.playlists){const serviceLocation=playlist.attributes.serviceLocation;if(serviceLocation&&(newPathways.push(serviceLocation),!availablePathways.has(serviceLocation)))return!0}return!(newPathways.length||!availablePathways.size)})())&&this.resetContentSteeringController_()}))}excludeThenChangePathway_(){const currentPathway=this.contentSteeringController_.getPathway();if(!currentPathway)return;this.handlePathwayClones_();const playlists=this.main().playlists,ids=new Set;let didEnablePlaylists=!1;Object.keys(playlists).forEach((key=>{const variant=playlists[key],pathwayId=this.pathwayAttribute_(variant),differentPathwayId=pathwayId&¤tPathway!==pathwayId;variant.excludeUntil===1/0&&"content-steering"===variant.lastExcludeReason_&&!differentPathwayId&&(delete variant.excludeUntil,delete variant.lastExcludeReason_,didEnablePlaylists=!0);const noExcludeUntil=!variant.excludeUntil&&variant.excludeUntil!==1/0;!ids.has(variant.id)&&differentPathwayId&&noExcludeUntil&&(ids.add(variant.id),variant.excludeUntil=1/0,variant.lastExcludeReason_="content-steering",this.logger_("excluding ".concat(variant.id," for ").concat(variant.lastExcludeReason_)))})),"DASH"===this.contentSteeringController_.manifestType_&&Object.keys(this.mediaTypes_).forEach((key=>{const type=this.mediaTypes_[key];if(type.activePlaylistLoader){const currentPlaylist=type.activePlaylistLoader.media_;currentPlaylist&¤tPlaylist.attributes.serviceLocation!==currentPathway&&(didEnablePlaylists=!0)}})),didEnablePlaylists&&this.changeSegmentPathway_()}handlePathwayClones_(){const playlists=this.main().playlists,currentPathwayClones=this.contentSteeringController_.currentPathwayClones,nextPathwayClones=this.contentSteeringController_.nextPathwayClones;if(currentPathwayClones&¤tPathwayClones.size||nextPathwayClones&&nextPathwayClones.size){for(const[id,clone]of currentPathwayClones.entries()){nextPathwayClones.get(id)||(this.mainPlaylistLoader_.updateOrDeleteClone(clone),this.contentSteeringController_.excludePathway(id))}for(const[id,clone]of nextPathwayClones.entries()){const oldClone=currentPathwayClones.get(id);if(oldClone)this.equalPathwayClones_(oldClone,clone)||(this.mainPlaylistLoader_.updateOrDeleteClone(clone,!0),this.contentSteeringController_.addAvailablePathway(id));else{playlists.filter((p=>p.attributes["PATHWAY-ID"]===clone["BASE-ID"])).forEach((p=>{this.mainPlaylistLoader_.addClonePathway(clone,p)})),this.contentSteeringController_.addAvailablePathway(id)}}this.contentSteeringController_.currentPathwayClones=new Map(JSON.parse(JSON.stringify([...nextPathwayClones])))}}equalPathwayClones_(a,b){if(a["BASE-ID"]!==b["BASE-ID"]||a.ID!==b.ID||a["URI-REPLACEMENT"].HOST!==b["URI-REPLACEMENT"].HOST)return!1;const aParams=a["URI-REPLACEMENT"].PARAMS,bParams=b["URI-REPLACEMENT"].PARAMS;for(const p in aParams)if(aParams[p]!==bParams[p])return!1;for(const p in bParams)if(aParams[p]!==bParams[p])return!1;return!0}changeSegmentPathway_(){const nextPlaylist=this.selectPlaylist();this.pauseLoading(),"DASH"===this.contentSteeringController_.manifestType_&&this.switchMediaForDASHContentSteering_(),this.switchMedia_(nextPlaylist,"content-steering")}excludeNonUsablePlaylistsByKeyId_(){if(!this.mainPlaylistLoader_||!this.mainPlaylistLoader_.main)return;let nonUsableKeyStatusCount=0;this.mainPlaylistLoader_.main.playlists.forEach((playlist=>{const keyIdSet=this.mainPlaylistLoader_.getKeyIdSet(playlist);keyIdSet&&keyIdSet.size&&keyIdSet.forEach((key=>{const hasUsableKeyStatus=this.keyStatusMap_.has(key)&&"usable"===this.keyStatusMap_.get(key),nonUsableExclusion="non-usable"===playlist.lastExcludeReason_&&playlist.excludeUntil===1/0;hasUsableKeyStatus?hasUsableKeyStatus&&nonUsableExclusion&&(delete playlist.excludeUntil,delete playlist.lastExcludeReason_,this.logger_("enabling playlist ".concat(playlist.id," because key ID ").concat(key," is ").concat("usable"))):(playlist.excludeUntil!==1/0&&"non-usable"!==playlist.lastExcludeReason_&&(playlist.excludeUntil=1/0,playlist.lastExcludeReason_="non-usable",this.logger_("excluding playlist ".concat(playlist.id," because the key ID ").concat(key," doesn't exist in the keyStatusMap or is not ").concat("usable"))),nonUsableKeyStatusCount++)}))})),nonUsableKeyStatusCount>=this.mainPlaylistLoader_.main.playlists.length&&this.mainPlaylistLoader_.main.playlists.forEach((playlist=>{const isNonHD=playlist&&playlist.attributes&&playlist.attributes.RESOLUTION&&playlist.attributes.RESOLUTION.height<720,excludedForNonUsableKey=playlist.excludeUntil===1/0&&"non-usable"===playlist.lastExcludeReason_;isNonHD&&excludedForNonUsableKey&&(delete playlist.excludeUntil,videojs.log.warn("enabling non-HD playlist ".concat(playlist.id," because all playlists were excluded due to ").concat("non-usable"," key IDs")))}))}addKeyStatus_(keyId,status){const formattedKeyIdString=("string"==typeof keyId?keyId:(buffer=>{const uInt8Buffer=new Uint8Array(buffer);return Array.from(uInt8Buffer).map((byte=>byte.toString(16).padStart(2,"0"))).join("")})(keyId)).slice(0,32).toLowerCase();this.logger_("KeyStatus '".concat(status,"' with key ID ").concat(formattedKeyIdString," added to the keyStatusMap")),this.keyStatusMap_.set(formattedKeyIdString,status)}updatePlaylistByKeyStatus(keyId,status){this.addKeyStatus_(keyId,status),this.waitingForFastQualityPlaylistReceived_||this.excludeNonUsableThenChangePlaylist_(),this.mainPlaylistLoader_.off("loadedplaylist",this.excludeNonUsableThenChangePlaylist_.bind(this)),this.mainPlaylistLoader_.on("loadedplaylist",this.excludeNonUsableThenChangePlaylist_.bind(this))}excludeNonUsableThenChangePlaylist_(){this.excludeNonUsablePlaylistsByKeyId_(),this.fastQualityChange_()}}class Representation{constructor(vhsHandler,playlist,id){const{playlistController_:pc}=vhsHandler,qualityChangeFunction=pc.fastQualityChange_.bind(pc);if(playlist.attributes){const resolution=playlist.attributes.RESOLUTION;this.width=resolution&&resolution.width,this.height=resolution&&resolution.height,this.bandwidth=playlist.attributes.BANDWIDTH,this.frameRate=playlist.attributes["FRAME-RATE"]}var loader,playlistID,changePlaylistFn;this.codecs=codecsForPlaylist(pc.main(),playlist),this.playlist=playlist,this.id=id,this.enabled=(loader=vhsHandler.playlists,playlistID=playlist.id,changePlaylistFn=qualityChangeFunction,enable=>{const playlist=loader.main.playlists[playlistID],incompatible=isIncompatible(playlist),currentlyEnabled=isEnabled(playlist);return void 0===enable?currentlyEnabled:(enable?delete playlist.disabled:playlist.disabled=!0,enable===currentlyEnabled||incompatible||(changePlaylistFn(),enable?loader.trigger("renditionenabled"):loader.trigger("renditiondisabled")),enable)})}}const timerCancelEvents=["seeking","seeked","pause","playing","error"];class PlaybackWatcher{constructor(options){this.playlistController_=options.playlistController,this.tech_=options.tech,this.seekable=options.seekable,this.allowSeeksWithinUnsafeLiveWindow=options.allowSeeksWithinUnsafeLiveWindow,this.liveRangeSafeTimeDelta=options.liveRangeSafeTimeDelta,this.media=options.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.checkCurrentTimeTimeout_=null,this.logger_=logger("PlaybackWatcher"),this.logger_("initialize");const playHandler=()=>this.monitorCurrentTime_(),canPlayHandler=()=>this.monitorCurrentTime_(),waitingHandler=()=>this.techWaiting_(),cancelTimerHandler=()=>this.resetTimeUpdate_(),pc=this.playlistController_,loaderTypes=["main","subtitle","audio"],loaderChecks={};loaderTypes.forEach((type=>{loaderChecks[type]={reset:()=>this.resetSegmentDownloads_(type),updateend:()=>this.checkSegmentDownloads_(type)},pc["".concat(type,"SegmentLoader_")].on("appendsdone",loaderChecks[type].updateend),pc["".concat(type,"SegmentLoader_")].on("playlistupdate",loaderChecks[type].reset),this.tech_.on(["seeked","seeking"],loaderChecks[type].reset)}));const setSeekingHandlers=fn=>{["main","audio"].forEach((type=>{pc["".concat(type,"SegmentLoader_")][fn]("appended",this.seekingAppendCheck_)}))};this.seekingAppendCheck_=()=>{this.fixesBadSeeks_()&&(this.consecutiveUpdates=0,this.lastRecordedTime=this.tech_.currentTime(),setSeekingHandlers("off"))},this.clearSeekingAppendCheck_=()=>setSeekingHandlers("off"),this.watchForBadSeeking_=()=>{this.clearSeekingAppendCheck_(),setSeekingHandlers("on")},this.tech_.on("seeked",this.clearSeekingAppendCheck_),this.tech_.on("seeking",this.watchForBadSeeking_),this.tech_.on("waiting",waitingHandler),this.tech_.on(timerCancelEvents,cancelTimerHandler),this.tech_.on("canplay",canPlayHandler),this.tech_.one("play",playHandler),this.dispose=()=>{this.clearSeekingAppendCheck_(),this.logger_("dispose"),this.tech_.off("waiting",waitingHandler),this.tech_.off(timerCancelEvents,cancelTimerHandler),this.tech_.off("canplay",canPlayHandler),this.tech_.off("play",playHandler),this.tech_.off("seeking",this.watchForBadSeeking_),this.tech_.off("seeked",this.clearSeekingAppendCheck_),loaderTypes.forEach((type=>{pc["".concat(type,"SegmentLoader_")].off("appendsdone",loaderChecks[type].updateend),pc["".concat(type,"SegmentLoader_")].off("playlistupdate",loaderChecks[type].reset),this.tech_.off(["seeked","seeking"],loaderChecks[type].reset)})),this.checkCurrentTimeTimeout_&&window.clearTimeout(this.checkCurrentTimeTimeout_),this.resetTimeUpdate_()}}monitorCurrentTime_(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&window.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=window.setTimeout(this.monitorCurrentTime_.bind(this),250)}resetSegmentDownloads_(type){const loader=this.playlistController_["".concat(type,"SegmentLoader_")];this["".concat(type,"StalledDownloads_")]>0&&this.logger_("resetting possible stalled download count for ".concat(type," loader")),this["".concat(type,"StalledDownloads_")]=0,this["".concat(type,"Buffered_")]=loader.buffered_()}checkSegmentDownloads_(type){const pc=this.playlistController_,loader=pc["".concat(type,"SegmentLoader_")],buffered=loader.buffered_(),isBufferedDifferent=function(a,b){if(a===b)return!1;if(!a&&b||!b&&a)return!0;if(a.length!==b.length)return!0;for(let i=0;i=buffered.end(buffered.length-1)))return this.techWaiting_();this.consecutiveUpdates>=5&¤tTime===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):currentTime===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=currentTime)}resetTimeUpdate_(){this.consecutiveUpdates=0}fixesBadSeeks_(){if(!this.tech_.seeking())return!1;const seekable=this.seekable(),currentTime=this.tech_.currentTime();let seekTo;if(this.afterSeekableWindow_(seekable,currentTime,this.media(),this.allowSeeksWithinUnsafeLiveWindow)){seekTo=seekable.end(seekable.length-1)}if(this.beforeSeekableWindow_(seekable,currentTime)){const seekableStart=seekable.start(0);seekTo=seekableStart+(seekableStart===seekable.end(0)?0:.1)}if(void 0!==seekTo)return this.logger_("Trying to seek outside of seekable at time ".concat(currentTime," with ")+"seekable range ".concat(printableRange(seekable),". Seeking to ")+"".concat(seekTo,".")),this.tech_.setCurrentTime(seekTo),!0;const sourceUpdater=this.playlistController_.sourceUpdater_,buffered=this.tech_.buffered(),audioBuffered=sourceUpdater.audioBuffer?sourceUpdater.audioBuffered():null,videoBuffered=sourceUpdater.videoBuffer?sourceUpdater.videoBuffered():null,media=this.media(),minAppendedDuration=media.partTargetDuration?media.partTargetDuration:2*(media.targetDuration-.03333333333333333),bufferedToCheck=[audioBuffered,videoBuffered];for(let i=0;i ").concat(currentRange.end(0),"]. Attempting to resume ")+"playback by seeking to the current time."),void this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"})):void 0}techWaiting_(){const seekable=this.seekable(),currentTime=this.tech_.currentTime();if(this.tech_.seeking())return!0;if(this.beforeSeekableWindow_(seekable,currentTime)){const livePoint=seekable.end(seekable.length-1);return this.logger_("Fell out of live window at time ".concat(currentTime,". Seeking to ")+"live point (seekable end) ".concat(livePoint)),this.resetTimeUpdate_(),this.tech_.setCurrentTime(livePoint),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),!0}const sourceUpdater=this.tech_.vhs.playlistController_.sourceUpdater_,buffered=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:sourceUpdater.audioBuffered(),videoBuffered:sourceUpdater.videoBuffered(),currentTime:currentTime}))return this.resetTimeUpdate_(),this.tech_.setCurrentTime(currentTime),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),!0;const nextRange=findNextRange(buffered,currentTime);return nextRange.length>0&&(this.logger_("Stopped at ".concat(currentTime," and seeking to ").concat(nextRange.start(0))),this.resetTimeUpdate_(),this.skipTheGap_(currentTime),!0)}afterSeekableWindow_(seekable,currentTime,playlist){let allowSeeksWithinUnsafeLiveWindow=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!seekable.length)return!1;let allowedEnd=seekable.end(seekable.length-1)+.1;const isLive=!playlist.endList,isLLHLS="number"==typeof playlist.partTargetDuration;return isLive&&(isLLHLS||allowSeeksWithinUnsafeLiveWindow)&&(allowedEnd=seekable.end(seekable.length-1)+3*playlist.targetDuration),currentTime>allowedEnd}beforeSeekableWindow_(seekable,currentTime){return!!(seekable.length&&seekable.start(0)>0&¤tTime2)return{start:start,end:end}}return null}}const defaultOptions={errorInterval:30,getSource(next){return next(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},initPlugin=function(player,options){let lastCalled=0,seekTo=0;const localOptions=merge(defaultOptions,options);player.ready((()=>{player.trigger({type:"usage",name:"vhs-error-reload-initialized"})}));const loadedMetadataHandler=function(){seekTo&&player.currentTime(seekTo)},setSource=function(sourceObj){null!=sourceObj&&(seekTo=player.duration()!==1/0&&player.currentTime()||0,player.one("loadedmetadata",loadedMetadataHandler),player.src(sourceObj),player.trigger({type:"usage",name:"vhs-error-reload"}),player.play())},errorHandler=function(){if(Date.now()-lastCalled<1e3*localOptions.errorInterval)player.trigger({type:"usage",name:"vhs-error-reload-canceled"});else{if(localOptions.getSource&&"function"==typeof localOptions.getSource)return lastCalled=Date.now(),localOptions.getSource.call(player,setSource);videojs.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}},cleanupEvents=function(){player.off("loadedmetadata",loadedMetadataHandler),player.off("error",errorHandler),player.off("dispose",cleanupEvents)};player.on("error",errorHandler),player.on("dispose",cleanupEvents),player.reloadSourceOnError=function(newOptions){cleanupEvents(),initPlugin(player,newOptions)}},reloadSourceOnError=function(options){initPlugin(this,options)};const Vhs={PlaylistLoader:PlaylistLoader,Playlist:Playlist,utils:utils,STANDARD_PLAYLIST_SELECTOR:lastBandwidthSelector,INITIAL_PLAYLIST_SELECTOR:function(){const playlists=this.playlists.main.playlists.filter(Playlist.isEnabled);stableSort(playlists,((a,b)=>comparePlaylistBandwidth(a,b)));return playlists.filter((playlist=>!!codecsForPlaylist(this.playlists.main,playlist).video))[0]||null},lastBandwidthSelector:lastBandwidthSelector,movingAverageBandwidthSelector:function(decay){let average=-1,lastSystemBandwidth=-1;if(decay<0||decay>1)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){const pixelRatio=this.useDevicePixelRatio&&window.devicePixelRatio||1;return average<0&&(average=this.systemBandwidth,lastSystemBandwidth=this.systemBandwidth),this.systemBandwidth>0&&this.systemBandwidth!==lastSystemBandwidth&&(average=decay*this.systemBandwidth+(1-decay)*average,lastSystemBandwidth=this.systemBandwidth),simpleSelector(this.playlists.main,average,parseInt(safeGetComputedStyle(this.tech_.el(),"width"),10)*pixelRatio,parseInt(safeGetComputedStyle(this.tech_.el(),"height"),10)*pixelRatio,this.limitRenditionByPlayerDimensions,this.playlistController_)}},comparePlaylistBandwidth:comparePlaylistBandwidth,comparePlaylistResolution:function(left,right){let leftWidth,rightWidth;return left.attributes.RESOLUTION&&left.attributes.RESOLUTION.width&&(leftWidth=left.attributes.RESOLUTION.width),leftWidth=leftWidth||window.Number.MAX_VALUE,right.attributes.RESOLUTION&&right.attributes.RESOLUTION.width&&(rightWidth=right.attributes.RESOLUTION.width),rightWidth=rightWidth||window.Number.MAX_VALUE,leftWidth===rightWidth&&left.attributes.BANDWIDTH&&right.attributes.BANDWIDTH?left.attributes.BANDWIDTH-right.attributes.BANDWIDTH:leftWidth-rightWidth},xhr:xhrFactory()};Object.keys(Config).forEach((prop=>{Object.defineProperty(Vhs,prop,{get:()=>(videojs.log.warn("using Vhs.".concat(prop," is UNSAFE be sure you know what you are doing")),Config[prop]),set(value){videojs.log.warn("using Vhs.".concat(prop," is UNSAFE be sure you know what you are doing")),"number"!=typeof value||value<0?videojs.log.warn("value of Vhs.".concat(prop," must be greater than or equal to 0")):Config[prop]=value}})}));const handleVhsMediaChange=function(qualityLevels,playlistLoader){const newPlaylist=playlistLoader.media();let selectedIndex=-1;for(let i=0;i{let{player:player,sourceKeySystems:sourceKeySystems,audioMedia:audioMedia,mainPlaylists:mainPlaylists}=_ref84;if(!player.eme.initializeMediaKeys)return Promise.resolve();const keySystemsOptionsArr=((playlists,keySystems)=>playlists.reduce(((keySystemsArr,playlist)=>{if(!playlist.contentProtection)return keySystemsArr;const keySystemsOptions=keySystems.reduce(((keySystemsObj,keySystem)=>{const keySystemOptions=playlist.contentProtection[keySystem];return keySystemOptions&&keySystemOptions.pssh&&(keySystemsObj[keySystem]={pssh:keySystemOptions.pssh}),keySystemsObj}),{});return Object.keys(keySystemsOptions).length&&keySystemsArr.push(keySystemsOptions),keySystemsArr}),[]))(audioMedia?mainPlaylists.concat([audioMedia]):mainPlaylists,Object.keys(sourceKeySystems)),initializationFinishedPromises=[],keySessionCreatedPromises=[];return keySystemsOptionsArr.forEach((keySystemsOptions=>{keySessionCreatedPromises.push(new Promise(((resolve,reject)=>{player.tech_.one("keysessioncreated",resolve)}))),initializationFinishedPromises.push(new Promise(((resolve,reject)=>{player.eme.initializeMediaKeys({keySystems:keySystemsOptions},(err=>{err?reject(err):resolve()}))})))})),Promise.race([Promise.all(initializationFinishedPromises),Promise.race(keySessionCreatedPromises)])},setupEmeOptions=_ref85=>{let{player:player,sourceKeySystems:sourceKeySystems,media:media,audioMedia:audioMedia}=_ref85;const sourceOptions=((keySystemOptions,mainPlaylist,audioPlaylist)=>{if(!keySystemOptions)return keySystemOptions;let codecs={};mainPlaylist&&mainPlaylist.attributes&&mainPlaylist.attributes.CODECS&&(codecs=unwrapCodecList(parseCodecs(mainPlaylist.attributes.CODECS))),audioPlaylist&&audioPlaylist.attributes&&audioPlaylist.attributes.CODECS&&(codecs.audio=audioPlaylist.attributes.CODECS);const videoContentType=getMimeForCodec(codecs.video),audioContentType=getMimeForCodec(codecs.audio),keySystemContentTypes={};for(const keySystem in keySystemOptions)keySystemContentTypes[keySystem]={},audioContentType&&(keySystemContentTypes[keySystem].audioContentType=audioContentType),videoContentType&&(keySystemContentTypes[keySystem].videoContentType=videoContentType),mainPlaylist.contentProtection&&mainPlaylist.contentProtection[keySystem]&&mainPlaylist.contentProtection[keySystem].pssh&&(keySystemContentTypes[keySystem].pssh=mainPlaylist.contentProtection[keySystem].pssh),"string"==typeof keySystemOptions[keySystem]&&(keySystemContentTypes[keySystem].url=keySystemOptions[keySystem]);return merge(keySystemOptions,keySystemContentTypes)})(sourceKeySystems,media,audioMedia);return!!sourceOptions&&(player.currentSource().keySystems=sourceOptions,!(sourceOptions&&!player.eme)||(videojs.log.warn("DRM encrypted source cannot be decrypted without a DRM plugin"),!1))},getVhsLocalStorage=()=>{if(!window.localStorage)return null;const storedObject=window.localStorage.getItem("videojs-vhs");if(!storedObject)return null;try{return JSON.parse(storedObject)}catch(e){return null}},addOnRequestHook=(xhr,callback)=>{xhr._requestCallbackSet||(xhr._requestCallbackSet=new Set),xhr._requestCallbackSet.add(callback)},addOnResponseHook=(xhr,callback)=>{xhr._responseCallbackSet||(xhr._responseCallbackSet=new Set),xhr._responseCallbackSet.add(callback)},removeOnRequestHook=(xhr,callback)=>{xhr._requestCallbackSet&&(xhr._requestCallbackSet.delete(callback),xhr._requestCallbackSet.size||delete xhr._requestCallbackSet)},removeOnResponseHook=(xhr,callback)=>{xhr._responseCallbackSet&&(xhr._responseCallbackSet.delete(callback),xhr._responseCallbackSet.size||delete xhr._responseCallbackSet)};Vhs.supportsNativeHls=function(){if(!document||!document.createElement)return!1;const video=document.createElement("video");if(!videojs.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(canItPlay){return/maybe|probably/i.test(video.canPlayType(canItPlay))}))}(),Vhs.supportsNativeDash=!!(document&&document.createElement&&videojs.getTech("Html5").isSupported())&&/maybe|probably/i.test(document.createElement("video").canPlayType("application/dash+xml")),Vhs.supportsTypeNatively=type=>"hls"===type?Vhs.supportsNativeHls:"dash"===type&&Vhs.supportsNativeDash,Vhs.isSupported=function(){return videojs.log.warn("VHS is no longer a tech. Please remove it from your player's techOrder.")},Vhs.xhr.onRequest=function(callback){addOnRequestHook(Vhs.xhr,callback)},Vhs.xhr.onResponse=function(callback){addOnResponseHook(Vhs.xhr,callback)},Vhs.xhr.offRequest=function(callback){removeOnRequestHook(Vhs.xhr,callback)},Vhs.xhr.offResponse=function(callback){removeOnResponseHook(Vhs.xhr,callback)};const Component=videojs.getComponent("Component");class VhsHandler extends Component{constructor(source,tech,options){if(super(tech,options.vhs),"number"==typeof options.initialBandwidth&&(this.options_.bandwidth=options.initialBandwidth),this.logger_=logger("VhsHandler"),tech.options_&&tech.options_.playerId){const _player=videojs.getPlayer(tech.options_.playerId);this.player_=_player}if(this.tech_=tech,this.source_=source,this.stats={},this.ignoreNextSeekingEvent_=!1,this.setOptions_(),this.options_.overrideNative&&tech.overrideNativeAudioTracks&&tech.overrideNativeVideoTracks)tech.overrideNativeAudioTracks(!0),tech.overrideNativeVideoTracks(!0);else if(this.options_.overrideNative&&(tech.featuresNativeVideoTracks||tech.featuresNativeAudioTracks))throw new Error("Overriding native VHS requires emulated tracks. See https://git.io/vMpjB");this.on(document,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],(event=>{const fullscreenElement=document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement;fullscreenElement&&fullscreenElement.contains(this.tech_.el())?this.playlistController_.fastQualityChange_():this.playlistController_.checkABR_()})),this.on(this.tech_,"seeking",(function(){this.ignoreNextSeekingEvent_?this.ignoreNextSeekingEvent_=!1:this.setCurrentTime(this.tech_.currentTime())})),this.on(this.tech_,"error",(function(){this.tech_.error()&&this.playlistController_&&this.playlistController_.pauseLoading()})),this.on(this.tech_,"play",this.play)}setOptions_(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.options_=merge(this.options_,options),this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.useDevicePixelRatio=this.options_.useDevicePixelRatio||!1,this.options_.useBandwidthFromLocalStorage=void 0!==this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.useForcedSubtitles=this.options_.useForcedSubtitles||!1,this.options_.useNetworkInformationApi=this.options_.useNetworkInformationApi||!1,this.options_.useDtsForTimestampOffset=this.options_.useDtsForTimestampOffset||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,this.options_.llhls=!1!==this.options_.llhls,this.options_.bufferBasedABR=this.options_.bufferBasedABR||!1,"number"!=typeof this.options_.playlistExclusionDuration&&(this.options_.playlistExclusionDuration=60),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage){const storedObject=getVhsLocalStorage();storedObject&&storedObject.bandwidth&&(this.options_.bandwidth=storedObject.bandwidth,this.tech_.trigger({type:"usage",name:"vhs-bandwidth-from-local-storage"})),storedObject&&storedObject.throughput&&(this.options_.throughput=storedObject.throughput,this.tech_.trigger({type:"usage",name:"vhs-throughput-from-local-storage"}))}"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=Config.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===Config.INITIAL_BANDWIDTH,["withCredentials","useDevicePixelRatio","limitRenditionByPlayerDimensions","bandwidth","customTagParsers","customTagMappers","cacheEncryptionKeys","playlistSelector","initialPlaylistSelector","bufferBasedABR","liveRangeSafeTimeDelta","llhls","useForcedSubtitles","useNetworkInformationApi","useDtsForTimestampOffset","exactManifestTimings","leastPixelDiffSelector"].forEach((option=>{void 0!==this.source_[option]&&(this.options_[option]=this.source_[option])})),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions,this.useDevicePixelRatio=this.options_.useDevicePixelRatio}setOptions(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.setOptions_(options)}src(src,type){if(!src)return;var dataUri;this.setOptions_(),this.options_.src=0===(dataUri=this.source_.src).toLowerCase().indexOf("data:application/vnd.videojs.vhs+json,")?JSON.parse(dataUri.substring(dataUri.indexOf(",")+1)):dataUri,this.options_.tech=this.tech_,this.options_.externVhs=Vhs,this.options_.sourceType=simpleTypeFromSourceType(type),this.options_.seekTo=time=>{this.tech_.setCurrentTime(time)},this.playlistController_=new PlaylistController(this.options_);const playbackWatcherOptions=merge({liveRangeSafeTimeDelta:.1},this.options_,{seekable:()=>this.seekable(),media:()=>this.playlistController_.media(),playlistController:this.playlistController_});this.playbackWatcher_=new PlaybackWatcher(playbackWatcherOptions),this.playlistController_.on("error",(()=>{const player=videojs.players[this.tech_.options_.playerId];let error=this.playlistController_.error;"object"!=typeof error||error.code?"string"==typeof error&&(error={message:error,code:3}):error.code=3,player.error(error)}));const defaultSelector=this.options_.bufferBasedABR?Vhs.movingAverageBandwidthSelector(.55):Vhs.STANDARD_PLAYLIST_SELECTOR;this.playlistController_.selectPlaylist=this.selectPlaylist?this.selectPlaylist.bind(this):defaultSelector.bind(this),this.playlistController_.selectInitialPlaylist=Vhs.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.playlistController_.mainPlaylistLoader_,this.mediaSource=this.playlistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get(){return this.playlistController_.selectPlaylist},set(selectPlaylist){this.playlistController_.selectPlaylist=selectPlaylist.bind(this)}},throughput:{get(){return this.playlistController_.mainSegmentLoader_.throughput.rate},set(throughput){this.playlistController_.mainSegmentLoader_.throughput.rate=throughput,this.playlistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get(){let playerBandwidthEst=this.playlistController_.mainSegmentLoader_.bandwidth;const networkInformation=window.navigator.connection||window.navigator.mozConnection||window.navigator.webkitConnection;if(this.options_.useNetworkInformationApi&&networkInformation){const networkInfoBandwidthEstBitsPerSec=1e3*networkInformation.downlink*1e3;playerBandwidthEst=networkInfoBandwidthEstBitsPerSec>=1e7&&playerBandwidthEst>=1e7?Math.max(playerBandwidthEst,networkInfoBandwidthEstBitsPerSec):networkInfoBandwidthEstBitsPerSec}return playerBandwidthEst},set(bandwidth){this.playlistController_.mainSegmentLoader_.bandwidth=bandwidth,this.playlistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get(){const invBandwidth=1/(this.bandwidth||1);let invThroughput;invThroughput=this.throughput>0?1/this.throughput:0;return Math.floor(1/(invBandwidth+invThroughput))},set(){videojs.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:()=>this.bandwidth||0,enumerable:!0},mediaRequests:{get:()=>this.playlistController_.mediaRequests_()||0,enumerable:!0},mediaRequestsAborted:{get:()=>this.playlistController_.mediaRequestsAborted_()||0,enumerable:!0},mediaRequestsTimedout:{get:()=>this.playlistController_.mediaRequestsTimedout_()||0,enumerable:!0},mediaRequestsErrored:{get:()=>this.playlistController_.mediaRequestsErrored_()||0,enumerable:!0},mediaTransferDuration:{get:()=>this.playlistController_.mediaTransferDuration_()||0,enumerable:!0},mediaBytesTransferred:{get:()=>this.playlistController_.mediaBytesTransferred_()||0,enumerable:!0},mediaSecondsLoaded:{get:()=>this.playlistController_.mediaSecondsLoaded_()||0,enumerable:!0},mediaAppends:{get:()=>this.playlistController_.mediaAppends_()||0,enumerable:!0},mainAppendsToLoadedData:{get:()=>this.playlistController_.mainAppendsToLoadedData_()||0,enumerable:!0},audioAppendsToLoadedData:{get:()=>this.playlistController_.audioAppendsToLoadedData_()||0,enumerable:!0},appendsToLoadedData:{get:()=>this.playlistController_.appendsToLoadedData_()||0,enumerable:!0},timeToLoadedData:{get:()=>this.playlistController_.timeToLoadedData_()||0,enumerable:!0},buffered:{get:()=>timeRangesToArray(this.tech_.buffered()),enumerable:!0},currentTime:{get:()=>this.tech_.currentTime(),enumerable:!0},currentSource:{get:()=>this.tech_.currentSource_,enumerable:!0},currentTech:{get:()=>this.tech_.name_,enumerable:!0},duration:{get:()=>this.tech_.duration(),enumerable:!0},main:{get:()=>this.playlists.main,enumerable:!0},playerDimensions:{get:()=>this.tech_.currentDimensions(),enumerable:!0},seekable:{get:()=>timeRangesToArray(this.tech_.seekable()),enumerable:!0},timestamp:{get:()=>Date.now(),enumerable:!0},videoPlaybackQuality:{get:()=>this.tech_.getVideoPlaybackQuality(),enumerable:!0}}),this.tech_.one("canplay",this.playlistController_.setupFirstPlay.bind(this.playlistController_)),this.tech_.on("bandwidthupdate",(()=>{this.options_.useBandwidthFromLocalStorage&&(options=>{if(!window.localStorage)return!1;let objectToStore=getVhsLocalStorage();objectToStore=objectToStore?merge(objectToStore,options):options;try{window.localStorage.setItem("videojs-vhs",JSON.stringify(objectToStore))}catch(e){return!1}})({bandwidth:this.bandwidth,throughput:Math.round(this.throughput)})})),this.playlistController_.on("selectedinitialmedia",(()=>{var vhsHandler;(vhsHandler=this).representations=()=>{const main=vhsHandler.playlistController_.main(),playlists=isAudioOnly(main)?vhsHandler.playlistController_.getAudioTrackPlaylists_():main.playlists;return playlists?playlists.filter((media=>!isIncompatible(media))).map(((e,i)=>new Representation(vhsHandler,e,e.id))):[]}})),this.playlistController_.sourceUpdater_.on("createdsourcebuffers",(()=>{this.setupEme_()})),this.on(this.playlistController_,"progress",(function(){this.tech_.trigger("progress")})),this.on(this.playlistController_,"firstplay",(function(){this.ignoreNextSeekingEvent_=!0})),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=window.URL.createObjectURL(this.playlistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_))}createKeySessions_(){const audioPlaylistLoader=this.playlistController_.mediaTypes_.AUDIO.activePlaylistLoader;this.logger_("waiting for EME key session creation"),waitForKeySessionCreation({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:audioPlaylistLoader&&audioPlaylistLoader.media(),mainPlaylists:this.playlists.main.playlists}).then((()=>{this.logger_("created EME key session"),this.playlistController_.sourceUpdater_.initializedEme()})).catch((err=>{this.logger_("error while creating EME key session",err),this.player_.error({message:"Failed to initialize media keys for EME",code:3})}))}handleWaitingForKey_(){this.logger_("waitingforkey fired, attempting to create any new key sessions"),this.createKeySessions_()}setupEme_(){const audioPlaylistLoader=this.playlistController_.mediaTypes_.AUDIO.activePlaylistLoader,didSetupEmeOptions=setupEmeOptions({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:audioPlaylistLoader&&audioPlaylistLoader.media()});this.player_.tech_.on("keystatuschange",(e=>{this.playlistController_.updatePlaylistByKeyStatus(e.keyId,e.status)})),this.handleWaitingForKey_=this.handleWaitingForKey_.bind(this),this.player_.tech_.on("waitingforkey",this.handleWaitingForKey_),didSetupEmeOptions?this.createKeySessions_():this.playlistController_.sourceUpdater_.initializedEme()}setupQualityLevels_(){const player=videojs.players[this.tech_.options_.playerId];player&&player.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=player.qualityLevels(),this.playlistController_.on("selectedinitialmedia",(()=>{var qualityLevels,vhs;qualityLevels=this.qualityLevels_,(vhs=this).representations().forEach((rep=>{qualityLevels.addQualityLevel(rep)})),handleVhsMediaChange(qualityLevels,vhs.playlists)})),this.playlists.on("mediachange",(()=>{handleVhsMediaChange(this.qualityLevels_,this.playlists)})))}static version(){return{"@videojs/http-streaming":"3.10.0","mux.js":"7.0.2","mpd-parser":"1.3.0","m3u8-parser":"7.1.0","aes-decrypter":"4.0.1"}}version(){return this.constructor.version()}canChangeType(){return SourceUpdater.canChangeType()}play(){this.playlistController_.play()}setCurrentTime(currentTime){this.playlistController_.setCurrentTime(currentTime)}duration(){return this.playlistController_.duration()}seekable(){return this.playlistController_.seekable()}dispose(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.playlistController_&&this.playlistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.mediaSourceUrl_&&window.URL.revokeObjectURL&&(window.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),this.tech_&&this.tech_.off("waitingforkey",this.handleWaitingForKey_),super.dispose()}convertToProgramTime(time,callback){return getProgramTime({playlist:this.playlistController_.media(),time:time,callback:callback})}seekToProgramTime(programTime,callback){let pauseAfterSeek=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],retryCount=arguments.length>3&&void 0!==arguments[3]?arguments[3]:2;return seekToProgramTime({programTime:programTime,playlist:this.playlistController_.media(),retryCount:retryCount,pauseAfterSeek:pauseAfterSeek,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:callback})}setupXhrHooks_(){this.xhr.onRequest=callback=>{addOnRequestHook(this.xhr,callback)},this.xhr.onResponse=callback=>{addOnResponseHook(this.xhr,callback)},this.xhr.offRequest=callback=>{removeOnRequestHook(this.xhr,callback)},this.xhr.offResponse=callback=>{removeOnResponseHook(this.xhr,callback)},this.player_.trigger("xhr-hooks-ready")}}const VhsSourceHandler={name:"videojs-http-streaming",VERSION:"3.10.0",canHandleSource(srcObj){let options=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const localOptions=merge(videojs.options,options);return VhsSourceHandler.canPlayType(srcObj.type,localOptions)},handleSource(source,tech){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const localOptions=merge(videojs.options,options);return tech.vhs=new VhsHandler(source,tech,localOptions),tech.vhs.xhr=xhrFactory(),tech.vhs.setupXhrHooks_(),tech.vhs.src(source.src,source.type),tech.vhs},canPlayType(type,options){const simpleType=simpleTypeFromSourceType(type);if(!simpleType)return"";const overrideNative=VhsSourceHandler.getOverrideNative(options);return!Vhs.supportsTypeNatively(simpleType)||overrideNative?"maybe":""},getOverrideNative(){let options=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{vhs:vhs={}}=options,defaultOverrideNative=!(videojs.browser.IS_ANY_SAFARI||videojs.browser.IS_IOS),{overrideNative:overrideNative=defaultOverrideNative}=vhs;return overrideNative}};return browserSupportsCodec("avc1.4d400d,mp4a.40.2")&&videojs.getTech("Html5").registerSourceHandler(VhsSourceHandler,0),videojs.VhsHandler=VhsHandler,videojs.VhsSourceHandler=VhsSourceHandler,videojs.Vhs=Vhs,videojs.use||videojs.registerComponent("Vhs",Vhs),videojs.options.vhs=videojs.options.vhs||{},videojs.getPlugin&&videojs.getPlugin("reloadSourceOnError")||videojs.registerPlugin("reloadSourceOnError",reloadSourceOnError),videojs})); //# sourceMappingURL=video-lazy.min.js.map \ No newline at end of file diff --git a/media/player/videojs/amd/build/video-lazy.min.js.map b/media/player/videojs/amd/build/video-lazy.min.js.map index edb51eaf093a..478c36dc43b1 100644 --- a/media/player/videojs/amd/build/video-lazy.min.js.map +++ b/media/player/videojs/amd/build/video-lazy.min.js.map @@ -1 +1 @@ -{"version":3,"file":"video-lazy.min.js","sources":["../src/video-lazy.js"],"sourcesContent":["/**\n * @license\n * Video.js 8.3.0 \n * Copyright Brightcove, Inc. \n * Available under Apache License Version 2.0\n * \n *\n * Includes vtt.js \n * Available under Apache License Version 2.0\n * \n */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojs = factory());\n})(this, (function () { 'use strict';\n\n var version$5 = \"8.3.0\";\n\n /**\n * An Object that contains lifecycle hooks as keys which point to an array\n * of functions that are run when a lifecycle is triggered\n *\n * @private\n */\n const hooks_ = {};\n\n /**\n * Get a list of hooks for a specific lifecycle\n *\n * @param {string} type\n * the lifecycle to get hooks from\n *\n * @param {Function|Function[]} [fn]\n * Optionally add a hook (or hooks) to the lifecycle that your are getting.\n *\n * @return {Array}\n * an array of hooks, or an empty array if there are none.\n */\n const hooks = function (type, fn) {\n hooks_[type] = hooks_[type] || [];\n if (fn) {\n hooks_[type] = hooks_[type].concat(fn);\n }\n return hooks_[type];\n };\n\n /**\n * Add a function hook to a specific videojs lifecycle.\n *\n * @param {string} type\n * the lifecycle to hook the function to.\n *\n * @param {Function|Function[]}\n * The function or array of functions to attach.\n */\n const hook = function (type, fn) {\n hooks(type, fn);\n };\n\n /**\n * Remove a hook from a specific videojs lifecycle.\n *\n * @param {string} type\n * the lifecycle that the function hooked to\n *\n * @param {Function} fn\n * The hooked function to remove\n *\n * @return {boolean}\n * The function that was removed or undef\n */\n const removeHook = function (type, fn) {\n const index = hooks(type).indexOf(fn);\n if (index <= -1) {\n return false;\n }\n hooks_[type] = hooks_[type].slice();\n hooks_[type].splice(index, 1);\n return true;\n };\n\n /**\n * Add a function hook that will only run once to a specific videojs lifecycle.\n *\n * @param {string} type\n * the lifecycle to hook the function to.\n *\n * @param {Function|Function[]}\n * The function or array of functions to attach.\n */\n const hookOnce = function (type, fn) {\n hooks(type, [].concat(fn).map(original => {\n const wrapper = (...args) => {\n removeHook(type, wrapper);\n return original(...args);\n };\n return wrapper;\n }));\n };\n\n /**\n * @file fullscreen-api.js\n * @module fullscreen-api\n */\n\n /**\n * Store the browser-specific methods for the fullscreen API.\n *\n * @type {Object}\n * @see [Specification]{@link https://fullscreen.spec.whatwg.org}\n * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}\n */\n const FullscreenApi = {\n prefixed: true\n };\n\n // browser API methods\n const apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror', 'fullscreen'],\n // WebKit\n ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror', '-webkit-full-screen'],\n // Mozilla\n ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror', '-moz-full-screen'],\n // Microsoft\n ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError', '-ms-fullscreen']];\n const specApi = apiMap[0];\n let browserApi;\n\n // determine the supported set of functions\n for (let i = 0; i < apiMap.length; i++) {\n // check for exitFullscreen function\n if (apiMap[i][1] in document) {\n browserApi = apiMap[i];\n break;\n }\n }\n\n // map the browser API names to the spec API names\n if (browserApi) {\n for (let i = 0; i < browserApi.length; i++) {\n FullscreenApi[specApi[i]] = browserApi[i];\n }\n FullscreenApi.prefixed = browserApi[0] !== specApi[0];\n }\n\n /**\n * @file create-logger.js\n * @module create-logger\n */\n\n // This is the private tracking variable for the logging history.\n let history = [];\n\n /**\n * Log messages to the console and history based on the type of message\n *\n * @private\n * @param {string} type\n * The name of the console method to use.\n *\n * @param {Array} args\n * The arguments to be passed to the matching console method.\n */\n const LogByTypeFactory = (name, log) => (type, level, args) => {\n const lvl = log.levels[level];\n const lvlRegExp = new RegExp(`^(${lvl})$`);\n if (type !== 'log') {\n // Add the type to the front of the message when it's not \"log\".\n args.unshift(type.toUpperCase() + ':');\n }\n\n // Add console prefix after adding to history.\n args.unshift(name + ':');\n\n // Add a clone of the args at this point to history.\n if (history) {\n history.push([].concat(args));\n\n // only store 1000 history entries\n const splice = history.length - 1000;\n history.splice(0, splice > 0 ? splice : 0);\n }\n\n // If there's no console then don't try to output messages, but they will\n // still be stored in history.\n if (!window.console) {\n return;\n }\n\n // Was setting these once outside of this function, but containing them\n // in the function makes it easier to test cases where console doesn't exist\n // when the module is executed.\n let fn = window.console[type];\n if (!fn && type === 'debug') {\n // Certain browsers don't have support for console.debug. For those, we\n // should default to the closest comparable log.\n fn = window.console.info || window.console.log;\n }\n\n // Bail out if there's no console or if this type is not allowed by the\n // current logging level.\n if (!fn || !lvl || !lvlRegExp.test(type)) {\n return;\n }\n fn[Array.isArray(args) ? 'apply' : 'call'](window.console, args);\n };\n function createLogger$1(name) {\n // This is the private tracking variable for logging level.\n let level = 'info';\n\n // the curried logByType bound to the specific log and history\n let logByType;\n\n /**\n * Logs plain debug messages. Similar to `console.log`.\n *\n * Due to [limitations](https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149)\n * of our JSDoc template, we cannot properly document this as both a function\n * and a namespace, so its function signature is documented here.\n *\n * #### Arguments\n * ##### *args\n * *[]\n *\n * Any combination of values that could be passed to `console.log()`.\n *\n * #### Return Value\n *\n * `undefined`\n *\n * @namespace\n * @param {...*} args\n * One or more messages or objects that should be logged.\n */\n const log = function (...args) {\n logByType('log', level, args);\n };\n\n // This is the logByType helper that the logging methods below use\n logByType = LogByTypeFactory(name, log);\n\n /**\n * Create a new sublogger which chains the old name to the new name.\n *\n * For example, doing `videojs.log.createLogger('player')` and then using that logger will log the following:\n * ```js\n * mylogger('foo');\n * // > VIDEOJS: player: foo\n * ```\n *\n * @param {string} name\n * The name to add call the new logger\n * @return {Object}\n */\n log.createLogger = subname => createLogger$1(name + ': ' + subname);\n\n /**\n * Enumeration of available logging levels, where the keys are the level names\n * and the values are `|`-separated strings containing logging methods allowed\n * in that logging level. These strings are used to create a regular expression\n * matching the function name being called.\n *\n * Levels provided by Video.js are:\n *\n * - `off`: Matches no calls. Any value that can be cast to `false` will have\n * this effect. The most restrictive.\n * - `all`: Matches only Video.js-provided functions (`debug`, `log`,\n * `log.warn`, and `log.error`).\n * - `debug`: Matches `log.debug`, `log`, `log.warn`, and `log.error` calls.\n * - `info` (default): Matches `log`, `log.warn`, and `log.error` calls.\n * - `warn`: Matches `log.warn` and `log.error` calls.\n * - `error`: Matches only `log.error` calls.\n *\n * @type {Object}\n */\n log.levels = {\n all: 'debug|log|warn|error',\n off: '',\n debug: 'debug|log|warn|error',\n info: 'log|warn|error',\n warn: 'warn|error',\n error: 'error',\n DEFAULT: level\n };\n\n /**\n * Get or set the current logging level.\n *\n * If a string matching a key from {@link module:log.levels} is provided, acts\n * as a setter.\n *\n * @param {string} [lvl]\n * Pass a valid level to set a new logging level.\n *\n * @return {string}\n * The current logging level.\n */\n log.level = lvl => {\n if (typeof lvl === 'string') {\n if (!log.levels.hasOwnProperty(lvl)) {\n throw new Error(`\"${lvl}\" in not a valid log level`);\n }\n level = lvl;\n }\n return level;\n };\n\n /**\n * Returns an array containing everything that has been logged to the history.\n *\n * This array is a shallow clone of the internal history record. However, its\n * contents are _not_ cloned; so, mutating objects inside this array will\n * mutate them in history.\n *\n * @return {Array}\n */\n log.history = () => history ? [].concat(history) : [];\n\n /**\n * Allows you to filter the history by the given logger name\n *\n * @param {string} fname\n * The name to filter by\n *\n * @return {Array}\n * The filtered list to return\n */\n log.history.filter = fname => {\n return (history || []).filter(historyItem => {\n // if the first item in each historyItem includes `fname`, then it's a match\n return new RegExp(`.*${fname}.*`).test(historyItem[0]);\n });\n };\n\n /**\n * Clears the internal history tracking, but does not prevent further history\n * tracking.\n */\n log.history.clear = () => {\n if (history) {\n history.length = 0;\n }\n };\n\n /**\n * Disable history tracking if it is currently enabled.\n */\n log.history.disable = () => {\n if (history !== null) {\n history.length = 0;\n history = null;\n }\n };\n\n /**\n * Enable history tracking if it is currently disabled.\n */\n log.history.enable = () => {\n if (history === null) {\n history = [];\n }\n };\n\n /**\n * Logs error messages. Similar to `console.error`.\n *\n * @param {...*} args\n * One or more messages or objects that should be logged as an error\n */\n log.error = (...args) => logByType('error', level, args);\n\n /**\n * Logs warning messages. Similar to `console.warn`.\n *\n * @param {...*} args\n * One or more messages or objects that should be logged as a warning.\n */\n log.warn = (...args) => logByType('warn', level, args);\n\n /**\n * Logs debug messages. Similar to `console.debug`, but may also act as a comparable\n * log if `console.debug` is not available\n *\n * @param {...*} args\n * One or more messages or objects that should be logged as debug.\n */\n log.debug = (...args) => logByType('debug', level, args);\n return log;\n }\n\n /**\n * @file log.js\n * @module log\n */\n const log$1 = createLogger$1('VIDEOJS');\n const createLogger = log$1.createLogger;\n\n /**\n * @file obj.js\n * @module obj\n */\n\n /**\n * @callback obj:EachCallback\n *\n * @param {*} value\n * The current key for the object that is being iterated over.\n *\n * @param {string} key\n * The current key-value for object that is being iterated over\n */\n\n /**\n * @callback obj:ReduceCallback\n *\n * @param {*} accum\n * The value that is accumulating over the reduce loop.\n *\n * @param {*} value\n * The current key for the object that is being iterated over.\n *\n * @param {string} key\n * The current key-value for object that is being iterated over\n *\n * @return {*}\n * The new accumulated value.\n */\n const toString$1 = Object.prototype.toString;\n\n /**\n * Get the keys of an Object\n *\n * @param {Object}\n * The Object to get the keys from\n *\n * @return {string[]}\n * An array of the keys from the object. Returns an empty array if the\n * object passed in was invalid or had no keys.\n *\n * @private\n */\n const keys = function (object) {\n return isObject$1(object) ? Object.keys(object) : [];\n };\n\n /**\n * Array-like iteration for objects.\n *\n * @param {Object} object\n * The object to iterate over\n *\n * @param {obj:EachCallback} fn\n * The callback function which is called for each key in the object.\n */\n function each(object, fn) {\n keys(object).forEach(key => fn(object[key], key));\n }\n\n /**\n * Array-like reduce for objects.\n *\n * @param {Object} object\n * The Object that you want to reduce.\n *\n * @param {Function} fn\n * A callback function which is called for each key in the object. It\n * receives the accumulated value and the per-iteration value and key\n * as arguments.\n *\n * @param {*} [initial = 0]\n * Starting value\n *\n * @return {*}\n * The final accumulated value.\n */\n function reduce(object, fn, initial = 0) {\n return keys(object).reduce((accum, key) => fn(accum, object[key], key), initial);\n }\n\n /**\n * Returns whether a value is an object of any kind - including DOM nodes,\n * arrays, regular expressions, etc. Not functions, though.\n *\n * This avoids the gotcha where using `typeof` on a `null` value\n * results in `'object'`.\n *\n * @param {Object} value\n * @return {boolean}\n */\n function isObject$1(value) {\n return !!value && typeof value === 'object';\n }\n\n /**\n * Returns whether an object appears to be a \"plain\" object - that is, a\n * direct instance of `Object`.\n *\n * @param {Object} value\n * @return {boolean}\n */\n function isPlain(value) {\n return isObject$1(value) && toString$1.call(value) === '[object Object]' && value.constructor === Object;\n }\n\n /**\n * Merge two objects recursively.\n *\n * Performs a deep merge like\n * {@link https://lodash.com/docs/4.17.10#merge|lodash.merge}, but only merges\n * plain objects (not arrays, elements, or anything else).\n *\n * Non-plain object values will be copied directly from the right-most\n * argument.\n *\n * @param {Object[]} sources\n * One or more objects to merge into a new object.\n *\n * @return {Object}\n * A new object that is the merged result of all sources.\n */\n function merge$2(...sources) {\n const result = {};\n sources.forEach(source => {\n if (!source) {\n return;\n }\n each(source, (value, key) => {\n if (!isPlain(value)) {\n result[key] = value;\n return;\n }\n if (!isPlain(result[key])) {\n result[key] = {};\n }\n result[key] = merge$2(result[key], value);\n });\n });\n return result;\n }\n\n /**\n * Object.defineProperty but \"lazy\", which means that the value is only set after\n * it is retrieved the first time, rather than being set right away.\n *\n * @param {Object} obj the object to set the property on\n * @param {string} key the key for the property to set\n * @param {Function} getValue the function used to get the value when it is needed.\n * @param {boolean} setter whether a setter should be allowed or not\n */\n function defineLazyProperty(obj, key, getValue, setter = true) {\n const set = value => Object.defineProperty(obj, key, {\n value,\n enumerable: true,\n writable: true\n });\n const options = {\n configurable: true,\n enumerable: true,\n get() {\n const value = getValue();\n set(value);\n return value;\n }\n };\n if (setter) {\n options.set = set;\n }\n return Object.defineProperty(obj, key, options);\n }\n\n var Obj = /*#__PURE__*/Object.freeze({\n __proto__: null,\n each: each,\n reduce: reduce,\n isObject: isObject$1,\n isPlain: isPlain,\n merge: merge$2,\n defineLazyProperty: defineLazyProperty\n });\n\n /**\n * @file browser.js\n * @module browser\n */\n\n /**\n * Whether or not this device is an iPod.\n *\n * @static\n * @type {Boolean}\n */\n let IS_IPOD = false;\n\n /**\n * The detected iOS version - or `null`.\n *\n * @static\n * @type {string|null}\n */\n let IOS_VERSION = null;\n\n /**\n * Whether or not this is an Android device.\n *\n * @static\n * @type {Boolean}\n */\n let IS_ANDROID = false;\n\n /**\n * The detected Android version - or `null` if not Android or indeterminable.\n *\n * @static\n * @type {number|string|null}\n */\n let ANDROID_VERSION;\n\n /**\n * Whether or not this is Mozilla Firefox.\n *\n * @static\n * @type {Boolean}\n */\n let IS_FIREFOX = false;\n\n /**\n * Whether or not this is Microsoft Edge.\n *\n * @static\n * @type {Boolean}\n */\n let IS_EDGE = false;\n\n /**\n * Whether or not this is any Chromium Browser\n *\n * @static\n * @type {Boolean}\n */\n let IS_CHROMIUM = false;\n\n /**\n * Whether or not this is any Chromium browser that is not Edge.\n *\n * This will also be `true` for Chrome on iOS, which will have different support\n * as it is actually Safari under the hood.\n *\n * Deprecated, as the behaviour to not match Edge was to prevent Legacy Edge's UA matching.\n * IS_CHROMIUM should be used instead.\n * \"Chromium but not Edge\" could be explicitly tested with IS_CHROMIUM && !IS_EDGE\n *\n * @static\n * @deprecated\n * @type {Boolean}\n */\n let IS_CHROME = false;\n\n /**\n * The detected Chromium version - or `null`.\n *\n * @static\n * @type {number|null}\n */\n let CHROMIUM_VERSION = null;\n\n /**\n * The detected Google Chrome version - or `null`.\n * This has always been the _Chromium_ version, i.e. would return on Chromium Edge.\n * Deprecated, use CHROMIUM_VERSION instead.\n *\n * @static\n * @deprecated\n * @type {number|null}\n */\n let CHROME_VERSION = null;\n\n /**\n * The detected Internet Explorer version - or `null`.\n *\n * @static\n * @deprecated\n * @type {number|null}\n */\n let IE_VERSION = null;\n\n /**\n * Whether or not this is desktop Safari.\n *\n * @static\n * @type {Boolean}\n */\n let IS_SAFARI = false;\n\n /**\n * Whether or not this is a Windows machine.\n *\n * @static\n * @type {Boolean}\n */\n let IS_WINDOWS = false;\n\n /**\n * Whether or not this device is an iPad.\n *\n * @static\n * @type {Boolean}\n */\n let IS_IPAD = false;\n\n /**\n * Whether or not this device is an iPhone.\n *\n * @static\n * @type {Boolean}\n */\n // The Facebook app's UIWebView identifies as both an iPhone and iPad, so\n // to identify iPhones, we need to exclude iPads.\n // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/\n let IS_IPHONE = false;\n\n /**\n * Whether or not this device is touch-enabled.\n *\n * @static\n * @const\n * @type {Boolean}\n */\n const TOUCH_ENABLED = Boolean(isReal() && ('ontouchstart' in window || window.navigator.maxTouchPoints || window.DocumentTouch && window.document instanceof window.DocumentTouch));\n const UAD = window.navigator && window.navigator.userAgentData;\n if (UAD) {\n // If userAgentData is present, use it instead of userAgent to avoid warnings\n // Currently only implemented on Chromium\n // userAgentData does not expose Android version, so ANDROID_VERSION remains `null`\n\n IS_ANDROID = UAD.platform === 'Android';\n IS_EDGE = Boolean(UAD.brands.find(b => b.brand === 'Microsoft Edge'));\n IS_CHROMIUM = Boolean(UAD.brands.find(b => b.brand === 'Chromium'));\n IS_CHROME = !IS_EDGE && IS_CHROMIUM;\n CHROMIUM_VERSION = CHROME_VERSION = (UAD.brands.find(b => b.brand === 'Chromium') || {}).version || null;\n IS_WINDOWS = UAD.platform === 'Windows';\n }\n\n // If the browser is not Chromium, either userAgentData is not present which could be an old Chromium browser,\n // or it's a browser that has added userAgentData since that we don't have tests for yet. In either case,\n // the checks need to be made agiainst the regular userAgent string.\n if (!IS_CHROMIUM) {\n const USER_AGENT = window.navigator && window.navigator.userAgent || '';\n IS_IPOD = /iPod/i.test(USER_AGENT);\n IOS_VERSION = function () {\n const match = USER_AGENT.match(/OS (\\d+)_/i);\n if (match && match[1]) {\n return match[1];\n }\n return null;\n }();\n IS_ANDROID = /Android/i.test(USER_AGENT);\n ANDROID_VERSION = function () {\n // This matches Android Major.Minor.Patch versions\n // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned\n const match = USER_AGENT.match(/Android (\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))*/i);\n if (!match) {\n return null;\n }\n const major = match[1] && parseFloat(match[1]);\n const minor = match[2] && parseFloat(match[2]);\n if (major && minor) {\n return parseFloat(match[1] + '.' + match[2]);\n } else if (major) {\n return major;\n }\n return null;\n }();\n IS_FIREFOX = /Firefox/i.test(USER_AGENT);\n IS_EDGE = /Edg/i.test(USER_AGENT);\n IS_CHROMIUM = /Chrome/i.test(USER_AGENT) || /CriOS/i.test(USER_AGENT);\n IS_CHROME = !IS_EDGE && IS_CHROMIUM;\n CHROMIUM_VERSION = CHROME_VERSION = function () {\n const match = USER_AGENT.match(/(Chrome|CriOS)\\/(\\d+)/);\n if (match && match[2]) {\n return parseFloat(match[2]);\n }\n return null;\n }();\n IE_VERSION = function () {\n const result = /MSIE\\s(\\d+)\\.\\d/.exec(USER_AGENT);\n let version = result && parseFloat(result[1]);\n if (!version && /Trident\\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) {\n // IE 11 has a different user agent string than other IE versions\n version = 11.0;\n }\n return version;\n }();\n IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;\n IS_WINDOWS = /Windows/i.test(USER_AGENT);\n IS_IPAD = /iPad/i.test(USER_AGENT) || IS_SAFARI && TOUCH_ENABLED && !/iPhone/i.test(USER_AGENT);\n IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;\n }\n\n /**\n * Whether or not this is an iOS device.\n *\n * @static\n * @const\n * @type {Boolean}\n */\n const IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;\n\n /**\n * Whether or not this is any flavor of Safari - including iOS.\n *\n * @static\n * @const\n * @type {Boolean}\n */\n const IS_ANY_SAFARI = (IS_SAFARI || IS_IOS) && !IS_CHROME;\n\n var browser = /*#__PURE__*/Object.freeze({\n __proto__: null,\n get IS_IPOD () { return IS_IPOD; },\n get IOS_VERSION () { return IOS_VERSION; },\n get IS_ANDROID () { return IS_ANDROID; },\n get ANDROID_VERSION () { return ANDROID_VERSION; },\n get IS_FIREFOX () { return IS_FIREFOX; },\n get IS_EDGE () { return IS_EDGE; },\n get IS_CHROMIUM () { return IS_CHROMIUM; },\n get IS_CHROME () { return IS_CHROME; },\n get CHROMIUM_VERSION () { return CHROMIUM_VERSION; },\n get CHROME_VERSION () { return CHROME_VERSION; },\n get IE_VERSION () { return IE_VERSION; },\n get IS_SAFARI () { return IS_SAFARI; },\n get IS_WINDOWS () { return IS_WINDOWS; },\n get IS_IPAD () { return IS_IPAD; },\n get IS_IPHONE () { return IS_IPHONE; },\n TOUCH_ENABLED: TOUCH_ENABLED,\n IS_IOS: IS_IOS,\n IS_ANY_SAFARI: IS_ANY_SAFARI\n });\n\n /**\n * @file dom.js\n * @module dom\n */\n\n /**\n * Detect if a value is a string with any non-whitespace characters.\n *\n * @private\n * @param {string} str\n * The string to check\n *\n * @return {boolean}\n * Will be `true` if the string is non-blank, `false` otherwise.\n *\n */\n function isNonBlankString(str) {\n // we use str.trim as it will trim any whitespace characters\n // from the front or back of non-whitespace characters. aka\n // Any string that contains non-whitespace characters will\n // still contain them after `trim` but whitespace only strings\n // will have a length of 0, failing this check.\n return typeof str === 'string' && Boolean(str.trim());\n }\n\n /**\n * Throws an error if the passed string has whitespace. This is used by\n * class methods to be relatively consistent with the classList API.\n *\n * @private\n * @param {string} str\n * The string to check for whitespace.\n *\n * @throws {Error}\n * Throws an error if there is whitespace in the string.\n */\n function throwIfWhitespace(str) {\n // str.indexOf instead of regex because str.indexOf is faster performance wise.\n if (str.indexOf(' ') >= 0) {\n throw new Error('class has illegal whitespace characters');\n }\n }\n\n /**\n * Whether the current DOM interface appears to be real (i.e. not simulated).\n *\n * @return {boolean}\n * Will be `true` if the DOM appears to be real, `false` otherwise.\n */\n function isReal() {\n // Both document and window will never be undefined thanks to `global`.\n return document === window.document;\n }\n\n /**\n * Determines, via duck typing, whether or not a value is a DOM element.\n *\n * @param {*} value\n * The value to check.\n *\n * @return {boolean}\n * Will be `true` if the value is a DOM element, `false` otherwise.\n */\n function isEl(value) {\n return isObject$1(value) && value.nodeType === 1;\n }\n\n /**\n * Determines if the current DOM is embedded in an iframe.\n *\n * @return {boolean}\n * Will be `true` if the DOM is embedded in an iframe, `false`\n * otherwise.\n */\n function isInFrame() {\n // We need a try/catch here because Safari will throw errors when attempting\n // to get either `parent` or `self`\n try {\n return window.parent !== window.self;\n } catch (x) {\n return true;\n }\n }\n\n /**\n * Creates functions to query the DOM using a given method.\n *\n * @private\n * @param {string} method\n * The method to create the query with.\n *\n * @return {Function}\n * The query method\n */\n function createQuerier(method) {\n return function (selector, context) {\n if (!isNonBlankString(selector)) {\n return document[method](null);\n }\n if (isNonBlankString(context)) {\n context = document.querySelector(context);\n }\n const ctx = isEl(context) ? context : document;\n return ctx[method] && ctx[method](selector);\n };\n }\n\n /**\n * Creates an element and applies properties, attributes, and inserts content.\n *\n * @param {string} [tagName='div']\n * Name of tag to be created.\n *\n * @param {Object} [properties={}]\n * Element properties to be applied.\n *\n * @param {Object} [attributes={}]\n * Element attributes to be applied.\n *\n * @param {ContentDescriptor} [content]\n * A content descriptor object.\n *\n * @return {Element}\n * The element that was created.\n */\n function createEl(tagName = 'div', properties = {}, attributes = {}, content) {\n const el = document.createElement(tagName);\n Object.getOwnPropertyNames(properties).forEach(function (propName) {\n const val = properties[propName];\n\n // Handle textContent since it's not supported everywhere and we have a\n // method for it.\n if (propName === 'textContent') {\n textContent(el, val);\n } else if (el[propName] !== val || propName === 'tabIndex') {\n el[propName] = val;\n }\n });\n Object.getOwnPropertyNames(attributes).forEach(function (attrName) {\n el.setAttribute(attrName, attributes[attrName]);\n });\n if (content) {\n appendContent(el, content);\n }\n return el;\n }\n\n /**\n * Injects text into an element, replacing any existing contents entirely.\n *\n * @param {Element} el\n * The element to add text content into\n *\n * @param {string} text\n * The text content to add.\n *\n * @return {Element}\n * The element with added text content.\n */\n function textContent(el, text) {\n if (typeof el.textContent === 'undefined') {\n el.innerText = text;\n } else {\n el.textContent = text;\n }\n return el;\n }\n\n /**\n * Insert an element as the first child node of another\n *\n * @param {Element} child\n * Element to insert\n *\n * @param {Element} parent\n * Element to insert child into\n */\n function prependTo(child, parent) {\n if (parent.firstChild) {\n parent.insertBefore(child, parent.firstChild);\n } else {\n parent.appendChild(child);\n }\n }\n\n /**\n * Check if an element has a class name.\n *\n * @param {Element} element\n * Element to check\n *\n * @param {string} classToCheck\n * Class name to check for\n *\n * @return {boolean}\n * Will be `true` if the element has a class, `false` otherwise.\n *\n * @throws {Error}\n * Throws an error if `classToCheck` has white space.\n */\n function hasClass(element, classToCheck) {\n throwIfWhitespace(classToCheck);\n return element.classList.contains(classToCheck);\n }\n\n /**\n * Add a class name to an element.\n *\n * @param {Element} element\n * Element to add class name to.\n *\n * @param {...string} classesToAdd\n * One or more class name to add.\n *\n * @return {Element}\n * The DOM element with the added class name.\n */\n function addClass(element, ...classesToAdd) {\n element.classList.add(...classesToAdd.reduce((prev, current) => prev.concat(current.split(/\\s+/)), []));\n return element;\n }\n\n /**\n * Remove a class name from an element.\n *\n * @param {Element} element\n * Element to remove a class name from.\n *\n * @param {...string} classesToRemove\n * One or more class name to remove.\n *\n * @return {Element}\n * The DOM element with class name removed.\n */\n function removeClass(element, ...classesToRemove) {\n // Protect in case the player gets disposed\n if (!element) {\n log$1.warn(\"removeClass was called with an element that doesn't exist\");\n return null;\n }\n element.classList.remove(...classesToRemove.reduce((prev, current) => prev.concat(current.split(/\\s+/)), []));\n return element;\n }\n\n /**\n * The callback definition for toggleClass.\n *\n * @callback module:dom~PredicateCallback\n * @param {Element} element\n * The DOM element of the Component.\n *\n * @param {string} classToToggle\n * The `className` that wants to be toggled\n *\n * @return {boolean|undefined}\n * If `true` is returned, the `classToToggle` will be added to the\n * `element`. If `false`, the `classToToggle` will be removed from\n * the `element`. If `undefined`, the callback will be ignored.\n */\n\n /**\n * Adds or removes a class name to/from an element depending on an optional\n * condition or the presence/absence of the class name.\n *\n * @param {Element} element\n * The element to toggle a class name on.\n *\n * @param {string} classToToggle\n * The class that should be toggled.\n *\n * @param {boolean|module:dom~PredicateCallback} [predicate]\n * See the return value for {@link module:dom~PredicateCallback}\n *\n * @return {Element}\n * The element with a class that has been toggled.\n */\n function toggleClass(element, classToToggle, predicate) {\n if (typeof predicate === 'function') {\n predicate = predicate(element, classToToggle);\n }\n if (typeof predicate !== 'boolean') {\n predicate = undefined;\n }\n classToToggle.split(/\\s+/).forEach(className => element.classList.toggle(className, predicate));\n return element;\n }\n\n /**\n * Apply attributes to an HTML element.\n *\n * @param {Element} el\n * Element to add attributes to.\n *\n * @param {Object} [attributes]\n * Attributes to be applied.\n */\n function setAttributes(el, attributes) {\n Object.getOwnPropertyNames(attributes).forEach(function (attrName) {\n const attrValue = attributes[attrName];\n if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {\n el.removeAttribute(attrName);\n } else {\n el.setAttribute(attrName, attrValue === true ? '' : attrValue);\n }\n });\n }\n\n /**\n * Get an element's attribute values, as defined on the HTML tag.\n *\n * Attributes are not the same as properties. They're defined on the tag\n * or with setAttribute.\n *\n * @param {Element} tag\n * Element from which to get tag attributes.\n *\n * @return {Object}\n * All attributes of the element. Boolean attributes will be `true` or\n * `false`, others will be strings.\n */\n function getAttributes(tag) {\n const obj = {};\n\n // known boolean attributes\n // we can check for matching boolean properties, but not all browsers\n // and not all tags know about these attributes, so, we still want to check them manually\n const knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ',';\n if (tag && tag.attributes && tag.attributes.length > 0) {\n const attrs = tag.attributes;\n for (let i = attrs.length - 1; i >= 0; i--) {\n const attrName = attrs[i].name;\n let attrVal = attrs[i].value;\n\n // check for known booleans\n // the matching element property will return a value for typeof\n if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {\n // the value of an included boolean attribute is typically an empty\n // string ('') which would equal false if we just check for a false value.\n // we also don't want support bad code like autoplay='false'\n attrVal = attrVal !== null ? true : false;\n }\n obj[attrName] = attrVal;\n }\n }\n return obj;\n }\n\n /**\n * Get the value of an element's attribute.\n *\n * @param {Element} el\n * A DOM element.\n *\n * @param {string} attribute\n * Attribute to get the value of.\n *\n * @return {string}\n * The value of the attribute.\n */\n function getAttribute(el, attribute) {\n return el.getAttribute(attribute);\n }\n\n /**\n * Set the value of an element's attribute.\n *\n * @param {Element} el\n * A DOM element.\n *\n * @param {string} attribute\n * Attribute to set.\n *\n * @param {string} value\n * Value to set the attribute to.\n */\n function setAttribute(el, attribute, value) {\n el.setAttribute(attribute, value);\n }\n\n /**\n * Remove an element's attribute.\n *\n * @param {Element} el\n * A DOM element.\n *\n * @param {string} attribute\n * Attribute to remove.\n */\n function removeAttribute(el, attribute) {\n el.removeAttribute(attribute);\n }\n\n /**\n * Attempt to block the ability to select text.\n */\n function blockTextSelection() {\n document.body.focus();\n document.onselectstart = function () {\n return false;\n };\n }\n\n /**\n * Turn off text selection blocking.\n */\n function unblockTextSelection() {\n document.onselectstart = function () {\n return true;\n };\n }\n\n /**\n * Identical to the native `getBoundingClientRect` function, but ensures that\n * the method is supported at all (it is in all browsers we claim to support)\n * and that the element is in the DOM before continuing.\n *\n * This wrapper function also shims properties which are not provided by some\n * older browsers (namely, IE8).\n *\n * Additionally, some browsers do not support adding properties to a\n * `ClientRect`/`DOMRect` object; so, we shallow-copy it with the standard\n * properties (except `x` and `y` which are not widely supported). This helps\n * avoid implementations where keys are non-enumerable.\n *\n * @param {Element} el\n * Element whose `ClientRect` we want to calculate.\n *\n * @return {Object|undefined}\n * Always returns a plain object - or `undefined` if it cannot.\n */\n function getBoundingClientRect(el) {\n if (el && el.getBoundingClientRect && el.parentNode) {\n const rect = el.getBoundingClientRect();\n const result = {};\n ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(k => {\n if (rect[k] !== undefined) {\n result[k] = rect[k];\n }\n });\n if (!result.height) {\n result.height = parseFloat(computedStyle(el, 'height'));\n }\n if (!result.width) {\n result.width = parseFloat(computedStyle(el, 'width'));\n }\n return result;\n }\n }\n\n /**\n * Represents the position of a DOM element on the page.\n *\n * @typedef {Object} module:dom~Position\n *\n * @property {number} left\n * Pixels to the left.\n *\n * @property {number} top\n * Pixels from the top.\n */\n\n /**\n * Get the position of an element in the DOM.\n *\n * Uses `getBoundingClientRect` technique from John Resig.\n *\n * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/\n *\n * @param {Element} el\n * Element from which to get offset.\n *\n * @return {module:dom~Position}\n * The position of the element that was passed in.\n */\n function findPosition(el) {\n if (!el || el && !el.offsetParent) {\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0\n };\n }\n const width = el.offsetWidth;\n const height = el.offsetHeight;\n let left = 0;\n let top = 0;\n while (el.offsetParent && el !== document[FullscreenApi.fullscreenElement]) {\n left += el.offsetLeft;\n top += el.offsetTop;\n el = el.offsetParent;\n }\n return {\n left,\n top,\n width,\n height\n };\n }\n\n /**\n * Represents x and y coordinates for a DOM element or mouse pointer.\n *\n * @typedef {Object} module:dom~Coordinates\n *\n * @property {number} x\n * x coordinate in pixels\n *\n * @property {number} y\n * y coordinate in pixels\n */\n\n /**\n * Get the pointer position within an element.\n *\n * The base on the coordinates are the bottom left of the element.\n *\n * @param {Element} el\n * Element on which to get the pointer position on.\n *\n * @param {Event} event\n * Event object.\n *\n * @return {module:dom~Coordinates}\n * A coordinates object corresponding to the mouse position.\n *\n */\n function getPointerPosition(el, event) {\n const translated = {\n x: 0,\n y: 0\n };\n if (IS_IOS) {\n let item = el;\n while (item && item.nodeName.toLowerCase() !== 'html') {\n const transform = computedStyle(item, 'transform');\n if (/^matrix/.test(transform)) {\n const values = transform.slice(7, -1).split(/,\\s/).map(Number);\n translated.x += values[4];\n translated.y += values[5];\n } else if (/^matrix3d/.test(transform)) {\n const values = transform.slice(9, -1).split(/,\\s/).map(Number);\n translated.x += values[12];\n translated.y += values[13];\n }\n item = item.parentNode;\n }\n }\n const position = {};\n const boxTarget = findPosition(event.target);\n const box = findPosition(el);\n const boxW = box.width;\n const boxH = box.height;\n let offsetY = event.offsetY - (box.top - boxTarget.top);\n let offsetX = event.offsetX - (box.left - boxTarget.left);\n if (event.changedTouches) {\n offsetX = event.changedTouches[0].pageX - box.left;\n offsetY = event.changedTouches[0].pageY + box.top;\n if (IS_IOS) {\n offsetX -= translated.x;\n offsetY -= translated.y;\n }\n }\n position.y = 1 - Math.max(0, Math.min(1, offsetY / boxH));\n position.x = Math.max(0, Math.min(1, offsetX / boxW));\n return position;\n }\n\n /**\n * Determines, via duck typing, whether or not a value is a text node.\n *\n * @param {*} value\n * Check if this value is a text node.\n *\n * @return {boolean}\n * Will be `true` if the value is a text node, `false` otherwise.\n */\n function isTextNode$1(value) {\n return isObject$1(value) && value.nodeType === 3;\n }\n\n /**\n * Empties the contents of an element.\n *\n * @param {Element} el\n * The element to empty children from\n *\n * @return {Element}\n * The element with no children\n */\n function emptyEl(el) {\n while (el.firstChild) {\n el.removeChild(el.firstChild);\n }\n return el;\n }\n\n /**\n * This is a mixed value that describes content to be injected into the DOM\n * via some method. It can be of the following types:\n *\n * Type | Description\n * -----------|-------------\n * `string` | The value will be normalized into a text node.\n * `Element` | The value will be accepted as-is.\n * `Text` | A TextNode. The value will be accepted as-is.\n * `Array` | A one-dimensional array of strings, elements, text nodes, or functions. These functions should return a string, element, or text node (any other return value, like an array, will be ignored).\n * `Function` | A function, which is expected to return a string, element, text node, or array - any of the other possible values described above. This means that a content descriptor could be a function that returns an array of functions, but those second-level functions must return strings, elements, or text nodes.\n *\n * @typedef {string|Element|Text|Array|Function} ContentDescriptor\n */\n\n /**\n * Normalizes content for eventual insertion into the DOM.\n *\n * This allows a wide range of content definition methods, but helps protect\n * from falling into the trap of simply writing to `innerHTML`, which could\n * be an XSS concern.\n *\n * The content for an element can be passed in multiple types and\n * combinations, whose behavior is as follows:\n *\n * @param {ContentDescriptor} content\n * A content descriptor value.\n *\n * @return {Array}\n * All of the content that was passed in, normalized to an array of\n * elements or text nodes.\n */\n function normalizeContent(content) {\n // First, invoke content if it is a function. If it produces an array,\n // that needs to happen before normalization.\n if (typeof content === 'function') {\n content = content();\n }\n\n // Next up, normalize to an array, so one or many items can be normalized,\n // filtered, and returned.\n return (Array.isArray(content) ? content : [content]).map(value => {\n // First, invoke value if it is a function to produce a new value,\n // which will be subsequently normalized to a Node of some kind.\n if (typeof value === 'function') {\n value = value();\n }\n if (isEl(value) || isTextNode$1(value)) {\n return value;\n }\n if (typeof value === 'string' && /\\S/.test(value)) {\n return document.createTextNode(value);\n }\n }).filter(value => value);\n }\n\n /**\n * Normalizes and appends content to an element.\n *\n * @param {Element} el\n * Element to append normalized content to.\n *\n * @param {ContentDescriptor} content\n * A content descriptor value.\n *\n * @return {Element}\n * The element with appended normalized content.\n */\n function appendContent(el, content) {\n normalizeContent(content).forEach(node => el.appendChild(node));\n return el;\n }\n\n /**\n * Normalizes and inserts content into an element; this is identical to\n * `appendContent()`, except it empties the element first.\n *\n * @param {Element} el\n * Element to insert normalized content into.\n *\n * @param {ContentDescriptor} content\n * A content descriptor value.\n *\n * @return {Element}\n * The element with inserted normalized content.\n */\n function insertContent(el, content) {\n return appendContent(emptyEl(el), content);\n }\n\n /**\n * Check if an event was a single left click.\n *\n * @param {Event} event\n * Event object.\n *\n * @return {boolean}\n * Will be `true` if a single left click, `false` otherwise.\n */\n function isSingleLeftClick(event) {\n // Note: if you create something draggable, be sure to\n // call it on both `mousedown` and `mousemove` event,\n // otherwise `mousedown` should be enough for a button\n\n if (event.button === undefined && event.buttons === undefined) {\n // Why do we need `buttons` ?\n // Because, middle mouse sometimes have this:\n // e.button === 0 and e.buttons === 4\n // Furthermore, we want to prevent combination click, something like\n // HOLD middlemouse then left click, that would be\n // e.button === 0, e.buttons === 5\n // just `button` is not gonna work\n\n // Alright, then what this block does ?\n // this is for chrome `simulate mobile devices`\n // I want to support this as well\n\n return true;\n }\n if (event.button === 0 && event.buttons === undefined) {\n // Touch screen, sometimes on some specific device, `buttons`\n // doesn't have anything (safari on ios, blackberry...)\n\n return true;\n }\n\n // `mouseup` event on a single left click has\n // `button` and `buttons` equal to 0\n if (event.type === 'mouseup' && event.button === 0 && event.buttons === 0) {\n return true;\n }\n if (event.button !== 0 || event.buttons !== 1) {\n // This is the reason we have those if else block above\n // if any special case we can catch and let it slide\n // we do it above, when get to here, this definitely\n // is-not-left-click\n\n return false;\n }\n return true;\n }\n\n /**\n * Finds a single DOM element matching `selector` within the optional\n * `context` of another DOM element (defaulting to `document`).\n *\n * @param {string} selector\n * A valid CSS selector, which will be passed to `querySelector`.\n *\n * @param {Element|String} [context=document]\n * A DOM element within which to query. Can also be a selector\n * string in which case the first matching element will be used\n * as context. If missing (or no element matches selector), falls\n * back to `document`.\n *\n * @return {Element|null}\n * The element that was found or null.\n */\n const $ = createQuerier('querySelector');\n\n /**\n * Finds a all DOM elements matching `selector` within the optional\n * `context` of another DOM element (defaulting to `document`).\n *\n * @param {string} selector\n * A valid CSS selector, which will be passed to `querySelectorAll`.\n *\n * @param {Element|String} [context=document]\n * A DOM element within which to query. Can also be a selector\n * string in which case the first matching element will be used\n * as context. If missing (or no element matches selector), falls\n * back to `document`.\n *\n * @return {NodeList}\n * A element list of elements that were found. Will be empty if none\n * were found.\n *\n */\n const $$ = createQuerier('querySelectorAll');\n\n /**\n * A safe getComputedStyle.\n *\n * This is needed because in Firefox, if the player is loaded in an iframe with\n * `display:none`, then `getComputedStyle` returns `null`, so, we do a\n * null-check to make sure that the player doesn't break in these cases.\n *\n * @param {Element} el\n * The element you want the computed style of\n *\n * @param {string} prop\n * The property name you want\n *\n * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n */\n function computedStyle(el, prop) {\n if (!el || !prop) {\n return '';\n }\n if (typeof window.getComputedStyle === 'function') {\n let computedStyleValue;\n try {\n computedStyleValue = window.getComputedStyle(el);\n } catch (e) {\n return '';\n }\n return computedStyleValue ? computedStyleValue.getPropertyValue(prop) || computedStyleValue[prop] : '';\n }\n return '';\n }\n\n var Dom = /*#__PURE__*/Object.freeze({\n __proto__: null,\n isReal: isReal,\n isEl: isEl,\n isInFrame: isInFrame,\n createEl: createEl,\n textContent: textContent,\n prependTo: prependTo,\n hasClass: hasClass,\n addClass: addClass,\n removeClass: removeClass,\n toggleClass: toggleClass,\n setAttributes: setAttributes,\n getAttributes: getAttributes,\n getAttribute: getAttribute,\n setAttribute: setAttribute,\n removeAttribute: removeAttribute,\n blockTextSelection: blockTextSelection,\n unblockTextSelection: unblockTextSelection,\n getBoundingClientRect: getBoundingClientRect,\n findPosition: findPosition,\n getPointerPosition: getPointerPosition,\n isTextNode: isTextNode$1,\n emptyEl: emptyEl,\n normalizeContent: normalizeContent,\n appendContent: appendContent,\n insertContent: insertContent,\n isSingleLeftClick: isSingleLeftClick,\n $: $,\n $$: $$,\n computedStyle: computedStyle\n });\n\n /**\n * @file setup.js - Functions for setting up a player without\n * user interaction based on the data-setup `attribute` of the video tag.\n *\n * @module setup\n */\n let _windowLoaded = false;\n let videojs$1;\n\n /**\n * Set up any tags that have a data-setup `attribute` when the player is started.\n */\n const autoSetup = function () {\n if (videojs$1.options.autoSetup === false) {\n return;\n }\n const vids = Array.prototype.slice.call(document.getElementsByTagName('video'));\n const audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));\n const divs = Array.prototype.slice.call(document.getElementsByTagName('video-js'));\n const mediaEls = vids.concat(audios, divs);\n\n // Check if any media elements exist\n if (mediaEls && mediaEls.length > 0) {\n for (let i = 0, e = mediaEls.length; i < e; i++) {\n const mediaEl = mediaEls[i];\n\n // Check if element exists, has getAttribute func.\n if (mediaEl && mediaEl.getAttribute) {\n // Make sure this player hasn't already been set up.\n if (mediaEl.player === undefined) {\n const options = mediaEl.getAttribute('data-setup');\n\n // Check if data-setup attr exists.\n // We only auto-setup if they've added the data-setup attr.\n if (options !== null) {\n // Create new video.js instance.\n videojs$1(mediaEl);\n }\n }\n\n // If getAttribute isn't defined, we need to wait for the DOM.\n } else {\n autoSetupTimeout(1);\n break;\n }\n }\n\n // No videos were found, so keep looping unless page is finished loading.\n } else if (!_windowLoaded) {\n autoSetupTimeout(1);\n }\n };\n\n /**\n * Wait until the page is loaded before running autoSetup. This will be called in\n * autoSetup if `hasLoaded` returns false.\n *\n * @param {number} wait\n * How long to wait in ms\n *\n * @param {module:videojs} [vjs]\n * The videojs library function\n */\n function autoSetupTimeout(wait, vjs) {\n // Protect against breakage in non-browser environments\n if (!isReal()) {\n return;\n }\n if (vjs) {\n videojs$1 = vjs;\n }\n window.setTimeout(autoSetup, wait);\n }\n\n /**\n * Used to set the internal tracking of window loaded state to true.\n *\n * @private\n */\n function setWindowLoaded() {\n _windowLoaded = true;\n window.removeEventListener('load', setWindowLoaded);\n }\n if (isReal()) {\n if (document.readyState === 'complete') {\n setWindowLoaded();\n } else {\n /**\n * Listen for the load event on window, and set _windowLoaded to true.\n *\n * We use a standard event listener here to avoid incrementing the GUID\n * before any players are created.\n *\n * @listens load\n */\n window.addEventListener('load', setWindowLoaded);\n }\n }\n\n /**\n * @file stylesheet.js\n * @module stylesheet\n */\n\n /**\n * Create a DOM style element given a className for it.\n *\n * @param {string} className\n * The className to add to the created style element.\n *\n * @return {Element}\n * The element that was created.\n */\n const createStyleElement = function (className) {\n const style = document.createElement('style');\n style.className = className;\n return style;\n };\n\n /**\n * Add text to a DOM element.\n *\n * @param {Element} el\n * The Element to add text content to.\n *\n * @param {string} content\n * The text to add to the element.\n */\n const setTextContent = function (el, content) {\n if (el.styleSheet) {\n el.styleSheet.cssText = content;\n } else {\n el.textContent = content;\n }\n };\n\n /**\n * @file dom-data.js\n * @module dom-data\n */\n\n /**\n * Element Data Store.\n *\n * Allows for binding data to an element without putting it directly on the\n * element. Ex. Event listeners are stored here.\n * (also from jsninja.com, slightly modified and updated for closure compiler)\n *\n * @type {Object}\n * @private\n */\n var DomData = new WeakMap();\n\n /**\n * @file guid.js\n * @module guid\n */\n\n // Default value for GUIDs. This allows us to reset the GUID counter in tests.\n //\n // The initial GUID is 3 because some users have come to rely on the first\n // default player ID ending up as `vjs_video_3`.\n //\n // See: https://github.com/videojs/video.js/pull/6216\n const _initialGuid = 3;\n\n /**\n * Unique ID for an element or function\n *\n * @type {Number}\n */\n let _guid = _initialGuid;\n\n /**\n * Get a unique auto-incrementing ID by number that has not been returned before.\n *\n * @return {number}\n * A new unique ID.\n */\n function newGUID() {\n return _guid++;\n }\n\n /**\n * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)\n * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)\n * This should work very similarly to jQuery's events, however it's based off the book version which isn't as\n * robust as jquery's, so there's probably some differences.\n *\n * @file events.js\n * @module events\n */\n\n /**\n * Clean up the listener cache and dispatchers\n *\n * @param {Element|Object} elem\n * Element to clean up\n *\n * @param {string} type\n * Type of event to clean up\n */\n function _cleanUpEvents(elem, type) {\n if (!DomData.has(elem)) {\n return;\n }\n const data = DomData.get(elem);\n\n // Remove the events of a particular type if there are none left\n if (data.handlers[type].length === 0) {\n delete data.handlers[type];\n // data.handlers[type] = null;\n // Setting to null was causing an error with data.handlers\n\n // Remove the meta-handler from the element\n if (elem.removeEventListener) {\n elem.removeEventListener(type, data.dispatcher, false);\n } else if (elem.detachEvent) {\n elem.detachEvent('on' + type, data.dispatcher);\n }\n }\n\n // Remove the events object if there are no types left\n if (Object.getOwnPropertyNames(data.handlers).length <= 0) {\n delete data.handlers;\n delete data.dispatcher;\n delete data.disabled;\n }\n\n // Finally remove the element data if there is no data left\n if (Object.getOwnPropertyNames(data).length === 0) {\n DomData.delete(elem);\n }\n }\n\n /**\n * Loops through an array of event types and calls the requested method for each type.\n *\n * @param {Function} fn\n * The event method we want to use.\n *\n * @param {Element|Object} elem\n * Element or object to bind listeners to\n *\n * @param {string} type\n * Type of event to bind to.\n *\n * @param {Function} callback\n * Event listener.\n */\n function _handleMultipleEvents(fn, elem, types, callback) {\n types.forEach(function (type) {\n // Call the event method for each one of the types\n fn(elem, type, callback);\n });\n }\n\n /**\n * Fix a native event to have standard property values\n *\n * @param {Object} event\n * Event object to fix.\n *\n * @return {Object}\n * Fixed event object.\n */\n function fixEvent(event) {\n if (event.fixed_) {\n return event;\n }\n function returnTrue() {\n return true;\n }\n function returnFalse() {\n return false;\n }\n\n // Test if fixing up is needed\n // Used to check if !event.stopPropagation instead of isPropagationStopped\n // But native events return true for stopPropagation, but don't have\n // other expected methods like isPropagationStopped. Seems to be a problem\n // with the Javascript Ninja code. So we're just overriding all events now.\n if (!event || !event.isPropagationStopped || !event.isImmediatePropagationStopped) {\n const old = event || window.event;\n event = {};\n // Clone the old object so that we can modify the values event = {};\n // IE8 Doesn't like when you mess with native event properties\n // Firefox returns false for event.hasOwnProperty('type') and other props\n // which makes copying more difficult.\n // TODO: Probably best to create a whitelist of event props\n for (const key in old) {\n // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y\n // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation\n // and webkitMovementX/Y\n // Lighthouse complains if Event.path is copied\n if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY' && key !== 'path') {\n // Chrome 32+ warns if you try to copy deprecated returnValue, but\n // we still want to if preventDefault isn't supported (IE8).\n if (!(key === 'returnValue' && old.preventDefault)) {\n event[key] = old[key];\n }\n }\n }\n\n // The event occurred on this element\n if (!event.target) {\n event.target = event.srcElement || document;\n }\n\n // Handle which other element the event is related to\n if (!event.relatedTarget) {\n event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;\n }\n\n // Stop the default browser action\n event.preventDefault = function () {\n if (old.preventDefault) {\n old.preventDefault();\n }\n event.returnValue = false;\n old.returnValue = false;\n event.defaultPrevented = true;\n };\n event.defaultPrevented = false;\n\n // Stop the event from bubbling\n event.stopPropagation = function () {\n if (old.stopPropagation) {\n old.stopPropagation();\n }\n event.cancelBubble = true;\n old.cancelBubble = true;\n event.isPropagationStopped = returnTrue;\n };\n event.isPropagationStopped = returnFalse;\n\n // Stop the event from bubbling and executing other handlers\n event.stopImmediatePropagation = function () {\n if (old.stopImmediatePropagation) {\n old.stopImmediatePropagation();\n }\n event.isImmediatePropagationStopped = returnTrue;\n event.stopPropagation();\n };\n event.isImmediatePropagationStopped = returnFalse;\n\n // Handle mouse position\n if (event.clientX !== null && event.clientX !== undefined) {\n const doc = document.documentElement;\n const body = document.body;\n event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\n event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);\n }\n\n // Handle key presses\n event.which = event.charCode || event.keyCode;\n\n // Fix button for mouse clicks:\n // 0 == left; 1 == middle; 2 == right\n if (event.button !== null && event.button !== undefined) {\n // The following is disabled because it does not pass videojs-standard\n // and... yikes.\n /* eslint-disable */\n event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;\n /* eslint-enable */\n }\n }\n\n event.fixed_ = true;\n // Returns fixed-up instance\n return event;\n }\n\n /**\n * Whether passive event listeners are supported\n */\n let _supportsPassive;\n const supportsPassive = function () {\n if (typeof _supportsPassive !== 'boolean') {\n _supportsPassive = false;\n try {\n const opts = Object.defineProperty({}, 'passive', {\n get() {\n _supportsPassive = true;\n }\n });\n window.addEventListener('test', null, opts);\n window.removeEventListener('test', null, opts);\n } catch (e) {\n // disregard\n }\n }\n return _supportsPassive;\n };\n\n /**\n * Touch events Chrome expects to be passive\n */\n const passiveEvents = ['touchstart', 'touchmove'];\n\n /**\n * Add an event listener to element\n * It stores the handler function in a separate cache object\n * and adds a generic handler to the element's event,\n * along with a unique id (guid) to the element.\n *\n * @param {Element|Object} elem\n * Element or object to bind listeners to\n *\n * @param {string|string[]} type\n * Type of event to bind to.\n *\n * @param {Function} fn\n * Event listener.\n */\n function on(elem, type, fn) {\n if (Array.isArray(type)) {\n return _handleMultipleEvents(on, elem, type, fn);\n }\n if (!DomData.has(elem)) {\n DomData.set(elem, {});\n }\n const data = DomData.get(elem);\n\n // We need a place to store all our handler data\n if (!data.handlers) {\n data.handlers = {};\n }\n if (!data.handlers[type]) {\n data.handlers[type] = [];\n }\n if (!fn.guid) {\n fn.guid = newGUID();\n }\n data.handlers[type].push(fn);\n if (!data.dispatcher) {\n data.disabled = false;\n data.dispatcher = function (event, hash) {\n if (data.disabled) {\n return;\n }\n event = fixEvent(event);\n const handlers = data.handlers[event.type];\n if (handlers) {\n // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.\n const handlersCopy = handlers.slice(0);\n for (let m = 0, n = handlersCopy.length; m < n; m++) {\n if (event.isImmediatePropagationStopped()) {\n break;\n } else {\n try {\n handlersCopy[m].call(elem, event, hash);\n } catch (e) {\n log$1.error(e);\n }\n }\n }\n }\n };\n }\n if (data.handlers[type].length === 1) {\n if (elem.addEventListener) {\n let options = false;\n if (supportsPassive() && passiveEvents.indexOf(type) > -1) {\n options = {\n passive: true\n };\n }\n elem.addEventListener(type, data.dispatcher, options);\n } else if (elem.attachEvent) {\n elem.attachEvent('on' + type, data.dispatcher);\n }\n }\n }\n\n /**\n * Removes event listeners from an element\n *\n * @param {Element|Object} elem\n * Object to remove listeners from.\n *\n * @param {string|string[]} [type]\n * Type of listener to remove. Don't include to remove all events from element.\n *\n * @param {Function} [fn]\n * Specific listener to remove. Don't include to remove listeners for an event\n * type.\n */\n function off(elem, type, fn) {\n // Don't want to add a cache object through getElData if not needed\n if (!DomData.has(elem)) {\n return;\n }\n const data = DomData.get(elem);\n\n // If no events exist, nothing to unbind\n if (!data.handlers) {\n return;\n }\n if (Array.isArray(type)) {\n return _handleMultipleEvents(off, elem, type, fn);\n }\n\n // Utility function\n const removeType = function (el, t) {\n data.handlers[t] = [];\n _cleanUpEvents(el, t);\n };\n\n // Are we removing all bound events?\n if (type === undefined) {\n for (const t in data.handlers) {\n if (Object.prototype.hasOwnProperty.call(data.handlers || {}, t)) {\n removeType(elem, t);\n }\n }\n return;\n }\n const handlers = data.handlers[type];\n\n // If no handlers exist, nothing to unbind\n if (!handlers) {\n return;\n }\n\n // If no listener was provided, remove all listeners for type\n if (!fn) {\n removeType(elem, type);\n return;\n }\n\n // We're only removing a single handler\n if (fn.guid) {\n for (let n = 0; n < handlers.length; n++) {\n if (handlers[n].guid === fn.guid) {\n handlers.splice(n--, 1);\n }\n }\n }\n _cleanUpEvents(elem, type);\n }\n\n /**\n * Trigger an event for an element\n *\n * @param {Element|Object} elem\n * Element to trigger an event on\n *\n * @param {EventTarget~Event|string} event\n * A string (the type) or an event object with a type attribute\n *\n * @param {Object} [hash]\n * data hash to pass along with the event\n *\n * @return {boolean|undefined}\n * Returns the opposite of `defaultPrevented` if default was\n * prevented. Otherwise, returns `undefined`\n */\n function trigger(elem, event, hash) {\n // Fetches element data and a reference to the parent (for bubbling).\n // Don't want to add a data object to cache for every parent,\n // so checking hasElData first.\n const elemData = DomData.has(elem) ? DomData.get(elem) : {};\n const parent = elem.parentNode || elem.ownerDocument;\n // type = event.type || event,\n // handler;\n\n // If an event name was passed as a string, creates an event out of it\n if (typeof event === 'string') {\n event = {\n type: event,\n target: elem\n };\n } else if (!event.target) {\n event.target = elem;\n }\n\n // Normalizes the event properties.\n event = fixEvent(event);\n\n // If the passed element has a dispatcher, executes the established handlers.\n if (elemData.dispatcher) {\n elemData.dispatcher.call(elem, event, hash);\n }\n\n // Unless explicitly stopped or the event does not bubble (e.g. media events)\n // recursively calls this function to bubble the event up the DOM.\n if (parent && !event.isPropagationStopped() && event.bubbles === true) {\n trigger.call(null, parent, event, hash);\n\n // If at the top of the DOM, triggers the default action unless disabled.\n } else if (!parent && !event.defaultPrevented && event.target && event.target[event.type]) {\n if (!DomData.has(event.target)) {\n DomData.set(event.target, {});\n }\n const targetData = DomData.get(event.target);\n\n // Checks if the target has a default action for this event.\n if (event.target[event.type]) {\n // Temporarily disables event dispatching on the target as we have already executed the handler.\n targetData.disabled = true;\n // Executes the default action.\n if (typeof event.target[event.type] === 'function') {\n event.target[event.type]();\n }\n // Re-enables event dispatching.\n targetData.disabled = false;\n }\n }\n\n // Inform the triggerer if the default was prevented by returning false\n return !event.defaultPrevented;\n }\n\n /**\n * Trigger a listener only once for an event.\n *\n * @param {Element|Object} elem\n * Element or object to bind to.\n *\n * @param {string|string[]} type\n * Name/type of event\n *\n * @param {Event~EventListener} fn\n * Event listener function\n */\n function one(elem, type, fn) {\n if (Array.isArray(type)) {\n return _handleMultipleEvents(one, elem, type, fn);\n }\n const func = function () {\n off(elem, type, func);\n fn.apply(this, arguments);\n };\n\n // copy the guid to the new function so it can removed using the original function's ID\n func.guid = fn.guid = fn.guid || newGUID();\n on(elem, type, func);\n }\n\n /**\n * Trigger a listener only once and then turn if off for all\n * configured events\n *\n * @param {Element|Object} elem\n * Element or object to bind to.\n *\n * @param {string|string[]} type\n * Name/type of event\n *\n * @param {Event~EventListener} fn\n * Event listener function\n */\n function any(elem, type, fn) {\n const func = function () {\n off(elem, type, func);\n fn.apply(this, arguments);\n };\n\n // copy the guid to the new function so it can removed using the original function's ID\n func.guid = fn.guid = fn.guid || newGUID();\n\n // multiple ons, but one off for everything\n on(elem, type, func);\n }\n\n var Events = /*#__PURE__*/Object.freeze({\n __proto__: null,\n fixEvent: fixEvent,\n on: on,\n off: off,\n trigger: trigger,\n one: one,\n any: any\n });\n\n /**\n * @file fn.js\n * @module fn\n */\n const UPDATE_REFRESH_INTERVAL = 30;\n\n /**\n * A private, internal-only function for changing the context of a function.\n *\n * It also stores a unique id on the function so it can be easily removed from\n * events.\n *\n * @private\n * @function\n * @param {*} context\n * The object to bind as scope.\n *\n * @param {Function} fn\n * The function to be bound to a scope.\n *\n * @param {number} [uid]\n * An optional unique ID for the function to be set\n *\n * @return {Function}\n * The new function that will be bound into the context given\n */\n const bind_ = function (context, fn, uid) {\n // Make sure the function has a unique ID\n if (!fn.guid) {\n fn.guid = newGUID();\n }\n\n // Create the new function that changes the context\n const bound = fn.bind(context);\n\n // Allow for the ability to individualize this function\n // Needed in the case where multiple objects might share the same prototype\n // IF both items add an event listener with the same function, then you try to remove just one\n // it will remove both because they both have the same guid.\n // when using this, you need to use the bind method when you remove the listener as well.\n // currently used in text tracks\n bound.guid = uid ? uid + '_' + fn.guid : fn.guid;\n return bound;\n };\n\n /**\n * Wraps the given function, `fn`, with a new function that only invokes `fn`\n * at most once per every `wait` milliseconds.\n *\n * @function\n * @param {Function} fn\n * The function to be throttled.\n *\n * @param {number} wait\n * The number of milliseconds by which to throttle.\n *\n * @return {Function}\n */\n const throttle = function (fn, wait) {\n let last = window.performance.now();\n const throttled = function (...args) {\n const now = window.performance.now();\n if (now - last >= wait) {\n fn(...args);\n last = now;\n }\n };\n return throttled;\n };\n\n /**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked.\n *\n * Inspired by lodash and underscore implementations.\n *\n * @function\n * @param {Function} func\n * The function to wrap with debounce behavior.\n *\n * @param {number} wait\n * The number of milliseconds to wait after the last invocation.\n *\n * @param {boolean} [immediate]\n * Whether or not to invoke the function immediately upon creation.\n *\n * @param {Object} [context=window]\n * The \"context\" in which the debounced function should debounce. For\n * example, if this function should be tied to a Video.js player,\n * the player can be passed here. Alternatively, defaults to the\n * global `window` object.\n *\n * @return {Function}\n * A debounced function.\n */\n const debounce = function (func, wait, immediate, context = window) {\n let timeout;\n const cancel = () => {\n context.clearTimeout(timeout);\n timeout = null;\n };\n\n /* eslint-disable consistent-this */\n const debounced = function () {\n const self = this;\n const args = arguments;\n let later = function () {\n timeout = null;\n later = null;\n if (!immediate) {\n func.apply(self, args);\n }\n };\n if (!timeout && immediate) {\n func.apply(self, args);\n }\n context.clearTimeout(timeout);\n timeout = context.setTimeout(later, wait);\n };\n /* eslint-enable consistent-this */\n\n debounced.cancel = cancel;\n return debounced;\n };\n\n var Fn = /*#__PURE__*/Object.freeze({\n __proto__: null,\n UPDATE_REFRESH_INTERVAL: UPDATE_REFRESH_INTERVAL,\n bind_: bind_,\n throttle: throttle,\n debounce: debounce\n });\n\n /**\n * @file src/js/event-target.js\n */\n let EVENT_MAP;\n\n /**\n * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It\n * adds shorthand functions that wrap around lengthy functions. For example:\n * the `on` function is a wrapper around `addEventListener`.\n *\n * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}\n * @class EventTarget\n */\n class EventTarget$2 {\n /**\n * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a\n * function that will get called when an event with a certain name gets triggered.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to call with `EventTarget`s\n */\n on(type, fn) {\n // Remove the addEventListener alias before calling Events.on\n // so we don't get into an infinite type loop\n const ael = this.addEventListener;\n this.addEventListener = () => {};\n on(this, type, fn);\n this.addEventListener = ael;\n }\n /**\n * Removes an `event listener` for a specific event from an instance of `EventTarget`.\n * This makes it so that the `event listener` will no longer get called when the\n * named event happens.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to remove.\n */\n off(type, fn) {\n off(this, type, fn);\n }\n /**\n * This function will add an `event listener` that gets triggered only once. After the\n * first trigger it will get removed. This is like adding an `event listener`\n * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to be called once for each event name.\n */\n one(type, fn) {\n // Remove the addEventListener aliasing Events.on\n // so we don't get into an infinite type loop\n const ael = this.addEventListener;\n this.addEventListener = () => {};\n one(this, type, fn);\n this.addEventListener = ael;\n }\n /**\n * This function will add an `event listener` that gets triggered only once and is\n * removed from all events. This is like adding an array of `event listener`s\n * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the\n * first time it is triggered.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to be called once for each event name.\n */\n any(type, fn) {\n // Remove the addEventListener aliasing Events.on\n // so we don't get into an infinite type loop\n const ael = this.addEventListener;\n this.addEventListener = () => {};\n any(this, type, fn);\n this.addEventListener = ael;\n }\n /**\n * This function causes an event to happen. This will then cause any `event listeners`\n * that are waiting for that event, to get called. If there are no `event listeners`\n * for an event then nothing will happen.\n *\n * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.\n * Trigger will also call the `on` + `uppercaseEventName` function.\n *\n * Example:\n * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call\n * `onClick` if it exists.\n *\n * @param {string|EventTarget~Event|Object} event\n * The name of the event, an `Event`, or an object with a key of type set to\n * an event name.\n */\n trigger(event) {\n const type = event.type || event;\n\n // deprecation\n // In a future version we should default target to `this`\n // similar to how we default the target to `elem` in\n // `Events.trigger`. Right now the default `target` will be\n // `document` due to the `Event.fixEvent` call.\n if (typeof event === 'string') {\n event = {\n type\n };\n }\n event = fixEvent(event);\n if (this.allowedEvents_[type] && this['on' + type]) {\n this['on' + type](event);\n }\n trigger(this, event);\n }\n queueTrigger(event) {\n // only set up EVENT_MAP if it'll be used\n if (!EVENT_MAP) {\n EVENT_MAP = new Map();\n }\n const type = event.type || event;\n let map = EVENT_MAP.get(this);\n if (!map) {\n map = new Map();\n EVENT_MAP.set(this, map);\n }\n const oldTimeout = map.get(type);\n map.delete(type);\n window.clearTimeout(oldTimeout);\n const timeout = window.setTimeout(() => {\n map.delete(type);\n // if we cleared out all timeouts for the current target, delete its map\n if (map.size === 0) {\n map = null;\n EVENT_MAP.delete(this);\n }\n this.trigger(event);\n }, 0);\n map.set(type, timeout);\n }\n }\n\n /**\n * A Custom DOM event.\n *\n * @typedef {CustomEvent} Event\n * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}\n */\n\n /**\n * All event listeners should follow the following format.\n *\n * @callback EventTarget~EventListener\n * @this {EventTarget}\n *\n * @param {Event} event\n * the event that triggered this function\n *\n * @param {Object} [hash]\n * hash of data sent during the event\n */\n\n /**\n * An object containing event names as keys and booleans as values.\n *\n * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}\n * will have extra functionality. See that function for more information.\n *\n * @property EventTarget.prototype.allowedEvents_\n * @private\n */\n EventTarget$2.prototype.allowedEvents_ = {};\n\n /**\n * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic\n * the standard DOM API.\n *\n * @function\n * @see {@link EventTarget#on}\n */\n EventTarget$2.prototype.addEventListener = EventTarget$2.prototype.on;\n\n /**\n * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic\n * the standard DOM API.\n *\n * @function\n * @see {@link EventTarget#off}\n */\n EventTarget$2.prototype.removeEventListener = EventTarget$2.prototype.off;\n\n /**\n * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic\n * the standard DOM API.\n *\n * @function\n * @see {@link EventTarget#trigger}\n */\n EventTarget$2.prototype.dispatchEvent = EventTarget$2.prototype.trigger;\n\n /**\n * @file mixins/evented.js\n * @module evented\n */\n const objName = obj => {\n if (typeof obj.name === 'function') {\n return obj.name();\n }\n if (typeof obj.name === 'string') {\n return obj.name;\n }\n if (obj.name_) {\n return obj.name_;\n }\n if (obj.constructor && obj.constructor.name) {\n return obj.constructor.name;\n }\n return typeof obj;\n };\n\n /**\n * Returns whether or not an object has had the evented mixin applied.\n *\n * @param {Object} object\n * An object to test.\n *\n * @return {boolean}\n * Whether or not the object appears to be evented.\n */\n const isEvented = object => object instanceof EventTarget$2 || !!object.eventBusEl_ && ['on', 'one', 'off', 'trigger'].every(k => typeof object[k] === 'function');\n\n /**\n * Adds a callback to run after the evented mixin applied.\n *\n * @param {Object} object\n * An object to Add\n * @param {Function} callback\n * The callback to run.\n */\n const addEventedCallback = (target, callback) => {\n if (isEvented(target)) {\n callback();\n } else {\n if (!target.eventedCallbacks) {\n target.eventedCallbacks = [];\n }\n target.eventedCallbacks.push(callback);\n }\n };\n\n /**\n * Whether a value is a valid event type - non-empty string or array.\n *\n * @private\n * @param {string|Array} type\n * The type value to test.\n *\n * @return {boolean}\n * Whether or not the type is a valid event type.\n */\n const isValidEventType = type =>\n // The regex here verifies that the `type` contains at least one non-\n // whitespace character.\n typeof type === 'string' && /\\S/.test(type) || Array.isArray(type) && !!type.length;\n\n /**\n * Validates a value to determine if it is a valid event target. Throws if not.\n *\n * @private\n * @throws {Error}\n * If the target does not appear to be a valid event target.\n *\n * @param {Object} target\n * The object to test.\n *\n * @param {Object} obj\n * The evented object we are validating for\n *\n * @param {string} fnName\n * The name of the evented mixin function that called this.\n */\n const validateTarget = (target, obj, fnName) => {\n if (!target || !target.nodeName && !isEvented(target)) {\n throw new Error(`Invalid target for ${objName(obj)}#${fnName}; must be a DOM node or evented object.`);\n }\n };\n\n /**\n * Validates a value to determine if it is a valid event target. Throws if not.\n *\n * @private\n * @throws {Error}\n * If the type does not appear to be a valid event type.\n *\n * @param {string|Array} type\n * The type to test.\n *\n * @param {Object} obj\n * The evented object we are validating for\n *\n * @param {string} fnName\n * The name of the evented mixin function that called this.\n */\n const validateEventType = (type, obj, fnName) => {\n if (!isValidEventType(type)) {\n throw new Error(`Invalid event type for ${objName(obj)}#${fnName}; must be a non-empty string or array.`);\n }\n };\n\n /**\n * Validates a value to determine if it is a valid listener. Throws if not.\n *\n * @private\n * @throws {Error}\n * If the listener is not a function.\n *\n * @param {Function} listener\n * The listener to test.\n *\n * @param {Object} obj\n * The evented object we are validating for\n *\n * @param {string} fnName\n * The name of the evented mixin function that called this.\n */\n const validateListener = (listener, obj, fnName) => {\n if (typeof listener !== 'function') {\n throw new Error(`Invalid listener for ${objName(obj)}#${fnName}; must be a function.`);\n }\n };\n\n /**\n * Takes an array of arguments given to `on()` or `one()`, validates them, and\n * normalizes them into an object.\n *\n * @private\n * @param {Object} self\n * The evented object on which `on()` or `one()` was called. This\n * object will be bound as the `this` value for the listener.\n *\n * @param {Array} args\n * An array of arguments passed to `on()` or `one()`.\n *\n * @param {string} fnName\n * The name of the evented mixin function that called this.\n *\n * @return {Object}\n * An object containing useful values for `on()` or `one()` calls.\n */\n const normalizeListenArgs = (self, args, fnName) => {\n // If the number of arguments is less than 3, the target is always the\n // evented object itself.\n const isTargetingSelf = args.length < 3 || args[0] === self || args[0] === self.eventBusEl_;\n let target;\n let type;\n let listener;\n if (isTargetingSelf) {\n target = self.eventBusEl_;\n\n // Deal with cases where we got 3 arguments, but we are still listening to\n // the evented object itself.\n if (args.length >= 3) {\n args.shift();\n }\n [type, listener] = args;\n } else {\n [target, type, listener] = args;\n }\n validateTarget(target, self, fnName);\n validateEventType(type, self, fnName);\n validateListener(listener, self, fnName);\n listener = bind_(self, listener);\n return {\n isTargetingSelf,\n target,\n type,\n listener\n };\n };\n\n /**\n * Adds the listener to the event type(s) on the target, normalizing for\n * the type of target.\n *\n * @private\n * @param {Element|Object} target\n * A DOM node or evented object.\n *\n * @param {string} method\n * The event binding method to use (\"on\" or \"one\").\n *\n * @param {string|Array} type\n * One or more event type(s).\n *\n * @param {Function} listener\n * A listener function.\n */\n const listen = (target, method, type, listener) => {\n validateTarget(target, target, method);\n if (target.nodeName) {\n Events[method](target, type, listener);\n } else {\n target[method](type, listener);\n }\n };\n\n /**\n * Contains methods that provide event capabilities to an object which is passed\n * to {@link module:evented|evented}.\n *\n * @mixin EventedMixin\n */\n const EventedMixin = {\n /**\n * Add a listener to an event (or events) on this object or another evented\n * object.\n *\n * @param {string|Array|Element|Object} targetOrType\n * If this is a string or array, it represents the event type(s)\n * that will trigger the listener.\n *\n * Another evented object can be passed here instead, which will\n * cause the listener to listen for events on _that_ object.\n *\n * In either case, the listener's `this` value will be bound to\n * this object.\n *\n * @param {string|Array|Function} typeOrListener\n * If the first argument was a string or array, this should be the\n * listener function. Otherwise, this is a string or array of event\n * type(s).\n *\n * @param {Function} [listener]\n * If the first argument was another evented object, this will be\n * the listener function.\n */\n on(...args) {\n const {\n isTargetingSelf,\n target,\n type,\n listener\n } = normalizeListenArgs(this, args, 'on');\n listen(target, 'on', type, listener);\n\n // If this object is listening to another evented object.\n if (!isTargetingSelf) {\n // If this object is disposed, remove the listener.\n const removeListenerOnDispose = () => this.off(target, type, listener);\n\n // Use the same function ID as the listener so we can remove it later it\n // using the ID of the original listener.\n removeListenerOnDispose.guid = listener.guid;\n\n // Add a listener to the target's dispose event as well. This ensures\n // that if the target is disposed BEFORE this object, we remove the\n // removal listener that was just added. Otherwise, we create a memory leak.\n const removeRemoverOnTargetDispose = () => this.off('dispose', removeListenerOnDispose);\n\n // Use the same function ID as the listener so we can remove it later\n // it using the ID of the original listener.\n removeRemoverOnTargetDispose.guid = listener.guid;\n listen(this, 'on', 'dispose', removeListenerOnDispose);\n listen(target, 'on', 'dispose', removeRemoverOnTargetDispose);\n }\n },\n /**\n * Add a listener to an event (or events) on this object or another evented\n * object. The listener will be called once per event and then removed.\n *\n * @param {string|Array|Element|Object} targetOrType\n * If this is a string or array, it represents the event type(s)\n * that will trigger the listener.\n *\n * Another evented object can be passed here instead, which will\n * cause the listener to listen for events on _that_ object.\n *\n * In either case, the listener's `this` value will be bound to\n * this object.\n *\n * @param {string|Array|Function} typeOrListener\n * If the first argument was a string or array, this should be the\n * listener function. Otherwise, this is a string or array of event\n * type(s).\n *\n * @param {Function} [listener]\n * If the first argument was another evented object, this will be\n * the listener function.\n */\n one(...args) {\n const {\n isTargetingSelf,\n target,\n type,\n listener\n } = normalizeListenArgs(this, args, 'one');\n\n // Targeting this evented object.\n if (isTargetingSelf) {\n listen(target, 'one', type, listener);\n\n // Targeting another evented object.\n } else {\n // TODO: This wrapper is incorrect! It should only\n // remove the wrapper for the event type that called it.\n // Instead all listeners are removed on the first trigger!\n // see https://github.com/videojs/video.js/issues/5962\n const wrapper = (...largs) => {\n this.off(target, type, wrapper);\n listener.apply(null, largs);\n };\n\n // Use the same function ID as the listener so we can remove it later\n // it using the ID of the original listener.\n wrapper.guid = listener.guid;\n listen(target, 'one', type, wrapper);\n }\n },\n /**\n * Add a listener to an event (or events) on this object or another evented\n * object. The listener will only be called once for the first event that is triggered\n * then removed.\n *\n * @param {string|Array|Element|Object} targetOrType\n * If this is a string or array, it represents the event type(s)\n * that will trigger the listener.\n *\n * Another evented object can be passed here instead, which will\n * cause the listener to listen for events on _that_ object.\n *\n * In either case, the listener's `this` value will be bound to\n * this object.\n *\n * @param {string|Array|Function} typeOrListener\n * If the first argument was a string or array, this should be the\n * listener function. Otherwise, this is a string or array of event\n * type(s).\n *\n * @param {Function} [listener]\n * If the first argument was another evented object, this will be\n * the listener function.\n */\n any(...args) {\n const {\n isTargetingSelf,\n target,\n type,\n listener\n } = normalizeListenArgs(this, args, 'any');\n\n // Targeting this evented object.\n if (isTargetingSelf) {\n listen(target, 'any', type, listener);\n\n // Targeting another evented object.\n } else {\n const wrapper = (...largs) => {\n this.off(target, type, wrapper);\n listener.apply(null, largs);\n };\n\n // Use the same function ID as the listener so we can remove it later\n // it using the ID of the original listener.\n wrapper.guid = listener.guid;\n listen(target, 'any', type, wrapper);\n }\n },\n /**\n * Removes listener(s) from event(s) on an evented object.\n *\n * @param {string|Array|Element|Object} [targetOrType]\n * If this is a string or array, it represents the event type(s).\n *\n * Another evented object can be passed here instead, in which case\n * ALL 3 arguments are _required_.\n *\n * @param {string|Array|Function} [typeOrListener]\n * If the first argument was a string or array, this may be the\n * listener function. Otherwise, this is a string or array of event\n * type(s).\n *\n * @param {Function} [listener]\n * If the first argument was another evented object, this will be\n * the listener function; otherwise, _all_ listeners bound to the\n * event type(s) will be removed.\n */\n off(targetOrType, typeOrListener, listener) {\n // Targeting this evented object.\n if (!targetOrType || isValidEventType(targetOrType)) {\n off(this.eventBusEl_, targetOrType, typeOrListener);\n\n // Targeting another evented object.\n } else {\n const target = targetOrType;\n const type = typeOrListener;\n\n // Fail fast and in a meaningful way!\n validateTarget(target, this, 'off');\n validateEventType(type, this, 'off');\n validateListener(listener, this, 'off');\n\n // Ensure there's at least a guid, even if the function hasn't been used\n listener = bind_(this, listener);\n\n // Remove the dispose listener on this evented object, which was given\n // the same guid as the event listener in on().\n this.off('dispose', listener);\n if (target.nodeName) {\n off(target, type, listener);\n off(target, 'dispose', listener);\n } else if (isEvented(target)) {\n target.off(type, listener);\n target.off('dispose', listener);\n }\n }\n },\n /**\n * Fire an event on this evented object, causing its listeners to be called.\n *\n * @param {string|Object} event\n * An event type or an object with a type property.\n *\n * @param {Object} [hash]\n * An additional object to pass along to listeners.\n *\n * @return {boolean}\n * Whether or not the default behavior was prevented.\n */\n trigger(event, hash) {\n validateTarget(this.eventBusEl_, this, 'trigger');\n const type = event && typeof event !== 'string' ? event.type : event;\n if (!isValidEventType(type)) {\n throw new Error(`Invalid event type for ${objName(this)}#trigger; ` + 'must be a non-empty string or object with a type key that has a non-empty value.');\n }\n return trigger(this.eventBusEl_, event, hash);\n }\n };\n\n /**\n * Applies {@link module:evented~EventedMixin|EventedMixin} to a target object.\n *\n * @param {Object} target\n * The object to which to add event methods.\n *\n * @param {Object} [options={}]\n * Options for customizing the mixin behavior.\n *\n * @param {string} [options.eventBusKey]\n * By default, adds a `eventBusEl_` DOM element to the target object,\n * which is used as an event bus. If the target object already has a\n * DOM element that should be used, pass its key here.\n *\n * @return {Object}\n * The target object.\n */\n function evented(target, options = {}) {\n const {\n eventBusKey\n } = options;\n\n // Set or create the eventBusEl_.\n if (eventBusKey) {\n if (!target[eventBusKey].nodeName) {\n throw new Error(`The eventBusKey \"${eventBusKey}\" does not refer to an element.`);\n }\n target.eventBusEl_ = target[eventBusKey];\n } else {\n target.eventBusEl_ = createEl('span', {\n className: 'vjs-event-bus'\n });\n }\n Object.assign(target, EventedMixin);\n if (target.eventedCallbacks) {\n target.eventedCallbacks.forEach(callback => {\n callback();\n });\n }\n\n // When any evented object is disposed, it removes all its listeners.\n target.on('dispose', () => {\n target.off();\n [target, target.el_, target.eventBusEl_].forEach(function (val) {\n if (val && DomData.has(val)) {\n DomData.delete(val);\n }\n });\n window.setTimeout(() => {\n target.eventBusEl_ = null;\n }, 0);\n });\n return target;\n }\n\n /**\n * @file mixins/stateful.js\n * @module stateful\n */\n\n /**\n * Contains methods that provide statefulness to an object which is passed\n * to {@link module:stateful}.\n *\n * @mixin StatefulMixin\n */\n const StatefulMixin = {\n /**\n * A hash containing arbitrary keys and values representing the state of\n * the object.\n *\n * @type {Object}\n */\n state: {},\n /**\n * Set the state of an object by mutating its\n * {@link module:stateful~StatefulMixin.state|state} object in place.\n *\n * @fires module:stateful~StatefulMixin#statechanged\n * @param {Object|Function} stateUpdates\n * A new set of properties to shallow-merge into the plugin state.\n * Can be a plain object or a function returning a plain object.\n *\n * @return {Object|undefined}\n * An object containing changes that occurred. If no changes\n * occurred, returns `undefined`.\n */\n setState(stateUpdates) {\n // Support providing the `stateUpdates` state as a function.\n if (typeof stateUpdates === 'function') {\n stateUpdates = stateUpdates();\n }\n let changes;\n each(stateUpdates, (value, key) => {\n // Record the change if the value is different from what's in the\n // current state.\n if (this.state[key] !== value) {\n changes = changes || {};\n changes[key] = {\n from: this.state[key],\n to: value\n };\n }\n this.state[key] = value;\n });\n\n // Only trigger \"statechange\" if there were changes AND we have a trigger\n // function. This allows us to not require that the target object be an\n // evented object.\n if (changes && isEvented(this)) {\n /**\n * An event triggered on an object that is both\n * {@link module:stateful|stateful} and {@link module:evented|evented}\n * indicating that its state has changed.\n *\n * @event module:stateful~StatefulMixin#statechanged\n * @type {Object}\n * @property {Object} changes\n * A hash containing the properties that were changed and\n * the values they were changed `from` and `to`.\n */\n this.trigger({\n changes,\n type: 'statechanged'\n });\n }\n return changes;\n }\n };\n\n /**\n * Applies {@link module:stateful~StatefulMixin|StatefulMixin} to a target\n * object.\n *\n * If the target object is {@link module:evented|evented} and has a\n * `handleStateChanged` method, that method will be automatically bound to the\n * `statechanged` event on itself.\n *\n * @param {Object} target\n * The object to be made stateful.\n *\n * @param {Object} [defaultState]\n * A default set of properties to populate the newly-stateful object's\n * `state` property.\n *\n * @return {Object}\n * Returns the `target`.\n */\n function stateful(target, defaultState) {\n Object.assign(target, StatefulMixin);\n\n // This happens after the mixing-in because we need to replace the `state`\n // added in that step.\n target.state = Object.assign({}, target.state, defaultState);\n\n // Auto-bind the `handleStateChanged` method of the target object if it exists.\n if (typeof target.handleStateChanged === 'function' && isEvented(target)) {\n target.on('statechanged', target.handleStateChanged);\n }\n return target;\n }\n\n /**\n * @file str.js\n * @module to-lower-case\n */\n\n /**\n * Lowercase the first letter of a string.\n *\n * @param {string} string\n * String to be lowercased\n *\n * @return {string}\n * The string with a lowercased first letter\n */\n const toLowerCase = function (string) {\n if (typeof string !== 'string') {\n return string;\n }\n return string.replace(/./, w => w.toLowerCase());\n };\n\n /**\n * Uppercase the first letter of a string.\n *\n * @param {string} string\n * String to be uppercased\n *\n * @return {string}\n * The string with an uppercased first letter\n */\n const toTitleCase$1 = function (string) {\n if (typeof string !== 'string') {\n return string;\n }\n return string.replace(/./, w => w.toUpperCase());\n };\n\n /**\n * Compares the TitleCase versions of the two strings for equality.\n *\n * @param {string} str1\n * The first string to compare\n *\n * @param {string} str2\n * The second string to compare\n *\n * @return {boolean}\n * Whether the TitleCase versions of the strings are equal\n */\n const titleCaseEquals = function (str1, str2) {\n return toTitleCase$1(str1) === toTitleCase$1(str2);\n };\n\n var Str = /*#__PURE__*/Object.freeze({\n __proto__: null,\n toLowerCase: toLowerCase,\n toTitleCase: toTitleCase$1,\n titleCaseEquals: titleCaseEquals\n });\n\n var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\n function unwrapExports (x) {\n return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n }\n\n function createCommonjsModule(fn, module) {\n return module = { exports: {} }, fn(module, module.exports), module.exports;\n }\n\n var keycode = createCommonjsModule(function (module, exports) {\n // Source: http://jsfiddle.net/vWx8V/\n // http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes\n\n /**\n * Conenience method returns corresponding value for given keyName or keyCode.\n *\n * @param {Mixed} keyCode {Number} or keyName {String}\n * @return {Mixed}\n * @api public\n */\n\n function keyCode(searchInput) {\n // Keyboard Events\n if (searchInput && 'object' === typeof searchInput) {\n var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode;\n if (hasKeyCode) searchInput = hasKeyCode;\n }\n\n // Numbers\n if ('number' === typeof searchInput) return names[searchInput];\n\n // Everything else (cast to string)\n var search = String(searchInput);\n\n // check codes\n var foundNamedKey = codes[search.toLowerCase()];\n if (foundNamedKey) return foundNamedKey;\n\n // check aliases\n var foundNamedKey = aliases[search.toLowerCase()];\n if (foundNamedKey) return foundNamedKey;\n\n // weird character?\n if (search.length === 1) return search.charCodeAt(0);\n return undefined;\n }\n\n /**\n * Compares a keyboard event with a given keyCode or keyName.\n *\n * @param {Event} event Keyboard event that should be tested\n * @param {Mixed} keyCode {Number} or keyName {String}\n * @return {Boolean}\n * @api public\n */\n keyCode.isEventKey = function isEventKey(event, nameOrCode) {\n if (event && 'object' === typeof event) {\n var keyCode = event.which || event.keyCode || event.charCode;\n if (keyCode === null || keyCode === undefined) {\n return false;\n }\n if (typeof nameOrCode === 'string') {\n // check codes\n var foundNamedKey = codes[nameOrCode.toLowerCase()];\n if (foundNamedKey) {\n return foundNamedKey === keyCode;\n }\n\n // check aliases\n var foundNamedKey = aliases[nameOrCode.toLowerCase()];\n if (foundNamedKey) {\n return foundNamedKey === keyCode;\n }\n } else if (typeof nameOrCode === 'number') {\n return nameOrCode === keyCode;\n }\n return false;\n }\n };\n exports = module.exports = keyCode;\n\n /**\n * Get by name\n *\n * exports.code['enter'] // => 13\n */\n\n var codes = exports.code = exports.codes = {\n 'backspace': 8,\n 'tab': 9,\n 'enter': 13,\n 'shift': 16,\n 'ctrl': 17,\n 'alt': 18,\n 'pause/break': 19,\n 'caps lock': 20,\n 'esc': 27,\n 'space': 32,\n 'page up': 33,\n 'page down': 34,\n 'end': 35,\n 'home': 36,\n 'left': 37,\n 'up': 38,\n 'right': 39,\n 'down': 40,\n 'insert': 45,\n 'delete': 46,\n 'command': 91,\n 'left command': 91,\n 'right command': 93,\n 'numpad *': 106,\n 'numpad +': 107,\n 'numpad -': 109,\n 'numpad .': 110,\n 'numpad /': 111,\n 'num lock': 144,\n 'scroll lock': 145,\n 'my computer': 182,\n 'my calculator': 183,\n ';': 186,\n '=': 187,\n ',': 188,\n '-': 189,\n '.': 190,\n '/': 191,\n '`': 192,\n '[': 219,\n '\\\\': 220,\n ']': 221,\n \"'\": 222\n };\n\n // Helper aliases\n\n var aliases = exports.aliases = {\n 'windows': 91,\n '⇧': 16,\n '⌥': 18,\n '⌃': 17,\n '⌘': 91,\n 'ctl': 17,\n 'control': 17,\n 'option': 18,\n 'pause': 19,\n 'break': 19,\n 'caps': 20,\n 'return': 13,\n 'escape': 27,\n 'spc': 32,\n 'spacebar': 32,\n 'pgup': 33,\n 'pgdn': 34,\n 'ins': 45,\n 'del': 46,\n 'cmd': 91\n };\n\n /*!\n * Programatically add the following\n */\n\n // lower case chars\n for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32;\n\n // numbers\n for (var i = 48; i < 58; i++) codes[i - 48] = i;\n\n // function keys\n for (i = 1; i < 13; i++) codes['f' + i] = i + 111;\n\n // numpad keys\n for (i = 0; i < 10; i++) codes['numpad ' + i] = i + 96;\n\n /**\n * Get by code\n *\n * exports.name[13] // => 'Enter'\n */\n\n var names = exports.names = exports.title = {}; // title for backward compat\n\n // Create reverse mapping\n for (i in codes) names[codes[i]] = i;\n\n // Add aliases\n for (var alias in aliases) {\n codes[alias] = aliases[alias];\n }\n });\n keycode.code;\n keycode.codes;\n keycode.aliases;\n keycode.names;\n keycode.title;\n\n /**\n * Player Component - Base class for all UI objects\n *\n * @file component.js\n */\n\n /**\n * Base class for all UI Components.\n * Components are UI objects which represent both a javascript object and an element\n * in the DOM. They can be children of other components, and can have\n * children themselves.\n *\n * Components can also use methods from {@link EventTarget}\n */\n class Component$1 {\n /**\n * A callback that is called when a component is ready. Does not have any\n * parameters and any callback value will be ignored.\n *\n * @callback ReadyCallback\n * @this Component\n */\n\n /**\n * Creates an instance of this class.\n *\n * @param { import('./player').default } player\n * The `Player` that this class should be attached to.\n *\n * @param {Object} [options]\n * The key/value store of component options.\n *\n * @param {Object[]} [options.children]\n * An array of children objects to initialize this component with. Children objects have\n * a name property that will be used if more than one component of the same type needs to be\n * added.\n *\n * @param {string} [options.className]\n * A class or space separated list of classes to add the component\n *\n * @param {ReadyCallback} [ready]\n * Function that gets called when the `Component` is ready.\n */\n constructor(player, options, ready) {\n // The component might be the player itself and we can't pass `this` to super\n if (!player && this.play) {\n this.player_ = player = this; // eslint-disable-line\n } else {\n this.player_ = player;\n }\n this.isDisposed_ = false;\n\n // Hold the reference to the parent component via `addChild` method\n this.parentComponent_ = null;\n\n // Make a copy of prototype.options_ to protect against overriding defaults\n this.options_ = merge$2({}, this.options_);\n\n // Updated options with supplied options\n options = this.options_ = merge$2(this.options_, options);\n\n // Get ID from options or options element if one is supplied\n this.id_ = options.id || options.el && options.el.id;\n\n // If there was no ID from the options, generate one\n if (!this.id_) {\n // Don't require the player ID function in the case of mock players\n const id = player && player.id && player.id() || 'no_player';\n this.id_ = `${id}_component_${newGUID()}`;\n }\n this.name_ = options.name || null;\n\n // Create element if one wasn't provided in options\n if (options.el) {\n this.el_ = options.el;\n } else if (options.createEl !== false) {\n this.el_ = this.createEl();\n }\n if (options.className && this.el_) {\n options.className.split(' ').forEach(c => this.addClass(c));\n }\n\n // Remove the placeholder event methods. If the component is evented, the\n // real methods are added next\n ['on', 'off', 'one', 'any', 'trigger'].forEach(fn => {\n this[fn] = undefined;\n });\n\n // if evented is anything except false, we want to mixin in evented\n if (options.evented !== false) {\n // Make this an evented object and use `el_`, if available, as its event bus\n evented(this, {\n eventBusKey: this.el_ ? 'el_' : null\n });\n this.handleLanguagechange = this.handleLanguagechange.bind(this);\n this.on(this.player_, 'languagechange', this.handleLanguagechange);\n }\n stateful(this, this.constructor.defaultState);\n this.children_ = [];\n this.childIndex_ = {};\n this.childNameIndex_ = {};\n this.setTimeoutIds_ = new Set();\n this.setIntervalIds_ = new Set();\n this.rafIds_ = new Set();\n this.namedRafs_ = new Map();\n this.clearingTimersOnDispose_ = false;\n\n // Add any child components in options\n if (options.initChildren !== false) {\n this.initChildren();\n }\n\n // Don't want to trigger ready here or it will go before init is actually\n // finished for all children that run this constructor\n this.ready(ready);\n if (options.reportTouchActivity !== false) {\n this.enableTouchActivity();\n }\n }\n\n // `on`, `off`, `one`, `any` and `trigger` are here so tsc includes them in definitions.\n // They are replaced or removed in the constructor\n\n /**\n * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a\n * function that will get called when an event with a certain name gets triggered.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to call with `EventTarget`s\n */\n on(type, fn) {}\n\n /**\n * Removes an `event listener` for a specific event from an instance of `EventTarget`.\n * This makes it so that the `event listener` will no longer get called when the\n * named event happens.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to remove.\n */\n off(type, fn) {}\n\n /**\n * This function will add an `event listener` that gets triggered only once. After the\n * first trigger it will get removed. This is like adding an `event listener`\n * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to be called once for each event name.\n */\n one(type, fn) {}\n\n /**\n * This function will add an `event listener` that gets triggered only once and is\n * removed from all events. This is like adding an array of `event listener`s\n * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the\n * first time it is triggered.\n *\n * @param {string|string[]} type\n * An event name or an array of event names.\n *\n * @param {Function} fn\n * The function to be called once for each event name.\n */\n any(type, fn) {}\n\n /**\n * This function causes an event to happen. This will then cause any `event listeners`\n * that are waiting for that event, to get called. If there are no `event listeners`\n * for an event then nothing will happen.\n *\n * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.\n * Trigger will also call the `on` + `uppercaseEventName` function.\n *\n * Example:\n * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call\n * `onClick` if it exists.\n *\n * @param {string|Event|Object} event\n * The name of the event, an `Event`, or an object with a key of type set to\n * an event name.\n */\n trigger(event) {}\n\n /**\n * Dispose of the `Component` and all child components.\n *\n * @fires Component#dispose\n *\n * @param {Object} options\n * @param {Element} options.originalEl element with which to replace player element\n */\n dispose(options = {}) {\n // Bail out if the component has already been disposed.\n if (this.isDisposed_) {\n return;\n }\n if (this.readyQueue_) {\n this.readyQueue_.length = 0;\n }\n\n /**\n * Triggered when a `Component` is disposed.\n *\n * @event Component#dispose\n * @type {Event}\n *\n * @property {boolean} [bubbles=false]\n * set to false so that the dispose event does not\n * bubble up\n */\n this.trigger({\n type: 'dispose',\n bubbles: false\n });\n this.isDisposed_ = true;\n\n // Dispose all children.\n if (this.children_) {\n for (let i = this.children_.length - 1; i >= 0; i--) {\n if (this.children_[i].dispose) {\n this.children_[i].dispose();\n }\n }\n }\n\n // Delete child references\n this.children_ = null;\n this.childIndex_ = null;\n this.childNameIndex_ = null;\n this.parentComponent_ = null;\n if (this.el_) {\n // Remove element from DOM\n if (this.el_.parentNode) {\n if (options.restoreEl) {\n this.el_.parentNode.replaceChild(options.restoreEl, this.el_);\n } else {\n this.el_.parentNode.removeChild(this.el_);\n }\n }\n this.el_ = null;\n }\n\n // remove reference to the player after disposing of the element\n this.player_ = null;\n }\n\n /**\n * Determine whether or not this component has been disposed.\n *\n * @return {boolean}\n * If the component has been disposed, will be `true`. Otherwise, `false`.\n */\n isDisposed() {\n return Boolean(this.isDisposed_);\n }\n\n /**\n * Return the {@link Player} that the `Component` has attached to.\n *\n * @return { import('./player').default }\n * The player that this `Component` has attached to.\n */\n player() {\n return this.player_;\n }\n\n /**\n * Deep merge of options objects with new options.\n * > Note: When both `obj` and `options` contain properties whose values are objects.\n * The two properties get merged using {@link module:obj.merge}\n *\n * @param {Object} obj\n * The object that contains new options.\n *\n * @return {Object}\n * A new object of `this.options_` and `obj` merged together.\n */\n options(obj) {\n if (!obj) {\n return this.options_;\n }\n this.options_ = merge$2(this.options_, obj);\n return this.options_;\n }\n\n /**\n * Get the `Component`s DOM element\n *\n * @return {Element}\n * The DOM element for this `Component`.\n */\n el() {\n return this.el_;\n }\n\n /**\n * Create the `Component`s DOM element.\n *\n * @param {string} [tagName]\n * Element's DOM node type. e.g. 'div'\n *\n * @param {Object} [properties]\n * An object of properties that should be set.\n *\n * @param {Object} [attributes]\n * An object of attributes that should be set.\n *\n * @return {Element}\n * The element that gets created.\n */\n createEl(tagName, properties, attributes) {\n return createEl(tagName, properties, attributes);\n }\n\n /**\n * Localize a string given the string in english.\n *\n * If tokens are provided, it'll try and run a simple token replacement on the provided string.\n * The tokens it looks for look like `{1}` with the index being 1-indexed into the tokens array.\n *\n * If a `defaultValue` is provided, it'll use that over `string`,\n * if a value isn't found in provided language files.\n * This is useful if you want to have a descriptive key for token replacement\n * but have a succinct localized string and not require `en.json` to be included.\n *\n * Currently, it is used for the progress bar timing.\n * ```js\n * {\n * \"progress bar timing: currentTime={1} duration={2}\": \"{1} of {2}\"\n * }\n * ```\n * It is then used like so:\n * ```js\n * this.localize('progress bar timing: currentTime={1} duration{2}',\n * [this.player_.currentTime(), this.player_.duration()],\n * '{1} of {2}');\n * ```\n *\n * Which outputs something like: `01:23 of 24:56`.\n *\n *\n * @param {string} string\n * The string to localize and the key to lookup in the language files.\n * @param {string[]} [tokens]\n * If the current item has token replacements, provide the tokens here.\n * @param {string} [defaultValue]\n * Defaults to `string`. Can be a default value to use for token replacement\n * if the lookup key is needed to be separate.\n *\n * @return {string}\n * The localized string or if no localization exists the english string.\n */\n localize(string, tokens, defaultValue = string) {\n const code = this.player_.language && this.player_.language();\n const languages = this.player_.languages && this.player_.languages();\n const language = languages && languages[code];\n const primaryCode = code && code.split('-')[0];\n const primaryLang = languages && languages[primaryCode];\n let localizedString = defaultValue;\n if (language && language[string]) {\n localizedString = language[string];\n } else if (primaryLang && primaryLang[string]) {\n localizedString = primaryLang[string];\n }\n if (tokens) {\n localizedString = localizedString.replace(/\\{(\\d+)\\}/g, function (match, index) {\n const value = tokens[index - 1];\n let ret = value;\n if (typeof value === 'undefined') {\n ret = match;\n }\n return ret;\n });\n }\n return localizedString;\n }\n\n /**\n * Handles language change for the player in components. Should be overridden by sub-components.\n *\n * @abstract\n */\n handleLanguagechange() {}\n\n /**\n * Return the `Component`s DOM element. This is where children get inserted.\n * This will usually be the the same as the element returned in {@link Component#el}.\n *\n * @return {Element}\n * The content element for this `Component`.\n */\n contentEl() {\n return this.contentEl_ || this.el_;\n }\n\n /**\n * Get this `Component`s ID\n *\n * @return {string}\n * The id of this `Component`\n */\n id() {\n return this.id_;\n }\n\n /**\n * Get the `Component`s name. The name gets used to reference the `Component`\n * and is set during registration.\n *\n * @return {string}\n * The name of this `Component`.\n */\n name() {\n return this.name_;\n }\n\n /**\n * Get an array of all child components\n *\n * @return {Array}\n * The children\n */\n children() {\n return this.children_;\n }\n\n /**\n * Returns the child `Component` with the given `id`.\n *\n * @param {string} id\n * The id of the child `Component` to get.\n *\n * @return {Component|undefined}\n * The child `Component` with the given `id` or undefined.\n */\n getChildById(id) {\n return this.childIndex_[id];\n }\n\n /**\n * Returns the child `Component` with the given `name`.\n *\n * @param {string} name\n * The name of the child `Component` to get.\n *\n * @return {Component|undefined}\n * The child `Component` with the given `name` or undefined.\n */\n getChild(name) {\n if (!name) {\n return;\n }\n return this.childNameIndex_[name];\n }\n\n /**\n * Returns the descendant `Component` following the givent\n * descendant `names`. For instance ['foo', 'bar', 'baz'] would\n * try to get 'foo' on the current component, 'bar' on the 'foo'\n * component and 'baz' on the 'bar' component and return undefined\n * if any of those don't exist.\n *\n * @param {...string[]|...string} names\n * The name of the child `Component` to get.\n *\n * @return {Component|undefined}\n * The descendant `Component` following the given descendant\n * `names` or undefined.\n */\n getDescendant(...names) {\n // flatten array argument into the main array\n names = names.reduce((acc, n) => acc.concat(n), []);\n let currentChild = this;\n for (let i = 0; i < names.length; i++) {\n currentChild = currentChild.getChild(names[i]);\n if (!currentChild || !currentChild.getChild) {\n return;\n }\n }\n return currentChild;\n }\n\n /**\n * Add a child `Component` inside the current `Component`.\n *\n *\n * @param {string|Component} child\n * The name or instance of a child to add.\n *\n * @param {Object} [options={}]\n * The key/value store of options that will get passed to children of\n * the child.\n *\n * @param {number} [index=this.children_.length]\n * The index to attempt to add a child into.\n *\n * @return {Component}\n * The `Component` that gets added as a child. When using a string the\n * `Component` will get created by this process.\n */\n addChild(child, options = {}, index = this.children_.length) {\n let component;\n let componentName;\n\n // If child is a string, create component with options\n if (typeof child === 'string') {\n componentName = toTitleCase$1(child);\n const componentClassName = options.componentClass || componentName;\n\n // Set name through options\n options.name = componentName;\n\n // Create a new object & element for this controls set\n // If there's no .player_, this is a player\n const ComponentClass = Component$1.getComponent(componentClassName);\n if (!ComponentClass) {\n throw new Error(`Component ${componentClassName} does not exist`);\n }\n\n // data stored directly on the videojs object may be\n // misidentified as a component to retain\n // backwards-compatibility with 4.x. check to make sure the\n // component class can be instantiated.\n if (typeof ComponentClass !== 'function') {\n return null;\n }\n component = new ComponentClass(this.player_ || this, options);\n\n // child is a component instance\n } else {\n component = child;\n }\n if (component.parentComponent_) {\n component.parentComponent_.removeChild(component);\n }\n this.children_.splice(index, 0, component);\n component.parentComponent_ = this;\n if (typeof component.id === 'function') {\n this.childIndex_[component.id()] = component;\n }\n\n // If a name wasn't used to create the component, check if we can use the\n // name function of the component\n componentName = componentName || component.name && toTitleCase$1(component.name());\n if (componentName) {\n this.childNameIndex_[componentName] = component;\n this.childNameIndex_[toLowerCase(componentName)] = component;\n }\n\n // Add the UI object's element to the container div (box)\n // Having an element is not required\n if (typeof component.el === 'function' && component.el()) {\n // If inserting before a component, insert before that component's element\n let refNode = null;\n if (this.children_[index + 1]) {\n // Most children are components, but the video tech is an HTML element\n if (this.children_[index + 1].el_) {\n refNode = this.children_[index + 1].el_;\n } else if (isEl(this.children_[index + 1])) {\n refNode = this.children_[index + 1];\n }\n }\n this.contentEl().insertBefore(component.el(), refNode);\n }\n\n // Return so it can stored on parent object if desired.\n return component;\n }\n\n /**\n * Remove a child `Component` from this `Component`s list of children. Also removes\n * the child `Component`s element from this `Component`s element.\n *\n * @param {Component} component\n * The child `Component` to remove.\n */\n removeChild(component) {\n if (typeof component === 'string') {\n component = this.getChild(component);\n }\n if (!component || !this.children_) {\n return;\n }\n let childFound = false;\n for (let i = this.children_.length - 1; i >= 0; i--) {\n if (this.children_[i] === component) {\n childFound = true;\n this.children_.splice(i, 1);\n break;\n }\n }\n if (!childFound) {\n return;\n }\n component.parentComponent_ = null;\n this.childIndex_[component.id()] = null;\n this.childNameIndex_[toTitleCase$1(component.name())] = null;\n this.childNameIndex_[toLowerCase(component.name())] = null;\n const compEl = component.el();\n if (compEl && compEl.parentNode === this.contentEl()) {\n this.contentEl().removeChild(component.el());\n }\n }\n\n /**\n * Add and initialize default child `Component`s based upon options.\n */\n initChildren() {\n const children = this.options_.children;\n if (children) {\n // `this` is `parent`\n const parentOptions = this.options_;\n const handleAdd = child => {\n const name = child.name;\n let opts = child.opts;\n\n // Allow options for children to be set at the parent options\n // e.g. videojs(id, { controlBar: false });\n // instead of videojs(id, { children: { controlBar: false });\n if (parentOptions[name] !== undefined) {\n opts = parentOptions[name];\n }\n\n // Allow for disabling default components\n // e.g. options['children']['posterImage'] = false\n if (opts === false) {\n return;\n }\n\n // Allow options to be passed as a simple boolean if no configuration\n // is necessary.\n if (opts === true) {\n opts = {};\n }\n\n // We also want to pass the original player options\n // to each component as well so they don't need to\n // reach back into the player for options later.\n opts.playerOptions = this.options_.playerOptions;\n\n // Create and add the child component.\n // Add a direct reference to the child by name on the parent instance.\n // If two of the same component are used, different names should be supplied\n // for each\n const newChild = this.addChild(name, opts);\n if (newChild) {\n this[name] = newChild;\n }\n };\n\n // Allow for an array of children details to passed in the options\n let workingChildren;\n const Tech = Component$1.getComponent('Tech');\n if (Array.isArray(children)) {\n workingChildren = children;\n } else {\n workingChildren = Object.keys(children);\n }\n workingChildren\n // children that are in this.options_ but also in workingChildren would\n // give us extra children we do not want. So, we want to filter them out.\n .concat(Object.keys(this.options_).filter(function (child) {\n return !workingChildren.some(function (wchild) {\n if (typeof wchild === 'string') {\n return child === wchild;\n }\n return child === wchild.name;\n });\n })).map(child => {\n let name;\n let opts;\n if (typeof child === 'string') {\n name = child;\n opts = children[name] || this.options_[name] || {};\n } else {\n name = child.name;\n opts = child;\n }\n return {\n name,\n opts\n };\n }).filter(child => {\n // we have to make sure that child.name isn't in the techOrder since\n // techs are registered as Components but can't aren't compatible\n // See https://github.com/videojs/video.js/issues/2772\n const c = Component$1.getComponent(child.opts.componentClass || toTitleCase$1(child.name));\n return c && !Tech.isTech(c);\n }).forEach(handleAdd);\n }\n }\n\n /**\n * Builds the default DOM class name. Should be overridden by sub-components.\n *\n * @return {string}\n * The DOM class name for this object.\n *\n * @abstract\n */\n buildCSSClass() {\n // Child classes can include a function that does:\n // return 'CLASS NAME' + this._super();\n return '';\n }\n\n /**\n * Bind a listener to the component's ready state.\n * Different from event listeners in that if the ready event has already happened\n * it will trigger the function immediately.\n *\n * @param {ReadyCallback} fn\n * Function that gets called when the `Component` is ready.\n *\n * @return {Component}\n * Returns itself; method can be chained.\n */\n ready(fn, sync = false) {\n if (!fn) {\n return;\n }\n if (!this.isReady_) {\n this.readyQueue_ = this.readyQueue_ || [];\n this.readyQueue_.push(fn);\n return;\n }\n if (sync) {\n fn.call(this);\n } else {\n // Call the function asynchronously by default for consistency\n this.setTimeout(fn, 1);\n }\n }\n\n /**\n * Trigger all the ready listeners for this `Component`.\n *\n * @fires Component#ready\n */\n triggerReady() {\n this.isReady_ = true;\n\n // Ensure ready is triggered asynchronously\n this.setTimeout(function () {\n const readyQueue = this.readyQueue_;\n\n // Reset Ready Queue\n this.readyQueue_ = [];\n if (readyQueue && readyQueue.length > 0) {\n readyQueue.forEach(function (fn) {\n fn.call(this);\n }, this);\n }\n\n // Allow for using event listeners also\n /**\n * Triggered when a `Component` is ready.\n *\n * @event Component#ready\n * @type {Event}\n */\n this.trigger('ready');\n }, 1);\n }\n\n /**\n * Find a single DOM element matching a `selector`. This can be within the `Component`s\n * `contentEl()` or another custom context.\n *\n * @param {string} selector\n * A valid CSS selector, which will be passed to `querySelector`.\n *\n * @param {Element|string} [context=this.contentEl()]\n * A DOM element within which to query. Can also be a selector string in\n * which case the first matching element will get used as context. If\n * missing `this.contentEl()` gets used. If `this.contentEl()` returns\n * nothing it falls back to `document`.\n *\n * @return {Element|null}\n * the dom element that was found, or null\n *\n * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)\n */\n $(selector, context) {\n return $(selector, context || this.contentEl());\n }\n\n /**\n * Finds all DOM element matching a `selector`. This can be within the `Component`s\n * `contentEl()` or another custom context.\n *\n * @param {string} selector\n * A valid CSS selector, which will be passed to `querySelectorAll`.\n *\n * @param {Element|string} [context=this.contentEl()]\n * A DOM element within which to query. Can also be a selector string in\n * which case the first matching element will get used as context. If\n * missing `this.contentEl()` gets used. If `this.contentEl()` returns\n * nothing it falls back to `document`.\n *\n * @return {NodeList}\n * a list of dom elements that were found\n *\n * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)\n */\n $$(selector, context) {\n return $$(selector, context || this.contentEl());\n }\n\n /**\n * Check if a component's element has a CSS class name.\n *\n * @param {string} classToCheck\n * CSS class name to check.\n *\n * @return {boolean}\n * - True if the `Component` has the class.\n * - False if the `Component` does not have the class`\n */\n hasClass(classToCheck) {\n return hasClass(this.el_, classToCheck);\n }\n\n /**\n * Add a CSS class name to the `Component`s element.\n *\n * @param {...string} classesToAdd\n * One or more CSS class name to add.\n */\n addClass(...classesToAdd) {\n addClass(this.el_, ...classesToAdd);\n }\n\n /**\n * Remove a CSS class name from the `Component`s element.\n *\n * @param {...string} classesToRemove\n * One or more CSS class name to remove.\n */\n removeClass(...classesToRemove) {\n removeClass(this.el_, ...classesToRemove);\n }\n\n /**\n * Add or remove a CSS class name from the component's element.\n * - `classToToggle` gets added when {@link Component#hasClass} would return false.\n * - `classToToggle` gets removed when {@link Component#hasClass} would return true.\n *\n * @param {string} classToToggle\n * The class to add or remove based on (@link Component#hasClass}\n *\n * @param {boolean|Dom~predicate} [predicate]\n * An {@link Dom~predicate} function or a boolean\n */\n toggleClass(classToToggle, predicate) {\n toggleClass(this.el_, classToToggle, predicate);\n }\n\n /**\n * Show the `Component`s element if it is hidden by removing the\n * 'vjs-hidden' class name from it.\n */\n show() {\n this.removeClass('vjs-hidden');\n }\n\n /**\n * Hide the `Component`s element if it is currently showing by adding the\n * 'vjs-hidden` class name to it.\n */\n hide() {\n this.addClass('vjs-hidden');\n }\n\n /**\n * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'\n * class name to it. Used during fadeIn/fadeOut.\n *\n * @private\n */\n lockShowing() {\n this.addClass('vjs-lock-showing');\n }\n\n /**\n * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'\n * class name from it. Used during fadeIn/fadeOut.\n *\n * @private\n */\n unlockShowing() {\n this.removeClass('vjs-lock-showing');\n }\n\n /**\n * Get the value of an attribute on the `Component`s element.\n *\n * @param {string} attribute\n * Name of the attribute to get the value from.\n *\n * @return {string|null}\n * - The value of the attribute that was asked for.\n * - Can be an empty string on some browsers if the attribute does not exist\n * or has no value\n * - Most browsers will return null if the attribute does not exist or has\n * no value.\n *\n * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}\n */\n getAttribute(attribute) {\n return getAttribute(this.el_, attribute);\n }\n\n /**\n * Set the value of an attribute on the `Component`'s element\n *\n * @param {string} attribute\n * Name of the attribute to set.\n *\n * @param {string} value\n * Value to set the attribute to.\n *\n * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}\n */\n setAttribute(attribute, value) {\n setAttribute(this.el_, attribute, value);\n }\n\n /**\n * Remove an attribute from the `Component`s element.\n *\n * @param {string} attribute\n * Name of the attribute to remove.\n *\n * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}\n */\n removeAttribute(attribute) {\n removeAttribute(this.el_, attribute);\n }\n\n /**\n * Get or set the width of the component based upon the CSS styles.\n * See {@link Component#dimension} for more detailed information.\n *\n * @param {number|string} [num]\n * The width that you want to set postfixed with '%', 'px' or nothing.\n *\n * @param {boolean} [skipListeners]\n * Skip the componentresize event trigger\n *\n * @return {number|string}\n * The width when getting, zero if there is no width. Can be a string\n * postpixed with '%' or 'px'.\n */\n width(num, skipListeners) {\n return this.dimension('width', num, skipListeners);\n }\n\n /**\n * Get or set the height of the component based upon the CSS styles.\n * See {@link Component#dimension} for more detailed information.\n *\n * @param {number|string} [num]\n * The height that you want to set postfixed with '%', 'px' or nothing.\n *\n * @param {boolean} [skipListeners]\n * Skip the componentresize event trigger\n *\n * @return {number|string}\n * The width when getting, zero if there is no width. Can be a string\n * postpixed with '%' or 'px'.\n */\n height(num, skipListeners) {\n return this.dimension('height', num, skipListeners);\n }\n\n /**\n * Set both the width and height of the `Component` element at the same time.\n *\n * @param {number|string} width\n * Width to set the `Component`s element to.\n *\n * @param {number|string} height\n * Height to set the `Component`s element to.\n */\n dimensions(width, height) {\n // Skip componentresize listeners on width for optimization\n this.width(width, true);\n this.height(height);\n }\n\n /**\n * Get or set width or height of the `Component` element. This is the shared code\n * for the {@link Component#width} and {@link Component#height}.\n *\n * Things to know:\n * - If the width or height in an number this will return the number postfixed with 'px'.\n * - If the width/height is a percent this will return the percent postfixed with '%'\n * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function\n * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.\n * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}\n * for more information\n * - If you want the computed style of the component, use {@link Component#currentWidth}\n * and {@link {Component#currentHeight}\n *\n * @fires Component#componentresize\n *\n * @param {string} widthOrHeight\n 8 'width' or 'height'\n *\n * @param {number|string} [num]\n 8 New dimension\n *\n * @param {boolean} [skipListeners]\n * Skip componentresize event trigger\n *\n * @return {number}\n * The dimension when getting or 0 if unset\n */\n dimension(widthOrHeight, num, skipListeners) {\n if (num !== undefined) {\n // Set to zero if null or literally NaN (NaN !== NaN)\n if (num === null || num !== num) {\n num = 0;\n }\n\n // Check if using css width/height (% or px) and adjust\n if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {\n this.el_.style[widthOrHeight] = num;\n } else if (num === 'auto') {\n this.el_.style[widthOrHeight] = '';\n } else {\n this.el_.style[widthOrHeight] = num + 'px';\n }\n\n // skipListeners allows us to avoid triggering the resize event when setting both width and height\n if (!skipListeners) {\n /**\n * Triggered when a component is resized.\n *\n * @event Component#componentresize\n * @type {Event}\n */\n this.trigger('componentresize');\n }\n return;\n }\n\n // Not setting a value, so getting it\n // Make sure element exists\n if (!this.el_) {\n return 0;\n }\n\n // Get dimension value from style\n const val = this.el_.style[widthOrHeight];\n const pxIndex = val.indexOf('px');\n if (pxIndex !== -1) {\n // Return the pixel value with no 'px'\n return parseInt(val.slice(0, pxIndex), 10);\n }\n\n // No px so using % or no style was set, so falling back to offsetWidth/height\n // If component has display:none, offset will return 0\n // TODO: handle display:none and no dimension style using px\n return parseInt(this.el_['offset' + toTitleCase$1(widthOrHeight)], 10);\n }\n\n /**\n * Get the computed width or the height of the component's element.\n *\n * Uses `window.getComputedStyle`.\n *\n * @param {string} widthOrHeight\n * A string containing 'width' or 'height'. Whichever one you want to get.\n *\n * @return {number}\n * The dimension that gets asked for or 0 if nothing was set\n * for that dimension.\n */\n currentDimension(widthOrHeight) {\n let computedWidthOrHeight = 0;\n if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {\n throw new Error('currentDimension only accepts width or height value');\n }\n computedWidthOrHeight = computedStyle(this.el_, widthOrHeight);\n\n // remove 'px' from variable and parse as integer\n computedWidthOrHeight = parseFloat(computedWidthOrHeight);\n\n // if the computed value is still 0, it's possible that the browser is lying\n // and we want to check the offset values.\n // This code also runs wherever getComputedStyle doesn't exist.\n if (computedWidthOrHeight === 0 || isNaN(computedWidthOrHeight)) {\n const rule = `offset${toTitleCase$1(widthOrHeight)}`;\n computedWidthOrHeight = this.el_[rule];\n }\n return computedWidthOrHeight;\n }\n\n /**\n * An object that contains width and height values of the `Component`s\n * computed style. Uses `window.getComputedStyle`.\n *\n * @typedef {Object} Component~DimensionObject\n *\n * @property {number} width\n * The width of the `Component`s computed style.\n *\n * @property {number} height\n * The height of the `Component`s computed style.\n */\n\n /**\n * Get an object that contains computed width and height values of the\n * component's element.\n *\n * Uses `window.getComputedStyle`.\n *\n * @return {Component~DimensionObject}\n * The computed dimensions of the component's element.\n */\n currentDimensions() {\n return {\n width: this.currentDimension('width'),\n height: this.currentDimension('height')\n };\n }\n\n /**\n * Get the computed width of the component's element.\n *\n * Uses `window.getComputedStyle`.\n *\n * @return {number}\n * The computed width of the component's element.\n */\n currentWidth() {\n return this.currentDimension('width');\n }\n\n /**\n * Get the computed height of the component's element.\n *\n * Uses `window.getComputedStyle`.\n *\n * @return {number}\n * The computed height of the component's element.\n */\n currentHeight() {\n return this.currentDimension('height');\n }\n\n /**\n * Set the focus to this component\n */\n focus() {\n this.el_.focus();\n }\n\n /**\n * Remove the focus from this component\n */\n blur() {\n this.el_.blur();\n }\n\n /**\n * When this Component receives a `keydown` event which it does not process,\n * it passes the event to the Player for handling.\n *\n * @param {KeyboardEvent} event\n * The `keydown` event that caused this function to be called.\n */\n handleKeyDown(event) {\n if (this.player_) {\n // We only stop propagation here because we want unhandled events to fall\n // back to the browser. Exclude Tab for focus trapping.\n if (!keycode.isEventKey(event, 'Tab')) {\n event.stopPropagation();\n }\n this.player_.handleKeyDown(event);\n }\n }\n\n /**\n * Many components used to have a `handleKeyPress` method, which was poorly\n * named because it listened to a `keydown` event. This method name now\n * delegates to `handleKeyDown`. This means anyone calling `handleKeyPress`\n * will not see their method calls stop working.\n *\n * @param {Event} event\n * The event that caused this function to be called.\n */\n handleKeyPress(event) {\n this.handleKeyDown(event);\n }\n\n /**\n * Emit a 'tap' events when touch event support gets detected. This gets used to\n * support toggling the controls through a tap on the video. They get enabled\n * because every sub-component would have extra overhead otherwise.\n *\n * @private\n * @fires Component#tap\n * @listens Component#touchstart\n * @listens Component#touchmove\n * @listens Component#touchleave\n * @listens Component#touchcancel\n * @listens Component#touchend\n */\n emitTapEvents() {\n // Track the start time so we can determine how long the touch lasted\n let touchStart = 0;\n let firstTouch = null;\n\n // Maximum movement allowed during a touch event to still be considered a tap\n // Other popular libs use anywhere from 2 (hammer.js) to 15,\n // so 10 seems like a nice, round number.\n const tapMovementThreshold = 10;\n\n // The maximum length a touch can be while still being considered a tap\n const touchTimeThreshold = 200;\n let couldBeTap;\n this.on('touchstart', function (event) {\n // If more than one finger, don't consider treating this as a click\n if (event.touches.length === 1) {\n // Copy pageX/pageY from the object\n firstTouch = {\n pageX: event.touches[0].pageX,\n pageY: event.touches[0].pageY\n };\n // Record start time so we can detect a tap vs. \"touch and hold\"\n touchStart = window.performance.now();\n // Reset couldBeTap tracking\n couldBeTap = true;\n }\n });\n this.on('touchmove', function (event) {\n // If more than one finger, don't consider treating this as a click\n if (event.touches.length > 1) {\n couldBeTap = false;\n } else if (firstTouch) {\n // Some devices will throw touchmoves for all but the slightest of taps.\n // So, if we moved only a small distance, this could still be a tap\n const xdiff = event.touches[0].pageX - firstTouch.pageX;\n const ydiff = event.touches[0].pageY - firstTouch.pageY;\n const touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);\n if (touchDistance > tapMovementThreshold) {\n couldBeTap = false;\n }\n }\n });\n const noTap = function () {\n couldBeTap = false;\n };\n\n // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s\n this.on('touchleave', noTap);\n this.on('touchcancel', noTap);\n\n // When the touch ends, measure how long it took and trigger the appropriate\n // event\n this.on('touchend', function (event) {\n firstTouch = null;\n // Proceed only if the touchmove/leave/cancel event didn't happen\n if (couldBeTap === true) {\n // Measure how long the touch lasted\n const touchTime = window.performance.now() - touchStart;\n\n // Make sure the touch was less than the threshold to be considered a tap\n if (touchTime < touchTimeThreshold) {\n // Don't let browser turn this into a click\n event.preventDefault();\n /**\n * Triggered when a `Component` is tapped.\n *\n * @event Component#tap\n * @type {MouseEvent}\n */\n this.trigger('tap');\n // It may be good to copy the touchend event object and change the\n // type to tap, if the other event properties aren't exact after\n // Events.fixEvent runs (e.g. event.target)\n }\n }\n });\n }\n\n /**\n * This function reports user activity whenever touch events happen. This can get\n * turned off by any sub-components that wants touch events to act another way.\n *\n * Report user touch activity when touch events occur. User activity gets used to\n * determine when controls should show/hide. It is simple when it comes to mouse\n * events, because any mouse event should show the controls. So we capture mouse\n * events that bubble up to the player and report activity when that happens.\n * With touch events it isn't as easy as `touchstart` and `touchend` toggle player\n * controls. So touch events can't help us at the player level either.\n *\n * User activity gets checked asynchronously. So what could happen is a tap event\n * on the video turns the controls off. Then the `touchend` event bubbles up to\n * the player. Which, if it reported user activity, would turn the controls right\n * back on. We also don't want to completely block touch events from bubbling up.\n * Furthermore a `touchmove` event and anything other than a tap, should not turn\n * controls back on.\n *\n * @listens Component#touchstart\n * @listens Component#touchmove\n * @listens Component#touchend\n * @listens Component#touchcancel\n */\n enableTouchActivity() {\n // Don't continue if the root player doesn't support reporting user activity\n if (!this.player() || !this.player().reportUserActivity) {\n return;\n }\n\n // listener for reporting that the user is active\n const report = bind_(this.player(), this.player().reportUserActivity);\n let touchHolding;\n this.on('touchstart', function () {\n report();\n // For as long as the they are touching the device or have their mouse down,\n // we consider them active even if they're not moving their finger or mouse.\n // So we want to continue to update that they are active\n this.clearInterval(touchHolding);\n // report at the same interval as activityCheck\n touchHolding = this.setInterval(report, 250);\n });\n const touchEnd = function (event) {\n report();\n // stop the interval that maintains activity if the touch is holding\n this.clearInterval(touchHolding);\n };\n this.on('touchmove', report);\n this.on('touchend', touchEnd);\n this.on('touchcancel', touchEnd);\n }\n\n /**\n * A callback that has no parameters and is bound into `Component`s context.\n *\n * @callback Component~GenericCallback\n * @this Component\n */\n\n /**\n * Creates a function that runs after an `x` millisecond timeout. This function is a\n * wrapper around `window.setTimeout`. There are a few reasons to use this one\n * instead though:\n * 1. It gets cleared via {@link Component#clearTimeout} when\n * {@link Component#dispose} gets called.\n * 2. The function callback will gets turned into a {@link Component~GenericCallback}\n *\n * > Note: You can't use `window.clearTimeout` on the id returned by this function. This\n * will cause its dispose listener not to get cleaned up! Please use\n * {@link Component#clearTimeout} or {@link Component#dispose} instead.\n *\n * @param {Component~GenericCallback} fn\n * The function that will be run after `timeout`.\n *\n * @param {number} timeout\n * Timeout in milliseconds to delay before executing the specified function.\n *\n * @return {number}\n * Returns a timeout ID that gets used to identify the timeout. It can also\n * get used in {@link Component#clearTimeout} to clear the timeout that\n * was set.\n *\n * @listens Component#dispose\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}\n */\n setTimeout(fn, timeout) {\n // declare as variables so they are properly available in timeout function\n // eslint-disable-next-line\n var timeoutId;\n fn = bind_(this, fn);\n this.clearTimersOnDispose_();\n timeoutId = window.setTimeout(() => {\n if (this.setTimeoutIds_.has(timeoutId)) {\n this.setTimeoutIds_.delete(timeoutId);\n }\n fn();\n }, timeout);\n this.setTimeoutIds_.add(timeoutId);\n return timeoutId;\n }\n\n /**\n * Clears a timeout that gets created via `window.setTimeout` or\n * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}\n * use this function instead of `window.clearTimout`. If you don't your dispose\n * listener will not get cleaned up until {@link Component#dispose}!\n *\n * @param {number} timeoutId\n * The id of the timeout to clear. The return value of\n * {@link Component#setTimeout} or `window.setTimeout`.\n *\n * @return {number}\n * Returns the timeout id that was cleared.\n *\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}\n */\n clearTimeout(timeoutId) {\n if (this.setTimeoutIds_.has(timeoutId)) {\n this.setTimeoutIds_.delete(timeoutId);\n window.clearTimeout(timeoutId);\n }\n return timeoutId;\n }\n\n /**\n * Creates a function that gets run every `x` milliseconds. This function is a wrapper\n * around `window.setInterval`. There are a few reasons to use this one instead though.\n * 1. It gets cleared via {@link Component#clearInterval} when\n * {@link Component#dispose} gets called.\n * 2. The function callback will be a {@link Component~GenericCallback}\n *\n * @param {Component~GenericCallback} fn\n * The function to run every `x` seconds.\n *\n * @param {number} interval\n * Execute the specified function every `x` milliseconds.\n *\n * @return {number}\n * Returns an id that can be used to identify the interval. It can also be be used in\n * {@link Component#clearInterval} to clear the interval.\n *\n * @listens Component#dispose\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}\n */\n setInterval(fn, interval) {\n fn = bind_(this, fn);\n this.clearTimersOnDispose_();\n const intervalId = window.setInterval(fn, interval);\n this.setIntervalIds_.add(intervalId);\n return intervalId;\n }\n\n /**\n * Clears an interval that gets created via `window.setInterval` or\n * {@link Component#setInterval}. If you set an interval via {@link Component#setInterval}\n * use this function instead of `window.clearInterval`. If you don't your dispose\n * listener will not get cleaned up until {@link Component#dispose}!\n *\n * @param {number} intervalId\n * The id of the interval to clear. The return value of\n * {@link Component#setInterval} or `window.setInterval`.\n *\n * @return {number}\n * Returns the interval id that was cleared.\n *\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}\n */\n clearInterval(intervalId) {\n if (this.setIntervalIds_.has(intervalId)) {\n this.setIntervalIds_.delete(intervalId);\n window.clearInterval(intervalId);\n }\n return intervalId;\n }\n\n /**\n * Queues up a callback to be passed to requestAnimationFrame (rAF), but\n * with a few extra bonuses:\n *\n * - Supports browsers that do not support rAF by falling back to\n * {@link Component#setTimeout}.\n *\n * - The callback is turned into a {@link Component~GenericCallback} (i.e.\n * bound to the component).\n *\n * - Automatic cancellation of the rAF callback is handled if the component\n * is disposed before it is called.\n *\n * @param {Component~GenericCallback} fn\n * A function that will be bound to this component and executed just\n * before the browser's next repaint.\n *\n * @return {number}\n * Returns an rAF ID that gets used to identify the timeout. It can\n * also be used in {@link Component#cancelAnimationFrame} to cancel\n * the animation frame callback.\n *\n * @listens Component#dispose\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame}\n */\n requestAnimationFrame(fn) {\n this.clearTimersOnDispose_();\n\n // declare as variables so they are properly available in rAF function\n // eslint-disable-next-line\n var id;\n fn = bind_(this, fn);\n id = window.requestAnimationFrame(() => {\n if (this.rafIds_.has(id)) {\n this.rafIds_.delete(id);\n }\n fn();\n });\n this.rafIds_.add(id);\n return id;\n }\n\n /**\n * Request an animation frame, but only one named animation\n * frame will be queued. Another will never be added until\n * the previous one finishes.\n *\n * @param {string} name\n * The name to give this requestAnimationFrame\n *\n * @param {Component~GenericCallback} fn\n * A function that will be bound to this component and executed just\n * before the browser's next repaint.\n */\n requestNamedAnimationFrame(name, fn) {\n if (this.namedRafs_.has(name)) {\n return;\n }\n this.clearTimersOnDispose_();\n fn = bind_(this, fn);\n const id = this.requestAnimationFrame(() => {\n fn();\n if (this.namedRafs_.has(name)) {\n this.namedRafs_.delete(name);\n }\n });\n this.namedRafs_.set(name, id);\n return name;\n }\n\n /**\n * Cancels a current named animation frame if it exists.\n *\n * @param {string} name\n * The name of the requestAnimationFrame to cancel.\n */\n cancelNamedAnimationFrame(name) {\n if (!this.namedRafs_.has(name)) {\n return;\n }\n this.cancelAnimationFrame(this.namedRafs_.get(name));\n this.namedRafs_.delete(name);\n }\n\n /**\n * Cancels a queued callback passed to {@link Component#requestAnimationFrame}\n * (rAF).\n *\n * If you queue an rAF callback via {@link Component#requestAnimationFrame},\n * use this function instead of `window.cancelAnimationFrame`. If you don't,\n * your dispose listener will not get cleaned up until {@link Component#dispose}!\n *\n * @param {number} id\n * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}.\n *\n * @return {number}\n * Returns the rAF ID that was cleared.\n *\n * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame}\n */\n cancelAnimationFrame(id) {\n if (this.rafIds_.has(id)) {\n this.rafIds_.delete(id);\n window.cancelAnimationFrame(id);\n }\n return id;\n }\n\n /**\n * A function to setup `requestAnimationFrame`, `setTimeout`,\n * and `setInterval`, clearing on dispose.\n *\n * > Previously each timer added and removed dispose listeners on it's own.\n * For better performance it was decided to batch them all, and use `Set`s\n * to track outstanding timer ids.\n *\n * @private\n */\n clearTimersOnDispose_() {\n if (this.clearingTimersOnDispose_) {\n return;\n }\n this.clearingTimersOnDispose_ = true;\n this.one('dispose', () => {\n [['namedRafs_', 'cancelNamedAnimationFrame'], ['rafIds_', 'cancelAnimationFrame'], ['setTimeoutIds_', 'clearTimeout'], ['setIntervalIds_', 'clearInterval']].forEach(([idName, cancelName]) => {\n // for a `Set` key will actually be the value again\n // so forEach((val, val) =>` but for maps we want to use\n // the key.\n this[idName].forEach((val, key) => this[cancelName](key));\n });\n this.clearingTimersOnDispose_ = false;\n });\n }\n\n /**\n * Register a `Component` with `videojs` given the name and the component.\n *\n * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s\n * should be registered using {@link Tech.registerTech} or\n * {@link videojs:videojs.registerTech}.\n *\n * > NOTE: This function can also be seen on videojs as\n * {@link videojs:videojs.registerComponent}.\n *\n * @param {string} name\n * The name of the `Component` to register.\n *\n * @param {Component} ComponentToRegister\n * The `Component` class to register.\n *\n * @return {Component}\n * The `Component` that was registered.\n */\n static registerComponent(name, ComponentToRegister) {\n if (typeof name !== 'string' || !name) {\n throw new Error(`Illegal component name, \"${name}\"; must be a non-empty string.`);\n }\n const Tech = Component$1.getComponent('Tech');\n\n // We need to make sure this check is only done if Tech has been registered.\n const isTech = Tech && Tech.isTech(ComponentToRegister);\n const isComp = Component$1 === ComponentToRegister || Component$1.prototype.isPrototypeOf(ComponentToRegister.prototype);\n if (isTech || !isComp) {\n let reason;\n if (isTech) {\n reason = 'techs must be registered using Tech.registerTech()';\n } else {\n reason = 'must be a Component subclass';\n }\n throw new Error(`Illegal component, \"${name}\"; ${reason}.`);\n }\n name = toTitleCase$1(name);\n if (!Component$1.components_) {\n Component$1.components_ = {};\n }\n const Player = Component$1.getComponent('Player');\n if (name === 'Player' && Player && Player.players) {\n const players = Player.players;\n const playerNames = Object.keys(players);\n\n // If we have players that were disposed, then their name will still be\n // in Players.players. So, we must loop through and verify that the value\n // for each item is not null. This allows registration of the Player component\n // after all players have been disposed or before any were created.\n if (players && playerNames.length > 0 && playerNames.map(pname => players[pname]).every(Boolean)) {\n throw new Error('Can not register Player component after player has been created.');\n }\n }\n Component$1.components_[name] = ComponentToRegister;\n Component$1.components_[toLowerCase(name)] = ComponentToRegister;\n return ComponentToRegister;\n }\n\n /**\n * Get a `Component` based on the name it was registered with.\n *\n * @param {string} name\n * The Name of the component to get.\n *\n * @return {Component}\n * The `Component` that got registered under the given name.\n */\n static getComponent(name) {\n if (!name || !Component$1.components_) {\n return;\n }\n return Component$1.components_[name];\n }\n }\n Component$1.registerComponent('Component', Component$1);\n\n /**\n * @file time.js\n * @module time\n */\n\n /**\n * Returns the time for the specified index at the start or end\n * of a TimeRange object.\n *\n * @typedef {Function} TimeRangeIndex\n *\n * @param {number} [index=0]\n * The range number to return the time for.\n *\n * @return {number}\n * The time offset at the specified index.\n *\n * @deprecated The index argument must be provided.\n * In the future, leaving it out will throw an error.\n */\n\n /**\n * An object that contains ranges of time, which mimics {@link TimeRanges}.\n *\n * @typedef {Object} TimeRange\n *\n * @property {number} length\n * The number of time ranges represented by this object.\n *\n * @property {module:time~TimeRangeIndex} start\n * Returns the time offset at which a specified time range begins.\n *\n * @property {module:time~TimeRangeIndex} end\n * Returns the time offset at which a specified time range ends.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges\n */\n\n /**\n * Check if any of the time ranges are over the maximum index.\n *\n * @private\n * @param {string} fnName\n * The function name to use for logging\n *\n * @param {number} index\n * The index to check\n *\n * @param {number} maxIndex\n * The maximum possible index\n *\n * @throws {Error} if the timeRanges provided are over the maxIndex\n */\n function rangeCheck(fnName, index, maxIndex) {\n if (typeof index !== 'number' || index < 0 || index > maxIndex) {\n throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is non-numeric or out of bounds (0-${maxIndex}).`);\n }\n }\n\n /**\n * Get the time for the specified index at the start or end\n * of a TimeRange object.\n *\n * @private\n * @param {string} fnName\n * The function name to use for logging\n *\n * @param {string} valueIndex\n * The property that should be used to get the time. should be\n * 'start' or 'end'\n *\n * @param {Array} ranges\n * An array of time ranges\n *\n * @param {Array} [rangeIndex=0]\n * The index to start the search at\n *\n * @return {number}\n * The time that offset at the specified index.\n *\n * @deprecated rangeIndex must be set to a value, in the future this will throw an error.\n * @throws {Error} if rangeIndex is more than the length of ranges\n */\n function getRange(fnName, valueIndex, ranges, rangeIndex) {\n rangeCheck(fnName, rangeIndex, ranges.length - 1);\n return ranges[rangeIndex][valueIndex];\n }\n\n /**\n * Create a time range object given ranges of time.\n *\n * @private\n * @param {Array} [ranges]\n * An array of time ranges.\n *\n * @return {TimeRange}\n */\n function createTimeRangesObj(ranges) {\n let timeRangesObj;\n if (ranges === undefined || ranges.length === 0) {\n timeRangesObj = {\n length: 0,\n start() {\n throw new Error('This TimeRanges object is empty');\n },\n end() {\n throw new Error('This TimeRanges object is empty');\n }\n };\n } else {\n timeRangesObj = {\n length: ranges.length,\n start: getRange.bind(null, 'start', 0, ranges),\n end: getRange.bind(null, 'end', 1, ranges)\n };\n }\n if (window.Symbol && window.Symbol.iterator) {\n timeRangesObj[window.Symbol.iterator] = () => (ranges || []).values();\n }\n return timeRangesObj;\n }\n\n /**\n * Create a `TimeRange` object which mimics an\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}.\n *\n * @param {number|Array[]} start\n * The start of a single range (a number) or an array of ranges (an\n * array of arrays of two numbers each).\n *\n * @param {number} end\n * The end of a single range. Cannot be used with the array form of\n * the `start` argument.\n *\n * @return {TimeRange}\n */\n function createTimeRanges$1(start, end) {\n if (Array.isArray(start)) {\n return createTimeRangesObj(start);\n } else if (start === undefined || end === undefined) {\n return createTimeRangesObj();\n }\n return createTimeRangesObj([[start, end]]);\n }\n\n /**\n * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in\n * seconds) will force a number of leading zeros to cover the length of the\n * guide.\n *\n * @private\n * @param {number} seconds\n * Number of seconds to be turned into a string\n *\n * @param {number} guide\n * Number (in seconds) to model the string after\n *\n * @return {string}\n * Time formatted as H:MM:SS or M:SS\n */\n const defaultImplementation = function (seconds, guide) {\n seconds = seconds < 0 ? 0 : seconds;\n let s = Math.floor(seconds % 60);\n let m = Math.floor(seconds / 60 % 60);\n let h = Math.floor(seconds / 3600);\n const gm = Math.floor(guide / 60 % 60);\n const gh = Math.floor(guide / 3600);\n\n // handle invalid times\n if (isNaN(seconds) || seconds === Infinity) {\n // '-' is false for all relational operators (e.g. <, >=) so this setting\n // will add the minimum number of fields specified by the guide\n h = m = s = '-';\n }\n\n // Check if we need to show hours\n h = h > 0 || gh > 0 ? h + ':' : '';\n\n // If hours are showing, we may need to add a leading zero.\n // Always show at least one digit of minutes.\n m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';\n\n // Check if leading zero is need for seconds\n s = s < 10 ? '0' + s : s;\n return h + m + s;\n };\n\n // Internal pointer to the current implementation.\n let implementation = defaultImplementation;\n\n /**\n * Replaces the default formatTime implementation with a custom implementation.\n *\n * @param {Function} customImplementation\n * A function which will be used in place of the default formatTime\n * implementation. Will receive the current time in seconds and the\n * guide (in seconds) as arguments.\n */\n function setFormatTime(customImplementation) {\n implementation = customImplementation;\n }\n\n /**\n * Resets formatTime to the default implementation.\n */\n function resetFormatTime() {\n implementation = defaultImplementation;\n }\n\n /**\n * Delegates to either the default time formatting function or a custom\n * function supplied via `setFormatTime`.\n *\n * Formats seconds as a time string (H:MM:SS or M:SS). Supplying a\n * guide (in seconds) will force a number of leading zeros to cover the\n * length of the guide.\n *\n * @example formatTime(125, 600) === \"02:05\"\n * @param {number} seconds\n * Number of seconds to be turned into a string\n *\n * @param {number} guide\n * Number (in seconds) to model the string after\n *\n * @return {string}\n * Time formatted as H:MM:SS or M:SS\n */\n function formatTime(seconds, guide = seconds) {\n return implementation(seconds, guide);\n }\n\n var Time = /*#__PURE__*/Object.freeze({\n __proto__: null,\n createTimeRanges: createTimeRanges$1,\n createTimeRange: createTimeRanges$1,\n setFormatTime: setFormatTime,\n resetFormatTime: resetFormatTime,\n formatTime: formatTime\n });\n\n /**\n * @file buffer.js\n * @module buffer\n */\n\n /**\n * Compute the percentage of the media that has been buffered.\n *\n * @param { import('./time').TimeRange } buffered\n * The current `TimeRanges` object representing buffered time ranges\n *\n * @param {number} duration\n * Total duration of the media\n *\n * @return {number}\n * Percent buffered of the total duration in decimal form.\n */\n function bufferedPercent(buffered, duration) {\n let bufferedDuration = 0;\n let start;\n let end;\n if (!duration) {\n return 0;\n }\n if (!buffered || !buffered.length) {\n buffered = createTimeRanges$1(0, 0);\n }\n for (let i = 0; i < buffered.length; i++) {\n start = buffered.start(i);\n end = buffered.end(i);\n\n // buffered end can be bigger than duration by a very small fraction\n if (end > duration) {\n end = duration;\n }\n bufferedDuration += end - start;\n }\n return bufferedDuration / duration;\n }\n\n /**\n * @file media-error.js\n */\n\n /**\n * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.\n *\n * @param {number|string|Object|MediaError} value\n * This can be of multiple types:\n * - number: should be a standard error code\n * - string: an error message (the code will be 0)\n * - Object: arbitrary properties\n * - `MediaError` (native): used to populate a video.js `MediaError` object\n * - `MediaError` (video.js): will return itself if it's already a\n * video.js `MediaError` object.\n *\n * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}\n * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}\n *\n * @class MediaError\n */\n function MediaError(value) {\n // Allow redundant calls to this constructor to avoid having `instanceof`\n // checks peppered around the code.\n if (value instanceof MediaError) {\n return value;\n }\n if (typeof value === 'number') {\n this.code = value;\n } else if (typeof value === 'string') {\n // default code is zero, so this is a custom error\n this.message = value;\n } else if (isObject$1(value)) {\n // We assign the `code` property manually because native `MediaError` objects\n // do not expose it as an own/enumerable property of the object.\n if (typeof value.code === 'number') {\n this.code = value.code;\n }\n Object.assign(this, value);\n }\n if (!this.message) {\n this.message = MediaError.defaultMessages[this.code] || '';\n }\n }\n\n /**\n * The error code that refers two one of the defined `MediaError` types\n *\n * @type {Number}\n */\n MediaError.prototype.code = 0;\n\n /**\n * An optional message that to show with the error. Message is not part of the HTML5\n * video spec but allows for more informative custom errors.\n *\n * @type {String}\n */\n MediaError.prototype.message = '';\n\n /**\n * An optional status code that can be set by plugins to allow even more detail about\n * the error. For example a plugin might provide a specific HTTP status code and an\n * error message for that code. Then when the plugin gets that error this class will\n * know how to display an error message for it. This allows a custom message to show\n * up on the `Player` error overlay.\n *\n * @type {Array}\n */\n MediaError.prototype.status = null;\n\n /**\n * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the\n * specification listed under {@link MediaError} for more information.\n *\n * @enum {array}\n * @readonly\n * @property {string} 0 - MEDIA_ERR_CUSTOM\n * @property {string} 1 - MEDIA_ERR_ABORTED\n * @property {string} 2 - MEDIA_ERR_NETWORK\n * @property {string} 3 - MEDIA_ERR_DECODE\n * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED\n * @property {string} 5 - MEDIA_ERR_ENCRYPTED\n */\n MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];\n\n /**\n * The default `MediaError` messages based on the {@link MediaError.errorTypes}.\n *\n * @type {Array}\n * @constant\n */\n MediaError.defaultMessages = {\n 1: 'You aborted the media playback',\n 2: 'A network error caused the media download to fail part-way.',\n 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',\n 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',\n 5: 'The media is encrypted and we do not have the keys to decrypt it.'\n };\n\n // Add types as properties on MediaError\n // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;\n for (let errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {\n MediaError[MediaError.errorTypes[errNum]] = errNum;\n // values should be accessible on both the class and instance\n MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;\n }\n\n var tuple = SafeParseTuple;\n function SafeParseTuple(obj, reviver) {\n var json;\n var error = null;\n try {\n json = JSON.parse(obj, reviver);\n } catch (err) {\n error = err;\n }\n return [error, json];\n }\n\n /**\n * Returns whether an object is `Promise`-like (i.e. has a `then` method).\n *\n * @param {Object} value\n * An object that may or may not be `Promise`-like.\n *\n * @return {boolean}\n * Whether or not the object is `Promise`-like.\n */\n function isPromise(value) {\n return value !== undefined && value !== null && typeof value.then === 'function';\n }\n\n /**\n * Silence a Promise-like object.\n *\n * This is useful for avoiding non-harmful, but potentially confusing \"uncaught\n * play promise\" rejection error messages.\n *\n * @param {Object} value\n * An object that may or may not be `Promise`-like.\n */\n function silencePromise(value) {\n if (isPromise(value)) {\n value.then(null, e => {});\n }\n }\n\n /**\n * @file text-track-list-converter.js Utilities for capturing text track state and\n * re-creating tracks based on a capture.\n *\n * @module text-track-list-converter\n */\n\n /**\n * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that\n * represents the {@link TextTrack}'s state.\n *\n * @param {TextTrack} track\n * The text track to query.\n *\n * @return {Object}\n * A serializable javascript representation of the TextTrack.\n * @private\n */\n const trackToJson_ = function (track) {\n const ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce((acc, prop, i) => {\n if (track[prop]) {\n acc[prop] = track[prop];\n }\n return acc;\n }, {\n cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {\n return {\n startTime: cue.startTime,\n endTime: cue.endTime,\n text: cue.text,\n id: cue.id\n };\n })\n });\n return ret;\n };\n\n /**\n * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the\n * state of all {@link TextTrack}s currently configured. The return array is compatible with\n * {@link text-track-list-converter:jsonToTextTracks}.\n *\n * @param { import('../tech/tech').default } tech\n * The tech object to query\n *\n * @return {Array}\n * A serializable javascript representation of the {@link Tech}s\n * {@link TextTrackList}.\n */\n const textTracksToJson = function (tech) {\n const trackEls = tech.$$('track');\n const trackObjs = Array.prototype.map.call(trackEls, t => t.track);\n const tracks = Array.prototype.map.call(trackEls, function (trackEl) {\n const json = trackToJson_(trackEl.track);\n if (trackEl.src) {\n json.src = trackEl.src;\n }\n return json;\n });\n return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {\n return trackObjs.indexOf(track) === -1;\n }).map(trackToJson_));\n };\n\n /**\n * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript\n * object {@link TextTrack} representations.\n *\n * @param {Array} json\n * An array of `TextTrack` representation objects, like those that would be\n * produced by `textTracksToJson`.\n *\n * @param {Tech} tech\n * The `Tech` to create the `TextTrack`s on.\n */\n const jsonToTextTracks = function (json, tech) {\n json.forEach(function (track) {\n const addedTrack = tech.addRemoteTextTrack(track).track;\n if (!track.src && track.cues) {\n track.cues.forEach(cue => addedTrack.addCue(cue));\n }\n });\n return tech.textTracks();\n };\n var textTrackConverter = {\n textTracksToJson,\n jsonToTextTracks,\n trackToJson_\n };\n\n /**\n * @file modal-dialog.js\n */\n const MODAL_CLASS_NAME = 'vjs-modal-dialog';\n\n /**\n * The `ModalDialog` displays over the video and its controls, which blocks\n * interaction with the player until it is closed.\n *\n * Modal dialogs include a \"Close\" button and will close when that button\n * is activated - or when ESC is pressed anywhere.\n *\n * @extends Component\n */\n class ModalDialog extends Component$1 {\n /**\n * Create an instance of this class.\n *\n * @param { import('./player').default } player\n * The `Player` that this class should be attached to.\n *\n * @param {Object} [options]\n * The key/value store of player options.\n *\n * @param { import('./utils/dom').ContentDescriptor} [options.content=undefined]\n * Provide customized content for this modal.\n *\n * @param {string} [options.description]\n * A text description for the modal, primarily for accessibility.\n *\n * @param {boolean} [options.fillAlways=false]\n * Normally, modals are automatically filled only the first time\n * they open. This tells the modal to refresh its content\n * every time it opens.\n *\n * @param {string} [options.label]\n * A text label for the modal, primarily for accessibility.\n *\n * @param {boolean} [options.pauseOnOpen=true]\n * If `true`, playback will will be paused if playing when\n * the modal opens, and resumed when it closes.\n *\n * @param {boolean} [options.temporary=true]\n * If `true`, the modal can only be opened once; it will be\n * disposed as soon as it's closed.\n *\n * @param {boolean} [options.uncloseable=false]\n * If `true`, the user will not be able to close the modal\n * through the UI in the normal ways. Programmatic closing is\n * still possible.\n */\n constructor(player, options) {\n super(player, options);\n this.handleKeyDown_ = e => this.handleKeyDown(e);\n this.close_ = e => this.close(e);\n this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;\n this.closeable(!this.options_.uncloseable);\n this.content(this.options_.content);\n\n // Make sure the contentEl is defined AFTER any children are initialized\n // because we only want the contents of the modal in the contentEl\n // (not the UI elements like the close button).\n this.contentEl_ = createEl('div', {\n className: `${MODAL_CLASS_NAME}-content`\n }, {\n role: 'document'\n });\n this.descEl_ = createEl('p', {\n className: `${MODAL_CLASS_NAME}-description vjs-control-text`,\n id: this.el().getAttribute('aria-describedby')\n });\n textContent(this.descEl_, this.description());\n this.el_.appendChild(this.descEl_);\n this.el_.appendChild(this.contentEl_);\n }\n\n /**\n * Create the `ModalDialog`'s DOM element\n *\n * @return {Element}\n * The DOM element that gets created.\n */\n createEl() {\n return super.createEl('div', {\n className: this.buildCSSClass(),\n tabIndex: -1\n }, {\n 'aria-describedby': `${this.id()}_description`,\n 'aria-hidden': 'true',\n 'aria-label': this.label(),\n 'role': 'dialog'\n });\n }\n dispose() {\n this.contentEl_ = null;\n this.descEl_ = null;\n this.previouslyActiveEl_ = null;\n super.dispose();\n }\n\n /**\n * Builds the default DOM `className`.\n *\n * @return {string}\n * The DOM `className` for this object.\n */\n buildCSSClass() {\n return `${MODAL_CLASS_NAME} vjs-hidden ${super.buildCSSClass()}`;\n }\n\n /**\n * Returns the label string for this modal. Primarily used for accessibility.\n *\n * @return {string}\n * the localized or raw label of this modal.\n */\n label() {\n return this.localize(this.options_.label || 'Modal Window');\n }\n\n /**\n * Returns the description string for this modal. Primarily used for\n * accessibility.\n *\n * @return {string}\n * The localized or raw description of this modal.\n */\n description() {\n let desc = this.options_.description || this.localize('This is a modal window.');\n\n // Append a universal closeability message if the modal is closeable.\n if (this.closeable()) {\n desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');\n }\n return desc;\n }\n\n /**\n * Opens the modal.\n *\n * @fires ModalDialog#beforemodalopen\n * @fires ModalDialog#modalopen\n */\n open() {\n if (!this.opened_) {\n const player = this.player();\n\n /**\n * Fired just before a `ModalDialog` is opened.\n *\n * @event ModalDialog#beforemodalopen\n * @type {Event}\n */\n this.trigger('beforemodalopen');\n this.opened_ = true;\n\n // Fill content if the modal has never opened before and\n // never been filled.\n if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {\n this.fill();\n }\n\n // If the player was playing, pause it and take note of its previously\n // playing state.\n this.wasPlaying_ = !player.paused();\n if (this.options_.pauseOnOpen && this.wasPlaying_) {\n player.pause();\n }\n this.on('keydown', this.handleKeyDown_);\n\n // Hide controls and note if they were enabled.\n this.hadControls_ = player.controls();\n player.controls(false);\n this.show();\n this.conditionalFocus_();\n this.el().setAttribute('aria-hidden', 'false');\n\n /**\n * Fired just after a `ModalDialog` is opened.\n *\n * @event ModalDialog#modalopen\n * @type {Event}\n */\n this.trigger('modalopen');\n this.hasBeenOpened_ = true;\n }\n }\n\n /**\n * If the `ModalDialog` is currently open or closed.\n *\n * @param {boolean} [value]\n * If given, it will open (`true`) or close (`false`) the modal.\n *\n * @return {boolean}\n * the current open state of the modaldialog\n */\n opened(value) {\n if (typeof value === 'boolean') {\n this[value ? 'open' : 'close']();\n }\n return this.opened_;\n }\n\n /**\n * Closes the modal, does nothing if the `ModalDialog` is\n * not open.\n *\n * @fires ModalDialog#beforemodalclose\n * @fires ModalDialog#modalclose\n */\n close() {\n if (!this.opened_) {\n return;\n }\n const player = this.player();\n\n /**\n * Fired just before a `ModalDialog` is closed.\n *\n * @event ModalDialog#beforemodalclose\n * @type {Event}\n */\n this.trigger('beforemodalclose');\n this.opened_ = false;\n if (this.wasPlaying_ && this.options_.pauseOnOpen) {\n player.play();\n }\n this.off('keydown', this.handleKeyDown_);\n if (this.hadControls_) {\n player.controls(true);\n }\n this.hide();\n this.el().setAttribute('aria-hidden', 'true');\n\n /**\n * Fired just after a `ModalDialog` is closed.\n *\n * @event ModalDialog#modalclose\n * @type {Event}\n */\n this.trigger('modalclose');\n this.conditionalBlur_();\n if (this.options_.temporary) {\n this.dispose();\n }\n }\n\n /**\n * Check to see if the `ModalDialog` is closeable via the UI.\n *\n * @param {boolean} [value]\n * If given as a boolean, it will set the `closeable` option.\n *\n * @return {boolean}\n * Returns the final value of the closable option.\n */\n closeable(value) {\n if (typeof value === 'boolean') {\n const closeable = this.closeable_ = !!value;\n let close = this.getChild('closeButton');\n\n // If this is being made closeable and has no close button, add one.\n if (closeable && !close) {\n // The close button should be a child of the modal - not its\n // content element, so temporarily change the content element.\n const temp = this.contentEl_;\n this.contentEl_ = this.el_;\n close = this.addChild('closeButton', {\n controlText: 'Close Modal Dialog'\n });\n this.contentEl_ = temp;\n this.on(close, 'close', this.close_);\n }\n\n // If this is being made uncloseable and has a close button, remove it.\n if (!closeable && close) {\n this.off(close, 'close', this.close_);\n this.removeChild(close);\n close.dispose();\n }\n }\n return this.closeable_;\n }\n\n /**\n * Fill the modal's content element with the modal's \"content\" option.\n * The content element will be emptied before this change takes place.\n */\n fill() {\n this.fillWith(this.content());\n }\n\n /**\n * Fill the modal's content element with arbitrary content.\n * The content element will be emptied before this change takes place.\n *\n * @fires ModalDialog#beforemodalfill\n * @fires ModalDialog#modalfill\n *\n * @param { import('./utils/dom').ContentDescriptor} [content]\n * The same rules apply to this as apply to the `content` option.\n */\n fillWith(content) {\n const contentEl = this.contentEl();\n const parentEl = contentEl.parentNode;\n const nextSiblingEl = contentEl.nextSibling;\n\n /**\n * Fired just before a `ModalDialog` is filled with content.\n *\n * @event ModalDialog#beforemodalfill\n * @type {Event}\n */\n this.trigger('beforemodalfill');\n this.hasBeenFilled_ = true;\n\n // Detach the content element from the DOM before performing\n // manipulation to avoid modifying the live DOM multiple times.\n parentEl.removeChild(contentEl);\n this.empty();\n insertContent(contentEl, content);\n /**\n * Fired just after a `ModalDialog` is filled with content.\n *\n * @event ModalDialog#modalfill\n * @type {Event}\n */\n this.trigger('modalfill');\n\n // Re-inject the re-filled content element.\n if (nextSiblingEl) {\n parentEl.insertBefore(contentEl, nextSiblingEl);\n } else {\n parentEl.appendChild(contentEl);\n }\n\n // make sure that the close button is last in the dialog DOM\n const closeButton = this.getChild('closeButton');\n if (closeButton) {\n parentEl.appendChild(closeButton.el_);\n }\n }\n\n /**\n * Empties the content element. This happens anytime the modal is filled.\n *\n * @fires ModalDialog#beforemodalempty\n * @fires ModalDialog#modalempty\n */\n empty() {\n /**\n * Fired just before a `ModalDialog` is emptied.\n *\n * @event ModalDialog#beforemodalempty\n * @type {Event}\n */\n this.trigger('beforemodalempty');\n emptyEl(this.contentEl());\n\n /**\n * Fired just after a `ModalDialog` is emptied.\n *\n * @event ModalDialog#modalempty\n * @type {Event}\n */\n this.trigger('modalempty');\n }\n\n /**\n * Gets or sets the modal content, which gets normalized before being\n * rendered into the DOM.\n *\n * This does not update the DOM or fill the modal, but it is called during\n * that process.\n *\n * @param { import('./utils/dom').ContentDescriptor} [value]\n * If defined, sets the internal content value to be used on the\n * next call(s) to `fill`. This value is normalized before being\n * inserted. To \"clear\" the internal content value, pass `null`.\n *\n * @return { import('./utils/dom').ContentDescriptor}\n * The current content of the modal dialog\n */\n content(value) {\n if (typeof value !== 'undefined') {\n this.content_ = value;\n }\n return this.content_;\n }\n\n /**\n * conditionally focus the modal dialog if focus was previously on the player.\n *\n * @private\n */\n conditionalFocus_() {\n const activeEl = document.activeElement;\n const playerEl = this.player_.el_;\n this.previouslyActiveEl_ = null;\n if (playerEl.contains(activeEl) || playerEl === activeEl) {\n this.previouslyActiveEl_ = activeEl;\n this.focus();\n }\n }\n\n /**\n * conditionally blur the element and refocus the last focused element\n *\n * @private\n */\n conditionalBlur_() {\n if (this.previouslyActiveEl_) {\n this.previouslyActiveEl_.focus();\n this.previouslyActiveEl_ = null;\n }\n }\n\n /**\n * Keydown handler. Attached when modal is focused.\n *\n * @listens keydown\n */\n handleKeyDown(event) {\n // Do not allow keydowns to reach out of the modal dialog.\n event.stopPropagation();\n if (keycode.isEventKey(event, 'Escape') && this.closeable()) {\n event.preventDefault();\n this.close();\n return;\n }\n\n // exit early if it isn't a tab key\n if (!keycode.isEventKey(event, 'Tab')) {\n return;\n }\n const focusableEls = this.focusableEls_();\n const activeEl = this.el_.querySelector(':focus');\n let focusIndex;\n for (let i = 0; i < focusableEls.length; i++) {\n if (activeEl === focusableEls[i]) {\n focusIndex = i;\n break;\n }\n }\n if (document.activeElement === this.el_) {\n focusIndex = 0;\n }\n if (event.shiftKey && focusIndex === 0) {\n focusableEls[focusableEls.length - 1].focus();\n event.preventDefault();\n } else if (!event.shiftKey && focusIndex === focusableEls.length - 1) {\n focusableEls[0].focus();\n event.preventDefault();\n }\n }\n\n /**\n * get all focusable elements\n *\n * @private\n */\n focusableEls_() {\n const allChildren = this.el_.querySelectorAll('*');\n return Array.prototype.filter.call(allChildren, child => {\n return (child instanceof window.HTMLAnchorElement || child instanceof window.HTMLAreaElement) && child.hasAttribute('href') || (child instanceof window.HTMLInputElement || child instanceof window.HTMLSelectElement || child instanceof window.HTMLTextAreaElement || child instanceof window.HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof window.HTMLIFrameElement || child instanceof window.HTMLObjectElement || child instanceof window.HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable');\n });\n }\n }\n\n /**\n * Default options for `ModalDialog` default options.\n *\n * @type {Object}\n * @private\n */\n ModalDialog.prototype.options_ = {\n pauseOnOpen: true,\n temporary: true\n };\n Component$1.registerComponent('ModalDialog', ModalDialog);\n\n /**\n * @file track-list.js\n */\n\n /**\n * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and\n * {@link VideoTrackList}\n *\n * @extends EventTarget\n */\n class TrackList extends EventTarget$2 {\n /**\n * Create an instance of this class\n *\n * @param { import('./track').default[] } tracks\n * A list of tracks to initialize the list with.\n *\n * @abstract\n */\n constructor(tracks = []) {\n super();\n this.tracks_ = [];\n\n /**\n * @memberof TrackList\n * @member {number} length\n * The current number of `Track`s in the this Trackist.\n * @instance\n */\n Object.defineProperty(this, 'length', {\n get() {\n return this.tracks_.length;\n }\n });\n for (let i = 0; i < tracks.length; i++) {\n this.addTrack(tracks[i]);\n }\n }\n\n /**\n * Add a {@link Track} to the `TrackList`\n *\n * @param { import('./track').default } track\n * The audio, video, or text track to add to the list.\n *\n * @fires TrackList#addtrack\n */\n addTrack(track) {\n const index = this.tracks_.length;\n if (!('' + index in this)) {\n Object.defineProperty(this, index, {\n get() {\n return this.tracks_[index];\n }\n });\n }\n\n // Do not add duplicate tracks\n if (this.tracks_.indexOf(track) === -1) {\n this.tracks_.push(track);\n /**\n * Triggered when a track is added to a track list.\n *\n * @event TrackList#addtrack\n * @type {Event}\n * @property {Track} track\n * A reference to track that was added.\n */\n this.trigger({\n track,\n type: 'addtrack',\n target: this\n });\n }\n\n /**\n * Triggered when a track label is changed.\n *\n * @event TrackList#addtrack\n * @type {Event}\n * @property {Track} track\n * A reference to track that was added.\n */\n track.labelchange_ = () => {\n this.trigger({\n track,\n type: 'labelchange',\n target: this\n });\n };\n if (isEvented(track)) {\n track.addEventListener('labelchange', track.labelchange_);\n }\n }\n\n /**\n * Remove a {@link Track} from the `TrackList`\n *\n * @param { import('./track').default } rtrack\n * The audio, video, or text track to remove from the list.\n *\n * @fires TrackList#removetrack\n */\n removeTrack(rtrack) {\n let track;\n for (let i = 0, l = this.length; i < l; i++) {\n if (this[i] === rtrack) {\n track = this[i];\n if (track.off) {\n track.off();\n }\n this.tracks_.splice(i, 1);\n break;\n }\n }\n if (!track) {\n return;\n }\n\n /**\n * Triggered when a track is removed from track list.\n *\n * @event TrackList#removetrack\n * @type {Event}\n * @property {Track} track\n * A reference to track that was removed.\n */\n this.trigger({\n track,\n type: 'removetrack',\n target: this\n });\n }\n\n /**\n * Get a Track from the TrackList by a tracks id\n *\n * @param {string} id - the id of the track to get\n * @method getTrackById\n * @return { import('./track').default }\n * @private\n */\n getTrackById(id) {\n let result = null;\n for (let i = 0, l = this.length; i < l; i++) {\n const track = this[i];\n if (track.id === id) {\n result = track;\n break;\n }\n }\n return result;\n }\n }\n\n /**\n * Triggered when a different track is selected/enabled.\n *\n * @event TrackList#change\n * @type {Event}\n */\n\n /**\n * Events that can be called with on + eventName. See {@link EventHandler}.\n *\n * @property {Object} TrackList#allowedEvents_\n * @private\n */\n TrackList.prototype.allowedEvents_ = {\n change: 'change',\n addtrack: 'addtrack',\n removetrack: 'removetrack',\n labelchange: 'labelchange'\n };\n\n // emulate attribute EventHandler support to allow for feature detection\n for (const event in TrackList.prototype.allowedEvents_) {\n TrackList.prototype['on' + event] = null;\n }\n\n /**\n * @file audio-track-list.js\n */\n\n /**\n * Anywhere we call this function we diverge from the spec\n * as we only support one enabled audiotrack at a time\n *\n * @param {AudioTrackList} list\n * list to work on\n *\n * @param { import('./audio-track').default } track\n * The track to skip\n *\n * @private\n */\n const disableOthers$1 = function (list, track) {\n for (let i = 0; i < list.length; i++) {\n if (!Object.keys(list[i]).length || track.id === list[i].id) {\n continue;\n }\n // another audio track is enabled, disable it\n list[i].enabled = false;\n }\n };\n\n /**\n * The current list of {@link AudioTrack} for a media file.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}\n * @extends TrackList\n */\n class AudioTrackList extends TrackList {\n /**\n * Create an instance of this class.\n *\n * @param {AudioTrack[]} [tracks=[]]\n * A list of `AudioTrack` to instantiate the list with.\n */\n constructor(tracks = []) {\n // make sure only 1 track is enabled\n // sorted from last index to first index\n for (let i = tracks.length - 1; i >= 0; i--) {\n if (tracks[i].enabled) {\n disableOthers$1(tracks, tracks[i]);\n break;\n }\n }\n super(tracks);\n this.changing_ = false;\n }\n\n /**\n * Add an {@link AudioTrack} to the `AudioTrackList`.\n *\n * @param { import('./audio-track').default } track\n * The AudioTrack to add to the list\n *\n * @fires TrackList#addtrack\n */\n addTrack(track) {\n if (track.enabled) {\n disableOthers$1(this, track);\n }\n super.addTrack(track);\n // native tracks don't have this\n if (!track.addEventListener) {\n return;\n }\n track.enabledChange_ = () => {\n // when we are disabling other tracks (since we don't support\n // more than one track at a time) we will set changing_\n // to true so that we don't trigger additional change events\n if (this.changing_) {\n return;\n }\n this.changing_ = true;\n disableOthers$1(this, track);\n this.changing_ = false;\n this.trigger('change');\n };\n\n /**\n * @listens AudioTrack#enabledchange\n * @fires TrackList#change\n */\n track.addEventListener('enabledchange', track.enabledChange_);\n }\n removeTrack(rtrack) {\n super.removeTrack(rtrack);\n if (rtrack.removeEventListener && rtrack.enabledChange_) {\n rtrack.removeEventListener('enabledchange', rtrack.enabledChange_);\n rtrack.enabledChange_ = null;\n }\n }\n }\n\n /**\n * @file video-track-list.js\n */\n\n /**\n * Un-select all other {@link VideoTrack}s that are selected.\n *\n * @param {VideoTrackList} list\n * list to work on\n *\n * @param { import('./video-track').default } track\n * The track to skip\n *\n * @private\n */\n const disableOthers = function (list, track) {\n for (let i = 0; i < list.length; i++) {\n if (!Object.keys(list[i]).length || track.id === list[i].id) {\n continue;\n }\n // another video track is enabled, disable it\n list[i].selected = false;\n }\n };\n\n /**\n * The current list of {@link VideoTrack} for a video.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}\n * @extends TrackList\n */\n class VideoTrackList extends TrackList {\n /**\n * Create an instance of this class.\n *\n * @param {VideoTrack[]} [tracks=[]]\n * A list of `VideoTrack` to instantiate the list with.\n */\n constructor(tracks = []) {\n // make sure only 1 track is enabled\n // sorted from last index to first index\n for (let i = tracks.length - 1; i >= 0; i--) {\n if (tracks[i].selected) {\n disableOthers(tracks, tracks[i]);\n break;\n }\n }\n super(tracks);\n this.changing_ = false;\n\n /**\n * @member {number} VideoTrackList#selectedIndex\n * The current index of the selected {@link VideoTrack`}.\n */\n Object.defineProperty(this, 'selectedIndex', {\n get() {\n for (let i = 0; i < this.length; i++) {\n if (this[i].selected) {\n return i;\n }\n }\n return -1;\n },\n set() {}\n });\n }\n\n /**\n * Add a {@link VideoTrack} to the `VideoTrackList`.\n *\n * @param { import('./video-track').default } track\n * The VideoTrack to add to the list\n *\n * @fires TrackList#addtrack\n */\n addTrack(track) {\n if (track.selected) {\n disableOthers(this, track);\n }\n super.addTrack(track);\n // native tracks don't have this\n if (!track.addEventListener) {\n return;\n }\n track.selectedChange_ = () => {\n if (this.changing_) {\n return;\n }\n this.changing_ = true;\n disableOthers(this, track);\n this.changing_ = false;\n this.trigger('change');\n };\n\n /**\n * @listens VideoTrack#selectedchange\n * @fires TrackList#change\n */\n track.addEventListener('selectedchange', track.selectedChange_);\n }\n removeTrack(rtrack) {\n super.removeTrack(rtrack);\n if (rtrack.removeEventListener && rtrack.selectedChange_) {\n rtrack.removeEventListener('selectedchange', rtrack.selectedChange_);\n rtrack.selectedChange_ = null;\n }\n }\n }\n\n /**\n * @file text-track-list.js\n */\n\n /**\n * The current list of {@link TextTrack} for a media file.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}\n * @extends TrackList\n */\n class TextTrackList extends TrackList {\n /**\n * Add a {@link TextTrack} to the `TextTrackList`\n *\n * @param { import('./text-track').default } track\n * The text track to add to the list.\n *\n * @fires TrackList#addtrack\n */\n addTrack(track) {\n super.addTrack(track);\n if (!this.queueChange_) {\n this.queueChange_ = () => this.queueTrigger('change');\n }\n if (!this.triggerSelectedlanguagechange) {\n this.triggerSelectedlanguagechange_ = () => this.trigger('selectedlanguagechange');\n }\n\n /**\n * @listens TextTrack#modechange\n * @fires TrackList#change\n */\n track.addEventListener('modechange', this.queueChange_);\n const nonLanguageTextTrackKind = ['metadata', 'chapters'];\n if (nonLanguageTextTrackKind.indexOf(track.kind) === -1) {\n track.addEventListener('modechange', this.triggerSelectedlanguagechange_);\n }\n }\n removeTrack(rtrack) {\n super.removeTrack(rtrack);\n\n // manually remove the event handlers we added\n if (rtrack.removeEventListener) {\n if (this.queueChange_) {\n rtrack.removeEventListener('modechange', this.queueChange_);\n }\n if (this.selectedlanguagechange_) {\n rtrack.removeEventListener('modechange', this.triggerSelectedlanguagechange_);\n }\n }\n }\n }\n\n /**\n * @file html-track-element-list.js\n */\n\n /**\n * The current list of {@link HtmlTrackElement}s.\n */\n class HtmlTrackElementList {\n /**\n * Create an instance of this class.\n *\n * @param {HtmlTrackElement[]} [tracks=[]]\n * A list of `HtmlTrackElement` to instantiate the list with.\n */\n constructor(trackElements = []) {\n this.trackElements_ = [];\n\n /**\n * @memberof HtmlTrackElementList\n * @member {number} length\n * The current number of `Track`s in the this Trackist.\n * @instance\n */\n Object.defineProperty(this, 'length', {\n get() {\n return this.trackElements_.length;\n }\n });\n for (let i = 0, length = trackElements.length; i < length; i++) {\n this.addTrackElement_(trackElements[i]);\n }\n }\n\n /**\n * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`\n *\n * @param {HtmlTrackElement} trackElement\n * The track element to add to the list.\n *\n * @private\n */\n addTrackElement_(trackElement) {\n const index = this.trackElements_.length;\n if (!('' + index in this)) {\n Object.defineProperty(this, index, {\n get() {\n return this.trackElements_[index];\n }\n });\n }\n\n // Do not add duplicate elements\n if (this.trackElements_.indexOf(trackElement) === -1) {\n this.trackElements_.push(trackElement);\n }\n }\n\n /**\n * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an\n * {@link TextTrack}.\n *\n * @param {TextTrack} track\n * The track associated with a track element.\n *\n * @return {HtmlTrackElement|undefined}\n * The track element that was found or undefined.\n *\n * @private\n */\n getTrackElementByTrack_(track) {\n let trackElement_;\n for (let i = 0, length = this.trackElements_.length; i < length; i++) {\n if (track === this.trackElements_[i].track) {\n trackElement_ = this.trackElements_[i];\n break;\n }\n }\n return trackElement_;\n }\n\n /**\n * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`\n *\n * @param {HtmlTrackElement} trackElement\n * The track element to remove from the list.\n *\n * @private\n */\n removeTrackElement_(trackElement) {\n for (let i = 0, length = this.trackElements_.length; i < length; i++) {\n if (trackElement === this.trackElements_[i]) {\n if (this.trackElements_[i].track && typeof this.trackElements_[i].track.off === 'function') {\n this.trackElements_[i].track.off();\n }\n if (typeof this.trackElements_[i].off === 'function') {\n this.trackElements_[i].off();\n }\n this.trackElements_.splice(i, 1);\n break;\n }\n }\n }\n }\n\n /**\n * @file text-track-cue-list.js\n */\n\n /**\n * @typedef {Object} TextTrackCueList~TextTrackCue\n *\n * @property {string} id\n * The unique id for this text track cue\n *\n * @property {number} startTime\n * The start time for this text track cue\n *\n * @property {number} endTime\n * The end time for this text track cue\n *\n * @property {boolean} pauseOnExit\n * Pause when the end time is reached if true.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}\n */\n\n /**\n * A List of TextTrackCues.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}\n */\n class TextTrackCueList {\n /**\n * Create an instance of this class..\n *\n * @param {Array} cues\n * A list of cues to be initialized with\n */\n constructor(cues) {\n TextTrackCueList.prototype.setCues_.call(this, cues);\n\n /**\n * @memberof TextTrackCueList\n * @member {number} length\n * The current number of `TextTrackCue`s in the TextTrackCueList.\n * @instance\n */\n Object.defineProperty(this, 'length', {\n get() {\n return this.length_;\n }\n });\n }\n\n /**\n * A setter for cues in this list. Creates getters\n * an an index for the cues.\n *\n * @param {Array} cues\n * An array of cues to set\n *\n * @private\n */\n setCues_(cues) {\n const oldLength = this.length || 0;\n let i = 0;\n const l = cues.length;\n this.cues_ = cues;\n this.length_ = cues.length;\n const defineProp = function (index) {\n if (!('' + index in this)) {\n Object.defineProperty(this, '' + index, {\n get() {\n return this.cues_[index];\n }\n });\n }\n };\n if (oldLength < l) {\n i = oldLength;\n for (; i < l; i++) {\n defineProp.call(this, i);\n }\n }\n }\n\n /**\n * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.\n *\n * @param {string} id\n * The id of the cue that should be searched for.\n *\n * @return {TextTrackCueList~TextTrackCue|null}\n * A single cue or null if none was found.\n */\n getCueById(id) {\n let result = null;\n for (let i = 0, l = this.length; i < l; i++) {\n const cue = this[i];\n if (cue.id === id) {\n result = cue;\n break;\n }\n }\n return result;\n }\n }\n\n /**\n * @file track-kinds.js\n */\n\n /**\n * All possible `VideoTrackKind`s\n *\n * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind\n * @typedef VideoTrack~Kind\n * @enum\n */\n const VideoTrackKind = {\n alternative: 'alternative',\n captions: 'captions',\n main: 'main',\n sign: 'sign',\n subtitles: 'subtitles',\n commentary: 'commentary'\n };\n\n /**\n * All possible `AudioTrackKind`s\n *\n * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind\n * @typedef AudioTrack~Kind\n * @enum\n */\n const AudioTrackKind = {\n 'alternative': 'alternative',\n 'descriptions': 'descriptions',\n 'main': 'main',\n 'main-desc': 'main-desc',\n 'translation': 'translation',\n 'commentary': 'commentary'\n };\n\n /**\n * All possible `TextTrackKind`s\n *\n * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind\n * @typedef TextTrack~Kind\n * @enum\n */\n const TextTrackKind = {\n subtitles: 'subtitles',\n captions: 'captions',\n descriptions: 'descriptions',\n chapters: 'chapters',\n metadata: 'metadata'\n };\n\n /**\n * All possible `TextTrackMode`s\n *\n * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode\n * @typedef TextTrack~Mode\n * @enum\n */\n const TextTrackMode = {\n disabled: 'disabled',\n hidden: 'hidden',\n showing: 'showing'\n };\n\n /**\n * @file track.js\n */\n\n /**\n * A Track class that contains all of the common functionality for {@link AudioTrack},\n * {@link VideoTrack}, and {@link TextTrack}.\n *\n * > Note: This class should not be used directly\n *\n * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}\n * @extends EventTarget\n * @abstract\n */\n class Track extends EventTarget$2 {\n /**\n * Create an instance of this class.\n *\n * @param {Object} [options={}]\n * Object of option names and values\n *\n * @param {string} [options.kind='']\n * A valid kind for the track type you are creating.\n *\n * @param {string} [options.id='vjs_track_' + Guid.newGUID()]\n * A unique id for this AudioTrack.\n *\n * @param {string} [options.label='']\n * The menu label for this track.\n *\n * @param {string} [options.language='']\n * A valid two character language code.\n *\n * @abstract\n */\n constructor(options = {}) {\n super();\n const trackProps = {\n id: options.id || 'vjs_track_' + newGUID(),\n kind: options.kind || '',\n language: options.language || ''\n };\n let label = options.label || '';\n\n /**\n * @memberof Track\n * @member {string} id\n * The id of this track. Cannot be changed after creation.\n * @instance\n *\n * @readonly\n */\n\n /**\n * @memberof Track\n * @member {string} kind\n * The kind of track that this is. Cannot be changed after creation.\n * @instance\n *\n * @readonly\n */\n\n /**\n * @memberof Track\n * @member {string} language\n * The two letter language code for this track. Cannot be changed after\n * creation.\n * @instance\n *\n * @readonly\n */\n\n for (const key in trackProps) {\n Object.defineProperty(this, key, {\n get() {\n return trackProps[key];\n },\n set() {}\n });\n }\n\n /**\n * @memberof Track\n * @member {string} label\n * The label of this track. Cannot be changed after creation.\n * @instance\n *\n * @fires Track#labelchange\n */\n Object.defineProperty(this, 'label', {\n get() {\n return label;\n },\n set(newLabel) {\n if (newLabel !== label) {\n label = newLabel;\n\n /**\n * An event that fires when label changes on this track.\n *\n * > Note: This is not part of the spec!\n *\n * @event Track#labelchange\n * @type {Event}\n */\n this.trigger('labelchange');\n }\n }\n });\n }\n }\n\n /**\n * @file url.js\n * @module url\n */\n\n /**\n * @typedef {Object} url:URLObject\n *\n * @property {string} protocol\n * The protocol of the url that was parsed.\n *\n * @property {string} hostname\n * The hostname of the url that was parsed.\n *\n * @property {string} port\n * The port of the url that was parsed.\n *\n * @property {string} pathname\n * The pathname of the url that was parsed.\n *\n * @property {string} search\n * The search query of the url that was parsed.\n *\n * @property {string} hash\n * The hash of the url that was parsed.\n *\n * @property {string} host\n * The host of the url that was parsed.\n */\n\n /**\n * Resolve and parse the elements of a URL.\n *\n * @function\n * @param {String} url\n * The url to parse\n *\n * @return {url:URLObject}\n * An object of url details\n */\n const parseUrl = function (url) {\n // This entire method can be replace with URL once we are able to drop IE11\n\n const props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];\n\n // add the url to an anchor and let the browser parse the URL\n const a = document.createElement('a');\n a.href = url;\n\n // Copy the specific URL properties to a new object\n // This is also needed for IE because the anchor loses its\n // properties when it's removed from the dom\n const details = {};\n for (let i = 0; i < props.length; i++) {\n details[props[i]] = a[props[i]];\n }\n\n // IE adds the port to the host property unlike everyone else. If\n // a port identifier is added for standard ports, strip it.\n if (details.protocol === 'http:') {\n details.host = details.host.replace(/:80$/, '');\n }\n if (details.protocol === 'https:') {\n details.host = details.host.replace(/:443$/, '');\n }\n if (!details.protocol) {\n details.protocol = window.location.protocol;\n }\n\n /* istanbul ignore if */\n if (!details.host) {\n details.host = window.location.host;\n }\n return details;\n };\n\n /**\n * Get absolute version of relative URL.\n *\n * @function\n * @param {string} url\n * URL to make absolute\n *\n * @return {string}\n * Absolute URL\n *\n * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue\n */\n const getAbsoluteURL = function (url) {\n // Check if absolute URL\n if (!url.match(/^https?:\\/\\//)) {\n // Add the url to an anchor and let the browser parse it to convert to an absolute url\n const a = document.createElement('a');\n a.href = url;\n url = a.href;\n }\n return url;\n };\n\n /**\n * Returns the extension of the passed file name. It will return an empty string\n * if passed an invalid path.\n *\n * @function\n * @param {string} path\n * The fileName path like '/path/to/file.mp4'\n *\n * @return {string}\n * The extension in lower case or an empty string if no\n * extension could be found.\n */\n const getFileExtension = function (path) {\n if (typeof path === 'string') {\n const splitPathRe = /^(\\/?)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?)(\\.([^\\.\\/\\?]+)))(?:[\\/]*|[\\?].*)$/;\n const pathParts = splitPathRe.exec(path);\n if (pathParts) {\n return pathParts.pop().toLowerCase();\n }\n }\n return '';\n };\n\n /**\n * Returns whether the url passed is a cross domain request or not.\n *\n * @function\n * @param {string} url\n * The url to check.\n *\n * @param {Object} [winLoc]\n * the domain to check the url against, defaults to window.location\n *\n * @param {string} [winLoc.protocol]\n * The window location protocol defaults to window.location.protocol\n *\n * @param {string} [winLoc.host]\n * The window location host defaults to window.location.host\n *\n * @return {boolean}\n * Whether it is a cross domain request or not.\n */\n const isCrossOrigin = function (url, winLoc = window.location) {\n const urlInfo = parseUrl(url);\n\n // IE8 protocol relative urls will return ':' for protocol\n const srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;\n\n // Check if url is for another domain/origin\n // IE8 doesn't know location.origin, so we won't rely on it here\n const crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;\n return crossOrigin;\n };\n\n var Url = /*#__PURE__*/Object.freeze({\n __proto__: null,\n parseUrl: parseUrl,\n getAbsoluteURL: getAbsoluteURL,\n getFileExtension: getFileExtension,\n isCrossOrigin: isCrossOrigin\n });\n\n var win;\n if (typeof window !== \"undefined\") {\n win = window;\n } else if (typeof commonjsGlobal !== \"undefined\") {\n win = commonjsGlobal;\n } else if (typeof self !== \"undefined\") {\n win = self;\n } else {\n win = {};\n }\n var window_1 = win;\n\n var _extends_1 = createCommonjsModule(function (module) {\n function _extends() {\n module.exports = _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n return _extends.apply(this, arguments);\n }\n module.exports = _extends, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n });\n var _extends$1 = unwrapExports(_extends_1);\n\n var isFunction_1 = isFunction;\n var toString = Object.prototype.toString;\n function isFunction(fn) {\n if (!fn) {\n return false;\n }\n var string = toString.call(fn);\n return string === '[object Function]' || typeof fn === 'function' && string !== '[object RegExp]' || typeof window !== 'undefined' && (\n // IE8 and below\n fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt);\n }\n\n var httpResponseHandler = function httpResponseHandler(callback, decodeResponseBody) {\n if (decodeResponseBody === void 0) {\n decodeResponseBody = false;\n }\n return function (err, response, responseBody) {\n // if the XHR failed, return that error\n if (err) {\n callback(err);\n return;\n } // if the HTTP status code is 4xx or 5xx, the request also failed\n\n if (response.statusCode >= 400 && response.statusCode <= 599) {\n var cause = responseBody;\n if (decodeResponseBody) {\n if (window_1.TextDecoder) {\n var charset = getCharset(response.headers && response.headers['content-type']);\n try {\n cause = new TextDecoder(charset).decode(responseBody);\n } catch (e) {}\n } else {\n cause = String.fromCharCode.apply(null, new Uint8Array(responseBody));\n }\n }\n callback({\n cause: cause\n });\n return;\n } // otherwise, request succeeded\n\n callback(null, responseBody);\n };\n };\n function getCharset(contentTypeHeader) {\n if (contentTypeHeader === void 0) {\n contentTypeHeader = '';\n }\n return contentTypeHeader.toLowerCase().split(';').reduce(function (charset, contentType) {\n var _contentType$split = contentType.split('='),\n type = _contentType$split[0],\n value = _contentType$split[1];\n if (type.trim() === 'charset') {\n return value.trim();\n }\n return charset;\n }, 'utf-8');\n }\n var httpHandler = httpResponseHandler;\n\n createXHR.httpHandler = httpHandler;\n /**\n * @license\n * slighly modified parse-headers 2.0.2 \n * Copyright (c) 2014 David Björklund\n * Available under the MIT license\n * \n */\n\n var parseHeaders = function parseHeaders(headers) {\n var result = {};\n if (!headers) {\n return result;\n }\n headers.trim().split('\\n').forEach(function (row) {\n var index = row.indexOf(':');\n var key = row.slice(0, index).trim().toLowerCase();\n var value = row.slice(index + 1).trim();\n if (typeof result[key] === 'undefined') {\n result[key] = value;\n } else if (Array.isArray(result[key])) {\n result[key].push(value);\n } else {\n result[key] = [result[key], value];\n }\n });\n return result;\n };\n var lib = createXHR; // Allow use of default import syntax in TypeScript\n\n var default_1 = createXHR;\n createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop$1;\n createXHR.XDomainRequest = \"withCredentials\" in new createXHR.XMLHttpRequest() ? createXHR.XMLHttpRequest : window_1.XDomainRequest;\n forEachArray([\"get\", \"put\", \"post\", \"patch\", \"head\", \"delete\"], function (method) {\n createXHR[method === \"delete\" ? \"del\" : method] = function (uri, options, callback) {\n options = initParams(uri, options, callback);\n options.method = method.toUpperCase();\n return _createXHR(options);\n };\n });\n function forEachArray(array, iterator) {\n for (var i = 0; i < array.length; i++) {\n iterator(array[i]);\n }\n }\n function isEmpty(obj) {\n for (var i in obj) {\n if (obj.hasOwnProperty(i)) return false;\n }\n return true;\n }\n function initParams(uri, options, callback) {\n var params = uri;\n if (isFunction_1(options)) {\n callback = options;\n if (typeof uri === \"string\") {\n params = {\n uri: uri\n };\n }\n } else {\n params = _extends_1({}, options, {\n uri: uri\n });\n }\n params.callback = callback;\n return params;\n }\n function createXHR(uri, options, callback) {\n options = initParams(uri, options, callback);\n return _createXHR(options);\n }\n function _createXHR(options) {\n if (typeof options.callback === \"undefined\") {\n throw new Error(\"callback argument missing\");\n }\n var called = false;\n var callback = function cbOnce(err, response, body) {\n if (!called) {\n called = true;\n options.callback(err, response, body);\n }\n };\n function readystatechange() {\n if (xhr.readyState === 4) {\n setTimeout(loadFunc, 0);\n }\n }\n function getBody() {\n // Chrome with requestType=blob throws errors arround when even testing access to responseText\n var body = undefined;\n if (xhr.response) {\n body = xhr.response;\n } else {\n body = xhr.responseText || getXml(xhr);\n }\n if (isJson) {\n try {\n body = JSON.parse(body);\n } catch (e) {}\n }\n return body;\n }\n function errorFunc(evt) {\n clearTimeout(timeoutTimer);\n if (!(evt instanceof Error)) {\n evt = new Error(\"\" + (evt || \"Unknown XMLHttpRequest Error\"));\n }\n evt.statusCode = 0;\n return callback(evt, failureResponse);\n } // will load the data & process the response in a special response object\n\n function loadFunc() {\n if (aborted) return;\n var status;\n clearTimeout(timeoutTimer);\n if (options.useXDR && xhr.status === undefined) {\n //IE8 CORS GET successful response doesn't have a status field, but body is fine\n status = 200;\n } else {\n status = xhr.status === 1223 ? 204 : xhr.status;\n }\n var response = failureResponse;\n var err = null;\n if (status !== 0) {\n response = {\n body: getBody(),\n statusCode: status,\n method: method,\n headers: {},\n url: uri,\n rawRequest: xhr\n };\n if (xhr.getAllResponseHeaders) {\n //remember xhr can in fact be XDR for CORS in IE\n response.headers = parseHeaders(xhr.getAllResponseHeaders());\n }\n } else {\n err = new Error(\"Internal XMLHttpRequest Error\");\n }\n return callback(err, response, response.body);\n }\n var xhr = options.xhr || null;\n if (!xhr) {\n if (options.cors || options.useXDR) {\n xhr = new createXHR.XDomainRequest();\n } else {\n xhr = new createXHR.XMLHttpRequest();\n }\n }\n var key;\n var aborted;\n var uri = xhr.url = options.uri || options.url;\n var method = xhr.method = options.method || \"GET\";\n var body = options.body || options.data;\n var headers = xhr.headers = options.headers || {};\n var sync = !!options.sync;\n var isJson = false;\n var timeoutTimer;\n var failureResponse = {\n body: undefined,\n headers: {},\n statusCode: 0,\n method: method,\n url: uri,\n rawRequest: xhr\n };\n if (\"json\" in options && options.json !== false) {\n isJson = true;\n headers[\"accept\"] || headers[\"Accept\"] || (headers[\"Accept\"] = \"application/json\"); //Don't override existing accept header declared by user\n\n if (method !== \"GET\" && method !== \"HEAD\") {\n headers[\"content-type\"] || headers[\"Content-Type\"] || (headers[\"Content-Type\"] = \"application/json\"); //Don't override existing accept header declared by user\n\n body = JSON.stringify(options.json === true ? body : options.json);\n }\n }\n xhr.onreadystatechange = readystatechange;\n xhr.onload = loadFunc;\n xhr.onerror = errorFunc; // IE9 must have onprogress be set to a unique function.\n\n xhr.onprogress = function () {// IE must die\n };\n xhr.onabort = function () {\n aborted = true;\n };\n xhr.ontimeout = errorFunc;\n xhr.open(method, uri, !sync, options.username, options.password); //has to be after open\n\n if (!sync) {\n xhr.withCredentials = !!options.withCredentials;\n } // Cannot set timeout with sync request\n // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly\n // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent\n\n if (!sync && options.timeout > 0) {\n timeoutTimer = setTimeout(function () {\n if (aborted) return;\n aborted = true; //IE9 may still call readystatechange\n\n xhr.abort(\"timeout\");\n var e = new Error(\"XMLHttpRequest timeout\");\n e.code = \"ETIMEDOUT\";\n errorFunc(e);\n }, options.timeout);\n }\n if (xhr.setRequestHeader) {\n for (key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n } else if (options.headers && !isEmpty(options.headers)) {\n throw new Error(\"Headers cannot be set on an XDomainRequest object\");\n }\n if (\"responseType\" in options) {\n xhr.responseType = options.responseType;\n }\n if (\"beforeSend\" in options && typeof options.beforeSend === \"function\") {\n options.beforeSend(xhr);\n } // Microsoft Edge browser sends \"undefined\" when send is called with undefined value.\n // XMLHttpRequest spec says to pass null as body to indicate no body\n // See https://github.com/naugtur/xhr/issues/100.\n\n xhr.send(body || null);\n return xhr;\n }\n function getXml(xhr) {\n // xhr.responseXML will throw Exception \"InvalidStateError\" or \"DOMException\"\n // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML.\n try {\n if (xhr.responseType === \"document\") {\n return xhr.responseXML;\n }\n var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === \"parsererror\";\n if (xhr.responseType === \"\" && !firefoxBugTakenEffect) {\n return xhr.responseXML;\n }\n } catch (e) {}\n return null;\n }\n function noop$1() {}\n lib.default = default_1;\n\n /**\n * @file text-track.js\n */\n\n /**\n * Takes a webvtt file contents and parses it into cues\n *\n * @param {string} srcContent\n * webVTT file contents\n *\n * @param {TextTrack} track\n * TextTrack to add cues to. Cues come from the srcContent.\n *\n * @private\n */\n const parseCues = function (srcContent, track) {\n const parser = new window.WebVTT.Parser(window, window.vttjs, window.WebVTT.StringDecoder());\n const errors = [];\n parser.oncue = function (cue) {\n track.addCue(cue);\n };\n parser.onparsingerror = function (error) {\n errors.push(error);\n };\n parser.onflush = function () {\n track.trigger({\n type: 'loadeddata',\n target: track\n });\n };\n parser.parse(srcContent);\n if (errors.length > 0) {\n if (window.console && window.console.groupCollapsed) {\n window.console.groupCollapsed(`Text Track parsing errors for ${track.src}`);\n }\n errors.forEach(error => log$1.error(error));\n if (window.console && window.console.groupEnd) {\n window.console.groupEnd();\n }\n }\n parser.flush();\n };\n\n /**\n * Load a `TextTrack` from a specified url.\n *\n * @param {string} src\n * Url to load track from.\n *\n * @param {TextTrack} track\n * Track to add cues to. Comes from the content at the end of `url`.\n *\n * @private\n */\n const loadTrack = function (src, track) {\n const opts = {\n uri: src\n };\n const crossOrigin = isCrossOrigin(src);\n if (crossOrigin) {\n opts.cors = crossOrigin;\n }\n const withCredentials = track.tech_.crossOrigin() === 'use-credentials';\n if (withCredentials) {\n opts.withCredentials = withCredentials;\n }\n lib(opts, bind_(this, function (err, response, responseBody) {\n if (err) {\n return log$1.error(err, response);\n }\n track.loaded_ = true;\n\n // Make sure that vttjs has loaded, otherwise, wait till it finished loading\n // NOTE: this is only used for the alt/video.novtt.js build\n if (typeof window.WebVTT !== 'function') {\n if (track.tech_) {\n // to prevent use before define eslint error, we define loadHandler\n // as a let here\n track.tech_.any(['vttjsloaded', 'vttjserror'], event => {\n if (event.type === 'vttjserror') {\n log$1.error(`vttjs failed to load, stopping trying to process ${track.src}`);\n return;\n }\n return parseCues(responseBody, track);\n });\n }\n } else {\n parseCues(responseBody, track);\n }\n }));\n };\n\n /**\n * A representation of a single `TextTrack`.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}\n * @extends Track\n */\n class TextTrack extends Track {\n /**\n * Create an instance of this class.\n *\n * @param {Object} options={}\n * Object of option names and values\n *\n * @param { import('../tech/tech').default } options.tech\n * A reference to the tech that owns this TextTrack.\n *\n * @param {TextTrack~Kind} [options.kind='subtitles']\n * A valid text track kind.\n *\n * @param {TextTrack~Mode} [options.mode='disabled']\n * A valid text track mode.\n *\n * @param {string} [options.id='vjs_track_' + Guid.newGUID()]\n * A unique id for this TextTrack.\n *\n * @param {string} [options.label='']\n * The menu label for this track.\n *\n * @param {string} [options.language='']\n * A valid two character language code.\n *\n * @param {string} [options.srclang='']\n * A valid two character language code. An alternative, but deprioritized\n * version of `options.language`\n *\n * @param {string} [options.src]\n * A url to TextTrack cues.\n *\n * @param {boolean} [options.default]\n * If this track should default to on or off.\n */\n constructor(options = {}) {\n if (!options.tech) {\n throw new Error('A tech was not provided.');\n }\n const settings = merge$2(options, {\n kind: TextTrackKind[options.kind] || 'subtitles',\n language: options.language || options.srclang || ''\n });\n let mode = TextTrackMode[settings.mode] || 'disabled';\n const default_ = settings.default;\n if (settings.kind === 'metadata' || settings.kind === 'chapters') {\n mode = 'hidden';\n }\n super(settings);\n this.tech_ = settings.tech;\n this.cues_ = [];\n this.activeCues_ = [];\n this.preload_ = this.tech_.preloadTextTracks !== false;\n const cues = new TextTrackCueList(this.cues_);\n const activeCues = new TextTrackCueList(this.activeCues_);\n let changed = false;\n this.timeupdateHandler = bind_(this, function (event = {}) {\n if (this.tech_.isDisposed()) {\n return;\n }\n if (!this.tech_.isReady_) {\n if (event.type !== 'timeupdate') {\n this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler);\n }\n return;\n }\n\n // Accessing this.activeCues for the side-effects of updating itself\n // due to its nature as a getter function. Do not remove or cues will\n // stop updating!\n // Use the setter to prevent deletion from uglify (pure_getters rule)\n this.activeCues = this.activeCues;\n if (changed) {\n this.trigger('cuechange');\n changed = false;\n }\n if (event.type !== 'timeupdate') {\n this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler);\n }\n });\n const disposeHandler = () => {\n this.stopTracking();\n };\n this.tech_.one('dispose', disposeHandler);\n if (mode !== 'disabled') {\n this.startTracking();\n }\n Object.defineProperties(this, {\n /**\n * @memberof TextTrack\n * @member {boolean} default\n * If this track was set to be on or off by default. Cannot be changed after\n * creation.\n * @instance\n *\n * @readonly\n */\n default: {\n get() {\n return default_;\n },\n set() {}\n },\n /**\n * @memberof TextTrack\n * @member {string} mode\n * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will\n * not be set if setting to an invalid mode.\n * @instance\n *\n * @fires TextTrack#modechange\n */\n mode: {\n get() {\n return mode;\n },\n set(newMode) {\n if (!TextTrackMode[newMode]) {\n return;\n }\n if (mode === newMode) {\n return;\n }\n mode = newMode;\n if (!this.preload_ && mode !== 'disabled' && this.cues.length === 0) {\n // On-demand load.\n loadTrack(this.src, this);\n }\n this.stopTracking();\n if (mode !== 'disabled') {\n this.startTracking();\n }\n /**\n * An event that fires when mode changes on this track. This allows\n * the TextTrackList that holds this track to act accordingly.\n *\n * > Note: This is not part of the spec!\n *\n * @event TextTrack#modechange\n * @type {Event}\n */\n this.trigger('modechange');\n }\n },\n /**\n * @memberof TextTrack\n * @member {TextTrackCueList} cues\n * The text track cue list for this TextTrack.\n * @instance\n */\n cues: {\n get() {\n if (!this.loaded_) {\n return null;\n }\n return cues;\n },\n set() {}\n },\n /**\n * @memberof TextTrack\n * @member {TextTrackCueList} activeCues\n * The list text track cues that are currently active for this TextTrack.\n * @instance\n */\n activeCues: {\n get() {\n if (!this.loaded_) {\n return null;\n }\n\n // nothing to do\n if (this.cues.length === 0) {\n return activeCues;\n }\n const ct = this.tech_.currentTime();\n const active = [];\n for (let i = 0, l = this.cues.length; i < l; i++) {\n const cue = this.cues[i];\n if (cue.startTime <= ct && cue.endTime >= ct) {\n active.push(cue);\n }\n }\n changed = false;\n if (active.length !== this.activeCues_.length) {\n changed = true;\n } else {\n for (let i = 0; i < active.length; i++) {\n if (this.activeCues_.indexOf(active[i]) === -1) {\n changed = true;\n }\n }\n }\n this.activeCues_ = active;\n activeCues.setCues_(this.activeCues_);\n return activeCues;\n },\n // /!\\ Keep this setter empty (see the timeupdate handler above)\n set() {}\n }\n });\n if (settings.src) {\n this.src = settings.src;\n if (!this.preload_) {\n // Tracks will load on-demand.\n // Act like we're loaded for other purposes.\n this.loaded_ = true;\n }\n if (this.preload_ || settings.kind !== 'subtitles' && settings.kind !== 'captions') {\n loadTrack(this.src, this);\n }\n } else {\n this.loaded_ = true;\n }\n }\n startTracking() {\n // More precise cues based on requestVideoFrameCallback with a requestAnimationFram fallback\n this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler);\n // Also listen to timeupdate in case rVFC/rAF stops (window in background, audio in video el)\n this.tech_.on('timeupdate', this.timeupdateHandler);\n }\n stopTracking() {\n if (this.rvf_) {\n this.tech_.cancelVideoFrameCallback(this.rvf_);\n this.rvf_ = undefined;\n }\n this.tech_.off('timeupdate', this.timeupdateHandler);\n }\n\n /**\n * Add a cue to the internal list of cues.\n *\n * @param {TextTrack~Cue} cue\n * The cue to add to our internal list\n */\n addCue(originalCue) {\n let cue = originalCue;\n if (window.vttjs && !(originalCue instanceof window.vttjs.VTTCue)) {\n cue = new window.vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);\n for (const prop in originalCue) {\n if (!(prop in cue)) {\n cue[prop] = originalCue[prop];\n }\n }\n\n // make sure that `id` is copied over\n cue.id = originalCue.id;\n cue.originalCue_ = originalCue;\n }\n const tracks = this.tech_.textTracks();\n for (let i = 0; i < tracks.length; i++) {\n if (tracks[i] !== this) {\n tracks[i].removeCue(cue);\n }\n }\n this.cues_.push(cue);\n this.cues.setCues_(this.cues_);\n }\n\n /**\n * Remove a cue from our internal list\n *\n * @param {TextTrack~Cue} removeCue\n * The cue to remove from our internal list\n */\n removeCue(removeCue) {\n let i = this.cues_.length;\n while (i--) {\n const cue = this.cues_[i];\n if (cue === removeCue || cue.originalCue_ && cue.originalCue_ === removeCue) {\n this.cues_.splice(i, 1);\n this.cues.setCues_(this.cues_);\n break;\n }\n }\n }\n }\n\n /**\n * cuechange - One or more cues in the track have become active or stopped being active.\n */\n TextTrack.prototype.allowedEvents_ = {\n cuechange: 'cuechange'\n };\n\n /**\n * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}\n * only one `AudioTrack` in the list will be enabled at a time.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}\n * @extends Track\n */\n class AudioTrack extends Track {\n /**\n * Create an instance of this class.\n *\n * @param {Object} [options={}]\n * Object of option names and values\n *\n * @param {AudioTrack~Kind} [options.kind='']\n * A valid audio track kind\n *\n * @param {string} [options.id='vjs_track_' + Guid.newGUID()]\n * A unique id for this AudioTrack.\n *\n * @param {string} [options.label='']\n * The menu label for this track.\n *\n * @param {string} [options.language='']\n * A valid two character language code.\n *\n * @param {boolean} [options.enabled]\n * If this track is the one that is currently playing. If this track is part of\n * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.\n */\n constructor(options = {}) {\n const settings = merge$2(options, {\n kind: AudioTrackKind[options.kind] || ''\n });\n super(settings);\n let enabled = false;\n\n /**\n * @memberof AudioTrack\n * @member {boolean} enabled\n * If this `AudioTrack` is enabled or not. When setting this will\n * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.\n * @instance\n *\n * @fires VideoTrack#selectedchange\n */\n Object.defineProperty(this, 'enabled', {\n get() {\n return enabled;\n },\n set(newEnabled) {\n // an invalid or unchanged value\n if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {\n return;\n }\n enabled = newEnabled;\n\n /**\n * An event that fires when enabled changes on this track. This allows\n * the AudioTrackList that holds this track to act accordingly.\n *\n * > Note: This is not part of the spec! Native tracks will do\n * this internally without an event.\n *\n * @event AudioTrack#enabledchange\n * @type {Event}\n */\n this.trigger('enabledchange');\n }\n });\n\n // if the user sets this track to selected then\n // set selected to that true value otherwise\n // we keep it false\n if (settings.enabled) {\n this.enabled = settings.enabled;\n }\n this.loaded_ = true;\n }\n }\n\n /**\n * A representation of a single `VideoTrack`.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}\n * @extends Track\n */\n class VideoTrack extends Track {\n /**\n * Create an instance of this class.\n *\n * @param {Object} [options={}]\n * Object of option names and values\n *\n * @param {string} [options.kind='']\n * A valid {@link VideoTrack~Kind}\n *\n * @param {string} [options.id='vjs_track_' + Guid.newGUID()]\n * A unique id for this AudioTrack.\n *\n * @param {string} [options.label='']\n * The menu label for this track.\n *\n * @param {string} [options.language='']\n * A valid two character language code.\n *\n * @param {boolean} [options.selected]\n * If this track is the one that is currently playing.\n */\n constructor(options = {}) {\n const settings = merge$2(options, {\n kind: VideoTrackKind[options.kind] || ''\n });\n super(settings);\n let selected = false;\n\n /**\n * @memberof VideoTrack\n * @member {boolean} selected\n * If this `VideoTrack` is selected or not. When setting this will\n * fire {@link VideoTrack#selectedchange} if the state of selected changed.\n * @instance\n *\n * @fires VideoTrack#selectedchange\n */\n Object.defineProperty(this, 'selected', {\n get() {\n return selected;\n },\n set(newSelected) {\n // an invalid or unchanged value\n if (typeof newSelected !== 'boolean' || newSelected === selected) {\n return;\n }\n selected = newSelected;\n\n /**\n * An event that fires when selected changes on this track. This allows\n * the VideoTrackList that holds this track to act accordingly.\n *\n * > Note: This is not part of the spec! Native tracks will do\n * this internally without an event.\n *\n * @event VideoTrack#selectedchange\n * @type {Event}\n */\n this.trigger('selectedchange');\n }\n });\n\n // if the user sets this track to selected then\n // set selected to that true value otherwise\n // we keep it false\n if (settings.selected) {\n this.selected = settings.selected;\n }\n }\n }\n\n /**\n * @file html-track-element.js\n */\n\n /**\n * A single track represented in the DOM.\n *\n * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}\n * @extends EventTarget\n */\n class HTMLTrackElement extends EventTarget$2 {\n /**\n * Create an instance of this class.\n *\n * @param {Object} options={}\n * Object of option names and values\n *\n * @param { import('../tech/tech').default } options.tech\n * A reference to the tech that owns this HTMLTrackElement.\n *\n * @param {TextTrack~Kind} [options.kind='subtitles']\n * A valid text track kind.\n *\n * @param {TextTrack~Mode} [options.mode='disabled']\n * A valid text track mode.\n *\n * @param {string} [options.id='vjs_track_' + Guid.newGUID()]\n * A unique id for this TextTrack.\n *\n * @param {string} [options.label='']\n * The menu label for this track.\n *\n * @param {string} [options.language='']\n * A valid two character language code.\n *\n * @param {string} [options.srclang='']\n * A valid two character language code. An alternative, but deprioritized\n * version of `options.language`\n *\n * @param {string} [options.src]\n * A url to TextTrack cues.\n *\n * @param {boolean} [options.default]\n * If this track should default to on or off.\n */\n constructor(options = {}) {\n super();\n let readyState;\n const track = new TextTrack(options);\n this.kind = track.kind;\n this.src = track.src;\n this.srclang = track.language;\n this.label = track.label;\n this.default = track.default;\n Object.defineProperties(this, {\n /**\n * @memberof HTMLTrackElement\n * @member {HTMLTrackElement~ReadyState} readyState\n * The current ready state of the track element.\n * @instance\n */\n readyState: {\n get() {\n return readyState;\n }\n },\n /**\n * @memberof HTMLTrackElement\n * @member {TextTrack} track\n * The underlying TextTrack object.\n * @instance\n *\n */\n track: {\n get() {\n return track;\n }\n }\n });\n readyState = HTMLTrackElement.NONE;\n\n /**\n * @listens TextTrack#loadeddata\n * @fires HTMLTrackElement#load\n */\n track.addEventListener('loadeddata', () => {\n readyState = HTMLTrackElement.LOADED;\n this.trigger({\n type: 'load',\n target: this\n });\n });\n }\n }\n HTMLTrackElement.prototype.allowedEvents_ = {\n load: 'load'\n };\n\n /**\n * The text track not loaded state.\n *\n * @type {number}\n * @static\n */\n HTMLTrackElement.NONE = 0;\n\n /**\n * The text track loading state.\n *\n * @type {number}\n * @static\n */\n HTMLTrackElement.LOADING = 1;\n\n /**\n * The text track loaded state.\n *\n * @type {number}\n * @static\n */\n HTMLTrackElement.LOADED = 2;\n\n /**\n * The text track failed to load state.\n *\n * @type {number}\n * @static\n */\n HTMLTrackElement.ERROR = 3;\n\n /*\n * This file contains all track properties that are used in\n * player.js, tech.js, html5.js and possibly other techs in the future.\n */\n\n const NORMAL = {\n audio: {\n ListClass: AudioTrackList,\n TrackClass: AudioTrack,\n capitalName: 'Audio'\n },\n video: {\n ListClass: VideoTrackList,\n TrackClass: VideoTrack,\n capitalName: 'Video'\n },\n text: {\n ListClass: TextTrackList,\n TrackClass: TextTrack,\n capitalName: 'Text'\n }\n };\n Object.keys(NORMAL).forEach(function (type) {\n NORMAL[type].getterName = `${type}Tracks`;\n NORMAL[type].privateName = `${type}Tracks_`;\n });\n const REMOTE = {\n remoteText: {\n ListClass: TextTrackList,\n TrackClass: TextTrack,\n capitalName: 'RemoteText',\n getterName: 'remoteTextTracks',\n privateName: 'remoteTextTracks_'\n },\n remoteTextEl: {\n ListClass: HtmlTrackElementList,\n TrackClass: HTMLTrackElement,\n capitalName: 'RemoteTextTrackEls',\n getterName: 'remoteTextTrackEls',\n privateName: 'remoteTextTrackEls_'\n }\n };\n const ALL = Object.assign({}, NORMAL, REMOTE);\n REMOTE.names = Object.keys(REMOTE);\n NORMAL.names = Object.keys(NORMAL);\n ALL.names = [].concat(REMOTE.names).concat(NORMAL.names);\n\n var minDoc = {};\n\n var topLevel = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : {};\n var doccy;\n if (typeof document !== 'undefined') {\n doccy = document;\n } else {\n doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];\n if (!doccy) {\n doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;\n }\n }\n var document_1 = doccy;\n\n /**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */\n\n var _objCreate = Object.create || function () {\n function F() {}\n return function (o) {\n if (arguments.length !== 1) {\n throw new Error('Object.create shim only accepts one parameter.');\n }\n F.prototype = o;\n return new F();\n };\n }();\n\n // Creates a new ParserError object from an errorData object. The errorData\n // object should have default code and message properties. The default message\n // property can be overriden by passing in a message parameter.\n // See ParsingError.Errors below for acceptable errors.\n function ParsingError(errorData, message) {\n this.name = \"ParsingError\";\n this.code = errorData.code;\n this.message = message || errorData.message;\n }\n ParsingError.prototype = _objCreate(Error.prototype);\n ParsingError.prototype.constructor = ParsingError;\n\n // ParsingError metadata for acceptable ParsingErrors.\n ParsingError.Errors = {\n BadSignature: {\n code: 0,\n message: \"Malformed WebVTT signature.\"\n },\n BadTimeStamp: {\n code: 1,\n message: \"Malformed time stamp.\"\n }\n };\n\n // Try to parse input as a time stamp.\n function parseTimeStamp(input) {\n function computeSeconds(h, m, s, f) {\n return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;\n }\n var m = input.match(/^(\\d+):(\\d{1,2})(:\\d{1,2})?\\.(\\d{3})/);\n if (!m) {\n return null;\n }\n if (m[3]) {\n // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]\n return computeSeconds(m[1], m[2], m[3].replace(\":\", \"\"), m[4]);\n } else if (m[1] > 59) {\n // Timestamp takes the form of [hours]:[minutes].[milliseconds]\n // First position is hours as it's over 59.\n return computeSeconds(m[1], m[2], 0, m[4]);\n } else {\n // Timestamp takes the form of [minutes]:[seconds].[milliseconds]\n return computeSeconds(0, m[1], m[2], m[4]);\n }\n }\n\n // A settings object holds key/value pairs and will ignore anything but the first\n // assignment to a specific key.\n function Settings() {\n this.values = _objCreate(null);\n }\n Settings.prototype = {\n // Only accept the first assignment to any key.\n set: function (k, v) {\n if (!this.get(k) && v !== \"\") {\n this.values[k] = v;\n }\n },\n // Return the value for a key, or a default value.\n // If 'defaultKey' is passed then 'dflt' is assumed to be an object with\n // a number of possible default values as properties where 'defaultKey' is\n // the key of the property that will be chosen; otherwise it's assumed to be\n // a single value.\n get: function (k, dflt, defaultKey) {\n if (defaultKey) {\n return this.has(k) ? this.values[k] : dflt[defaultKey];\n }\n return this.has(k) ? this.values[k] : dflt;\n },\n // Check whether we have a value for a key.\n has: function (k) {\n return k in this.values;\n },\n // Accept a setting if its one of the given alternatives.\n alt: function (k, v, a) {\n for (var n = 0; n < a.length; ++n) {\n if (v === a[n]) {\n this.set(k, v);\n break;\n }\n }\n },\n // Accept a setting if its a valid (signed) integer.\n integer: function (k, v) {\n if (/^-?\\d+$/.test(v)) {\n // integer\n this.set(k, parseInt(v, 10));\n }\n },\n // Accept a setting if its a valid percentage.\n percent: function (k, v) {\n if (v.match(/^([\\d]{1,3})(\\.[\\d]*)?%$/)) {\n v = parseFloat(v);\n if (v >= 0 && v <= 100) {\n this.set(k, v);\n return true;\n }\n }\n return false;\n }\n };\n\n // Helper function to parse input into groups separated by 'groupDelim', and\n // interprete each group as a key/value pair separated by 'keyValueDelim'.\n function parseOptions(input, callback, keyValueDelim, groupDelim) {\n var groups = groupDelim ? input.split(groupDelim) : [input];\n for (var i in groups) {\n if (typeof groups[i] !== \"string\") {\n continue;\n }\n var kv = groups[i].split(keyValueDelim);\n if (kv.length !== 2) {\n continue;\n }\n var k = kv[0].trim();\n var v = kv[1].trim();\n callback(k, v);\n }\n }\n function parseCue(input, cue, regionList) {\n // Remember the original input if we need to throw an error.\n var oInput = input;\n // 4.1 WebVTT timestamp\n function consumeTimeStamp() {\n var ts = parseTimeStamp(input);\n if (ts === null) {\n throw new ParsingError(ParsingError.Errors.BadTimeStamp, \"Malformed timestamp: \" + oInput);\n }\n // Remove time stamp from input.\n input = input.replace(/^[^\\sa-zA-Z-]+/, \"\");\n return ts;\n }\n\n // 4.4.2 WebVTT cue settings\n function consumeCueSettings(input, cue) {\n var settings = new Settings();\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"region\":\n // Find the last region we parsed with the same region id.\n for (var i = regionList.length - 1; i >= 0; i--) {\n if (regionList[i].id === v) {\n settings.set(k, regionList[i].region);\n break;\n }\n }\n break;\n case \"vertical\":\n settings.alt(k, v, [\"rl\", \"lr\"]);\n break;\n case \"line\":\n var vals = v.split(\",\"),\n vals0 = vals[0];\n settings.integer(k, vals0);\n settings.percent(k, vals0) ? settings.set(\"snapToLines\", false) : null;\n settings.alt(k, vals0, [\"auto\"]);\n if (vals.length === 2) {\n settings.alt(\"lineAlign\", vals[1], [\"start\", \"center\", \"end\"]);\n }\n break;\n case \"position\":\n vals = v.split(\",\");\n settings.percent(k, vals[0]);\n if (vals.length === 2) {\n settings.alt(\"positionAlign\", vals[1], [\"start\", \"center\", \"end\"]);\n }\n break;\n case \"size\":\n settings.percent(k, v);\n break;\n case \"align\":\n settings.alt(k, v, [\"start\", \"center\", \"end\", \"left\", \"right\"]);\n break;\n }\n }, /:/, /\\s/);\n\n // Apply default values for any missing fields.\n cue.region = settings.get(\"region\", null);\n cue.vertical = settings.get(\"vertical\", \"\");\n try {\n cue.line = settings.get(\"line\", \"auto\");\n } catch (e) {}\n cue.lineAlign = settings.get(\"lineAlign\", \"start\");\n cue.snapToLines = settings.get(\"snapToLines\", true);\n cue.size = settings.get(\"size\", 100);\n // Safari still uses the old middle value and won't accept center\n try {\n cue.align = settings.get(\"align\", \"center\");\n } catch (e) {\n cue.align = settings.get(\"align\", \"middle\");\n }\n try {\n cue.position = settings.get(\"position\", \"auto\");\n } catch (e) {\n cue.position = settings.get(\"position\", {\n start: 0,\n left: 0,\n center: 50,\n middle: 50,\n end: 100,\n right: 100\n }, cue.align);\n }\n cue.positionAlign = settings.get(\"positionAlign\", {\n start: \"start\",\n left: \"start\",\n center: \"center\",\n middle: \"center\",\n end: \"end\",\n right: \"end\"\n }, cue.align);\n }\n function skipWhitespace() {\n input = input.replace(/^\\s+/, \"\");\n }\n\n // 4.1 WebVTT cue timings.\n skipWhitespace();\n cue.startTime = consumeTimeStamp(); // (1) collect cue start time\n skipWhitespace();\n if (input.substr(0, 3) !== \"-->\") {\n // (3) next characters must match \"-->\"\n throw new ParsingError(ParsingError.Errors.BadTimeStamp, \"Malformed time stamp (time stamps must be separated by '-->'): \" + oInput);\n }\n input = input.substr(3);\n skipWhitespace();\n cue.endTime = consumeTimeStamp(); // (5) collect cue end time\n\n // 4.1 WebVTT cue settings list.\n skipWhitespace();\n consumeCueSettings(input, cue);\n }\n\n // When evaluating this file as part of a Webpack bundle for server\n // side rendering, `document` is an empty object.\n var TEXTAREA_ELEMENT = document_1.createElement && document_1.createElement(\"textarea\");\n var TAG_NAME = {\n c: \"span\",\n i: \"i\",\n b: \"b\",\n u: \"u\",\n ruby: \"ruby\",\n rt: \"rt\",\n v: \"span\",\n lang: \"span\"\n };\n\n // 5.1 default text color\n // 5.2 default text background color is equivalent to text color with bg_ prefix\n var DEFAULT_COLOR_CLASS = {\n white: 'rgba(255,255,255,1)',\n lime: 'rgba(0,255,0,1)',\n cyan: 'rgba(0,255,255,1)',\n red: 'rgba(255,0,0,1)',\n yellow: 'rgba(255,255,0,1)',\n magenta: 'rgba(255,0,255,1)',\n blue: 'rgba(0,0,255,1)',\n black: 'rgba(0,0,0,1)'\n };\n var TAG_ANNOTATION = {\n v: \"title\",\n lang: \"lang\"\n };\n var NEEDS_PARENT = {\n rt: \"ruby\"\n };\n\n // Parse content into a document fragment.\n function parseContent(window, input) {\n function nextToken() {\n // Check for end-of-string.\n if (!input) {\n return null;\n }\n\n // Consume 'n' characters from the input.\n function consume(result) {\n input = input.substr(result.length);\n return result;\n }\n var m = input.match(/^([^<]*)(<[^>]*>?)?/);\n // If there is some text before the next tag, return it, otherwise return\n // the tag.\n return consume(m[1] ? m[1] : m[2]);\n }\n function unescape(s) {\n TEXTAREA_ELEMENT.innerHTML = s;\n s = TEXTAREA_ELEMENT.textContent;\n TEXTAREA_ELEMENT.textContent = \"\";\n return s;\n }\n function shouldAdd(current, element) {\n return !NEEDS_PARENT[element.localName] || NEEDS_PARENT[element.localName] === current.localName;\n }\n\n // Create an element for this tag.\n function createElement(type, annotation) {\n var tagName = TAG_NAME[type];\n if (!tagName) {\n return null;\n }\n var element = window.document.createElement(tagName);\n var name = TAG_ANNOTATION[type];\n if (name && annotation) {\n element[name] = annotation.trim();\n }\n return element;\n }\n var rootDiv = window.document.createElement(\"div\"),\n current = rootDiv,\n t,\n tagStack = [];\n while ((t = nextToken()) !== null) {\n if (t[0] === '<') {\n if (t[1] === \"/\") {\n // If the closing tag matches, move back up to the parent node.\n if (tagStack.length && tagStack[tagStack.length - 1] === t.substr(2).replace(\">\", \"\")) {\n tagStack.pop();\n current = current.parentNode;\n }\n // Otherwise just ignore the end tag.\n continue;\n }\n var ts = parseTimeStamp(t.substr(1, t.length - 2));\n var node;\n if (ts) {\n // Timestamps are lead nodes as well.\n node = window.document.createProcessingInstruction(\"timestamp\", ts);\n current.appendChild(node);\n continue;\n }\n var m = t.match(/^<([^.\\s/0-9>]+)(\\.[^\\s\\\\>]+)?([^>\\\\]+)?(\\\\?)>?$/);\n // If we can't parse the tag, skip to the next tag.\n if (!m) {\n continue;\n }\n // Try to construct an element, and ignore the tag if we couldn't.\n node = createElement(m[1], m[3]);\n if (!node) {\n continue;\n }\n // Determine if the tag should be added based on the context of where it\n // is placed in the cuetext.\n if (!shouldAdd(current, node)) {\n continue;\n }\n // Set the class list (as a list of classes, separated by space).\n if (m[2]) {\n var classes = m[2].split('.');\n classes.forEach(function (cl) {\n var bgColor = /^bg_/.test(cl);\n // slice out `bg_` if it's a background color\n var colorName = bgColor ? cl.slice(3) : cl;\n if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) {\n var propName = bgColor ? 'background-color' : 'color';\n var propValue = DEFAULT_COLOR_CLASS[colorName];\n node.style[propName] = propValue;\n }\n });\n node.className = classes.join(' ');\n }\n // Append the node to the current node, and enter the scope of the new\n // node.\n tagStack.push(m[1]);\n current.appendChild(node);\n current = node;\n continue;\n }\n\n // Text nodes are leaf nodes.\n current.appendChild(window.document.createTextNode(unescape(t)));\n }\n return rootDiv;\n }\n\n // This is a list of all the Unicode characters that have a strong\n // right-to-left category. What this means is that these characters are\n // written right-to-left for sure. It was generated by pulling all the strong\n // right-to-left characters out of the Unicode data table. That table can\n // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt\n var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6], [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d], [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6], [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5], [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815], [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858], [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f], [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c], [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1], [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc], [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808], [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855], [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f], [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13], [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58], [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72], [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f], [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32], [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42], [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f], [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59], [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62], [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77], [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b], [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];\n function isStrongRTLChar(charCode) {\n for (var i = 0; i < strongRTLRanges.length; i++) {\n var currentRange = strongRTLRanges[i];\n if (charCode >= currentRange[0] && charCode <= currentRange[1]) {\n return true;\n }\n }\n return false;\n }\n function determineBidi(cueDiv) {\n var nodeStack = [],\n text = \"\",\n charCode;\n if (!cueDiv || !cueDiv.childNodes) {\n return \"ltr\";\n }\n function pushNodes(nodeStack, node) {\n for (var i = node.childNodes.length - 1; i >= 0; i--) {\n nodeStack.push(node.childNodes[i]);\n }\n }\n function nextTextNode(nodeStack) {\n if (!nodeStack || !nodeStack.length) {\n return null;\n }\n var node = nodeStack.pop(),\n text = node.textContent || node.innerText;\n if (text) {\n // TODO: This should match all unicode type B characters (paragraph\n // separator characters). See issue #115.\n var m = text.match(/^.*(\\n|\\r)/);\n if (m) {\n nodeStack.length = 0;\n return m[0];\n }\n return text;\n }\n if (node.tagName === \"ruby\") {\n return nextTextNode(nodeStack);\n }\n if (node.childNodes) {\n pushNodes(nodeStack, node);\n return nextTextNode(nodeStack);\n }\n }\n pushNodes(nodeStack, cueDiv);\n while (text = nextTextNode(nodeStack)) {\n for (var i = 0; i < text.length; i++) {\n charCode = text.charCodeAt(i);\n if (isStrongRTLChar(charCode)) {\n return \"rtl\";\n }\n }\n }\n return \"ltr\";\n }\n function computeLinePos(cue) {\n if (typeof cue.line === \"number\" && (cue.snapToLines || cue.line >= 0 && cue.line <= 100)) {\n return cue.line;\n }\n if (!cue.track || !cue.track.textTrackList || !cue.track.textTrackList.mediaElement) {\n return -1;\n }\n var track = cue.track,\n trackList = track.textTrackList,\n count = 0;\n for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {\n if (trackList[i].mode === \"showing\") {\n count++;\n }\n }\n return ++count * -1;\n }\n function StyleBox() {}\n\n // Apply styles to a div. If there is no div passed then it defaults to the\n // div on 'this'.\n StyleBox.prototype.applyStyles = function (styles, div) {\n div = div || this.div;\n for (var prop in styles) {\n if (styles.hasOwnProperty(prop)) {\n div.style[prop] = styles[prop];\n }\n }\n };\n StyleBox.prototype.formatStyle = function (val, unit) {\n return val === 0 ? 0 : val + unit;\n };\n\n // Constructs the computed display state of the cue (a div). Places the div\n // into the overlay which should be a block level element (usually a div).\n function CueStyleBox(window, cue, styleOptions) {\n StyleBox.call(this);\n this.cue = cue;\n\n // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will\n // have inline positioning and will function as the cue background box.\n this.cueDiv = parseContent(window, cue.text);\n var styles = {\n color: \"rgba(255, 255, 255, 1)\",\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n position: \"relative\",\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n display: \"inline\",\n writingMode: cue.vertical === \"\" ? \"horizontal-tb\" : cue.vertical === \"lr\" ? \"vertical-lr\" : \"vertical-rl\",\n unicodeBidi: \"plaintext\"\n };\n this.applyStyles(styles, this.cueDiv);\n\n // Create an absolutely positioned div that will be used to position the cue\n // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS\n // mirrors of them except middle instead of center on Safari.\n this.div = window.document.createElement(\"div\");\n styles = {\n direction: determineBidi(this.cueDiv),\n writingMode: cue.vertical === \"\" ? \"horizontal-tb\" : cue.vertical === \"lr\" ? \"vertical-lr\" : \"vertical-rl\",\n unicodeBidi: \"plaintext\",\n textAlign: cue.align === \"middle\" ? \"center\" : cue.align,\n font: styleOptions.font,\n whiteSpace: \"pre-line\",\n position: \"absolute\"\n };\n this.applyStyles(styles);\n this.div.appendChild(this.cueDiv);\n\n // Calculate the distance from the reference edge of the viewport to the text\n // position of the cue box. The reference edge will be resolved later when\n // the box orientation styles are applied.\n var textPos = 0;\n switch (cue.positionAlign) {\n case \"start\":\n textPos = cue.position;\n break;\n case \"center\":\n textPos = cue.position - cue.size / 2;\n break;\n case \"end\":\n textPos = cue.position - cue.size;\n break;\n }\n\n // Horizontal box orientation; textPos is the distance from the left edge of the\n // area to the left edge of the box and cue.size is the distance extending to\n // the right from there.\n if (cue.vertical === \"\") {\n this.applyStyles({\n left: this.formatStyle(textPos, \"%\"),\n width: this.formatStyle(cue.size, \"%\")\n });\n // Vertical box orientation; textPos is the distance from the top edge of the\n // area to the top edge of the box and cue.size is the height extending\n // downwards from there.\n } else {\n this.applyStyles({\n top: this.formatStyle(textPos, \"%\"),\n height: this.formatStyle(cue.size, \"%\")\n });\n }\n this.move = function (box) {\n this.applyStyles({\n top: this.formatStyle(box.top, \"px\"),\n bottom: this.formatStyle(box.bottom, \"px\"),\n left: this.formatStyle(box.left, \"px\"),\n right: this.formatStyle(box.right, \"px\"),\n height: this.formatStyle(box.height, \"px\"),\n width: this.formatStyle(box.width, \"px\")\n });\n };\n }\n CueStyleBox.prototype = _objCreate(StyleBox.prototype);\n CueStyleBox.prototype.constructor = CueStyleBox;\n\n // Represents the co-ordinates of an Element in a way that we can easily\n // compute things with such as if it overlaps or intersects with another Element.\n // Can initialize it with either a StyleBox or another BoxPosition.\n function BoxPosition(obj) {\n // Either a BoxPosition was passed in and we need to copy it, or a StyleBox\n // was passed in and we need to copy the results of 'getBoundingClientRect'\n // as the object returned is readonly. All co-ordinate values are in reference\n // to the viewport origin (top left).\n var lh, height, width, top;\n if (obj.div) {\n height = obj.div.offsetHeight;\n width = obj.div.offsetWidth;\n top = obj.div.offsetTop;\n var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && rects.getClientRects && rects.getClientRects();\n obj = obj.div.getBoundingClientRect();\n // In certain cases the outter div will be slightly larger then the sum of\n // the inner div's lines. This could be due to bold text, etc, on some platforms.\n // In this case we should get the average line height and use that. This will\n // result in the desired behaviour.\n lh = rects ? Math.max(rects[0] && rects[0].height || 0, obj.height / rects.length) : 0;\n }\n this.left = obj.left;\n this.right = obj.right;\n this.top = obj.top || top;\n this.height = obj.height || height;\n this.bottom = obj.bottom || top + (obj.height || height);\n this.width = obj.width || width;\n this.lineHeight = lh !== undefined ? lh : obj.lineHeight;\n }\n\n // Move the box along a particular axis. Optionally pass in an amount to move\n // the box. If no amount is passed then the default is the line height of the\n // box.\n BoxPosition.prototype.move = function (axis, toMove) {\n toMove = toMove !== undefined ? toMove : this.lineHeight;\n switch (axis) {\n case \"+x\":\n this.left += toMove;\n this.right += toMove;\n break;\n case \"-x\":\n this.left -= toMove;\n this.right -= toMove;\n break;\n case \"+y\":\n this.top += toMove;\n this.bottom += toMove;\n break;\n case \"-y\":\n this.top -= toMove;\n this.bottom -= toMove;\n break;\n }\n };\n\n // Check if this box overlaps another box, b2.\n BoxPosition.prototype.overlaps = function (b2) {\n return this.left < b2.right && this.right > b2.left && this.top < b2.bottom && this.bottom > b2.top;\n };\n\n // Check if this box overlaps any other boxes in boxes.\n BoxPosition.prototype.overlapsAny = function (boxes) {\n for (var i = 0; i < boxes.length; i++) {\n if (this.overlaps(boxes[i])) {\n return true;\n }\n }\n return false;\n };\n\n // Check if this box is within another box.\n BoxPosition.prototype.within = function (container) {\n return this.top >= container.top && this.bottom <= container.bottom && this.left >= container.left && this.right <= container.right;\n };\n\n // Check if this box is entirely within the container or it is overlapping\n // on the edge opposite of the axis direction passed. For example, if \"+x\" is\n // passed and the box is overlapping on the left edge of the container, then\n // return true.\n BoxPosition.prototype.overlapsOppositeAxis = function (container, axis) {\n switch (axis) {\n case \"+x\":\n return this.left < container.left;\n case \"-x\":\n return this.right > container.right;\n case \"+y\":\n return this.top < container.top;\n case \"-y\":\n return this.bottom > container.bottom;\n }\n };\n\n // Find the percentage of the area that this box is overlapping with another\n // box.\n BoxPosition.prototype.intersectPercentage = function (b2) {\n var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),\n y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),\n intersectArea = x * y;\n return intersectArea / (this.height * this.width);\n };\n\n // Convert the positions from this box to CSS compatible positions using\n // the reference container's positions. This has to be done because this\n // box's positions are in reference to the viewport origin, whereas, CSS\n // values are in referecne to their respective edges.\n BoxPosition.prototype.toCSSCompatValues = function (reference) {\n return {\n top: this.top - reference.top,\n bottom: reference.bottom - this.bottom,\n left: this.left - reference.left,\n right: reference.right - this.right,\n height: this.height,\n width: this.width\n };\n };\n\n // Get an object that represents the box's position without anything extra.\n // Can pass a StyleBox, HTMLElement, or another BoxPositon.\n BoxPosition.getSimpleBoxPosition = function (obj) {\n var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;\n var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;\n var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;\n obj = obj.div ? obj.div.getBoundingClientRect() : obj.tagName ? obj.getBoundingClientRect() : obj;\n var ret = {\n left: obj.left,\n right: obj.right,\n top: obj.top || top,\n height: obj.height || height,\n bottom: obj.bottom || top + (obj.height || height),\n width: obj.width || width\n };\n return ret;\n };\n\n // Move a StyleBox to its specified, or next best, position. The containerBox\n // is the box that contains the StyleBox, such as a div. boxPositions are\n // a list of other boxes that the styleBox can't overlap with.\n function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {\n // Find the best position for a cue box, b, on the video. The axis parameter\n // is a list of axis, the order of which, it will move the box along. For example:\n // Passing [\"+x\", \"-x\"] will move the box first along the x axis in the positive\n // direction. If it doesn't find a good position for it there it will then move\n // it along the x axis in the negative direction.\n function findBestPosition(b, axis) {\n var bestPosition,\n specifiedPosition = new BoxPosition(b),\n percentage = 1; // Highest possible so the first thing we get is better.\n\n for (var i = 0; i < axis.length; i++) {\n while (b.overlapsOppositeAxis(containerBox, axis[i]) || b.within(containerBox) && b.overlapsAny(boxPositions)) {\n b.move(axis[i]);\n }\n // We found a spot where we aren't overlapping anything. This is our\n // best position.\n if (b.within(containerBox)) {\n return b;\n }\n var p = b.intersectPercentage(containerBox);\n // If we're outside the container box less then we were on our last try\n // then remember this position as the best position.\n if (percentage > p) {\n bestPosition = new BoxPosition(b);\n percentage = p;\n }\n // Reset the box position to the specified position.\n b = new BoxPosition(specifiedPosition);\n }\n return bestPosition || specifiedPosition;\n }\n var boxPosition = new BoxPosition(styleBox),\n cue = styleBox.cue,\n linePos = computeLinePos(cue),\n axis = [];\n\n // If we have a line number to align the cue to.\n if (cue.snapToLines) {\n var size;\n switch (cue.vertical) {\n case \"\":\n axis = [\"+y\", \"-y\"];\n size = \"height\";\n break;\n case \"rl\":\n axis = [\"+x\", \"-x\"];\n size = \"width\";\n break;\n case \"lr\":\n axis = [\"-x\", \"+x\"];\n size = \"width\";\n break;\n }\n var step = boxPosition.lineHeight,\n position = step * Math.round(linePos),\n maxPosition = containerBox[size] + step,\n initialAxis = axis[0];\n\n // If the specified intial position is greater then the max position then\n // clamp the box to the amount of steps it would take for the box to\n // reach the max position.\n if (Math.abs(position) > maxPosition) {\n position = position < 0 ? -1 : 1;\n position *= Math.ceil(maxPosition / step) * step;\n }\n\n // If computed line position returns negative then line numbers are\n // relative to the bottom of the video instead of the top. Therefore, we\n // need to increase our initial position by the length or width of the\n // video, depending on the writing direction, and reverse our axis directions.\n if (linePos < 0) {\n position += cue.vertical === \"\" ? containerBox.height : containerBox.width;\n axis = axis.reverse();\n }\n\n // Move the box to the specified position. This may not be its best\n // position.\n boxPosition.move(initialAxis, position);\n } else {\n // If we have a percentage line value for the cue.\n var calculatedPercentage = boxPosition.lineHeight / containerBox.height * 100;\n switch (cue.lineAlign) {\n case \"center\":\n linePos -= calculatedPercentage / 2;\n break;\n case \"end\":\n linePos -= calculatedPercentage;\n break;\n }\n\n // Apply initial line position to the cue box.\n switch (cue.vertical) {\n case \"\":\n styleBox.applyStyles({\n top: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n case \"rl\":\n styleBox.applyStyles({\n left: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n case \"lr\":\n styleBox.applyStyles({\n right: styleBox.formatStyle(linePos, \"%\")\n });\n break;\n }\n axis = [\"+y\", \"-x\", \"+x\", \"-y\"];\n\n // Get the box position again after we've applied the specified positioning\n // to it.\n boxPosition = new BoxPosition(styleBox);\n }\n var bestPosition = findBestPosition(boxPosition, axis);\n styleBox.move(bestPosition.toCSSCompatValues(containerBox));\n }\n function WebVTT$1() {\n // Nothing\n }\n\n // Helper to allow strings to be decoded instead of the default binary utf8 data.\n WebVTT$1.StringDecoder = function () {\n return {\n decode: function (data) {\n if (!data) {\n return \"\";\n }\n if (typeof data !== \"string\") {\n throw new Error(\"Error - expected string data.\");\n }\n return decodeURIComponent(encodeURIComponent(data));\n }\n };\n };\n WebVTT$1.convertCueToDOMTree = function (window, cuetext) {\n if (!window || !cuetext) {\n return null;\n }\n return parseContent(window, cuetext);\n };\n var FONT_SIZE_PERCENT = 0.05;\n var FONT_STYLE = \"sans-serif\";\n var CUE_BACKGROUND_PADDING = \"1.5%\";\n\n // Runs the processing model over the cues and regions passed to it.\n // @param overlay A block level element (usually a div) that the computed cues\n // and regions will be placed into.\n WebVTT$1.processCues = function (window, cues, overlay) {\n if (!window || !cues || !overlay) {\n return null;\n }\n\n // Remove all previous children.\n while (overlay.firstChild) {\n overlay.removeChild(overlay.firstChild);\n }\n var paddedOverlay = window.document.createElement(\"div\");\n paddedOverlay.style.position = \"absolute\";\n paddedOverlay.style.left = \"0\";\n paddedOverlay.style.right = \"0\";\n paddedOverlay.style.top = \"0\";\n paddedOverlay.style.bottom = \"0\";\n paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;\n overlay.appendChild(paddedOverlay);\n\n // Determine if we need to compute the display states of the cues. This could\n // be the case if a cue's state has been changed since the last computation or\n // if it has not been computed yet.\n function shouldCompute(cues) {\n for (var i = 0; i < cues.length; i++) {\n if (cues[i].hasBeenReset || !cues[i].displayState) {\n return true;\n }\n }\n return false;\n }\n\n // We don't need to recompute the cues' display states. Just reuse them.\n if (!shouldCompute(cues)) {\n for (var i = 0; i < cues.length; i++) {\n paddedOverlay.appendChild(cues[i].displayState);\n }\n return;\n }\n var boxPositions = [],\n containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),\n fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;\n var styleOptions = {\n font: fontSize + \"px \" + FONT_STYLE\n };\n (function () {\n var styleBox, cue;\n for (var i = 0; i < cues.length; i++) {\n cue = cues[i];\n\n // Compute the intial position and styles of the cue div.\n styleBox = new CueStyleBox(window, cue, styleOptions);\n paddedOverlay.appendChild(styleBox.div);\n\n // Move the cue div to it's correct line position.\n moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);\n\n // Remember the computed div so that we don't have to recompute it later\n // if we don't have too.\n cue.displayState = styleBox.div;\n boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));\n }\n })();\n };\n WebVTT$1.Parser = function (window, vttjs, decoder) {\n if (!decoder) {\n decoder = vttjs;\n vttjs = {};\n }\n if (!vttjs) {\n vttjs = {};\n }\n this.window = window;\n this.vttjs = vttjs;\n this.state = \"INITIAL\";\n this.buffer = \"\";\n this.decoder = decoder || new TextDecoder(\"utf8\");\n this.regionList = [];\n };\n WebVTT$1.Parser.prototype = {\n // If the error is a ParsingError then report it to the consumer if\n // possible. If it's not a ParsingError then throw it like normal.\n reportOrThrowError: function (e) {\n if (e instanceof ParsingError) {\n this.onparsingerror && this.onparsingerror(e);\n } else {\n throw e;\n }\n },\n parse: function (data) {\n var self = this;\n\n // If there is no data then we won't decode it, but will just try to parse\n // whatever is in buffer already. This may occur in circumstances, for\n // example when flush() is called.\n if (data) {\n // Try to decode the data that we received.\n self.buffer += self.decoder.decode(data, {\n stream: true\n });\n }\n function collectNextLine() {\n var buffer = self.buffer;\n var pos = 0;\n while (pos < buffer.length && buffer[pos] !== '\\r' && buffer[pos] !== '\\n') {\n ++pos;\n }\n var line = buffer.substr(0, pos);\n // Advance the buffer early in case we fail below.\n if (buffer[pos] === '\\r') {\n ++pos;\n }\n if (buffer[pos] === '\\n') {\n ++pos;\n }\n self.buffer = buffer.substr(pos);\n return line;\n }\n\n // 3.4 WebVTT region and WebVTT region settings syntax\n function parseRegion(input) {\n var settings = new Settings();\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"id\":\n settings.set(k, v);\n break;\n case \"width\":\n settings.percent(k, v);\n break;\n case \"lines\":\n settings.integer(k, v);\n break;\n case \"regionanchor\":\n case \"viewportanchor\":\n var xy = v.split(',');\n if (xy.length !== 2) {\n break;\n }\n // We have to make sure both x and y parse, so use a temporary\n // settings object here.\n var anchor = new Settings();\n anchor.percent(\"x\", xy[0]);\n anchor.percent(\"y\", xy[1]);\n if (!anchor.has(\"x\") || !anchor.has(\"y\")) {\n break;\n }\n settings.set(k + \"X\", anchor.get(\"x\"));\n settings.set(k + \"Y\", anchor.get(\"y\"));\n break;\n case \"scroll\":\n settings.alt(k, v, [\"up\"]);\n break;\n }\n }, /=/, /\\s/);\n\n // Create the region, using default values for any values that were not\n // specified.\n if (settings.has(\"id\")) {\n var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();\n region.width = settings.get(\"width\", 100);\n region.lines = settings.get(\"lines\", 3);\n region.regionAnchorX = settings.get(\"regionanchorX\", 0);\n region.regionAnchorY = settings.get(\"regionanchorY\", 100);\n region.viewportAnchorX = settings.get(\"viewportanchorX\", 0);\n region.viewportAnchorY = settings.get(\"viewportanchorY\", 100);\n region.scroll = settings.get(\"scroll\", \"\");\n // Register the region.\n self.onregion && self.onregion(region);\n // Remember the VTTRegion for later in case we parse any VTTCues that\n // reference it.\n self.regionList.push({\n id: settings.get(\"id\"),\n region: region\n });\n }\n }\n\n // draft-pantos-http-live-streaming-20\n // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5\n // 3.5 WebVTT\n function parseTimestampMap(input) {\n var settings = new Settings();\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"MPEGT\":\n settings.integer(k + 'S', v);\n break;\n case \"LOCA\":\n settings.set(k + 'L', parseTimeStamp(v));\n break;\n }\n }, /[^\\d]:/, /,/);\n self.ontimestampmap && self.ontimestampmap({\n \"MPEGTS\": settings.get(\"MPEGTS\"),\n \"LOCAL\": settings.get(\"LOCAL\")\n });\n }\n\n // 3.2 WebVTT metadata header syntax\n function parseHeader(input) {\n if (input.match(/X-TIMESTAMP-MAP/)) {\n // This line contains HLS X-TIMESTAMP-MAP metadata\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"X-TIMESTAMP-MAP\":\n parseTimestampMap(v);\n break;\n }\n }, /=/);\n } else {\n parseOptions(input, function (k, v) {\n switch (k) {\n case \"Region\":\n // 3.3 WebVTT region metadata header syntax\n parseRegion(v);\n break;\n }\n }, /:/);\n }\n }\n\n // 5.1 WebVTT file parsing.\n try {\n var line;\n if (self.state === \"INITIAL\") {\n // We can't start parsing until we have the first line.\n if (!/\\r\\n|\\n/.test(self.buffer)) {\n return this;\n }\n line = collectNextLine();\n var m = line.match(/^WEBVTT([ \\t].*)?$/);\n if (!m || !m[0]) {\n throw new ParsingError(ParsingError.Errors.BadSignature);\n }\n self.state = \"HEADER\";\n }\n var alreadyCollectedLine = false;\n while (self.buffer) {\n // We can't parse a line until we have the full line.\n if (!/\\r\\n|\\n/.test(self.buffer)) {\n return this;\n }\n if (!alreadyCollectedLine) {\n line = collectNextLine();\n } else {\n alreadyCollectedLine = false;\n }\n switch (self.state) {\n case \"HEADER\":\n // 13-18 - Allow a header (metadata) under the WEBVTT line.\n if (/:/.test(line)) {\n parseHeader(line);\n } else if (!line) {\n // An empty line terminates the header and starts the body (cues).\n self.state = \"ID\";\n }\n continue;\n case \"NOTE\":\n // Ignore NOTE blocks.\n if (!line) {\n self.state = \"ID\";\n }\n continue;\n case \"ID\":\n // Check for the start of NOTE blocks.\n if (/^NOTE($|[ \\t])/.test(line)) {\n self.state = \"NOTE\";\n break;\n }\n // 19-29 - Allow any number of line terminators, then initialize new cue values.\n if (!line) {\n continue;\n }\n self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, \"\");\n // Safari still uses the old middle value and won't accept center\n try {\n self.cue.align = \"center\";\n } catch (e) {\n self.cue.align = \"middle\";\n }\n self.state = \"CUE\";\n // 30-39 - Check if self line contains an optional identifier or timing data.\n if (line.indexOf(\"-->\") === -1) {\n self.cue.id = line;\n continue;\n }\n // Process line as start of a cue.\n /*falls through*/\n case \"CUE\":\n // 40 - Collect cue timings and settings.\n try {\n parseCue(line, self.cue, self.regionList);\n } catch (e) {\n self.reportOrThrowError(e);\n // In case of an error ignore rest of the cue.\n self.cue = null;\n self.state = \"BADCUE\";\n continue;\n }\n self.state = \"CUETEXT\";\n continue;\n case \"CUETEXT\":\n var hasSubstring = line.indexOf(\"-->\") !== -1;\n // 34 - If we have an empty line then report the cue.\n // 35 - If we have the special substring '-->' then report the cue,\n // but do not collect the line as we need to process the current\n // one as a new cue.\n if (!line || hasSubstring && (alreadyCollectedLine = true)) {\n // We are done parsing self cue.\n self.oncue && self.oncue(self.cue);\n self.cue = null;\n self.state = \"ID\";\n continue;\n }\n if (self.cue.text) {\n self.cue.text += \"\\n\";\n }\n self.cue.text += line.replace(/\\u2028/g, '\\n').replace(/u2029/g, '\\n');\n continue;\n case \"BADCUE\":\n // BADCUE\n // 54-62 - Collect and discard the remaining cue.\n if (!line) {\n self.state = \"ID\";\n }\n continue;\n }\n }\n } catch (e) {\n self.reportOrThrowError(e);\n\n // If we are currently parsing a cue, report what we have.\n if (self.state === \"CUETEXT\" && self.cue && self.oncue) {\n self.oncue(self.cue);\n }\n self.cue = null;\n // Enter BADWEBVTT state if header was not parsed correctly otherwise\n // another exception occurred so enter BADCUE state.\n self.state = self.state === \"INITIAL\" ? \"BADWEBVTT\" : \"BADCUE\";\n }\n return this;\n },\n flush: function () {\n var self = this;\n try {\n // Finish decoding the stream.\n self.buffer += self.decoder.decode();\n // Synthesize the end of the current cue or region.\n if (self.cue || self.state === \"HEADER\") {\n self.buffer += \"\\n\\n\";\n self.parse();\n }\n // If we've flushed, parsed, and we're still on the INITIAL state then\n // that means we don't have enough of the stream to parse the first\n // line.\n if (self.state === \"INITIAL\") {\n throw new ParsingError(ParsingError.Errors.BadSignature);\n }\n } catch (e) {\n self.reportOrThrowError(e);\n }\n self.onflush && self.onflush();\n return this;\n }\n };\n var vtt = WebVTT$1;\n\n /**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n var autoKeyword = \"auto\";\n var directionSetting = {\n \"\": 1,\n \"lr\": 1,\n \"rl\": 1\n };\n var alignSetting = {\n \"start\": 1,\n \"center\": 1,\n \"end\": 1,\n \"left\": 1,\n \"right\": 1,\n \"auto\": 1,\n \"line-left\": 1,\n \"line-right\": 1\n };\n function findDirectionSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var dir = directionSetting[value.toLowerCase()];\n return dir ? value.toLowerCase() : false;\n }\n function findAlignSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var align = alignSetting[value.toLowerCase()];\n return align ? value.toLowerCase() : false;\n }\n function VTTCue(startTime, endTime, text) {\n /**\n * Shim implementation specific properties. These properties are not in\n * the spec.\n */\n\n // Lets us know when the VTTCue's data has changed in such a way that we need\n // to recompute its display state. This lets us compute its display state\n // lazily.\n this.hasBeenReset = false;\n\n /**\n * VTTCue and TextTrackCue properties\n * http://dev.w3.org/html5/webvtt/#vttcue-interface\n */\n\n var _id = \"\";\n var _pauseOnExit = false;\n var _startTime = startTime;\n var _endTime = endTime;\n var _text = text;\n var _region = null;\n var _vertical = \"\";\n var _snapToLines = true;\n var _line = \"auto\";\n var _lineAlign = \"start\";\n var _position = \"auto\";\n var _positionAlign = \"auto\";\n var _size = 100;\n var _align = \"center\";\n Object.defineProperties(this, {\n \"id\": {\n enumerable: true,\n get: function () {\n return _id;\n },\n set: function (value) {\n _id = \"\" + value;\n }\n },\n \"pauseOnExit\": {\n enumerable: true,\n get: function () {\n return _pauseOnExit;\n },\n set: function (value) {\n _pauseOnExit = !!value;\n }\n },\n \"startTime\": {\n enumerable: true,\n get: function () {\n return _startTime;\n },\n set: function (value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"Start time must be set to a number.\");\n }\n _startTime = value;\n this.hasBeenReset = true;\n }\n },\n \"endTime\": {\n enumerable: true,\n get: function () {\n return _endTime;\n },\n set: function (value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"End time must be set to a number.\");\n }\n _endTime = value;\n this.hasBeenReset = true;\n }\n },\n \"text\": {\n enumerable: true,\n get: function () {\n return _text;\n },\n set: function (value) {\n _text = \"\" + value;\n this.hasBeenReset = true;\n }\n },\n \"region\": {\n enumerable: true,\n get: function () {\n return _region;\n },\n set: function (value) {\n _region = value;\n this.hasBeenReset = true;\n }\n },\n \"vertical\": {\n enumerable: true,\n get: function () {\n return _vertical;\n },\n set: function (value) {\n var setting = findDirectionSetting(value);\n // Have to check for false because the setting an be an empty string.\n if (setting === false) {\n throw new SyntaxError(\"Vertical: an invalid or illegal direction string was specified.\");\n }\n _vertical = setting;\n this.hasBeenReset = true;\n }\n },\n \"snapToLines\": {\n enumerable: true,\n get: function () {\n return _snapToLines;\n },\n set: function (value) {\n _snapToLines = !!value;\n this.hasBeenReset = true;\n }\n },\n \"line\": {\n enumerable: true,\n get: function () {\n return _line;\n },\n set: function (value) {\n if (typeof value !== \"number\" && value !== autoKeyword) {\n throw new SyntaxError(\"Line: an invalid number or illegal string was specified.\");\n }\n _line = value;\n this.hasBeenReset = true;\n }\n },\n \"lineAlign\": {\n enumerable: true,\n get: function () {\n return _lineAlign;\n },\n set: function (value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n console.warn(\"lineAlign: an invalid or illegal string was specified.\");\n } else {\n _lineAlign = setting;\n this.hasBeenReset = true;\n }\n }\n },\n \"position\": {\n enumerable: true,\n get: function () {\n return _position;\n },\n set: function (value) {\n if (value < 0 || value > 100) {\n throw new Error(\"Position must be between 0 and 100.\");\n }\n _position = value;\n this.hasBeenReset = true;\n }\n },\n \"positionAlign\": {\n enumerable: true,\n get: function () {\n return _positionAlign;\n },\n set: function (value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n console.warn(\"positionAlign: an invalid or illegal string was specified.\");\n } else {\n _positionAlign = setting;\n this.hasBeenReset = true;\n }\n }\n },\n \"size\": {\n enumerable: true,\n get: function () {\n return _size;\n },\n set: function (value) {\n if (value < 0 || value > 100) {\n throw new Error(\"Size must be between 0 and 100.\");\n }\n _size = value;\n this.hasBeenReset = true;\n }\n },\n \"align\": {\n enumerable: true,\n get: function () {\n return _align;\n },\n set: function (value) {\n var setting = findAlignSetting(value);\n if (!setting) {\n throw new SyntaxError(\"align: an invalid or illegal alignment string was specified.\");\n }\n _align = setting;\n this.hasBeenReset = true;\n }\n }\n });\n\n /**\n * Other spec defined properties\n */\n\n // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state\n this.displayState = undefined;\n }\n\n /**\n * VTTCue methods\n */\n\n VTTCue.prototype.getCueAsHTML = function () {\n // Assume WebVTT.convertCueToDOMTree is on the global.\n return WebVTT.convertCueToDOMTree(window, this.text);\n };\n var vttcue = VTTCue;\n\n /**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n var scrollSetting = {\n \"\": true,\n \"up\": true\n };\n function findScrollSetting(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n var scroll = scrollSetting[value.toLowerCase()];\n return scroll ? value.toLowerCase() : false;\n }\n function isValidPercentValue(value) {\n return typeof value === \"number\" && value >= 0 && value <= 100;\n }\n\n // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface\n function VTTRegion() {\n var _width = 100;\n var _lines = 3;\n var _regionAnchorX = 0;\n var _regionAnchorY = 100;\n var _viewportAnchorX = 0;\n var _viewportAnchorY = 100;\n var _scroll = \"\";\n Object.defineProperties(this, {\n \"width\": {\n enumerable: true,\n get: function () {\n return _width;\n },\n set: function (value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"Width must be between 0 and 100.\");\n }\n _width = value;\n }\n },\n \"lines\": {\n enumerable: true,\n get: function () {\n return _lines;\n },\n set: function (value) {\n if (typeof value !== \"number\") {\n throw new TypeError(\"Lines must be set to a number.\");\n }\n _lines = value;\n }\n },\n \"regionAnchorY\": {\n enumerable: true,\n get: function () {\n return _regionAnchorY;\n },\n set: function (value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"RegionAnchorX must be between 0 and 100.\");\n }\n _regionAnchorY = value;\n }\n },\n \"regionAnchorX\": {\n enumerable: true,\n get: function () {\n return _regionAnchorX;\n },\n set: function (value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"RegionAnchorY must be between 0 and 100.\");\n }\n _regionAnchorX = value;\n }\n },\n \"viewportAnchorY\": {\n enumerable: true,\n get: function () {\n return _viewportAnchorY;\n },\n set: function (value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"ViewportAnchorY must be between 0 and 100.\");\n }\n _viewportAnchorY = value;\n }\n },\n \"viewportAnchorX\": {\n enumerable: true,\n get: function () {\n return _viewportAnchorX;\n },\n set: function (value) {\n if (!isValidPercentValue(value)) {\n throw new Error(\"ViewportAnchorX must be between 0 and 100.\");\n }\n _viewportAnchorX = value;\n }\n },\n \"scroll\": {\n enumerable: true,\n get: function () {\n return _scroll;\n },\n set: function (value) {\n var setting = findScrollSetting(value);\n // Have to check for false as an empty string is a legal value.\n if (setting === false) {\n console.warn(\"Scroll: an invalid or illegal string was specified.\");\n } else {\n _scroll = setting;\n }\n }\n }\n });\n }\n var vttregion = VTTRegion;\n\n var browserIndex = createCommonjsModule(function (module) {\n /**\n * Copyright 2013 vtt.js Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n // Default exports for Node. Export the extended versions of VTTCue and\n // VTTRegion in Node since we likely want the capability to convert back and\n // forth between JSON. If we don't then it's not that big of a deal since we're\n // off browser.\n\n var vttjs = module.exports = {\n WebVTT: vtt,\n VTTCue: vttcue,\n VTTRegion: vttregion\n };\n window_1.vttjs = vttjs;\n window_1.WebVTT = vttjs.WebVTT;\n var cueShim = vttjs.VTTCue;\n var regionShim = vttjs.VTTRegion;\n var nativeVTTCue = window_1.VTTCue;\n var nativeVTTRegion = window_1.VTTRegion;\n vttjs.shim = function () {\n window_1.VTTCue = cueShim;\n window_1.VTTRegion = regionShim;\n };\n vttjs.restore = function () {\n window_1.VTTCue = nativeVTTCue;\n window_1.VTTRegion = nativeVTTRegion;\n };\n if (!window_1.VTTCue) {\n vttjs.shim();\n }\n });\n browserIndex.WebVTT;\n browserIndex.VTTCue;\n browserIndex.VTTRegion;\n\n /**\n * @file tech.js\n */\n\n /**\n * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string\n * that just contains the src url alone.\n * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`\n * `var SourceString = 'http://example.com/some-video.mp4';`\n *\n * @typedef {Object|string} Tech~SourceObject\n *\n * @property {string} src\n * The url to the source\n *\n * @property {string} type\n * The mime type of the source\n */\n\n /**\n * A function used by {@link Tech} to create a new {@link TextTrack}.\n *\n * @private\n *\n * @param {Tech} self\n * An instance of the Tech class.\n *\n * @param {string} kind\n * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)\n *\n * @param {string} [label]\n * Label to identify the text track\n *\n * @param {string} [language]\n * Two letter language abbreviation\n *\n * @param {Object} [options={}]\n * An object with additional text track options\n *\n * @return {TextTrack}\n * The text track that was created.\n */\n function createTrackHelper(self, kind, label, language, options = {}) {\n const tracks = self.textTracks();\n options.kind = kind;\n if (label) {\n options.label = label;\n }\n if (language) {\n options.language = language;\n }\n options.tech = self;\n const track = new ALL.text.TrackClass(options);\n tracks.addTrack(track);\n return track;\n }\n\n /**\n * This is the base class for media playback technology controllers, such as\n * {@link HTML5}\n *\n * @extends Component\n */\n class Tech extends Component$1 {\n /**\n * Create an instance of this Tech.\n *\n * @param {Object} [options]\n * The key/value store of player options.\n *\n * @param {Function} [ready]\n * Callback function to call when the `HTML5` Tech is ready.\n */\n constructor(options = {}, ready = function () {}) {\n // we don't want the tech to report user activity automatically.\n // This is done manually in addControlsListeners\n options.reportTouchActivity = false;\n super(null, options, ready);\n this.onDurationChange_ = e => this.onDurationChange(e);\n this.trackProgress_ = e => this.trackProgress(e);\n this.trackCurrentTime_ = e => this.trackCurrentTime(e);\n this.stopTrackingCurrentTime_ = e => this.stopTrackingCurrentTime(e);\n this.disposeSourceHandler_ = e => this.disposeSourceHandler(e);\n this.queuedHanders_ = new Set();\n\n // keep track of whether the current source has played at all to\n // implement a very limited played()\n this.hasStarted_ = false;\n this.on('playing', function () {\n this.hasStarted_ = true;\n });\n this.on('loadstart', function () {\n this.hasStarted_ = false;\n });\n ALL.names.forEach(name => {\n const props = ALL[name];\n if (options && options[props.getterName]) {\n this[props.privateName] = options[props.getterName];\n }\n });\n\n // Manually track progress in cases where the browser/tech doesn't report it.\n if (!this.featuresProgressEvents) {\n this.manualProgressOn();\n }\n\n // Manually track timeupdates in cases where the browser/tech doesn't report it.\n if (!this.featuresTimeupdateEvents) {\n this.manualTimeUpdatesOn();\n }\n ['Text', 'Audio', 'Video'].forEach(track => {\n if (options[`native${track}Tracks`] === false) {\n this[`featuresNative${track}Tracks`] = false;\n }\n });\n if (options.nativeCaptions === false || options.nativeTextTracks === false) {\n this.featuresNativeTextTracks = false;\n } else if (options.nativeCaptions === true || options.nativeTextTracks === true) {\n this.featuresNativeTextTracks = true;\n }\n if (!this.featuresNativeTextTracks) {\n this.emulateTextTracks();\n }\n this.preloadTextTracks = options.preloadTextTracks !== false;\n this.autoRemoteTextTracks_ = new ALL.text.ListClass();\n this.initTrackListeners();\n\n // Turn on component tap events only if not using native controls\n if (!options.nativeControlsForTouch) {\n this.emitTapEvents();\n }\n if (this.constructor) {\n this.name_ = this.constructor.name || 'Unknown Tech';\n }\n }\n\n /**\n * A special function to trigger source set in a way that will allow player\n * to re-trigger if the player or tech are not ready yet.\n *\n * @fires Tech#sourceset\n * @param {string} src The source string at the time of the source changing.\n */\n triggerSourceset(src) {\n if (!this.isReady_) {\n // on initial ready we have to trigger source set\n // 1ms after ready so that player can watch for it.\n this.one('ready', () => this.setTimeout(() => this.triggerSourceset(src), 1));\n }\n\n /**\n * Fired when the source is set on the tech causing the media element\n * to reload.\n *\n * @see {@link Player#event:sourceset}\n * @event Tech#sourceset\n * @type {Event}\n */\n this.trigger({\n src,\n type: 'sourceset'\n });\n }\n\n /* Fallbacks for unsupported event types\n ================================================================================ */\n\n /**\n * Polyfill the `progress` event for browsers that don't support it natively.\n *\n * @see {@link Tech#trackProgress}\n */\n manualProgressOn() {\n this.on('durationchange', this.onDurationChange_);\n this.manualProgress = true;\n\n // Trigger progress watching when a source begins loading\n this.one('ready', this.trackProgress_);\n }\n\n /**\n * Turn off the polyfill for `progress` events that was created in\n * {@link Tech#manualProgressOn}\n */\n manualProgressOff() {\n this.manualProgress = false;\n this.stopTrackingProgress();\n this.off('durationchange', this.onDurationChange_);\n }\n\n /**\n * This is used to trigger a `progress` event when the buffered percent changes. It\n * sets an interval function that will be called every 500 milliseconds to check if the\n * buffer end percent has changed.\n *\n * > This function is called by {@link Tech#manualProgressOn}\n *\n * @param {Event} event\n * The `ready` event that caused this to run.\n *\n * @listens Tech#ready\n * @fires Tech#progress\n */\n trackProgress(event) {\n this.stopTrackingProgress();\n this.progressInterval = this.setInterval(bind_(this, function () {\n // Don't trigger unless buffered amount is greater than last time\n\n const numBufferedPercent = this.bufferedPercent();\n if (this.bufferedPercent_ !== numBufferedPercent) {\n /**\n * See {@link Player#progress}\n *\n * @event Tech#progress\n * @type {Event}\n */\n this.trigger('progress');\n }\n this.bufferedPercent_ = numBufferedPercent;\n if (numBufferedPercent === 1) {\n this.stopTrackingProgress();\n }\n }), 500);\n }\n\n /**\n * Update our internal duration on a `durationchange` event by calling\n * {@link Tech#duration}.\n *\n * @param {Event} event\n * The `durationchange` event that caused this to run.\n *\n * @listens Tech#durationchange\n */\n onDurationChange(event) {\n this.duration_ = this.duration();\n }\n\n /**\n * Get and create a `TimeRange` object for buffering.\n *\n * @return { import('../utils/time').TimeRange }\n * The time range object that was created.\n */\n buffered() {\n return createTimeRanges$1(0, 0);\n }\n\n /**\n * Get the percentage of the current video that is currently buffered.\n *\n * @return {number}\n * A number from 0 to 1 that represents the decimal percentage of the\n * video that is buffered.\n *\n */\n bufferedPercent() {\n return bufferedPercent(this.buffered(), this.duration_);\n }\n\n /**\n * Turn off the polyfill for `progress` events that was created in\n * {@link Tech#manualProgressOn}\n * Stop manually tracking progress events by clearing the interval that was set in\n * {@link Tech#trackProgress}.\n */\n stopTrackingProgress() {\n this.clearInterval(this.progressInterval);\n }\n\n /**\n * Polyfill the `timeupdate` event for browsers that don't support it.\n *\n * @see {@link Tech#trackCurrentTime}\n */\n manualTimeUpdatesOn() {\n this.manualTimeUpdates = true;\n this.on('play', this.trackCurrentTime_);\n this.on('pause', this.stopTrackingCurrentTime_);\n }\n\n /**\n * Turn off the polyfill for `timeupdate` events that was created in\n * {@link Tech#manualTimeUpdatesOn}\n */\n manualTimeUpdatesOff() {\n this.manualTimeUpdates = false;\n this.stopTrackingCurrentTime();\n this.off('play', this.trackCurrentTime_);\n this.off('pause', this.stopTrackingCurrentTime_);\n }\n\n /**\n * Sets up an interval function to track current time and trigger `timeupdate` every\n * 250 milliseconds.\n *\n * @listens Tech#play\n * @triggers Tech#timeupdate\n */\n trackCurrentTime() {\n if (this.currentTimeInterval) {\n this.stopTrackingCurrentTime();\n }\n this.currentTimeInterval = this.setInterval(function () {\n /**\n * Triggered at an interval of 250ms to indicated that time is passing in the video.\n *\n * @event Tech#timeupdate\n * @type {Event}\n */\n this.trigger({\n type: 'timeupdate',\n target: this,\n manuallyTriggered: true\n });\n\n // 42 = 24 fps // 250 is what Webkit uses // FF uses 15\n }, 250);\n }\n\n /**\n * Stop the interval function created in {@link Tech#trackCurrentTime} so that the\n * `timeupdate` event is no longer triggered.\n *\n * @listens {Tech#pause}\n */\n stopTrackingCurrentTime() {\n this.clearInterval(this.currentTimeInterval);\n\n // #1002 - if the video ends right before the next timeupdate would happen,\n // the progress bar won't make it all the way to the end\n this.trigger({\n type: 'timeupdate',\n target: this,\n manuallyTriggered: true\n });\n }\n\n /**\n * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},\n * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.\n *\n * @fires Component#dispose\n */\n dispose() {\n // clear out all tracks because we can't reuse them between techs\n this.clearTracks(NORMAL.names);\n\n // Turn off any manual progress or timeupdate tracking\n if (this.manualProgress) {\n this.manualProgressOff();\n }\n if (this.manualTimeUpdates) {\n this.manualTimeUpdatesOff();\n }\n super.dispose();\n }\n\n /**\n * Clear out a single `TrackList` or an array of `TrackLists` given their names.\n *\n * > Note: Techs without source handlers should call this between sources for `video`\n * & `audio` tracks. You don't want to use them between tracks!\n *\n * @param {string[]|string} types\n * TrackList names to clear, valid names are `video`, `audio`, and\n * `text`.\n */\n clearTracks(types) {\n types = [].concat(types);\n // clear out all tracks because we can't reuse them between techs\n types.forEach(type => {\n const list = this[`${type}Tracks`]() || [];\n let i = list.length;\n while (i--) {\n const track = list[i];\n if (type === 'text') {\n this.removeRemoteTextTrack(track);\n }\n list.removeTrack(track);\n }\n });\n }\n\n /**\n * Remove any TextTracks added via addRemoteTextTrack that are\n * flagged for automatic garbage collection\n */\n cleanupAutoTextTracks() {\n const list = this.autoRemoteTextTracks_ || [];\n let i = list.length;\n while (i--) {\n const track = list[i];\n this.removeRemoteTextTrack(track);\n }\n }\n\n /**\n * Reset the tech, which will removes all sources and reset the internal readyState.\n *\n * @abstract\n */\n reset() {}\n\n /**\n * Get the value of `crossOrigin` from the tech.\n *\n * @abstract\n *\n * @see {Html5#crossOrigin}\n */\n crossOrigin() {}\n\n /**\n * Set the value of `crossOrigin` on the tech.\n *\n * @abstract\n *\n * @param {string} crossOrigin the crossOrigin value\n * @see {Html5#setCrossOrigin}\n */\n setCrossOrigin() {}\n\n /**\n * Get or set an error on the Tech.\n *\n * @param {MediaError} [err]\n * Error to set on the Tech\n *\n * @return {MediaError|null}\n * The current error object on the tech, or null if there isn't one.\n */\n error(err) {\n if (err !== undefined) {\n this.error_ = new MediaError(err);\n this.trigger('error');\n }\n return this.error_;\n }\n\n /**\n * Returns the `TimeRange`s that have been played through for the current source.\n *\n * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.\n * It only checks whether the source has played at all or not.\n *\n * @return {TimeRange}\n * - A single time range if this video has played\n * - An empty set of ranges if not.\n */\n played() {\n if (this.hasStarted_) {\n return createTimeRanges$1(0, 0);\n }\n return createTimeRanges$1();\n }\n\n /**\n * Start playback\n *\n * @abstract\n *\n * @see {Html5#play}\n */\n play() {}\n\n /**\n * Set whether we are scrubbing or not\n *\n * @abstract\n * @param {boolean} _isScrubbing\n * - true for we are currently scrubbing\n * - false for we are no longer scrubbing\n *\n * @see {Html5#setScrubbing}\n */\n setScrubbing(_isScrubbing) {}\n\n /**\n * Get whether we are scrubbing or not\n *\n * @abstract\n *\n * @see {Html5#scrubbing}\n */\n scrubbing() {}\n\n /**\n * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was\n * previously called.\n *\n * @param {number} _seconds\n * Set the current time of the media to this.\n * @fires Tech#timeupdate\n */\n setCurrentTime(_seconds) {\n // improve the accuracy of manual timeupdates\n if (this.manualTimeUpdates) {\n /**\n * A manual `timeupdate` event.\n *\n * @event Tech#timeupdate\n * @type {Event}\n */\n this.trigger({\n type: 'timeupdate',\n target: this,\n manuallyTriggered: true\n });\n }\n }\n\n /**\n * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and\n * {@link TextTrackList} events.\n *\n * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.\n *\n * @fires Tech#audiotrackchange\n * @fires Tech#videotrackchange\n * @fires Tech#texttrackchange\n */\n initTrackListeners() {\n /**\n * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}\n *\n * @event Tech#audiotrackchange\n * @type {Event}\n */\n\n /**\n * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}\n *\n * @event Tech#videotrackchange\n * @type {Event}\n */\n\n /**\n * Triggered when tracks are added or removed on the Tech {@link TextTrackList}\n *\n * @event Tech#texttrackchange\n * @type {Event}\n */\n NORMAL.names.forEach(name => {\n const props = NORMAL[name];\n const trackListChanges = () => {\n this.trigger(`${name}trackchange`);\n };\n const tracks = this[props.getterName]();\n tracks.addEventListener('removetrack', trackListChanges);\n tracks.addEventListener('addtrack', trackListChanges);\n this.on('dispose', () => {\n tracks.removeEventListener('removetrack', trackListChanges);\n tracks.removeEventListener('addtrack', trackListChanges);\n });\n });\n }\n\n /**\n * Emulate TextTracks using vtt.js if necessary\n *\n * @fires Tech#vttjsloaded\n * @fires Tech#vttjserror\n */\n addWebVttScript_() {\n if (window.WebVTT) {\n return;\n }\n\n // Initially, Tech.el_ is a child of a dummy-div wait until the Component system\n // signals that the Tech is ready at which point Tech.el_ is part of the DOM\n // before inserting the WebVTT script\n if (document.body.contains(this.el())) {\n // load via require if available and vtt.js script location was not passed in\n // as an option. novtt builds will turn the above require call into an empty object\n // which will cause this if check to always fail.\n if (!this.options_['vtt.js'] && isPlain(browserIndex) && Object.keys(browserIndex).length > 0) {\n this.trigger('vttjsloaded');\n return;\n }\n\n // load vtt.js via the script location option or the cdn of no location was\n // passed in\n const script = document.createElement('script');\n script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js';\n script.onload = () => {\n /**\n * Fired when vtt.js is loaded.\n *\n * @event Tech#vttjsloaded\n * @type {Event}\n */\n this.trigger('vttjsloaded');\n };\n script.onerror = () => {\n /**\n * Fired when vtt.js was not loaded due to an error\n *\n * @event Tech#vttjsloaded\n * @type {Event}\n */\n this.trigger('vttjserror');\n };\n this.on('dispose', () => {\n script.onload = null;\n script.onerror = null;\n });\n // but have not loaded yet and we set it to true before the inject so that\n // we don't overwrite the injected window.WebVTT if it loads right away\n window.WebVTT = true;\n this.el().parentNode.appendChild(script);\n } else {\n this.ready(this.addWebVttScript_);\n }\n }\n\n /**\n * Emulate texttracks\n *\n */\n emulateTextTracks() {\n const tracks = this.textTracks();\n const remoteTracks = this.remoteTextTracks();\n const handleAddTrack = e => tracks.addTrack(e.track);\n const handleRemoveTrack = e => tracks.removeTrack(e.track);\n remoteTracks.on('addtrack', handleAddTrack);\n remoteTracks.on('removetrack', handleRemoveTrack);\n this.addWebVttScript_();\n const updateDisplay = () => this.trigger('texttrackchange');\n const textTracksChanges = () => {\n updateDisplay();\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n track.removeEventListener('cuechange', updateDisplay);\n if (track.mode === 'showing') {\n track.addEventListener('cuechange', updateDisplay);\n }\n }\n };\n textTracksChanges();\n tracks.addEventListener('change', textTracksChanges);\n tracks.addEventListener('addtrack', textTracksChanges);\n tracks.addEventListener('removetrack', textTracksChanges);\n this.on('dispose', function () {\n remoteTracks.off('addtrack', handleAddTrack);\n remoteTracks.off('removetrack', handleRemoveTrack);\n tracks.removeEventListener('change', textTracksChanges);\n tracks.removeEventListener('addtrack', textTracksChanges);\n tracks.removeEventListener('removetrack', textTracksChanges);\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n track.removeEventListener('cuechange', updateDisplay);\n }\n });\n }\n\n /**\n * Create and returns a remote {@link TextTrack} object.\n *\n * @param {string} kind\n * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)\n *\n * @param {string} [label]\n * Label to identify the text track\n *\n * @param {string} [language]\n * Two letter language abbreviation\n *\n * @return {TextTrack}\n * The TextTrack that gets created.\n */\n addTextTrack(kind, label, language) {\n if (!kind) {\n throw new Error('TextTrack kind is required but was not provided');\n }\n return createTrackHelper(this, kind, label, language);\n }\n\n /**\n * Create an emulated TextTrack for use by addRemoteTextTrack\n *\n * This is intended to be overridden by classes that inherit from\n * Tech in order to create native or custom TextTracks.\n *\n * @param {Object} options\n * The object should contain the options to initialize the TextTrack with.\n *\n * @param {string} [options.kind]\n * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).\n *\n * @param {string} [options.label].\n * Label to identify the text track\n *\n * @param {string} [options.language]\n * Two letter language abbreviation.\n *\n * @return {HTMLTrackElement}\n * The track element that gets created.\n */\n createRemoteTextTrack(options) {\n const track = merge$2(options, {\n tech: this\n });\n return new REMOTE.remoteTextEl.TrackClass(track);\n }\n\n /**\n * Creates a remote text track object and returns an html track element.\n *\n * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.\n *\n * @param {Object} options\n * See {@link Tech#createRemoteTextTrack} for more detailed properties.\n *\n * @param {boolean} [manualCleanup=false]\n * - When false: the TextTrack will be automatically removed from the video\n * element whenever the source changes\n * - When True: The TextTrack will have to be cleaned up manually\n *\n * @return {HTMLTrackElement}\n * An Html Track Element.\n *\n */\n addRemoteTextTrack(options = {}, manualCleanup) {\n const htmlTrackElement = this.createRemoteTextTrack(options);\n if (typeof manualCleanup !== 'boolean') {\n manualCleanup = false;\n }\n\n // store HTMLTrackElement and TextTrack to remote list\n this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);\n this.remoteTextTracks().addTrack(htmlTrackElement.track);\n if (manualCleanup === false) {\n // create the TextTrackList if it doesn't exist\n this.ready(() => this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track));\n }\n return htmlTrackElement;\n }\n\n /**\n * Remove a remote text track from the remote `TextTrackList`.\n *\n * @param {TextTrack} track\n * `TextTrack` to remove from the `TextTrackList`\n */\n removeRemoteTextTrack(track) {\n const trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);\n\n // remove HTMLTrackElement and TextTrack from remote list\n this.remoteTextTrackEls().removeTrackElement_(trackElement);\n this.remoteTextTracks().removeTrack(track);\n this.autoRemoteTextTracks_.removeTrack(track);\n }\n\n /**\n * Gets available media playback quality metrics as specified by the W3C's Media\n * Playback Quality API.\n *\n * @see [Spec]{@link https://wicg.github.io/media-playback-quality}\n *\n * @return {Object}\n * An object with supported media playback quality metrics\n *\n * @abstract\n */\n getVideoPlaybackQuality() {\n return {};\n }\n\n /**\n * Attempt to create a floating video window always on top of other windows\n * so that users may continue consuming media while they interact with other\n * content sites, or applications on their device.\n *\n * @see [Spec]{@link https://wicg.github.io/picture-in-picture}\n *\n * @return {Promise|undefined}\n * A promise with a Picture-in-Picture window if the browser supports\n * Promises (or one was passed in as an option). It returns undefined\n * otherwise.\n *\n * @abstract\n */\n requestPictureInPicture() {\n return Promise.reject();\n }\n\n /**\n * A method to check for the value of the 'disablePictureInPicture'