carousel-angular
Version:
A simple carousel component for Angular 14+ based on 'angular-responsive-carousel' by Ivy Laboratory http://ivylab.space
362 lines • 50.2 kB
JavaScript
import { Component, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core';
import { Touches } from './touches';
import { Carousel } from './carousel';
import { Container } from './container';
import { Cells } from './cells';
import { Slide } from './slide';
import { Utils } from './utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class CarouselComponent {
constructor(elementRef, ref) {
this.elementRef = elementRef;
this.ref = ref;
this._isCounter = false;
this._cellWidth = 200;
this.isMoving = false;
this.isNgContent = false;
this.events = new EventEmitter();
this.height = 450;
this.autoplay = true;
this.autoplayInterval = 5000;
this.pauseOnHover = true;
this.dots = false;
this.margin = 10;
this.objectFit = 'cover';
this.minSwipeDistance = 10;
this.transitionDuration = 200;
this.transitionTimingFunction = 'ease-out';
this.counterSeparator = ' / ';
this.overflowCellsLimit = 3;
this.listeners = 'mouse and touch';
this.cellsToShow = 1;
this.cellsToScroll = 1;
this.freeScroll = false;
this.arrows = true;
this.arrowsOutside = false;
this.arrowsTheme = 'light';
this.hostClassCarousel = true;
this.handleTouchstart = (event) => {
this.touches.addEventListeners('mousemove', 'handleMousemove');
this.carousel.handleTouchstart(event);
this.isMoving = true;
};
this.handleHorizontalSwipe = (event) => {
event.preventDefault();
this.carousel.handleHorizontalSwipe(event);
};
this.handleTouchend = (event) => {
const { touches } = event;
this.carousel.handleTouchend(event);
this.touches.removeEventListeners('mousemove', 'handleMousemove');
this.isMoving = false;
};
this.handleTap = (event) => {
const outboundEvent = {
name: 'click'
};
const nodes = Array.prototype.slice.call(this.cellsElement.children);
const cellElement = event.srcElement.closest('.carousel-cell');
const i = nodes.indexOf(cellElement);
const cellIndex = nodes.indexOf(cellElement);
outboundEvent.cellIndex = cellIndex;
};
}
get slideCounter() {
if (this.carousel) {
return this.carousel.slideCounter;
}
}
get lapCounter() {
if (this.carousel) {
return this.carousel.lapCounter;
}
}
get isLandscape() {
return window.innerWidth > window.innerHeight;
}
get isSafari() {
const ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') !== -1) {
return !(ua.indexOf('chrome') > -1);
}
}
get counter() {
const counter = this.slideCounter;
return counter + 1 + this.counterSeparator + this.cellLength;
}
get cellsElement() {
return this.elementRef.nativeElement.querySelector('.carousel-cells');
}
get isArrows() {
return this.arrows && !this.freeScroll;
}
get isCounter() {
return this._isCounter && this.cellLength > 1;
}
get activeDotIndex() {
return this.slideCounter % this.cellLength;
}
get cellLimit() {
if (this.carousel) {
return this.carousel.cellLimit;
}
}
get carouselWidth() {
return this.elementRef.nativeElement.clientWidth;
}
set cellWidth(value) {
if (value) {
this._cellWidth = value;
}
}
set isCounter(value) {
if (value) {
this._isCounter = value;
}
}
onWindowResize(event) {
if (this.utils.visibleWidth !== this.savedCarouselWidth) {
this.resize();
}
}
onMouseEnter() {
if (this.autoplay && this.pauseOnHover) {
this.carouselProperties.autoplayIsPossible = false;
this.carousel.stopAutoplay();
}
}
onMouseLeave() {
if (this.autoplay && this.pauseOnHover) {
this.carouselProperties.autoplayIsPossible = true;
this.carousel.autoplay();
}
}
onDragStart() {
return false;
}
ngOnInit() {
this.isNgContent = this.cellsElement.children.length > 0;
this.touches = new Touches({
element: this.cellsElement,
listeners: this.listeners,
mouseListeners: {
mousedown: 'handleMousedown',
mouseup: 'handleMouseup'
}
});
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.setDimensions();
}
ngAfterViewInit() {
this.initCarousel();
this.cellLength = this.getCellLength();
this.dotsArr = Array(this.cellLength).fill(1);
this.ref.detectChanges();
this.carousel.lineUpCells();
this.savedCarouselWidth = this.carouselWidth;
/* Start detecting changes in the DOM tree */
this.detectDomChanges();
}
ngOnChanges(changes) {
const isFirstChange = Object.values(changes).some(change => change.isFirstChange());
if (!isFirstChange && (changes.width || changes.height)) {
this.setDimensions();
this.initCarousel();
this.carousel.lineUpCells();
this.ref.detectChanges();
}
}
ngOnDestroy() {
this.touches.destroy();
// this.carousel.destroy();
}
initCarousel() {
this.carouselProperties = {
id: this.id,
cellsElement: this.elementRef.nativeElement.querySelector('.carousel-cells'),
hostElement: this.elementRef.nativeElement,
cellWidth: this.getCellWidth(),
autoplayInterval: this.autoplayInterval,
autoplayIsPossible: true,
overflowCellsLimit: this.overflowCellsLimit,
visibleWidth: this.width,
margin: this.margin,
minSwipeDistance: this.minSwipeDistance,
transitionDuration: this.transitionDuration,
transitionTimingFunction: this.transitionTimingFunction,
videoProperties: this.videoProperties,
eventHandler: this.events,
freeScroll: this.freeScroll
};
this.utils = new Utils(this.carouselProperties);
this.cells = new Cells(this.carouselProperties, this.utils);
this.container = new Container(this.carouselProperties, this.utils, this.cells);
this.slide = new Slide(this.carouselProperties, this.utils, this.cells, this.container);
if (this.autoplay && this.carousel) {
this.carousel.stopAutoplay();
}
this.carousel = new Carousel(this.carouselProperties, this.utils, this.cells, this.container, this.slide);
if (this.autoplay) {
this.carousel.autoplay();
}
}
resize() {
this.landscapeMode = this.isLandscape;
this.savedCarouselWidth = this.carouselWidth;
this.carouselProperties.cellWidth = this.getCellWidth();
this.cells.updateProperties(this.carouselProperties);
this.carousel.updateProperties(this.carouselProperties);
this.container.updateProperties(this.carouselProperties);
this.slide.updateProperties(this.carouselProperties);
this.utils.updateProperties(this.carouselProperties);
this.carousel.lineUpCells();
this.slide.select(0);
this.ref.detectChanges();
}
detectDomChanges() {
const observer = new MutationObserver((mutations) => {
this.onDomChanges();
});
const config = {
attributes: true,
childList: true,
characterData: true
};
observer.observe(this.cellsElement, config);
}
onDomChanges() {
this.cellLength = this.getCellLength();
this.carousel.lineUpCells();
this.ref.detectChanges();
}
setDimensions() {
this.hostStyleHeight = `${this.height}px`;
this.hostStyleWidth = `${this.width}px`;
}
handleTransitionendCellContainer(event) {
if (event.target.className === 'carousel-cells') {
this.carousel.handleTransitionend();
}
}
getCellWidth() {
const elementWidth = this.carouselWidth;
if (this.cellsToShow) {
const margin = this.cellsToShow > 1 ? this.margin : 0;
const totalMargin = margin * (this.cellsToShow - 1);
return (elementWidth - totalMargin) / this.cellsToShow;
}
if (this._cellWidth === '100%') {
return elementWidth;
}
return this._cellWidth;
}
next() {
this.carousel.next(this.cellsToScroll);
this.carousel.stopAutoplay();
}
prev() {
this.carousel.prev(this.cellsToScroll);
this.carousel.stopAutoplay();
}
isNextArrowDisabled() {
if (this.carousel) {
return this.carousel.isNextArrowDisabled();
}
}
isPrevArrowDisabled() {
if (this.carousel) {
return this.carousel.isPrevArrowDisabled();
}
}
getCellLength() {
return this.cellsElement.children.length;
}
}
CarouselComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
CarouselComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CarouselComponent, selector: "carousel, [carousel]", inputs: { id: "id", height: "height", width: "width", autoplay: "autoplay", autoplayInterval: "autoplayInterval", pauseOnHover: "pauseOnHover", dots: "dots", borderRadius: "borderRadius", margin: "margin", objectFit: "objectFit", minSwipeDistance: "minSwipeDistance", transitionDuration: "transitionDuration", transitionTimingFunction: "transitionTimingFunction", videoProperties: "videoProperties", counterSeparator: "counterSeparator", overflowCellsLimit: "overflowCellsLimit", listeners: "listeners", cellsToShow: "cellsToShow", cellsToScroll: "cellsToScroll", freeScroll: "freeScroll", arrows: "arrows", arrowsOutside: "arrowsOutside", arrowsTheme: "arrowsTheme", cellWidth: "cellWidth", isCounter: ["counter", "isCounter"] }, outputs: { events: "events" }, host: { listeners: { "window:resize": "onWindowResize($event)", "mouseenter": "onMouseEnter($event)", "mouseleave": "onMouseLeave($event)", "dragstart": "onDragStart($event)" }, properties: { "class.carousel": "this.hostClassCarousel", "style.height": "this.hostStyleHeight", "style.width": "this.hostStyleWidth" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\r\n\r\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\r\n\t<div class=\"carousel-cells\" #cells (transitionend)=\"handleTransitionendCellContainer($event)\">\r\n\t\t<ng-content></ng-content>\r\n\t</div>\r\n\r\n\t<div class=\"carousel-dots\" *ngIf=\"dots\">\r\n\t\t<div class=\"carousel-dot\" [class.carousel-dot-active]=\"i === activeDotIndex\" *ngFor=\"let dot of dotsArr; index as i\"></div>\r\n\t</div>\r\n</div>\r\n\r\n<div class=\"carousel-arrows\"\r\n\t[class.carousel-arrows-outside]=\"arrowsOutside\"\r\n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\r\n\t*ngIf=\"isArrows\">\r\n\r\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\r\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\r\n</div>\r\n", styles: [":host{-webkit-user-select:none;user-select:none;position:relative;z-index:10000;top:0;left:0;transform-origin:top left;display:block;box-sizing:border-box;width:100%;height:100%}:host .carousel-container{cursor:grab;overflow:hidden;width:100%;height:100%}:host .carousel-container.carousel-moving{cursor:grabbing}:host .carousel-counter{position:absolute;z-index:30;top:8px;right:24px;padding:5px 7px;font-size:11px;line-height:initial;color:#fff;text-align:right;background-color:#1725444d;border-radius:13px;transition:opacity .2s}:host ::ng-deep .carousel-cells{will-change:transform;display:block;width:100%;height:100%;transition:transform .2s}:host ::ng-deep .carousel-cells .carousel-cell{position:absolute;overflow:hidden;width:100%;height:100%}:host ::ng-deep .carousel-cells .carousel-cell img,:host ::ng-deep .carousel-cells .carousel-cell video{position:relative;width:100%;height:100%;object-fit:contain}:host ::ng-deep .carousel-cells .carousel-cell img.swiper-hide{display:none}:host ::ng-deep .carousel-cells .carousel-cell .carousel-play{position:absolute;z-index:1;inset:0}:host .carousel-arrow{cursor:pointer;position:absolute;z-index:10;top:50%;display:inline-block;width:20px;height:20px;margin-top:-10px;opacity:0;border:solid rgba(255,255,255,.6);border-width:0 4px 4px 0;border-radius:2px;transition:opacity .1s ease-in-out}:host .carousel-arrow:before{content:\" \";position:absolute;top:-50px;left:-50px;display:inline-block;width:100px;height:100px;border:0}:host .carousel-arrow:hover{opacity:.5}:host .carousel-arrow-prev{left:35px;transform:rotate(135deg)}:host .carousel-arrow-next{right:35px;transform:rotate(-45deg)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{filter:invert(1)}:host .carousel-arrow-disabled{display:none}:host .carousel-dots{position:absolute;z-index:10;right:0;bottom:0;left:0;text-align:center}:host .carousel-dots .carousel-dot{display:inline-block;width:8px;height:8px;margin:4px;border:2px solid #fff;border-radius:100px}:host .carousel-dots .carousel-dot-active{background-color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CarouselComponent, decorators: [{
type: Component,
args: [{ selector: 'carousel, [carousel]', template: "<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\r\n\r\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\r\n\t<div class=\"carousel-cells\" #cells (transitionend)=\"handleTransitionendCellContainer($event)\">\r\n\t\t<ng-content></ng-content>\r\n\t</div>\r\n\r\n\t<div class=\"carousel-dots\" *ngIf=\"dots\">\r\n\t\t<div class=\"carousel-dot\" [class.carousel-dot-active]=\"i === activeDotIndex\" *ngFor=\"let dot of dotsArr; index as i\"></div>\r\n\t</div>\r\n</div>\r\n\r\n<div class=\"carousel-arrows\"\r\n\t[class.carousel-arrows-outside]=\"arrowsOutside\"\r\n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\r\n\t*ngIf=\"isArrows\">\r\n\r\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\r\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\r\n</div>\r\n", styles: [":host{-webkit-user-select:none;user-select:none;position:relative;z-index:10000;top:0;left:0;transform-origin:top left;display:block;box-sizing:border-box;width:100%;height:100%}:host .carousel-container{cursor:grab;overflow:hidden;width:100%;height:100%}:host .carousel-container.carousel-moving{cursor:grabbing}:host .carousel-counter{position:absolute;z-index:30;top:8px;right:24px;padding:5px 7px;font-size:11px;line-height:initial;color:#fff;text-align:right;background-color:#1725444d;border-radius:13px;transition:opacity .2s}:host ::ng-deep .carousel-cells{will-change:transform;display:block;width:100%;height:100%;transition:transform .2s}:host ::ng-deep .carousel-cells .carousel-cell{position:absolute;overflow:hidden;width:100%;height:100%}:host ::ng-deep .carousel-cells .carousel-cell img,:host ::ng-deep .carousel-cells .carousel-cell video{position:relative;width:100%;height:100%;object-fit:contain}:host ::ng-deep .carousel-cells .carousel-cell img.swiper-hide{display:none}:host ::ng-deep .carousel-cells .carousel-cell .carousel-play{position:absolute;z-index:1;inset:0}:host .carousel-arrow{cursor:pointer;position:absolute;z-index:10;top:50%;display:inline-block;width:20px;height:20px;margin-top:-10px;opacity:0;border:solid rgba(255,255,255,.6);border-width:0 4px 4px 0;border-radius:2px;transition:opacity .1s ease-in-out}:host .carousel-arrow:before{content:\" \";position:absolute;top:-50px;left:-50px;display:inline-block;width:100px;height:100px;border:0}:host .carousel-arrow:hover{opacity:.5}:host .carousel-arrow-prev{left:35px;transform:rotate(135deg)}:host .carousel-arrow-next{right:35px;transform:rotate(-45deg)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{filter:invert(1)}:host .carousel-arrow-disabled{display:none}:host .carousel-dots{position:absolute;z-index:10;right:0;bottom:0;left:0;text-align:center}:host .carousel-dots .carousel-dot{display:inline-block;width:8px;height:8px;margin:4px;border:2px solid #fff;border-radius:100px}:host .carousel-dots .carousel-dot-active{background-color:#fff}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { events: [{
type: Output
}], id: [{
type: Input
}], height: [{
type: Input
}], width: [{
type: Input
}], autoplay: [{
type: Input
}], autoplayInterval: [{
type: Input
}], pauseOnHover: [{
type: Input
}], dots: [{
type: Input
}], borderRadius: [{
type: Input
}], margin: [{
type: Input
}], objectFit: [{
type: Input
}], minSwipeDistance: [{
type: Input
}], transitionDuration: [{
type: Input
}], transitionTimingFunction: [{
type: Input
}], videoProperties: [{
type: Input
}], counterSeparator: [{
type: Input
}], overflowCellsLimit: [{
type: Input
}], listeners: [{
type: Input
}], cellsToShow: [{
type: Input
}], cellsToScroll: [{
type: Input
}], freeScroll: [{
type: Input
}], arrows: [{
type: Input
}], arrowsOutside: [{
type: Input
}], arrowsTheme: [{
type: Input
}], cellWidth: [{
type: Input,
args: ['cellWidth']
}], isCounter: [{
type: Input,
args: ['counter']
}], hostClassCarousel: [{
type: HostBinding,
args: ['class.carousel']
}], hostStyleHeight: [{
type: HostBinding,
args: ['style.height']
}], hostStyleWidth: [{
type: HostBinding,
args: ['style.width']
}], onWindowResize: [{
type: HostListener,
args: ['window:resize', ['$event']]
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter', ['$event']]
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave', ['$event']]
}], onDragStart: [{
type: HostListener,
args: ['dragstart', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY2Fyb3VzZWwtYW5ndWxhci9zcmMvbGliL2Nhcm91c2VsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3Byb2plY3RzL2Nhcm91c2VsLWFuZ3VsYXIvc3JjL2xpYi9jYXJvdXNlbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBR1AsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNoQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7OztBQU9oQyxNQUFNLE9BQU8saUJBQWlCO0lBd0w1QixZQUFvQixVQUFzQixFQUFVLEdBQXNCO1FBQXRELGVBQVUsR0FBVixVQUFVLENBQVk7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXpLMUUsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUVuQixlQUFVLEdBQW9CLEdBQUcsQ0FBQztRQUVsQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWpCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBZ0VWLFdBQU0sR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUlyRCxXQUFNLEdBQUcsR0FBRyxDQUFDO1FBSWIsYUFBUSxHQUFHLElBQUksQ0FBQztRQUVoQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFF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QUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsYUFBYTtzQkFBckIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRWtCLFNBQVM7c0JBQWhDLEtBQUs7dUJBQUMsV0FBVztnQkFNSSxTQUFTO3NCQUE5QixLQUFLO3VCQUFDLFNBQVM7Z0JBTWUsaUJBQWlCO3NCQUEvQyxXQUFXO3VCQUFDLGdCQUFnQjtnQkFFQSxlQUFlO3NCQUEzQyxXQUFXO3VCQUFDLGNBQWM7Z0JBRUMsY0FBYztzQkFBekMsV0FBVzt1QkFBQyxhQUFhO2dCQUcxQixjQUFjO3NCQURiLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVF6QyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVN0QyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVN0QyxXQUFXO3NCQURWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFByb3BlcnRpZXMgYXMgQ2Fyb3VzZWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFRvdWNoZXMgfSBmcm9tICcuL3RvdWNoZXMnO1xuaW1wb3J0IHsgQ2Fyb3VzZWwgfSBmcm9tICcuL2Nhcm91c2VsJztcbmltcG9ydCB7IENvbnRhaW5lciB9IGZyb20gJy4vY29udGFpbmVyJztcbmltcG9ydCB7IENlbGxzIH0gZnJvbSAnLi9jZWxscyc7XG5pbXBvcnQgeyBTbGlkZSB9IGZyb20gJy4vc2xpZGUnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuL3V0aWxzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2Fyb3VzZWwsIFtjYXJvdXNlbF0nLFxuICB0ZW1wbGF0ZVVybDogJy4vY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jYXJvdXNlbC5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIENhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgY2Fyb3VzZWw6IGFueTtcblxuICBjb250YWluZXI6IGFueTtcblxuICB1dGlsczogYW55O1xuXG4gIGNlbGxzOiBhbnk7XG5cbiAgc2xpZGU6IGFueTtcblxuICB0b3VjaGVzOiBhbnk7XG5cbiAgbGFuZHNjYXBlTW9kZTogYW55O1xuXG4gIF9pc0NvdW50ZXIgPSBmYWxzZTtcblxuICBfY2VsbFdpZHRoOiBudW1iZXIgfCAnMTAwJScgPSAyMDA7XG5cbiAgaXNNb3ZpbmcgPSBmYWxzZTtcblxuICBpc05nQ29udGVudCA9IGZhbHNlO1xuXG4gIGNlbGxMZW5ndGghOiBudW1iZXI7XG5cbiAgZG90c0FycjogYW55O1xuXG4gIGNhcm91c2VsUHJvcGVydGllcyE6IENhcm91c2VsUHJvcGVydGllcztcblxuICBzYXZlZENhcm91c2VsV2lkdGghOiBudW1iZXI7XG5cbiAgZ2V0IHNsaWRlQ291bnRlcigpIHtcbiAgICBpZiAodGhpcy5jYXJvdXNlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWwuc2xpZGVDb3VudGVyO1xuICAgIH1cbiAgfVxuXG4gIGdldCBsYXBDb3VudGVyKCkge1xuICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5sYXBDb3VudGVyO1xuICAgIH1cbiAgfVxuXG4gIGdldCBpc0xhbmRzY2FwZSgpIHtcbiAgICByZXR1cm4gd2luZG93LmlubmVyV2lkdGggPiB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gIH1cblxuICBnZXQgaXNTYWZhcmkoKTogYW55IHtcbiAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAodWEuaW5kZXhPZignc2FmYXJpJykgIT09IC0xKSB7XG4gICAgICByZXR1cm4gISh1YS5pbmRleE9mKCdjaHJvbWUnKSA+IC0xKTtcbiAgICB9XG4gIH1cblxuICBnZXQgY291bnRlcigpIHtcbiAgICBjb25zdCBjb3VudGVyID0gdGhpcy5zbGlkZUNvdW50ZXI7XG4gICAgcmV0dXJuIGNvdW50ZXIgKyAxICsgdGhpcy5jb3VudGVyU2VwYXJhdG9yICsgdGhpcy5jZWxsTGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGNlbGxzRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyk7XG4gIH1cblxuICBnZXQgaXNBcnJvd3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXJyb3dzICYmICF0aGlzLmZyZWVTY3JvbGw7XG4gIH1cblxuICBnZXQgaXNDb3VudGVyKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0NvdW50ZXIgJiYgdGhpcy5jZWxsTGVuZ3RoID4gMTtcbiAgfVxuXG4gIGdldCBhY3RpdmVEb3RJbmRleCgpIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZUNvdW50ZXIgJSB0aGlzLmNlbGxMZW5ndGg7XG4gIH1cblxuICBnZXQgY2VsbExpbWl0KCkge1xuICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5jZWxsTGltaXQ7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNhcm91c2VsV2lkdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xuICB9XG5cbiAgQE91dHB1dCgpIGV2ZW50czogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBASW5wdXQoKSBpZCE6IG51bWJlcjtcblxuICBASW5wdXQoKSBoZWlnaHQgPSA0NTA7XG5cbiAgQElucHV0KCkgd2lkdGghOiBudW1iZXI7XG5cbiAgQElucHV0KCkgYXV0b3BsYXkgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIGF1dG9wbGF5SW50ZXJ2YWwgPSA1MDAwO1xuXG4gIEBJbnB1dCgpIHBhdXNlT25Ib3ZlciA9IHRydWU7XG5cbiAgQElucHV0KCkgZG90cyA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIGJvcmRlclJhZGl1cyE6IG51bWJlcjtcblxuICBASW5wdXQoKSBtYXJnaW4gPSAxMDtcblxuICBASW5wdXQoKSBvYmplY3RGaXQ6ICdjb250YWluJyB8ICdjb3ZlcicgfCAnbm9uZScgPSAnY292ZXInO1xuXG4gIEBJbnB1dCgpIG1pblN3aXBlRGlzdGFuY2UgPSAxMDtcblxuICBASW5wdXQoKSB0cmFuc2l0aW9uRHVyYXRpb24gPSAyMDA7XG5cbiAgQElucHV0KCkgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uOlxuICAgIHwgJ2Vhc2UnXG4gICAgfCAnZWFzZS1pbidcbiAgICB8ICdlYXNlLW91dCdcbiAgICB8ICdlYXNlLWluLW91dCdcbiAgICB8ICdsaW5lYXInID0gJ2Vhc2Utb3V0JztcblxuICBASW5wdXQoKSB2aWRlb1Byb3BlcnRpZXM6IGFueTtcblxuICBASW5wdXQoKSBjb3VudGVyU2VwYXJhdG9yID0gJyAvICc7XG5cbiAgQElucHV0KCkgb3ZlcmZsb3dDZWxsc0xpbWl0ID0gMztcblxuICBASW5wdXQoKSBsaXN0ZW5lcnM6ICdhdXRvJyB8ICdtb3VzZSBhbmQgdG91Y2gnID0gJ21vdXNlIGFuZCB0b3VjaCc7XG5cbiAgQElucHV0KCkgY2VsbHNUb1Nob3cgPSAxO1xuXG4gIEBJbnB1dCgpIGNlbGxzVG9TY3JvbGwgPSAxO1xuXG4gIEBJbnB1dCgpIGZyZWVTY3JvbGwgPSBmYWxzZTtcblxuICBASW5wdXQoKSBhcnJvd3MgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIGFycm93c091dHNpZGUgPSBmYWxzZTtcblxuICBASW5wdXQoKSBhcnJvd3NUaGVtZTogJ2xpZ2h0JyB8ICdkYXJrJyA9ICdsaWdodCc7XG5cbiAgQElucHV0KCdjZWxsV2lkdGgnKSBzZXQgY2VsbFdpZHRoKHZhbHVlOiBudW1iZXIgfCAnMTAwJScpIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuX2NlbGxXaWR0aCA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgnY291bnRlcicpIHNldCBpc0NvdW50ZXIodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuX2lzQ291bnRlciA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuY2Fyb3VzZWwnKSBob3N0Q2xhc3NDYXJvdXNlbCA9IHRydWU7XG5cbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS5oZWlnaHQnKSBob3N0U3R5bGVIZWlnaHQhOiBzdHJpbmc7XG5cbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS53aWR0aCcpIGhvc3RTdHlsZVdpZHRoITogc3RyaW5nO1xuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuICBvbldpbmRvd1Jlc2l6ZShldmVudDogYW55KSB7XG4gICAgaWYgKHRoaXMudXRpbHMudmlzaWJsZVdpZHRoICE9PSB0aGlzLnNhdmVkQ2Fyb3VzZWxXaWR0aCkge1xuICAgICAgdGhpcy5yZXNpemUoKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZUVudGVyKCkge1xuICAgIGlmICh0aGlzLmF1dG9wbGF5ICYmIHRoaXMucGF1c2VPbkhvdmVyKSB7XG4gICAgICB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5hdXRvcGxheUlzUG9zc2libGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2Fyb3VzZWwuc3RvcEF1dG9wbGF5KCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScsIFsnJGV2ZW50J10pXG4gIG9uTW91c2VMZWF2ZSgpIHtcbiAgICBpZiAodGhpcy5hdXRvcGxheSAmJiB0aGlzLnBhdXNlT25Ib3Zlcikge1xuICAgICAgdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuYXV0b3BsYXlJc1Bvc3NpYmxlID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2Fyb3VzZWwuYXV0b3BsYXkoKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcmFnc3RhcnQnLCBbJyRldmVudCddKVxuICBvbkRyYWdTdGFydCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgcmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmlzTmdDb250ZW50ID0gdGhpcy5jZWxsc0VsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID4gMDtcblxuICAgIHRoaXMudG91Y2hlcyA9IG5ldyBUb3VjaGVzKHtcbiAgICAgIGVsZW1lbnQ6IHRoaXMuY2VsbHNFbGVtZW50LFxuICAgICAgbGlzdGVuZXJzOiB0aGlzLmxpc3RlbmVycyxcbiAgICAgIG1vdXNlTGlzdGVuZXJzOiB7XG4gICAgICAgIG1vdXNlZG93bjogJ2hhbmRsZU1vdXNlZG93bicsXG4gICAgICAgIG1vdXNldXA6ICdoYW5kbGVNb3VzZXVwJ1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy50b3VjaGVzLm9uKCd0b3VjaHN0YXJ0JywgdGhpcy5oYW5kbGVUb3VjaHN0YXJ0KTtcbiAgICB0aGlzLnRvdWNoZXMub24oJ2hvcml6b250YWwtc3dpcGUnLCB0aGlzLmhhbmRsZUhvcml6b250YWxTd2lwZSk7XG4gICAgdGhpcy50b3VjaGVzLm9uKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgIHRoaXMudG91Y2hlcy5vbignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVUb3VjaHN0YXJ0KTtcbiAgICB0aGlzLnRvdWNoZXMub24oJ21vdXNldXAnLCB0aGlzLmhhbmRsZVRvdWNoZW5kKTtcbiAgICB0aGlzLnRvdWNoZXMub24oJ3RhcCcsIHRoaXMuaGFuZGxlVGFwKTtcblxuICAgIHRoaXMuc2V0RGltZW5zaW9ucygpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaW5pdENhcm91c2VsKCk7XG4gICAgdGhpcy5jZWxsTGVuZ3RoID0gdGhpcy5nZXRDZWxsTGVuZ3RoKCk7XG4gICAgdGhpcy5kb3RzQXJyID0gQXJyYXkodGhpcy5jZWxsTGVuZ3RoKS5maWxsKDEpO1xuICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLmNhcm91c2VsLmxpbmVVcENlbGxzKCk7XG4gICAgdGhpcy5zYXZlZENhcm91c2VsV2lkdGggPSB0aGlzLmNhcm91c2VsV2lkdGg7XG5cbiAgICAvKiBTdGFydCBkZXRlY3RpbmcgY2hhbmdlcyBpbiB0aGUgRE9NIHRyZWUgKi9cbiAgICB0aGlzLmRldGVjdERvbUNoYW5nZXMoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICAgICAgY29uc3QgaXNGaXJzdENoYW5nZSA9IE9iamVjdC52YWx1ZXMoY2hhbmdlcykuc29tZShjaGFuZ2UgPT4gY2hhbmdlLmlzRmlyc3RDaGFuZ2UoKSk7XG4gICAgaWYgKCFpc0ZpcnN0Q2hhbmdlICYmIChjaGFuZ2VzLndpZHRoIHx8IGNoYW5nZXMuaGVpZ2h0KSkge1xuICAgICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgICB0aGlzLmluaXRDYXJvdXNlbCgpO1xuICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMudG91Y2hlcy5kZXN0cm95KCk7XG4gICAgLy8gdGhpcy5jYXJvdXNlbC5kZXN0cm95KCk7XG4gIH1cblxuICBpbml0Q2Fyb3VzZWwoKSB7XG4gICAgdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMgPSB7XG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIGNlbGxzRWxlbWVudDpcbiAgICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyksXG4gICAgICBob3N0RWxlbWVudDogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICBjZWxsV2lkdGg6IHRoaXMuZ2V0Q2VsbFdpZHRoKCksXG4gICAgICBhdXRvcGxheUludGVydmFsOiB0aGlzLmF1dG9wbGF5SW50ZXJ2YWwsXG4gICAgICBhdXRvcGxheUlzUG9zc2libGU6IHRydWUsXG4gICAgICBvdmVyZmxvd0NlbGxzTGltaXQ6IHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0LFxuICAgICAgdmlzaWJsZVdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgbWFyZ2luOiB0aGlzLm1hcmdpbixcbiAgICAgIG1pblN3aXBlRGlzdGFuY2U6IHRoaXMubWluU3dpcGVEaXN0YW5jZSxcbiAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogdGhpcy50cmFuc2l0aW9uRHVyYXRpb24sXG4gICAgICB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246IHRoaXMudHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uLFxuICAgICAgdmlkZW9Qcm9wZXJ0aWVzOiB0aGlzLnZpZGVvUHJvcGVydGllcyxcbiAgICAgIGV2ZW50SGFuZGxlcjogdGhpcy5ldmVudHMsXG4gICAgICBmcmVlU2Nyb2xsOiB0aGlzLmZyZWVTY3JvbGxcbiAgICB9O1xuXG4gICAgdGhpcy51dGlscyA9IG5ldyBVdGlscyh0aGlzLmNhcm91c2VsUHJvcGVydGllcyk7XG4gICAgdGhpcy5jZWxscyA9IG5ldyBDZWxscyh0aGlzLmNhcm91c2VsUHJvcGVydGllcywgdGhpcy51dGlscyk7XG4gICAgdGhpcy5jb250YWluZXIgPSBuZXcgQ29udGFpbmVyKFxuICAgICAgdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMsXG4gICAgICB0aGlzLnV0aWxzLFxuICAgICAgdGhpcy5jZWxsc1xuICAgICk7XG4gICAgdGhpcy5zbGlkZSA9IG5ldyBTbGlkZShcbiAgICAgIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzLFxuICAgICAgdGhpcy51dGlscyxcbiAgICAgIHRoaXMuY2VsbHMsXG4gICAgICB0aGlzLmNvbnRhaW5lclxuICAgICk7XG5cbiAgICBpZiAodGhpcy5hdXRvcGxheSAmJiB0aGlzLmNhcm91c2VsKSB7XG4gICAgICB0aGlzLmNhcm91c2VsLnN0b3BBdXRvcGxheSgpO1xuICAgIH1cbiAgICB0aGlzLmNhcm91c2VsID0gbmV3IENhcm91c2VsKFxuICAgICAgdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMsXG4gICAgICB0aGlzLnV0aWxzLFxuICAgICAgdGhpcy5jZWxscyxcbiAgICAgIHRoaXMuY29udGFpbmVyLFxuICAgICAgdGhpcy5zbGlkZVxuICAgICk7XG5cbiAgICBpZiAodGhpcy5hdXRvcGxheSkge1xuICAgICAgdGhpcy5jYXJvdXNlbC5hdXRvcGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2l6ZSgpIHtcbiAgICB0aGlzLmxhbmRzY2FwZU1vZGUgPSB0aGlzLmlzTGFuZHNjYXBlO1xuICAgIHRoaXMuc2F2ZWRDYXJvdXNlbFdpZHRoID0gdGhpcy5jYXJvdXNlbFdpZHRoO1xuXG4gICAgdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuY2VsbFdpZHRoID0gdGhpcy5nZXRDZWxsV2lkdGgoKTtcbiAgICB0aGlzLmNlbGxzLnVwZGF0ZVByb3BlcnRpZXModGhpcy5jYXJvdXNlbFByb3BlcnRpZXMpO1xuICAgIHRoaXMuY2Fyb3VzZWwudXBkYXRlUHJvcGVydGllcyh0aGlzLmNhcm91c2VsUHJvcGVydGllcyk7XG4gICAgdGhpcy5jb250YWluZXIudXBkYXRlUHJvcGVydGllcyh0aGlzLmNhcm91c2VsUHJvcGVydGllcyk7XG4gICAgdGhpcy5zbGlkZS51cGRhdGVQcm9wZXJ0aWVzKHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzKTtcbiAgICB0aGlzLnV0aWxzLnVwZGF0ZVByb3BlcnRpZXModGhpcy5jYXJvdXNlbFByb3BlcnRpZXMpO1xuICAgIHRoaXMuY2Fyb3VzZWwubGluZVVwQ2VsbHMoKTtcbiAgICB0aGlzLnNsaWRlLnNlbGVjdCgwKTtcbiAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBkZXRlY3REb21DaGFuZ2VzKCkge1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9ucykgPT4ge1xuICAgICAgdGhpcy5vbkRvbUNoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlXG4gICAgfTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKHRoaXMuY2VsbHNFbGVtZW50LCBjb25maWcpO1xuICB9XG5cbiAgb25Eb21DaGFuZ2VzKCkge1xuICAgIHRoaXMuY2VsbExlbmd0aCA9IHRoaXMuZ2V0Q2VsbExlbmd0aCgpO1xuICAgIHRoaXMuY2Fyb3VzZWwubGluZVVwQ2VsbHMoKTtcbiAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBzZXREaW1lbnNpb25zKCkge1xuICAgIHRoaXMuaG9zdFN0eWxlSGVpZ2h0ID0gYCR7dGhpcy5oZWlnaHR9cHhgO1xuICAgIHRoaXMuaG9zdFN0eWxlV2lkdGggPSBgJHt0aGlzLndpZHRofXB4YDtcbiAgfVxuXG4gIGhhbmRsZVRvdWNoc3RhcnQgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgIHRoaXMudG91Y2hlcy5hZGRFdmVudExpc3RlbmVycygnbW91c2Vtb3ZlJywgJ2hhbmRsZU1vdXNlbW92ZScpO1xuICAgIHRoaXMuY2Fyb3VzZWwuaGFuZGxlVG91Y2hzdGFydChldmVudCk7XG4gICAgdGhpcy5pc01vdmluZyA9IHRydWU7XG4gIH07XG5cbiAgaGFuZGxlSG9yaXpvbnRhbFN3aXBlID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuY2Fyb3VzZWwuaGFuZGxlSG9yaXpvbnRhbFN3aXBlKGV2ZW50KTtcbiAgfTtcblxuICBoYW5kbGVUb3VjaGVuZCA9IChldmVudDogYW55KSA9PiB7XG4gICAgY29uc3QgeyB0b3VjaGVzIH0gPSBldmVudDtcbiAgICB0aGlzLmNhcm91c2VsLmhhbmRsZVRvdWNoZW5kKGV2ZW50KTtcbiAgICB0aGlzLnRvdWNoZXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoJ21vdXNlbW92ZScsICdoYW5kbGVNb3VzZW1vdmUnKTtcbiAgICB0aGlzLmlzTW92aW5nID0gZmFsc2U7XG4gIH07XG5cbiAgaGFuZGxlVGFwID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICBjb25zdCBvdXRib3VuZEV2ZW50OiBhbnkgPSB7XG4gICAgICBuYW1lOiAnY2xpY2snXG4gICAgfTtcbiAgICBjb25zdCBub2RlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuY2VsbHNFbGVtZW50LmNoaWxkcmVuKTtcbiAgICBjb25zdCBjZWxsRWxlbWVudCA9IGV2ZW50LnNyY0VsZW1lbnQuY2xvc2VzdCgnLmNhcm91c2VsLWNlbGwnKTtcbiAgICBjb25zdCBpID0gbm9kZXMuaW5kZXhPZihjZWxsRWxlbWVudCk7XG4gICAgY29uc3QgY2VsbEluZGV4ID0gbm9kZXMuaW5kZXhPZihjZWxsRWxlbWVudCk7XG5cbiAgICBvdXRib3VuZEV2ZW50LmNlbGxJbmRleCA9IGNlbGxJbmRleDtcbiAgfTtcblxuICBoYW5kbGVUcmFuc2l0aW9uZW5kQ2VsbENvbnRhaW5lcihldmVudDogYW55KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldC5jbGFzc05hbWUgPT09ICdjYXJvdXNlbC1jZWxscycpIHtcbiAgICAgIHRoaXMuY2Fyb3VzZWwuaGFuZGxlVHJhbnNpdGlvbmVuZCgpO1xuICAgIH1cbiAgfVxuXG4gIGdldENlbGxXaWR0aCgpIHtcbiAgICBjb25zdCBlbGVtZW50V2lkdGggPSB0aGlzLmNhcm91c2VsV2lkdGg7XG5cbiAgICBpZiAodGhpcy5jZWxsc1RvU2hvdykge1xuICAgICAgY29uc3QgbWFyZ2luID0gdGhpcy5jZWxsc1RvU2hvdyA+IDEgPyB0aGlzLm1hcmdpbiA6IDA7XG4gICAgICBjb25zdCB0b3RhbE1hcmdpbiA9IG1hcmdpbiAqICh0aGlzLmNlbGxzVG9TaG93IC0gMSk7XG4gICAgICByZXR1cm4gKGVsZW1lbnRXaWR0aCAtIHRvdGFsTWFyZ2luKSAvIHRoaXMuY2VsbHNUb1Nob3c7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NlbGxXaWR0aCA9PT0gJzEwMCUnKSB7XG4gICAgICByZXR1cm4gZWxlbWVudFdpZHRoO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2VsbFdpZHRoO1xuICB9XG5cbiAgbmV4dCgpIHtcbiAgICB0aGlzLmNhcm91c2VsLm5leHQodGhpcy5jZWxsc1RvU2Nyb2xsKTtcbiAgICB0aGlzLmNhcm91c2VsLnN0b3BBdXRvcGxheSgpO1xuICB9XG5cbiAgcHJldigpIHtcbiAgICB0aGlzLmNhcm91c2VsLnByZXYodGhpcy5jZWxsc1RvU2Nyb2xsKTtcbiAgICB0aGlzLmNhcm91c2VsLnN0b3BBdXRvcGxheSgpO1xuICB9XG5cbiAgaXNOZXh0QXJyb3dEaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy5jYXJvdXNlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWwuaXNOZXh0QXJyb3dEaXNhYmxlZCgpO1xuICAgIH1cbiAgfVxuXG4gIGlzUHJldkFycm93RGlzYWJsZWQoKSB7XG4gICAgaWYgKHRoaXMuY2Fyb3VzZWwpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsLmlzUHJldkFycm93RGlzYWJsZWQoKTtcbiAgICB9XG4gIH1cblxuICBnZXRDZWxsTGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLmNlbGxzRWxlbWVudC5jaGlsZHJlbi5sZW5ndGg7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjYXJvdXNlbC1jb3VudGVyXCIgKm5nSWY9XCJpc0NvdW50ZXJcIj57e2NvdW50ZXJ9fTwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImNhcm91c2VsLWNvbnRhaW5lclwiIFtjbGFzcy5jYXJvdXNlbC1tb3ZpbmddPVwiaXNNb3ZpbmdcIj5cclxuXHQ8ZGl2IGNsYXNzPVwiY2Fyb3VzZWwtY2VsbHNcIiAjY2VsbHMgKHRyYW5zaXRpb25lbmQpPVwiaGFuZGxlVHJhbnNpdGlvbmVuZENlbGxDb250YWluZXIoJGV2ZW50KVwiPlxyXG5cdFx0PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG5cdDwvZGl2PlxyXG5cclxuXHQ8ZGl2IGNsYXNzPVwiY2Fyb3VzZWwtZG90c1wiICpuZ0lmPVwiZG90c1wiPlxyXG5cdFx0PGRpdiBjbGFzcz1cImNhcm91c2VsLWRvdFwiIFtjbGFzcy5jYXJvdXNlbC1kb3QtYWN0aXZlXT1cImkgPT09IGFjdGl2ZURvdEluZGV4XCIgKm5nRm9yPVwibGV0IGRvdCBvZiBkb3RzQXJyOyBpbmRleCBhcyBpXCI+PC9kaXY+XHJcblx0PC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImNhcm91c2VsLWFycm93c1wiXHJcblx0W2NsYXNzLmNhcm91c2VsLWFycm93cy1vdXRzaWRlXT1cImFycm93c091dHNpZGVcIlxyXG5cdFtjbGFzcy5jYXJvdXNlbC1kYXJrLWFycm93c109XCJhcnJvd3NUaGVtZSA9PT0gJ2RhcmsnXCJcclxuXHQqbmdJZj1cImlzQXJyb3dzXCI+XHJcblxyXG5cdDxkaXYgY2xhc3M9XCJjYXJvdXNlbC1hcnJvdyBjYXJvdXNlbC1hcnJvdy1wcmV2XCIgW2NsYXNzLmNhcm91c2VsLWFycm93LWRpc2FibGVkXT1cImlzUHJldkFycm93RGlzYWJsZWQoKVwiIChjbGljayk9XCJwcmV2KClcIj48L2Rpdj5ccl