ngx-pinch-zoom
Version:
Pinch zoom component for Angular2.
494 lines • 53.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('ngx-pinch-zoom', ['exports', '@angular/core', '@angular/common'], factory) :
(factory((global['ngx-pinch-zoom'] = {}),global.ng.core,global.ng.common));
}(this, (function (exports,core,common) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var PinchZoomComponent = (function () {
function PinchZoomComponent(elementRef) {
this.elementRef = elementRef;
this.i = 0;
this.scale = 1;
this.initialScale = 1;
this.moveX = 0;
this.moveY = 0;
this.initialMoveX = 0;
this.initialMoveY = 0;
this.draggingMode = false;
this.lastTap = 0;
this.transitionDuration = 200;
this.autoZoomOut = false;
this.events = new core.EventEmitter();
}
Object.defineProperty(PinchZoomComponent.prototype, "id", {
get: /**
* @return {?}
*/ function () {
return this._id;
},
set: /**
* @param {?} value
* @return {?}
*/ function (value) {
this._id = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isMobile", {
get: /**
* @return {?}
*/ function () {
var /** @type {?} */ check = false;
(function (a) {
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)))
check = true;
})(navigator.userAgent || navigator.vendor);
return check;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PinchZoomComponent.prototype, "isDragging", {
get: /**
* @return {?}
*/ function () {
var /** @type {?} */ imgHeight = this.getImageHeight();
var /** @type {?} */ imgWidth = this.getImageWidth();
if (this.scale > 1) {
return imgHeight * this.scale > this.parentElement.offsetHeight || imgWidth * this.scale > this.parentElement.offsetWidth;
}
if (this.scale === 1) {
return imgHeight > this.parentElement.offsetHeight || imgWidth > this.parentElement.offsetWidth;
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
PinchZoomComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.element = this.contentElement.nativeElement;
this.parentElement = this.elementRef.nativeElement;
this.setBasicStyles();
};
/*
* Mobile listeners
*/
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.onResize = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.setImageWidth();
this.transformElement(this.transitionDuration);
};
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.touchstartHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.getElementPosition();
if (!this.eventType) {
this.startX = event.touches[0].clientX - this.elementPosition.left;
this.startY = event.touches[0].clientY - this.elementPosition.top;
this.startClientX = event.touches[0].clientX - this.elementPosition.left;
this.startClientY = event.touches[0].clientY - this.elementPosition.top;
}
this.events.emit({ type: 'touchstart' });
};
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.touchmoveHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
var /** @type {?} */ touches = event.touches;
// Swipe
if (this.detectSwipe(touches) || this.eventType == 'swipe') {
this.handleSwipe(event);
}
// Pinch
if (touches.length === 2 && !this.eventType || this.eventType == 'pinch') {
this.handlePinch(event);
}
};
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.touchendHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.i = 0;
this.draggingMode = false;
var /** @type {?} */ touches = event.touches;
if (this.scale < 1) {
this.scale = 1;
}
// Auto Zoom Out
if (this.autoZoomOut && this.eventType === 'pinch') {
this.scale = 1;
}
this.events.emit({ type: 'touchend' });
if (this.eventType === 'pinch' || this.eventType === 'swipe') {
this.alignImage();
}
if (this.eventType === 'pinch' ||
this.eventType === 'swipe' ||
this.eventType === 'horizontal-swipe' ||
this.eventType === 'vertical-swipe') {
this.updateInitialValues();
}
this.eventType = 'touchend';
if (touches && touches.length == 0) {
this.eventType = '';
}
};
/*
* Handlers
*/
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.handleSwipe = /**
* @param {?} event
* @return {?}
*/
function (event) {
event.preventDefault();
if (!this.eventType) {
this.startX = event.touches[0].clientX - this.elementPosition.left;
this.startY = event.touches[0].clientY - this.elementPosition.top;
}
this.eventType = 'swipe';
this.events.emit({
type: 'swipe',
moveX: this.moveX,
moveY: this.moveY
});
this.moveX = this.initialMoveX + ((event.touches[0].clientX - this.elementPosition.left) - this.startX);
this.moveY = this.initialMoveY + ((event.touches[0].clientY - this.elementPosition.top) - this.startY);
this.transformElement(0);
};
/**
* @param {?} event
* @return {?}
*/
PinchZoomComponent.prototype.handlePinch = /**
* @param {?} event
* @return {?}
*/
function (event) {
event.preventDefault();
var /** @type {?} */ touches = event.touches;
if (!this.eventType) {
this.initialDistance = this.getDistance(touches);
this.moveXC = (((event.touches[0].clientX - this.elementPosition.left) + (event.touches[1].clientX - this.elementPosition.left)) / 2) - this.initialMoveX;
this.moveYC = (((event.touches[0].clientY - this.elementPosition.top) + (event.touches[1].clientY - this.elementPosition.top)) / 2) - this.initialMoveY;
}
this.eventType = 'pinch';
this.events.emit({ type: 'pinch' });
this.distance = this.getDistance(touches);
this.scale = this.initialScale * (this.distance / this.initialDistance);
this.moveX = this.initialMoveX - (((this.distance / this.initialDistance) * this.moveXC) - this.moveXC);
this.moveY = this.initialMoveY - (((this.distance / this.initialDistance) * this.moveYC) - this.moveYC);
this.transformElement(0);
};
/**
* @param {?} touches
* @return {?}
*/
PinchZoomComponent.prototype.detectSwipe = /**
* @param {?} touches
* @return {?}
*/
function (touches) {
return touches.length === 1 && this.scale > 1 && !this.eventType;
};
/**
* @param {?} touches
* @return {?}
*/
PinchZoomComponent.prototype.getDistance = /**
* @param {?} touches
* @return {?}
*/
function (touches) {
return Math.sqrt(Math.pow(touches[0].pageX - touches[1].pageX, 2) + Math.pow(touches[0].pageY - touches[1].pageY, 2));
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.getImageHeight = /**
* @return {?}
*/
function () {
return this.element.getElementsByTagName("img")[0].offsetHeight;
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.getImageWidth = /**
* @return {?}
*/
function () {
return this.element.getElementsByTagName("img")[0].offsetWidth;
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.setBasicStyles = /**
* @return {?}
*/
function () {
this.element.style.display = "flex";
this.element.style.height = "100%";
this.element.style.alignItems = "center";
this.element.style.justifyContent = "center";
this.element.style.transformOrigin = '0 0';
this.hostDisplay = "block";
this.hostOverflow = "hidden";
this.hostHeight = this.containerHeight;
this.setImageWidth();
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.setImageWidth = /**
* @return {?}
*/
function () {
var /** @type {?} */ imgElement = this.element.getElementsByTagName("img");
if (imgElement.length) {
imgElement[0].style.maxWidth = '100%';
imgElement[0].style.maxHeight = '100%';
}
};
/**
* @param {?=} duration
* @return {?}
*/
PinchZoomComponent.prototype.transformElement = /**
* @param {?=} duration
* @return {?}
*/
function (duration) {
if (duration === void 0) {
duration = 50;
}
this.element.style.transition = 'all ' + duration + 'ms';
this.element.style.transform = 'matrix(' + Number(this.scale) + ',' + 0 + ',' + 0 + ',' + Number(this.scale) + ',' + Number(this.moveX) + ',' + Number(this.moveY) + ')';
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.resetScale = /**
* @return {?}
*/
function () {
this.scale = 1;
this.moveX = 0;
this.moveY = 0;
this.updateInitialValues();
this.transformElement(this.transitionDuration);
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.updateInitialValues = /**
* @return {?}
*/
function () {
this.initialScale = this.scale;
this.initialMoveX = this.moveX;
this.initialMoveY = this.moveY;
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.centeringImage = /**
* @return {?}
*/
function () {
var /** @type {?} */ img = this.element.getElementsByTagName("img")[0];
var /** @type {?} */ initialMoveX = this.moveX;
var /** @type {?} */ initialMoveY = this.moveY;
if (this.moveY > 0) {
this.moveY = 0;
}
if (this.moveX > 0) {
this.moveX = 0;
}
if (img) {
this.transitionYRestriction();
this.transitionXRestriction();
}
if (img && this.scale < 1) {
if (this.moveX < this.element.offsetWidth * (1 - this.scale)) {
this.moveX = this.element.offsetWidth * (1 - this.scale);
}
}
return initialMoveX != this.moveX || initialMoveY != this.moveY;
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.alignImage = /**
* @return {?}
*/
function () {
var /** @type {?} */ isMoveChanged = this.centeringImage();
if (isMoveChanged) {
this.updateInitialValues();
this.transformElement(this.transitionDuration);
}
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.transitionYRestriction = /**
* @return {?}
*/
function () {
var /** @type {?} */ imgHeight = this.getImageHeight();
if (imgHeight * this.scale < this.parentElement.offsetHeight) {
this.moveY = (this.parentElement.offsetHeight - this.element.offsetHeight * this.scale) / 2;
}
else {
var /** @type {?} */ imgOffsetTop = ((imgHeight - this.element.offsetHeight) * this.scale) / 2;
if (this.moveY > imgOffsetTop) {
this.moveY = imgOffsetTop;
}
else if ((imgHeight * this.scale + Math.abs(imgOffsetTop) - this.parentElement.offsetHeight) + this.moveY < 0) {
this.moveY = -(imgHeight * this.scale + Math.abs(imgOffsetTop) - this.parentElement.offsetHeight);
}
}
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.transitionXRestriction = /**
* @return {?}
*/
function () {
var /** @type {?} */ imgWidth = this.getImageWidth();
if (imgWidth * this.scale < this.parentElement.offsetWidth) {
this.moveX = (this.parentElement.offsetWidth - this.element.offsetWidth * this.scale) / 2;
}
else {
var /** @type {?} */ imgOffsetLeft = ((imgWidth - this.element.offsetWidth) * this.scale) / 2;
if (this.moveX > imgOffsetLeft) {
this.moveX = imgOffsetLeft;
}
else if ((imgWidth * this.scale + Math.abs(imgOffsetLeft) - this.parentElement.offsetWidth) + this.moveX < 0) {
this.moveX = -(imgWidth * this.scale + Math.abs(imgOffsetLeft) - this.parentElement.offsetWidth);
}
}
};
/**
* @return {?}
*/
PinchZoomComponent.prototype.getElementPosition = /**
* @return {?}
*/
function () {
this.elementPosition = this.elementRef.nativeElement.getBoundingClientRect();
};
PinchZoomComponent.decorators = [
{ type: core.Component, args: [{
selector: 'pinch-zoom, [pinch-zoom]',
template: "<div #content>\n\t<ng-content></ng-content>\n</div>",
styles: [":host{position:relative}"]
},] },
];
/** @nocollapse */
PinchZoomComponent.ctorParameters = function () {
return [
{ type: core.ElementRef }
];
};
PinchZoomComponent.propDecorators = {
containerHeight: [{ type: core.Input, args: ['height',] }],
transitionDuration: [{ type: core.Input, args: ['transition-duration',] }],
autoZoomOut: [{ type: core.Input, args: ['auto-zoom-out',] }],
id: [{ type: core.Input, args: ['id',] }],
events: [{ type: core.Output }],
hostDisplay: [{ type: core.HostBinding, args: ['style.display',] }],
hostOverflow: [{ type: core.HostBinding, args: ['style.overflow',] }],
hostHeight: [{ type: core.HostBinding, args: ['style.height',] }],
contentElement: [{ type: core.ViewChild, args: ['content',] }],
onResize: [{ type: core.HostListener, args: ['window:resize', ['$event'],] }],
touchstartHandler: [{ type: core.HostListener, args: ['touchstart', ['$event'],] }],
touchmoveHandler: [{ type: core.HostListener, args: ['touchmove', ['$event'],] }],
touchendHandler: [{ type: core.HostListener, args: ['touchend', ['$event'],] }]
};
return PinchZoomComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var PinchZoomModule = (function () {
function PinchZoomModule() {
}
PinchZoomModule.decorators = [
{ type: core.NgModule, args: [{
declarations: [
PinchZoomComponent
],
imports: [
common.CommonModule
],
exports: [
PinchZoomComponent
],
entryComponents: [
PinchZoomComponent
]
},] },
];
return PinchZoomModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
exports.PinchZoomComponent = PinchZoomComponent;
exports.PinchZoomModule = PinchZoomModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBpbmNoLXpvb20udW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9uZ3gtcGluY2gtem9vbS9saWIvcGluY2gtem9vbS5jb21wb25lbnQudHMiLCJuZzovL25neC1waW5jaC16b29tL2xpYi9waW5jaC16b29tLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEhvc3RCaW5kaW5nLCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIE9uSW5pdCwgVmlld0NoaWxkLCBJbnB1dCwgRXZlbnRFbWl0dGVyLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwaW5jaC16b29tLCBbcGluY2gtem9vbV0nLFxuICAgIHRlbXBsYXRlOiBgPGRpdiAjY29udGVudD5cblx0PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9kaXY+YCxcbiAgICBzdHlsZXM6IFtgOmhvc3R7cG9zaXRpb246cmVsYXRpdmV9YF1cbn0pXG5cbmV4cG9ydCBjbGFzcyBQaW5jaFpvb21Db21wb25lbnQge1xuXG4gICAgaTogbnVtYmVyID0gMDtcbiAgICBfaWQ6IGFueTtcbiAgICBlbGVtZW50OiBhbnk7XG4gICAgZWxlbWVudFBvc2l0aW9uOiBhbnk7XG4gICAgcGFyZW50RWxlbWVudDogYW55O1xuICAgIGV2ZW50VHlwZTogYW55O1xuXG4gICAgc2NhbGU6IG51bWJlciA9IDE7XG4gICAgaW5pdGlhbFNjYWxlOiBudW1iZXIgPSAxO1xuXG4gICAgc3RhcnRYOiBudW1iZXI7XG4gICAgc3RhcnRZOiBudW1iZXI7XG4gICAgc3RhcnRDbGllbnRYOiBudW1iZXI7XG4gICAgc3RhcnRDbGllbnRZOiBudW1iZXI7XG5cbiAgICBtb3ZlWDogYW55ID0gMDtcbiAgICBtb3ZlWTogYW55ID0gMDtcbiAgICBpbml0aWFsTW92ZVg6IGFueSA9IDA7XG4gICAgaW5pdGlhbE1vdmVZOiBhbnkgPSAwO1xuICAgIG1vdmVYQzogbnVtYmVyO1xuICAgIG1vdmVZQzogbnVtYmVyO1xuXG4gICAgZGlzdGFuY2U6IG51bWJlcjtcbiAgICBpbml0aWFsRGlzdGFuY2U6IG51bWJlcjtcbiAgICBkcmFnZ2luZ01vZGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBkb3VibGVUYXBUaW1lb3V0OiBhbnk7XG4gICAgbGFzdFRhcDogbnVtYmVyID0gMDtcblxuICAgIEBJbnB1dCgnaGVpZ2h0JykgY29udGFpbmVySGVpZ2h0OiBzdHJpbmc7XG4gICAgQElucHV0KCd0cmFuc2l0aW9uLWR1cmF0aW9uJykgdHJhbnNpdGlvbkR1cmF0aW9uOiBudW1iZXIgPSAyMDA7XG4gICAgQElucHV0KCdhdXRvLXpvb20tb3V0JykgYXV0b1pvb21PdXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoJ2lkJykgc2V0IGlkKHZhbHVlOiBhbnkpIHtcbiAgICAgICAgdGhpcy5faWQgPSB2YWx1ZTtcbiAgICB9XG4gICAgZ2V0IGlkKCl7XG4gICAgICAgIHJldHVybiB0aGlzLl9pZDtcbiAgICB9XG4gICAgXG4gICAgQE91dHB1dCgpIGV2ZW50czogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAgIEBIb3N0QmluZGluZygnc3R5bGUuZGlzcGxheScpIGhvc3REaXNwbGF5OnN0cmluZztcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLm92ZXJmbG93JykgaG9zdE92ZXJmbG93OnN0cmluZztcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmhlaWdodCcpIGhvc3RIZWlnaHQ6c3RyaW5nO1xuXG4gICAgQFZpZXdDaGlsZCgnY29udGVudCcpIGNvbnRlbnRFbGVtZW50OiBFbGVtZW50UmVmO1xuXG4gICAgZ2V0IGlzTW9iaWxlKCkge1xuICAgICAgICB2YXIgY2hlY2sgPSBmYWxzZTtcbiAgICAgICAgKGZ1bmN0aW9uKGEpe2lmKC8oYW5kcm9pZHxiYlxcZCt8bWVlZ28pLittb2JpbGV8YXZhbnRnb3xiYWRhXFwvfGJsYWNrYmVycnl8YmxhemVyfGNvbXBhbHxlbGFpbmV8ZmVubmVjfGhpcHRvcHxpZW1vYmlsZXxpcChob25lfG9kKXxpcmlzfGtpbmRsZXxsZ2UgfG1hZW1vfG1pZHB8bW1wfG1vYmlsZS4rZmlyZWZveHxuZXRmcm9udHxvcGVyYSBtKG9ifGluKWl8cGFsbSggb3MpP3xwaG9uZXxwKGl4aXxyZSlcXC98cGx1Y2tlcnxwb2NrZXR8cHNwfHNlcmllcyg0fDYpMHxzeW1iaWFufHRyZW98dXBcXC4oYnJvd3NlcnxsaW5rKXx2b2RhZm9uZXx3YXB8d2luZG93cyBjZXx4ZGF8eGlpbm8vaS50ZXN0KGEpfHwvMTIwN3w2MzEwfDY1OTB8M2dzb3w0dGhwfDUwWzEtNl1pfDc3MHN8ODAyc3xhIHdhfGFiYWN8YWMoZXJ8b298c1xcLSl8YWkoa298cm4pfGFsKGF2fGNhfGNvKXxhbW9pfGFuKGV4fG55fHl3KXxhcHR1fGFyKGNofGdvKXxhcyh0ZXx1cyl8YXR0d3xhdShkaXxcXC1tfHIgfHMgKXxhdmFufGJlKGNrfGxsfG5xKXxiaShsYnxyZCl8YmwoYWN8YXopfGJyKGV8dil3fGJ1bWJ8YndcXC0obnx1KXxjNTVcXC98Y2FwaXxjY3dhfGNkbVxcLXxjZWxsfGNodG18Y2xkY3xjbWRcXC18Y28obXB8bmQpfGNyYXd8ZGEoaXR8bGx8bmcpfGRidGV8ZGNcXC1zfGRldml8ZGljYXxkbW9ifGRvKGN8cClvfGRzKDEyfFxcLWQpfGVsKDQ5fGFpKXxlbShsMnx1bCl8ZXIoaWN8azApfGVzbDh8ZXooWzQtN10wfG9zfHdhfHplKXxmZXRjfGZseShcXC18Xyl8ZzEgdXxnNTYwfGdlbmV8Z2ZcXC01fGdcXC1tb3xnbyhcXC53fG9kKXxncihhZHx1bil8aGFpZXxoY2l0fGhkXFwtKG18cHx0KXxoZWlcXC18aGkocHR8dGEpfGhwKCBpfGlwKXxoc1xcLWN8aHQoYyhcXC18IHxffGF8Z3xwfHN8dCl8dHApfGh1KGF3fHRjKXxpXFwtKDIwfGdvfG1hKXxpMjMwfGlhYyggfFxcLXxcXC8pfGlicm98aWRlYXxpZzAxfGlrb218aW0xa3xpbm5vfGlwYXF8aXJpc3xqYSh0fHYpYXxqYnJvfGplbXV8amlnc3xrZGRpfGtlaml8a2d0KCB8XFwvKXxrbG9ufGtwdCB8a3djXFwtfGt5byhjfGspfGxlKG5vfHhpKXxsZyggZ3xcXC8oa3xsfHUpfDUwfDU0fFxcLVthLXddKXxsaWJ3fGx5bnh8bTFcXC13fG0zZ2F8bTUwXFwvfG1hKHRlfHVpfHhvKXxtYygwMXwyMXxjYSl8bVxcLWNyfG1lKHJjfHJpKXxtaShvOHxvYXx0cyl8bW1lZnxtbygwMXwwMnxiaXxkZXxkb3x0KFxcLXwgfG98dil8enopfG10KDUwfHAxfHYgKXxtd2JwfG15d2F8bjEwWzAtMl18bjIwWzItM118bjMwKDB8Mil8bjUwKDB8Mnw1KXxuNygwKDB8MSl8MTApfG5lKChjfG0pXFwtfG9ufHRmfHdmfHdnfHd0KXxub2soNnxpKXxuenBofG8yaW18b3AodGl8d3YpfG9yYW58b3dnMXxwODAwfHBhbihhfGR8dCl8cGR4Z3xwZygxM3xcXC0oWzEtOF18YykpfHBoaWx8cGlyZXxwbChheXx1Yyl8cG5cXC0yfHBvKGNrfHJ0fHNlKXxwcm94fHBzaW98cHRcXC1nfHFhXFwtYXxxYygwN3wxMnwyMXwzMnw2MHxcXC1bMi03XXxpXFwtKXxxdGVrfHIzODB8cjYwMHxyYWtzfHJpbTl8cm8odmV8em8pfHM1NVxcL3xzYShnZXxtYXxtbXxtc3xueXx2YSl8c2MoMDF8aFxcLXxvb3xwXFwtKXxzZGtcXC98c2UoYyhcXC18MHwxKXw0N3xtY3xuZHxyaSl8c2doXFwtfHNoYXJ8c2llKFxcLXxtKXxza1xcLTB8c2woNDV8aWQpfHNtKGFsfGFyfGIzfGl0fHQ1KXxzbyhmdHxueSl8c3AoMDF8aFxcLXx2XFwtfHYgKXxzeSgwMXxtYil8dDIoMTh8NTApfHQ2KDAwfDEwfDE4KXx0YShndHxsayl8dGNsXFwtfHRkZ1xcLXx0ZWwoaXxtKXx0aW1cXC18dFxcLW1vfHRvKHBsfHNoKXx0cyg3MHxtXFwtfG0zfG01KXx0eFxcLTl8dXAoXFwuYnxnMXxzaSl8dXRzdHx2NDAwfHY3NTB8dmVyaXx2aShyZ3x0ZSl8dmsoNDB8NVswLTNdfFxcLXYpfHZtNDB8dm9kYXx2dWxjfHZ4KDUyfDUzfDYwfDYxfDcwfDgwfDgxfDgzfDg1fDk4KXx3M2MoXFwtfCApfHdlYmN8d2hpdHx3aShnIHxuY3xudyl8d21sYnx3b251fHg3MDB8eWFzXFwtfHlvdXJ8emV0b3x6dGVcXC0vaS50ZXN0KGEuc3Vic3RyKDAsNCkpKSBjaGVjayA9IHRydWU7fSkobmF2aWdhdG9yLnVzZXJBZ2VudHx8bmF2aWdhdG9yLnZlbmRvcik7XG4gICAgICAgIHJldHVybiBjaGVjaztcbiAgICB9O1xuXG4gICAgZ2V0IGlzRHJhZ2dpbmcoKXtcbiAgICAgICAgbGV0IGltZ0hlaWdodCA9IHRoaXMuZ2V0SW1hZ2VIZWlnaHQoKTtcbiAgICAgICAgbGV0IGltZ1dpZHRoID0gdGhpcy5nZXRJbWFnZVdpZHRoKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuc2NhbGUgPiAxKSB7XG4gICAgICAgICAgICByZXR1cm4gaW1nSGVpZ2h0ICogdGhpcy5zY2FsZSA+IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgaW1nV2lkdGggKiB0aGlzLnNjYWxlID4gdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNjYWxlID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gaW1nSGVpZ2h0ID4gdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldEhlaWdodCB8fCBpbWdXaWR0aCA+IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZil7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuY29udGVudEVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy5wYXJlbnRFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc2V0QmFzaWNTdHlsZXMoKTtcbiAgICB9XG5cblxuICAgIC8qXG4gICAgICogTW9iaWxlIGxpc3RlbmVyc1xuICAgICAqL1xuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25SZXNpemUoZXZlbnQ6RXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZXRJbWFnZVdpZHRoKCk7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtRWxlbWVudCh0aGlzLnRyYW5zaXRpb25EdXJhdGlvbik7IFxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBbJyRldmVudCddKVxuICAgIHRvdWNoc3RhcnRIYW5kbGVyKGV2ZW50OmFueSkge1xuICAgICAgICB0aGlzLmdldEVsZW1lbnRQb3NpdGlvbigpO1xuXG4gICAgICAgIGlmICghdGhpcy5ldmVudFR5cGUpe1xuICAgICAgICAgICAgdGhpcy5zdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0O1xuICAgICAgICAgICAgdGhpcy5zdGFydFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3A7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0Q2xpZW50WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQ7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0Q2xpZW50WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe3R5cGU6ICd0b3VjaHN0YXJ0J30pO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3RvdWNobW92ZScsIFsnJGV2ZW50J10pXG4gICAgdG91Y2htb3ZlSGFuZGxlcihldmVudDphbnkpIHtcbiAgICAgICAgbGV0IHRvdWNoZXMgPSBldmVudC50b3VjaGVzO1xuXG4gICAgICAgIC8vIFN3aXBlXG4gICAgICAgIGlmICh0aGlzLmRldGVjdFN3aXBlKHRvdWNoZXMpIHx8IHRoaXMuZXZlbnRUeXBlID09ICdzd2lwZScpe1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVTd2lwZShldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQaW5jaFxuICAgICAgICBpZiAodG91Y2hlcy5sZW5ndGggPT09IDIgJiYgIXRoaXMuZXZlbnRUeXBlIHx8IHRoaXMuZXZlbnRUeXBlID09ICdwaW5jaCcpe1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVQaW5jaChldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCd0b3VjaGVuZCcsIFsnJGV2ZW50J10pXG4gICAgdG91Y2hlbmRIYW5kbGVyKGV2ZW50OmFueSkge1xuICAgICAgICB0aGlzLmkgPSAwO1xuICAgICAgICB0aGlzLmRyYWdnaW5nTW9kZSA9IGZhbHNlO1xuICAgICAgICBsZXQgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XG5cbiAgICAgICAgaWYgKHRoaXMuc2NhbGUgPCAxKXtcbiAgICAgICAgICAgIHRoaXMuc2NhbGUgPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXV0byBab29tIE91dFxuICAgICAgICBpZiAodGhpcy5hdXRvWm9vbU91dCAmJiB0aGlzLmV2ZW50VHlwZSA9PT0gJ3BpbmNoJyl7XG4gICAgICAgICAgICB0aGlzLnNjYWxlID0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe3R5cGU6ICd0b3VjaGVuZCd9KTtcblxuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgPT09ICdwaW5jaCcgfHwgdGhpcy5ldmVudFR5cGUgPT09ICdzd2lwZScpe1xuICAgICAgICAgICAgdGhpcy5hbGlnbkltYWdlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgPT09ICdwaW5jaCcgfHwgXG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ3N3aXBlJyB8fFxuICAgICAgICAgICAgdGhpcy5ldmVudFR5cGUgPT09ICdob3Jpem9udGFsLXN3aXBlJyB8fFxuICAgICAgICAgICAgdGhpcy5ldmVudFR5cGUgPT09ICd2ZXJ0aWNhbC1zd2lwZScpe1xuICAgICAgICAgICAgdGhpcy51cGRhdGVJbml0aWFsVmFsdWVzKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICd0b3VjaGVuZCc7XG5cbiAgICAgICAgaWYgKHRvdWNoZXMgJiYgdG91Y2hlcy5sZW5ndGggPT0gMCl7XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICcnO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKlxuICAgICAqIEhhbmRsZXJzXG4gICAgICovXG5cbiAgICBoYW5kbGVTd2lwZShldmVudDphbnkpe1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGlmICghdGhpcy5ldmVudFR5cGUpe1xuICAgICAgICAgICAgdGhpcy5zdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0O1xuICAgICAgICAgICAgdGhpcy5zdGFydFkgPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3A7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICdzd2lwZSc7XG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe1xuICAgICAgICAgICAgdHlwZTogJ3N3aXBlJyxcbiAgICAgICAgICAgIG1vdmVYOiB0aGlzLm1vdmVYLFxuICAgICAgICAgICAgbW92ZVk6IHRoaXMubW92ZVlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5tb3ZlWCA9IHRoaXMuaW5pdGlhbE1vdmVYICsgKChldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0KSAtIHRoaXMuc3RhcnRYKTtcbiAgICAgICAgdGhpcy5tb3ZlWSA9IHRoaXMuaW5pdGlhbE1vdmVZICsgKChldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3ApIC0gdGhpcy5zdGFydFkpO1xuXG4gICAgICAgIHRoaXMudHJhbnNmb3JtRWxlbWVudCgwKTtcbiAgICB9XG5cbiAgICBoYW5kbGVQaW5jaChldmVudDphbnkpe1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGxldCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcblxuICAgICAgICBpZiAoIXRoaXMuZXZlbnRUeXBlKXtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbERpc3RhbmNlID0gdGhpcy5nZXREaXN0YW5jZSh0b3VjaGVzKTtcbiAgICAgICAgICAgIHRoaXMubW92ZVhDID0gKCgoZXZlbnQudG91Y2hlc1swXS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdCkgKyAoZXZlbnQudG91Y2hlc1sxXS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdCkpIC8gMikgLSB0aGlzLmluaXRpYWxNb3ZlWDtcbiAgICAgICAgICAgIHRoaXMubW92ZVlDID0gKCgoZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wKSArIChldmVudC50b3VjaGVzWzFdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3ApKSAvIDIpIC0gdGhpcy5pbml0aWFsTW92ZVk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICdwaW5jaCc7XG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe3R5cGU6ICdwaW5jaCd9KTtcbiAgICAgICAgdGhpcy5kaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UodG91Y2hlcyk7XG4gICAgICAgIHRoaXMuc2NhbGUgPSB0aGlzLmluaXRpYWxTY2FsZSAqICh0aGlzLmRpc3RhbmNlIC8gdGhpcy5pbml0aWFsRGlzdGFuY2UpO1xuICAgICAgICB0aGlzLm1vdmVYID0gdGhpcy5pbml0aWFsTW92ZVggLSAoKCh0aGlzLmRpc3RhbmNlIC8gdGhpcy5pbml0aWFsRGlzdGFuY2UpICogdGhpcy5tb3ZlWEMpIC0gdGhpcy5tb3ZlWEMpO1xuICAgICAgICB0aGlzLm1vdmVZID0gdGhpcy5pbml0aWFsTW92ZVkgLSAoKCh0aGlzLmRpc3RhbmNlIC8gdGhpcy5pbml0aWFsRGlzdGFuY2UpICogdGhpcy5tb3ZlWUMpIC0gdGhpcy5tb3ZlWUMpO1xuXG4gICAgICAgIHRoaXMudHJhbnNmb3JtRWxlbWVudCgwKTtcbiAgICB9XG5cblxuICAgIGRldGVjdFN3aXBlKHRvdWNoZXM6YW55KXtcbiAgICAgICAgcmV0dXJuIHRvdWNoZXMubGVuZ3RoID09PSAxICYmIHRoaXMuc2NhbGUgPiAxICYmICF0aGlzLmV2ZW50VHlwZTtcbiAgICB9XG5cbiAgICBnZXREaXN0YW5jZSh0b3VjaGVzOiBhbnkpe1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KCBNYXRoLnBvdyh0b3VjaGVzWzBdLnBhZ2VYIC0gdG91Y2hlc1sxXS5wYWdlWCwgMikgKyBNYXRoLnBvdyh0b3VjaGVzWzBdLnBhZ2VZIC0gdG91Y2hlc1sxXS5wYWdlWSwgMikpO1xuICAgIH1cblxuICAgIGdldEltYWdlSGVpZ2h0KCl7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbWdcIilbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgIH1cblxuICAgIGdldEltYWdlV2lkdGgoKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImltZ1wiKVswXS5vZmZzZXRXaWR0aDtcbiAgICB9XG5cbiAgICBzZXRCYXNpY1N0eWxlcygpOnZvaWQge1xuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwiZmxleFwiO1xuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5hbGlnbkl0ZW1zID0gXCJjZW50ZXJcIjtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmp1c3RpZnlDb250ZW50ID0gXCJjZW50ZXJcIjtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9ICcwIDAnO1xuICAgICAgICB0aGlzLmhvc3REaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICB0aGlzLmhvc3RPdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG4gICAgICAgIHRoaXMuaG9zdEhlaWdodCA9IHRoaXMuY29udGFpbmVySGVpZ2h0O1xuXG4gICAgICAgIHRoaXMuc2V0SW1hZ2VXaWR0aCgpO1xuICAgIH1cblxuICAgIHNldEltYWdlV2lkdGgoKTp2b2lkIHtcbiAgICAgICAgbGV0IGltZ0VsZW1lbnQgPSB0aGlzLmVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbWdcIik7XG5cbiAgICAgICAgaWYgKGltZ0VsZW1lbnQubGVuZ3RoKXtcbiAgICAgICAgICAgIGltZ0VsZW1lbnRbMF0uc3R5bGUubWF4V2lkdGggPSAnMTAwJSc7XG4gICAgICAgICAgICBpbWdFbGVtZW50WzBdLnN0eWxlLm1heEhlaWdodCA9ICcxMDAlJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRyYW5zZm9ybUVsZW1lbnQoZHVyYXRpb246IGFueSA9IDUwKXtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSAnYWxsICcrIGR1cmF0aW9uICsnbXMnO1xuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gJ21hdHJpeCgnKyBOdW1iZXIodGhpcy5zY2FsZSkgKycsJysgMCArJywnKyAwICsnLCcrIE51bWJlcih0aGlzLnNjYWxlKSArJywnKyBOdW1iZXIodGhpcy5tb3ZlWCkgKycsJysgTnVtYmVyKHRoaXMubW92ZVkpICsnKSc7XG4gICAgfVxuXG4gICAgcmVzZXRTY2FsZSgpOnZvaWQge1xuICAgICAgICB0aGlzLnNjYWxlID0gMTtcbiAgICAgICAgdGhpcy5tb3ZlWCA9IDA7XG4gICAgICAgIHRoaXMubW92ZVkgPSAwO1xuICAgICAgICB0aGlzLnVwZGF0ZUluaXRpYWxWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1FbGVtZW50KHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uKTtcbiAgICB9XG5cbiAgICB1cGRhdGVJbml0aWFsVmFsdWVzKCk6dm9pZCB7XG4gICAgICAgIHRoaXMuaW5pdGlhbFNjYWxlID0gdGhpcy5zY2FsZTtcbiAgICAgICAgdGhpcy5pbml0aWFsTW92ZVggPSB0aGlzLm1vdmVYO1xuICAgICAgICB0aGlzLmluaXRpYWxNb3ZlWSA9IHRoaXMubW92ZVk7XG4gICAgfVxuXG4gICAgY2VudGVyaW5nSW1hZ2UoKTpib29sZWFuIHtcbiAgICAgICAgbGV0IGltZyA9IHRoaXMuZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImltZ1wiKVswXTtcbiAgICAgICAgY29uc3QgaW5pdGlhbE1vdmVYID0gdGhpcy5tb3ZlWDtcbiAgICAgICAgY29uc3QgaW5pdGlhbE1vdmVZID0gdGhpcy5tb3ZlWTtcblxuICAgICAgICBpZiAodGhpcy5tb3ZlWSA+IDApe1xuICAgICAgICAgICAgdGhpcy5tb3ZlWSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubW92ZVggPiAwKXtcbiAgICAgICAgICAgIHRoaXMubW92ZVggPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGltZyl7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25ZUmVzdHJpY3Rpb24oKTtcbiAgICAgICAgICAgIHRoaXMudHJhbnNpdGlvblhSZXN0cmljdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbWcgJiYgdGhpcy5zY2FsZSA8IDEpe1xuICAgICAgICAgICAgaWYgKHRoaXMubW92ZVggPCB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGggKiAoMSAtIHRoaXMuc2NhbGUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3ZlWCA9IHRoaXMuZWxlbWVudC5vZmZzZXRXaWR0aCAqICgxIC0gdGhpcy5zY2FsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5pdGlhbE1vdmVYICE9IHRoaXMubW92ZVggfHwgaW5pdGlhbE1vdmVZICE9IHRoaXMubW92ZVk7XG4gICAgfVxuXG4gICAgcHVibGljIGFsaWduSW1hZ2UoKTp2b2lkIHtcbiAgICAgICAgbGV0IGlzTW92ZUNoYW5nZWQgPSB0aGlzLmNlbnRlcmluZ0ltYWdlKCk7XG5cbiAgICAgICAgaWYgKGlzTW92ZUNoYW5nZWQpe1xuICAgICAgICAgICAgdGhpcy51cGRhdGVJbml0aWFsVmFsdWVzKCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybUVsZW1lbnQodGhpcy50cmFuc2l0aW9uRHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdHJhbnNpdGlvbllSZXN0cmljdGlvbigpOnZvaWQge1xuICAgICAgICBsZXQgaW1nSGVpZ2h0ID0gdGhpcy5nZXRJbWFnZUhlaWdodCgpO1xuXG4gICAgICAgIGlmIChpbWdIZWlnaHQgKiB0aGlzLnNjYWxlIDwgdGhpcy5wYXJlbnRFbGVtZW50Lm9mZnNldEhlaWdodCl7XG4gICAgICAgICAgICB0aGlzLm1vdmVZID0gKHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQgLSB0aGlzLmVsZW1lbnQub2Zmc2V0SGVpZ2h0ICogdGhpcy5zY2FsZSkgLyAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGltZ09mZnNldFRvcCA9ICgoaW1nSGVpZ2h0IC0gdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodCkgKiB0aGlzLnNjYWxlKSAvIDI7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm1vdmVZID4gaW1nT2Zmc2V0VG9wKXtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdmVZID0gaW1nT2Zmc2V0VG9wO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoaW1nSGVpZ2h0ICogdGhpcy5zY2FsZSArIE1hdGguYWJzKGltZ09mZnNldFRvcCkgLSB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KSArIHRoaXMubW92ZVkgPCAwKXtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdmVZID0gLSAoaW1nSGVpZ2h0ICogdGhpcy5zY2FsZSArIE1hdGguYWJzKGltZ09mZnNldFRvcCkgLSB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRyYW5zaXRpb25YUmVzdHJpY3Rpb24oKTp2b2lkIHtcbiAgICAgICAgbGV0IGltZ1dpZHRoID0gdGhpcy5nZXRJbWFnZVdpZHRoKCk7XG5cbiAgICAgICAgaWYgKGltZ1dpZHRoICogdGhpcy5zY2FsZSA8IHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRXaWR0aCkge1xuICAgICAgICAgICAgdGhpcy5tb3ZlWCA9ICh0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0V2lkdGggLSB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGggKiB0aGlzLnNjYWxlKSAvIDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgaW1nT2Zmc2V0TGVmdCA9ICgoaW1nV2lkdGggLSB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGgpICogdGhpcy5zY2FsZSkgLyAyO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5tb3ZlWCA+IGltZ09mZnNldExlZnQpe1xuICAgICAgICAgICAgICAgIHRoaXMubW92ZVggPSBpbWdPZmZzZXRMZWZ0O1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoaW1nV2lkdGggKiB0aGlzLnNjYWxlICsgTWF0aC5hYnMoaW1nT2Zmc2V0TGVmdCkgLSB0aGlzLnBhcmVudEVsZW1lbnQub2Zmc2V0V2lkdGgpICsgdGhpcy5tb3ZlWCA8IDApe1xuICAgICAgICAgICAgICAgIHRoaXMubW92ZVggPSAtIChpbWdXaWR0aCAqIHRoaXMuc2NhbGUgKyBNYXRoLmFicyhpbWdPZmZzZXRMZWZ0KSAtIHRoaXMucGFyZW50RWxlbWVudC5vZmZzZXRXaWR0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRFbGVtZW50UG9zaXRpb24oKTp2b2lkIHtcbiAgICAgICAgdGhpcy5lbGVtZW50UG9zaXRpb24gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG59IiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBQaW5jaFpvb21Db21wb25lbnQgfSBmcm9tICcuL3BpbmNoLXpvb20uY29tcG9uZW50JzsgXG5cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbXG4gICAgICAgIFBpbmNoWm9vbUNvbXBvbmVudFxuICAgIF0sXG4gICAgaW1wb3J0czogW1xuICAgICAgICBDb21tb25Nb2R1bGVcbiAgICBdLFxuICAgIGV4cG9ydHM6IFtcbiAgICAgICAgUGluY2hab29tQ29tcG9uZW50XG4gICAgXSxcbiAgICBlbnRyeUNvbXBvbmVudHM6IFtcbiAgICAgICAgUGluY2hab29tQ29tcG9uZW50XG4gICAgXVxufSlcbmV4cG9ydCBjbGFzcyBQaW5jaFpvb21Nb2R1bGUgeyB9XG4iXSwibmFtZXMiOlsiRXZlbnRFbWl0dGVyIiwiQ29tcG9uZW50IiwiRWxlbWVudFJlZiIsIklucHV0IiwiT3V0cHV0IiwiSG9zdEJpbmRpbmciLCJWaWV3Q2hpbGQiLCJIb3N0TGlzdGVuZXIiLCJOZ01vZHVsZSIsIkNvbW1vbk1vZHVsZSJdLCJtYXBwaW5n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