@makiwin/ngx-plyr
Version:
## ngx-plyr
240 lines • 30 kB
JavaScript
import { Component, ElementRef, Input, NgZone, Output, Renderer2, ViewChild, } from "@angular/core";
import * as Plyr from "plyr";
import { BehaviorSubject, Observable } from "rxjs";
import { filter, first, switchMap } from "rxjs/operators";
import { DefaultPlyrDriver } from "../plyr-driver/default-plyr-driver";
import * as i0 from "@angular/core";
export class PlyrComponent {
get player() {
return this.playerChange.getValue();
}
constructor(elementRef, ngZone, renderer) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.playerChange = new BehaviorSubject(null);
this.events = new Map();
this.plyrType = "video";
// ngx-plyr events
this.plyrInit = this.playerChange.pipe(filter((player) => !!player));
// standard media events
this.plyrProgress = this.createLazyEvent("progress");
this.plyrPlaying = this.createLazyEvent("playing");
this.plyrPlay = this.createLazyEvent("play");
this.plyrPause = this.createLazyEvent("pause");
this.plyrTimeUpdate = this.createLazyEvent("timeupdate");
this.plyrVolumeChange = this.createLazyEvent("volumechange");
this.plyrSeeking = this.createLazyEvent("seeking");
this.plyrSeeked = this.createLazyEvent("seeked");
this.plyrRateChange = this.createLazyEvent("ratechange");
this.plyrEnded = this.createLazyEvent("ended");
this.plyrEnterFullScreen = this.createLazyEvent("enterfullscreen");
this.plyrExitFullScreen = this.createLazyEvent("exitfullscreen");
this.plyrCaptionsEnabled = this.createLazyEvent("captionsenabled");
this.plyrCaptionsDisabled = this.createLazyEvent("captionsdisabled");
this.plyrLanguageChange = this.createLazyEvent("languagechange");
this.plyrControlsHidden = this.createLazyEvent("controlshidden");
this.plyrControlsShown = this.createLazyEvent("controlsshown");
this.plyrReady = this.createLazyEvent("ready");
// HTML5 events
this.plyrLoadStart = this.createLazyEvent("loadstart");
this.plyrLoadedData = this.createLazyEvent("loadeddata");
this.plyrLoadedMetadata = this.createLazyEvent("loadedmetadata");
this.plyrQualityChange = this.createLazyEvent("qualitychange");
this.plyrCanPlay = this.createLazyEvent("canplay");
this.plyrCanPlayThrough = this.createLazyEvent("canplaythrough");
this.plyrStalled = this.createLazyEvent("stalled");
this.plyrWaiting = this.createLazyEvent("waiting");
this.plyrEmptied = this.createLazyEvent("emptied");
this.plyrCueChange = this.createLazyEvent("cuechange");
this.plyrError = this.createLazyEvent("error");
// YouTube events
this.plyrStateChange = this.createLazyEvent("statechange");
this.subscriptions = [];
}
ngOnChanges(changes) {
this.subscriptions.push(this.plyrInit.pipe(first()).subscribe((player) => {
const reinitTriggers = [
changes.plyrOptions,
changes.plyrPlaysInline,
changes.plyrCrossOrigin,
].filter((t) => !!t);
if (reinitTriggers.length) {
if (reinitTriggers.some((t) => !t.firstChange)) {
this.initPlyr(true);
}
}
else {
this.updatePlyrSource(player);
}
}));
}
ngOnDestroy() {
this.destroyPlayer();
this.subscriptions.forEach((s) => s.unsubscribe());
}
ngAfterViewInit() {
this.initPlyr();
}
initPlyr(force = false) {
if (force || !this.player) {
this.ngZone.runOutsideAngular(() => {
this.destroyPlayer();
this.driver = this.plyrDriver || new DefaultPlyrDriver();
this.ensureVideoElement();
const newPlayer = this.driver.create({
videoElement: this.videoElement,
options: this.plyrOptions,
});
this.updatePlyrSource(newPlayer);
this.playerChange.next(newPlayer);
});
}
}
updatePlyrSource(plyr) {
this.driver.updateSource({
videoElement: this.videoElement,
plyr,
source: {
type: this.plyrType,
title: this.plyrTitle,
sources: this.plyrSources,
poster: this.plyrPoster,
tracks: this.plyrTracks,
},
});
}
// see https://stackoverflow.com/a/53704102/1990451
createLazyEvent(name) {
return this.plyrInit.pipe(switchMap(() => new Observable((observer) => this.on(name, (data) => this.ngZone.run(() => observer.next(data))))));
}
destroyPlayer() {
if (this.player) {
Array.from(this.events.keys()).forEach((name) => this.off(name));
this.driver.destroy({
plyr: this.player,
});
this.videoElement = null;
}
}
get hostElement() {
return this.elementRef.nativeElement;
}
// this method is required because the plyr inserts clone of the original element on destroy
// so we catch the clone element right here and reuse it
ensureVideoElement() {
const videoElement = this.hostElement.querySelector("video");
if (videoElement) {
this.videoElement = videoElement;
}
else {
this.videoElement = this.renderer.createElement("video");
this.videoElement.controls = true;
if (this.plyrCrossOrigin) {
this.videoElement.setAttribute("crossorigin", "");
}
if (this.plyrPlaysInline) {
this.videoElement.setAttribute("playsinline", "");
}
this.renderer.appendChild(this.hostElement, this.videoElement);
}
}
on(name, handler) {
this.events.set(name, handler);
this.player.on(name, handler);
}
off(name) {
this.player.off(name, this.events.get(name));
this.events.delete(name);
}
}
PlyrComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PlyrComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
PlyrComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PlyrComponent, selector: "plyr, [plyr]", inputs: { plyrDriver: "plyrDriver", plyrType: "plyrType", plyrTitle: "plyrTitle", plyrPoster: "plyrPoster", plyrSources: "plyrSources", plyrTracks: "plyrTracks", plyrOptions: "plyrOptions", plyrCrossOrigin: "plyrCrossOrigin", plyrPlaysInline: "plyrPlaysInline" }, outputs: { plyrInit: "plyrInit", plyrProgress: "plyrProgress", plyrPlaying: "plyrPlaying", plyrPlay: "plyrPlay", plyrPause: "plyrPause", plyrTimeUpdate: "plyrTimeUpdate", plyrVolumeChange: "plyrVolumeChange", plyrSeeking: "plyrSeeking", plyrSeeked: "plyrSeeked", plyrRateChange: "plyrRateChange", plyrEnded: "plyrEnded", plyrEnterFullScreen: "plyrEnterFullScreen", plyrExitFullScreen: "plyrExitFullScreen", plyrCaptionsEnabled: "plyrCaptionsEnabled", plyrCaptionsDisabled: "plyrCaptionsDisabled", plyrLanguageChange: "plyrLanguageChange", plyrControlsHidden: "plyrControlsHidden", plyrControlsShown: "plyrControlsShown", plyrReady: "plyrReady", plyrLoadStart: "plyrLoadStart", plyrLoadedData: "plyrLoadedData", plyrLoadedMetadata: "plyrLoadedMetadata", plyrQualityChange: "plyrQualityChange", plyrCanPlay: "plyrCanPlay", plyrCanPlayThrough: "plyrCanPlayThrough", plyrStalled: "plyrStalled", plyrWaiting: "plyrWaiting", plyrEmptied: "plyrEmptied", plyrCueChange: "plyrCueChange", plyrError: "plyrError", plyrStateChange: "plyrStateChange" }, viewQueries: [{ propertyName: "vr", first: true, predicate: ["v"], descendants: true }], exportAs: ["plyr"], usesOnChanges: true, ngImport: i0, template: "", styles: [""] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PlyrComponent, decorators: [{
type: Component,
args: [{ selector: "plyr, [plyr]", exportAs: "plyr", template: "" }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { plyrDriver: [{
type: Input
}], plyrType: [{
type: Input
}], plyrTitle: [{
type: Input
}], plyrPoster: [{
type: Input
}], plyrSources: [{
type: Input
}], plyrTracks: [{
type: Input
}], plyrOptions: [{
type: Input
}], plyrCrossOrigin: [{
type: Input
}], plyrPlaysInline: [{
type: Input
}], vr: [{
type: ViewChild,
args: ["v"]
}], plyrInit: [{
type: Output
}], plyrProgress: [{
type: Output
}], plyrPlaying: [{
type: Output
}], plyrPlay: [{
type: Output
}], plyrPause: [{
type: Output
}], plyrTimeUpdate: [{
type: Output
}], plyrVolumeChange: [{
type: Output
}], plyrSeeking: [{
type: Output
}], plyrSeeked: [{
type: Output
}], plyrRateChange: [{
type: Output
}], plyrEnded: [{
type: Output
}], plyrEnterFullScreen: [{
type: Output
}], plyrExitFullScreen: [{
type: Output
}], plyrCaptionsEnabled: [{
type: Output
}], plyrCaptionsDisabled: [{
type: Output
}], plyrLanguageChange: [{
type: Output
}], plyrControlsHidden: [{
type: Output
}], plyrControlsShown: [{
type: Output
}], plyrReady: [{
type: Output
}], plyrLoadStart: [{
type: Output
}], plyrLoadedData: [{
type: Output
}], plyrLoadedMetadata: [{
type: Output
}], plyrQualityChange: [{
type: Output
}], plyrCanPlay: [{
type: Output
}], plyrCanPlayThrough: [{
type: Output
}], plyrStalled: [{
type: Output
}], plyrWaiting: [{
type: Output
}], plyrEmptied: [{
type: Output
}], plyrCueChange: [{
type: Output
}], plyrError: [{
type: Output
}], plyrStateChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx5ci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcGx5ci9zcmMvbGliL3BseXIvcGx5ci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcGx5ci9zcmMvbGliL3BseXIvcGx5ci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFVBQVUsRUFFVixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBRVQsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUNqRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7QUFTdkUsTUFBTSxPQUFPLGFBQWE7SUFHeEIsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUF1RUQsWUFDVSxVQUFzQyxFQUN0QyxNQUFjLEVBQ2QsUUFBbUI7UUFGbkIsZUFBVSxHQUFWLFVBQVUsQ0FBNEI7UUFDdEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVc7UUE5RXJCLGlCQUFZLEdBQUcsSUFBSSxlQUFlLENBQU8sSUFBSSxDQUFDLENBQUM7UUFNL0MsV0FBTSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7UUFJbEIsYUFBUSxHQUFtQixPQUFPLENBQUM7UUFrQjVDLGtCQUFrQjtRQUNSLGFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FD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QkFBekIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUdHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFHRyxlQUFlO3NCQUF4QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlLFxuICBWaWV3Q2hpbGQsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgKiBhcyBQbHlyIGZyb20gXCJwbHlyXCI7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBmaWx0ZXIsIGZpcnN0LCBzd2l0Y2hNYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7IERlZmF1bHRQbHlyRHJpdmVyIH0gZnJvbSBcIi4uL3BseXItZHJpdmVyL2RlZmF1bHQtcGx5ci1kcml2ZXJcIjtcbmltcG9ydCB7IFBseXJEcml2ZXIgfSBmcm9tIFwiLi4vcGx5ci1kcml2ZXIvcGx5ci1kcml2ZXJcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInBseXIsIFtwbHlyXVwiLCAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lXG4gIHRlbXBsYXRlVXJsOiBcIi4vcGx5ci5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vcGx5ci5jb21wb25lbnQuY3NzXCJdLFxuICBleHBvcnRBczogXCJwbHlyXCIsXG59KVxuZXhwb3J0IGNsYXNzIFBseXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcGxheWVyQ2hhbmdlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQbHlyPihudWxsKTtcblxuICBnZXQgcGxheWVyKCk6IFBseXIge1xuICAgIHJldHVybiB0aGlzLnBsYXllckNoYW5nZS5nZXRWYWx1ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBldmVudHMgPSBuZXcgTWFwKCk7XG5cbiAgQElucHV0KCkgcGx5ckRyaXZlcjogUGx5ckRyaXZlcjtcblxuICBASW5wdXQoKSBwbHlyVHlwZTogUGx5ci5NZWRpYVR5cGUgPSBcInZpZGVvXCI7XG5cbiAgQElucHV0KCkgcGx5clRpdGxlOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgcGx5clBvc3Rlcjogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHBseXJTb3VyY2VzOiBQbHlyLlNvdXJjZVtdO1xuXG4gIEBJbnB1dCgpIHBseXJUcmFja3M6IFBseXIuVHJhY2tbXTtcblxuICBASW5wdXQoKSBwbHlyT3B0aW9uczogUGx5ci5PcHRpb25zO1xuXG4gIEBJbnB1dCgpIHBseXJDcm9zc09yaWdpbjogYm9vbGVhbjtcblxuICBASW5wdXQoKSBwbHlyUGxheXNJbmxpbmU6IGJvb2xlYW47XG5cbiAgQFZpZXdDaGlsZChcInZcIikgcHJpdmF0ZSB2cjogRWxlbWVudFJlZjtcblxuICAvLyBuZ3gtcGx5ciBldmVudHNcbiAgQE91dHB1dCgpIHBseXJJbml0ID0gdGhpcy5wbGF5ZXJDaGFuZ2UucGlwZShcbiAgICBmaWx0ZXIoKHBsYXllcikgPT4gISFwbGF5ZXIpXG4gICkgYXMgRXZlbnRFbWl0dGVyPFBseXI+O1xuXG4gIC8vIHN0YW5kYXJkIG1lZGlhIGV2ZW50c1xuICBAT3V0cHV0KCkgcGx5clByb2dyZXNzID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJwcm9ncmVzc1wiKTtcbiAgQE91dHB1dCgpIHBseXJQbGF5aW5nID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJwbGF5aW5nXCIpO1xuICBAT3V0cHV0KCkgcGx5clBsYXkgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInBsYXlcIik7XG4gIEBPdXRwdXQoKSBwbHlyUGF1c2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInBhdXNlXCIpO1xuICBAT3V0cHV0KCkgcGx5clRpbWVVcGRhdGUgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInRpbWV1cGRhdGVcIik7XG4gIEBPdXRwdXQoKSBwbHlyVm9sdW1lQ2hhbmdlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJ2b2x1bWVjaGFuZ2VcIik7XG4gIEBPdXRwdXQoKSBwbHlyU2Vla2luZyA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwic2Vla2luZ1wiKTtcbiAgQE91dHB1dCgpIHBseXJTZWVrZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInNlZWtlZFwiKTtcbiAgQE91dHB1dCgpIHBseXJSYXRlQ2hhbmdlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJyYXRlY2hhbmdlXCIpO1xuICBAT3V0cHV0KCkgcGx5ckVuZGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJlbmRlZFwiKTtcbiAgQE91dHB1dCgpIHBseXJFbnRlckZ1bGxTY3JlZW4gPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImVudGVyZnVsbHNjcmVlblwiKTtcbiAgQE91dHB1dCgpIHBseXJFeGl0RnVsbFNjcmVlbiA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwiZXhpdGZ1bGxzY3JlZW5cIik7XG4gIEBPdXRwdXQoKSBwbHlyQ2FwdGlvbnNFbmFibGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJjYXB0aW9uc2VuYWJsZWRcIik7XG4gIEBPdXRwdXQoKSBwbHlyQ2FwdGlvbnNEaXNhYmxlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwiY2FwdGlvbnNkaXNhYmxlZFwiKTtcbiAgQE91dHB1dCgpIHBseXJMYW5ndWFnZUNoYW5nZSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwibGFuZ3VhZ2VjaGFuZ2VcIik7XG4gIEBPdXRwdXQoKSBwbHlyQ29udHJvbHNIaWRkZW4gPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImNvbnRyb2xzaGlkZGVuXCIpO1xuICBAT3V0cHV0KCkgcGx5ckNvbnRyb2xzU2hvd24gPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImNvbnRyb2xzc2hvd25cIik7XG4gIEBPdXRwdXQoKSBwbHlyUmVhZHkgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInJlYWR5XCIpO1xuXG4gIC8vIEhUTUw1IGV2ZW50c1xuICBAT3V0cHV0KCkgcGx5ckxvYWRTdGFydCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwibG9hZHN0YXJ0XCIpO1xuICBAT3V0cHV0KCkgcGx5ckxvYWRlZERhdGEgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImxvYWRlZGRhdGFcIik7XG4gIEBPdXRwdXQoKSBwbHlyTG9hZGVkTWV0YWRhdGEgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImxvYWRlZG1ldGFkYXRhXCIpO1xuICBAT3V0cHV0KCkgcGx5clF1YWxpdHlDaGFuZ2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInF1YWxpdHljaGFuZ2VcIik7XG4gIEBPdXRwdXQoKSBwbHlyQ2FuUGxheSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwiY2FucGxheVwiKTtcbiAgQE91dHB1dCgpIHBseXJDYW5QbGF5VGhyb3VnaCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwiY2FucGxheXRocm91Z2hcIik7XG4gIEBPdXRwdXQoKSBwbHlyU3RhbGxlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KFwic3RhbGxlZFwiKTtcbiAgQE91dHB1dCgpIHBseXJXYWl0aW5nID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJ3YWl0aW5nXCIpO1xuICBAT3V0cHV0KCkgcGx5ckVtcHRpZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImVtcHRpZWRcIik7XG4gIEBPdXRwdXQoKSBwbHlyQ3VlQ2hhbmdlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoXCJjdWVjaGFuZ2VcIik7XG4gIEBPdXRwdXQoKSBwbHlyRXJyb3IgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcImVycm9yXCIpO1xuXG4gIC8vIFlvdVR1YmUgZXZlbnRzXG4gIEBPdXRwdXQoKSBwbHlyU3RhdGVDaGFuZ2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudChcInN0YXRlY2hhbmdlXCIpO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICBwcml2YXRlIGRyaXZlcjogUGx5ckRyaXZlcjtcblxuICBwcml2YXRlIHZpZGVvRWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+LFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyXG4gICkge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7IFtwIGluIGtleW9mIFBseXJDb21wb25lbnRdPzogU2ltcGxlQ2hhbmdlIH0pIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMucGx5ckluaXQucGlwZShmaXJzdCgpKS5zdWJzY3JpYmUoKHBsYXllcjogUGx5cikgPT4ge1xuICAgICAgICBjb25zdCByZWluaXRUcmlnZ2VycyA9IFtcbiAgICAgICAgICBjaGFuZ2VzLnBseXJPcHRpb25zLFxuICAgICAgICAgIGNoYW5nZXMucGx5clBsYXlzSW5saW5lLFxuICAgICAgICAgIGNoYW5nZXMucGx5ckNyb3NzT3JpZ2luLFxuICAgICAgICBdLmZpbHRlcigodCkgPT4gISF0KTtcblxuICAgICAgICBpZiAocmVpbml0VHJpZ2dlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKHJlaW5pdFRyaWdnZXJzLnNvbWUoKHQpID0+ICF0LmZpcnN0Q2hhbmdlKSkge1xuICAgICAgICAgICAgdGhpcy5pbml0UGx5cih0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVQbHlyU291cmNlKHBsYXllcik7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveVBsYXllcigpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzKSA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaW5pdFBseXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdFBseXIoZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmIChmb3JjZSB8fCAhdGhpcy5wbGF5ZXIpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgdGhpcy5kZXN0cm95UGxheWVyKCk7XG5cbiAgICAgICAgdGhpcy5kcml2ZXIgPSB0aGlzLnBseXJEcml2ZXIgfHwgbmV3IERlZmF1bHRQbHlyRHJpdmVyKCk7XG5cbiAgICAgICAgdGhpcy5lbnN1cmVWaWRlb0VsZW1lbnQoKTtcblxuICAgICAgICBjb25zdCBuZXdQbGF5ZXIgPSB0aGlzLmRyaXZlci5jcmVhdGUoe1xuICAgICAgICAgIHZpZGVvRWxlbWVudDogdGhpcy52aWRlb0VsZW1lbnQsXG4gICAgICAgICAgb3B0aW9uczogdGhpcy5wbHlyT3B0aW9ucyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVQbHlyU291cmNlKG5ld1BsYXllcik7XG5cbiAgICAgICAgdGhpcy5wbGF5ZXJDaGFuZ2UubmV4dChuZXdQbGF5ZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVQbHlyU291cmNlKHBseXI6IFBseXIpIHtcbiAgICB0aGlzLmRyaXZlci51cGRhdGVTb3VyY2Uoe1xuICAgICAgdmlkZW9FbGVtZW50OiB0aGlzLnZpZGVvRWxlbWVudCxcbiAgICAgIHBseXIsXG4gICAgICBzb3VyY2U6IHtcbiAgICAgICAgdHlwZTogdGhpcy5wbHlyVHlwZSxcbiAgICAgICAgdGl0bGU6IHRoaXMucGx5clRpdGxlLFxuICAgICAgICBzb3VyY2VzOiB0aGlzLnBseXJTb3VyY2VzLFxuICAgICAgICBwb3N0ZXI6IHRoaXMucGx5clBvc3RlcixcbiAgICAgICAgdHJhY2tzOiB0aGlzLnBseXJUcmFja3MsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLy8gc2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81MzcwNDEwMi8xOTkwNDUxXG4gIHByaXZhdGUgY3JlYXRlTGF6eUV2ZW50PFQgZXh0ZW5kcyBQbHlyLlBseXJFdmVudD4oXG4gICAgbmFtZTogUGx5ci5TdGFuZGFyZEV2ZW50IHwgUGx5ci5IdG1sNUV2ZW50IHwgUGx5ci5Zb3V0dWJlRXZlbnRcbiAgKTogRXZlbnRFbWl0dGVyPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5wbHlySW5pdC5waXBlKFxuICAgICAgc3dpdGNoTWFwKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT5cbiAgICAgICAgICAgIHRoaXMub24obmFtZSwgKGRhdGE6IFQpID0+XG4gICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiBvYnNlcnZlci5uZXh0KGRhdGEpKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgIClcbiAgICApIGFzIEV2ZW50RW1pdHRlcjxUPjtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveVBsYXllcigpIHtcbiAgICBpZiAodGhpcy5wbGF5ZXIpIHtcbiAgICAgIEFycmF5LmZyb20odGhpcy5ldmVudHMua2V5cygpKS5mb3JFYWNoKChuYW1lKSA9PiB0aGlzLm9mZihuYW1lKSk7XG5cbiAgICAgIHRoaXMuZHJpdmVyLmRlc3Ryb3koe1xuICAgICAgICBwbHlyOiB0aGlzLnBsYXllcixcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnZpZGVvRWxlbWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgaG9zdEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgLy8gdGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgYmVjYXVzZSB0aGUgcGx5ciBpbnNlcnRzIGNsb25lIG9mIHRoZSBvcmlnaW5hbCBlbGVtZW50IG9uIGRlc3Ryb3lcbiAgLy8gc28gd2UgY2F0Y2ggdGhlIGNsb25lIGVsZW1lbnQgcmlnaHQgaGVyZSBhbmQgcmV1c2UgaXRcbiAgcHJpdmF0ZSBlbnN1cmVWaWRlb0VsZW1lbnQoKSB7XG4gICAgY29uc3QgdmlkZW9FbGVtZW50ID0gdGhpcy5ob3N0RWxlbWVudC5xdWVyeVNlbGVjdG9yKFwidmlkZW9cIik7XG5cbiAgICBpZiAodmlkZW9FbGVtZW50KSB7XG4gICAgICB0aGlzLnZpZGVvRWxlbWVudCA9IHZpZGVvRWxlbWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWRlb0VsZW1lbnQgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiKTtcbiAgICAgIHRoaXMudmlkZW9FbGVtZW50LmNvbnRyb2xzID0gdHJ1ZTtcblxuICAgICAgaWYgKHRoaXMucGx5ckNyb3NzT3JpZ2luKSB7XG4gICAgICAgIHRoaXMudmlkZW9FbGVtZW50LnNldEF0dHJpYnV0ZShcImNyb3Nzb3JpZ2luXCIsIFwiXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wbHlyUGxheXNJbmxpbmUpIHtcbiAgICAgICAgdGhpcy52aWRlb0VsZW1lbnQuc2V0QXR0cmlidXRlKFwicGxheXNpbmxpbmVcIiwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5ob3N0RWxlbWVudCwgdGhpcy52aWRlb0VsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb24obmFtZTogc3RyaW5nLCBoYW5kbGVyOiBhbnkpIHtcbiAgICB0aGlzLmV2ZW50cy5zZXQobmFtZSwgaGFuZGxlcik7XG4gICAgdGhpcy5wbGF5ZXIub24obmFtZSBhcyBhbnksIGhhbmRsZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBvZmYobmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5wbGF5ZXIub2ZmKG5hbWUgYXMgYW55LCB0aGlzLmV2ZW50cy5nZXQobmFtZSkpO1xuICAgIHRoaXMuZXZlbnRzLmRlbGV0ZShuYW1lKTtcbiAgfVxufVxuIiwiIl19