angular-gallery
Version:
Responsive gallery for Angular with touch screen support.
379 lines • 43.4 kB
JavaScript
import { __decorate } from "tslib";
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, OnDestroy, SimpleChanges } from '@angular/core';
import { Touches } from './touches';
import { Carousel } from './carousel';
import { EventService as OverlayEventService } from './overlay/event.service';
var CarouselComponent = /** @class */ (function () {
function CarouselComponent(elementRef, ref, overlayEventService) {
var _this = this;
this.elementRef = elementRef;
this.ref = ref;
this.overlayEventService = overlayEventService;
this.minTimeout = 30;
this._cellWidth = 200;
this._transitionDuration = 200;
this.events = new EventEmitter();
this.height = 200;
this.margin = 10;
this.objectFit = 'cover';
this.minSwipeDistance = 50;
this.transitionTimingFunction = 'ease';
this.counterSeparator = " / ";
this.overflowCellsLimit = 3;
this.listeners = 'mouse and touch';
this.arrows = true;
this.arrowsTheme = 'light';
this.hostClassCarousel = true;
/* Touchstart */
this.handleTouchstart = function (event) {
event.preventDefault();
_this.carousel.handleTouchstart(event);
_this.isMoving = true;
_this.events.emit({
type: 'touchstart',
event: event
});
};
/* Touchmove */
this.handleHorizontalSwipe = function (event) {
event.preventDefault();
_this.carousel.handleHorizontalSwipe(event);
_this.events.emit({
type: 'swipe',
event: event
});
};
/* Touchend */
this.handleTouchend = function (event) {
var touches = event.touches;
_this.carousel.handleTouchend(event);
_this.isMoving = false;
_this.events.emit({
type: 'touchend',
event: event
});
};
/* Tap */
this.handleTap = function (event) {
var i = _this.carousel.slideCounter;
var cellIndex = _this.carousel.currentCellIndex;
var fileIndex = _this.carousel.getFileIndex(i);
var file = _this.carousel.getFile(cellIndex);
_this.events.emit({
type: 'click',
file: file,
index: fileIndex
});
};
}
Object.defineProperty(CarouselComponent.prototype, "isLandscape", {
get: function () {
return window.innerWidth > window.innerHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "isSafari", {
get: function () {
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') !== -1) {
return !(ua.indexOf('chrome') > -1);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "counter", {
get: function () {
return this.carousel.slideCounter + 1 + this.counterSeparator + this.images.length;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "images", {
get: function () {
return this._images;
},
set: function (images) {
this._images = images;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "isNgContent", {
get: function () {
return this.elementRef.nativeElement.querySelector('.carousel-content-wrapper').children.length > 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "transitionDuration", {
get: function () {
if (this._transitionDuration === 0) {
return 1;
}
else {
return this._transitionDuration;
}
},
set: function (value) {
this._transitionDuration = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "cellWidth", {
set: function (value) {
if (value) {
this._cellWidth = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "isCounter", {
get: function () {
return this._isCounter && this.images.length > 1;
},
set: function (value) {
if (value) {
this._isCounter = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "overlayProperties", {
set: function (properties) {
this._properties = properties;
this._images = this._properties.metadata.images;
this._cellWidth = this._properties.metadata.width;
this.height = this._properties.metadata.height;
this.objectFit = this._properties.metadata.objectFit;
this.margin = this._properties.metadata.margin;
this.transitionDuration = this._properties.metadata.transitionDuration;
this.overflowCellsLimit = this._properties.metadata.overflowCellsLimit;
this.minSwipeDistance = this._properties.metadata.minSwipeDistance;
this.transitionTimingFunction = this._properties.metadata.transitionTimingFunction;
this._isCounter = this._properties.metadata.counter;
this.counterSeparator = this._properties.metadata.counterSeparator;
this.arrows = this._properties.metadata.arrows;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "properties", {
get: function () {
return this._properties;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "cellLimit", {
get: function () {
if (this.carousel) {
return this.carousel.cellLimit;
}
},
enumerable: true,
configurable: true
});
CarouselComponent.prototype.onWindowResize = function (event) {
this.landscapeMode = this.isLandscape;
this.ref.detectChanges();
this.initCarousel();
this.carousel.lineUpCells();
};
CarouselComponent.prototype.ngOnInit = function () {
this.touches = new Touches({
element: this.elementRef.nativeElement.querySelector('.carousel-cells'),
listeners: this.listeners
});
this.touches.on('touchstart', this.handleTouchstart);
this.touches.on('horizontal-swipe', this.handleHorizontalSwipe);
this.touches.on('touchend', this.handleTouchend);
this.touches.on('mousedown', this.handleTouchstart);
this.touches.on('mouseup', this.handleTouchend);
this.touches.on('tap', this.handleTap);
this.initCarousel();
this.setDimensions();
this.setInitialIndex();
};
CarouselComponent.prototype.ngAfterViewInit = function () {
this.carousel.lineUpCells();
};
CarouselComponent.prototype.ngOnChanges = function (changes) {
if (changes.width || changes.height) {
this.setDimensions();
this.initCarousel();
this.carousel.lineUpCells();
}
};
CarouselComponent.prototype.ngOnDestroy = function () {
this.touches.destroy();
};
CarouselComponent.prototype.initCarousel = function () {
this.carousel = new Carousel({
element: this.elementRef.nativeElement.querySelector('.carousel-cells'),
container: this.elementRef.nativeElement,
images: this.images,
cellWidth: this.getCellWidth(),
overflowCellsLimit: this.overflowCellsLimit,
visibleWidth: this.width,
margin: this.margin,
minSwipeDistance: this.minSwipeDistance,
transitionDuration: this.transitionDuration,
transitionTimingFunction: this.transitionTimingFunction,
videoProperties: this.videoProperties
});
};
CarouselComponent.prototype.setDimensions = function () {
this.hostStyleHeight = this.height + 'px';
this.hostStyleWidth = this.width + 'px';
};
CarouselComponent.prototype.getFile = function (index) {
return this.carousel.getFile(index);
};
CarouselComponent.prototype.handleTransitionendCellContainer = function (event) {
this.carousel.handleSlideEnd();
};
CarouselComponent.prototype.toggleVideo = function (video) {
event.preventDefault();
if (this.videoProperties.noPlay) {
return;
}
if (video.paused) {
video.play();
this.isVideoPlaying = true;
}
else {
video.pause();
this.isVideoPlaying = false;
}
this.ref.detectChanges();
};
CarouselComponent.prototype.getCurrentIndex = function () {
return this.carousel.slideCounter;
};
CarouselComponent.prototype.getCellWidth = function () {
if (this._cellWidth === '100%') {
return this.elementRef.nativeElement.clientWidth;
}
else {
return this._cellWidth;
}
};
CarouselComponent.prototype.next = function () {
this.carousel.next(1);
};
CarouselComponent.prototype.prev = function () {
this.carousel.prev(1);
};
CarouselComponent.prototype.select = function (index) {
this.carousel.select(index);
};
CarouselComponent.prototype.isNextArrowDisabled = function () {
return this.carousel.isNextArrowDisabled();
};
CarouselComponent.prototype.isPrevArrowDisabled = function () {
return this.carousel.isPrevArrowDisabled();
};
CarouselComponent.prototype.close = function () {
this.overlayEventService.emitChangeEvent({
type: 'Hide'
});
};
CarouselComponent.prototype.setInitialIndex = function () {
if (this._properties.metadata.index != undefined) {
this.select(this._properties.metadata.index);
}
};
CarouselComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: OverlayEventService }
]; };
__decorate([
Input()
], CarouselComponent.prototype, "images", null);
__decorate([
Output()
], CarouselComponent.prototype, "events", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "height", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "width", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "borderRadius", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "margin", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "objectFit", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "minSwipeDistance", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "transitionDuration", null);
__decorate([
Input()
], CarouselComponent.prototype, "transitionTimingFunction", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "videoProperties", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "counterSeparator", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "overflowCellsLimit", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "listeners", void 0);
__decorate([
Input('cellWidth')
], CarouselComponent.prototype, "cellWidth", null);
__decorate([
Input('counter')
], CarouselComponent.prototype, "isCounter", null);
__decorate([
Input()
], CarouselComponent.prototype, "arrows", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "arrowsOutside", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "arrowsTheme", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "overlayProperties", null);
__decorate([
HostBinding('class.carousel')
], CarouselComponent.prototype, "hostClassCarousel", void 0);
__decorate([
HostBinding('style.height')
], CarouselComponent.prototype, "hostStyleHeight", void 0);
__decorate([
HostBinding('style.width')
], CarouselComponent.prototype, "hostStyleWidth", void 0);
__decorate([
HostListener('window:resize', ['$event'])
], CarouselComponent.prototype, "onWindowResize", null);
CarouselComponent = __decorate([
Component({
selector: 'carousel, [carousel]',
exportAs: 'carousel',
template: "<div class=\"carousel-backdrop\"></div>\n\n<div class=\"carousel-close\" (click)=\"close()\"></div>\n\n<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\n\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\n\t<div class=\"carousel-cells\" (transitionend)=\"handleTransitionendCellContainer($event)\">\n\t\t<ng-template ngFor let-image [ngForOf]=\"images\" let-i=\"index\">\n\t\t\t<div class=\"carousel-cell\" \n\t\t\t\t*ngIf=\"i < cellLimit\" \n\t\t\t\t[style.width]=\"getCellWidth()+'px'\"\n\t\t\t\t[style.border-radius]=\"borderRadius+'px'\">\n\t\t\t\t<!-- Image -->\n\t\t\t\t<img \n\t\t\t\t\t*ngIf=\"getFile(i) && getFile(i)['image']\" \n\t\t\t\t\t[src]=\"getFile(i)['image']['path']\"\n\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\tdraggable=\"false\" />\n\n\t\t\t\t<!-- Video -->\n\t\t\t\t<ng-template [ngIf]=\"getFile(i) && getFile(i)['type'] === 'video'\">\n\t\t\t\t\t<div class=\"carousel-play\" (click)=\"toggleVideo(video)\"></div>\n\n\t\t\t\t\t<video #video\n\t\t\t\t\t\t[loop]=\"videoProperties.loop\"\n\t\t\t\t\t\t[muted]=\"videoProperties.muted\"\n\t\t\t\t\t\t[controls]=\"isSafari\"\n\t\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\t\t[style.border-radius]=\"borderRadius+'px'\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t<source [src]=\"getFile(i)['path']\" type=\"video/mp4\">\n\t\t\t\t\t</video>\n\t\t\t\t</ng-template>\n\t\t\t</div>\n\t\t</ng-template>\n\t</div>\n</div>\n\n<div class=\"carousel-arrows\" \n\t[class.carousel-arrows-outside]=\"arrowsOutside\" \n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\n\t*ngIf=\"arrows\">\n\t\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\n</div>",
styles: [":host{position:relative;display:block;top:0;left:0;width:100%;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10000;transform-origin:top left;box-sizing:border-box}:host .carousel-container{overflow:hidden;width:100%;height:100%;cursor:-webkit-grab;cursor:grab}:host .carousel-container.carousel-moving{cursor:-webkit-grabbing;cursor:grabbing}:host .carousel-counter{text-align:right;position:absolute;z-index:30;transition:opacity .2s;top:15px;left:10px;border-radius:13px;background-color:rgba(23,37,68,.3);font-size:13px;color:#fff;padding:5px 7px;line-height:initial}:host .carousel-cells{transition:transform .2s;width:100%;height:100%;display:block}:host .carousel-cells ::ng-deep .carousel-cell.swiper-prev-image{transform:translate3d(-100%,0,0)}:host .carousel-cells ::ng-deep .carousel-cell.swiper-next-image{transform:translate3d(100%,0,0)}:host .carousel-cells ::ng-deep .carousel-cell{width:100%;height:100%;text-align:center;position:absolute;display:flex;align-items:center;justify-content:center;overflow:hidden}:host .carousel-cells ::ng-deep .carousel-cell img,:host .carousel-cells ::ng-deep .carousel-cell video{width:100%;height:100%;position:relative;-o-object-fit:contain;object-fit:contain}:host .carousel-cells ::ng-deep .carousel-cell img.swiper-hide{display:none}:host .carousel-cells ::ng-deep .carousel-cell .carousel-play{position:absolute;top:0;left:0;bottom:0;right:0;z-index:1}:host .carousel-arrow{width:40px;height:40px;background-color:#fff;background-repeat:no-repeat;background-size:31px;background-position:center;border-radius:100px;position:absolute;top:50%;margin-top:-20px;z-index:10;cursor:pointer;box-shadow:0 0 5px rgba(0,0,0,.15)}:host .carousel-arrow-prev{left:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTUuNDEgMTYuNTlMMTAuODMgMTJsNC41OC00LjU5TDE0IDZsLTYgNiA2IDYgMS40MS0xLjQxeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==)}:host .carousel-arrow-next{right:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNOC41OSAxNi41OUwxMy4xNyAxMiA4LjU5IDcuNDEgMTAgNmw2IDYtNiA2LTEuNDEtMS40MXoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{-webkit-filter:invert(1);filter:invert(1)}:host .carousel-arrow-disabled{cursor:default;opacity:.5}:host .carousel-close{position:fixed;top:10px;right:10px;width:40px;height:40px;z-index:100;cursor:pointer;background-repeat:no-repeat;background-size:31px;background-position:center;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=);-webkit-filter:invert(1);filter:invert(1)}:host .carousel-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#000;opacity:.5}"]
})
], CarouselComponent);
return CarouselComponent;
}());
export { CarouselComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1nYWxsZXJ5LyIsInNvdXJjZXMiOlsibGliL2Nhcm91c2VsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFDLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBR3pKLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUVwQyxPQUFPLEVBQUMsWUFBWSxJQUFJLG1CQUFtQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFVNUU7SUErSEksMkJBQ1ksVUFBc0IsRUFDdEIsR0FBc0IsRUFDdEIsbUJBQXdDO1FBSHBELGlCQUlDO1FBSFcsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0Qix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBNUhwRCxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBSWhCLGVBQVUsR0FBb0IsR0FBRyxDQUFDO1FBR2xDLHdCQUFtQixHQUFXLEdBQUcsQ0FBQztRQTZCeEIsV0FBTSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRXJELFdBQU0sR0FBVyxHQUFHLENBQUM7UUFHckIsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQUNwQixjQUFTLEdBQWlDLE9BQU8sQ0FBQztRQUNsRCxxQkFBZ0IsR0FBVyxFQUFFLENBQUM7UUFjOUIsNkJBQXdCLEdBQStELE1BQU0sQ0FBQztRQUU5RixxQkFBZ0IsR0FBVyxLQUFLLENBQUM7UUFDakMsdUJBQWtCLEdBQVcsQ0FBQyxDQUFDO1FBQy9CLGNBQVMsR0FBK0IsaUJBQWlCLENBQUM7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O0lBQzlGO1FBQVIsS0FBSyxFQUFFOzhEQUFzQjtJQUNyQjtRQUFSLEtBQUssRUFBRTsrREFBa0M7SUFDakM7UUFBUixLQUFLLEVBQUU7aUVBQWdDO0lBQy9CO1FBQVIsS0FBSyxFQUFFO3dEQUEyRDtJQUUvQztRQUFuQixLQUFLLENBQUMsV0FBVyxDQUFDO3NEQUlsQjtJQUVpQjtRQUFqQixLQUFLLENBQUMsU0FBUyxDQUFDO3NEQUloQjtJQUtRO1FBQVIsS0FBSyxFQUFFO3FEQUF3QjtJQUN2QjtRQUFSLEtBQUssRUFBRTs0REFBd0I7SUFDdkI7UUFBUixLQUFLLEVBQUU7MERBQXlDO0lBRXhDO1FBQVIsS0FBSyxFQUFFOzhEQWNQO0lBWThCO1FBQTlCLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQztnRUFBbUM7SUFDcEM7UUFBNUIsV0FBVyxDQUFDLGNBQWMsQ0FBQzs4REFBeUI7SUFDekI7UUFBM0IsV0FBVyxDQUFDLGFBQWEsQ0FBQzs2REFBd0I7SUFHbkQ7UUFEQyxZQUFZLENBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7MkRBT3pDO0lBN0hRLGlCQUFpQjtRQVA3QixTQUFTLENBQUM7WUFDVixRQUFRLEVBQUUsc0JBQXNCO1lBQzdCLFFBQVEsRUFBRSxVQUFVO1lBQ3ZCLDAyREFBd0M7O1NBRXhDLENBQUM7T0FFVyxpQkFBaUIsQ0E4UzdCO0lBQUQsd0JBQUM7Q0FBQSxBQTlTRCxJQThTQztTQTlTWSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdEJpbmRpbmcsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE91dHB1dCwgT25EZXN0cm95LCBTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtJbWFnZXN9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQge1RvdWNoZXN9IGZyb20gJy4vdG91Y2hlcyc7XG5pbXBvcnQge0Nhcm91c2VsfSBmcm9tICcuL2Nhcm91c2VsJztcbmltcG9ydCB7T3ZlcmxheVByb3BlcnRpZXN9IGZyb20gJy4vb3ZlcmxheS9pbnRlcmZhY2VzJztcbmltcG9ydCB7RXZlbnRTZXJ2aWNlIGFzIE92ZXJsYXlFdmVudFNlcnZpY2V9IGZyb20gJy4vb3ZlcmxheS9ldmVudC5zZXJ2aWNlJzsgXG5cblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnY2Fyb3VzZWwsIFtjYXJvdXNlbF0nLFxuICAgIGV4cG9ydEFzOiAnY2Fyb3VzZWwnLFxuXHR0ZW1wbGF0ZVVybDogJy4vY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2Nhcm91c2VsLmNvbXBvbmVudC5zYXNzJ11cbn0pXG5cbmV4cG9ydCBjbGFzcyBDYXJvdXNlbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgX2lkOiBzdHJpbmc7XG4gICAgX2ltYWdlczogSW1hZ2VzO1xuICAgIHRvdWNoZXM6IGFueTtcbiAgICBjYXJvdXNlbDogYW55O1xuICAgIGxhbmRzY2FwZU1vZGU6IGFueTtcbiAgICBtaW5UaW1lb3V0ID0gMzA7XG4gICAgaXNWaWRlb1BsYXlpbmc6IGJvb2xlYW47XG4gICAgX2lzQ291bnRlcjogYm9vbGVhbjtcbiAgICBfd2lkdGg6IG51bWJlcjtcbiAgICBfY2VsbFdpZHRoOiBudW1iZXIgfCAnMTAwJScgPSAyMDA7XG4gICAgaXNNb3Zpbmc6IGJvb2xlYW47XG4gICAgX3Byb3BlcnRpZXM6IE92ZXJsYXlQcm9wZXJ0aWVzO1xuICAgIF90cmFuc2l0aW9uRHVyYXRpb246IG51bWJlciA9IDIwMDtcblxuICAgIGdldCBpc0xhbmRzY2FwZSgpe1xuICAgICAgICByZXR1cm4gd2luZG93LmlubmVyV2lkdGggPiB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgfVxuXG4gICAgZ2V0IGlzU2FmYXJpKCk6IGFueSB7XG4gICAgICAgIGNvbnN0IHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAodWEuaW5kZXhPZignc2FmYXJpJykgIT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gISh1YS5pbmRleE9mKCdjaHJvbWUnKSA+IC0xKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjb3VudGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5zbGlkZUNvdW50ZXIgKyAxICsgdGhpcy5jb3VudGVyU2VwYXJhdG9yICsgdGhpcy5pbWFnZXMubGVuZ3RoO1xuICAgIH1cblxuICAgIEBJbnB1dCgpXG4gICAgc2V0IGltYWdlcyhpbWFnZXM6IEltYWdlcyAmIGFueSkge1xuICAgICAgICB0aGlzLl9pbWFnZXMgPSBpbWFnZXM7XG4gICAgfVxuICAgIGdldCBpbWFnZXMoKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ltYWdlcztcbiAgICB9XG5cbiAgICBnZXQgaXNOZ0NvbnRlbnQoKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYXJvdXNlbC1jb250ZW50LXdyYXBwZXInKS5jaGlsZHJlbi5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIEBPdXRwdXQoKSBldmVudHM6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IDIwMDtcbiAgICBASW5wdXQoKSB3aWR0aDogbnVtYmVyO1xuICAgIEBJbnB1dCgpIGJvcmRlclJhZGl1czogbnVtYmVyO1xuICAgIEBJbnB1dCgpIG1hcmdpbjogbnVtYmVyID0gMTA7XG4gICAgQElucHV0KCkgb2JqZWN0Rml0OiAnY29udGFpbicgfCAnY292ZXInIHwgJ25vbmUnID0gJ2NvdmVyJztcbiAgICBASW5wdXQoKSBtaW5Td2lwZURpc3RhbmNlOiBudW1iZXIgPSA1MDtcblxuICAgIEBJbnB1dCgpXG4gICAgc2V0IHRyYW5zaXRpb25EdXJhdGlvbih2YWx1ZTogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zaXRpb25EdXJhdGlvbiA9IHZhbHVlO1xuICAgIH1cbiAgICBnZXQgdHJhbnNpdGlvbkR1cmF0aW9uKCl7XG4gICAgICAgIGlmICh0aGlzLl90cmFuc2l0aW9uRHVyYXRpb24gPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zaXRpb25EdXJhdGlvbjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBJbnB1dCgpIHRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbjogJ2Vhc2UnIHwgJ2Vhc2UtaW4nIHwgJ2Vhc2Utb3V0JyB8ICdlYXNlLWluLW91dCcgfCAnbGluZWFyJyA9ICdlYXNlJztcbiAgICBASW5wdXQoKSB2aWRlb1Byb3BlcnRpZXM6IGFueTtcbiAgICBASW5wdXQoKSBjb3VudGVyU2VwYXJhdG9yOiBzdHJpbmcgPSBcIiAvIFwiO1xuICAgIEBJbnB1dCgpIG92ZXJmbG93Q2VsbHNMaW1pdDogbnVtYmVyID0gMztcbiAgICBASW5wdXQoKSBsaXN0ZW5lcnM6ICdhdXRvJyB8ICdtb3VzZSBhbmQgdG91Y2gnID0gJ21vdXNlIGFuZCB0b3VjaCc7XG5cbiAgICBASW5wdXQoJ2NlbGxXaWR0aCcpIHNldCBjZWxsV2lkdGgodmFsdWU6IG51bWJlciB8ICcxMDAlJykge1xuICAgICAgICBpZiAodmFsdWUpe1xuICAgICAgICAgICAgdGhpcy5fY2VsbFdpZHRoID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASW5wdXQoJ2NvdW50ZXInKSBzZXQgaXNDb3VudGVyKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh2YWx1ZSl7XG4gICAgICAgICAgICB0aGlzLl9pc0NvdW50ZXIgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgaXNDb3VudGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNDb3VudGVyICYmIHRoaXMuaW1hZ2VzLmxlbmd0aCA+IDE7XG4gICAgfVxuXG4gICAgQElucHV0KCkgYXJyb3dzOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBhcnJvd3NPdXRzaWRlOiBib29sZWFuO1xuICAgIEBJbnB1dCgpIGFycm93c1RoZW1lOiAnbGlnaHQnIHwgJ2RhcmsnID0gJ2xpZ2h0JztcblxuICAgIEBJbnB1dCgpIHNldCBvdmVybGF5UHJvcGVydGllcyAocHJvcGVydGllczogT3ZlcmxheVByb3BlcnRpZXMpIHtcbiAgICAgICAgdGhpcy5fcHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMuX2ltYWdlcyA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEuaW1hZ2VzO1xuICAgICAgICB0aGlzLl9jZWxsV2lkdGggPSB0aGlzLl9wcm9wZXJ0aWVzLm1ldGFkYXRhLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEuaGVpZ2h0O1xuICAgICAgICB0aGlzLm9iamVjdEZpdCA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEub2JqZWN0Rml0O1xuICAgICAgICB0aGlzLm1hcmdpbiA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEubWFyZ2luO1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbiA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEudHJhbnNpdGlvbkR1cmF0aW9uO1xuICAgICAgICB0aGlzLm92ZXJmbG93Q2VsbHNMaW1pdCA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEub3ZlcmZsb3dDZWxsc0xpbWl0O1xuICAgICAgICB0aGlzLm1pblN3aXBlRGlzdGFuY2UgPSB0aGlzLl9wcm9wZXJ0aWVzLm1ldGFkYXRhLm1pblN3aXBlRGlzdGFuY2U7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uID0gdGhpcy5fcHJvcGVydGllcy5tZXRhZGF0YS50cmFuc2l0aW9uVGltaW5nRnVuY3Rpb247XG4gICAgICAgIHRoaXMuX2lzQ291bnRlciA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEuY291bnRlcjtcbiAgICAgICAgdGhpcy5jb3VudGVyU2VwYXJhdG9yID0gdGhpcy5fcHJvcGVydGllcy5tZXRhZGF0YS5jb3VudGVyU2VwYXJhdG9yO1xuICAgICAgICB0aGlzLmFycm93cyA9IHRoaXMuX3Byb3BlcnRpZXMubWV0YWRhdGEuYXJyb3dzO1xuICAgIH1cblxuICAgIGdldCBwcm9wZXJ0aWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvcGVydGllcztcbiAgICB9XG5cbiAgICBnZXQgY2VsbExpbWl0KCkge1xuICAgICAgICBpZiAodGhpcy5jYXJvdXNlbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWwuY2VsbExpbWl0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jYXJvdXNlbCcpIGhvc3RDbGFzc0Nhcm91c2VsOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmhlaWdodCcpIGhvc3RTdHlsZUhlaWdodDogc3RyaW5nO1xuICAgIEBIb3N0QmluZGluZygnc3R5bGUud2lkdGgnKSBob3N0U3R5bGVXaWR0aDogc3RyaW5nO1xuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25XaW5kb3dSZXNpemUoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmxhbmRzY2FwZU1vZGUgPSB0aGlzLmlzTGFuZHNjYXBlO1xuICAgICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5pbml0Q2Fyb3VzZWwoKTtcbiAgICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIFxuICAgICAgICBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgb3ZlcmxheUV2ZW50U2VydmljZTogT3ZlcmxheUV2ZW50U2VydmljZSl7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKXtcbiAgICAgICAgdGhpcy50b3VjaGVzID0gbmV3IFRvdWNoZXMoe1xuICAgICAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyksXG4gICAgICAgICAgICBsaXN0ZW5lcnM6IHRoaXMubGlzdGVuZXJzXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudG91Y2hlcy5vbigndG91Y2hzdGFydCcsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignaG9yaXpvbnRhbC1zd2lwZScsIHRoaXMuaGFuZGxlSG9yaXpvbnRhbFN3aXBlKTtcbiAgICAgICAgdGhpcy50b3VjaGVzLm9uKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ21vdXNlZG93bicsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignbW91c2V1cCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ3RhcCcsIHRoaXMuaGFuZGxlVGFwKTtcblxuICAgICAgICB0aGlzLmluaXRDYXJvdXNlbCgpO1xuICAgICAgICB0aGlzLnNldERpbWVuc2lvbnMoKTtcbiAgICAgICAgdGhpcy5zZXRJbml0aWFsSW5kZXgoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWwubGluZVVwQ2VsbHMoKTtcbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGlmIChjaGFuZ2VzLndpZHRoIHx8IGNoYW5nZXMuaGVpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLnNldERpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgIHRoaXMuaW5pdENhcm91c2VsKCk7XG4gICAgICAgICAgICB0aGlzLmNhcm91c2VsLmxpbmVVcENlbGxzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy50b3VjaGVzLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBpbml0Q2Fyb3VzZWwoKSB7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWwgPSBuZXcgQ2Fyb3VzZWwoe1xuICAgICAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyksXG4gICAgICAgICAgICBjb250YWluZXI6IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LFxuICAgICAgICAgICAgaW1hZ2VzOiB0aGlzLmltYWdlcyxcbiAgICAgICAgICAgIGNlbGxXaWR0aDogdGhpcy5nZXRDZWxsV2lkdGgoKSxcbiAgICAgICAgICAgIG92ZXJmbG93Q2VsbHNMaW1pdDogdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQsXG4gICAgICAgICAgICB2aXNpYmxlV2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICAgICAgICBtYXJnaW46IHRoaXMubWFyZ2luLFxuICAgICAgICAgICAgbWluU3dpcGVEaXN0YW5jZTogdGhpcy5taW5Td2lwZURpc3RhbmNlLFxuICAgICAgICAgICAgdHJhbnNpdGlvbkR1cmF0aW9uOiB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbixcbiAgICAgICAgICAgIHRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbjogdGhpcy50cmFuc2l0aW9uVGltaW5nRnVuY3Rpb24sXG4gICAgICAgICAgICB2aWRlb1Byb3BlcnRpZXM6IHRoaXMudmlkZW9Qcm9wZXJ0aWVzXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNldERpbWVuc2lvbnMoKSB7XG4gICAgICAgIHRoaXMuaG9zdFN0eWxlSGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgICB0aGlzLmhvc3RTdHlsZVdpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgfVxuXG4gICAgZ2V0RmlsZShpbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5nZXRGaWxlKGluZGV4KTtcbiAgICB9XG5cbiAgICAvKiBUb3VjaHN0YXJ0ICovXG4gICAgaGFuZGxlVG91Y2hzdGFydCA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWwuaGFuZGxlVG91Y2hzdGFydChldmVudCk7XG4gICAgICAgIHRoaXMuaXNNb3ZpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICd0b3VjaHN0YXJ0JyxcbiAgICAgICAgICAgIGV2ZW50XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIFRvdWNobW92ZSAqL1xuICAgIGhhbmRsZUhvcml6b250YWxTd2lwZSA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWwuaGFuZGxlSG9yaXpvbnRhbFN3aXBlKGV2ZW50KTtcbiAgICAgICAgdGhpcy5ldmVudHMuZW1pdCh7XG4gICAgICAgICAgICB0eXBlOiAnc3dpcGUnLFxuICAgICAgICAgICAgZXZlbnRcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogVG91Y2hlbmQgKi9cbiAgICBoYW5kbGVUb3VjaGVuZCA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHRvdWNoZXMgPSBldmVudC50b3VjaGVzO1xuICAgICAgICB0aGlzLmNhcm91c2VsLmhhbmRsZVRvdWNoZW5kKGV2ZW50KTtcbiAgICAgICAgdGhpcy5pc01vdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICd0b3VjaGVuZCcsXG4gICAgICAgICAgICBldmVudFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiBUYXAgKi9cbiAgICBoYW5kbGVUYXAgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5jYXJvdXNlbC5zbGlkZUNvdW50ZXI7XG4gICAgICAgIGNvbnN0IGNlbGxJbmRleCA9IHRoaXMuY2Fyb3VzZWwuY3VycmVudENlbGxJbmRleDtcbiAgICAgICAgY29uc3QgZmlsZUluZGV4ID0gdGhpcy5jYXJvdXNlbC5nZXRGaWxlSW5kZXgoaSk7XG4gICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmNhcm91c2VsLmdldEZpbGUoY2VsbEluZGV4KTtcblxuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICdjbGljaycsXG4gICAgICAgICAgICBmaWxlOiBmaWxlLFxuICAgICAgICAgICAgaW5kZXg6IGZpbGVJbmRleFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBoYW5kbGVUcmFuc2l0aW9uZW5kQ2VsbENvbnRhaW5lcihldmVudCkge1xuICAgICAgICB0aGlzLmNhcm91c2VsLmhhbmRsZVNsaWRlRW5kKCk7XG4gICAgfVxuXG4gICAgdG9nZ2xlVmlkZW8odmlkZW8pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKHRoaXMudmlkZW9Qcm9wZXJ0aWVzLm5vUGxheSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZpZGVvLnBhdXNlZCkge1xuICAgICAgICAgICAgdmlkZW8ucGxheSgpO1xuICAgICAgICAgICAgdGhpcy5pc1ZpZGVvUGxheWluZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2aWRlby5wYXVzZSgpO1xuICAgICAgICAgICAgdGhpcy5pc1ZpZGVvUGxheWluZyA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIGdldEN1cnJlbnRJbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWwuc2xpZGVDb3VudGVyO1xuICAgIH1cblxuICAgIGdldENlbGxXaWR0aCgpOiBudW1iZXIge1xuICAgICAgICBpZiAodGhpcy5fY2VsbFdpZHRoID09PSAnMTAwJScpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jZWxsV2lkdGg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZXh0KCkge1xuICAgICAgICB0aGlzLmNhcm91c2VsLm5leHQoMSk7XG4gICAgfVxuXG4gICAgcHJldigpIHtcbiAgICAgICAgdGhpcy5jYXJvdXNlbC5wcmV2KDEpO1xuICAgIH1cblxuICAgIHNlbGVjdChpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWwuc2VsZWN0KGluZGV4KTtcbiAgICB9XG5cbiAgICBpc05leHRBcnJvd0Rpc2FibGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5pc05leHRBcnJvd0Rpc2FibGVkKCk7XG4gICAgfVxuXG4gICAgaXNQcmV2QXJyb3dEaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWwuaXNQcmV2QXJyb3dEaXNhYmxlZCgpO1xuICAgIH1cblxuICAgIGNsb3NlKCkge1xuICAgICAgICB0aGlzLm92ZXJsYXlFdmVudFNlcnZpY2UuZW1pdENoYW5nZUV2ZW50KHtcbiAgICAgICAgICAgIHR5cGU6ICdIaWRlJ1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzZXRJbml0aWFsSW5kZXgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9wcm9wZXJ0aWVzLm1ldGFkYXRhLmluZGV4ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3QodGhpcy5fcHJvcGVydGllcy5tZXRhZGF0YS5pbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG59Il19