diff --git a/ajax/libs/plyr/3.5.4/blank.mp4 b/ajax/libs/plyr/3.5.4/blank.mp4 new file mode 100644 index 00000000000000..d8982b6378ce73 Binary files /dev/null and b/ajax/libs/plyr/3.5.4/blank.mp4 differ diff --git a/ajax/libs/plyr/3.5.4/plyr.css b/ajax/libs/plyr/3.5.4/plyr.css new file mode 100644 index 00000000000000..9e6c998ee88b2c --- /dev/null +++ b/ajax/libs/plyr/3.5.4/plyr.css @@ -0,0 +1 @@ +@keyframes plyr-progress{to{background-position:25px 0}}@keyframes plyr-popup{0%{opacity:.5;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes plyr-fade-in{from{opacity:0}to{opacity:1}}.plyr{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:subpixel-antialiased;direction:ltr;font-family:Avenir,"Avenir Next","Helvetica Neue","Segoe UI",Helvetica,Arial,sans-serif;font-variant-numeric:tabular-nums;font-weight:500;line-height:1.7;max-width:100%;min-width:200px;position:relative;text-shadow:none;transition:box-shadow .3s ease}.plyr audio,.plyr video{border-radius:inherit;height:auto;vertical-align:middle;width:100%}.plyr button{font:inherit;line-height:inherit;width:auto}.plyr:focus{outline:0}.plyr--full-ui{box-sizing:border-box}.plyr--full-ui *,.plyr--full-ui ::after,.plyr--full-ui ::before{box-sizing:inherit}.plyr--full-ui a,.plyr--full-ui button,.plyr--full-ui input,.plyr--full-ui label{touch-action:manipulation}.plyr__badge{background:#4f5b5f;border-radius:2px;color:#fff;font-size:9px;line-height:1;padding:3px 4px}.plyr--full-ui ::-webkit-media-text-track-container{display:none}.plyr__captions{animation:plyr-fade-in .3s ease;bottom:0;color:#fff;display:none;font-size:14px;left:0;padding:10px;position:absolute;text-align:center;transition:transform .4s ease-in-out;width:100%}.plyr__captions .plyr__caption{background:rgba(0,0,0,.8);border-radius:2px;-webkit-box-decoration-break:clone;box-decoration-break:clone;line-height:185%;padding:.2em .5em;white-space:pre-wrap}.plyr__captions .plyr__caption div{display:inline}.plyr__captions span:empty{display:none}@media (min-width:480px){.plyr__captions{font-size:16px;padding:20px}}@media (min-width:768px){.plyr__captions{font-size:18px}}.plyr--captions-active .plyr__captions{display:block}.plyr:not(.plyr--hide-controls) .plyr__controls:not(:empty)~.plyr__captions{transform:translateY(-40px)}.plyr__control{background:0 0;border:0;border-radius:3px;color:inherit;cursor:pointer;flex-shrink:0;overflow:visible;padding:7px;position:relative;transition:all .3s ease}.plyr__control svg{display:block;fill:currentColor;height:18px;pointer-events:none;width:18px}.plyr__control:focus{outline:0}.plyr__control.plyr__tab-focus{box-shadow:0 0 0 5px rgba(26,175,255,.5);outline:0}a.plyr__control{text-decoration:none}a.plyr__control::after,a.plyr__control::before{display:none}.plyr__control.plyr__control--pressed .icon--not-pressed,.plyr__control.plyr__control--pressed .label--not-pressed,.plyr__control:not(.plyr__control--pressed) .icon--pressed,.plyr__control:not(.plyr__control--pressed) .label--pressed{display:none}.plyr--audio .plyr__control.plyr__tab-focus,.plyr--audio .plyr__control:hover,.plyr--audio .plyr__control[aria-expanded=true]{background:#1aafff;color:#fff}.plyr--video .plyr__control svg{filter:drop-shadow(0 1px 1px rgba(0, 0, 0, .15))}.plyr--video .plyr__control.plyr__tab-focus,.plyr--video .plyr__control:hover,.plyr--video .plyr__control[aria-expanded=true]{background:#1aafff;color:#fff}.plyr__control--overlaid{background:rgba(26,175,255,.8);border:0;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15);color:#fff;display:none;left:50%;padding:15px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:2}.plyr__control--overlaid svg{left:2px;position:relative}.plyr__control--overlaid:focus,.plyr__control--overlaid:hover{background:#1aafff}.plyr--playing .plyr__control--overlaid{opacity:0;visibility:hidden}.plyr--full-ui.plyr--video .plyr__control--overlaid{display:block}.plyr--full-ui ::-webkit-media-controls{display:none}.plyr__controls{align-items:center;display:flex;justify-content:flex-end;text-align:center}.plyr__controls .plyr__progress__container{flex:1}.plyr__controls .plyr__controls__item{margin-left:2.5px}.plyr__controls .plyr__controls__item:first-child{margin-left:0;margin-right:auto}.plyr__controls .plyr__controls__item.plyr__progress__container{padding-left:2.5px}.plyr__controls .plyr__controls__item.plyr__time{padding:0 5px}.plyr__controls .plyr__controls__item.plyr__progress__container:first-child,.plyr__controls .plyr__controls__item.plyr__time+.plyr__time,.plyr__controls .plyr__controls__item.plyr__time:first-child{padding-left:0}.plyr__controls .plyr__controls__item.plyr__volume{padding-right:5px}.plyr__controls .plyr__controls__item.plyr__volume:first-child{padding-right:0}.plyr__controls:empty{display:none}.plyr--audio .plyr__controls{background:#fff;border-radius:inherit;color:#4f5b5f;padding:10px}.plyr--video .plyr__controls{background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.7));border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;bottom:0;color:#fff;left:0;padding:20px 5px 5px;position:absolute;right:0;transition:opacity .4s ease-in-out,transform .4s ease-in-out;z-index:3}@media (min-width:480px){.plyr--video .plyr__controls{padding:35px 10px 10px}}.plyr--video.plyr--hide-controls .plyr__controls{opacity:0;pointer-events:none;transform:translateY(100%)}.plyr [data-plyr=airplay],.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen],.plyr [data-plyr=pip]{display:none}.plyr--airplay-supported [data-plyr=airplay],.plyr--captions-enabled [data-plyr=captions],.plyr--fullscreen-enabled [data-plyr=fullscreen],.plyr--pip-supported [data-plyr=pip]{display:inline-block}.plyr__menu{display:flex;position:relative}.plyr__menu .plyr__control svg{transition:transform .3s ease}.plyr__menu .plyr__control[aria-expanded=true] svg{transform:rotate(90deg)}.plyr__menu .plyr__control[aria-expanded=true] .plyr__tooltip{display:none}.plyr__menu__container{animation:plyr-popup .2s ease;background:rgba(255,255,255,.9);border-radius:4px;bottom:100%;box-shadow:0 1px 2px rgba(0,0,0,.15);color:#4f5b5f;font-size:16px;margin-bottom:10px;position:absolute;right:-3px;text-align:left;white-space:nowrap;z-index:3}.plyr__menu__container>div{overflow:hidden;transition:height .35s cubic-bezier(.4,0,.2,1),width .35s cubic-bezier(.4,0,.2,1)}.plyr__menu__container::after{border:4px solid transparent;border-top-color:rgba(255,255,255,.9);content:'';height:0;position:absolute;right:15px;top:100%;width:0}.plyr__menu__container [role=menu]{padding:7px}.plyr__menu__container [role=menuitem],.plyr__menu__container [role=menuitemradio]{margin-top:2px}.plyr__menu__container [role=menuitem]:first-child,.plyr__menu__container [role=menuitemradio]:first-child{margin-top:0}.plyr__menu__container .plyr__control{align-items:center;color:#4f5b5f;display:flex;font-size:14px;padding:4px 11px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%}.plyr__menu__container .plyr__control>span{align-items:inherit;display:flex;width:100%}.plyr__menu__container .plyr__control::after{border:4px solid transparent;content:'';position:absolute;top:50%;transform:translateY(-50%)}.plyr__menu__container .plyr__control--forward{padding-right:28px}.plyr__menu__container .plyr__control--forward::after{border-left-color:rgba(79,91,95,.8);right:5px}.plyr__menu__container .plyr__control--forward.plyr__tab-focus::after,.plyr__menu__container .plyr__control--forward:hover::after{border-left-color:currentColor}.plyr__menu__container .plyr__control--back{font-weight:500;margin:7px;margin-bottom:3px;padding-left:28px;position:relative;width:calc(100% - 14px)}.plyr__menu__container .plyr__control--back::after{border-right-color:rgba(79,91,95,.8);left:7px}.plyr__menu__container .plyr__control--back::before{background:#b7c5cd;box-shadow:0 1px 0 #fff;content:'';height:1px;left:0;margin-top:4px;overflow:hidden;position:absolute;right:0;top:100%}.plyr__menu__container .plyr__control--back.plyr__tab-focus::after,.plyr__menu__container .plyr__control--back:hover::after{border-right-color:currentColor}.plyr__menu__container .plyr__control[role=menuitemradio]{padding-left:7px}.plyr__menu__container .plyr__control[role=menuitemradio]::after,.plyr__menu__container .plyr__control[role=menuitemradio]::before{border-radius:100%}.plyr__menu__container .plyr__control[role=menuitemradio]::before{background:rgba(0,0,0,.1);content:'';display:block;flex-shrink:0;height:16px;margin-right:10px;transition:all .3s ease;width:16px}.plyr__menu__container .plyr__control[role=menuitemradio]::after{background:#fff;border:0;height:6px;left:12px;opacity:0;top:50%;transform:translateY(-50%) scale(0);transition:transform .3s ease,opacity .3s ease;width:6px}.plyr__menu__container .plyr__control[role=menuitemradio][aria-checked=true]::before{background:#1aafff}.plyr__menu__container .plyr__control[role=menuitemradio][aria-checked=true]::after{opacity:1;transform:translateY(-50%) scale(1)}.plyr__menu__container .plyr__control[role=menuitemradio].plyr__tab-focus::before,.plyr__menu__container .plyr__control[role=menuitemradio]:hover::before{background:rgba(0,0,0,.1)}.plyr__menu__container .plyr__menu__value{align-items:center;display:flex;margin-left:auto;margin-right:-5px;overflow:hidden;padding-left:25px;pointer-events:none}.plyr--full-ui input[type=range]{-webkit-appearance:none;background:0 0;border:0;border-radius:26px;color:#1aafff;display:block;height:19px;margin:0;padding:0;transition:box-shadow .3s ease;width:100%}.plyr--full-ui input[type=range]::-webkit-slider-runnable-track{background:0 0;border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;-webkit-user-select:none;user-select:none;background-image:linear-gradient(to right,currentColor var(--value,0),transparent var(--value,0))}.plyr--full-ui input[type=range]::-webkit-slider-thumb{background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2);height:13px;position:relative;transition:all .2s ease;width:13px;-webkit-appearance:none;margin-top:-4px}.plyr--full-ui input[type=range]::-moz-range-track{background:0 0;border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;-moz-user-select:none;user-select:none}.plyr--full-ui input[type=range]::-moz-range-thumb{background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2);height:13px;position:relative;transition:all .2s ease;width:13px}.plyr--full-ui input[type=range]::-moz-range-progress{background:currentColor;border-radius:2.5px;height:5px}.plyr--full-ui input[type=range]::-ms-track{background:0 0;border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;-ms-user-select:none;user-select:none;color:transparent}.plyr--full-ui input[type=range]::-ms-fill-upper{background:0 0;border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;-ms-user-select:none;user-select:none}.plyr--full-ui input[type=range]::-ms-fill-lower{background:0 0;border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;-ms-user-select:none;user-select:none;background:currentColor}.plyr--full-ui input[type=range]::-ms-thumb{background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2);height:13px;position:relative;transition:all .2s ease;width:13px;margin-top:0}.plyr--full-ui input[type=range]::-ms-tooltip{display:none}.plyr--full-ui input[type=range]:focus{outline:0}.plyr--full-ui input[type=range]::-moz-focus-outer{border:0}.plyr--full-ui input[type=range].plyr__tab-focus::-webkit-slider-runnable-track{box-shadow:0 0 0 5px rgba(26,175,255,.5);outline:0}.plyr--full-ui input[type=range].plyr__tab-focus::-moz-range-track{box-shadow:0 0 0 5px rgba(26,175,255,.5);outline:0}.plyr--full-ui input[type=range].plyr__tab-focus::-ms-track{box-shadow:0 0 0 5px rgba(26,175,255,.5);outline:0}.plyr--full-ui.plyr--video input[type=range]::-webkit-slider-runnable-track{background-color:rgba(255,255,255,.25)}.plyr--full-ui.plyr--video input[type=range]::-moz-range-track{background-color:rgba(255,255,255,.25)}.plyr--full-ui.plyr--video input[type=range]::-ms-track{background-color:rgba(255,255,255,.25)}.plyr--full-ui.plyr--video input[type=range]:active::-webkit-slider-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(255,255,255,.5)}.plyr--full-ui.plyr--video input[type=range]:active::-moz-range-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(255,255,255,.5)}.plyr--full-ui.plyr--video input[type=range]:active::-ms-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(255,255,255,.5)}.plyr--full-ui.plyr--audio input[type=range]::-webkit-slider-runnable-track{background-color:rgba(183,197,205,.66)}.plyr--full-ui.plyr--audio input[type=range]::-moz-range-track{background-color:rgba(183,197,205,.66)}.plyr--full-ui.plyr--audio input[type=range]::-ms-track{background-color:rgba(183,197,205,.66)}.plyr--full-ui.plyr--audio input[type=range]:active::-webkit-slider-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(0,0,0,.1)}.plyr--full-ui.plyr--audio input[type=range]:active::-moz-range-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(0,0,0,.1)}.plyr--full-ui.plyr--audio input[type=range]:active::-ms-thumb{box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(47,52,61,.2),0 0 0 3px rgba(0,0,0,.1)}.plyr__poster{background-color:#000;background-position:50% 50%;background-repeat:no-repeat;background-size:contain;height:100%;left:0;opacity:0;position:absolute;top:0;transition:opacity .2s ease;width:100%;z-index:1}.plyr--stopped.plyr__poster-enabled .plyr__poster{opacity:1}.plyr__time{font-size:14px}.plyr__time+.plyr__time::before{content:'\2044';margin-right:10px}@media (max-width:767px){.plyr__time+.plyr__time{display:none}}.plyr--video .plyr__time{text-shadow:0 1px 1px rgba(0,0,0,.15)}.plyr__tooltip{background:rgba(255,255,255,.9);border-radius:3px;bottom:100%;box-shadow:0 1px 2px rgba(0,0,0,.15);color:#4f5b5f;font-size:14px;font-weight:500;left:50%;line-height:1.3;margin-bottom:10px;opacity:0;padding:5px 7.5px;pointer-events:none;position:absolute;transform:translate(-50%,10px) scale(.8);transform-origin:50% 100%;transition:transform .2s .1s ease,opacity .2s .1s ease;white-space:nowrap;z-index:2}.plyr__tooltip::before{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(255,255,255,.9);bottom:-4px;content:'';height:0;left:50%;position:absolute;transform:translateX(-50%);width:0;z-index:2}.plyr .plyr__control.plyr__tab-focus .plyr__tooltip,.plyr .plyr__control:hover .plyr__tooltip,.plyr__tooltip--visible{opacity:1;transform:translate(-50%,0) scale(1)}.plyr .plyr__control:hover .plyr__tooltip{z-index:3}.plyr__controls>.plyr__control:first-child .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip{left:0;transform:translate(0,10px) scale(.8);transform-origin:0 100%}.plyr__controls>.plyr__control:first-child .plyr__tooltip::before,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip::before{left:16px}.plyr__controls>.plyr__control:last-child .plyr__tooltip{left:auto;right:0;transform:translate(0,10px) scale(.8);transform-origin:100% 100%}.plyr__controls>.plyr__control:last-child .plyr__tooltip::before{left:auto;right:16px;transform:translateX(50%)}.plyr__controls>.plyr__control:first-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control.plyr__tab-focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control:hover .plyr__tooltip,.plyr__controls>.plyr__control:first-child.plyr__tab-focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child:hover .plyr__tooltip,.plyr__controls>.plyr__control:last-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:last-child.plyr__tab-focus .plyr__tooltip,.plyr__controls>.plyr__control:last-child:hover .plyr__tooltip{transform:translate(0,0) scale(1)}.plyr--video{background:#000;overflow:hidden}.plyr--video.plyr--menu-open{overflow:visible}.plyr__video-wrapper{background:#000;border-radius:inherit;overflow:hidden;position:relative;z-index:0}.plyr__video-embed,.plyr__video-wrapper--fixed-ratio{height:0;padding-bottom:56.25%}.plyr__video-embed iframe,.plyr__video-wrapper--fixed-ratio video{border:0;height:100%;left:0;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%}.plyr--full-ui .plyr__video-embed>.plyr__video-embed__container{padding-bottom:240%;position:relative;transform:translateY(-38.28125%)}.plyr__progress{left:6.5px;margin-right:13px;position:relative}.plyr__progress input[type=range],.plyr__progress__buffer{margin-left:-6.5px;margin-right:-6.5px;width:calc(100% + 13px)}.plyr__progress input[type=range]{position:relative;z-index:2}.plyr__progress .plyr__tooltip{font-size:14px;left:0}.plyr__progress__buffer{-webkit-appearance:none;background:0 0;border:0;border-radius:100px;height:5px;left:0;margin-top:-2.5px;padding:0;position:absolute;top:50%}.plyr__progress__buffer::-webkit-progress-bar{background:0 0}.plyr__progress__buffer::-webkit-progress-value{background:currentColor;border-radius:100px;min-width:5px;transition:width .2s ease}.plyr__progress__buffer::-moz-progress-bar{background:currentColor;border-radius:100px;min-width:5px;transition:width .2s ease}.plyr__progress__buffer::-ms-fill{border-radius:100px;transition:width .2s ease}.plyr--video .plyr__progress__buffer{box-shadow:0 1px 1px rgba(0,0,0,.15);color:rgba(255,255,255,.25)}.plyr--audio .plyr__progress__buffer{color:rgba(183,197,205,.66)}.plyr--loading .plyr__progress__buffer{animation:plyr-progress 1s linear infinite;background-image:linear-gradient(-45deg,rgba(47,52,61,.6) 25%,transparent 25%,transparent 50%,rgba(47,52,61,.6) 50%,rgba(47,52,61,.6) 75%,transparent 75%,transparent);background-repeat:repeat-x;background-size:25px 25px;color:transparent}.plyr--video.plyr--loading .plyr__progress__buffer{background-color:rgba(255,255,255,.25)}.plyr--audio.plyr--loading .plyr__progress__buffer{background-color:rgba(183,197,205,.66)}.plyr__volume{align-items:center;display:flex;flex:1;position:relative}.plyr__volume input[type=range]{margin-left:5px;position:relative;z-index:2}@media (min-width:480px){.plyr__volume{max-width:90px}}@media (min-width:768px){.plyr__volume{max-width:110px}}.plyr--is-ios .plyr__volume{display:none!important}.plyr--is-ios.plyr--vimeo [data-plyr=mute]{display:none!important}.plyr:-webkit-full-screen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:-ms-fullscreen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:fullscreen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:-webkit-full-screen video{height:100%}.plyr:-ms-fullscreen video{height:100%}.plyr:fullscreen video{height:100%}.plyr:-webkit-full-screen .plyr__video-wrapper{height:100%;width:100%}.plyr:-ms-fullscreen .plyr__video-wrapper{height:100%;width:100%}.plyr:fullscreen .plyr__video-wrapper{height:100%;width:100%}.plyr:-webkit-full-screen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:-ms-fullscreen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:fullscreen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:-webkit-full-screen .plyr__control .icon--exit-fullscreen{display:block}.plyr:-ms-fullscreen .plyr__control .icon--exit-fullscreen{display:block}.plyr:fullscreen .plyr__control .icon--exit-fullscreen{display:block}.plyr:-webkit-full-screen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:-ms-fullscreen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:fullscreen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:-webkit-full-screen.plyr--hide-controls{cursor:none}.plyr:-ms-fullscreen.plyr--hide-controls{cursor:none}.plyr:fullscreen.plyr--hide-controls{cursor:none}@media (min-width:1024px){.plyr:-webkit-full-screen .plyr__captions{font-size:21px}.plyr:-ms-fullscreen .plyr__captions{font-size:21px}.plyr:fullscreen .plyr__captions{font-size:21px}}.plyr:-webkit-full-screen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:-webkit-full-screen video{height:100%}.plyr:-webkit-full-screen .plyr__video-wrapper{height:100%;width:100%}.plyr:-webkit-full-screen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:-webkit-full-screen .plyr__control .icon--exit-fullscreen{display:block}.plyr:-webkit-full-screen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:-webkit-full-screen.plyr--hide-controls{cursor:none}@media (min-width:1024px){.plyr:-webkit-full-screen .plyr__captions{font-size:21px}}.plyr:-moz-full-screen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:-moz-full-screen video{height:100%}.plyr:-moz-full-screen .plyr__video-wrapper{height:100%;width:100%}.plyr:-moz-full-screen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:-moz-full-screen .plyr__control .icon--exit-fullscreen{display:block}.plyr:-moz-full-screen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:-moz-full-screen.plyr--hide-controls{cursor:none}@media (min-width:1024px){.plyr:-moz-full-screen .plyr__captions{font-size:21px}}.plyr:-ms-fullscreen{background:#000;border-radius:0!important;height:100%;margin:0;width:100%}.plyr:-ms-fullscreen video{height:100%}.plyr:-ms-fullscreen .plyr__video-wrapper{height:100%;width:100%}.plyr:-ms-fullscreen.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr:-ms-fullscreen .plyr__control .icon--exit-fullscreen{display:block}.plyr:-ms-fullscreen .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr:-ms-fullscreen.plyr--hide-controls{cursor:none}@media (min-width:1024px){.plyr:-ms-fullscreen .plyr__captions{font-size:21px}}.plyr--fullscreen-fallback{background:#000;border-radius:0!important;height:100%;margin:0;width:100%;bottom:0;left:0;position:fixed;right:0;top:0;z-index:10000000}.plyr--fullscreen-fallback video{height:100%}.plyr--fullscreen-fallback .plyr__video-wrapper{height:100%;width:100%}.plyr--fullscreen-fallback.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)}.plyr--fullscreen-fallback .plyr__control .icon--exit-fullscreen{display:block}.plyr--fullscreen-fallback .plyr__control .icon--exit-fullscreen+svg{display:none}.plyr--fullscreen-fallback.plyr--hide-controls{cursor:none}@media (min-width:1024px){.plyr--fullscreen-fallback .plyr__captions{font-size:21px}}.plyr__ads{border-radius:inherit;bottom:0;cursor:pointer;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:-1}.plyr__ads>div,.plyr__ads>div iframe{height:100%;position:absolute;width:100%}.plyr__ads::after{background:rgba(47,52,61,.8);border-radius:2px;bottom:10px;color:#fff;content:attr(data-badge-text);font-size:11px;padding:2px 6px;pointer-events:none;position:absolute;right:10px;z-index:3}.plyr__ads::after:empty{display:none}.plyr__cues{background:currentColor;display:block;height:5px;left:0;margin:-2.5px 0 0;opacity:.8;position:absolute;top:50%;width:3px;z-index:3}.plyr__preview-thumb{background-color:rgba(255,255,255,.9);border-radius:3px;bottom:100%;box-shadow:0 1px 2px rgba(0,0,0,.15);margin-bottom:10px;opacity:0;padding:3px;pointer-events:none;position:absolute;transform:translate(0,10px) scale(.8);transform-origin:50% 100%;transition:transform .2s .1s ease,opacity .2s .1s ease;z-index:2}.plyr__preview-thumb--is-shown{opacity:1;transform:translate(0,0) scale(1)}.plyr__preview-thumb::before{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(255,255,255,.9);bottom:-4px;content:'';height:0;left:50%;position:absolute;transform:translateX(-50%);width:0;z-index:2}.plyr__preview-thumb__image-container{background:#b7c5cd;border-radius:2px;overflow:hidden;position:relative;z-index:0}.plyr__preview-thumb__image-container img{height:100%;left:0;max-height:none;max-width:none;position:absolute;top:0;width:100%}.plyr__preview-thumb__time-container{bottom:6px;left:0;position:absolute;right:0;white-space:nowrap;z-index:3}.plyr__preview-thumb__time-container span{background-color:rgba(0,0,0,.55);border-radius:2px;color:#fff;font-size:14px;padding:3px 6px}.plyr__preview-scrubbing{bottom:0;filter:blur(1px);height:100%;left:0;margin:auto;opacity:0;overflow:hidden;position:absolute;right:0;top:0;transition:opacity .3s ease;width:100%;z-index:1}.plyr__preview-scrubbing--is-shown{opacity:1}.plyr__preview-scrubbing img{height:100%;left:0;max-height:none;max-width:none;-o-object-fit:contain;object-fit:contain;position:absolute;top:0;width:100%}.plyr--no-transition{transition:none!important}.plyr__sr-only{clip:rect(1px,1px,1px,1px);overflow:hidden;border:0!important;height:1px!important;padding:0!important;position:absolute!important;width:1px!important}.plyr [hidden]{display:none!important} \ No newline at end of file diff --git a/ajax/libs/plyr/3.5.4/plyr.js b/ajax/libs/plyr/3.5.4/plyr.js new file mode 100644 index 00000000000000..9e7a047a3ca9a6 --- /dev/null +++ b/ajax/libs/plyr/3.5.4/plyr.js @@ -0,0 +1,9137 @@ +typeof navigator === "object" && (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define('Plyr', factory) : + (global = global || self, global.Plyr = factory()); +}(this, function () { 'use strict'; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + + var defaults = { + addCSS: true, + // Add CSS to the element to improve usability (required here or in your CSS!) + thumbWidth: 15, + // The width of the thumb handle + watch: true // Watch for new elements that match a string target + + }; + + // Element matches a selector + function matches(element, selector) { + + function match() { + return Array.from(document.querySelectorAll(selector)).includes(this); + } + + var matches = match; + return matches.call(element, selector); + } + + // Trigger event + function trigger(element, type) { + if (!element || !type) { + return; + } // Create and dispatch the event + + + var event = new Event(type); // Dispatch the event + + element.dispatchEvent(event); + } + + // ========================================================================== + // Type checking utils + // ========================================================================== + var getConstructor = function getConstructor(input) { + return input !== null && typeof input !== 'undefined' ? input.constructor : null; + }; + + var instanceOf = function instanceOf(input, constructor) { + return Boolean(input && constructor && input instanceof constructor); + }; + + var isNullOrUndefined = function isNullOrUndefined(input) { + return input === null || typeof input === 'undefined'; + }; + + var isObject = function isObject(input) { + return getConstructor(input) === Object; + }; + + var isNumber = function isNumber(input) { + return getConstructor(input) === Number && !Number.isNaN(input); + }; + + var isString = function isString(input) { + return getConstructor(input) === String; + }; + + var isBoolean = function isBoolean(input) { + return getConstructor(input) === Boolean; + }; + + var isFunction = function isFunction(input) { + return getConstructor(input) === Function; + }; + + var isArray = function isArray(input) { + return Array.isArray(input); + }; + + var isNodeList = function isNodeList(input) { + return instanceOf(input, NodeList); + }; + + var isElement = function isElement(input) { + return instanceOf(input, Element); + }; + + var isEvent = function isEvent(input) { + return instanceOf(input, Event); + }; + + var isEmpty = function isEmpty(input) { + return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length; + }; + + var is = { + nullOrUndefined: isNullOrUndefined, + object: isObject, + number: isNumber, + string: isString, + boolean: isBoolean, + function: isFunction, + array: isArray, + nodeList: isNodeList, + element: isElement, + event: isEvent, + empty: isEmpty + }; + + // Get the number of decimal places + function getDecimalPlaces(value) { + var match = "".concat(value).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); + + if (!match) { + return 0; + } + + return Math.max(0, // Number of digits right of decimal point. + (match[1] ? match[1].length : 0) - ( // Adjust for scientific notation. + match[2] ? +match[2] : 0)); + } // Round to the nearest step + + function round(number, step) { + if (step < 1) { + var places = getDecimalPlaces(step); + return parseFloat(number.toFixed(places)); + } + + return Math.round(number / step) * step; + } + + var RangeTouch = + /*#__PURE__*/ + function () { + /** + * Setup a new instance + * @param {String|Element} target + * @param {Object} options + */ + function RangeTouch(target, options) { + _classCallCheck(this, RangeTouch); + + if (is.element(target)) { + // An Element is passed, use it directly + this.element = target; + } else if (is.string(target)) { + // A CSS Selector is passed, fetch it from the DOM + this.element = document.querySelector(target); + } + + if (!is.element(this.element) || !is.empty(this.element.rangeTouch)) { + return; + } + + this.config = Object.assign({}, defaults, options); + this.init(); + } + + _createClass(RangeTouch, [{ + key: "init", + value: function init() { + // Bail if not a touch enabled device + if (!RangeTouch.enabled) { + return; + } // Add useful CSS + + + if (this.config.addCSS) { + // TODO: Restore original values on destroy + this.element.style.userSelect = 'none'; + this.element.style.webKitUserSelect = 'none'; + this.element.style.touchAction = 'manipulation'; + } + + this.listeners(true); + this.element.rangeTouch = this; + } + }, { + key: "destroy", + value: function destroy() { + // Bail if not a touch enabled device + if (!RangeTouch.enabled) { + return; + } + + this.listeners(false); + this.element.rangeTouch = null; + } + }, { + key: "listeners", + value: function listeners(toggle) { + var _this = this; + + var method = toggle ? 'addEventListener' : 'removeEventListener'; // Listen for events + + ['touchstart', 'touchmove', 'touchend'].forEach(function (type) { + _this.element[method](type, function (event) { + return _this.set(event); + }, false); + }); + } + /** + * Get the value based on touch position + * @param {Event} event + */ + + }, { + key: "get", + value: function get(event) { + if (!RangeTouch.enabled || !is.event(event)) { + return null; + } + + var input = event.target; + var touch = event.changedTouches[0]; + var min = parseFloat(input.getAttribute('min')) || 0; + var max = parseFloat(input.getAttribute('max')) || 100; + var step = parseFloat(input.getAttribute('step')) || 1; + var delta = max - min; // Calculate percentage + + var percent; + var clientRect = input.getBoundingClientRect(); + var thumbWidth = 100 / clientRect.width * (this.config.thumbWidth / 2) / 100; // Determine left percentage + + percent = 100 / clientRect.width * (touch.clientX - clientRect.left); // Don't allow outside bounds + + if (percent < 0) { + percent = 0; + } else if (percent > 100) { + percent = 100; + } // Factor in the thumb offset + + + if (percent < 50) { + percent -= (100 - percent * 2) * thumbWidth; + } else if (percent > 50) { + percent += (percent - 50) * 2 * thumbWidth; + } // Find the closest step to the mouse position + + + return min + round(delta * (percent / 100), step); + } + /** + * Update range value based on position + * @param {Event} event + */ + + }, { + key: "set", + value: function set(event) { + if (!RangeTouch.enabled || !is.event(event) || event.target.disabled) { + return; + } // Prevent text highlight on iOS + + + event.preventDefault(); // Set value + + event.target.value = this.get(event); // Trigger event + + trigger(event.target, event.type === 'touchend' ? 'change' : 'input'); + } + }], [{ + key: "setup", + + /** + * Setup multiple instances + * @param {String|Element|NodeList|Array} target + * @param {Object} options + */ + value: function setup(target) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var targets = null; + + if (is.empty(target) || is.string(target)) { + targets = Array.from(document.querySelectorAll(is.string(target) ? target : 'input[type="range"]')); + } else if (is.element(target)) { + targets = [target]; + } else if (is.nodeList(target)) { + targets = Array.from(target); + } else if (is.array(target)) { + targets = target.filter(is.element); + } + + if (is.empty(targets)) { + return null; + } + + var config = Object.assign({}, defaults, options); + + if (is.string(target) && config.watch) { + // Create an observer instance + var observer = new MutationObserver(function (mutations) { + Array.from(mutations).forEach(function (mutation) { + Array.from(mutation.addedNodes).forEach(function (node) { + if (!is.element(node) || !matches(node, target)) { + return; + } // eslint-disable-next-line no-unused-vars + + + var range = new RangeTouch(node, config); + }); + }); + }); // Pass in the target node, as well as the observer options + + observer.observe(document.body, { + childList: true, + subtree: true + }); + } + + return targets.map(function (t) { + return new RangeTouch(t, options); + }); + } + }, { + key: "enabled", + get: function get() { + return 'ontouchstart' in document.documentElement; + } + }]); + + return RangeTouch; + }(); + + // ========================================================================== + // Type checking utils + // ========================================================================== + var getConstructor$1 = function getConstructor(input) { + return input !== null && typeof input !== 'undefined' ? input.constructor : null; + }; + + var instanceOf$1 = function instanceOf(input, constructor) { + return Boolean(input && constructor && input instanceof constructor); + }; + + var isNullOrUndefined$1 = function isNullOrUndefined(input) { + return input === null || typeof input === 'undefined'; + }; + + var isObject$1 = function isObject(input) { + return getConstructor$1(input) === Object; + }; + + var isNumber$1 = function isNumber(input) { + return getConstructor$1(input) === Number && !Number.isNaN(input); + }; + + var isString$1 = function isString(input) { + return getConstructor$1(input) === String; + }; + + var isBoolean$1 = function isBoolean(input) { + return getConstructor$1(input) === Boolean; + }; + + var isFunction$1 = function isFunction(input) { + return getConstructor$1(input) === Function; + }; + + var isArray$1 = function isArray(input) { + return Array.isArray(input); + }; + + var isWeakMap = function isWeakMap(input) { + return instanceOf$1(input, WeakMap); + }; + + var isNodeList$1 = function isNodeList(input) { + return instanceOf$1(input, NodeList); + }; + + var isElement$1 = function isElement(input) { + return instanceOf$1(input, Element); + }; + + var isTextNode = function isTextNode(input) { + return getConstructor$1(input) === Text; + }; + + var isEvent$1 = function isEvent(input) { + return instanceOf$1(input, Event); + }; + + var isKeyboardEvent = function isKeyboardEvent(input) { + return instanceOf$1(input, KeyboardEvent); + }; + + var isCue = function isCue(input) { + return instanceOf$1(input, window.TextTrackCue) || instanceOf$1(input, window.VTTCue); + }; + + var isTrack = function isTrack(input) { + return instanceOf$1(input, TextTrack) || !isNullOrUndefined$1(input) && isString$1(input.kind); + }; + + var isPromise = function isPromise(input) { + return instanceOf$1(input, Promise); + }; + + var isEmpty$1 = function isEmpty(input) { + return isNullOrUndefined$1(input) || (isString$1(input) || isArray$1(input) || isNodeList$1(input)) && !input.length || isObject$1(input) && !Object.keys(input).length; + }; + + var isUrl = function isUrl(input) { + // Accept a URL object + if (instanceOf$1(input, window.URL)) { + return true; + } // Must be string from here + + + if (!isString$1(input)) { + return false; + } // Add the protocol if required + + + var string = input; + + if (!input.startsWith('http://') || !input.startsWith('https://')) { + string = "http://".concat(input); + } + + try { + return !isEmpty$1(new URL(string).hostname); + } catch (e) { + return false; + } + }; + + var is$1 = { + nullOrUndefined: isNullOrUndefined$1, + object: isObject$1, + number: isNumber$1, + string: isString$1, + boolean: isBoolean$1, + function: isFunction$1, + array: isArray$1, + weakMap: isWeakMap, + nodeList: isNodeList$1, + element: isElement$1, + textNode: isTextNode, + event: isEvent$1, + keyboardEvent: isKeyboardEvent, + cue: isCue, + track: isTrack, + promise: isPromise, + url: isUrl, + empty: isEmpty$1 + }; + + // ========================================================================== + // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md + // https://www.youtube.com/watch?v=NPM6172J22g + + var supportsPassiveListeners = function () { + // Test via a getter in the options object to see if the passive property is accessed + var supported = false; + + try { + var options = Object.defineProperty({}, 'passive', { + get: function get() { + supported = true; + return null; + } + }); + window.addEventListener('test', null, options); + window.removeEventListener('test', null, options); + } catch (e) {// Do nothing + } + + return supported; + }(); // Toggle event listener + + + function toggleListener(element, event, callback) { + var _this = this; + + var toggle = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var capture = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; + + // Bail if no element, event, or callback + if (!element || !('addEventListener' in element) || is$1.empty(event) || !is$1.function(callback)) { + return; + } // Allow multiple events + + + var events = event.split(' '); // Build options + // Default to just the capture boolean for browsers with no passive listener support + + var options = capture; // If passive events listeners are supported + + if (supportsPassiveListeners) { + options = { + // Whether the listener can be passive (i.e. default never prevented) + passive: passive, + // Whether the listener is a capturing listener or not + capture: capture + }; + } // If a single node is passed, bind the event listener + + + events.forEach(function (type) { + if (_this && _this.eventListeners && toggle) { + // Cache event listener + _this.eventListeners.push({ + element: element, + type: type, + callback: callback, + options: options + }); + } + + element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options); + }); + } // Bind event handler + + function on(element) { + var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var callback = arguments.length > 2 ? arguments[2] : undefined; + var passive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + toggleListener.call(this, element, events, callback, true, passive, capture); + } // Unbind event handler + + function off(element) { + var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var callback = arguments.length > 2 ? arguments[2] : undefined; + var passive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + toggleListener.call(this, element, events, callback, false, passive, capture); + } // Bind once-only event handler + + function once(element) { + var _this2 = this; + + var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var callback = arguments.length > 2 ? arguments[2] : undefined; + var passive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + var onceCallback = function onceCallback() { + off(element, events, onceCallback, passive, capture); + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + callback.apply(_this2, args); + }; + + toggleListener.call(this, element, events, onceCallback, true, passive, capture); + } // Trigger event + + function triggerEvent(element) { + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var bubbles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var detail = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + // Bail if no element + if (!is$1.element(element) || is$1.empty(type)) { + return; + } // Create and dispatch the event + + + var event = new CustomEvent(type, { + bubbles: bubbles, + detail: Object.assign({}, detail, { + plyr: this + }) + }); // Dispatch the event + + element.dispatchEvent(event); + } // Unbind all cached event listeners + + function unbindListeners() { + if (this && this.eventListeners) { + this.eventListeners.forEach(function (item) { + var element = item.element, + type = item.type, + callback = item.callback, + options = item.options; + element.removeEventListener(type, callback, options); + }); + this.eventListeners = []; + } + } // Run method when / if player is ready + + function ready() { + var _this3 = this; + + return new Promise(function (resolve) { + return _this3.ready ? setTimeout(resolve, 0) : on.call(_this3, _this3.elements.container, 'ready', resolve); + }).then(function () {}); + } + + function cloneDeep(object) { + return JSON.parse(JSON.stringify(object)); + } // Get a nested value in an object + + function getDeep(object, path) { + return path.split('.').reduce(function (obj, key) { + return obj && obj[key]; + }, object); + } // Deep extend destination object with N more objects + + function extend() { + var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (!sources.length) { + return target; + } + + var source = sources.shift(); + + if (!is$1.object(source)) { + return target; + } + + Object.keys(source).forEach(function (key) { + if (is$1.object(source[key])) { + if (!Object.keys(target).includes(key)) { + Object.assign(target, _defineProperty({}, key, {})); + } + + extend(target[key], source[key]); + } else { + Object.assign(target, _defineProperty({}, key, source[key])); + } + }); + return extend.apply(void 0, [target].concat(sources)); + } + + function wrap(elements, wrapper) { + // Convert `elements` to an array, if necessary. + var targets = elements.length ? elements : [elements]; // Loops backwards to prevent having to clone the wrapper on the + // first element (see `child` below). + + Array.from(targets).reverse().forEach(function (element, index) { + var child = index > 0 ? wrapper.cloneNode(true) : wrapper; // Cache the current parent and sibling. + + var parent = element.parentNode; + var sibling = element.nextSibling; // Wrap the element (is automatically removed from its current + // parent). + + child.appendChild(element); // If the element had a sibling, insert the wrapper before + // the sibling to maintain the HTML structure; otherwise, just + // append it to the parent. + + if (sibling) { + parent.insertBefore(child, sibling); + } else { + parent.appendChild(child); + } + }); + } // Set attributes + + function setAttributes(element, attributes) { + if (!is$1.element(element) || is$1.empty(attributes)) { + return; + } // Assume null and undefined attributes should be left out, + // Setting them would otherwise convert them to "null" and "undefined" + + + Object.entries(attributes).filter(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + value = _ref2[1]; + + return !is$1.nullOrUndefined(value); + }).forEach(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + key = _ref4[0], + value = _ref4[1]; + + return element.setAttribute(key, value); + }); + } // Create a DocumentFragment + + function createElement(type, attributes, text) { + // Create a new + var element = document.createElement(type); // Set all passed attributes + + if (is$1.object(attributes)) { + setAttributes(element, attributes); + } // Add text node + + + if (is$1.string(text)) { + element.innerText = text; + } // Return built element + + + return element; + } // Inaert an element after another + + function insertAfter(element, target) { + if (!is$1.element(element) || !is$1.element(target)) { + return; + } + + target.parentNode.insertBefore(element, target.nextSibling); + } // Insert a DocumentFragment + + function insertElement(type, parent, attributes, text) { + if (!is$1.element(parent)) { + return; + } + + parent.appendChild(createElement(type, attributes, text)); + } // Remove element(s) + + function removeElement(element) { + if (is$1.nodeList(element) || is$1.array(element)) { + Array.from(element).forEach(removeElement); + return; + } + + if (!is$1.element(element) || !is$1.element(element.parentNode)) { + return; + } + + element.parentNode.removeChild(element); + } // Remove all child elements + + function emptyElement(element) { + if (!is$1.element(element)) { + return; + } + + var length = element.childNodes.length; + + while (length > 0) { + element.removeChild(element.lastChild); + length -= 1; + } + } // Replace element + + function replaceElement(newChild, oldChild) { + if (!is$1.element(oldChild) || !is$1.element(oldChild.parentNode) || !is$1.element(newChild)) { + return null; + } + + oldChild.parentNode.replaceChild(newChild, oldChild); + return newChild; + } // Get an attribute object from a string selector + + function getAttributesFromSelector(sel, existingAttributes) { + // For example: + // '.test' to { class: 'test' } + // '#test' to { id: 'test' } + // '[data-test="test"]' to { 'data-test': 'test' } + if (!is$1.string(sel) || is$1.empty(sel)) { + return {}; + } + + var attributes = {}; + var existing = extend({}, existingAttributes); + sel.split(',').forEach(function (s) { + // Remove whitespace + var selector = s.trim(); + var className = selector.replace('.', ''); + var stripped = selector.replace(/[[\]]/g, ''); // Get the parts and value + + var parts = stripped.split('='); + + var _parts = _slicedToArray(parts, 1), + key = _parts[0]; + + var value = parts.length > 1 ? parts[1].replace(/["']/g, '') : ''; // Get the first character + + var start = selector.charAt(0); + + switch (start) { + case '.': + // Add to existing classname + if (is$1.string(existing.class)) { + attributes.class = "".concat(existing.class, " ").concat(className); + } else { + attributes.class = className; + } + + break; + + case '#': + // ID selector + attributes.id = selector.replace('#', ''); + break; + + case '[': + // Attribute selector + attributes[key] = value; + break; + + default: + break; + } + }); + return extend(existing, attributes); + } // Toggle hidden + + function toggleHidden(element, hidden) { + if (!is$1.element(element)) { + return; + } + + var hide = hidden; + + if (!is$1.boolean(hide)) { + hide = !element.hidden; + } + + if (hide) { + element.setAttribute('hidden', ''); + } else { + element.removeAttribute('hidden'); + } + } // Mirror Element.classList.toggle, with IE compatibility for "force" argument + + function toggleClass(element, className, force) { + if (is$1.nodeList(element)) { + return Array.from(element).map(function (e) { + return toggleClass(e, className, force); + }); + } + + if (is$1.element(element)) { + var method = 'toggle'; + + if (typeof force !== 'undefined') { + method = force ? 'add' : 'remove'; + } + + element.classList[method](className); + return element.classList.contains(className); + } + + return false; + } // Has class name + + function hasClass(element, className) { + return is$1.element(element) && element.classList.contains(className); + } // Element matches selector + + function matches$1(element, selector) { + + function match() { + return Array.from(document.querySelectorAll(selector)).includes(this); + } + + var matches = match; + return matches.call(element, selector); + } // Find all elements + + function getElements(selector) { + return this.elements.container.querySelectorAll(selector); + } // Find a single element + + function getElement(selector) { + return this.elements.container.querySelector(selector); + } // Trap focus inside container + + function trapFocus() { + var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!is$1.element(element)) { + return; + } + + var focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]'); + var first = focusable[0]; + var last = focusable[focusable.length - 1]; + + var trap = function trap(event) { + // Bail if not tab key or not fullscreen + if (event.key !== 'Tab' || event.keyCode !== 9) { + return; + } // Get the current focused element + + + var focused = document.activeElement; + + if (focused === last && !event.shiftKey) { + // Move focus to first element that can be tabbed if Shift isn't used + first.focus(); + event.preventDefault(); + } else if (focused === first && event.shiftKey) { + // Move focus to last element that can be tabbed if Shift is used + last.focus(); + event.preventDefault(); + } + }; + + toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false); + } // Set focus and tab focus class + + function setFocus() { + var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var tabFocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!is$1.element(element)) { + return; + } // Set regular focus + + + element.focus({ + preventScroll: true + }); // If we want to mimic keyboard focus via tab + + if (tabFocus) { + toggleClass(element, this.config.classNames.tabFocus); + } + } + + // ========================================================================== + var transitionEndEvent = function () { + var element = document.createElement('span'); + var events = { + WebkitTransition: 'webkitTransitionEnd', + MozTransition: 'transitionend', + OTransition: 'oTransitionEnd otransitionend', + transition: 'transitionend' + }; + var type = Object.keys(events).find(function (event) { + return element.style[event] !== undefined; + }); + return is$1.string(type) ? events[type] : false; + }(); // Force repaint of element + + function repaint(element) { + setTimeout(function () { + try { + toggleHidden(element, true); + element.offsetHeight; // eslint-disable-line + + toggleHidden(element, false); + } catch (e) {// Do nothing + } + }, 0); + } + + // ========================================================================== + // Browser sniffing + // Unfortunately, due to mixed support, UA sniffing is required + // ========================================================================== + var browser = { + isIE: + /* @cc_on!@ */ + !!document.documentMode, + isEdge: window.navigator.userAgent.includes('Edge'), + isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent), + isIPhone: /(iPhone|iPod)/gi.test(navigator.platform), + isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform) + }; + + var defaultCodecs = { + 'audio/ogg': 'vorbis', + 'audio/wav': '1', + 'video/webm': 'vp8, vorbis', + 'video/mp4': 'avc1.42E01E, mp4a.40.2', + 'video/ogg': 'theora' + }; // Check for feature support + + var support = { + // Basic support + audio: 'canPlayType' in document.createElement('audio'), + video: 'canPlayType' in document.createElement('video'), + // Check for support + // Basic functionality vs full UI + check: function check(type, provider, playsinline) { + var canPlayInline = browser.isIPhone && playsinline && support.playsinline; + var api = support[type] || provider !== 'html5'; + var ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline); + return { + api: api, + ui: ui + }; + }, + // Picture-in-picture support + // Safari & Chrome only currently + pip: function () { + if (browser.isIPhone) { + return false; + } // Safari + // https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls + + + if (is$1.function(createElement('video').webkitSetPresentationMode)) { + return true; + } // Chrome + // https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture + + + if (document.pictureInPictureEnabled && !createElement('video').disablePictureInPicture) { + return true; + } + + return false; + }(), + // Airplay support + // Safari only currently + airplay: is$1.function(window.WebKitPlaybackTargetAvailabilityEvent), + // Inline playback support + // https://webkit.org/blog/6784/new-video-policies-for-ios/ + playsinline: 'playsInline' in document.createElement('video'), + // Check for mime type support against a player instance + // Credits: http://diveintohtml5.info/everything.html + // Related: http://www.leanbackplayer.com/test/h5mt.html + mime: function mime(input) { + if (is$1.empty(input)) { + return false; + } + + var _input$split = input.split('/'), + _input$split2 = _slicedToArray(_input$split, 1), + mediaType = _input$split2[0]; + + var type = input; // Verify we're using HTML5 and there's no media type mismatch + + if (!this.isHTML5 || mediaType !== this.type) { + return false; + } // Add codec if required + + + if (Object.keys(defaultCodecs).includes(type)) { + type += "; codecs=\"".concat(defaultCodecs[input], "\""); + } + + try { + return Boolean(type && this.media.canPlayType(type).replace(/no/, '')); + } catch (e) { + return false; + } + }, + // Check for textTracks support + textTracks: 'textTracks' in document.createElement('video'), + // Sliders + rangeInput: function () { + var range = document.createElement('input'); + range.type = 'range'; + return range.type === 'range'; + }(), + // Touch + // NOTE: Remember a device can be mouse + touch enabled so we check on first touch event + touch: 'ontouchstart' in document.documentElement, + // Detect transitions support + transitions: transitionEndEvent !== false, + // Reduced motion iOS & MacOS setting + // https://webkit.org/blog/7551/responsive-design-for-motion/ + reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches + }; + + function validateRatio(input) { + if (!is$1.array(input) && (!is$1.string(input) || !input.includes(':'))) { + return false; + } + + var ratio = is$1.array(input) ? input : input.split(':'); + return ratio.map(Number).every(is$1.number); + } + function reduceAspectRatio(ratio) { + if (!is$1.array(ratio) || !ratio.every(is$1.number)) { + return null; + } + + var _ratio = _slicedToArray(ratio, 2), + width = _ratio[0], + height = _ratio[1]; + + var getDivider = function getDivider(w, h) { + return h === 0 ? w : getDivider(h, w % h); + }; + + var divider = getDivider(width, height); + return [width / divider, height / divider]; + } + function getAspectRatio(input) { + var parse = function parse(ratio) { + if (!validateRatio(ratio)) { + return null; + } + + return ratio.split(':').map(Number); + }; // Provided ratio + + + var ratio = parse(input); // Get from config + + if (ratio === null) { + ratio = parse(this.config.ratio); + } // Get from embed + + + if (ratio === null && !is$1.empty(this.embed) && is$1.array(this.embed.ratio)) { + ratio = this.embed.ratio; + } // Get from HTML5 video + + + if (ratio === null && this.isHTML5) { + var _this$media = this.media, + videoWidth = _this$media.videoWidth, + videoHeight = _this$media.videoHeight; + ratio = reduceAspectRatio([videoWidth, videoHeight]); + } + + return ratio; + } // Set aspect ratio for responsive container + + function setAspectRatio(input) { + if (!this.isVideo) { + return {}; + } + + var ratio = getAspectRatio.call(this, input); + + var _ref = is$1.array(ratio) ? ratio : [0, 0], + _ref2 = _slicedToArray(_ref, 2), + w = _ref2[0], + h = _ref2[1]; + + var padding = 100 / w * h; + this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra
to hide the standard controls and UI + + if (this.isVimeo && this.supported.ui) { + var height = 240; + var offset = (height - padding) / (height / 50); + this.media.style.transform = "translateY(-".concat(offset, "%)"); + } else if (this.isHTML5) { + this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); + } + + return { + padding: padding, + ratio: ratio + }; + } + + // ========================================================================== + var html5 = { + getSources: function getSources() { + var _this = this; + + if (!this.isHTML5) { + return []; + } + + var sources = Array.from(this.media.querySelectorAll('source')); // Filter out unsupported sources (if type is specified) + + return sources.filter(function (source) { + var type = source.getAttribute('type'); + + if (is$1.empty(type)) { + return true; + } + + return support.mime.call(_this, type); + }); + }, + // Get quality levels + getQualityOptions: function getQualityOptions() { + // Get sizes from elements + return html5.getSources.call(this).map(function (source) { + return Number(source.getAttribute('size')); + }).filter(Boolean); + }, + extend: function extend() { + if (!this.isHTML5) { + return; + } + + var player = this; // Set aspect ratio if set + + setAspectRatio.call(player); // Quality + + Object.defineProperty(player.media, 'quality', { + get: function get() { + // Get sources + var sources = html5.getSources.call(player); + var source = sources.find(function (source) { + return source.getAttribute('src') === player.source; + }); // Return size, if match is found + + return source && Number(source.getAttribute('size')); + }, + set: function set(input) { + // Get sources + var sources = html5.getSources.call(player); // Get first match for requested size + + var source = sources.find(function (source) { + return Number(source.getAttribute('size')) === input; + }); // No matching source found + + if (!source) { + return; + } // Get current state + + + var _player$media = player.media, + currentTime = _player$media.currentTime, + paused = _player$media.paused, + preload = _player$media.preload, + readyState = _player$media.readyState; // Set new source + + player.media.src = source.getAttribute('src'); // Prevent loading if preload="none" and the current source isn't loaded (#1044) + + if (preload !== 'none' || readyState) { + // Restore time + player.once('loadedmetadata', function () { + player.currentTime = currentTime; // Resume playing + + if (!paused) { + player.play(); + } + }); // Load new source + + player.media.load(); + } // Trigger change event + + + triggerEvent.call(player, player.media, 'qualitychange', false, { + quality: input + }); + } + }); + }, + // Cancel current network requests + // See https://github.com/sampotts/plyr/issues/174 + cancelRequests: function cancelRequests() { + if (!this.isHTML5) { + return; + } // Remove child sources + + + removeElement(html5.getSources.call(this)); // Set blank video src attribute + // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error + // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection + + this.media.setAttribute('src', this.config.blankVideo); // Load the new empty source + // This will cancel existing requests + // See https://github.com/sampotts/plyr/issues/174 + + this.media.load(); // Debugging + + this.debug.log('Cancelled network requests'); + } + }; + + // ========================================================================== + + function dedupe(array) { + if (!is$1.array(array)) { + return array; + } + + return array.filter(function (item, index) { + return array.indexOf(item) === index; + }); + } // Get the closest value in an array + + function closest(array, value) { + if (!is$1.array(array) || !array.length) { + return null; + } + + return array.reduce(function (prev, curr) { + return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev; + }); + } + + // ========================================================================== + + function generateId(prefix) { + return "".concat(prefix, "-").concat(Math.floor(Math.random() * 10000)); + } // Format string + + function format(input) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (is$1.empty(input)) { + return input; + } + + return input.toString().replace(/{(\d+)}/g, function (match, i) { + return args[i].toString(); + }); + } // Get percentage + + function getPercentage(current, max) { + if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) { + return 0; + } + + return (current / max * 100).toFixed(2); + } // Replace all occurances of a string in a string + + function replaceAll() { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var find = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var replace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + return input.replace(new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1'), 'g'), replace.toString()); + } // Convert to title case + + function toTitleCase() { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return input.toString().replace(/\w\S*/g, function (text) { + return text.charAt(0).toUpperCase() + text.substr(1).toLowerCase(); + }); + } // Convert string to pascalCase + + function toPascalCase() { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var string = input.toString(); // Convert kebab case + + string = replaceAll(string, '-', ' '); // Convert snake case + + string = replaceAll(string, '_', ' '); // Convert to title case + + string = toTitleCase(string); // Convert to pascal case + + return replaceAll(string, ' ', ''); + } // Convert string to pascalCase + + function toCamelCase() { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var string = input.toString(); // Convert to pascal case + + string = toPascalCase(string); // Convert first character to lowercase + + return string.charAt(0).toLowerCase() + string.slice(1); + } // Remove HTML from a string + + function stripHTML(source) { + var fragment = document.createDocumentFragment(); + var element = document.createElement('div'); + fragment.appendChild(element); + element.innerHTML = source; + return fragment.firstChild.innerText; + } // Like outerHTML, but also works for DocumentFragment + + function getHTML(element) { + var wrapper = document.createElement('div'); + wrapper.appendChild(element); + return wrapper.innerHTML; + } + + var resources = { + pip: 'PIP', + airplay: 'AirPlay', + html5: 'HTML5', + vimeo: 'Vimeo', + youtube: 'YouTube' + }; + var i18n = { + get: function get() { + var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (is$1.empty(key) || is$1.empty(config)) { + return ''; + } + + var string = getDeep(config.i18n, key); + + if (is$1.empty(string)) { + if (Object.keys(resources).includes(key)) { + return resources[key]; + } + + return ''; + } + + var replace = { + '{seektime}': config.seekTime, + '{title}': config.title + }; + Object.entries(replace).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + string = replaceAll(string, key, value); + }); + return string; + } + }; + + var Storage = + /*#__PURE__*/ + function () { + function Storage(player) { + _classCallCheck(this, Storage); + + this.enabled = player.config.storage.enabled; + this.key = player.config.storage.key; + } // Check for actual support (see if we can use it) + + + _createClass(Storage, [{ + key: "get", + value: function get(key) { + if (!Storage.supported || !this.enabled) { + return null; + } + + var store = window.localStorage.getItem(this.key); + + if (is$1.empty(store)) { + return null; + } + + var json = JSON.parse(store); + return is$1.string(key) && key.length ? json[key] : json; + } + }, { + key: "set", + value: function set(object) { + // Bail if we don't have localStorage support or it's disabled + if (!Storage.supported || !this.enabled) { + return; + } // Can only store objectst + + + if (!is$1.object(object)) { + return; + } // Get current storage + + + var storage = this.get(); // Default to empty object + + if (is$1.empty(storage)) { + storage = {}; + } // Update the working copy of the values + + + extend(storage, object); // Update storage + + window.localStorage.setItem(this.key, JSON.stringify(storage)); + } + }], [{ + key: "supported", + get: function get() { + try { + if (!('localStorage' in window)) { + return false; + } + + var test = '___test'; // Try to use it (it might be disabled, e.g. user is in private mode) + // see: https://github.com/sampotts/plyr/issues/131 + + window.localStorage.setItem(test, test); + window.localStorage.removeItem(test); + return true; + } catch (e) { + return false; + } + } + }]); + + return Storage; + }(); + + // ========================================================================== + // Fetch wrapper + // Using XHR to avoid issues with older browsers + // ========================================================================== + function fetch(url) { + var responseType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'text'; + return new Promise(function (resolve, reject) { + try { + var request = new XMLHttpRequest(); // Check for CORS support + + if (!('withCredentials' in request)) { + return; + } + + request.addEventListener('load', function () { + if (responseType === 'text') { + try { + resolve(JSON.parse(request.responseText)); + } catch (e) { + resolve(request.responseText); + } + } else { + resolve(request.response); + } + }); + request.addEventListener('error', function () { + throw new Error(request.status); + }); + request.open('GET', url, true); // Set the required response type + + request.responseType = responseType; + request.send(); + } catch (e) { + reject(e); + } + }); + } + + // ========================================================================== + + function loadSprite(url, id) { + if (!is$1.string(url)) { + return; + } + + var prefix = 'cache'; + var hasId = is$1.string(id); + var isCached = false; + + var exists = function exists() { + return document.getElementById(id) !== null; + }; + + var update = function update(container, data) { + container.innerHTML = data; // Check again incase of race condition + + if (hasId && exists()) { + return; + } // Inject the SVG to the body + + + document.body.insertAdjacentElement('afterbegin', container); + }; // Only load once if ID set + + + if (!hasId || !exists()) { + var useStorage = Storage.supported; // Create container + + var container = document.createElement('div'); + container.setAttribute('hidden', ''); + + if (hasId) { + container.setAttribute('id', id); + } // Check in cache + + + if (useStorage) { + var cached = window.localStorage.getItem("".concat(prefix, "-").concat(id)); + isCached = cached !== null; + + if (isCached) { + var data = JSON.parse(cached); + update(container, data.content); + } + } // Get the sprite + + + fetch(url).then(function (result) { + if (is$1.empty(result)) { + return; + } + + if (useStorage) { + window.localStorage.setItem("".concat(prefix, "-").concat(id), JSON.stringify({ + content: result + })); + } + + update(container, result); + }).catch(function () {}); + } + } + + // ========================================================================== + + var getHours = function getHours(value) { + return Math.trunc(value / 60 / 60 % 60, 10); + }; + var getMinutes = function getMinutes(value) { + return Math.trunc(value / 60 % 60, 10); + }; + var getSeconds = function getSeconds(value) { + return Math.trunc(value % 60, 10); + }; // Format time to UI friendly string + + function formatTime() { + var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var displayHours = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var inverted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + // Bail if the value isn't a number + if (!is$1.number(time)) { + return formatTime(null, displayHours, inverted); + } // Format time component to add leading zero + + + var format = function format(value) { + return "0".concat(value).slice(-2); + }; // Breakdown to hours, mins, secs + + + var hours = getHours(time); + var mins = getMinutes(time); + var secs = getSeconds(time); // Do we need to display hours? + + if (displayHours || hours > 0) { + hours = "".concat(hours, ":"); + } else { + hours = ''; + } // Render + + + return "".concat(inverted && time > 0 ? '-' : '').concat(hours).concat(format(mins), ":").concat(format(secs)); + } + + var controls = { + // Get icon URL + getIconUrl: function getIconUrl() { + var url = new URL(this.config.iconUrl, window.location); + var cors = url.host !== window.location.host || browser.isIE && !window.svg4everybody; + return { + url: this.config.iconUrl, + cors: cors + }; + }, + // Find the UI controls + findElements: function findElements() { + try { + this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper); // Buttons + + this.elements.buttons = { + play: getElements.call(this, this.config.selectors.buttons.play), + pause: getElement.call(this, this.config.selectors.buttons.pause), + restart: getElement.call(this, this.config.selectors.buttons.restart), + rewind: getElement.call(this, this.config.selectors.buttons.rewind), + fastForward: getElement.call(this, this.config.selectors.buttons.fastForward), + mute: getElement.call(this, this.config.selectors.buttons.mute), + pip: getElement.call(this, this.config.selectors.buttons.pip), + airplay: getElement.call(this, this.config.selectors.buttons.airplay), + settings: getElement.call(this, this.config.selectors.buttons.settings), + captions: getElement.call(this, this.config.selectors.buttons.captions), + fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen) + }; // Progress + + this.elements.progress = getElement.call(this, this.config.selectors.progress); // Inputs + + this.elements.inputs = { + seek: getElement.call(this, this.config.selectors.inputs.seek), + volume: getElement.call(this, this.config.selectors.inputs.volume) + }; // Display + + this.elements.display = { + buffer: getElement.call(this, this.config.selectors.display.buffer), + currentTime: getElement.call(this, this.config.selectors.display.currentTime), + duration: getElement.call(this, this.config.selectors.display.duration) + }; // Seek tooltip + + if (is$1.element(this.elements.progress)) { + this.elements.display.seekTooltip = this.elements.progress.querySelector(".".concat(this.config.classNames.tooltip)); + } + + return true; + } catch (error) { + // Log it + this.debug.warn('It looks like there is a problem with your custom controls HTML', error); // Restore native video controls + + this.toggleNativeControls(true); + return false; + } + }, + // Create icon + createIcon: function createIcon(type, attributes) { + var namespace = 'http://www.w3.org/2000/svg'; + var iconUrl = controls.getIconUrl.call(this); + var iconPath = "".concat(!iconUrl.cors ? iconUrl.url : '', "#").concat(this.config.iconPrefix); // Create + + var icon = document.createElementNS(namespace, 'svg'); + setAttributes(icon, extend(attributes, { + role: 'presentation', + focusable: 'false' + })); // Create the to reference sprite + + var use = document.createElementNS(namespace, 'use'); + var path = "".concat(iconPath, "-").concat(type); // Set `href` attributes + // https://github.com/sampotts/plyr/issues/460 + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href + + if ('href' in use) { + use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path); + } // Always set the older attribute even though it's "deprecated" (it'll be around for ages) + + + use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path); // Add to + + icon.appendChild(use); + return icon; + }, + // Create hidden text label + createLabel: function createLabel(key) { + var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var text = i18n.get(key, this.config); + var attributes = Object.assign({}, attr, { + class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ') + }); + return createElement('span', attributes, text); + }, + // Create a badge + createBadge: function createBadge(text) { + if (is$1.empty(text)) { + return null; + } + + var badge = createElement('span', { + class: this.config.classNames.menu.value + }); + badge.appendChild(createElement('span', { + class: this.config.classNames.menu.badge + }, text)); + return badge; + }, + // Create a
if needed + + if (is$1.empty(source)) { + source = player.media.getAttribute(player.config.attributes.embed.id); + } + + var id = parseId(source); // Build an iframe + + var iframe = createElement('iframe'); + var src = format(player.config.urls.vimeo.iframe, id, params); + iframe.setAttribute('src', src); + iframe.setAttribute('allowfullscreen', ''); + iframe.setAttribute('allowtransparency', ''); + iframe.setAttribute('allow', 'autoplay'); // Get poster, if already set + + var poster = player.poster; // Inject the package + + var wrapper = createElement('div', { + poster: poster, + class: player.config.classNames.embedContainer + }); + wrapper.appendChild(iframe); + player.media = replaceElement(wrapper, player.media); // Get poster image + + fetch(format(player.config.urls.vimeo.api, id), 'json').then(function (response) { + if (is$1.empty(response)) { + return; + } // Get the URL for thumbnail + + + var url = new URL(response[0].thumbnail_large); // Get original image + + url.pathname = "".concat(url.pathname.split('_')[0], ".jpg"); // Set and show poster + + ui.setPoster.call(player, url.href).catch(function () {}); + }); // Setup instance + // https://github.com/vimeo/player.js + + player.embed = new window.Vimeo.Player(iframe, { + autopause: player.config.autopause, + muted: player.muted + }); + player.media.paused = true; + player.media.currentTime = 0; // Disable native text track rendering + + if (player.supported.ui) { + player.embed.disableTextTrack(); + } // Create a faux HTML5 API using the Vimeo API + + + player.media.play = function () { + assurePlaybackState.call(player, true); + return player.embed.play(); + }; + + player.media.pause = function () { + assurePlaybackState.call(player, false); + return player.embed.pause(); + }; + + player.media.stop = function () { + player.pause(); + player.currentTime = 0; + }; // Seeking + + + var currentTime = player.media.currentTime; + Object.defineProperty(player.media, 'currentTime', { + get: function get() { + return currentTime; + }, + set: function set(time) { + // Vimeo will automatically play on seek if the video hasn't been played before + // Get current paused state and volume etc + var embed = player.embed, + media = player.media, + paused = player.paused, + volume = player.volume; + var restorePause = paused && !embed.hasPlayed; // Set seeking state and trigger event + + media.seeking = true; + triggerEvent.call(player, media, 'seeking'); // If paused, mute until seek is complete + + Promise.resolve(restorePause && embed.setVolume(0)) // Seek + .then(function () { + return embed.setCurrentTime(time); + }) // Restore paused + .then(function () { + return restorePause && embed.pause(); + }) // Restore volume + .then(function () { + return restorePause && embed.setVolume(volume); + }).catch(function () {// Do nothing + }); + } + }); // Playback speed + + var speed = player.config.speed.selected; + Object.defineProperty(player.media, 'playbackRate', { + get: function get() { + return speed; + }, + set: function set(input) { + player.embed.setPlaybackRate(input).then(function () { + speed = input; + triggerEvent.call(player, player.media, 'ratechange'); + }).catch(function (error) { + // Hide menu item (and menu if empty) + if (error.name === 'Error') { + controls.setSpeedMenu.call(player, []); + } + }); + } + }); // Volume + + var volume = player.config.volume; + Object.defineProperty(player.media, 'volume', { + get: function get() { + return volume; + }, + set: function set(input) { + player.embed.setVolume(input).then(function () { + volume = input; + triggerEvent.call(player, player.media, 'volumechange'); + }); + } + }); // Muted + + var muted = player.config.muted; + Object.defineProperty(player.media, 'muted', { + get: function get() { + return muted; + }, + set: function set(input) { + var toggle = is$1.boolean(input) ? input : false; + player.embed.setVolume(toggle ? 0 : player.config.volume).then(function () { + muted = toggle; + triggerEvent.call(player, player.media, 'volumechange'); + }); + } + }); // Loop + + var loop = player.config.loop; + Object.defineProperty(player.media, 'loop', { + get: function get() { + return loop; + }, + set: function set(input) { + var toggle = is$1.boolean(input) ? input : player.config.loop.active; + player.embed.setLoop(toggle).then(function () { + loop = toggle; + }); + } + }); // Source + + var currentSrc; + player.embed.getVideoUrl().then(function (value) { + currentSrc = value; + controls.setDownloadUrl.call(player); + }).catch(function (error) { + _this2.debug.warn(error); + }); + Object.defineProperty(player.media, 'currentSrc', { + get: function get() { + return currentSrc; + } + }); // Ended + + Object.defineProperty(player.media, 'ended', { + get: function get() { + return player.currentTime === player.duration; + } + }); // Set aspect ratio based on video size + + Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(function (dimensions) { + var _dimensions = _slicedToArray(dimensions, 2), + width = _dimensions[0], + height = _dimensions[1]; + + player.embed.ratio = [width, height]; + setAspectRatio.call(_this2); + }); // Set autopause + + player.embed.setAutopause(player.config.autopause).then(function (state) { + player.config.autopause = state; + }); // Get title + + player.embed.getVideoTitle().then(function (title) { + player.config.title = title; + ui.setTitle.call(_this2); + }); // Get current time + + player.embed.getCurrentTime().then(function (value) { + currentTime = value; + triggerEvent.call(player, player.media, 'timeupdate'); + }); // Get duration + + player.embed.getDuration().then(function (value) { + player.media.duration = value; + triggerEvent.call(player, player.media, 'durationchange'); + }); // Get captions + + player.embed.getTextTracks().then(function (tracks) { + player.media.textTracks = tracks; + captions.setup.call(player); + }); + player.embed.on('cuechange', function (_ref) { + var _ref$cues = _ref.cues, + cues = _ref$cues === void 0 ? [] : _ref$cues; + var strippedCues = cues.map(function (cue) { + return stripHTML(cue.text); + }); + captions.updateCues.call(player, strippedCues); + }); + player.embed.on('loaded', function () { + // Assure state and events are updated on autoplay + player.embed.getPaused().then(function (paused) { + assurePlaybackState.call(player, !paused); + + if (!paused) { + triggerEvent.call(player, player.media, 'playing'); + } + }); + + if (is$1.element(player.embed.element) && player.supported.ui) { + var frame = player.embed.element; // Fix keyboard focus issues + // https://github.com/sampotts/plyr/issues/317 + + frame.setAttribute('tabindex', -1); + } + }); + player.embed.on('play', function () { + assurePlaybackState.call(player, true); + triggerEvent.call(player, player.media, 'playing'); + }); + player.embed.on('pause', function () { + assurePlaybackState.call(player, false); + }); + player.embed.on('timeupdate', function (data) { + player.media.seeking = false; + currentTime = data.seconds; + triggerEvent.call(player, player.media, 'timeupdate'); + }); + player.embed.on('progress', function (data) { + player.media.buffered = data.percent; + triggerEvent.call(player, player.media, 'progress'); // Check all loaded + + if (parseInt(data.percent, 10) === 1) { + triggerEvent.call(player, player.media, 'canplaythrough'); + } // Get duration as if we do it before load, it gives an incorrect value + // https://github.com/sampotts/plyr/issues/891 + + + player.embed.getDuration().then(function (value) { + if (value !== player.media.duration) { + player.media.duration = value; + triggerEvent.call(player, player.media, 'durationchange'); + } + }); + }); + player.embed.on('seeked', function () { + player.media.seeking = false; + triggerEvent.call(player, player.media, 'seeked'); + }); + player.embed.on('ended', function () { + player.media.paused = true; + triggerEvent.call(player, player.media, 'ended'); + }); + player.embed.on('error', function (detail) { + player.media.error = detail; + triggerEvent.call(player, player.media, 'error'); + }); // Rebuild UI + + setTimeout(function () { + return ui.build.call(player); + }, 0); + } + }; + + // ========================================================================== + + function parseId$1(url) { + if (is$1.empty(url)) { + return null; + } + + var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/; + return url.match(regex) ? RegExp.$2 : url; + } // Set playback state and trigger change (only on actual change) + + + function assurePlaybackState$1(play) { + if (play && !this.embed.hasPlayed) { + this.embed.hasPlayed = true; + } + + if (this.media.paused === play) { + this.media.paused = !play; + triggerEvent.call(this, this.media, play ? 'play' : 'pause'); + } + } + + function getHost(config) { + if (config.noCookie) { + return 'https://www.youtube-nocookie.com'; + } + + if (window.location.protocol === 'http:') { + return 'http://www.youtube.com'; + } // Use YouTube's default + + + return undefined; + } + + var youtube = { + setup: function setup() { + var _this = this; + + // Add embed class for responsive + toggleClass(this.elements.wrapper, this.config.classNames.embed, true); // Setup API + + if (is$1.object(window.YT) && is$1.function(window.YT.Player)) { + youtube.ready.call(this); + } else { + // Load the API + loadScript(this.config.urls.youtube.sdk).catch(function (error) { + _this.debug.warn('YouTube API failed to load', error); + }); // Setup callback for the API + // YouTube has it's own system of course... + + window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || []; // Add to queue + + window.onYouTubeReadyCallbacks.push(function () { + youtube.ready.call(_this); + }); // Set callback to process queue + + window.onYouTubeIframeAPIReady = function () { + window.onYouTubeReadyCallbacks.forEach(function (callback) { + callback(); + }); + }; + } + }, + // Get the media title + getTitle: function getTitle(videoId) { + var _this2 = this; + + var url = format(this.config.urls.youtube.api, videoId); + fetch(url).then(function (data) { + if (is$1.object(data)) { + var title = data.title, + height = data.height, + width = data.width; // Set title + + _this2.config.title = title; + ui.setTitle.call(_this2); // Set aspect ratio + + _this2.embed.ratio = [width, height]; + } + + setAspectRatio.call(_this2); + }).catch(function () { + // Set aspect ratio + setAspectRatio.call(_this2); + }); + }, + // API ready + ready: function ready() { + var player = this; // Ignore already setup (race condition) + + var currentId = player.media.getAttribute('id'); + + if (!is$1.empty(currentId) && currentId.startsWith('youtube-')) { + return; + } // Get the source URL or ID + + + var source = player.media.getAttribute('src'); // Get from
if needed + + if (is$1.empty(source)) { + source = player.media.getAttribute(this.config.attributes.embed.id); + } // Replace the