ngx-owl-carousel-o
Version:
Angular powered owl-carousel
363 lines • 45 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, NgZone, ElementRef, HostListener, Renderer2, Input } from '@angular/core';
import { CarouselService } from '../../services/carousel.service';
import { Subject } from 'rxjs';
import { first } from 'rxjs/operators';
import { StageData } from '../../models/stage-data.model';
import { AnimateService } from '../../services/animate.service';
import { trigger, state, style, animate, transition } from '@angular/animations';
var StageComponent = /** @class */ (function () {
function StageComponent(zone, el, renderer, carouselService, animateService) {
var _this = this;
this.zone = zone;
this.el = el;
this.renderer = renderer;
this.carouselService = carouselService;
this.animateService = animateService;
/**
* Object with data needed for dragging
*/
this._drag = {
time: null,
target: null,
pointer: null,
stage: {
start: null,
current: null
},
direction: null,
active: false,
moving: false
};
/**
* Subject for notification when the carousel's rebuilding caused by resize event starts
*/
this._oneDragMove$ = new Subject();
/**
* Passes this to _oneMouseTouchMove();
*/
this.bindOneMouseTouchMove = function (ev) {
_this._oneMouseTouchMove(ev);
};
/**
* Passes this to _onDragMove();
*/
this.bindOnDragMove = function (ev) {
_this._onDragMove(ev);
};
/**
* Passes this to _onDragMove();
*/
this.bindOnDragEnd = function (ev) {
// this.zone.run(() => {
_this._onDragEnd(ev);
// });
};
/**
* Attaches handler for 'click' event on any element in .owl-stage in order to prevent dragging when moving of cursor is less than 3px
*/
this._oneClickHandler = function () {
_this.listenerOneClick = _this.renderer.listen(_this._drag.target, 'click', function () { return false; });
_this.listenerOneClick();
};
}
StageComponent.prototype.onMouseDown = function (event) {
if (this.owlDraggable.isMouseDragable) {
this._onDragStart(event);
}
};
StageComponent.prototype.onTouchStart = function (event) {
if (this.owlDraggable.isTouchDragable) {
this._onDragStart(event);
}
};
StageComponent.prototype.onTouchCancel = function (event) {
this._onDragEnd(event);
};
StageComponent.prototype.onDragStart = function () {
if (this.owlDraggable.isMouseDragable) {
return false;
}
};
StageComponent.prototype.onSelectStart = function () {
if (this.owlDraggable.isMouseDragable) {
return false;
}
};
StageComponent.prototype.ngOnInit = function () {
var _this = this;
this._oneMoveSubsription = this._oneDragMove$
.pipe(first())
.subscribe(function () {
_this._sendChanges();
});
};
StageComponent.prototype.ngOnDestroy = function () {
this._oneMoveSubsription.unsubscribe();
};
/**
* Handles `touchstart` and `mousedown` events.
* @todo Horizontal swipe threshold as option
* @todo #261
* @param event - The event arguments.
*/
StageComponent.prototype._onDragStart = function (event) {
var _this = this;
var stage = null;
if (event.which === 3) {
return;
}
stage = this._prepareDragging(event);
this._drag.time = new Date().getTime();
this._drag.target = event.target;
this._drag.stage.start = stage;
this._drag.stage.current = stage;
this._drag.pointer = this._pointer(event);
this.listenerMouseUp = this.renderer.listen(document, 'mouseup', this.bindOnDragEnd);
this.listenerTouchEnd = this.renderer.listen(document, 'touchend', this.bindOnDragEnd);
this.zone.runOutsideAngular(function () {
_this.listenerOneMouseMove = _this.renderer.listen(document, 'mousemove', _this.bindOneMouseTouchMove);
_this.listenerOneTouchMove = _this.renderer.listen(document, 'touchmove', _this.bindOneMouseTouchMove);
});
};
/**
* Attaches listeners to `touchmove` and `mousemove` events; initiates updating carousel after starting dragging
* @param event event objech of mouse or touch event
*/
StageComponent.prototype._oneMouseTouchMove = function (event) {
var delta = this._difference(this._drag.pointer, this._pointer(event));
if (this.listenerATag) {
this.listenerATag();
}
if (Math.abs(delta.x) < 3 && Math.abs(delta.y) < 3 && this._is('valid')) {
return;
}
if ((Math.abs(delta.x) < 3 && Math.abs(delta.x) < Math.abs(delta.y)) && this._is('valid')) {
return;
}
this.listenerOneMouseMove();
this.listenerOneTouchMove();
this._drag.moving = true;
this.blockClickAnchorInDragging(event);
this.listenerMouseMove = this.renderer.listen(document, 'mousemove', this.bindOnDragMove);
this.listenerTouchMove = this.renderer.listen(document, 'touchmove', this.bindOnDragMove);
event.preventDefault();
this._enterDragging();
this._oneDragMove$.next(event);
// this._sendChanges();
};
/**
* Attaches handler to HTMLAnchorElement for preventing click while carousel is being dragged
* @param event event object
*/
StageComponent.prototype.blockClickAnchorInDragging = function (event) {
var target = event.target;
while (target && !(target instanceof HTMLAnchorElement)) {
target = target.parentElement;
}
if (target instanceof HTMLAnchorElement) {
this.listenerATag = this.renderer.listen(target, 'click', function () { return false; });
}
};
/**
* Handles the `touchmove` and `mousemove` events.
* @todo #261
* @param event - The event arguments.
*/
StageComponent.prototype._onDragMove = function (event) {
var stage;
var stageOrExit = this.carouselService.defineNewCoordsDrag(event, this._drag);
if (stageOrExit === false) {
return;
}
stage = stageOrExit;
event.preventDefault();
this._drag.stage.current = stage;
this._animate(stage.x - this._drag.stage.start.x);
};
;
/**
* Moves .owl-stage left-right
* @param coordinate coordinate to be set to .owl-stage
*/
StageComponent.prototype._animate = function (coordinate) {
this.renderer.setStyle(this.el.nativeElement.children[0], 'transform', "translate3d(" + coordinate + "px,0px,0px");
this.renderer.setStyle(this.el.nativeElement.children[0], 'transition', '0s');
};
/**
* Handles the `touchend` and `mouseup` events.
* @todo #261
* @todo Threshold for click event
* @param event - The event arguments.
*/
StageComponent.prototype._onDragEnd = function (event) {
this.carouselService.owlDOMData.isGrab = false;
this.listenerOneMouseMove();
this.listenerOneTouchMove();
if (this._drag.moving) {
this.renderer.setStyle(this.el.nativeElement.children[0], 'transform', "");
this.renderer.setStyle(this.el.nativeElement.children[0], 'transition', this.carouselService.speed(+this.carouselService.settings.dragEndSpeed || this.carouselService.settings.smartSpeed) / 1000 + 's');
this._finishDragging(event);
this.listenerMouseMove();
this.listenerTouchMove();
}
this._drag = {
time: null,
target: null,
pointer: null,
stage: {
start: null,
current: null
},
direction: null,
active: false,
moving: false
};
// this.carouselService.trigger('dragged');
this.listenerMouseUp();
this.listenerTouchEnd();
};
;
/**
* Prepares data for dragging carousel. It starts after firing `touchstart` and `mousedown` events.
* @param event - The event arguments.
* @returns stage - object with 'x' and 'y' coordinates of .owl-stage
*/
StageComponent.prototype._prepareDragging = function (event) {
return this.carouselService.prepareDragging(event);
};
/**
* Finishes dragging
* @param event object event of 'mouseUp' of 'touchend' events
*/
StageComponent.prototype._finishDragging = function (event) {
this.carouselService.finishDragging(event, this._drag, this._oneClickHandler);
};
/**
* Gets unified pointer coordinates from event.
* @param event The `mousedown` or `touchstart` event.
* @returns Contains `x` and `y` coordinates of current pointer position.
*/
StageComponent.prototype._pointer = function (event) {
return this.carouselService.pointer(event);
};
/**
* Gets the difference of two vectors.
* @param first The first vector.
* @param second- The second vector.
* @returns The difference.
*/
StageComponent.prototype._difference = function (firstC, second) {
return this.carouselService.difference(firstC, second);
};
/**
* Checks whether the carousel is in a specific state or not.
* @param specificState The state to check.
* @returns The flag which indicates if the carousel is busy.
*/
StageComponent.prototype._is = function (specificState) {
return this.carouselService.is(specificState);
};
/**
* Enters a state.
* @param name The state name.
*/
StageComponent.prototype._enter = function (name) {
this.carouselService.enter(name);
};
/**
* Sends all data needed for View.
*/
StageComponent.prototype._sendChanges = function () {
this.carouselService.sendChanges();
};
/**
* Handler for transitioend event
*/
StageComponent.prototype.onTransitionEnd = function () {
this.carouselService.onTransitionEnd();
};
/**
* Enters into a 'dragging' state
*/
StageComponent.prototype._enterDragging = function () {
this.carouselService.enterDragging();
};
/**
* Handles the end of 'animationend' event
* @param id Id of slides
*/
StageComponent.prototype.clear = function (id) {
this.animateService.clear(id);
};
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], StageComponent.prototype, "owlDraggable", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", StageData)
], StageComponent.prototype, "stageData", void 0);
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Array)
], StageComponent.prototype, "slidesData", void 0);
tslib_1.__decorate([
HostListener('mousedown', ['$event']),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", [Object]),
tslib_1.__metadata("design:returntype", void 0)
], StageComponent.prototype, "onMouseDown", null);
tslib_1.__decorate([
HostListener('touchstart', ['$event']),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", [Object]),
tslib_1.__metadata("design:returntype", void 0)
], StageComponent.prototype, "onTouchStart", null);
tslib_1.__decorate([
HostListener('touchcancel', ['$event']),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", [Object]),
tslib_1.__metadata("design:returntype", void 0)
], StageComponent.prototype, "onTouchCancel", null);
tslib_1.__decorate([
HostListener('dragstart'),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", []),
tslib_1.__metadata("design:returntype", void 0)
], StageComponent.prototype, "onDragStart", null);
tslib_1.__decorate([
HostListener('selectstart'),
tslib_1.__metadata("design:type", Function),
tslib_1.__metadata("design:paramtypes", []),
tslib_1.__metadata("design:returntype", void 0)
], StageComponent.prototype, "onSelectStart", null);
StageComponent = tslib_1.__decorate([
Component({
selector: 'owl-stage',
template: "\n <div>\n <div class=\"owl-stage\" [ngStyle]=\"{'width': stageData.width + 'px',\n 'transform': stageData.transform,\n 'transition': stageData.transition,\n 'padding-left': stageData.paddingL ? stageData.paddingL + 'px' : '',\n 'padding-right': stageData.paddingR ? stageData.paddingR + 'px' : '' }\"\n (transitionend)=\"onTransitionEnd()\">\n <ng-container *ngFor=\"let slide of slidesData; let i = index\">\n <div class=\"owl-item\" [ngClass]=\"slide.classes\"\n [ngStyle]=\"{'width': slide.width + 'px',\n 'margin-left': slide.marginL ? slide.marginL + 'px' : '',\n 'margin-right': slide.marginR ? slide.marginR + 'px' : '',\n 'left': slide.left}\"\n (animationend)=\"clear(slide.id)\"\n [@autoHeight]=\"slide.heightState\">\n <ng-template *ngIf=\"slide.load\" [ngTemplateOutlet]=\"slide.tplRef\"></ng-template>\n </div><!-- /.owl-item -->\n </ng-container>\n </div><!-- /.owl-stage -->\n </div>\n ",
animations: [
trigger('autoHeight', [
state('nulled', style({ height: 0 })),
state('full', style({ height: '*' })),
transition('full => nulled', [
// style({height: '*'}),
animate('700ms 350ms')
]),
transition('nulled => full', [
// style({height: 0}),
animate(350)
]),
])
]
}),
tslib_1.__metadata("design:paramtypes", [NgZone,
ElementRef,
Renderer2,
CarouselService,
AnimateService])
], StageComponent);
return StageComponent;
}());
export { StageComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhZ2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW93bC1jYXJvdXNlbC1vLyIsInNvdXJjZXMiOlsibGliL2Nhcm91c2VsL3N0YWdlL3N0YWdlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQXFCLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsZUFBZSxFQUFVLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUxRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUNMLE9BQU8sRUFDUCxLQUFLLEVBQ0wsS0FBSyxFQUNMLE9BQU8sRUFDUCxVQUFVLEVBQ1gsTUFBTSxxQkFBcUIsQ0FBQztBQXdDN0I7SUE4RUUsd0JBQW9CLElBQVksRUFDWixFQUFjLEVBQ2QsUUFBbUIsRUFDbkIsZUFBZ0MsRUFDaEMsY0FBOEI7UUFKbEQsaUJBSXVEO1FBSm5DLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBOUJsRDs7V0FFRztRQUNLLFVBQUssR0FBUTtZQUNuQixJQUFJLEVBQUUsSUFBSTtZQUNWLE1BQU0sRUFBRSxJQUFJO1lBQ1osT0FBTyxFQUFFLElBQUk7WUFDYixLQUFLLEVBQUU7Z0JBQ0wsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsT0FBTyxFQUFFLElBQUk7YUFDZDtZQUNELFNBQVMsRUFBRSxJQUFJO1lBQ2YsTUFBTSxFQUFFLEtBQUs7WUFDYixNQUFNLEVBQUUsS0FBSztTQUNkLENBQUM7UUFFRjs7V0FFRztRQUNLLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQU8sQ0FBQztRQXFEM0M7O1dBRUc7UUFDSCwwQkFBcUIsR0FBRyxVQUFDLEVBQUU7WUFDekIsS0FBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQTtRQUVEOztXQUVHO1FBQ0gsbUJBQWMsR0FBRyxVQUFDLEVBQUU7WUFDbEIsS0FBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2QixDQUFDLENBQUE7UUFFRDs7V0FFRztRQUNILGtCQUFhLEdBQUcsVUFBQyxFQUFFO1lBQ2pCLHdCQUF3QjtZQUN0QixLQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RCLE1BQU07UUFDUixDQUFDLENBQUE7UUEySkQ7O1dBRUc7UUFDSyxxQkFBZ0IsR0FBRztZQUN6QixLQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLGNBQU0sT0FBQSxLQUFLLEVBQUwsQ0FBSyxDQUFDLENBQUE7WUFDckYsS0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFBO0lBaE9xRCxDQUFDO0lBRWhCLG9DQUFXLEdBQVgsVUFBWSxLQUFLO1FBQ3RELElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUU7WUFDckMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUMxQjtJQUNILENBQUM7SUFFdUMscUNBQVksR0FBWixVQUFhLEtBQUs7UUFDeEQsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRTtZQUNyQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzFCO0lBQ0gsQ0FBQztJQUV3QyxzQ0FBYSxHQUFiLFVBQWMsS0FBSztRQUMxRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFMEIsb0NBQVcsR0FBWDtRQUN6QixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxFQUFFO1lBQ3JDLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7SUFDSCxDQUFDO0lBRTRCLHNDQUFhLEdBQWI7UUFDM0IsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRTtZQUNyQyxPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQztJQUVELGlDQUFRLEdBQVI7UUFBQSxpQkFNQztRQUxDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsYUFBYTthQUMxQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7YUFDYixTQUFTLENBQUM7WUFDVCxLQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsb0NBQVcsR0FBWDtRQUNFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBeUJEOzs7OztTQUtFO0lBQ0sscUNBQVksR0FBcEIsVUFBcUIsS0FBSztRQUExQixpQkF1QkU7UUF0QkQsSUFBSSxLQUFLLEdBQVcsSUFBSSxDQUFDO1FBRXpCLElBQUksS0FBSyxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUU7WUFDdEIsT0FBTztTQUNMO1FBRUQsS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDakMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQy9CLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFMUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNyRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFdkYsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztZQUMxQixLQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNwRyxLQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN0RyxDQUFDLENBQUMsQ0FBQztJQUVMLENBQUM7SUFFRDs7O09BR0c7SUFDSywyQ0FBa0IsR0FBMUIsVUFBMkIsS0FBSztRQUM5QixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN6RSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3JCO1FBQ0QsSUFBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDeEUsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDekYsT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBRXpCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRTFGLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV2QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsdUJBQXVCO0lBQ3pCLENBQUM7SUFFRDs7O09BR0c7SUFDSyxtREFBMEIsR0FBbEMsVUFBbUMsS0FBVTtRQUMzQyxJQUFJLE1BQU0sR0FBdUIsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUM5QyxPQUFPLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFZLGlCQUFpQixDQUFDLEVBQUU7WUFDdkQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7U0FDL0I7UUFDRCxJQUFJLE1BQU0sWUFBWSxpQkFBaUIsRUFBRTtZQUN2QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBTSxPQUFBLEtBQUssRUFBTCxDQUFLLENBQUMsQ0FBQztTQUN4RTtJQUNILENBQUM7SUFFQTs7OztPQUlDO0lBQ0ssb0NBQVcsR0FBbkIsVUFBb0IsS0FBSztRQUN0QixJQUFJLEtBQWEsQ0FBQztRQUNsQixJQUFNLFdBQVcsR0FBcUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWxHLElBQUksV0FBVyxLQUFLLEtBQUssRUFBRTtZQUN6QixPQUFPO1NBQ1I7UUFDRCxLQUFLLEdBQUcsV0FBcUIsQ0FBQztRQUVoQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNuQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFBQSxDQUFDO0lBRUY7OztPQUdHO0lBQ0ssaUNBQVEsR0FBaEIsVUFBaUIsVUFBa0I7UUFDakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxpQkFBZSxVQUFVLGVBQVksQ0FBQyxDQUFDO1FBQzlHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVEOzs7OztTQUtFO0lBQ0ssbUNBQVUsR0FBbEIsVUFBbUIsS0FBSztRQUNyQixJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQy9DLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBRTVCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUU7WUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMzRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFDLElBQUksR0FBRSxHQUFHLENBQUMsQ0FBQztZQUV2TSxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1NBQzFCO1FBRUQsSUFBSSxDQUFDLEtBQUssR0FBRztZQUNYLElBQUksRUFBRSxJQUFJO1lBQ1YsTUFBTSxFQUFFLElBQUk7WUFDWixPQUFPLEVBQUUsSUFBSTtZQUNiLEtBQUssRUFBRTtnQkFDTCxLQUFLLEVBQUUsSUFBSTtnQkFDWCxPQUFPLEVBQUUsSUFBSTthQUNkO1lBQ0QsU0FBUyxFQUFFLElBQUk7WUFDZixNQUFNLEVBQUUsS0FBSztZQUNiLE1BQU0sRUFBRSxLQUFLO1NBQ2QsQ0FBQztRQUVGLDJDQUEyQztRQUMzQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUFBLENBQUM7SUFFRjs7OztTQUlFO0lBQ00seUNBQWdCLEdBQXhCLFVBQXlCLEtBQVU7UUFDakMsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBVUQ7OztPQUdHO0lBQ0ssd0NBQWUsR0FBdkIsVUFBd0IsS0FBVTtRQUNoQyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNoRixDQUFDO0lBRUQ7Ozs7U0FJRTtJQUNNLGlDQUFRLEdBQWhCLFVBQWlCLEtBQVU7UUFDekIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7Ozs7O1NBS0U7SUFDTSxvQ0FBVyxHQUFuQixVQUFvQixNQUFjLEVBQUUsTUFBYztRQUNoRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7Ozs7U0FJRTtJQUNNLDRCQUFHLEdBQVgsVUFBWSxhQUFxQjtRQUMvQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7O01BR0U7SUFDTSwrQkFBTSxHQUFkLFVBQWUsSUFBWTtRQUN6QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O1NBRUU7SUFDTSxxQ0FBWSxHQUFwQjtRQUNFLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsd0NBQWUsR0FBZjtRQUNFLElBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVEOztTQUVFO0lBQ00sdUNBQWMsR0FBdEI7UUFDRSxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7O09BR0c7SUFDSCw4QkFBSyxHQUFMLFVBQU0sRUFBRTtRQUNOLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUF2WFE7UUFBUixLQUFLLEVBQUU7O3dEQUdOO0lBS087UUFBUixLQUFLLEVBQUU7MENBQVksU0FBUztxREFBQztJQUtyQjtRQUFSLEtBQUssRUFBRTs7c0RBQTBCO0lBbUVLO1FBQXRDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7OztxREFJckM7SUFFdUM7UUFBdkMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDOzs7O3NEQUl0QztJQUV3QztRQUF4QyxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7Ozs7dURBRXZDO0lBRTBCO1FBQTFCLFlBQVksQ0FBQyxXQUFXLENBQUM7Ozs7cURBSXpCO0lBRTRCO1FBQTVCLFlBQVksQ0FBQyxhQUFhLENBQUM7Ozs7dURBSTNCO0lBOUdVLGNBQWM7UUF2QzFCLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxXQUFXO1lBQ3JCLFFBQVEsRUFBRSx1MENBcUJUO1lBQ0QsVUFBVSxFQUFFO2dCQUNWLE9BQU8sQ0FBQyxZQUFZLEVBQUU7b0JBQ3BCLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUMsTUFBTSxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7b0JBQ25DLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7b0JBQ25DLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTt3QkFDM0Isd0JBQXdCO3dCQUN4QixPQUFPLENBQUMsYUFBYSxDQUFDO3FCQUN2QixDQUFDO29CQUNGLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTt3QkFDM0Isc0JBQXNCO3dCQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDO3FCQUNiLENBQUM7aUJBQ0gsQ0FBQzthQUNIO1NBQ0YsQ0FBQztpREErRTBCLE1BQU07WUFDUixVQUFVO1lBQ0osU0FBUztZQUNGLGVBQWU7WUFDaEIsY0FBYztPQWxGdkMsY0FBYyxDQTRYMUI7SUFBRCxxQkFBQztDQUFBLEFBNVhELElBNFhDO1NBNVhZLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE5nWm9uZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBSZW5kZXJlcjIsIE9uSW5pdCwgT25EZXN0cm95LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDYXJvdXNlbFNlcnZpY2UsIENvb3JkcyB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2Nhcm91c2VsLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlyc3QgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IFN0YWdlRGF0YSB9IGZyb20gJy4uLy4uL21vZGVscy9zdGFnZS1kYXRhLm1vZGVsJztcclxuaW1wb3J0IHsgU2xpZGVNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9zbGlkZS5tb2RlbCc7XHJcbmltcG9ydCB7IEFuaW1hdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYW5pbWF0ZS5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICB0cmlnZ2VyLFxyXG4gIHN0YXRlLFxyXG4gIHN0eWxlLFxyXG4gIGFuaW1hdGUsXHJcbiAgdHJhbnNpdGlvblxyXG59IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ293bC1zdGFnZScsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxkaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJvd2wtc3RhZ2VcIiBbbmdTdHlsZV09XCJ7J3dpZHRoJzogc3RhZ2VEYXRhLndpZHRoICsgJ3B4JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0nOiBzdGFnZURhdGEudHJhbnNmb3JtLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RyYW5zaXRpb24nOiBzdGFnZURhdGEudHJhbnNpdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nLWxlZnQnOiBzdGFnZURhdGEucGFkZGluZ0wgPyBzdGFnZURhdGEucGFkZGluZ0wgKyAncHgnIDogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFkZGluZy1yaWdodCc6IHN0YWdlRGF0YS5wYWRkaW5nUiA/IHN0YWdlRGF0YS5wYWRkaW5nUiArICdweCcgOiAnJyB9XCJcclxuICAgICAgICAgICh0cmFuc2l0aW9uZW5kKT1cIm9uVHJhbnNpdGlvbkVuZCgpXCI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc2xpZGUgb2Ygc2xpZGVzRGF0YTsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm93bC1pdGVtXCIgW25nQ2xhc3NdPVwic2xpZGUuY2xhc3Nlc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyd3aWR0aCc6IHNsaWRlLndpZHRoICsgJ3B4JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWFyZ2luLWxlZnQnOiBzbGlkZS5tYXJnaW5MID8gc2xpZGUubWFyZ2luTCArICdweCcgOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWFyZ2luLXJpZ2h0Jzogc2xpZGUubWFyZ2luUiA/IHNsaWRlLm1hcmdpblIgKyAncHgnIDogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2xlZnQnOiBzbGlkZS5sZWZ0fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFuaW1hdGlvbmVuZCk9XCJjbGVhcihzbGlkZS5pZClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtAYXV0b0hlaWdodF09XCJzbGlkZS5oZWlnaHRTdGF0ZVwiPlxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nSWY9XCJzbGlkZS5sb2FkXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwic2xpZGUudHBsUmVmXCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgIDwvZGl2PjwhLS0gLy5vd2wtaXRlbSAtLT5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9kaXY+PCEtLSAvLm93bC1zdGFnZSAtLT5cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgdHJpZ2dlcignYXV0b0hlaWdodCcsIFtcclxuICAgICAgc3RhdGUoJ251bGxlZCcsIHN0eWxlKHtoZWlnaHQ6IDB9KSksXHJcbiAgICAgIHN0YXRlKCdmdWxsJywgc3R5bGUoe2hlaWdodDogJyonfSkpLFxyXG4gICAgICB0cmFuc2l0aW9uKCdmdWxsID0+IG51bGxlZCcsIFtcclxuICAgICAgICAvLyBzdHlsZSh7aGVpZ2h0OiAnKid9KSxcclxuICAgICAgICBhbmltYXRlKCc3MDBtcyAzNTBtcycpXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCdudWxsZWQgPT4gZnVsbCcsIFtcclxuICAgICAgICAvLyBzdHlsZSh7aGVpZ2h0OiAwfSksXHJcbiAgICAgICAgYW5pbWF0ZSgzNTApXHJcbiAgICAgIF0pLFxyXG4gICAgXSlcclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTdGFnZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAvKipcclxuICAgKiBPYmplY3Qgd2l0aCBzZXR0aW5ncyB3aGljaCBtYWtlIGNhcm91c2VsIGRyYWdnYWJsZSBieSB0b3VjaCBvciBtb3VzZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIG93bERyYWdnYWJsZToge1xyXG4gICAgaXNNb3VzZURyYWdhYmxlOiBib29sZWFuLFxyXG4gICAgaXNUb3VjaERyYWdhYmxlOiBib29sZWFuXHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGF0YSBvZiBvd2wtc3RhZ2VcclxuICAgKi9cclxuICBASW5wdXQoKSBzdGFnZURhdGE6IFN0YWdlRGF0YTtcclxuXHJcblx0LyoqXHJcblx0ICogIERhdGEgb2YgZXZlcnkgc2xpZGVcclxuXHQgKi9cclxuICBASW5wdXQoKSBzbGlkZXNEYXRhOiBTbGlkZU1vZGVsW107XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHdpY2ggd2lsbCBiZSByZXR1cm5lZCBhZnRlciBhdHRhY2hpbmcgbGlzdGVuZXIgdG8gJ21vdXNlbW92ZScgZXZlbnRcclxuICAgKi9cclxuICBsaXN0ZW5lck1vdXNlTW92ZTogKCkgPT4gdm9pZDtcclxuICAvKipcclxuICAgKiBGdW5jdGlvbiB3aWNoIHdpbGwgYmUgcmV0dXJuZWQgYWZ0ZXIgYXR0YWNoaW5nIGxpc3RlbmVyIHRvICd0b3VjaG1vdmUnIGV2ZW50XHJcbiAgICovXHJcbiAgbGlzdGVuZXJUb3VjaE1vdmU6ICgpID0+IHZvaWQ7XHJcbiAgLyoqXHJcbiAgICogRnVuY3Rpb24gd2ljaCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGF0dGFjaGluZyBsaXN0ZW5lciB0byAnbW91c2Vtb3ZlJyBldmVudFxyXG4gICAqL1xyXG4gIGxpc3RlbmVyT25lTW91c2VNb3ZlOiAoKSA9PiB2b2lkO1xyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHdpY2ggd2lsbCBiZSByZXR1cm5lZCBhZnRlciBhdHRhY2hpbmcgbGlzdGVuZXIgdG8gJ3RvdWNobW92ZScgZXZlbnRcclxuICAgKi9cclxuICBsaXN0ZW5lck9uZVRvdWNoTW92ZTogKCkgPT4gdm9pZDtcclxuXHJcbiAgLyoqXHJcbiAgICogRnVuY3Rpb24gd2ljaCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGF0dGFjaGluZyBsaXN0ZW5lciB0byAnbW91c2V1cCcgZXZlbnRcclxuICAgKi9cclxuICBsaXN0ZW5lck1vdXNlVXA6ICgpID0+IHZvaWQ7XHJcbiAgLyoqXHJcbiAgICogRnVuY3Rpb24gd2ljaCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGF0dGFjaGluZyBsaXN0ZW5lciB0byAndG91Y2hlbmQnIGV2ZW50XHJcbiAgICovXHJcbiAgbGlzdGVuZXJUb3VjaEVuZDogKCkgPT4gdm9pZDtcclxuXHJcbiAgLyoqXHJcbiAgICogRnVuY3Rpb24gd2ljaCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGF0dGFjaGluZyBsaXN0ZW5lciB0byAnY2xpY2snIGV2ZW50XHJcbiAgICovXHJcbiAgbGlzdGVuZXJPbmVDbGljazogKCkgPT4gdm9pZDtcclxuXHJcbiAgbGlzdGVuZXJBVGFnOiAoKSA9PiB2b2lkO1xyXG5cclxuICAvKipcclxuICAgKiBPYmplY3Qgd2l0aCBkYXRhIG5lZWRlZCBmb3IgZHJhZ2dpbmdcclxuICAgKi9cclxuICBwcml2YXRlIF9kcmFnOiBhbnkgPSB7XHJcbiAgICB0aW1lOiBudWxsLFxyXG4gICAgdGFyZ2V0OiBudWxsLFxyXG4gICAgcG9pbnRlcjogbnVsbCxcclxuICAgIHN0YWdlOiB7XHJcbiAgICAgIHN0YXJ0OiBudWxsLFxyXG4gICAgICBjdXJyZW50OiBudWxsXHJcbiAgICB9LFxyXG4gICAgZGlyZWN0aW9uOiBudWxsLFxyXG4gICAgYWN0aXZlOiBmYWxzZSxcclxuICAgIG1vdmluZzogZmFsc2VcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTdWJqZWN0IGZvciBub3RpZmljYXRpb24gd2hlbiB0aGUgY2Fyb3VzZWwncyByZWJ1aWxkaW5nIGNhdXNlZCBieSByZXNpemUgZXZlbnQgc3RhcnRzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfb25lRHJhZ01vdmUkID0gbmV3IFN1YmplY3Q8YW55PigpO1xyXG5cclxuICAvKipcclxuICAgKiBTdWJzY3RpcHRpb24gdG8gX29uZURyYWdNb3ZlJCBTdWJqZWN0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfb25lTW92ZVN1YnNyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogTmdab25lLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgY2Fyb3VzZWxTZXJ2aWNlOiBDYXJvdXNlbFNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBhbmltYXRlU2VydmljZTogQW5pbWF0ZVNlcnZpY2UpIHsgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdtb3VzZWRvd24nLCBbJyRldmVudCddKSBvbk1vdXNlRG93bihldmVudCkge1xyXG4gICAgaWYgKHRoaXMub3dsRHJhZ2dhYmxlLmlzTW91c2VEcmFnYWJsZSkge1xyXG4gICAgICB0aGlzLl9vbkRyYWdTdGFydChldmVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgWyckZXZlbnQnXSkgb25Ub3VjaFN0YXJ0KGV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5vd2xEcmFnZ2FibGUuaXNUb3VjaERyYWdhYmxlKSB7XHJcbiAgICAgIHRoaXMuX29uRHJhZ1N0YXJ0KGV2ZW50KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgWyckZXZlbnQnXSkgb25Ub3VjaENhbmNlbChldmVudCkge1xyXG4gICAgdGhpcy5fb25EcmFnRW5kKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RyYWdzdGFydCcpIG9uRHJhZ1N0YXJ0KCkge1xyXG4gICAgaWYgKHRoaXMub3dsRHJhZ2dhYmxlLmlzTW91c2VEcmFnYWJsZSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdzZWxlY3RzdGFydCcpIG9uU2VsZWN0U3RhcnQoKSB7XHJcbiAgICBpZiAodGhpcy5vd2xEcmFnZ2FibGUuaXNNb3VzZURyYWdhYmxlKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5fb25lTW92ZVN1YnNyaXB0aW9uID0gdGhpcy5fb25lRHJhZ01vdmUkXHJcbiAgICAgIC5waXBlKGZpcnN0KCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlbmRDaGFuZ2VzKCk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLl9vbmVNb3ZlU3Vic3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhc3NlcyB0aGlzIHRvIF9vbmVNb3VzZVRvdWNoTW92ZSgpO1xyXG4gICAqL1xyXG4gIGJpbmRPbmVNb3VzZVRvdWNoTW92ZSA9IChldikgPT4ge1xyXG4gICAgdGhpcy5fb25lTW91c2VUb3VjaE1vdmUoZXYpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUGFzc2VzIHRoaXMgdG8gX29uRHJhZ01vdmUoKTtcclxuICAgKi9cclxuICBiaW5kT25EcmFnTW92ZSA9IChldikgPT4ge1xyXG4gICAgdGhpcy5fb25EcmFnTW92ZShldik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXNzZXMgdGhpcyB0byBfb25EcmFnTW92ZSgpO1xyXG4gICAqL1xyXG4gIGJpbmRPbkRyYWdFbmQgPSAoZXYpID0+IHtcclxuICAgIC8vIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICB0aGlzLl9vbkRyYWdFbmQoZXYpO1xyXG4gICAgLy8gfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBIYW5kbGVzIGB0b3VjaHN0YXJ0YCBhbmQgYG1vdXNlZG93bmAgZXZlbnRzLlxyXG5cdCAqIEB0b2RvIEhvcml6b250YWwgc3dpcGUgdGhyZXNob2xkIGFzIG9wdGlvblxyXG5cdCAqIEB0b2RvICMyNjFcclxuXHQgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgYXJndW1lbnRzLlxyXG5cdCAqL1xyXG5cdHByaXZhdGUgX29uRHJhZ1N0YXJ0KGV2ZW50KTogYW55IHtcclxuXHRcdGxldCBzdGFnZTogQ29vcmRzID0gbnVsbDtcclxuXHJcblx0XHRpZiAoZXZlbnQud2hpY2ggPT09IDMpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YWdlID0gdGhpcy5fcHJlcGFyZURyYWdnaW5nKGV2ZW50KTtcclxuXHJcblx0XHR0aGlzLl9kcmFnLnRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuXHRcdHRoaXMuX2RyYWcudGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xyXG5cdFx0dGhpcy5fZHJhZy5zdGFnZS5zdGFydCA9IHN0YWdlO1xyXG5cdFx0dGhpcy5fZHJhZy5zdGFnZS5jdXJyZW50ID0gc3RhZ2U7XHJcbiAgICB0aGlzLl9kcmFnLnBvaW50ZXIgPSB0aGlzLl9wb2ludGVyKGV2ZW50KTtcclxuXHJcbiAgICB0aGlzLmxpc3RlbmVyTW91c2VVcCA9IHRoaXMucmVuZGVyZXIubGlzdGVuKGRvY3VtZW50LCAnbW91c2V1cCcsIHRoaXMuYmluZE9uRHJhZ0VuZCk7XHJcbiAgICB0aGlzLmxpc3RlbmVyVG91Y2hFbmQgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudCwgJ3RvdWNoZW5kJywgdGhpcy5iaW5kT25EcmFnRW5kKTtcclxuXHJcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyT25lTW91c2VNb3ZlID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oZG9jdW1lbnQsICdtb3VzZW1vdmUnLCB0aGlzLmJpbmRPbmVNb3VzZVRvdWNoTW92ZSk7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJPbmVUb3VjaE1vdmUgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudCwgJ3RvdWNobW92ZScsIHRoaXMuYmluZE9uZU1vdXNlVG91Y2hNb3ZlKTtcclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dGFjaGVzIGxpc3RlbmVycyB0byBgdG91Y2htb3ZlYCBhbmQgYG1vdXNlbW92ZWAgZXZlbnRzOyBpbml0aWF0ZXMgdXBkYXRpbmcgY2Fyb3VzZWwgYWZ0ZXIgc3RhcnRpbmcgZHJhZ2dpbmdcclxuICAgKiBAcGFyYW0gZXZlbnQgZXZlbnQgb2JqZWNoIG9mIG1vdXNlIG9yIHRvdWNoIGV2ZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfb25lTW91c2VUb3VjaE1vdmUoZXZlbnQpIHtcclxuICAgIGNvbnN0IGRlbHRhID0gdGhpcy5fZGlmZmVyZW5jZSh0aGlzLl9kcmFnLnBvaW50ZXIsIHRoaXMuX3BvaW50ZXIoZXZlbnQpKTtcclxuICAgIGlmICh0aGlzLmxpc3RlbmVyQVRhZykge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyQVRhZygpO1xyXG4gICAgfVxyXG4gICAgaWYgKCBNYXRoLmFicyhkZWx0YS54KSA8IDMgJiYgTWF0aC5hYnMoZGVsdGEueSkgPCAzICYmIHRoaXMuX2lzKCd2YWxpZCcpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoKE1hdGguYWJzKGRlbHRhLngpIDwgMyAmJiBNYXRoLmFicyhkZWx0YS54KSA8IE1hdGguYWJzKGRlbHRhLnkpKSAmJiB0aGlzLl9pcygndmFsaWQnKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmxpc3RlbmVyT25lTW91c2VNb3ZlKCk7XHJcbiAgICB0aGlzLmxpc3RlbmVyT25lVG91Y2hNb3ZlKCk7XHJcbiAgICB0aGlzLl9kcmFnLm1vdmluZyA9IHRydWU7XHJcblxyXG4gICAgdGhpcy5ibG9ja0NsaWNrQW5jaG9ySW5EcmFnZ2luZyhldmVudCk7XHJcblxyXG4gICAgdGhpcy5saXN0ZW5lck1vdXNlTW92ZSA9IHRoaXMucmVuZGVyZXIubGlzdGVuKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgdGhpcy5iaW5kT25EcmFnTW92ZSk7XHJcbiAgICB0aGlzLmxpc3RlbmVyVG91Y2hNb3ZlID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oZG9jdW1lbnQsICd0b3VjaG1vdmUnLCB0aGlzLmJpbmRPbkRyYWdNb3ZlKTtcclxuXHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgIHRoaXMuX2VudGVyRHJhZ2dpbmcoKTtcclxuICAgIHRoaXMuX29uZURyYWdNb3ZlJC5uZXh0KGV2ZW50KTtcclxuICAgIC8vIHRoaXMuX3NlbmRDaGFuZ2VzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBdHRhY2hlcyBoYW5kbGVyIHRvIEhUTUxBbmNob3JFbGVtZW50IGZvciBwcmV2ZW50aW5nIGNsaWNrIHdoaWxlIGNhcm91c2VsIGlzIGJlaW5nIGRyYWdnZWRcclxuICAgKiBAcGFyYW0gZXZlbnQgZXZlbnQgb2JqZWN0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBibG9ja0NsaWNrQW5jaG9ySW5EcmFnZ2luZyhldmVudDogYW55KSB7XHJcbiAgICBsZXQgdGFyZ2V0OiBIVE1MRWxlbWVudCB8IG51bGwgPSBldmVudC50YXJnZXQ7XHJcbiAgICB3aGlsZSAodGFyZ2V0ICYmICEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQpKSB7XHJcbiAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnRFbGVtZW50O1xyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxBbmNob3JFbGVtZW50KSB7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJBVGFnID0gdGhpcy5yZW5kZXJlci5saXN0ZW4odGFyZ2V0LCAnY2xpY2snLCAoKSA9PiBmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBcdC8qKlxyXG5cdCAqIEhhbmRsZXMgdGhlIGB0b3VjaG1vdmVgIGFuZCBgbW91c2Vtb3ZlYCBldmVudHMuXHJcblx0ICogQHRvZG8gIzI2MVxyXG5cdCAqIEBwYXJhbSBldmVudCAtIFRoZSBldmVudCBhcmd1bWVudHMuXHJcblx0ICovXHJcblx0cHJpdmF0ZSBfb25EcmFnTW92ZShldmVudCkge1xyXG4gICAgbGV0IHN0YWdlOiBDb29yZHM7XHJcbiAgICBjb25zdCBzdGFnZU9yRXhpdDogYm9vbGVhbiB8IENvb3JkcyA9IHRoaXMuY2Fyb3VzZWxTZXJ2aWNlLmRlZmluZU5ld0Nvb3Jkc0RyYWcoZXZlbnQsIHRoaXMuX2RyYWcpO1xyXG5cclxuICAgIGlmIChzdGFnZU9yRXhpdCA9PT0gZmFsc2UpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgc3RhZ2UgPSBzdGFnZU9yRXhpdCBhcyBDb29yZHM7XHJcblxyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICB0aGlzLl9kcmFnLnN0YWdlLmN1cnJlbnQgPSBzdGFnZTtcclxuXHRcdHRoaXMuX2FuaW1hdGUoc3RhZ2UueCAtIHRoaXMuX2RyYWcuc3RhZ2Uuc3RhcnQueCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogTW92ZXMgLm93bC1zdGFnZSBsZWZ0LXJpZ2h0XHJcbiAgICogQHBhcmFtIGNvb3JkaW5hdGUgY29vcmRpbmF0ZSB0byBiZSBzZXQgdG8gLm93bC1zdGFnZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2FuaW1hdGUoY29vcmRpbmF0ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWwubmF0aXZlRWxlbWVudC5jaGlsZHJlblswXSwgJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUzZCgke2Nvb3JkaW5hdGV9cHgsMHB4LDBweGApO1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW5bMF0sICd0cmFuc2l0aW9uJywgJzBzJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBIYW5kbGVzIHRoZSBgdG91Y2hlbmRgIGFuZCBgbW91c2V1cGAgZXZlbnRzLlxyXG5cdCAqIEB0b2RvICMyNjFcclxuXHQgKiBAdG9kbyBUaHJlc2hvbGQgZm9yIGNsaWNrIGV2ZW50XHJcblx0ICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IGFyZ3VtZW50cy5cclxuXHQgKi9cclxuXHRwcml2YXRlIF9vbkRyYWdFbmQoZXZlbnQpIHtcclxuICAgIHRoaXMuY2Fyb3VzZWxTZXJ2aWNlLm93bERPTURhdGEuaXNHcmFiID0gZmFsc2U7XHJcbiAgICB0aGlzLmxpc3RlbmVyT25lTW91c2VNb3ZlKCk7XHJcbiAgICB0aGlzLmxpc3RlbmVyT25lVG91Y2hNb3ZlKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuX2RyYWcubW92aW5nKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LmNoaWxkcmVuWzBdLCAndHJhbnNmb3JtJywgYGApO1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWwubmF0aXZlRWxlbWVudC5jaGlsZHJlblswXSwgJ3RyYW5zaXRpb24nLCB0aGlzLmNhcm91c2VsU2VydmljZS5zcGVlZCgrdGhpcy5jYXJvdXNlbFNlcnZpY2Uuc2V0dGluZ3MuZHJhZ0VuZFNwZWVkIHx8IHRoaXMuY2Fyb3VzZWxTZXJ2aWNlLnNldHRpbmdzLnNtYXJ0U3BlZWQpLzEwMDAgKydzJyk7XHJcblxyXG4gICAgICB0aGlzLl9maW5pc2hEcmFnZ2luZyhldmVudCk7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJNb3VzZU1vdmUoKTtcclxuICAgICAgdGhpcy5saXN0ZW5lclRvdWNoTW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2RyYWcgPSB7XHJcbiAgICAgIHRpbWU6IG51bGwsXHJcbiAgICAgIHRhcmdldDogbnVsbCxcclxuICAgICAgcG9pbnRlcjogbnVsbCxcclxuICAgICAgc3RhZ2U6IHtcclxuICAgICAgICBzdGFydDogbnVsbCxcclxuICAgICAgICBjdXJyZW50OiBudWxsXHJcbiAgICAgIH0sXHJcbiAgICAgIGRpcmVjdGlvbjogbnVsbCxcclxuICAgICAgYWN0aXZlOiBmYWxzZSxcclxuICAgICAgbW92aW5nOiBmYWxzZVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0aGlzLmNhcm91c2VsU2VydmljZS50cmlnZ2VyKCdkcmFnZ2VkJyk7XHJcbiAgICB0aGlzLmxpc3RlbmVyTW91c2VVcCgpO1xyXG4gICAgdGhpcy5saXN0ZW5lclRvdWNoRW5kKCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcblx0ICogUHJlcGFyZXMgZGF0YSBmb3IgZHJhZ2dpbmcgY2Fyb3VzZWwuIEl0IHN0YXJ0cyBhZnRlciBmaXJpbmcgYHRvdWNoc3RhcnRgIGFuZCBgbW91c2Vkb3duYCBldmVudHMuXHJcblx0ICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IGFyZ3VtZW50cy5cclxuXHQgKiBAcmV0dXJucyBzdGFnZSAtIG9iamVjdCB3aXRoICd4JyBhbmQgJ3knIGNvb3JkaW5hdGVzIG9mIC5vd2wtc3RhZ2VcclxuXHQgKi9cclxuICBwcml2YXRlIF9wcmVwYXJlRHJhZ2dpbmcoZXZlbnQ6IGFueSk6IENvb3JkcyB7XHJcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFNlcnZpY2UucHJlcGFyZURyYWdnaW5nKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dGFjaGVzIGhhbmRsZXIgZm9yICdjbGljaycgZXZlbnQgb24gYW55IGVsZW1lbnQgaW4gLm93bC1zdGFnZSBpbiBvcmRlciB0byBwcmV2ZW50IGRyYWdnaW5nIHdoZW4gbW92aW5nIG9mIGN1cnNvciBpcyBsZXNzIHRoYW4gM3B4XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfb25lQ2xpY2tIYW5kbGVyID0gKCkgPT4ge1xyXG4gICAgdGhpcy5saXN0ZW5lck9uZUNsaWNrID0gdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5fZHJhZy50YXJnZXQsICdjbGljaycsICgpID0+IGZhbHNlKVxyXG4gICAgdGhpcy5saXN0ZW5lck9uZUNsaWNrKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGaW5pc2hlcyBkcmFnZ2luZ1xyXG4gICAqIEBwYXJhbSBldmVudCBvYmplY3QgZXZlbnQgb2YgJ21vdXNlVXAnIG9mICd0b3VjaGVuZCcgZXZlbnRzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfZmluaXNoRHJhZ2dpbmcoZXZlbnQ6IGFueSkge1xyXG4gICAgdGhpcy5jYXJvdXNlbFNlcnZpY2UuZmluaXNoRHJhZ2dpbmcoZXZlbnQsIHRoaXMuX2RyYWcsIHRoaXMuX29uZUNsaWNrSGFuZGxlcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBHZXRzIHVuaWZpZWQgcG9pbnRlciBjb29yZGluYXRlcyBmcm9tIGV2ZW50LlxyXG5cdCAqIEBwYXJhbSBldmVudCBUaGUgYG1vdXNlZG93bmAgb3IgYHRvdWNoc3RhcnRgIGV2ZW50LlxyXG5cdCAqIEByZXR1cm5zIENvbnRhaW5zIGB4YCBhbmQgYHlgIGNvb3JkaW5hdGVzIG9mIGN1cnJlbnQgcG9pbnRlciBwb3NpdGlvbi5cclxuXHQgKi9cclxuICBwcml2YXRlIF9wb2ludGVyKGV2ZW50OiBhbnkpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2Fyb3VzZWxTZXJ2aWNlLnBvaW50ZXIoZXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcblx0ICogR2V0cyB0aGUgZGlmZmVyZW5jZSBvZiB0d28gdmVjdG9ycy5cclxuXHQgKiBAcGFyYW0gZmlyc3QgVGhlIGZpcnN0IHZlY3Rvci5cclxuXHQgKiBAcGFyYW0gc2Vjb25kLSBUaGUgc2Vjb25kIHZlY3Rvci5cclxuXHQgKiBAcmV0dXJucyBUaGUgZGlmZmVyZW5jZS5cclxuXHQgKi9cclxuICBwcml2YXRlIF9kaWZmZXJlbmNlKGZpcnN0QzogQ29vcmRzLCBzZWNvbmQ6IENvb3Jkcyk6IGFueSB7XHJcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFNlcnZpY2UuZGlmZmVyZW5jZShmaXJzdEMsIHNlY29uZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBDaGVja3Mgd2hldGhlciB0aGUgY2Fyb3VzZWwgaXMgaW4gYSBzcGVjaWZpYyBzdGF0ZSBvciBub3QuXHJcblx0ICogQHBhcmFtIHNwZWNpZmljU3RhdGUgVGhlIHN0YXRlIHRvIGNoZWNrLlxyXG5cdCAqIEByZXR1cm5zIFRoZSBmbGFnIHdoaWNoIGluZGljYXRlcyBpZiB0aGUgY2Fyb3VzZWwgaXMgYnVzeS5cclxuXHQgKi9cclxuICBwcml2YXRlIF9pcyhzcGVjaWZpY1N0YXRlOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmNhcm91c2VsU2VydmljZS5pcyhzcGVjaWZpY1N0YXRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogRW50ZXJzIGEgc3RhdGUuXHJcbiAgKiBAcGFyYW0gbmFtZSBUaGUgc3RhdGUgbmFtZS5cclxuICAqL1xyXG4gIHByaXZhdGUgX2VudGVyKG5hbWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5jYXJvdXNlbFNlcnZpY2UuZW50ZXIobmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBTZW5kcyBhbGwgZGF0YSBuZWVkZWQgZm9yIFZpZXcuXHJcblx0ICovXHJcbiAgcHJpdmF0ZSBfc2VuZENoYW5nZXMoKSB7XHJcbiAgICB0aGlzLmNhcm91c2VsU2VydmljZS5zZW5kQ2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlciBmb3IgdHJhbnNpdGlvZW5kIGV2ZW50XHJcbiAgICovXHJcbiAgb25UcmFuc2l0aW9uRW5kKCkge1xyXG4gICAgdGhpcy5jYXJvdXNlbFNlcnZpY2Uub25UcmFuc2l0aW9uRW5kKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuXHQgKiBFbnRlcnMgaW50byBhICdkcmFnZ2luZycgc3RhdGVcclxuXHQgKi9cclxuICBwcml2YXRlIF9lbnRlckRyYWdnaW5nKCkge1xyXG4gICAgdGhpcy5jYXJvdXNlbFNlcnZpY2UuZW50ZXJEcmFnZ2luZygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyB0aGUgZW5kIG9mICdhbmltYXRpb25lbmQnIGV2ZW50XHJcbiAgICogQHBhcmFtIGlkIElkIG9mIHNsaWRlc1xyXG4gICAqL1xyXG4gIGNsZWFyKGlkKSB7XHJcbiAgICB0aGlzLmFuaW1hdGVTZXJ2aWNlLmNsZWFyKGlkKTtcclxuICB9XHJcbn1cclxuIl19