ng-devui
Version:
DevUI components based on Angular
242 lines • 42.4 kB
JavaScript
import { Injectable } from '@angular/core';
import { DocumentRef, WindowRef } from 'ng-devui/window-ref';
import * as i0 from "@angular/core";
import * as i1 from "ng-devui/window-ref";
export class PositionService {
constructor(documentRef, windowRef) {
this.documentRef = documentRef;
this.windowRef = windowRef;
}
position(element, round = true) {
let elPosition;
let parentOffset = { width: 0, height: 0, top: 0, bottom: 0, left: 0, right: 0 };
if (this.getStyle(element, 'position') === 'fixed') {
elPosition = element.getBoundingClientRect();
}
else {
const offsetParentEl = this.offsetParent(element);
elPosition = this.offset(element, false);
if (offsetParentEl !== this.documentRef.documentElement) {
parentOffset = this.offset(offsetParentEl, false);
}
parentOffset.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
parentOffset.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
}
elPosition.top -= parentOffset.top;
elPosition.bottom -= parentOffset.top;
elPosition.left -= parentOffset.left;
elPosition.right -= parentOffset.left;
if (round) {
elPosition.top = Math.round(elPosition.top);
elPosition.bottom = Math.round(elPosition.bottom);
elPosition.left = Math.round(elPosition.left);
elPosition.right = Math.round(elPosition.right);
}
return elPosition;
}
offset(element, round = true) {
const elBcr = element.getBoundingClientRect();
const viewportOffset = {
top: this.windowRef.pageYOffset - this.documentRef.documentElement.clientTop,
left: this.windowRef.pageXOffset - this.documentRef.documentElement.clientLeft,
};
const elOffset = {
height: elBcr.height || element.offsetHeight,
width: elBcr.width || element.offsetWidth,
top: elBcr.top + viewportOffset.top,
bottom: elBcr.bottom + viewportOffset.top,
left: elBcr.left + viewportOffset.left,
right: elBcr.right + viewportOffset.left,
};
if (round) {
elOffset.height = Math.round(elOffset.height);
elOffset.width = Math.round(elOffset.width);
elOffset.top = Math.round(elOffset.top);
elOffset.bottom = Math.round(elOffset.bottom);
elOffset.left = Math.round(elOffset.left);
elOffset.right = Math.round(elOffset.right);
}
return elOffset;
}
getScrollParent(element) {
let style = getComputedStyle(element);
const excludeStaticParent = style.position === 'absolute';
const overflowRegex = /(auto|scroll|overlay)/;
if (style.position === 'fixed') {
return this.documentRef.body;
}
for (let parent = element; (parent = parent.parentElement); parent.parentElement !== this.documentRef.body) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === 'static') {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
return parent;
}
}
return this.documentRef.body;
}
positionElements(hostElement, targetElement, placement, appendToBody) {
const hostElPosition = appendToBody ? this.offset(hostElement, false) : this.position(hostElement, false);
const shiftWidth = {
left: hostElPosition.left,
center: hostElPosition.left + hostElPosition.width / 2 - targetElement.offsetWidth / 2,
right: hostElPosition.left + hostElPosition.width,
};
const shiftHeight = {
top: hostElPosition.top,
center: hostElPosition.top + hostElPosition.height / 2 - targetElement.offsetHeight / 2,
bottom: hostElPosition.top + hostElPosition.height,
};
const targetElBCR = targetElement.getBoundingClientRect();
const targetElPosition = {
height: targetElBCR.height || targetElement.offsetHeight,
width: targetElBCR.width || targetElement.offsetWidth,
top: 0,
bottom: targetElBCR.height || targetElement.offsetHeight,
left: 0,
right: targetElBCR.width || targetElement.offsetWidth,
};
let placementPrimary;
let placementSecondary;
if (Array.isArray(placement)) {
const targetPlacement = this.getPlacement(hostElement, targetElement, placement);
placementPrimary = targetPlacement[0];
placementSecondary = targetPlacement[1];
}
else {
placementPrimary = placement?.split('-')[0] || 'top';
placementSecondary = placement?.split('-')[1] || 'center';
}
switch (placementPrimary) {
case 'top':
targetElPosition.top = hostElPosition.top - targetElement.offsetHeight;
targetElPosition.bottom += hostElPosition.top - targetElement.offsetHeight;
targetElPosition.left =
placementSecondary === 'right' ? shiftWidth[placementSecondary] - targetElement.offsetWidth : shiftWidth[placementSecondary];
targetElPosition.right += shiftWidth[placementSecondary];
break;
case 'bottom':
targetElPosition.top = shiftHeight[placementPrimary];
targetElPosition.bottom += shiftHeight[placementPrimary];
targetElPosition.left =
placementSecondary === 'right' ? shiftWidth[placementSecondary] - targetElement.offsetWidth : shiftWidth[placementSecondary];
targetElPosition.right += shiftWidth[placementSecondary];
break;
case 'left':
targetElPosition.top =
placementSecondary === 'bottom' ? shiftHeight[placementSecondary] - targetElement.offsetHeight : shiftHeight[placementSecondary];
targetElPosition.bottom += shiftHeight[placementSecondary];
targetElPosition.left = hostElPosition.left - targetElement.offsetWidth;
targetElPosition.right += hostElPosition.left - targetElement.offsetWidth;
break;
case 'right':
targetElPosition.top =
placementSecondary === 'bottom' ? shiftHeight[placementSecondary] - targetElement.offsetHeight : shiftHeight[placementSecondary];
targetElPosition.bottom += shiftHeight[placementSecondary];
targetElPosition.left = shiftWidth[placementPrimary];
targetElPosition.right += shiftWidth[placementPrimary];
break;
default:
}
targetElPosition.top = Math.round(targetElPosition.top);
targetElPosition.bottom = Math.round(targetElPosition.bottom);
targetElPosition.left = Math.round(targetElPosition.left);
targetElPosition.right = Math.round(targetElPosition.right);
targetElPosition.placementPrimary = placementPrimary;
targetElPosition.placementSecondary = placementSecondary;
return targetElPosition;
}
// 根据传入数组选取第一个合适的位置
getPlacement(hostElement, targetElement, placement) {
const hostElPosition = this.offset(hostElement, false);
const shiftWidth = {
left: hostElPosition.left,
center: hostElPosition.left + hostElPosition.width / 2 - targetElement.offsetWidth / 2,
right: hostElPosition.left + hostElPosition.width,
};
const shiftHeight = {
top: hostElPosition.top,
center: hostElPosition.top + hostElPosition.height / 2 - targetElement.offsetHeight / 2,
bottom: hostElPosition.top + hostElPosition.height,
};
let placementPrimary = placement[0].split('-')[0] || 'top';
let placementSecondary = placement[0].split('-')[1] || 'center';
for (let i = 0; i < placement.length; i++) {
const placementPrimaryTemp = placement[i].split('-')[0] || 'top';
const placementSecondaryTemp = placement[i].split('-')[1] || 'center';
let top;
let left;
switch (placementPrimaryTemp) {
case 'top':
top = hostElPosition.top - targetElement.offsetHeight;
left =
placementSecondaryTemp === 'right'
? shiftWidth[placementSecondaryTemp] - targetElement.offsetWidth
: shiftWidth[placementSecondary];
break;
case 'bottom':
top = shiftHeight[placementPrimaryTemp];
left =
placementSecondaryTemp === 'right'
? shiftWidth[placementSecondaryTemp] - targetElement.offsetWidth
: shiftWidth[placementSecondary];
break;
case 'left':
top =
placementSecondaryTemp === 'bottom'
? shiftHeight[placementSecondaryTemp] - targetElement.offsetHeight
: shiftHeight[placementSecondary];
left = hostElPosition.left - targetElement.offsetWidth;
break;
case 'right':
top =
placementSecondaryTemp === 'bottom'
? shiftHeight[placementSecondaryTemp] - targetElement.offsetHeight
: shiftHeight[placementSecondary];
left = shiftWidth[placementPrimaryTemp];
break;
default:
}
if (this.isInViewPort(targetElement, { offsetLeft: left, offsetTop: top })) {
placementPrimary = placement[i].split('-')[0] || 'top';
placementSecondary = placement[i].split('-')[1] || 'center';
return [placementPrimary, placementSecondary];
}
}
return [placementPrimary, placementSecondary];
}
isInViewPort(ele, { offsetLeft, offsetTop }) {
const targetElBCR = ele.getBoundingClientRect();
const viewPortHeight = this.windowRef.innerHeight || this.documentRef.documentElement.clientHeight || this.documentRef.body.clientHeight;
const viewPortWidth = this.windowRef.innerWidth || this.documentRef.documentElement.clientWidth || this.documentRef.body.clientWidth;
const height = targetElBCR.height || targetElBCR.offsetHeight;
const width = targetElBCR.width || targetElBCR.offsetWidth;
offsetTop = offsetTop || ele.offsetTop;
const scrollTop = this.documentRef.documentElement.scrollTop || this.documentRef.body.scrollTop;
const top = offsetTop - scrollTop;
offsetLeft = offsetLeft || ele.offsetLeft;
const scrollLeft = this.documentRef.documentElement.scrollLeft || this.documentRef.body.scrollLeft;
const left = offsetLeft - scrollLeft;
return top + height <= viewPortHeight && top > 0 && left + width <= viewPortWidth && left > 0;
}
getStyle(element, prop) {
return this.windowRef.getComputedStyle(element)[prop];
}
isStaticPositioned(element) {
return (this.getStyle(element, 'position') || 'static') === 'static';
}
offsetParent(element) {
let offsetParentEl = element.offsetParent || this.documentRef.documentElement;
while (offsetParentEl && offsetParentEl !== this.documentRef.documentElement && this.isStaticPositioned(offsetParentEl)) {
offsetParentEl = offsetParentEl.offsetParent;
}
return offsetParentEl || this.documentRef.documentElement;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService, deps: [{ token: i1.DocumentRef }, { token: i1.WindowRef }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PositionService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.DocumentRef }, { type: i1.WindowRef }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zaXRpb25pbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2RldnVpL3Bvc2l0aW9uL3Bvc2l0aW9uaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7QUFHN0QsTUFBTSxPQUFPLGVBQWU7SUFDMUIsWUFBb0IsV0FBd0IsRUFBVSxTQUFvQjtRQUF0RCxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQVc7SUFBRyxDQUFDO0lBRTlFLFFBQVEsQ0FBQyxPQUFvQixFQUFFLEtBQUssR0FBRyxJQUFJO1FBQ3pDLElBQUksVUFBVSxDQUFDO1FBQ2YsSUFBSSxZQUFZLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBRWpGLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDbkQsVUFBVSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9DLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVsRCxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsSUFBSSxjQUFjLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDeEQsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFFRCxZQUFZLENBQUMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQztZQUN4RSxZQUFZLENBQUMsSUFBSSxJQUFJLGNBQWMsQ0FBQyxVQUFVLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQztRQUM3RSxDQUFDO1FBRUQsVUFBVSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDO1FBQ25DLFVBQVUsQ0FBQyxNQUFNLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQztRQUN0QyxVQUFVLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDckMsVUFBVSxDQUFDLEtBQUssSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDO1FBRXRDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixVQUFVLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzVDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEQsVUFBVSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5QyxVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsTUFBTSxDQUFDLE9BQW9CLEVBQUUsS0FBSyxHQUFHLElBQUk7UUFDdkMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDOUMsTUFBTSxjQUFjLEdBQUc7WUFDckIsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLFNBQVM7WUFDNUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLFVBQVU7U0FDL0UsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFHO1lBQ2YsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLFlBQVk7WUFDNUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLElBQUksT0FBTyxDQUFDLFdBQVc7WUFDekMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLEdBQUcsY0FBYyxDQUFDLEdBQUc7WUFDbkMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUc7WUFDekMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUk7WUFDdEMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLElBQUk7U0FDekMsQ0FBQztRQUVGLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QyxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxDQUFD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LEdBQUcsVUFBVSxDQUFDO1FBRXJDLE9BQU8sR0FBRyxHQUFHLE1BQU0sSUFBSSxjQUFjLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsS0FBSyxJQUFJLGFBQWEsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2hHLENBQUM7SUFFTyxRQUFRLENBQUMsT0FBb0IsRUFBRSxJQUFZO1FBQ2pELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRU8sa0JBQWtCLENBQUMsT0FBb0I7UUFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLFFBQVEsQ0FBQztJQUN2RSxDQUFDO0lBRU8sWUFBWSxDQUFDLE9BQW9CO1FBQ3ZDLElBQUksY0FBYyxHQUFnQixPQUFPLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO1FBRTNGLE9BQU8sY0FBYyxJQUFJLGNBQWMsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUN4SCxjQUFjLEdBQWdCLGNBQWMsQ0FBQyxZQUFZLENBQUM7UUFDNUQsQ0FBQztRQUVELE9BQU8sY0FBYyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO0lBQzVELENBQUM7K0dBblFVLGVBQWU7bUhBQWYsZUFBZTs7NEZBQWYsZUFBZTtrQkFEM0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRG9jdW1lbnRSZWYsIFdpbmRvd1JlZiB9IGZyb20gJ25nLWRldnVpL3dpbmRvdy1yZWYnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgUG9zaXRpb25TZXJ2aWNlIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRvY3VtZW50UmVmOiBEb2N1bWVudFJlZiwgcHJpdmF0ZSB3aW5kb3dSZWY6IFdpbmRvd1JlZikge31cclxuXHJcbiAgcG9zaXRpb24oZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSkge1xyXG4gICAgbGV0IGVsUG9zaXRpb247XHJcbiAgICBsZXQgcGFyZW50T2Zmc2V0ID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCwgbGVmdDogMCwgcmlnaHQ6IDAgfTtcclxuXHJcbiAgICBpZiAodGhpcy5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PT0gJ2ZpeGVkJykge1xyXG4gICAgICBlbFBvc2l0aW9uID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldFBhcmVudEVsID0gdGhpcy5vZmZzZXRQYXJlbnQoZWxlbWVudCk7XHJcblxyXG4gICAgICBlbFBvc2l0aW9uID0gdGhpcy5vZmZzZXQoZWxlbWVudCwgZmFsc2UpO1xyXG5cclxuICAgICAgaWYgKG9mZnNldFBhcmVudEVsICE9PSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudCkge1xyXG4gICAgICAgIHBhcmVudE9mZnNldCA9IHRoaXMub2Zmc2V0KG9mZnNldFBhcmVudEVsLCBmYWxzZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHBhcmVudE9mZnNldC50b3AgKz0gb2Zmc2V0UGFyZW50RWwuY2xpZW50VG9wIC0gb2Zmc2V0UGFyZW50RWwuc2Nyb2xsVG9wO1xyXG4gICAgICBwYXJlbnRPZmZzZXQubGVmdCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRMZWZ0IC0gb2Zmc2V0UGFyZW50RWwuc2Nyb2xsTGVmdDtcclxuICAgIH1cclxuXHJcbiAgICBlbFBvc2l0aW9uLnRvcCAtPSBwYXJlbnRPZmZzZXQudG9wO1xyXG4gICAgZWxQb3NpdGlvbi5ib3R0b20gLT0gcGFyZW50T2Zmc2V0LnRvcDtcclxuICAgIGVsUG9zaXRpb24ubGVmdCAtPSBwYXJlbnRPZmZzZXQubGVmdDtcclxuICAgIGVsUG9zaXRpb24ucmlnaHQgLT0gcGFyZW50T2Zmc2V0LmxlZnQ7XHJcblxyXG4gICAgaWYgKHJvdW5kKSB7XHJcbiAgICAgIGVsUG9zaXRpb24udG9wID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLnRvcCk7XHJcbiAgICAgIGVsUG9zaXRpb24uYm90dG9tID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLmJvdHRvbSk7XHJcbiAgICAgIGVsUG9zaXRpb24ubGVmdCA9IE1hdGgucm91bmQoZWxQb3NpdGlvbi5sZWZ0KTtcclxuICAgICAgZWxQb3NpdGlvbi5yaWdodCA9IE1hdGgucm91bmQoZWxQb3NpdGlvbi5yaWdodCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsUG9zaXRpb247XHJcbiAgfVxyXG5cclxuICBvZmZzZXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSkge1xyXG4gICAgY29uc3QgZWxCY3IgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgdmlld3BvcnRPZmZzZXQgPSB7XHJcbiAgICAgIHRvcDogdGhpcy53aW5kb3dSZWYucGFnZVlPZmZzZXQgLSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5jbGllbnRUb3AsXHJcbiAgICAgIGxlZnQ6IHRoaXMud2luZG93UmVmLnBhZ2VYT2Zmc2V0IC0gdGhpcy5kb2N1bWVudFJlZi5kb2N1bWVudEVsZW1lbnQuY2xpZW50TGVmdCxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZWxPZmZzZXQgPSB7XHJcbiAgICAgIGhlaWdodDogZWxCY3IuaGVpZ2h0IHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICB3aWR0aDogZWxCY3Iud2lkdGggfHwgZWxlbWVudC5vZmZzZXRXaWR0aCxcclxuICAgICAgdG9wOiBlbEJjci50b3AgKyB2aWV3cG9ydE9mZnNldC50b3AsXHJcbiAgICAgIGJvdHRvbTogZWxCY3IuYm90dG9tICsgdmlld3BvcnRPZmZzZXQudG9wLFxyXG4gICAgICBsZWZ0OiBlbEJjci5sZWZ0ICsgdmlld3BvcnRPZmZzZXQubGVmdCxcclxuICAgICAgcmlnaHQ6IGVsQmNyLnJpZ2h0ICsgdmlld3BvcnRPZmZzZXQubGVmdCxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHJvdW5kKSB7XHJcbiAgICAgIGVsT2Zmc2V0LmhlaWdodCA9IE1hdGgucm91bmQoZWxPZmZzZXQuaGVpZ2h0KTtcclxuICAgICAgZWxPZmZzZXQud2lkdGggPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LndpZHRoKTtcclxuICAgICAgZWxPZmZzZXQudG9wID0gTWF0aC5yb3VuZChlbE9mZnNldC50b3ApO1xyXG4gICAgICBlbE9mZnNldC5ib3R0b20gPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmJvdHRvbSk7XHJcbiAgICAgIGVsT2Zmc2V0LmxlZnQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmxlZnQpO1xyXG4gICAgICBlbE9mZnNldC5yaWdodCA9IE1hdGgucm91bmQoZWxPZmZzZXQucmlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBlbE9mZnNldDtcclxuICB9XHJcblxyXG4gIGdldFNjcm9sbFBhcmVudChlbGVtZW50KSB7XHJcbiAgICBsZXQgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZXhjbHVkZVN0YXRpY1BhcmVudCA9IHN0eWxlLnBvc2l0aW9uID09PSAnYWJzb2x1dGUnO1xyXG4gICAgY29uc3Qgb3ZlcmZsb3dSZWdleCA9IC8oYXV0b3xzY3JvbGx8b3ZlcmxheSkvO1xyXG5cclxuICAgIGlmIChzdHlsZS5wb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xyXG4gICAgICByZXR1cm4gdGhpcy5kb2N1bWVudFJlZi5ib2R5O1xyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgcGFyZW50ID0gZWxlbWVudDsgKHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50KTsgcGFyZW50LnBhcmVudEVsZW1lbnQgIT09IHRoaXMuZG9jdW1lbnRSZWYuYm9keSkge1xyXG4gICAgICBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuICAgICAgaWYgKGV4Y2x1ZGVTdGF0aWNQYXJlbnQgJiYgc3R5bGUucG9zaXRpb24gPT09ICdzdGF0aWMnKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKG92ZXJmbG93UmVnZXgudGVzdChzdHlsZS5vdmVyZmxvdyArIHN0eWxlLm92ZXJmbG93WSArIHN0eWxlLm92ZXJmbG93WCkpIHtcclxuICAgICAgICByZXR1cm4gcGFyZW50O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuZG9jdW1lbnRSZWYuYm9keTtcclxuICB9XHJcblxyXG4gIHBvc2l0aW9uRWxlbWVudHMoaG9zdEVsZW1lbnQ6IEhUTUxFbGVtZW50LCB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCwgcGxhY2VtZW50OiBzdHJpbmcgfCBzdHJpbmdbXSwgYXBwZW5kVG9Cb2R5PzogYm9vbGVhbik6IGFueSB7XHJcbiAgICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IGFwcGVuZFRvQm9keSA/IHRoaXMub2Zmc2V0KGhvc3RFbGVtZW50LCBmYWxzZSkgOiB0aGlzLnBvc2l0aW9uKGhvc3RFbGVtZW50LCBmYWxzZSk7XHJcbiAgICBjb25zdCBzaGlmdFdpZHRoOiBhbnkgPSB7XHJcbiAgICAgIGxlZnQ6IGhvc3RFbFBvc2l0aW9uLmxlZnQsXHJcbiAgICAgIGNlbnRlcjogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoIC8gMiAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLyAyLFxyXG4gICAgICByaWdodDogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHNoaWZ0SGVpZ2h0OiBhbnkgPSB7XHJcbiAgICAgIHRvcDogaG9zdEVsUG9zaXRpb24udG9wLFxyXG4gICAgICBjZW50ZXI6IGhvc3RFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLmhlaWdodCAvIDIgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAvIDIsXHJcbiAgICAgIGJvdHRvbTogaG9zdEVsUG9zaXRpb24udG9wICsgaG9zdEVsUG9zaXRpb24uaGVpZ2h0LFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHRhcmdldEVsQkNSID0gdGFyZ2V0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBjb25zdCB0YXJnZXRFbFBvc2l0aW9uOiBhbnkgPSB7XHJcbiAgICAgIGhlaWdodDogdGFyZ2V0RWxCQ1IuaGVpZ2h0IHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICB3aWR0aDogdGFyZ2V0RWxCQ1Iud2lkdGggfHwgdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCxcclxuICAgICAgdG9wOiAwLFxyXG4gICAgICBib3R0b206IHRhcmdldEVsQkNSLmhlaWdodCB8fCB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCxcclxuICAgICAgbGVmdDogMCxcclxuICAgICAgcmlnaHQ6IHRhcmdldEVsQkNSLndpZHRoIHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGgsXHJcbiAgICB9O1xyXG5cclxuICAgIGxldCBwbGFjZW1lbnRQcmltYXJ5OiBzdHJpbmc7XHJcbiAgICBsZXQgcGxhY2VtZW50U2Vjb25kYXJ5OiBzdHJpbmc7XHJcblxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGxhY2VtZW50KSkge1xyXG4gICAgICBjb25zdCB0YXJnZXRQbGFjZW1lbnQgPSB0aGlzLmdldFBsYWNlbWVudChob3N0RWxlbWVudCwgdGFyZ2V0RWxlbWVudCwgcGxhY2VtZW50KTtcclxuICAgICAgcGxhY2VtZW50UHJpbWFyeSA9IHRhcmdldFBsYWNlbWVudFswXTtcclxuICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gdGFyZ2V0UGxhY2VtZW50WzFdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcGxhY2VtZW50UHJpbWFyeSA9IHBsYWNlbWVudD8uc3BsaXQoJy0nKVswXSB8fCAndG9wJztcclxuICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gcGxhY2VtZW50Py5zcGxpdCgnLScpWzFdIHx8ICdjZW50ZXInO1xyXG4gICAgfVxyXG5cclxuICAgIHN3aXRjaCAocGxhY2VtZW50UHJpbWFyeSkge1xyXG4gICAgY2FzZSAndG9wJzpcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi50b3AgPSBob3N0RWxQb3NpdGlvbi50b3AgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gaG9zdEVsUG9zaXRpb24udG9wIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAncmlnaHQnID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCA6IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCArPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnYm90dG9tJzpcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi50b3AgPSBzaGlmdEhlaWdodFtwbGFjZW1lbnRQcmltYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gc2hpZnRIZWlnaHRbcGxhY2VtZW50UHJpbWFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAncmlnaHQnID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCA6IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCArPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnbGVmdCc6XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24udG9wID1cclxuICAgICAgICBwbGFjZW1lbnRTZWNvbmRhcnkgPT09ICdib3R0b20nID8gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0IDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICB0YXJnZXRFbFBvc2l0aW9uLnRvcCA9XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID09PSAnYm90dG9tJyA/IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV0gLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCA6IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tICs9IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9IHNoaWZ0V2lkdGhbcGxhY2VtZW50UHJpbWFyeV07XHJcbiAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gc2hpZnRXaWR0aFtwbGFjZW1lbnRQcmltYXJ5XTtcclxuICAgICAgYnJlYWs7XHJcbiAgICBkZWZhdWx0OlxyXG4gICAgfVxyXG5cclxuICAgIHRhcmdldEVsUG9zaXRpb24udG9wID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLnRvcCk7XHJcbiAgICB0YXJnZXRFbFBvc2l0aW9uLmJvdHRvbSA9IE1hdGgucm91bmQodGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20pO1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLmxlZnQpO1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCA9IE1hdGgucm91bmQodGFyZ2V0RWxQb3NpdGlvbi5yaWdodCk7XHJcbiAgICB0YXJnZXRFbFBvc2l0aW9uLnBsYWNlbWVudFByaW1hcnkgPSBwbGFjZW1lbnRQcmltYXJ5O1xyXG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5wbGFjZW1lbnRTZWNvbmRhcnkgPSBwbGFjZW1lbnRTZWNvbmRhcnk7XHJcblxyXG4gICAgcmV0dXJuIHRhcmdldEVsUG9zaXRpb247XHJcbiAgfVxyXG5cclxuICAvLyDmoLnmja7kvKDlhaXmlbDnu4TpgInlj5bnrKzkuIDkuKrlkIjpgILnmoTkvY3nva5cclxuICBwcml2YXRlIGdldFBsYWNlbWVudChob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBwbGFjZW1lbnQ6IHN0cmluZ1tdKSB7XHJcbiAgICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IHRoaXMub2Zmc2V0KGhvc3RFbGVtZW50LCBmYWxzZSk7XHJcbiAgICBjb25zdCBzaGlmdFdpZHRoOiBhbnkgPSB7XHJcbiAgICAgIGxlZnQ6IGhvc3RFbFBvc2l0aW9uLmxlZnQsXHJcbiAgICAgIGNlbnRlcjogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoIC8gMiAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLyAyLFxyXG4gICAgICByaWdodDogaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IHNoaWZ0SGVpZ2h0OiBhbnkgPSB7XHJcbiAgICAgIHRvcDogaG9zdEVsUG9zaXRpb24udG9wLFxyXG4gICAgICBjZW50ZXI6IGhvc3RFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLmhlaWdodCAvIDIgLSB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAvIDIsXHJcbiAgICAgIGJvdHRvbTogaG9zdEVsUG9zaXRpb24udG9wICsgaG9zdEVsUG9zaXRpb24uaGVpZ2h0LFxyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgcGxhY2VtZW50UHJpbWFyeSA9IHBsYWNlbWVudFswXS5zcGxpdCgnLScpWzBdIHx8ICd0b3AnO1xyXG4gICAgbGV0IHBsYWNlbWVudFNlY29uZGFyeSA9IHBsYWNlbWVudFswXS5zcGxpdCgnLScpWzFdIHx8ICdjZW50ZXInO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGxhY2VtZW50Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IHBsYWNlbWVudFByaW1hcnlUZW1wID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMF0gfHwgJ3RvcCc7XHJcbiAgICAgIGNvbnN0IHBsYWNlbWVudFNlY29uZGFyeVRlbXAgPSBwbGFjZW1lbnRbaV0uc3BsaXQoJy0nKVsxXSB8fCAnY2VudGVyJztcclxuXHJcbiAgICAgIGxldCB0b3A7XHJcbiAgICAgIGxldCBsZWZ0O1xyXG4gICAgICBzd2l0Y2ggKHBsYWNlbWVudFByaW1hcnlUZW1wKSB7XHJcbiAgICAgIGNhc2UgJ3RvcCc6XHJcbiAgICAgICAgdG9wID0gaG9zdEVsUG9zaXRpb24udG9wIC0gdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgbGVmdCA9XHJcbiAgICAgICAgICBwbGFjZW1lbnRTZWNvbmRhcnlUZW1wID09PSAncmlnaHQnXHJcbiAgICAgICAgICAgID8gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGhcclxuICAgICAgICAgICAgOiBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2JvdHRvbSc6XHJcbiAgICAgICAgdG9wID0gc2hpZnRIZWlnaHRbcGxhY2VtZW50UHJpbWFyeVRlbXBdO1xyXG4gICAgICAgIGxlZnQgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ3JpZ2h0J1xyXG4gICAgICAgICAgICA/IHNoaWZ0V2lkdGhbcGxhY2VtZW50U2Vjb25kYXJ5VGVtcF0gLSB0YXJnZXRFbGVtZW50Lm9mZnNldFdpZHRoXHJcbiAgICAgICAgICAgIDogc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICB0b3AgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ2JvdHRvbSdcclxuICAgICAgICAgICAgPyBzaGlmdEhlaWdodFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0XHJcbiAgICAgICAgICAgIDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgICBsZWZ0ID0gaG9zdEVsUG9zaXRpb24ubGVmdCAtIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgICB0b3AgPVxyXG4gICAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5VGVtcCA9PT0gJ2JvdHRvbSdcclxuICAgICAgICAgICAgPyBzaGlmdEhlaWdodFtwbGFjZW1lbnRTZWNvbmRhcnlUZW1wXSAtIHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0XHJcbiAgICAgICAgICAgIDogc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcclxuICAgICAgICBsZWZ0ID0gc2hpZnRXaWR0aFtwbGFjZW1lbnRQcmltYXJ5VGVtcF07XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuaXNJblZpZXdQb3J0KHRhcmdldEVsZW1lbnQsIHsgb2Zmc2V0TGVmdDogbGVmdCwgb2Zmc2V0VG9wOiB0b3AgfSkpIHtcclxuICAgICAgICBwbGFjZW1lbnRQcmltYXJ5ID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMF0gfHwgJ3RvcCc7XHJcbiAgICAgICAgcGxhY2VtZW50U2Vjb25kYXJ5ID0gcGxhY2VtZW50W2ldLnNwbGl0KCctJylbMV0gfHwgJ2NlbnRlcic7XHJcbiAgICAgICAgcmV0dXJuIFtwbGFjZW1lbnRQcmltYXJ5LCBwbGFjZW1lbnRTZWNvbmRhcnldO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gW3BsYWNlbWVudFByaW1hcnksIHBsYWNlbWVudFNlY29uZGFyeV07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGlzSW5WaWV3UG9ydChlbGUsIHsgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pIHtcclxuICAgIGNvbnN0IHRhcmdldEVsQkNSID0gZWxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgdmlld1BvcnRIZWlnaHQgPVxyXG4gICAgICB0aGlzLndpbmRvd1JlZi5pbm5lckhlaWdodCB8fCB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LmNsaWVudEhlaWdodDtcclxuICAgIGNvbnN0IHZpZXdQb3J0V2lkdGggPSB0aGlzLndpbmRvd1JlZi5pbm5lcldpZHRoIHx8IHRoaXMuZG9jdW1lbnRSZWYuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoIHx8IHRoaXMuZG9jdW1lbnRSZWYuYm9keS5jbGllbnRXaWR0aDtcclxuICAgIGNvbnN0IGhlaWdodCA9IHRhcmdldEVsQkNSLmhlaWdodCB8fCB0YXJnZXRFbEJDUi5vZmZzZXRIZWlnaHQ7XHJcbiAgICBjb25zdCB3aWR0aCA9IHRhcmdldEVsQkNSLndpZHRoIHx8IHRhcmdldEVsQkNSLm9mZnNldFdpZHRoO1xyXG4gICAgb2Zmc2V0VG9wID0gb2Zmc2V0VG9wIHx8IGVsZS5vZmZzZXRUb3A7XHJcbiAgICBjb25zdCBzY3JvbGxUb3AgPSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LnNjcm9sbFRvcDtcclxuICAgIGNvbnN0IHRvcCA9IG9mZnNldFRvcCAtIHNjcm9sbFRvcDtcclxuICAgIG9mZnNldExlZnQgPSBvZmZzZXRMZWZ0IHx8IGVsZS5vZmZzZXRMZWZ0O1xyXG4gICAgY29uc3Qgc2Nyb2xsTGVmdCA9IHRoaXMuZG9jdW1lbnRSZWYuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgdGhpcy5kb2N1bWVudFJlZi5ib2R5LnNjcm9sbExlZnQ7XHJcbiAgICBjb25zdCBsZWZ0ID0gb2Zmc2V0TGVmdCAtIHNjcm9sbExlZnQ7XHJcblxyXG4gICAgcmV0dXJuIHRvcCArIGhlaWdodCA8PSB2aWV3UG9ydEhlaWdodCAmJiB0b3AgPiAwICYmIGxlZnQgKyB3aWR0aCA8PSB2aWV3UG9ydFdpZHRoICYmIGxlZnQgPiAwO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRTdHlsZShlbGVtZW50OiBIVE1MRWxlbWVudCwgcHJvcDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLndpbmRvd1JlZi5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpW3Byb3BdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc1N0YXRpY1Bvc2l0aW9uZWQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAodGhpcy5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSB8fCAnc3RhdGljJykgPT09ICdzdGF0aWMnO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvZmZzZXRQYXJlbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBsZXQgb2Zmc2V0UGFyZW50RWwgPSA8SFRNTEVsZW1lbnQ+ZWxlbWVudC5vZmZzZXRQYXJlbnQgfHwgdGhpcy5kb2N1bWVudFJlZi5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG4gICAgd2hpbGUgKG9mZnNldFBhcmVudEVsICYmIG9mZnNldFBhcmVudEVsICE9PSB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudCAmJiB0aGlzLmlzU3RhdGljUG9zaXRpb25lZChvZmZzZXRQYXJlbnRFbCkpIHtcclxuICAgICAgb2Zmc2V0UGFyZW50RWwgPSA8SFRNTEVsZW1lbnQ+b2Zmc2V0UGFyZW50RWwub2Zmc2V0UGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvZmZzZXRQYXJlbnRFbCB8fCB0aGlzLmRvY3VtZW50UmVmLmRvY3VtZW50RWxlbWVudDtcclxuICB9XHJcbn1cclxuIl19