ng-image-video-gallery
Version:
Angular Image slider with lightbox. An Angular responsive image slider with lightbox popup. Also support youtube url, image base64 string and mp4 video urls and base64 string.
528 lines • 51.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/slider-lightbox/slider-lightbox.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __read, __spread } from "tslib";
import { ChangeDetectorRef, Component, Inject, Input, Output, EventEmitter, ViewChild, HostListener, ElementRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { DomSanitizer } from '@angular/platform-browser';
/** @type {?} */
var LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE = 'lightbox next';
/** @type {?} */
var LIGHTBOX_PREV_ARROW_CLICK_MESSAGE = 'lightbox previous';
var SliderLightboxComponent = /** @class */ (function () {
function SliderLightboxComponent(cdRef, sanitizer, elRef, document) {
this.cdRef = cdRef;
this.sanitizer = sanitizer;
this.elRef = elRef;
this.document = document;
this.totalImages = 0;
this.nextImageIndex = -1;
this.popupWidth = 1200;
this.marginLeft = 0;
this.imageFullscreenView = false;
this.lightboxPrevDisable = false;
this.lightboxNextDisable = false;
this.showLoading = true;
this.effectStyle = 'none';
this.speed = 1; // default speed in second
// default speed in second
this.title = '';
this.currentImageIndex = 0;
this.imageData = [];
// @Inputs
this.images = [];
this.videoAutoPlay = false;
this.direction = 'ltr';
this.paginationShow = false;
this.infinite = false;
this.arrowKeyMove = true;
this.showVideoControls = true;
// @Output
this.close = new EventEmitter();
this.prevImage = new EventEmitter();
this.nextImage = new EventEmitter();
this.closeLightBox = new EventEmitter();
}
Object.defineProperty(SliderLightboxComponent.prototype, "imageIndex", {
set: /**
* @param {?} index
* @return {?}
*/
function (index) {
if (index !== undefined && index > -1 && index < this.images.length) {
this.currentImageIndex = index;
}
this.nextPrevDisable();
},
enumerable: true,
configurable: true
});
Object.defineProperty(SliderLightboxComponent.prototype, "show", {
set: /**
* @param {?} visiableFlag
* @return {?}
*/
function (visiableFlag) {
this.imageFullscreenView = visiableFlag;
this.elRef.nativeElement.ownerDocument.body.style.overflow = '';
if (visiableFlag === true) {
this.elRef.nativeElement.ownerDocument.body.style.overflow = 'hidden';
// this.getImageData();
this.setPopupSliderWidth();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(SliderLightboxComponent.prototype, "animationSpeed", {
set: /**
* @param {?} data
* @return {?}
*/
function (data) {
if (data
&& typeof (data) === 'number'
&& data >= 0.1
&& data <= 5) {
this.speed = data;
}
},
enumerable: true,
configurable: true
});
/**
* @param {?} event
* @return {?}
*/
SliderLightboxComponent.prototype.onResize = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.effectStyle = 'none';
this.setPopupSliderWidth();
};
/**
* @param {?} event
* @return {?}
*/
SliderLightboxComponent.prototype.handleKeyboardEvent = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event && event.key && this.arrowKeyMove) {
if (event.key.toLowerCase() === 'arrowright') {
this.nextImageLightbox();
}
if (event.key.toLowerCase() === 'arrowleft') {
this.prevImageLightbox();
}
if (event.key.toLowerCase() === 'escape') {
this.closeLightbox();
}
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.imageData = __spread(this.images);
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.resetState();
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.setPopupSliderWidth = /**
* @return {?}
*/
function () {
var _this = this;
if (window && window.innerWidth) {
this.popupWidth = window.innerWidth;
this.totalImages = this.images.length;
if (typeof (this.currentImageIndex) === 'number' && this.currentImageIndex !== undefined) {
this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;
this.getImageData();
this.nextPrevDisable();
setTimeout((/**
* @return {?}
*/
function () {
_this.showLoading = false;
}), 500);
}
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.closeLightbox = /**
* @return {?}
*/
function () {
this.close.emit();
this.closeLightBox.emit(__spread(this.imageData));
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.prevImageLightbox = /**
* @return {?}
*/
function () {
var _this = this;
this.effectStyle = "all " + this.speed + "s ease-in-out";
if (this.currentImageIndex > 0 && !this.lightboxPrevDisable && !this.infinite) {
this.videoPause();
this.currentImageIndex--;
this.prevImage.emit(LIGHTBOX_PREV_ARROW_CLICK_MESSAGE);
this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;
this.getImageData();
this.nextPrevDisable();
}
if (this.infinite) {
this.videoAutoPlay = false;
this.videoPause();
this.currentImageIndex--;
this.prevImage.emit(LIGHTBOX_PREV_ARROW_CLICK_MESSAGE);
this.marginLeft += this.popupWidth;
setTimeout((/**
* @return {?}
*/
function () {
_this.effectStyle = 'none';
_this.marginLeft -= _this.popupWidth;
for (var i = 0; i < 1; i++) {
_this.images.unshift(_this.images[_this.images.length - 1]);
_this.images.pop();
}
}), this.speed * 1000);
this.nextPrevDisable();
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.videoPause = /**
* @return {?}
*/
function () {
document.querySelectorAll('iframe').forEach((/**
* @param {?} iframeUrl
* @return {?}
*/
function (iframeUrl) {
if (iframeUrl.src.startsWith("https://www.youtube.com")) {
iframeUrl.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', "*");
}
if (iframeUrl.src.indexOf('https://players.brightcove.net') !== -1) {
iframeUrl.src = iframeUrl.src + '&muted';
}
if (iframeUrl.src.indexOf('https://player.vimeo.com') !== -1 || iframeUrl.src.indexOf('wistia') !== -1) {
/** @type {?} */
var data = { method: "pause" };
iframeUrl.contentWindow.postMessage(JSON.stringify(data), "*");
}
}));
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.nextImageLightbox = /**
* @return {?}
*/
function () {
var _this = this;
this.effectStyle = "all " + this.speed + "s ease-in-out";
if (this.currentImageIndex < this.images.length - 1 && !this.lightboxNextDisable && !this.infinite) {
this.videoPause();
this.currentImageIndex++;
this.nextImage.emit(LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE);
this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;
this.getImageData();
this.nextPrevDisable();
}
if (this.infinite) {
this.videoAutoPlay = false;
this.videoPause();
this.nextImage.emit(LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE);
this.marginLeft -= this.popupWidth;
setTimeout((/**
* @return {?}
*/
function () {
_this.effectStyle = 'none';
for (var i = 0; i < 1; i++) {
_this.images.push(_this.images[0]);
_this.images.shift();
}
_this.marginLeft += _this.popupWidth;
}), this.speed * 1000);
this.nextPrevDisable();
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.nextPrevDisable = /**
* @return {?}
*/
function () {
var _this = this;
this.lightboxNextDisable = true;
this.lightboxPrevDisable = true;
setTimeout((/**
* @return {?}
*/
function () {
_this.applyButtonDisableCondition();
}), this.speed * 1000);
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.applyButtonDisableCondition = /**
* @return {?}
*/
function () {
this.lightboxNextDisable = false;
this.lightboxPrevDisable = false;
if (!this.infinite && this.currentImageIndex >= this.images.length - 1) {
this.lightboxNextDisable = true;
}
if (!this.infinite && this.currentImageIndex <= 0) {
this.lightboxPrevDisable = true;
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.getImageData = /**
* @return {?}
*/
function () {
if (this.images
&& this.images.length
&& typeof (this.currentImageIndex) === 'number'
&& this.currentImageIndex !== undefined
&& this.images[this.currentImageIndex]
&& (this.images[this.currentImageIndex]['image'] || this.images[this.currentImageIndex]['video'])) {
this.title = this.images[this.currentImageIndex]['title'] || '';
this.galleryData = this.images[this.currentImageIndex];
this.totalImages = this.images.length;
for (var iframeI in this.document.getElementsByTagName('iframe')) {
if (this.document.getElementsByTagName('iframe')[iframeI]
&& this.document.getElementsByTagName('iframe')[iframeI].contentWindow
&& this.document.getElementsByTagName('iframe')[iframeI].contentWindow.postMessage) {
this.document.getElementsByTagName('iframe')[iframeI].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}
}
for (var videoI in this.document.getElementsByTagName('video')) {
if (this.document.getElementsByTagName('video')[videoI] && this.document.getElementsByTagName('video')[videoI].pause) {
this.document.getElementsByTagName('video')[videoI].pause();
}
}
}
};
/**
* @return {?}
*/
SliderLightboxComponent.prototype.resetState = /**
* @return {?}
*/
function () {
this.images = [];
};
/**
* Swipe event handler
* Reference from https://stackoverflow.com/a/44511007/2067646
*/
/**
* Swipe event handler
* Reference from https://stackoverflow.com/a/44511007/2067646
* @param {?} e
* @param {?} when
* @return {?}
*/
SliderLightboxComponent.prototype.swipeLightboxImg = /**
* Swipe event handler
* Reference from https://stackoverflow.com/a/44511007/2067646
* @param {?} e
* @param {?} when
* @return {?}
*/
function (e, when) {
/** @type {?} */
var coord = [e.changedTouches[0].pageX, e.changedTouches[0].pageY];
/** @type {?} */
var time = new Date().getTime();
if (when === 'start') {
this.swipeLightboxImgCoord = coord;
this.swipeLightboxImgTime = time;
}
else if (when === 'end') {
/** @type {?} */
var direction = [coord[0] - this.swipeLightboxImgCoord[0], coord[1] - this.swipeLightboxImgCoord[1]];
/** @type {?} */
var duration = time - this.swipeLightboxImgTime;
if (duration < 1000 //
&& Math.abs(direction[0]) > 30 // Long enough
&& Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough
if (direction[0] < 0) {
this.nextImageLightbox();
}
else {
this.prevImageLightbox();
}
}
}
};
SliderLightboxComponent.decorators = [
{ type: Component, args: [{
selector: 'slider-lightbox',
template: "<div *ngIf=\"imageFullscreenView\" class=\"ng-image-fullscreen-view\">\r\n <div class=\"lightbox-wrapper\" [ngClass]=\"galleryData?.image ? 'lightbox-wrapper-main' : ''\">\r\n <a class=\"close\" (click)=\"closeLightbox()\"></a>\r\n <div class=\"lightbox-div\" #lightboxDiv>\r\n <div [ngClass]=\"galleryData?.image ? 'lightbox-header' : 'lightbox-video-header'\">\r\n <div [ngClass]=\"{'show': title}\" class=\"image-title \">{{ galleryData?.title ? galleryData?.title : '' }}</div>\r\n </div>\r\n <div *ngIf=\"showLoading\" class=\"pre-loader\">\r\n <div class=\"mnml-spinner\"></div>\r\n </div>\r\n <div class=\"lightbox-image-main\" [ngClass]=\"galleryData?.image ? 'lightbox-image-main-wrapper' : ''\"\r\n [ngStyle]=\"{'margin-left': marginLeft + 'px', 'grid-template-columns': 'repeat('+images.length+',1fr)', 'transition': effectStyle}\">\r\n <div class=\"lightbox-image\"\r\n [ngStyle]=\"{'width': popupWidth + 'px'}\"\r\n *ngFor=\"let img of images; let i = index\"\r\n [attr.id]=\"'ng-lightbox-image-' + i\"\r\n (touchstart)=\"swipeLightboxImg($event, 'start')\"\r\n (touchend)=\"swipeLightboxImg($event, 'end')\"\r\n #lightboxImageDiv>\r\n <custom-img\r\n [imageUrl]=\"img?.image || img?.video\"\r\n [isVideo]=\"!!(img?.posterImage || img?.video)\"\r\n [currentImageIndex]=\"currentImageIndex\"\r\n [imageIndex]=\"i\"\r\n [speed]=\"speed\"\r\n [videoAutoPlay]=\"videoAutoPlay && i == currentImageIndex\"\r\n [showVideoControls]=\"showVideoControls ? 1 : 0\"\r\n [alt]=\"img?.alt || img?.title || ''\"\r\n [title]=\"img?.title || img?.alt || ''\"\r\n [showVideo]=\"true\"\r\n [direction]=\"direction\">\r\n </custom-img> \r\n </div>\r\n <!-- <div [dir]=\"direction\" [ngClass]=\"{'show': title, 'hide': !title}\" class=\"caption\">{{ title }}</div> -->\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxPrevDisable}\" class=\"prev icons prev-icon\" (click)=\"prevImageLightbox()\">‹</a>\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxNextDisable}\" class=\"next icons next-icon\" (click)=\"nextImageLightbox()\">›</a>\r\n </div>\r\n <div [ngClass]=\"galleryData?.description ? 'lightbox-footer' : 'lightbox-video-footer' \">\r\n <div [ngClass]=\"galleryData?.description ? 'image-description' : ''\">{{ galleryData?.description ? galleryData?.description : '' }}</div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"paginationShow\" class=\"popup-pagination\">{{currentImageIndex + 1}} of {{totalImages}}</div>\r\n</div>\r\n",
styles: [".lightbox-header{color:#fff;padding:20px 45px}.lightbox-header .image-title{-webkit-box-orient:vertical;display:-webkit-box;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;word-break:break-all}.lightbox-image-main-wrapper{margin-bottom:20px}.lightbox-footer{color:#fff;padding:20px}.lightbox-footer .image-description{text-align:center;-webkit-box-orient:vertical;display:-webkit-box;-webkit-line-clamp:5;overflow:hidden;text-overflow:ellipsis;word-break:break-all}"]
}] }
];
/** @nocollapse */
SliderLightboxComponent.ctorParameters = function () { return [
{ type: ChangeDetectorRef },
{ type: DomSanitizer },
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
]; };
SliderLightboxComponent.propDecorators = {
lightboxDiv: [{ type: ViewChild, args: ['lightboxDiv', { static: false },] }],
lightboxImageDiv: [{ type: ViewChild, args: ['lightboxImageDiv', { static: false },] }],
lightboxTextDiv: [{ type: ViewChild, args: ['lightboxTextDiv', { static: false },] }],
images: [{ type: Input }],
imageIndex: [{ type: Input }],
show: [{ type: Input }],
videoAutoPlay: [{ type: Input }],
direction: [{ type: Input }],
paginationShow: [{ type: Input }],
animationSpeed: [{ type: Input }],
infinite: [{ type: Input }],
arrowKeyMove: [{ type: Input }],
showVideoControls: [{ type: Input }],
close: [{ type: Output }],
prevImage: [{ type: Output }],
nextImage: [{ type: Output }],
closeLightBox: [{ type: Output }],
onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }],
handleKeyboardEvent: [{ type: HostListener, args: ['document:keyup', ['$event'],] }]
};
return SliderLightboxComponent;
}());
export { SliderLightboxComponent };
if (false) {
/** @type {?} */
SliderLightboxComponent.prototype.totalImages;
/** @type {?} */
SliderLightboxComponent.prototype.nextImageIndex;
/** @type {?} */
SliderLightboxComponent.prototype.popupWidth;
/** @type {?} */
SliderLightboxComponent.prototype.marginLeft;
/** @type {?} */
SliderLightboxComponent.prototype.imageFullscreenView;
/** @type {?} */
SliderLightboxComponent.prototype.lightboxPrevDisable;
/** @type {?} */
SliderLightboxComponent.prototype.lightboxNextDisable;
/** @type {?} */
SliderLightboxComponent.prototype.showLoading;
/** @type {?} */
SliderLightboxComponent.prototype.effectStyle;
/** @type {?} */
SliderLightboxComponent.prototype.speed;
/** @type {?} */
SliderLightboxComponent.prototype.title;
/** @type {?} */
SliderLightboxComponent.prototype.currentImageIndex;
/** @type {?} */
SliderLightboxComponent.prototype.galleryData;
/** @type {?} */
SliderLightboxComponent.prototype.imageData;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.swipeLightboxImgCoord;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.swipeLightboxImgTime;
/** @type {?} */
SliderLightboxComponent.prototype.lightboxDiv;
/** @type {?} */
SliderLightboxComponent.prototype.lightboxImageDiv;
/** @type {?} */
SliderLightboxComponent.prototype.lightboxTextDiv;
/** @type {?} */
SliderLightboxComponent.prototype.images;
/** @type {?} */
SliderLightboxComponent.prototype.videoAutoPlay;
/** @type {?} */
SliderLightboxComponent.prototype.direction;
/** @type {?} */
SliderLightboxComponent.prototype.paginationShow;
/** @type {?} */
SliderLightboxComponent.prototype.infinite;
/** @type {?} */
SliderLightboxComponent.prototype.arrowKeyMove;
/** @type {?} */
SliderLightboxComponent.prototype.showVideoControls;
/** @type {?} */
SliderLightboxComponent.prototype.close;
/** @type {?} */
SliderLightboxComponent.prototype.prevImage;
/** @type {?} */
SliderLightboxComponent.prototype.nextImage;
/** @type {?} */
SliderLightboxComponent.prototype.closeLightBox;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.cdRef;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.sanitizer;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.elRef;
/**
* @type {?}
* @private
*/
SliderLightboxComponent.prototype.document;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLWxpZ2h0Ym94LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWltYWdlLXZpZGVvLWdhbGxlcnkvIiwic291cmNlcyI6WyJsaWIvc2xpZGVyLWxpZ2h0Ym94L3NsaWRlci1saWdodGJveC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsT0FBTyxFQUNILGlCQUFpQixFQUNqQixTQUFTLEVBSVQsTUFBTSxFQUdOLEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7O0lBRW5ELGlDQUFpQyxHQUFHLGVBQWU7O0lBQ3JELGlDQUFpQyxHQUFHLG1CQUFtQjtBQUUzRDtJQTJGSSxpQ0FDWSxLQUF3QixFQUN4QixTQUF1QixFQUN2QixLQUFpQixFQUNDLFFBQWE7UUFIL0IsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDeEIsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2QixVQUFLLEdBQUwsS0FBSyxDQUFZO1FBQ0MsYUFBUSxHQUFSLFFBQVEsQ0FBSztRQXpGM0MsZ0JBQVcsR0FBVyxDQUFDLENBQUM7UUFDeEIsbUJBQWMsR0FBVyxDQUFDLENBQUMsQ0FBQztRQUM1QixlQUFVLEdBQVcsSUFBSSxDQUFDO1FBQzFCLGVBQVUsR0FBVyxDQUFDLENBQUM7UUFDdkIsd0JBQW1CLEdBQVksS0FBSyxDQUFDO1FBQ3JDLHdCQUFtQixHQUFZLEtBQUssQ0FBQztRQUNyQyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDckMsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFDNUIsZ0JBQVcsR0FBVyxNQUFNLENBQUM7UUFDN0IsVUFBSyxHQUFXLENBQUMsQ0FBQyxDQUFDLDBCQUEwQjs7UUFD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OztJQUM3Qix3Q0FBa0I7O0lBQ2xCLHdDQUFtQjs7SUFDbkIsb0RBQThCOztJQUM5Qiw4Q0FBWTs7SUFDWiw0Q0FBYTs7Ozs7SUFFYix3REFBaUQ7Ozs7O0lBQ2pELHVEQUFzQzs7SUFFdEMsOENBQXlEOztJQUN6RCxtREFBbUU7O0lBQ25FLGtEQUFpRTs7SUFHakUseUNBQW9DOztJQWtCcEMsZ0RBQXdDOztJQUN4Qyw0Q0FBbUM7O0lBQ25DLGlEQUF5Qzs7SUFVekMsMkNBQW1DOztJQUNuQywrQ0FBc0M7O0lBQ3RDLG9EQUEyQzs7SUFHM0Msd0NBQTBDOztJQUMxQyw0Q0FBOEM7O0lBQzlDLDRDQUE4Qzs7SUFDOUMsZ0RBQXdFOzs7OztJQXlCcEUsd0NBQWdDOzs7OztJQUNoQyw0Q0FBK0I7Ozs7O0lBQy9CLHdDQUF5Qjs7Ozs7SUFDekIsMkNBQXVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgT25Jbml0LFxyXG4gICAgT25DaGFuZ2VzLFxyXG4gICAgU2ltcGxlQ2hhbmdlcyxcclxuICAgIEluamVjdCxcclxuICAgIEFmdGVyVmlld0luaXQsXHJcbiAgICBPbkRlc3Ryb3ksXHJcbiAgICBJbnB1dCxcclxuICAgIE91dHB1dCxcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIFZpZXdDaGlsZCxcclxuICAgIEhvc3RMaXN0ZW5lcixcclxuICAgIEVsZW1lbnRSZWZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcclxuXHJcbmNvbnN0IExJR0hUQk9YX05FWFRfQVJST1dfQ0xJQ0tfTUVTU0FHRSA9ICdsaWdodGJveCBuZXh0JyxcdFxyXG4gICAgTElHSFRCT1hfUFJFVl9BUlJPV19DTElDS19NRVNTQUdFID0gJ2xpZ2h0Ym94IHByZXZpb3VzJ1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NsaWRlci1saWdodGJveCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2xpZGVyLWxpZ2h0Ym94LmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL3NsaWRlci1saWdodGJveC5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTbGlkZXJMaWdodGJveENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICAgIHRvdGFsSW1hZ2VzOiBudW1iZXIgPSAwO1xyXG4gICAgbmV4dEltYWdlSW5kZXg6IG51bWJlciA9IC0xO1xyXG4gICAgcG9wdXBXaWR0aDogbnVtYmVyID0gMTIwMDtcclxuICAgIG1hcmdpbkxlZnQ6IG51bWJlciA9IDA7XHJcbiAgICBpbWFnZUZ1bGxzY3JlZW5WaWV3OiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBsaWdodGJveFByZXZEaXNhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBsaWdodGJveE5leHREaXNhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBzaG93TG9hZGluZzogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBlZmZlY3RTdHlsZTogc3RyaW5nID0gJ25vbmUnO1xyXG4gICAgc3BlZWQ6IG51bWJlciA9IDE7IC8vIGRlZmF1bHQgc3BlZWQgaW4gc2Vjb25kXHJcbiAgICB0aXRsZTogc3RyaW5nID0gJyc7XHJcbiAgICBjdXJyZW50SW1hZ2VJbmRleDogbnVtYmVyID0gMDtcclxuICAgIGdhbGxlcnlEYXRhO1xyXG4gICAgaW1hZ2VEYXRhPVtdO1xyXG4gICAgLy8gZm9yIHN3aXBlIGV2ZW50XHJcbiAgICBwcml2YXRlIHN3aXBlTGlnaHRib3hJbWdDb29yZD86IFtudW1iZXIsIG51bWJlcl07XHJcbiAgICBwcml2YXRlIHN3aXBlTGlnaHRib3hJbWdUaW1lPzogbnVtYmVyO1xyXG5cclxuICAgIEBWaWV3Q2hpbGQoJ2xpZ2h0Ym94RGl2JywgeyBzdGF0aWM6IGZhbHNlIH0pIGxpZ2h0Ym94RGl2O1xyXG4gICAgQFZpZXdDaGlsZCgnbGlnaHRib3hJbWFnZURpdicsIHsgc3RhdGljOiBmYWxzZSB9KSBsaWdodGJveEltYWdlRGl2O1xyXG4gICAgQFZpZXdDaGlsZCgnbGlnaHRib3hUZXh0RGl2JywgeyBzdGF0aWM6IGZhbHNlIH0pIGxpZ2h0Ym94VGV4dERpdjtcclxuXHJcbiAgICAvLyBASW5wdXRzXHJcbiAgICBASW5wdXQoKSBpbWFnZXM6IEFycmF5PG9iamVjdD4gPSBbXTtcclxuICAgIEBJbnB1dCgpXHJcbiAgICBzZXQgaW1hZ2VJbmRleChpbmRleDogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgaW5kZXggPiAtMSAmJiBpbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID0gaW5kZXg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICB9XHJcbiAgICBASW5wdXQoKVxyXG4gICAgc2V0IHNob3codmlzaWFibGVGbGFnOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5pbWFnZUZ1bGxzY3JlZW5WaWV3ID0gdmlzaWFibGVGbGFnO1xyXG4gICAgICAgIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnJztcclxuICAgICAgICBpZiAodmlzaWFibGVGbGFnID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgLy8gdGhpcy5nZXRJbWFnZURhdGEoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXRQb3B1cFNsaWRlcldpZHRoKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCkgdmlkZW9BdXRvUGxheTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgZGlyZWN0aW9uOiBzdHJpbmcgPSAnbHRyJztcclxuICAgIEBJbnB1dCgpIHBhZ2luYXRpb25TaG93OiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKVxyXG4gICAgc2V0IGFuaW1hdGlvblNwZWVkKGRhdGE6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChkYXRhXHJcbiAgICAgICAgICAgICYmIHR5cGVvZiAoZGF0YSkgPT09ICdudW1iZXInXHJcbiAgICAgICAgICAgICYmIGRhdGEgPj0gMC4xXHJcbiAgICAgICAgICAgICYmIGRhdGEgPD0gNSkge1xyXG4gICAgICAgICAgICB0aGlzLnNwZWVkID0gZGF0YTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoKSBpbmZpbml0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgYXJyb3dLZXlNb3ZlOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIHNob3dWaWRlb0NvbnRyb2xzOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgICAvLyBAT3V0cHV0XHJcbiAgICBAT3V0cHV0KCkgY2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSBwcmV2SW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSBuZXh0SW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSBjbG9zZUxpZ2h0Qm94OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxyXG4gICAgb25SZXNpemUoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmVmZmVjdFN0eWxlID0gJ25vbmUnO1xyXG4gICAgICAgIHRoaXMuc2V0UG9wdXBTbGlkZXJXaWR0aCgpO1xyXG4gICAgfVxyXG4gICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5dXAnLCBbJyRldmVudCddKVxyXG4gICAgaGFuZGxlS2V5Ym9hcmRFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgICAgIGlmIChldmVudCAmJiBldmVudC5rZXkgJiYgdGhpcy5hcnJvd0tleU1vdmUpIHtcclxuICAgICAgICAgICAgaWYgKGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpID09PSAnYXJyb3dyaWdodCcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV4dEltYWdlTGlnaHRib3goKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpID09PSAnYXJyb3dsZWZ0Jykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2SW1hZ2VMaWdodGJveCgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZXZlbnQua2V5LnRvTG93ZXJDYXNlKCkgPT09ICdlc2NhcGUnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlTGlnaHRib3goKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgICAgICBwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyLFxyXG4gICAgICAgIHByaXZhdGUgZWxSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogYW55KSB7IH1cclxuXHJcbiAgICBuZ09uSW5pdCgpIHtcclxuICAgICAgICB0aGlzLmltYWdlRGF0YT1bLi4udGhpcy5pbWFnZXNdXHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMucmVzZXRTdGF0ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFBvcHVwU2xpZGVyV2lkdGgoKSB7XHJcbiAgICAgICAgaWYgKHdpbmRvdyAmJiB3aW5kb3cuaW5uZXJXaWR0aCkge1xyXG4gICAgICAgICAgICB0aGlzLnBvcHVwV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IHRoaXMuaW1hZ2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCkgPT09ICdudW1iZXInICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXJnaW5MZWZ0ID0gLTEgKiB0aGlzLnBvcHVwV2lkdGggKiB0aGlzLmN1cnJlbnRJbWFnZUluZGV4O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRJbWFnZURhdGEoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LCA1MDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlTGlnaHRib3goKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZS5lbWl0KCk7XHJcbiAgICAgICAgdGhpcy5jbG9zZUxpZ2h0Qm94LmVtaXQoWy4uLnRoaXMuaW1hZ2VEYXRhXSk7IFxyXG4gICAgfVxyXG5cclxuICAgIHByZXZJbWFnZUxpZ2h0Ym94KCkge1xyXG4gICAgICAgIHRoaXMuZWZmZWN0U3R5bGUgPSBgYWxsICR7dGhpcy5zcGVlZH1zIGVhc2UtaW4tb3V0YDtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCA+IDAgJiYgIXRoaXMubGlnaHRib3hQcmV2RGlzYWJsZSAmJiAhdGhpcy5pbmZpbml0ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnZpZGVvUGF1c2UoKTtcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SW1hZ2VJbmRleC0tO1xyXG4gICAgICAgICAgICB0aGlzLnByZXZJbWFnZS5lbWl0KExJR0hUQk9YX1BSRVZfQVJST1dfQ0xJQ0tfTUVTU0FHRSk7XHJcbiAgICAgICAgICAgIHRoaXMubWFyZ2luTGVmdCA9IC0xICogdGhpcy5wb3B1cFdpZHRoICogdGhpcy5jdXJyZW50SW1hZ2VJbmRleDtcclxuICAgICAgICAgICAgdGhpcy5nZXRJbWFnZURhdGEoKTtcclxuICAgICAgICAgICAgdGhpcy5uZXh0UHJldkRpc2FibGUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYodGhpcy5pbmZpbml0ZSl7XHJcbiAgICAgICAgICAgIHRoaXMudmlkZW9BdXRvUGxheT1mYWxzZTtcclxuICAgICAgICAgICAgdGhpcy52aWRlb1BhdXNlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEltYWdlSW5kZXgtLTtcclxuICAgICAgICAgICAgdGhpcy5wcmV2SW1hZ2UuZW1pdChMSUdIVEJPWF9QUkVWX0FSUk9XX0NMSUNLX01FU1NBR0UpO1xyXG4gICAgICAgICAgICB0aGlzLm1hcmdpbkxlZnQgKz10aGlzLnBvcHVwV2lkdGggO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZWZmZWN0U3R5bGUgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1hcmdpbkxlZnQgLT0gIHRoaXMucG9wdXBXaWR0aCA7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDE7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VzLnVuc2hpZnQodGhpcy5pbWFnZXNbdGhpcy5pbWFnZXMubGVuZ3RoLTFdKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmltYWdlcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgdGhpcy5zcGVlZCAqIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLm5leHRQcmV2RGlzYWJsZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2aWRlb1BhdXNlKCkge1xyXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lmcmFtZScpLmZvckVhY2goaWZyYW1lVXJsPT4ge1xyXG4gICAgICAgICAgICBpZiAoaWZyYW1lVXJsLnNyYy5zdGFydHNXaXRoKFwiaHR0cHM6Ly93d3cueW91dHViZS5jb21cIikpIHtcclxuICAgICAgICAgICAgICAgaWZyYW1lVXJsLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoJ3tcImV2ZW50XCI6XCJjb21tYW5kXCIsXCJmdW5jXCI6XCJwYXVzZVZpZGVvXCIsXCJhcmdzXCI6XCJcIn0nLFwiKlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZihpZnJhbWVVcmwuc3JjLmluZGV4T2YoJ2h0dHBzOi8vcGxheWVycy5icmlnaHRjb3ZlLm5ldCcpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgIGlmcmFtZVVybC5zcmMgPSBpZnJhbWVVcmwuc3JjKycmbXV0ZWQnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICBpZihpZnJhbWVVcmwuc3JjLmluZGV4T2YoJ2h0dHBzOi8vcGxheWVyLnZpbWVvLmNvbScpICE9PSAtMSB8fCBpZnJhbWVVcmwuc3JjLmluZGV4T2YoJ3dpc3RpYScpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSB7IG1ldGhvZDogXCJwYXVzZVwiIH07XHJcbiAgICAgICAgICAgICAgICBpZnJhbWVVcmwuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShKU09OLnN0cmluZ2lmeShkYXRhKSwgXCIqXCIpOyAgICAgICBcclxuICAgICAgICAgICB9IFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgICBcclxuICAgIH1cclxuXHJcbiAgICBuZXh0SW1hZ2VMaWdodGJveCgpIHtcclxuICAgICAgICB0aGlzLmVmZmVjdFN0eWxlID0gYGFsbCAke3RoaXMuc3BlZWR9cyBlYXNlLWluLW91dGA7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEltYWdlSW5kZXggPCB0aGlzLmltYWdlcy5sZW5ndGggLSAxICYmICF0aGlzLmxpZ2h0Ym94TmV4dERpc2FibGUgJiYgIXRoaXMuaW5maW5pdGUpIHtcclxuICAgICAgICAgICAgdGhpcy52aWRlb1BhdXNlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEltYWdlSW5kZXgrKztcclxuICAgICAgICAgICAgdGhpcy5uZXh0SW1hZ2UuZW1pdChMSUdIVEJPWF9ORVhUX0FSUk9XX0NMSUNLX01FU1NBR0UpO1xyXG4gICAgICAgICAgICB0aGlzLm1hcmdpbkxlZnQgPSAtMSAqIHRoaXMucG9wdXBXaWR0aCAqIHRoaXMuY3VycmVudEltYWdlSW5kZXg7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0SW1hZ2VEYXRhKCk7XHJcbiAgICAgICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKHRoaXMuaW5maW5pdGUpe1xyXG4gICAgICAgICAgICB0aGlzLnZpZGVvQXV0b1BsYXk9ZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMudmlkZW9QYXVzZSgpO1xyXG4gICAgICAgICAgICB0aGlzLm5leHRJbWFnZS5lbWl0KExJR0hUQk9YX05FWFRfQVJST1dfQ0xJQ0tfTUVTU0FHRSk7XHJcbiAgICAgICAgICAgIHRoaXMubWFyZ2luTGVmdCAtPXRoaXMucG9wdXBXaWR0aCA7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lZmZlY3RTdHlsZSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbWFnZXMucHVzaCh0aGlzLmltYWdlc1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbWFnZXMuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgdGhpcy5tYXJnaW5MZWZ0ICs9IHRoaXMucG9wdXBXaWR0aDtcclxuICAgICAgICAgICAgfSwgdGhpcy5zcGVlZCAqIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLm5leHRQcmV2RGlzYWJsZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBuZXh0UHJldkRpc2FibGUoKSB7XHJcbiAgICAgICAgdGhpcy5saWdodGJveE5leHREaXNhYmxlID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmxpZ2h0Ym94UHJldkRpc2FibGUgPSB0cnVlO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFwcGx5QnV0dG9uRGlzYWJsZUNvbmRpdGlvbigpO1xyXG4gICAgICAgIH0sIHRoaXMuc3BlZWQgKiAxMDAwKTtcclxuICAgIH1cclxuXHJcbiAgICBhcHBseUJ1dHRvbkRpc2FibGVDb25kaXRpb24oKSB7XHJcbiAgICAgICAgdGhpcy5saWdodGJveE5leHREaXNhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5saWdodGJveFByZXZEaXNhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgaWYgKCF0aGlzLmluZmluaXRlICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggPj0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICB0aGlzLmxpZ2h0Ym94TmV4dERpc2FibGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuaW5maW5pdGUgJiYgdGhpcy5jdXJyZW50SW1hZ2VJbmRleCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGlnaHRib3hQcmV2RGlzYWJsZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldEltYWdlRGF0YSgpIHtcclxuICAgICAgICBpZiAodGhpcy5pbWFnZXNcclxuICAgICAgICAgICAgJiYgdGhpcy5pbWFnZXMubGVuZ3RoXHJcbiAgICAgICAgICAgICYmIHR5cGVvZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCkgPT09ICdudW1iZXInXHJcbiAgICAgICAgICAgICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggIT09IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAmJiB0aGlzLmltYWdlc1t0aGlzLmN1cnJlbnRJbWFnZUluZGV4XVxyXG4gICAgICAgICAgICAmJiAodGhpcy5pbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2VJbmRleF1bJ2ltYWdlJ10gfHwgdGhpcy5pbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2VJbmRleF1bJ3ZpZGVvJ10pKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGl0bGUgPSB0aGlzLmltYWdlc1t0aGlzLmN1cnJlbnRJbWFnZUluZGV4XVsndGl0bGUnXSB8fCAnJztcclxuICAgICAgICAgICAgdGhpcy5nYWxsZXJ5RGF0YSA9IHRoaXMuaW1hZ2VzW3RoaXMuY3VycmVudEltYWdlSW5kZXhdO1xyXG4gICAgICAgICAgICB0aGlzLnRvdGFsSW1hZ2VzID0gdGhpcy5pbWFnZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlmcmFtZUkgaW4gdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJykpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpZnJhbWUnKVtpZnJhbWVJXVxyXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lmcmFtZScpW2lmcmFtZUldLmNvbnRlbnRXaW5kb3dcclxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpZnJhbWUnKVtpZnJhbWVJXS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJylbaWZyYW1lSV0uY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSgne1wiZXZlbnRcIjpcImNvbW1hbmRcIixcImZ1bmNcIjpcInBhdXNlVmlkZW9cIixcImFyZ3NcIjpcIlwifScsICcqJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm9yIChjb25zdCB2aWRlb0kgaW4gdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndmlkZW8nKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3ZpZGVvJylbdmlkZW9JXSAmJiB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd2aWRlbycpW3ZpZGVvSV0ucGF1c2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd2aWRlbycpW3ZpZGVvSV0ucGF1c2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXNldFN0YXRlKCkge1xyXG4gICAgICAgIHRoaXMuaW1hZ2VzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTd2lwZSBldmVudCBoYW5kbGVyXHJcbiAgICAgKiBSZWZlcmVuY2UgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNDQ1MTEwMDcvMjA2NzY0NlxyXG4gICAgICovXHJcbiAgICBzd2lwZUxpZ2h0Ym94SW1nKGU6IFRvdWNoRXZlbnQsIHdoZW46IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGNvb3JkOiBbbnVtYmVyLCBudW1iZXJdID0gW2UuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVgsIGUuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVldO1xyXG4gICAgICAgIGNvbnN0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuXHJcbiAgICAgICAgaWYg