ngx-pinch-zoom
Version:
Pinch zoom component for Angular.
255 lines • 33.2 kB
JavaScript
import { Component, ElementRef, HostBinding, Input } from '@angular/core';
import { defaultProperties, backwardCompatibilityProperties } from './properties';
import { IvyPinch } from './ivypinch';
export const _defaultComponentProperties = {
overflow: "hidden",
disableZoomControl: "auto",
backgroundColor: "rgba(0,0,0,0.85)"
};
export class PinchZoomComponent {
constructor(elementRef) {
this.elementRef = elementRef;
this.defaultComponentProperties = this.getDefaultComponentProperties();
this.applyPropertiesDefault(this.defaultComponentProperties, {});
}
set properties(value) {
if (value) {
this._properties = value;
}
}
get properties() {
return this._properties;
}
// transitionDuration
set transitionDurationBackwardCompatibility(value) {
if (value) {
this._transitionDuration = value;
}
}
set transitionDuration(value) {
if (value) {
this._transitionDuration = value;
}
}
get transitionDuration() {
return this._transitionDuration;
}
// doubleTap
set doubleTapBackwardCompatibility(value) {
if (value) {
this._doubleTap = value;
}
}
set doubleTap(value) {
if (value) {
this._doubleTap = value;
}
}
get doubleTap() {
return this._doubleTap;
}
// doubleTapScale
set doubleTapScaleBackwardCompatibility(value) {
if (value) {
this._doubleTapScale = value;
}
}
set doubleTapScale(value) {
if (value) {
this._doubleTapScale = value;
}
}
get doubleTapScale() {
return this._doubleTapScale;
}
// autoZoomOut
set autoZoomOutBackwardCompatibility(value) {
if (value) {
this._autoZoomOut = value;
}
}
set autoZoomOut(value) {
if (value) {
this._autoZoomOut = value;
}
}
get autoZoomOut() {
return this._autoZoomOut;
}
// limitZoom
set limitZoomBackwardCompatibility(value) {
if (value) {
this._limitZoom = value;
}
}
set limitZoom(value) {
if (value) {
this._limitZoom = value;
}
}
get limitZoom() {
return this._limitZoom;
}
get hostOverflow() {
return this.properties['overflow'];
}
get hostBackgroundColor() {
return this.properties['backgroundColor'];
}
get isTouchScreen() {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
}
get isDragging() {
return this.pinchZoom ? this.pinchZoom.isDragging() : undefined;
}
get isDisabled() {
return this.properties['disabled'];
}
get scale() {
return this.pinchZoom.scale;
}
get isZoomedIn() {
return this.scale > 1;
}
get scaleLevel() {
return Math.round(this.scale / this._zoomControlScale);
}
get maxScale() {
return this.pinchZoom.maxScale;
}
get isZoomLimitReached() {
return this.scale >= this.maxScale;
}
get _zoomControlScale() {
return this.getPropertiesValue('zoomControlScale');
}
ngOnInit() {
this.initPinchZoom();
/* Calls the method until the image size is available */
this.detectLimitZoom();
}
ngOnChanges(changes) {
let changedProperties = this.getProperties(changes);
changedProperties = this.renameProperties(changedProperties);
this.applyPropertiesDefault(this.defaultComponentProperties, changedProperties);
}
ngOnDestroy() {
this.destroy();
}
initPinchZoom() {
if (this.properties['disabled']) {
return;
}
this.properties['element'] = this.elementRef.nativeElement.querySelector('.pinch-zoom-content');
this.pinchZoom = new IvyPinch(this.properties);
}
getProperties(changes) {
let properties = {};
for (var prop in changes) {
if (prop !== 'properties') {
properties[prop] = changes[prop].currentValue;
}
if (prop === 'properties') {
properties = changes[prop].currentValue;
}
}
return properties;
}
renameProperties(properties) {
for (var prop in properties) {
if (backwardCompatibilityProperties[prop]) {
properties[backwardCompatibilityProperties[prop]] = properties[prop];
delete properties[prop];
}
}
return properties;
}
applyPropertiesDefault(defaultProperties, properties) {
this.properties = Object.assign({}, defaultProperties, properties);
}
toggleZoom() {
this.pinchZoom.toggleZoom();
}
isControl() {
if (this.isDisabled) {
return false;
}
if (this.properties['disableZoomControl'] === "disable") {
return false;
}
if (this.isTouchScreen && this.properties['disableZoomControl'] === "auto") {
return false;
}
return true;
}
detectLimitZoom() {
if (this.pinchZoom) {
this.pinchZoom.detectLimitZoom();
}
}
destroy() {
this.pinchZoom.destroy();
}
getPropertiesValue(propertyName) {
if (this.properties && this.properties[propertyName]) {
return this.properties[propertyName];
}
else {
return this.defaultComponentProperties[propertyName];
}
}
getDefaultComponentProperties() {
return Object.assign(Object.assign({}, defaultProperties), _defaultComponentProperties);
}
}
PinchZoomComponent.decorators = [
{ type: Component, args: [{
selector: 'pinch-zoom, [pinch-zoom]',
exportAs: 'pinchZoom',
template: "<div class=\"pinch-zoom-content\" [class.pz-dragging]=\"isDragging\">\n\t<ng-content></ng-content>\n</div>\n\n<!-- Control: one button -->\n<div class=\"pz-zoom-button pz-zoom-control-position-bottom\" \n\t[class.pz-zoom-button-out]=\"isZoomedIn\" \n\t*ngIf=\"isControl()\" \n\t(click)=\"toggleZoom()\"></div>",
styles: [":host{display:block;overflow:hidden;position:relative}.pinch-zoom-content{height:inherit}.pz-dragging{cursor:all-scroll}.pz-zoom-button{-webkit-user-select:none;background-color:rgba(0,0,0,.8);background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgc3R5bGU9IiI+PHJlY3QgaWQ9ImJhY2tncm91bmRyZWN0IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIwIiB5PSIwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48ZyBjbGFzcz0iY3VycmVudExheWVyIiBzdHlsZT0iIj48dGl0bGU+TGF5ZXIgMTwvdGl0bGU+PHBhdGggZD0iTTE1LjUgMTRoLS43OWwtLjI4LS4yN0MxNS40MSAxMi41OSAxNiAxMS4xMSAxNiA5LjUgMTYgNS45MSAxMy4wOSAzIDkuNSAzUzMgNS45MSAzIDkuNSA1LjkxIDE2IDkuNSAxNmMxLjYxIDAgMy4wOS0uNTkgNC4yMy0xLjU3bC4yNy4yOHYuNzlsNSA0Ljk5TDIwLjQ5IDE5bC00Ljk5LTV6bS02IDBDNy4wMSAxNCA1IDExLjk5IDUgOS41UzcuMDEgNSA5LjUgNSAxNCA3LjAxIDE0IDkuNSAxMS45OSAxNCA5LjUgMTR6IiBpZD0ic3ZnXzEiIGNsYXNzPSIiIGZpbGw9IiNmZmZmZmYiIGZpbGwtb3BhY2l0eT0iMSIvPjxwYXRoIGQ9Ik0xMiAxMGgtMnYySDl2LTJIN1Y5aDJWN2gxdjJoMnYxeiIgaWQ9InN2Z18zIiBjbGFzcz0iIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjEiLz48L2c+PC9zdmc+),url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHJlY3QgaWQ9ImJhY2tncm91bmRyZWN0IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIwIiB5PSIwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48ZyBjbGFzcz0iY3VycmVudExheWVyIiBzdHlsZT0iIj48dGl0bGU+TGF5ZXIgMTwvdGl0bGU+PHBhdGggZD0iTTE1LjUgMTRoLS43OWwtLjI4LS4yN0MxNS40MSAxMi41OSAxNiAxMS4xMSAxNiA5LjUgMTYgNS45MSAxMy4wOSAzIDkuNSAzUzMgNS45MSAzIDkuNSA1LjkxIDE2IDkuNSAxNmMxLjYxIDAgMy4wOS0uNTkgNC4yMy0xLjU3bC4yNy4yOHYuNzlsNSA0Ljk5TDIwLjQ5IDE5bC00Ljk5LTV6bS02IDBDNy4wMSAxNCA1IDExLjk5IDUgOS41UzcuMDEgNSA5LjUgNSAxNCA3LjAxIDE0IDkuNSAxMS45OSAxNCA5LjUgMTR6TTcgOWg1djFIN3oiIGlkPSJzdmdfMiIgY2xhc3M9IiIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIxIi8+PC9nPjwvc3ZnPg==);background-position:50%,-1000px;background-repeat:no-repeat,no-repeat;background-size:40px;border-radius:4px;color:#fff;cursor:pointer;height:56px;opacity:.5;position:absolute;transition:opacity .1s;user-select:none;width:56px;z-index:1000}.pz-zoom-button-out{background-position:-1000px,50%}.pz-zoom-button:hover{opacity:.7}.pz-zoom-button.pz-zoom-control-position-right{margin-top:-28px;right:16px;top:50%}.pz-zoom-button.pz-zoom-control-position-right-bottom{bottom:32px;right:16px}.pz-zoom-button.pz-zoom-control-position-bottom{bottom:16px;left:50%;margin-left:-28px}.pz-zoom-control{background-color:rgba(0,0,0,.8);border-radius:4px;overflow:hidden;position:absolute}.pz-zoom-control.pz-zoom-control-position-right{margin-top:-48px;right:16px;top:50%}.pz-zoom-control.pz-zoom-control-position-right-bottom{bottom:32px;right:16px}.pz-zoom-control.pz-zoom-control-position-bottom{bottom:16px;left:50%;margin-left:-48px}.pz-zoom-in,.pz-zoom-out{background-position:50%;background-repeat:no-repeat;cursor:pointer;height:48px;opacity:1;width:48px}.pz-zoom-in:hover,.pz-zoom-out:hover{background-color:hsla(0,0%,100%,.2)}.pz-zoom-control-position-bottom .pz-zoom-in,.pz-zoom-control-position-bottom .pz-zoom-out{float:right}.pz-disabled{cursor:default;opacity:.5}.pz-disabled:hover{background-color:hsla(0,0%,100%,0)}.pz-zoom-in{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgc3R5bGU9IiI+PHJlY3QgaWQ9ImJhY2tncm91bmRyZWN0IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIwIiB5PSIwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48ZyBjbGFzcz0iY3VycmVudExheWVyIiBzdHlsZT0iIj48dGl0bGU+TGF5ZXIgMTwvdGl0bGU+PHBhdGggZD0iTTE5IDEzaC02djZoLTJ2LTZINXYtMmg2VjVoMnY2aDZ2MnoiIGlkPSJzdmdfMSIgY2xhc3M9IiIgc3Ryb2tlPSJub25lIiBmaWxsPSIjZmZmZmZmIiBmaWxsLW9wYWNpdHk9IjEiLz48cGF0aCBkPSJNLTE1LjgzNjczNDQyMDQ2MTY1Myw0NC41MzU0MDkzMDY3MTAxOCBoNTguMjA0MDgwODI3NTkzMDkgdi02LjU3NjIyNjcyMzM2OTIyMTUgSC0xNS44MzY3MzQ0MjA0NjE2NTMgeiIgZmlsbD0ibm9uZSIgaWQ9InN2Z18yIiBjbGFzcz0iIiBzdHJva2U9Im5vbmUiLz48L2c+PC9zdmc+)}.pz-zoom-out{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHJlY3QgaWQ9ImJhY2tncm91bmRyZWN0IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIwIiB5PSIwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiLz48ZyBjbGFzcz0iY3VycmVudExheWVyIiBzdHlsZT0iIj48dGl0bGU+TGF5ZXIgMTwvdGl0bGU+PHBhdGggZD0iTTE5IDEzSDV2LTJoMTR2MnoiIGlkPSJzdmdfMSIgY2xhc3M9IiIgZmlsbD0iI2ZmZmZmZiIgZmlsbC1vcGFjaXR5PSIxIi8+PC9nPjwvc3ZnPg==)}"]
},] }
];
PinchZoomComponent.ctorParameters = () => [
{ type: ElementRef }
];
PinchZoomComponent.propDecorators = {
properties: [{ type: Input, args: ['properties',] }],
transitionDurationBackwardCompatibility: [{ type: Input, args: ['transition-duration',] }],
transitionDuration: [{ type: Input, args: ['transitionDuration',] }],
doubleTapBackwardCompatibility: [{ type: Input, args: ['double-tap',] }],
doubleTap: [{ type: Input, args: ['doubleTap',] }],
doubleTapScaleBackwardCompatibility: [{ type: Input, args: ['double-tap-scale',] }],
doubleTapScale: [{ type: Input, args: ['doubleTapScale',] }],
autoZoomOutBackwardCompatibility: [{ type: Input, args: ['auto-zoom-out',] }],
autoZoomOut: [{ type: Input, args: ['autoZoomOut',] }],
limitZoomBackwardCompatibility: [{ type: Input, args: ['limit-zoom',] }],
limitZoom: [{ type: Input, args: ['limitZoom',] }],
disabled: [{ type: Input }],
disablePan: [{ type: Input }],
overflow: [{ type: Input }],
zoomControlScale: [{ type: Input }],
disableZoomControl: [{ type: Input }],
backgroundColor: [{ type: Input }],
limitPan: [{ type: Input }],
minPanScale: [{ type: Input }],
minScale: [{ type: Input }],
listeners: [{ type: Input }],
wheel: [{ type: Input }],
autoHeight: [{ type: Input }],
wheelZoomFactor: [{ type: Input }],
draggableImage: [{ type: Input }],
hostOverflow: [{ type: HostBinding, args: ['style.overflow',] }],
hostBackgroundColor: [{ type: HostBinding, args: ['style.background-color',] }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGluY2gtem9vbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcGluY2gtem9vbS9zcmMvbGliL3BpbmNoLXpvb20uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBb0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQWdCLEtBQUssRUFBMkIsTUFBTSxlQUFlLENBQUM7QUFHbkksT0FBTyxFQUFDLGlCQUFpQixFQUFFLCtCQUErQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBQ2hGLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFTcEMsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQXVCO0lBQzNELFFBQVEsRUFBRSxRQUFRO0lBQ2xCLGtCQUFrQixFQUFFLE1BQU07SUFDMUIsZUFBZSxFQUFFLGtCQUFrQjtDQUN0QyxDQUFBO0FBV0QsTUFBTSxPQUFPLGtCQUFrQjtJQXVLNUIsWUFBb0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUNyQyxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7UUFDdkUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBL0pELElBQXlCLFVBQVUsQ0FBQyxLQUEwQjtRQUMxRCxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1NBQzVCO0lBQ0wsQ0FBQztJQUNELElBQUksVUFBVTtRQUNWLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUM1QixDQUFDO0lBRUQscUJBQXFCO0lBQ3JCLElBQWtDLHVDQUF1QyxDQUFDLEtBQWE7UUFDbkYsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1NBQ3BDO0lBQ0wsQ0FBQztJQUNELElBQWlDLGtCQUFrQixDQUFDLEtBQWE7UUFDN0QsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1NBQ3BDO0lBQ0wsQ0FBQztJQUNELElBQUksa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDO0lBQ3BDLENBQUM7SUFFRCxZQUFZO0lBQ1osSUFBeUIsOEJBQThCLENBQUMsS0FBYztRQUNsRSxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1NBQzNCO0lBQ0wsQ0FBQztJQUNELElBQXdCLFNBQVMsQ0FBQyxLQUFjO1FBQzVDLElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7U0FDM0I7SUFDTCxDQUFDO0lBQ0QsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7SUFFRCxpQkFBaUI7SUFDakIsSUFBK0IsbUNBQW1DLENBQUMsS0FBYTtRQUM1RSxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1NBQ2hDO0lBQ0wsQ0FBQztJQUNELElBQTZCLGNBQWMsQ0FBQyxLQUFhO1FBQ3JELElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7U0FDaEM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxjQUFjO1FBQ2QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxjQUFjO0lBQ2QsSUFBNEIsZ0NBQWdDLENBQUMsS0FBYztRQUN2RSxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1NBQzdCO0lBQ0wsQ0FBQztJQUNELElBQTBCLFdBQVcsQ0FBQyxLQUFjO1FBQ2hELElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7U0FDN0I7SUFDTCxDQUFDO0lBQ0QsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLENBQUM7SUFFRCxZQUFZO0lBQ1osSUFBeUIsOEJBQThCLENBQUMsS0FBcUM7UUFDekYsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztTQUMzQjtJQUNMLENBQUM7SUFDRCxJQUF3QixTQUFTLENBQUMsS0FBcUM7UUFDbkUsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztTQUMzQjtJQUNMLENBQUM7SUFDRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQWlCRCxJQUNJLFlBQVk7UUFDWixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUNELElBQ0ksbUJBQW1CO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDYixJQUFJLFFBQVEsR0FBRywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEQsSUFBSSxFQUFFLEdBQUcsVUFBUyxLQUFTO1lBQ3ZCLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDNUMsQ0FBQyxDQUFBO1FBRUQsSUFBSSxDQUFDLGNBQWMsSUFBSSxNQUFNLENBQUMsRUFBRTtZQUM1QixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQscUZBQXFGO1FBQ3JGLHVCQUF1QjtRQUN2QixJQUFJLEtBQUssR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDcEUsQ0FBQztJQUVELElBQUksVUFBVTtRQUNWLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ0wsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7SUFDbkMsQ0FBQztJQUVELElBQUksa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNqQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFPRCxRQUFRO1FBQ0osSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLHdEQUF3RDtRQUN4RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFxQjtRQUM3QixJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEQsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxXQUFXO1FBQ1AsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCxhQUFhO1FBQ1QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQzdCLE9BQU87U0FDVjtRQUVELElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDaEcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELGFBQWEsQ0FBQyxPQUFxQjtRQUMvQixJQUFJLFVBQVUsR0FBTyxFQUFFLENBQUM7UUFFeEIsS0FBSyxJQUFJLElBQUksSUFBSSxPQUFPLEVBQUU7WUFDdEIsSUFBSSxJQUFJLEtBQUssWUFBWSxFQUFDO2dCQUN0QixVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQzthQUNqRDtZQUNELElBQUksSUFBSSxLQUFLLFlBQVksRUFBQztnQkFDdEIsVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUM7YUFDM0M7U0FDSjtRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxVQUFlO1FBQzVCLEtBQUssSUFBSSxJQUFJLElBQUksVUFBVSxFQUFFO1lBQ3pCLElBQUksK0JBQStCLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3ZDLFVBQVUsQ0FBQywrQkFBK0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDckUsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDM0I7U0FDSjtRQUVELE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxzQkFBc0IsQ0FBQyxpQkFBcUMsRUFBRSxVQUE4QjtRQUN4RixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxVQUFVO1FBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsU0FBUztRQUNMLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLFNBQVMsRUFBRTtZQUNyRCxPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUVELElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLEtBQUssTUFBTSxFQUFFO1lBQ3hFLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUNwQztJQUNMLENBQUM7SUFFRCxPQUFPO1FBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsa0JBQWtCLENBQUMsWUFBeUI7UUFDeEMsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLEVBQUU7WUFDbEQsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFBO1NBQ3ZDO2FBQU07WUFDSCxPQUFPLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUN4RDtJQUNMLENBQUM7SUFFRCw2QkFBNkI7UUFDekIsdUNBQVcsaUJBQWlCLEdBQUssMkJBQTJCLEVBQUU7SUFDbEUsQ0FBQzs7O1lBblJKLFNBQVMsU0FBQztnQkFDVixRQUFRLEVBQUUsMEJBQTBCO2dCQUNqQyxRQUFRLEVBQUUsV0FBVztnQkFDckIsaVVBQTBDOzthQUU3Qzs7O1lBMUJxQyxVQUFVOzs7eUJBdUMzQyxLQUFLLFNBQUMsWUFBWTtzREFVbEIsS0FBSyxTQUFDLHFCQUFxQjtpQ0FLM0IsS0FBSyxTQUFDLG9CQUFvQjs2Q0FVMUIsS0FBSyxTQUFDLFlBQVk7d0JBS2xCLEtBQUssU0FBQyxXQUFXO2tEQVVqQixLQUFLLFNBQUMsa0JBQWtCOzZCQUt4QixLQUFLLFNBQUMsZ0JBQWdCOytDQVV0QixLQUFLLFNBQUMsZUFBZTswQkFLckIsS0FBSyxTQUFDLGFBQWE7NkNBVW5CLEtBQUssU0FBQyxZQUFZO3dCQUtsQixLQUFLLFNBQUMsV0FBVzt1QkFTakIsS0FBSzt5QkFDTCxLQUFLO3VCQUNMLEtBQUs7K0JBQ0wsS0FBSztpQ0FDTCxLQUFLOzhCQUNMLEtBQUs7dUJBQ0wsS0FBSzswQkFDTCxLQUFLO3VCQUNMLEtBQUs7d0JBQ0wsS0FBSztvQkFDTCxLQUFLO3lCQUNMLEtBQUs7OEJBQ0wsS0FBSzs2QkFDTCxLQUFLOzJCQUVMLFdBQVcsU0FBQyxnQkFBZ0I7a0NBSTVCLFdBQVcsU0FBQyx3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXN9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHtQcm9wZXJ0aWVzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQge2RlZmF1bHRQcm9wZXJ0aWVzLCBiYWNrd2FyZENvbXBhdGliaWxpdHlQcm9wZXJ0aWVzfSBmcm9tICcuL3Byb3BlcnRpZXMnO1xyXG5pbXBvcnQge0l2eVBpbmNofSBmcm9tICcuL2l2eXBpbmNoJztcclxuXHJcbmludGVyZmFjZSBDb21wb25lbnRQcm9wZXJ0aWVzIGV4dGVuZHMgUHJvcGVydGllcyB7XHJcbiAgICBkaXNhYmxlZD86Ym9vbGVhbjtcclxuICAgIG92ZXJmbG93PzogXCJoaWRkZW5cIiB8IFwidmlzaWJsZVwiO1xyXG4gICAgZGlzYWJsZVpvb21Db250cm9sPzogXCJkaXNhYmxlXCIgfCBcIm5ldmVyXCIgfCBcImF1dG9cIjtcclxuICAgIGJhY2tncm91bmRDb2xvcj86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IF9kZWZhdWx0Q29tcG9uZW50UHJvcGVydGllczpDb21wb25lbnRQcm9wZXJ0aWVzID0ge1xyXG4gICAgb3ZlcmZsb3c6IFwiaGlkZGVuXCIsXHJcbiAgICBkaXNhYmxlWm9vbUNvbnRyb2w6IFwiYXV0b1wiLFxyXG4gICAgYmFja2dyb3VuZENvbG9yOiBcInJnYmEoMCwwLDAsMC44NSlcIlxyXG59XHJcblxyXG50eXBlIFByb3BlcnR5TmFtZSA9IGtleW9mIENvbXBvbmVudFByb3BlcnRpZXM7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHRzZWxlY3RvcjogJ3BpbmNoLXpvb20sIFtwaW5jaC16b29tXScsXHJcbiAgICBleHBvcnRBczogJ3BpbmNoWm9vbScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vcGluY2gtem9vbS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9waW5jaC16b29tLmNvbXBvbmVudC5zYXNzJ11cclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBQaW5jaFpvb21Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gICAgcGluY2hab29tOiBhbnk7XHJcbiAgICBfcHJvcGVydGllcyE6IENvbXBvbmVudFByb3BlcnRpZXM7XHJcbiAgICBkZWZhdWx0Q29tcG9uZW50UHJvcGVydGllcyE6IENvbXBvbmVudFByb3BlcnRpZXM7XHJcbiAgICB6b29tQ29udHJvbFBvc2l0aW9uQ2xhc3M6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuICAgIF90cmFuc2l0aW9uRHVyYXRpb24hOm51bWJlcjtcclxuICAgIF9kb3VibGVUYXAhOmJvb2xlYW47XHJcbiAgICBfZG91YmxlVGFwU2NhbGUhOm51bWJlcjtcclxuICAgIF9hdXRvWm9vbU91dCE6Ym9vbGVhbjtcclxuICAgIF9saW1pdFpvb20hOm51bWJlciB8IFwib3JpZ2luYWwgaW1hZ2Ugc2l6ZVwiO1xyXG5cclxuICAgIEBJbnB1dCgncHJvcGVydGllcycpIHNldCBwcm9wZXJ0aWVzKHZhbHVlOiBDb21wb25lbnRQcm9wZXJ0aWVzKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3Byb3BlcnRpZXMgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgcHJvcGVydGllcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvcGVydGllcztcclxuICAgIH1cclxuXHJcbiAgICAvLyB0cmFuc2l0aW9uRHVyYXRpb25cclxuICAgIEBJbnB1dCgndHJhbnNpdGlvbi1kdXJhdGlvbicpIHNldCB0cmFuc2l0aW9uRHVyYXRpb25CYWNrd2FyZENvbXBhdGliaWxpdHkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uRHVyYXRpb24gPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ3RyYW5zaXRpb25EdXJhdGlvbicpIHNldCB0cmFuc2l0aW9uRHVyYXRpb24odmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl90cmFuc2l0aW9uRHVyYXRpb24gPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgdHJhbnNpdGlvbkR1cmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc2l0aW9uRHVyYXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZG91YmxlVGFwXHJcbiAgICBASW5wdXQoJ2RvdWJsZS10YXAnKSBzZXQgZG91YmxlVGFwQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RvdWJsZVRhcCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIEBJbnB1dCgnZG91YmxlVGFwJykgc2V0IGRvdWJsZVRhcCh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9kb3VibGVUYXAgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgZG91YmxlVGFwKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9kb3VibGVUYXA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZG91YmxlVGFwU2NhbGVcclxuICAgIEBJbnB1dCgnZG91YmxlLXRhcC1zY2FsZScpIHNldCBkb3VibGVUYXBTY2FsZUJhY2t3YXJkQ29tcGF0aWJpbGl0eSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RvdWJsZVRhcFNjYWxlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdkb3VibGVUYXBTY2FsZScpIHNldCBkb3VibGVUYXBTY2FsZSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RvdWJsZVRhcFNjYWxlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGRvdWJsZVRhcFNjYWxlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9kb3VibGVUYXBTY2FsZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBhdXRvWm9vbU91dFxyXG4gICAgQElucHV0KCdhdXRvLXpvb20tb3V0Jykgc2V0IGF1dG9ab29tT3V0QmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dG9ab29tT3V0ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdhdXRvWm9vbU91dCcpIHNldCBhdXRvWm9vbU91dCh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRvWm9vbU91dCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBhdXRvWm9vbU91dCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXV0b1pvb21PdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gbGltaXRab29tXHJcbiAgICBASW5wdXQoJ2xpbWl0LXpvb20nKSBzZXQgbGltaXRab29tQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBudW1iZXIgfCBcIm9yaWdpbmFsIGltYWdlIHNpemVcIikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9saW1pdFpvb20gPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ2xpbWl0Wm9vbScpIHNldCBsaW1pdFpvb20odmFsdWU6IG51bWJlciB8IFwib3JpZ2luYWwgaW1hZ2Ugc2l6ZVwiKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpbWl0Wm9vbSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBsaW1pdFpvb20oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xpbWl0Wm9vbTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKSBkaXNhYmxlZCE6IGJvb2xlYW47XHJcbiAgICBASW5wdXQoKSBkaXNhYmxlUGFuITogYm9vbGVhbjtcclxuICAgIEBJbnB1dCgpIG92ZXJmbG93ITogXCJoaWRkZW5cIiB8IFwidmlzaWJsZVwiO1xyXG4gICAgQElucHV0KCkgem9vbUNvbnRyb2xTY2FsZSE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgpIGRpc2FibGVab29tQ29udHJvbCE6IFwiZGlzYWJsZVwiIHwgXCJuZXZlclwiIHwgXCJhdXRvXCI7XHJcbiAgICBASW5wdXQoKSBiYWNrZ3JvdW5kQ29sb3IhOiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBsaW1pdFBhbiE6IGJvb2xlYW47XHJcbiAgICBASW5wdXQoKSBtaW5QYW5TY2FsZSE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgpIG1pblNjYWxlITogbnVtYmVyO1xyXG4gICAgQElucHV0KCkgbGlzdGVuZXJzITogJ2F1dG8nIHwgJ21vdXNlIGFuZCB0b3VjaCc7XHJcbiAgICBASW5wdXQoKSB3aGVlbCE6IGJvb2xlYW47XHJcbiAgICBASW5wdXQoKSBhdXRvSGVpZ2h0ITogYm9vbGVhbjtcclxuICAgIEBJbnB1dCgpIHdoZWVsWm9vbUZhY3RvciE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgpIGRyYWdnYWJsZUltYWdlITogYm9vbGVhbjtcclxuXHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLm92ZXJmbG93JylcclxuICAgIGdldCBob3N0T3ZlcmZsb3coKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllc1snb3ZlcmZsb3cnXTtcclxuICAgIH1cclxuICAgIEBIb3N0QmluZGluZygnc3R5bGUuYmFja2dyb3VuZC1jb2xvcicpXHJcbiAgICBnZXQgaG9zdEJhY2tncm91bmRDb2xvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzWydiYWNrZ3JvdW5kQ29sb3InXTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaXNUb3VjaFNjcmVlbigpIHtcclxuICAgICAgICB2YXIgcHJlZml4ZXMgPSAnIC13ZWJraXQtIC1tb3otIC1vLSAtbXMtICcuc3BsaXQoJyAnKTtcclxuICAgICAgICB2YXIgbXEgPSBmdW5jdGlvbihxdWVyeTphbnkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5KS5tYXRjaGVzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCgnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaW5jbHVkZSB0aGUgJ2hlYXJ0eicgYXMgYSB3YXkgdG8gaGF2ZSBhIG5vbiBtYXRjaGluZyBNUSB0byBoZWxwIHRlcm1pbmF0ZSB0aGUgam9pblxyXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0LmlvL3Z6bkZIXHJcbiAgICAgICAgdmFyIHF1ZXJ5ID0gWycoJywgcHJlZml4ZXMuam9pbigndG91Y2gtZW5hYmxlZCksKCcpLCAnaGVhcnR6JywgJyknXS5qb2luKCcnKTtcclxuICAgICAgICByZXR1cm4gbXEocXVlcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBpc0RyYWdnaW5nKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBpbmNoWm9vbSA/IHRoaXMucGluY2hab29tLmlzRHJhZ2dpbmcoKSA6IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaXNEaXNhYmxlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzWydkaXNhYmxlZCddO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzY2FsZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5waW5jaFpvb20uc2NhbGU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlzWm9vbWVkSW4oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2NhbGUgPiAxO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzY2FsZUxldmVsKCkge1xyXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuc2NhbGUgLyB0aGlzLl96b29tQ29udHJvbFNjYWxlKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbWF4U2NhbGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGluY2hab29tLm1heFNjYWxlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBpc1pvb21MaW1pdFJlYWNoZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2NhbGUgPj0gdGhpcy5tYXhTY2FsZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3pvb21Db250cm9sU2NhbGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UHJvcGVydGllc1ZhbHVlKCd6b29tQ29udHJvbFNjYWxlJyk7XHJcbiAgICB9XHJcblxyXG4gICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgICAgICB0aGlzLmRlZmF1bHRDb21wb25lbnRQcm9wZXJ0aWVzID0gdGhpcy5nZXREZWZhdWx0Q29tcG9uZW50UHJvcGVydGllcygpO1xyXG4gICAgICAgIHRoaXMuYXBwbHlQcm9wZXJ0aWVzRGVmYXVsdCh0aGlzLmRlZmF1bHRDb21wb25lbnRQcm9wZXJ0aWVzLCB7fSk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKXtcclxuICAgICAgICB0aGlzLmluaXRQaW5jaFpvb20oKTtcclxuICAgICAgICBcclxuICAgICAgICAvKiBDYWxscyB0aGUgbWV0aG9kIHVudGlsIHRoZSBpbWFnZSBzaXplIGlzIGF2YWlsYWJsZSAqL1xyXG4gICAgICAgIHRoaXMuZGV0ZWN0TGltaXRab29tKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczpTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgbGV0IGNoYW5nZWRQcm9wZXJ0aWVzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKGNoYW5nZXMpO1xyXG4gICAgICAgIGNoYW5nZWRQcm9wZXJ0aWVzID0gdGhpcy5yZW5hbWVQcm9wZXJ0aWVzKGNoYW5nZWRQcm9wZXJ0aWVzKTtcclxuXHJcbiAgICAgICAgdGhpcy5hcHBseVByb3BlcnRpZXNEZWZhdWx0KHRoaXMuZGVmYXVsdENvbXBvbmVudFByb3BlcnRpZXMsIGNoYW5nZWRQcm9wZXJ0aWVzKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLmRlc3Ryb3koKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0UGluY2hab29tKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnByb3BlcnRpZXNbJ2Rpc2FibGVkJ10pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzWydlbGVtZW50J10gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcucGluY2gtem9vbS1jb250ZW50Jyk7XHJcbiAgICAgICAgdGhpcy5waW5jaFpvb20gPSBuZXcgSXZ5UGluY2godGhpcy5wcm9wZXJ0aWVzKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRQcm9wZXJ0aWVzKGNoYW5nZXM6U2ltcGxlQ2hhbmdlcykge1xyXG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOmFueSA9IHt9O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIGNoYW5nZXMpIHtcclxuICAgICAgICAgICAgaWYgKHByb3AgIT09ICdwcm9wZXJ0aWVzJyl7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzW3Byb3BdID0gY2hhbmdlc1twcm9wXS5jdXJyZW50VmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdwcm9wZXJ0aWVzJyl7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gY2hhbmdlc1twcm9wXS5jdXJyZW50VmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcmVuYW1lUHJvcGVydGllcyhwcm9wZXJ0aWVzOiBhbnkpIHtcclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHByb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgaWYgKGJhY2t3YXJkQ29tcGF0aWJpbGl0eVByb3BlcnRpZXNbcHJvcF0pIHtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXNbYmFja3dhcmRDb21wYXRpYmlsaXR5UHJvcGVydGllc1twcm9wXV0gPSBwcm9wZXJ0aWVzW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHByb3BlcnRpZXNbcHJvcF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9wZXJ0aWVzO1xyXG4gICAgfVxyXG5cclxuICAgIGFwcGx5UHJvcGVydGllc0RlZmF1bHQoZGVmYXVsdFByb3BlcnRpZXM6Q29tcG9uZW50UHJvcGVydGllcywgcHJvcGVydGllczpDb21wb25lbnRQcm9wZXJ0aWVzKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdFByb3BlcnRpZXMsIHByb3BlcnRpZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvZ2dsZVpvb20oKSB7XHJcbiAgICAgICAgdGhpcy5waW5jaFpvb20udG9nZ2xlWm9vbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzQ29udHJvbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnByb3BlcnRpZXNbJ2Rpc2FibGVab29tQ29udHJvbCddID09PSBcImRpc2FibGVcIikge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuICYmIHRoaXMucHJvcGVydGllc1snZGlzYWJsZVpvb21Db250cm9sJ10gPT09IFwiYXV0b1wiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGRldGVjdExpbWl0Wm9vbSgpIHtcclxuICAgICAgICBpZiAodGhpcy5waW5jaFpvb20pIHtcclxuICAgICAgICAgICAgdGhpcy5waW5jaFpvb20uZGV0ZWN0TGltaXRab29tKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5waW5jaFpvb20uZGVzdHJveSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFByb3BlcnRpZXNWYWx1ZShwcm9wZXJ0eU5hbWU6UHJvcGVydHlOYW1lKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcyAmJiB0aGlzLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0Q29tcG9uZW50UHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXREZWZhdWx0Q29tcG9uZW50UHJvcGVydGllcygpIHtcclxuICAgICAgICByZXR1cm4gey4uLmRlZmF1bHRQcm9wZXJ0aWVzLCAuLi5fZGVmYXVsdENvbXBvbmVudFByb3BlcnRpZXN9O1xyXG4gICAgfVxyXG59Il19