@oxyvn/ngx-gallery
Version:
A simple responsive native gallery component for Angular 8+ and 13+.
446 lines • 65.9 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { NgxGalleryAnimation } from '../ngx-gallery-animation';
import { animate, state, style, transition, trigger } from '@angular/animations';
import * as i0 from "@angular/core";
import * as i1 from "@angular/platform-browser";
import * as i2 from "../ngx-gallery.service";
import * as i3 from "@angular/common";
import * as i4 from "../ngx-gallery-arrows/ngx-gallery-arrows.component";
import * as i5 from "../ngx-gallery-action/ngx-gallery-action.component";
import * as i6 from "../ngx-gallery-bullets/ngx-gallery-bullets.component";
export class NgxGalleryImageComponent {
set selectedIndex(index) {
if (index > this._selectedIndex) {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideRight';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateRight';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
}
else if (index < this._selectedIndex) {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideLeft';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateLeft';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
}
this._selectedIndex = index;
}
constructor(sanitization, changeDetectorRef, elementRef, helperService) {
this.sanitization = sanitization;
this.changeDetectorRef = changeDetectorRef;
this.elementRef = elementRef;
this.helperService = helperService;
this.imageClick = new EventEmitter();
this.activeChange = new EventEmitter();
this.animating = new EventEmitter();
this.canChangeImage = true;
this.isAnimating = false;
this.changeDetectorRef = changeDetectorRef;
this.action = 'none';
}
// @HostBinding('style.display') public display = 'inline-block';
// @HostBinding('style.background-color') public color = 'lime';
ngOnInit() {
if (this.arrows && this.arrowsAutoHide) {
this.arrows = false;
}
if (this.autoPlay) {
this.startAutoPlay();
}
}
ngOnChanges(changes) {
if (changes['swipe']) {
this.helperService.manageSwipe(this.swipe, this.elementRef, 'image', () => this.showNext(), () => this.showPrev());
}
}
onMouseEnter() {
if (this.arrowsAutoHide && !this.arrows) {
this.arrows = true;
}
if (this.autoPlay && this.autoPlayPauseOnHover) {
this.stopAutoPlay();
}
}
onMouseLeave() {
if (this.arrowsAutoHide && this.arrows) {
this.arrows = false;
}
if (this.autoPlay && this.autoPlayPauseOnHover) {
this.startAutoPlay();
}
}
reset(index) {
this._selectedIndex = index;
this.action = 'none';
}
getImages() {
if (!this.images) {
return [];
}
if (this.lazyLoading) {
const indexes = [this._selectedIndex];
const prevIndex = this._selectedIndex - 1;
if (prevIndex === -1 && this.infinityMove) {
indexes.push(this.images.length - 1);
}
else if (prevIndex >= 0) {
indexes.push(prevIndex);
}
const nextIndex = this._selectedIndex + 1;
if (nextIndex === this.images.length && this.infinityMove) {
indexes.push(0);
}
else if (nextIndex < this.images.length) {
indexes.push(nextIndex);
}
return this.images.filter((img, i) => indexes.indexOf(i) !== -1);
}
else {
return this.images;
}
}
startAutoPlay() {
this.stopAutoPlay();
this.timer = setInterval(() => {
if (!this.showNext()) {
this._selectedIndex = -1;
this.showNext();
}
}, this.autoPlayInterval);
}
stopAutoPlay() {
if (this.timer) {
clearInterval(this.timer);
}
}
handleClick(event, index) {
if (this.clickable) {
this.imageClick.emit(index);
event.stopPropagation();
event.preventDefault();
}
}
show(index) {
if (this.isAnimating) {
return;
}
if (index > this._selectedIndex) {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideRight';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateRight';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
}
else {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideLeft';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateLeft';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
}
this._selectedIndex = index;
this.activeChange.emit(this._selectedIndex);
this.setChangeTimeout();
}
setAction(action) {
this.action = action;
this.changeDetectorRef.detectChanges();
}
showNext() {
if (this.isAnimating) {
return false;
}
if (this.canShowNext() && this.canChangeImage) {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideRight';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateRight';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
this._selectedIndex++;
if (this._selectedIndex === this.images.length) {
this._selectedIndex = 0;
}
this.activeChange.emit(this._selectedIndex);
this.setChangeTimeout();
return true;
}
else {
return false;
}
}
showPrev() {
if (this.isAnimating) {
return;
}
if (this.canShowPrev() && this.canChangeImage) {
let action;
if (this.animation === NgxGalleryAnimation.Slide) {
action = 'slideLeft';
}
else if (this.animation === NgxGalleryAnimation.Fade) {
action = 'fade';
}
else if (this.animation === NgxGalleryAnimation.Rotate) {
action = 'rotateLeft';
}
else if (this.animation === NgxGalleryAnimation.Zoom) {
action = 'zoom';
}
this.setAction(action);
this._selectedIndex--;
if (this._selectedIndex < 0) {
this._selectedIndex = this.images.length - 1;
}
this.activeChange.emit(this._selectedIndex);
this.setChangeTimeout();
}
}
setChangeTimeout() {
this.canChangeImage = false;
let timeout = 1000;
if (this.animation === NgxGalleryAnimation.Slide
|| this.animation === NgxGalleryAnimation.Fade) {
timeout = 500;
}
setTimeout(() => {
this.canChangeImage = true;
}, timeout);
}
canShowNext() {
if (this.images) {
return this.infinityMove || this._selectedIndex < this.images.length - 1;
}
else {
return false;
}
}
canShowPrev() {
if (this.images) {
return this.infinityMove || this._selectedIndex > 0;
}
else {
return false;
}
}
getSafeUrl(image) {
return this.sanitization.bypassSecurityTrustStyle(this.helperService.getBackgroundUrl(image.toString()));
}
getFileType(fileSource) {
return this.helperService.getFileType(fileSource);
}
onStart(event) {
this.isAnimating = true;
this.animating.emit(true);
}
onDone(event) {
this.isAnimating = false;
this.animating.emit(false);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NgxGalleryImageComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i2.NgxGalleryService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", type: NgxGalleryImageComponent, selector: "ngx-gallery-image", inputs: { images: "images", clickable: "clickable", selectedIndex: "selectedIndex", arrows: "arrows", arrowsAutoHide: "arrowsAutoHide", swipe: "swipe", animation: "animation", size: "size", arrowPrevIcon: "arrowPrevIcon", arrowNextIcon: "arrowNextIcon", autoPlay: "autoPlay", autoPlayInterval: "autoPlayInterval", autoPlayPauseOnHover: "autoPlayPauseOnHover", infinityMove: "infinityMove", lazyLoading: "lazyLoading", actions: "actions", descriptions: "descriptions", showDescription: "showDescription", bullets: "bullets" }, outputs: { imageClick: "imageClick", activeChange: "activeChange", animating: "animating" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ngx-gallery-image-wrapper ngx-gallery-animation-{{animation}} ngx-gallery-image-size-{{size}}\">\n <ng-container *ngFor=\"let image of getImages(); let i = index;\">\n\n <div *ngIf=\"image.type === 'image' && image.index === _selectedIndex\" class=\"ngx-gallery-image\"\n [ngClass]=\"{'ngx-gallery-clickable': clickable }\"\n [style.background-image]=\"getSafeUrl(image.src)\"\n (click)=\"handleClick($event, image.index)\"\n [@animation]=\"action\"\n (@animation.start)=\"onStart($event)\"\n (@animation.done)=\"onDone($event)\">\n <div class=\"ngx-gallery-icons-wrapper\">\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\n [titleText]=\"action.titleText\"\n (closeClick)=\"action.onClick($event, image.index)\"></ngx-gallery-action>\n </div>\n <div class=\"ngx-gallery-image-text\" *ngIf=\"showDescription && descriptions[image.index]\"\n [innerHTML]=\"descriptions[image.index]\" (click)=\"$event.stopPropagation()\"></div>\n </div>\n\n <div *ngIf=\"image.type === 'video' && image.index === _selectedIndex\" class=\"ngx-gallery-image\"\n [ngClass]=\"{'ngx-gallery-clickable': clickable }\"\n [style.background-image]=\"getSafeUrl(image.src)\"\n (click)=\"handleClick($event, image.index)\"\n [@animation]=\"action\"\n (@animation.start)=\"onStart($event)\"\n (@animation.done)=\"onDone($event)\">\n <video controls style=\"width:100%; height:100%; background: #000;\">\n <source [src]=\"image.src\">\n Your browser does not support the video tag.\n </video>\n <div class=\"ngx-gallery-icons-wrapper\">\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\n [titleText]=\"action.titleText\"\n (closeClick)=\"action.onClick($event, image.index)\"></ngx-gallery-action>\n </div>\n <div class=\"ngx-gallery-image-text\" *ngIf=\"showDescription && descriptions[image.index]\"\n [innerHTML]=\"descriptions[image.index]\" (click)=\"$event.stopPropagation()\"></div>\n </div>\n\n\n </ng-container>\n <ngx-gallery-bullets *ngIf=\"bullets\" [count]=\"images.length\" [active]=\"_selectedIndex\"\n (bulletChange)=\"show($event)\"></ngx-gallery-bullets>\n <ngx-gallery-arrows class=\"ngx-gallery-image-size-{{size}}\" *ngIf=\"arrows\" (prevClick)=\"showPrev()\"\n (nextClick)=\"showNext()\" [prevDisabled]=\"!canShowPrev()\" [nextDisabled]=\"!canShowNext()\"\n [arrowPrevIcon]=\"arrowPrevIcon\" [arrowNextIcon]=\"arrowNextIcon\"></ngx-gallery-arrows>\n</div>\n", styles: [":host{width:100%;display:inline-block;position:relative;font-size:25px}.ngx-gallery-image-wrapper{width:100%;height:100%;position:absolute;left:0;top:0;overflow:hidden}.ngx-gallery-image{background-position:center;background-repeat:no-repeat;height:100%;width:100%;position:absolute;top:0}.ngx-gallery-image-size-cover .ngx-gallery-image{background-size:cover}.ngx-gallery-image-size-contain .ngx-gallery-image{background-size:contain}.ngx-gallery-animation-fade .ngx-gallery-image{left:0;opacity:1;transition:.5s ease-in-out}.ngx-gallery-animation-fade .ngx-gallery-image.ngx-gallery-active{opacity:1}.ngx-gallery-animation-rotate .ngx-gallery-image{transition:1s ease;transform:scale(1) rotate(0);left:0;opacity:1}.ngx-gallery-animation-zoom .ngx-gallery-image{transition:1s ease;transform:scale(1);left:0;opacity:1}.ngx-gallery-image-text{width:100%;background:#000000b3;padding:10px;text-align:center;color:#fff;font-size:16px;position:absolute;bottom:0;z-index:10}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.NgxGalleryArrowsComponent, selector: "ngx-gallery-arrows", inputs: ["prevDisabled", "nextDisabled", "arrowPrevIcon", "arrowNextIcon"], outputs: ["prevClick", "nextClick"] }, { kind: "component", type: i5.NgxGalleryActionComponent, selector: "ngx-gallery-action", inputs: ["icon", "disabled", "titleText"], outputs: ["closeClick"] }, { kind: "component", type: i6.NgxGalleryBulletsComponent, selector: "ngx-gallery-bullets", inputs: ["count", "active"], outputs: ["bulletChange"] }], animations: [
trigger('animation', [
// ...
state('slideRight', style({})),
state('slideLeft', style({})),
state('fade', style({})),
state('rotateLeft', style({})),
state('rotateRight', style({})),
state('zoom', style({})),
transition('slideRight => void', [
animate('500ms ease-in-out', style({ transform: 'translateX(-100%)' }))
]),
transition('void => slideRight', [
style({ transform: 'translateX(100%)' }),
animate('500ms ease-in-out', style({ transform: 'translateX(0)' }))
]),
transition('slideLeft => void', [
animate('500ms ease-in-out', style({ transform: 'translateX(100%)' }))
]),
transition('void => slideLeft', [
style({ transform: 'translateX(-100%)' }),
animate('500ms ease-in-out', style({ transform: 'translateX(0)' }))
]),
transition('fade => void', [
animate('500ms ease-in-out', style({ opacity: '0' }))
]),
transition('void => fade', [
style({ opacity: '0' }),
animate('500ms ease-in-out', style({ opacity: '1' }))
]),
transition('rotateLeft => void', [
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(-90deg)', opacity: '0' }))
]),
transition('void => rotateLeft', [
style({ transform: 'scale(1, 1) rotate(-90deg)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(0deg)', opacity: '1' }))
]),
transition('rotateRight => void', [
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(90deg)', opacity: '0' }))
]),
transition('void => rotateRight', [
style({ transform: 'scale(1, 1) rotate(90deg)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(0deg)', opacity: '1' }))
]),
transition('zoom => void', [
animate('500ms ease-in-out', style({ transform: 'scale(2.5,2.5)', opacity: '0' }))
]),
transition('void => zoom', [
style({ transform: 'scale(2.5,2.5)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1)', opacity: '1' }))
]),
]),
], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NgxGalleryImageComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-gallery-image', changeDetection: ChangeDetectionStrategy.OnPush, animations: [
trigger('animation', [
// ...
state('slideRight', style({})),
state('slideLeft', style({})),
state('fade', style({})),
state('rotateLeft', style({})),
state('rotateRight', style({})),
state('zoom', style({})),
transition('slideRight => void', [
animate('500ms ease-in-out', style({ transform: 'translateX(-100%)' }))
]),
transition('void => slideRight', [
style({ transform: 'translateX(100%)' }),
animate('500ms ease-in-out', style({ transform: 'translateX(0)' }))
]),
transition('slideLeft => void', [
animate('500ms ease-in-out', style({ transform: 'translateX(100%)' }))
]),
transition('void => slideLeft', [
style({ transform: 'translateX(-100%)' }),
animate('500ms ease-in-out', style({ transform: 'translateX(0)' }))
]),
transition('fade => void', [
animate('500ms ease-in-out', style({ opacity: '0' }))
]),
transition('void => fade', [
style({ opacity: '0' }),
animate('500ms ease-in-out', style({ opacity: '1' }))
]),
transition('rotateLeft => void', [
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(-90deg)', opacity: '0' }))
]),
transition('void => rotateLeft', [
style({ transform: 'scale(1, 1) rotate(-90deg)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(0deg)', opacity: '1' }))
]),
transition('rotateRight => void', [
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(90deg)', opacity: '0' }))
]),
transition('void => rotateRight', [
style({ transform: 'scale(1, 1) rotate(90deg)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1) rotate(0deg)', opacity: '1' }))
]),
transition('zoom => void', [
animate('500ms ease-in-out', style({ transform: 'scale(2.5,2.5)', opacity: '0' }))
]),
transition('void => zoom', [
style({ transform: 'scale(2.5,2.5)', opacity: '0' }),
animate('500ms ease-in-out', style({ transform: 'scale(1, 1)', opacity: '1' }))
]),
]),
], template: "<div class=\"ngx-gallery-image-wrapper ngx-gallery-animation-{{animation}} ngx-gallery-image-size-{{size}}\">\n <ng-container *ngFor=\"let image of getImages(); let i = index;\">\n\n <div *ngIf=\"image.type === 'image' && image.index === _selectedIndex\" class=\"ngx-gallery-image\"\n [ngClass]=\"{'ngx-gallery-clickable': clickable }\"\n [style.background-image]=\"getSafeUrl(image.src)\"\n (click)=\"handleClick($event, image.index)\"\n [@animation]=\"action\"\n (@animation.start)=\"onStart($event)\"\n (@animation.done)=\"onDone($event)\">\n <div class=\"ngx-gallery-icons-wrapper\">\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\n [titleText]=\"action.titleText\"\n (closeClick)=\"action.onClick($event, image.index)\"></ngx-gallery-action>\n </div>\n <div class=\"ngx-gallery-image-text\" *ngIf=\"showDescription && descriptions[image.index]\"\n [innerHTML]=\"descriptions[image.index]\" (click)=\"$event.stopPropagation()\"></div>\n </div>\n\n <div *ngIf=\"image.type === 'video' && image.index === _selectedIndex\" class=\"ngx-gallery-image\"\n [ngClass]=\"{'ngx-gallery-clickable': clickable }\"\n [style.background-image]=\"getSafeUrl(image.src)\"\n (click)=\"handleClick($event, image.index)\"\n [@animation]=\"action\"\n (@animation.start)=\"onStart($event)\"\n (@animation.done)=\"onDone($event)\">\n <video controls style=\"width:100%; height:100%; background: #000;\">\n <source [src]=\"image.src\">\n Your browser does not support the video tag.\n </video>\n <div class=\"ngx-gallery-icons-wrapper\">\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\n [titleText]=\"action.titleText\"\n (closeClick)=\"action.onClick($event, image.index)\"></ngx-gallery-action>\n </div>\n <div class=\"ngx-gallery-image-text\" *ngIf=\"showDescription && descriptions[image.index]\"\n [innerHTML]=\"descriptions[image.index]\" (click)=\"$event.stopPropagation()\"></div>\n </div>\n\n\n </ng-container>\n <ngx-gallery-bullets *ngIf=\"bullets\" [count]=\"images.length\" [active]=\"_selectedIndex\"\n (bulletChange)=\"show($event)\"></ngx-gallery-bullets>\n <ngx-gallery-arrows class=\"ngx-gallery-image-size-{{size}}\" *ngIf=\"arrows\" (prevClick)=\"showPrev()\"\n (nextClick)=\"showNext()\" [prevDisabled]=\"!canShowPrev()\" [nextDisabled]=\"!canShowNext()\"\n [arrowPrevIcon]=\"arrowPrevIcon\" [arrowNextIcon]=\"arrowNextIcon\"></ngx-gallery-arrows>\n</div>\n", styles: [":host{width:100%;display:inline-block;position:relative;font-size:25px}.ngx-gallery-image-wrapper{width:100%;height:100%;position:absolute;left:0;top:0;overflow:hidden}.ngx-gallery-image{background-position:center;background-repeat:no-repeat;height:100%;width:100%;position:absolute;top:0}.ngx-gallery-image-size-cover .ngx-gallery-image{background-size:cover}.ngx-gallery-image-size-contain .ngx-gallery-image{background-size:contain}.ngx-gallery-animation-fade .ngx-gallery-image{left:0;opacity:1;transition:.5s ease-in-out}.ngx-gallery-animation-fade .ngx-gallery-image.ngx-gallery-active{opacity:1}.ngx-gallery-animation-rotate .ngx-gallery-image{transition:1s ease;transform:scale(1) rotate(0);left:0;opacity:1}.ngx-gallery-animation-zoom .ngx-gallery-image{transition:1s ease;transform:scale(1);left:0;opacity:1}.ngx-gallery-image-text{width:100%;background:#000000b3;padding:10px;text-align:center;color:#fff;font-size:16px;position:absolute;bottom:0;z-index:10}\n"] }]
}], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i2.NgxGalleryService }], propDecorators: { images: [{
type: Input
}], clickable: [{
type: Input
}], selectedIndex: [{
type: Input
}], arrows: [{
type: Input
}], arrowsAutoHide: [{
type: Input
}], swipe: [{
type: Input
}], animation: [{
type: Input
}], size: [{
type: Input
}], arrowPrevIcon: [{
type: Input
}], arrowNextIcon: [{
type: Input
}], autoPlay: [{
type: Input
}], autoPlayInterval: [{
type: Input
}], autoPlayPauseOnHover: [{
type: Input
}], infinityMove: [{
type: Input
}], lazyLoading: [{
type: Input
}], actions: [{
type: Input
}], descriptions: [{
type: Input
}], showDescription: [{
type: Input
}], bullets: [{
type: Input
}], imageClick: [{
type: Output
}], activeChange: [{
type: Output
}], animating: [{
type: Output
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter']
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWdhbGxlcnktaW1hZ2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FsbGVyeS9zcmMvbGliL25neC1nYWxsZXJ5LWltYWdlL25neC1nYWxsZXJ5LWltYWdlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbGxlcnkvc3JjL2xpYi9uZ3gtZ2FsbGVyeS1pbWFnZS9uZ3gtZ2FsbGVyeS1pbWFnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRVAsTUFBTSxlQUFlLENBQUM7QUFLdkIsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDN0QsT0FBTyxFQUFDLE9BQU8sRUFBa0IsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFDLE1BQU0scUJBQXFCLENBQUM7Ozs7Ozs7O0FBK0QvRixNQUFNLE9BQU8sd0JBQXdCO0lBS25DLElBQ0ksYUFBYSxDQUFDLEtBQWE7UUFDN0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ2hDLElBQUksTUFBTSxDQUFDO1lBQ1gsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLG1CQUFtQixDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNqRCxNQUFNLEdBQUcsWUFBWSxDQUFDO1lBQ3hCLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN2RCxNQUFNLEdBQUcsTUFBTSxDQUFDO1lBQ2xCLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN6RCxNQUFNLEdBQUcs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LEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUVJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQWtDcUIsWUFBWTtzQkFBdkMsWUFBWTt1QkFBQyxZQUFZO2dCQVVFLFlBQVk7c0JBQXZDLFlBQVk7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsLCBTYWZlU3R5bGV9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHtOZ3hHYWxsZXJ5U2VydmljZX0gZnJvbSAnLi4vbmd4LWdhbGxlcnkuc2VydmljZSc7XG5pbXBvcnQge05neEdhbGxlcnlPcmRlcmVkSW1hZ2V9IGZyb20gJy4uL25neC1nYWxsZXJ5LW9yZGVyZWQtaW1hZ2UnO1xuaW1wb3J0IHtOZ3hHYWxsZXJ5QWN0aW9ufSBmcm9tICcuLi9uZ3gtZ2FsbGVyeS1hY3Rpb24nO1xuaW1wb3J0IHtOZ3hHYWxsZXJ5QW5pbWF0aW9ufSBmcm9tICcuLi9uZ3gtZ2FsbGVyeS1hbmltYXRpb24nO1xuaW1wb3J0IHthbmltYXRlLCBBbmltYXRpb25FdmVudCwgc3RhdGUsIHN0eWxlLCB0cmFuc2l0aW9uLCB0cmlnZ2VyfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcblxudHlwZSBPcmllbnRhdGlvbiA9ICgnc2xpZGVMZWZ0JyB8ICdzbGlkZVJpZ2h0JyB8ICdmYWRlJyB8ICdyb3RhdGVMZWZ0JyB8ICdyb3RhdGVSaWdodCcgfCAnem9vbScgfCAnbm9uZScpO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZ2FsbGVyeS1pbWFnZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZ3gtZ2FsbGVyeS1pbWFnZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25neC1nYWxsZXJ5LWltYWdlLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcignYW5pbWF0aW9uJywgW1xuICAgICAgLy8gLi4uXG4gICAgICBzdGF0ZSgnc2xpZGVSaWdodCcsIHN0eWxlKHt9KSksXG4gICAgICBzdGF0ZSgnc2xpZGVMZWZ0Jywgc3R5bGUoe30pKSxcbiAgICAgIHN0YXRlKCdmYWRlJywgc3R5bGUoe30pKSxcbiAgICAgIHN0YXRlKCdyb3RhdGVMZWZ0Jywgc3R5bGUoe30pKSxcbiAgICAgIHN0YXRlKCdyb3RhdGVSaWdodCcsIHN0eWxlKHt9KSksXG4gICAgICBzdGF0ZSgnem9vbScsIHN0eWxlKHt9KSksXG4gICAgICB0cmFuc2l0aW9uKCdzbGlkZVJpZ2h0ID0+IHZvaWQnLCBbXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoLTEwMCUpJ30pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCd2b2lkID0+IHNsaWRlUmlnaHQnLCBbXG4gICAgICAgIHN0eWxlKHt0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDEwMCUpJ30pLFxuICAgICAgICBhbmltYXRlKCc1MDBtcyBlYXNlLWluLW91dCcsIHN0eWxlKHt0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJ30pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCdzbGlkZUxlZnQgPT4gdm9pZCcsIFtcbiAgICAgICAgYW5pbWF0ZSgnNTAwbXMgZWFzZS1pbi1vdXQnLCBzdHlsZSh7dHJhbnNmb3JtOiAndHJhbnNsYXRlWCgxMDAlKSd9KSlcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbigndm9pZCA9PiBzbGlkZUxlZnQnLCBbXG4gICAgICAgIHN0eWxlKHt0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKC0xMDAlKSd9KSxcbiAgICAgICAgYW5pbWF0ZSgnNTAwbXMgZWFzZS1pbi1vdXQnLCBzdHlsZSh7dHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKSd9KSlcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbignZmFkZSA9PiB2b2lkJywgW1xuICAgICAgICBhbmltYXRlKCc1MDBtcyBlYXNlLWluLW91dCcsIHN0eWxlKHtvcGFjaXR5OiAnMCd9KSlcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbigndm9pZCA9PiBmYWRlJywgW1xuICAgICAgICBzdHlsZSh7b3BhY2l0eTogJzAnfSksXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe29wYWNpdHk6ICcxJ30pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCdyb3RhdGVMZWZ0ID0+IHZvaWQnLCBbXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDEsIDEpIHJvdGF0ZSgtOTBkZWcpJywgb3BhY2l0eTogJzAnfSkpXG4gICAgICBdKSxcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gcm90YXRlTGVmdCcsIFtcbiAgICAgICAgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDEsIDEpIHJvdGF0ZSgtOTBkZWcpJywgb3BhY2l0eTogJzAnfSksXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDEsIDEpIHJvdGF0ZSgwZGVnKScsIG9wYWNpdHk6ICcxJ30pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCdyb3RhdGVSaWdodCA9PiB2b2lkJywgW1xuICAgICAgICBhbmltYXRlKCc1MDBtcyBlYXNlLWluLW91dCcsIHN0eWxlKHt0cmFuc2Zvcm06ICdzY2FsZSgxLCAxKSByb3RhdGUoOTBkZWcpJywgb3BhY2l0eTogJzAnfSkpXG4gICAgICBdKSxcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gcm90YXRlUmlnaHQnLCBbXG4gICAgICAgIHN0eWxlKHt0cmFuc2Zvcm06ICdzY2FsZSgxLCAxKSByb3RhdGUoOTBkZWcpJywgb3BhY2l0eTogJzAnfSksXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDEsIDEpIHJvdGF0ZSgwZGVnKScsIG9wYWNpdHk6ICcxJ30pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCd6b29tID0+IHZvaWQnLCBbXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDIuNSwyLjUpJywgb3BhY2l0eTogJzAnfSkpXG4gICAgICBdKSxcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gem9vbScsIFtcbiAgICAgICAgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDIuNSwyLjUpJywgb3BhY2l0eTogJzAnfSksXG4gICAgICAgIGFuaW1hdGUoJzUwMG1zIGVhc2UtaW4tb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3NjYWxlKDEsIDEpJywgb3BhY2l0eTogJzEnfSkpXG4gICAgICBdKSxcbiAgICBdKSxcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hHYWxsZXJ5SW1hZ2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGltYWdlczogTmd4R2FsbGVyeU9yZGVyZWRJbWFnZVtdO1xuICBASW5wdXQoKSBjbGlja2FibGU6IGJvb2xlYW47XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24sIG5vLXVuZGVyc2NvcmUtZGFuZ2xlLCBpZC1ibGFja2xpc3QsIGlkLW1hdGNoXG4gIF9zZWxlY3RlZEluZGV4O1xuICBASW5wdXQoKVxuICBzZXQgc2VsZWN0ZWRJbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKGluZGV4ID4gdGhpcy5fc2VsZWN0ZWRJbmRleCkge1xuICAgICAgbGV0IGFjdGlvbjtcbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5TbGlkZSkge1xuICAgICAgICBhY3Rpb24gPSAnc2xpZGVSaWdodCc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLkZhZGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ2ZhZGUnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5Sb3RhdGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ3JvdGF0ZVJpZ2h0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uWm9vbSkge1xuICAgICAgICBhY3Rpb24gPSAnem9vbSc7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGlvbihhY3Rpb24pO1xuICAgIH0gZWxzZSBpZiAoaW5kZXggPCB0aGlzLl9zZWxlY3RlZEluZGV4KSB7XG4gICAgICBsZXQgYWN0aW9uO1xuICAgICAgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLlNsaWRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdzbGlkZUxlZnQnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5GYWRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdmYWRlJztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uUm90YXRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdyb3RhdGVMZWZ0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uWm9vbSkge1xuICAgICAgICBhY3Rpb24gPSAnem9vbSc7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGlvbihhY3Rpb24pO1xuICAgIH1cblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBpbmRleDtcbiAgfVxuXG4gIEBJbnB1dCgpIGFycm93czogYm9vbGVhbjtcbiAgQElucHV0KCkgYXJyb3dzQXV0b0hpZGU6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHN3aXBlOiBib29sZWFuO1xuICBASW5wdXQoKSBhbmltYXRpb246IHN0cmluZztcbiAgQElucHV0KCkgc2l6ZTogc3RyaW5nO1xuICBASW5wdXQoKSBhcnJvd1ByZXZJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGFycm93TmV4dEljb246IHN0cmluZztcbiAgQElucHV0KCkgYXV0b1BsYXk6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGF1dG9QbGF5SW50ZXJ2YWw6IG51bWJlcjtcbiAgQElucHV0KCkgYXV0b1BsYXlQYXVzZU9uSG92ZXI6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGluZmluaXR5TW92ZTogYm9vbGVhbjtcbiAgQElucHV0KCkgbGF6eUxvYWRpbmc6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGFjdGlvbnM6IE5neEdhbGxlcnlBY3Rpb25bXTtcbiAgQElucHV0KCkgZGVzY3JpcHRpb25zOiBzdHJpbmdbXTtcbiAgQElucHV0KCkgc2hvd0Rlc2NyaXB0aW9uOiBib29sZWFuO1xuICBASW5wdXQoKSBidWxsZXRzOiBib29sZWFuO1xuXG4gIEBPdXRwdXQoKSBpbWFnZUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgYWN0aXZlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgYW5pbWF0aW5nID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGNhbkNoYW5nZUltYWdlID0gdHJ1ZTtcbiAgcHVibGljIGFjdGlvbjogT3JpZW50YXRpb247XG5cbiAgaXNBbmltYXRpbmcgPSBmYWxzZTtcblxuICBwcml2YXRlIHRpbWVyO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2FuaXRpemF0aW9uOiBEb21TYW5pdGl6ZXIsIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgaGVscGVyU2VydmljZTogTmd4R2FsbGVyeVNlcnZpY2UpIHtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmID0gY2hhbmdlRGV0ZWN0b3JSZWY7XG4gICAgdGhpcy5hY3Rpb24gPSAnbm9uZSc7XG4gIH1cblxuICAvLyBASG9zdEJpbmRpbmcoJ3N0eWxlLmRpc3BsYXknKSBwdWJsaWMgZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICAvLyBASG9zdEJpbmRpbmcoJ3N0eWxlLmJhY2tncm91bmQtY29sb3InKSBwdWJsaWMgY29sb3IgPSAnbGltZSc7XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMuYXJyb3dzICYmIHRoaXMuYXJyb3dzQXV0b0hpZGUpIHtcbiAgICAgIHRoaXMuYXJyb3dzID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXV0b1BsYXkpIHtcbiAgICAgIHRoaXMuc3RhcnRBdXRvUGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc3dpcGUnXSkge1xuICAgICAgdGhpcy5oZWxwZXJTZXJ2aWNlLm1hbmFnZVN3aXBlKHRoaXMuc3dpcGUsIHRoaXMuZWxlbWVudFJlZiwgJ2ltYWdlJywgKCkgPT4gdGhpcy5zaG93TmV4dCgpLCAoKSA9PiB0aGlzLnNob3dQcmV2KCkpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInKSBvbk1vdXNlRW50ZXIoKSB7XG4gICAgaWYgKHRoaXMuYXJyb3dzQXV0b0hpZGUgJiYgIXRoaXMuYXJyb3dzKSB7XG4gICAgICB0aGlzLmFycm93cyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXV0b1BsYXkgJiYgdGhpcy5hdXRvUGxheVBhdXNlT25Ib3Zlcikge1xuICAgICAgdGhpcy5zdG9wQXV0b1BsYXkoKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJykgb25Nb3VzZUxlYXZlKCkge1xuICAgIGlmICh0aGlzLmFycm93c0F1dG9IaWRlICYmIHRoaXMuYXJyb3dzKSB7XG4gICAgICB0aGlzLmFycm93cyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmF1dG9QbGF5ICYmIHRoaXMuYXV0b1BsYXlQYXVzZU9uSG92ZXIpIHtcbiAgICAgIHRoaXMuc3RhcnRBdXRvUGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2V0KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5hY3Rpb24gPSAnbm9uZSc7XG4gIH1cblxuICBnZXRJbWFnZXMoKTogTmd4R2FsbGVyeU9yZGVyZWRJbWFnZVtdIHtcbiAgICBpZiAoIXRoaXMuaW1hZ2VzKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGF6eUxvYWRpbmcpIHtcbiAgICAgIGNvbnN0IGluZGV4ZXMgPSBbdGhpcy5fc2VsZWN0ZWRJbmRleF07XG4gICAgICBjb25zdCBwcmV2SW5kZXggPSB0aGlzLl9zZWxlY3RlZEluZGV4IC0gMTtcblxuICAgICAgaWYgKHByZXZJbmRleCA9PT0gLTEgJiYgdGhpcy5pbmZpbml0eU1vdmUpIHtcbiAgICAgICAgaW5kZXhlcy5wdXNoKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpO1xuICAgICAgfSBlbHNlIGlmIChwcmV2SW5kZXggPj0gMCkge1xuICAgICAgICBpbmRleGVzLnB1c2gocHJldkluZGV4KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV4dEluZGV4ID0gdGhpcy5fc2VsZWN0ZWRJbmRleCArIDE7XG5cbiAgICAgIGlmIChuZXh0SW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCAmJiB0aGlzLmluZmluaXR5TW92ZSkge1xuICAgICAgICBpbmRleGVzLnB1c2goMCk7XG4gICAgICB9IGVsc2UgaWYgKG5leHRJbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICBpbmRleGVzLnB1c2gobmV4dEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuaW1hZ2VzLmZpbHRlcigoaW1nLCBpKSA9PiBpbmRleGVzLmluZGV4T2YoaSkgIT09IC0xKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaW1hZ2VzO1xuICAgIH1cbiAgfVxuXG4gIHN0YXJ0QXV0b1BsYXkoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wQXV0b1BsYXkoKTtcblxuICAgIHRoaXMudGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuc2hvd05leHQoKSkge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgIHRoaXMuc2hvd05leHQoKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLmF1dG9QbGF5SW50ZXJ2YWwpO1xuICB9XG5cbiAgc3RvcEF1dG9QbGF5KCkge1xuICAgIGlmICh0aGlzLnRpbWVyKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZUNsaWNrKGV2ZW50OiBFdmVudCwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmNsaWNrYWJsZSkge1xuICAgICAgdGhpcy5pbWFnZUNsaWNrLmVtaXQoaW5kZXgpO1xuXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgc2hvdyhpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuaXNBbmltYXRpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGluZGV4ID4gdGhpcy5fc2VsZWN0ZWRJbmRleCkge1xuICAgICAgbGV0IGFjdGlvbjtcbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5TbGlkZSkge1xuICAgICAgICBhY3Rpb24gPSAnc2xpZGVSaWdodCc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLkZhZGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ2ZhZGUnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5Sb3RhdGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ3JvdGF0ZVJpZ2h0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uWm9vbSkge1xuICAgICAgICBhY3Rpb24gPSAnem9vbSc7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGlvbihhY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgYWN0aW9uO1xuICAgICAgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLlNsaWRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdzbGlkZUxlZnQnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5GYWRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdmYWRlJztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uUm90YXRlKSB7XG4gICAgICAgIGFjdGlvbiA9ICdyb3RhdGVMZWZ0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uWm9vbSkge1xuICAgICAgICBhY3Rpb24gPSAnem9vbSc7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGlvbihhY3Rpb24pO1xuICAgIH1cblxuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmFjdGl2ZUNoYW5nZS5lbWl0KHRoaXMuX3NlbGVjdGVkSW5kZXgpO1xuICAgIHRoaXMuc2V0Q2hhbmdlVGltZW91dCgpO1xuICB9XG5cbiAgc2V0QWN0aW9uKGFjdGlvbjogT3JpZW50YXRpb24pIHtcbiAgICB0aGlzLmFjdGlvbiA9IGFjdGlvbjtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHNob3dOZXh0KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzQW5pbWF0aW5nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLmNhblNob3dOZXh0KCkgJiYgdGhpcy5jYW5DaGFuZ2VJbWFnZSkge1xuICAgICAgbGV0IGFjdGlvbjtcbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5TbGlkZSkge1xuICAgICAgICBhY3Rpb24gPSAnc2xpZGVSaWdodCc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLkZhZGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ2ZhZGUnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5Sb3RhdGUpIHtcbiAgICAgICAgYWN0aW9uID0gJ3JvdGF0ZVJpZ2h0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uWm9vbSkge1xuICAgICAgICBhY3Rpb24gPSAnem9vbSc7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGlvbihhY3Rpb24pO1xuICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCsrO1xuICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkSW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hY3RpdmVDaGFuZ2UuZW1pdCh0aGlzLl9zZWxlY3RlZEluZGV4KTtcbiAgICAgIHRoaXMuc2V0Q2hhbmdlVGltZW91dCgpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHNob3dQcmV2KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW5pbWF0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmNhblNob3dQcmV2KCkgJiYgdGhpcy5jYW5DaGFuZ2VJbWFnZSkge1xuICAgICAgbGV0IGFjdGlvbjtcbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5TbGlkZSkge1xuICAgICAgICBhY3Rpb24gPSAnc2xpZGVMZWZ0JztcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uRmFkZSkge1xuICAgICAgICBhY3Rpb24gPSAnZmFkZSc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLlJvdGF0ZSkge1xuICAgICAgICBhY3Rpb24gPSAncm90YXRlTGVmdCc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYW5pbWF0aW9uID09PSBOZ3hHYWxsZXJ5QW5pbWF0aW9uLlpvb20pIHtcbiAgICAgICAgYWN0aW9uID0gJ3pvb20nO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRBY3Rpb24oYWN0aW9uKTtcbiAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXgtLTtcbiAgICAgIGlmICh0aGlzLl9zZWxlY3RlZEluZGV4IDwgMCkge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hY3RpdmVDaGFuZ2UuZW1pdCh0aGlzLl9zZWxlY3RlZEluZGV4KTtcbiAgICAgIHRoaXMuc2V0Q2hhbmdlVGltZW91dCgpO1xuICAgIH1cbiAgfVxuXG4gIHNldENoYW5nZVRpbWVvdXQoKSB7XG4gICAgdGhpcy5jYW5DaGFuZ2VJbWFnZSA9IGZhbHNlO1xuICAgIGxldCB0aW1lb3V0ID0gMTAwMDtcblxuICAgIGlmICh0aGlzLmFuaW1hdGlvbiA9PT0gTmd4R2FsbGVyeUFuaW1hdGlvbi5TbGlkZVxuICAgICAgfHwgdGhpcy5hbmltYXRpb24gPT09IE5neEdhbGxlcnlBbmltYXRpb24uRmFkZSkge1xuICAgICAgdGltZW91dCA9IDUwMDtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY2FuQ2hhbmdlSW1hZ2UgPSB0cnVlO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9XG5cbiAgY2FuU2hvd05leHQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuaW1hZ2VzKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbmZpbml0eU1vdmUgfHwgdGhpcy5fc2VsZWN0ZWRJbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBjYW5TaG93UHJldigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5pbWFnZXMpIHtcbiAgICAgIHJldHVybiB0aGlzLmluZmluaXR5TW92ZSB8fCB0aGlzLl9zZWxlY3RlZEluZGV4ID4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGdldFNhZmVVcmwoaW1hZ2U6IHN0cmluZyB8IFNhZmVSZXNvdXJjZVVybCk6IFNhZmVTdHlsZSB7XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemF0aW9uLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZSh0aGlzLmhlbHBlclNlcnZpY2UuZ2V0QmFja2dyb3VuZFVybChpbWFnZS50b1N0cmluZygpKSk7XG4gIH1cblxuICBnZXRGaWxlVHlwZShmaWxlU291cmNlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5oZWxwZXJTZXJ2aWNlLmdldEZpbGVUeXBlKGZpbGVTb3VyY2UpO1xuICB9XG5cbiAgb25TdGFydChldmVudDogQW5pbWF0aW9uRXZlbnQpIHtcbiAgICB0aGlzLmlzQW5pbWF0aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmFuaW1hdGluZy5lbWl0KHRydWUpO1xuICB9XG5cbiAgb25Eb25lKGV2ZW50OiBBbmltYXRpb25FdmVudCkge1xuICAgIHRoaXMuaXNBbmltYXRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmFuaW1hdGluZy5lbWl0KGZhbHNlKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm5neC1nYWxsZXJ5LWltYWdlLXdyYXBwZXIgbmd4LWdhbGxlcnktYW5pbWF0aW9uLXt7YW5pbWF0aW9ufX0gbmd4LWdhbGxlcnktaW1hZ2Utc2l6ZS17e3NpemV9fVwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpbWFnZSBvZiBnZXRJbWFnZXMoKTsgbGV0IGkgPSBpbmRleDtcIj5cblxuICAgIDxkaXYgKm5nSWY9XCJpbWFnZS50eXBlID09PSAnaW1hZ2UnICYmIGltYWdlLmluZGV4ID09PSBfc2VsZWN0ZWRJbmRleFwiIGNsYXNzPVwibmd4LWdhbGxlcnktaW1hZ2VcIlxuICAgICAgICAgW25nQ2xhc3NdPVwieyduZ3gtZ2FsbGVyeS1jbGlja2FibGUnOiBjbGlja2FibGUgfVwiXG4gICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1pbWFnZV09XCJnZXRTYWZlVXJsKGltYWdlLnNyYylcIlxuICAgICAgICAgKGNsaWNrKT1cImhhbmRsZUNsaWNrKCRldmVudCwgaW1hZ2UuaW5kZXgpXCJcbiAgICAgICAgIFtAYW5pbWF0aW9uXT1cImFjdGlvblwiXG4gICAgICAgICAoQGFuaW1hdGlvbi5zdGFydCk9XCJvblN0YXJ0KCRldmVudClcIlxuICAgICAgICAgKEBhbmltYXRpb24uZG9uZSk9XCJvbkRvbmUoJGV2ZW50KVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm5neC1nYWxsZXJ5LWljb25zLXdyYXBwZXJcIj5cbiAgICAgICAgPG5neC1nYWxsZXJ5LWFjdGlvbiAqbmdGb3I9XCJsZXQgYWN0aW9uIG9mIGFjdGlvbnNcIiBbaWNvbl09XCJhY3Rpb24uaWNvblwiIFtkaXNhYmxlZF09XCJhY3Rpb24uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZVRleHRdPVwiYWN0aW9uLnRpdGxlVGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsb3NlQ2xpY2spPVwiYWN0aW9uLm9uQ2xpY2soJGV2ZW50LCBpbWFnZS5pbmRleClcIj48L25neC1nYWxsZXJ5LWFjdGlvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm5neC1nYWxsZXJ5LWltYWdlLXRleHRcIiAqbmdJZj1cInNob3dEZXNjcmlwdGlvbiAmJiBkZXNjcmlwdGlvbnNbaW1hZ2UuaW5kZXhdXCJcbiAgICAgICAgICBbaW5uZXJIVE1MXT1cImRlc2NyaXB0aW9uc1tpbWFnZS5pbmRleF1cIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICpuZ0lmPVwiaW1hZ2UudHlwZSA9PT0gJ3ZpZGVvJyAmJiBpbWFnZS5pbmRleCA9PT0gX3NlbGVjdGVkSW5kZXhcIiBjbGFzcz1cIm5neC1nYWxsZXJ5LWltYWdlXCJcbiAgICAgICAgIFtuZ0NsYXNzXT1cInsnbmd4LWdhbGxlcnktY2xpY2thYmxlJzogY2xpY2thYmxlIH1cIlxuICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtaW1hZ2VdPVwiZ2V0U2FmZVVybChpbWFnZS5zcmMpXCJcbiAgICAgICAgIChjbGljayk9XCJoYW5kbGVDbGljaygkZXZlbnQsIGltYWdlLmluZGV4KVwiXG4gICAgICAgICBbQGFuaW1hdGlvbl09XCJhY3Rpb25cIlxuICAgICAgICAgKEBhbmltYXRpb24uc3RhcnQpPVwib25TdGFydCgkZXZlbnQpXCJcbiAgICAgICAgIChAYW5pbWF0aW9uLmRvbmUpPVwib25Eb25lKCRldmVudClcIj5cbiAgICAgIDx2aWRlbyBjb250cm9scyBzdHlsZT1cIndpZHRoOjEwMCU7IGhlaWdodDoxMDAlOyBiYWNrZ3JvdW5kOiAjMDAwO1wiPlxuICAgICAgICA8c291cmNlIFtzcmNdPVwiaW1hZ2Uuc3JjXCI+XG4gICAgICAgICAgWW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHZpZGVvIHRhZy5cbiAgICAgIDwvdmlkZW8+XG4gICAgICA8ZGl2IGNsYXNzPVwibmd4LWdhbGxlcnktaWNvbnMtd3JhcHBlclwiPlxuICAgICAgPG5neC1nYWxsZXJ5LWFjdGlvbiAqbmdGb3I9XCJsZXQgYWN0aW9uIG9mIGFjdGlvbnNcIiBbaWNvbl09XCJhY3Rpb24uaWNvblwiIFtkaXNhYmxlZF09XCJhY3Rpb24uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVUZXh0XT1cImFjdGlvbi50aXRsZVRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xvc2VDbGljayk9XCJhY3Rpb24ub25DbGljaygkZXZlbnQsIGltYWdlLmluZGV4KVwiPjwvbmd4LWdhbGxlcnktYWN0aW9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibmd4LWdhbGxlcnktaW1hZ2UtdGV4dFwiICpuZ0lmPVwic2hvd0Rlc2NyaXB0aW9uICYmIGRlc2NyaXB0aW9uc1tpbWFnZS5pbmRleF1cIlxuICAgICAgICAgIFtpbm5lckhUTUxdPVwiZGVzY3JpcHRpb25zW2ltYWdlLmluZGV4XVwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZ3gtZ2FsbGVyeS1idWxsZXRzICpuZ0lmPVwiYnVsbGV0c1wiIFtjb3VudF09XCJpbWFnZXMubGVuZ3RoXCIgW2FjdGl2ZV09XCJfc2VsZWN0ZWRJbmRleFwiXG4gICAgICAgICAgICAgICAgICAgICAgIChidWxsZXRDaGFuZ2UpPVwic2hvdygkZXZlbnQpXCI+PC9uZ3gtZ2FsbGVyeS1idWxsZXRzPlxuICA8bmd4LWdhbGxlcnktYXJyb3dzIGNsYXNzPVwibmd4LWdhbGxlcnktaW1hZ2Utc2l6ZS17e3NpemV9fVwiICpuZ0lmPVwiYXJyb3dzXCIgKHByZXZDbGljayk9XCJzaG93UHJldigpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobmV4dENsaWNrKT1cInNob3dOZXh0KClcIiBbcHJldkRpc2FibGVkXT1cIiFjYW5TaG93UHJldigpXCIgW25leHREaXNhYmxlZF09XCIhY2FuU2hvd05leHQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2Fycm93UHJldkljb25dPVwiYXJyb3dQcmV2SWNvblwiIFthcnJvd05leHRJY29uXT1cImFycm93TmV4dEljb25cIj48L25neC1nYWxsZXJ5LWFycm93cz5cbjwvZGl2PlxuIl19