ngx-plyr3
Version:
235 lines • 30.1 kB
JavaScript
import { Component, Input, Output, ViewChild } from "@angular/core";
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 {
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 = [];
}
get player() {
return this.playerChange.getValue();
}
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: "14.2.0", 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: "14.2.0", 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: "" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx5ci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcGx5ci9zcmMvbGliL3BseXIvcGx5ci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcGx5ci9zcmMvbGliL3BseXIvcGx5ci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULEtBQUssRUFJTCxNQUFNLEVBR04sU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUNqRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7QUFRdkUsTUFBTSxPQUFPLGFBQWE7SUEwRXhCLFlBQ1UsVUFBc0MsRUFDdEMsTUFBYyxFQUNkLFFBQW1CO1FBRm5CLGVBQVUsR0FBVixVQUFVLENBQTRCO1FBQ3RDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBNUVyQixpQkFBWSxHQUFHLElBQUksZUFBZSxDQUFPLElBQUksQ0FBQyxDQUFDO1FBTS9DLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSWxCLGFBQVEsR0FBbUIsT0FBTyxDQUFDO1FBa0I1QyxrQkFBa0I7UUFDUixhQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUF1QixDQUFDO1FBRTlGLHdCQUF3QjtRQUNkLGlCQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoRCxnQkFB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QUNHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUdHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFHRyxlQUFlO3NCQUF4QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENvbXBvbmVudCwgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgTmdab25lLFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT3V0cHV0LFxyXG4gIFJlbmRlcmVyMixcclxuICBTaW1wbGVDaGFuZ2UsXHJcbiAgVmlld0NoaWxkXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0ICogYXMgUGx5ciBmcm9tIFwicGx5clwiO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IGZpbHRlciwgZmlyc3QsIHN3aXRjaE1hcCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQgeyBEZWZhdWx0UGx5ckRyaXZlciB9IGZyb20gXCIuLi9wbHlyLWRyaXZlci9kZWZhdWx0LXBseXItZHJpdmVyXCI7XHJcbmltcG9ydCB7IFBseXJEcml2ZXIgfSBmcm9tIFwiLi4vcGx5ci1kcml2ZXIvcGx5ci1kcml2ZXJcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncGx5ciwgW3BseXJdJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcGx5ci5jb21wb25lbnQuaHRtbCcsXHJcbiAgZXhwb3J0QXM6ICdwbHlyJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgUGx5ckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcclxuICBwcml2YXRlIHBsYXllckNoYW5nZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UGx5cj4obnVsbCk7XHJcblxyXG4gIGdldCBwbGF5ZXIoKTogUGx5ciB7XHJcbiAgICByZXR1cm4gdGhpcy5wbGF5ZXJDaGFuZ2UuZ2V0VmFsdWUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZXZlbnRzID0gbmV3IE1hcCgpO1xyXG5cclxuICBASW5wdXQoKSBwbHlyRHJpdmVyOiBQbHlyRHJpdmVyO1xyXG5cclxuICBASW5wdXQoKSBwbHlyVHlwZTogUGx5ci5NZWRpYVR5cGUgPSAndmlkZW8nO1xyXG5cclxuICBASW5wdXQoKSBwbHlyVGl0bGU6IHN0cmluZztcclxuXHJcbiAgQElucHV0KCkgcGx5clBvc3Rlcjogc3RyaW5nO1xyXG5cclxuICBASW5wdXQoKSBwbHlyU291cmNlczogUGx5ci5Tb3VyY2VbXTtcclxuXHJcbiAgQElucHV0KCkgcGx5clRyYWNrczogUGx5ci5UcmFja1tdO1xyXG5cclxuICBASW5wdXQoKSBwbHlyT3B0aW9uczogUGx5ci5PcHRpb25zO1xyXG5cclxuICBASW5wdXQoKSBwbHlyQ3Jvc3NPcmlnaW46IGJvb2xlYW47XHJcblxyXG4gIEBJbnB1dCgpIHBseXJQbGF5c0lubGluZTogYm9vbGVhbjtcclxuXHJcbiAgQFZpZXdDaGlsZCgndicpIHByaXZhdGUgdnI6IEVsZW1lbnRSZWY7XHJcblxyXG4gIC8vIG5neC1wbHlyIGV2ZW50c1xyXG4gIEBPdXRwdXQoKSBwbHlySW5pdCA9IHRoaXMucGxheWVyQ2hhbmdlLnBpcGUoZmlsdGVyKHBsYXllciA9PiAhIXBsYXllcikpIGFzIEV2ZW50RW1pdHRlcjxQbHlyPjtcclxuXHJcbiAgLy8gc3RhbmRhcmQgbWVkaWEgZXZlbnRzXHJcbiAgQE91dHB1dCgpIHBseXJQcm9ncmVzcyA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdwcm9ncmVzcycpO1xyXG4gIEBPdXRwdXQoKSBwbHlyUGxheWluZyA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdwbGF5aW5nJyk7XHJcbiAgQE91dHB1dCgpIHBseXJQbGF5ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3BsYXknKTtcclxuICBAT3V0cHV0KCkgcGx5clBhdXNlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3BhdXNlJyk7XHJcbiAgQE91dHB1dCgpIHBseXJUaW1lVXBkYXRlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3RpbWV1cGRhdGUnKTtcclxuICBAT3V0cHV0KCkgcGx5clZvbHVtZUNoYW5nZSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCd2b2x1bWVjaGFuZ2UnKTtcclxuICBAT3V0cHV0KCkgcGx5clNlZWtpbmcgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnc2Vla2luZycpO1xyXG4gIEBPdXRwdXQoKSBwbHlyU2Vla2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3NlZWtlZCcpO1xyXG4gIEBPdXRwdXQoKSBwbHlyUmF0ZUNoYW5nZSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdyYXRlY2hhbmdlJyk7XHJcbiAgQE91dHB1dCgpIHBseXJFbmRlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdlbmRlZCcpO1xyXG4gIEBPdXRwdXQoKSBwbHlyRW50ZXJGdWxsU2NyZWVuID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2VudGVyZnVsbHNjcmVlbicpO1xyXG4gIEBPdXRwdXQoKSBwbHlyRXhpdEZ1bGxTY3JlZW4gPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnZXhpdGZ1bGxzY3JlZW4nKTtcclxuICBAT3V0cHV0KCkgcGx5ckNhcHRpb25zRW5hYmxlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdjYXB0aW9uc2VuYWJsZWQnKTtcclxuICBAT3V0cHV0KCkgcGx5ckNhcHRpb25zRGlzYWJsZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnY2FwdGlvbnNkaXNhYmxlZCcpO1xyXG4gIEBPdXRwdXQoKSBwbHlyTGFuZ3VhZ2VDaGFuZ2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbGFuZ3VhZ2VjaGFuZ2UnKTtcclxuICBAT3V0cHV0KCkgcGx5ckNvbnRyb2xzSGlkZGVuID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NvbnRyb2xzaGlkZGVuJyk7XHJcbiAgQE91dHB1dCgpIHBseXJDb250cm9sc1Nob3duID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NvbnRyb2xzc2hvd24nKTtcclxuICBAT3V0cHV0KCkgcGx5clJlYWR5ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3JlYWR5Jyk7XHJcblxyXG4gIC8vIEhUTUw1IGV2ZW50c1xyXG4gIEBPdXRwdXQoKSBwbHlyTG9hZFN0YXJ0ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2xvYWRzdGFydCcpO1xyXG4gIEBPdXRwdXQoKSBwbHlyTG9hZGVkRGF0YSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdsb2FkZWRkYXRhJyk7XHJcbiAgQE91dHB1dCgpIHBseXJMb2FkZWRNZXRhZGF0YSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdsb2FkZWRtZXRhZGF0YScpO1xyXG4gIEBPdXRwdXQoKSBwbHlyUXVhbGl0eUNoYW5nZSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdxdWFsaXR5Y2hhbmdlJyk7XHJcbiAgQE91dHB1dCgpIHBseXJDYW5QbGF5ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NhbnBsYXknKTtcclxuICBAT3V0cHV0KCkgcGx5ckNhblBsYXlUaHJvdWdoID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NhbnBsYXl0aHJvdWdoJyk7XHJcbiAgQE91dHB1dCgpIHBseXJTdGFsbGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3N0YWxsZWQnKTtcclxuICBAT3V0cHV0KCkgcGx5cldhaXRpbmcgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnd2FpdGluZycpO1xyXG4gIEBPdXRwdXQoKSBwbHlyRW1wdGllZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdlbXB0aWVkJyk7XHJcbiAgQE91dHB1dCgpIHBseXJDdWVDaGFuZ2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnY3VlY2hhbmdlJyk7XHJcbiAgQE91dHB1dCgpIHBseXJFcnJvciA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdlcnJvcicpO1xyXG5cclxuICAvLyBZb3VUdWJlIGV2ZW50c1xyXG4gIEBPdXRwdXQoKSBwbHlyU3RhdGVDaGFuZ2UgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnc3RhdGVjaGFuZ2UnKTtcclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xyXG5cclxuICBwcml2YXRlIGRyaXZlcjogUGx5ckRyaXZlcjtcclxuXHJcbiAgcHJpdmF0ZSB2aWRlb0VsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PixcclxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgKSB7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7IFtwIGluIGtleW9mIFBseXJDb21wb25lbnRdPzogU2ltcGxlQ2hhbmdlOyB9KSB7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLnBseXJJbml0LnBpcGUoZmlyc3QoKSkuc3Vic2NyaWJlKChwbGF5ZXI6IFBseXIpID0+IHtcclxuICAgICAgY29uc3QgcmVpbml0VHJpZ2dlcnMgPSBbY2hhbmdlcy5wbHlyT3B0aW9ucywgY2hhbmdlcy5wbHlyUGxheXNJbmxpbmUsIGNoYW5nZXMucGx5ckNyb3NzT3JpZ2luXS5maWx0ZXIodCA9PiAhIXQpO1xyXG5cclxuICAgICAgaWYgKHJlaW5pdFRyaWdnZXJzLmxlbmd0aCkge1xyXG4gICAgICAgIGlmIChyZWluaXRUcmlnZ2Vycy5zb21lKHQgPT4gIXQuZmlyc3RDaGFuZ2UpKSB7XHJcbiAgICAgICAgICB0aGlzLmluaXRQbHlyKHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZVBseXJTb3VyY2UocGxheWVyKTtcclxuICAgICAgfVxyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmRlc3Ryb3lQbGF5ZXIoKTtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHMgPT4gcy51bnN1YnNjcmliZSgpKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMuaW5pdFBseXIoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdFBseXIoZm9yY2UgPSBmYWxzZSkge1xyXG4gICAgaWYgKGZvcmNlIHx8ICF0aGlzLnBsYXllcikge1xyXG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95UGxheWVyKCk7XHJcblxyXG4gICAgICAgIHRoaXMuZHJpdmVyID0gdGhpcy5wbHlyRHJpdmVyIHx8IG5ldyBEZWZhdWx0UGx5ckRyaXZlcigpO1xyXG5cclxuICAgICAgICB0aGlzLmVuc3VyZVZpZGVvRWxlbWVudCgpO1xyXG5cclxuICAgICAgICBjb25zdCBuZXdQbGF5ZXIgPSB0aGlzLmRyaXZlci5jcmVhdGUoe1xyXG4gICAgICAgICAgdmlkZW9FbGVtZW50OiB0aGlzLnZpZGVvRWxlbWVudCxcclxuICAgICAgICAgIG9wdGlvbnM6IHRoaXMucGx5ck9wdGlvbnMsXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlUGx5clNvdXJjZShuZXdQbGF5ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLnBsYXllckNoYW5nZS5uZXh0KG5ld1BsYXllcik7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVQbHlyU291cmNlKHBseXI6IFBseXIpIHtcclxuICAgIHRoaXMuZHJpdmVyLnVwZGF0ZVNvdXJjZSh7XHJcbiAgICAgIHZpZGVvRWxlbWVudDogdGhpcy52aWRlb0VsZW1lbnQsXHJcbiAgICAgIHBseXIsXHJcbiAgICAgIHNvdXJjZToge1xyXG4gICAgICAgIHR5cGU6IHRoaXMucGx5clR5cGUsXHJcbiAgICAgICAgdGl0bGU6IHRoaXMucGx5clRpdGxlLFxyXG4gICAgICAgIHNvdXJjZXM6IHRoaXMucGx5clNvdXJjZXMsXHJcbiAgICAgICAgcG9zdGVyOiB0aGlzLnBseXJQb3N0ZXIsXHJcbiAgICAgICAgdHJhY2tzOiB0aGlzLnBseXJUcmFja3MsXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIHNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTM3MDQxMDIvMTk5MDQ1MVxyXG4gIHByaXZhdGUgY3JlYXRlTGF6eUV2ZW50PFQgZXh0ZW5kcyBQbHlyLlBseXJFdmVudD4obmFtZTogUGx5ci5TdGFuZGFyZEV2ZW50IHwgUGx5ci5IdG1sNUV2ZW50IHwgUGx5ci5Zb3V0dWJlRXZlbnQpOiBFdmVudEVtaXR0ZXI8VD4ge1xyXG4gICAgcmV0dXJuIHRoaXMucGx5ckluaXQucGlwZShcclxuICAgICAgc3dpdGNoTWFwKCgpID0+IG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHRoaXMub24obmFtZSwgKGRhdGE6IFQpID0+IHRoaXMubmdab25lLnJ1bigoKSA9PiBvYnNlcnZlci5uZXh0KGRhdGEpKSkpKVxyXG4gICAgKSBhcyBFdmVudEVtaXR0ZXI8VD47XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRlc3Ryb3lQbGF5ZXIoKSB7XHJcbiAgICBpZiAodGhpcy5wbGF5ZXIpIHtcclxuICAgICAgQXJyYXkuZnJvbSh0aGlzLmV2ZW50cy5rZXlzKCkpLmZvckVhY2gobmFtZSA9PiB0aGlzLm9mZihuYW1lKSk7XHJcblxyXG4gICAgICB0aGlzLmRyaXZlci5kZXN0cm95KHtcclxuICAgICAgICBwbHlyOiB0aGlzLnBsYXllcixcclxuICAgICAgfSk7XHJcblxyXG4gICAgICB0aGlzLnZpZGVvRWxlbWVudCA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldCBob3N0RWxlbWVudCgpIHtcclxuICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcclxuICB9XHJcblxyXG4gIC8vIHRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGJlY2F1c2UgdGhlIHBseXIgaW5zZXJ0cyBjbG9uZSBvZiB0aGUgb3JpZ2luYWwgZWxlbWVudCBvbiBkZXN0cm95XHJcbiAgLy8gc28gd2UgY2F0Y2ggdGhlIGNsb25lIGVsZW1lbnQgcmlnaHQgaGVyZSBhbmQgcmV1c2UgaXRcclxuICBwcml2YXRlIGVuc3VyZVZpZGVvRWxlbWVudCgpIHtcclxuICAgIGNvbnN0IHZpZGVvRWxlbWVudCA9IHRoaXMuaG9zdEVsZW1lbnQucXVlcnlTZWxlY3RvcigndmlkZW8nKTtcclxuXHJcbiAgICBpZiAodmlkZW9FbGVtZW50KSB7XHJcbiAgICAgIHRoaXMudmlkZW9FbGVtZW50ID0gdmlkZW9FbGVtZW50O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy52aWRlb0VsZW1lbnQgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XHJcbiAgICAgIHRoaXMudmlkZW9FbGVtZW50LmNvbnRyb2xzID0gdHJ1ZTtcclxuXHJcbiAgICAgIGlmICh0aGlzLnBseXJDcm9zc09yaWdpbikge1xyXG4gICAgICAgIHRoaXMudmlkZW9FbGVtZW50LnNldEF0dHJpYnV0ZSgnY3Jvc3NvcmlnaW4nLCAnJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLnBseXJQbGF5c0lubGluZSkge1xyXG4gICAgICAgIHRoaXMudmlkZW9FbGVtZW50LnNldEF0dHJpYnV0ZSgncGxheXNpbmxpbmUnLCAnJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5ob3N0RWxlbWVudCwgdGhpcy52aWRlb0VsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbihuYW1lOiBzdHJpbmcsIGhhbmRsZXI6IGFueSkge1xyXG4gICAgdGhpcy5ldmVudHMuc2V0KG5hbWUsIGhhbmRsZXIpO1xyXG4gICAgdGhpcy5wbGF5ZXIub24obmFtZSBhcyBhbnksIGhhbmRsZXIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvZmYobmFtZTogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnBsYXllci5vZmYobmFtZSBhcyBhbnksIHRoaXMuZXZlbnRzLmdldChuYW1lKSk7XHJcbiAgICB0aGlzLmV2ZW50cy5kZWxldGUobmFtZSk7XHJcbiAgfVxyXG59XHJcbiIsIiJdfQ==