@spartacus/storefront
Version:
Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.
261 lines • 34 kB
JavaScript
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@spartacus/core";
export class PositioningService {
constructor(winRef) {
this.winRef = winRef;
}
get allowedPlacements() {
return [
'top',
'bottom',
'left',
'right',
'top-left',
'top-right',
'bottom-left',
'bottom-right',
'left-top',
'left-bottom',
'right-top',
'right-bottom',
];
}
get placementSeparator() {
return /\s+/;
}
get window() {
return this.winRef.nativeWindow;
}
get document() {
return this.winRef.document;
}
getAllStyles(element) {
var _a;
return (_a = this.window) === null || _a === void 0 ? void 0 : _a.getComputedStyle(element);
}
getPositionStyleProperty(element) {
const styles = this.getAllStyles(element);
if (styles)
return styles['position'] || undefined;
}
isStaticPositioned(element) {
return (this.getPositionStyleProperty(element) || 'static') === 'static';
}
offsetParent(element) {
let offsetParentEl = element.offsetParent || this.document.documentElement;
while (offsetParentEl &&
offsetParentEl !== this.document.documentElement &&
this.isStaticPositioned(offsetParentEl)) {
offsetParentEl = offsetParentEl.offsetParent;
}
return offsetParentEl || this.document.documentElement;
}
position(element, round = true) {
let elPosition;
let parentOffset = {
width: 0,
height: 0,
top: 0,
bottom: 0,
left: 0,
right: 0,
};
if (this.getPositionStyleProperty(element) === 'fixed') {
elPosition = element.getBoundingClientRect();
elPosition = {
top: elPosition.top,
bottom: elPosition.bottom,
left: elPosition.left,
right: elPosition.right,
height: elPosition.height,
width: elPosition.width,
};
}
else {
const offsetParentEl = this.offsetParent(element);
elPosition = this.offset(element, false);
if (offsetParentEl !== this.document.documentElement) {
parentOffset = this.offset(offsetParentEl, false);
}
parentOffset.top += offsetParentEl.clientTop;
parentOffset.left += offsetParentEl.clientLeft;
}
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.window &&
this.window.pageYOffset - this.document.documentElement.clientTop) ||
0,
left: (this.window &&
this.window.pageXOffset - this.document.documentElement.clientLeft) ||
0,
};
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;
}
/*
Return false if the element to position is outside the viewport.
*/
_positionElements(hostElement, targetElement, placement, appendToBody) {
var _a, _b;
const [placementPrimary = 'top', placementSecondary = 'center'] = placement.split('-');
const hostElPosition = appendToBody
? this.offset(hostElement, false)
: this.position(hostElement, false);
const targetElStyles = this.getAllStyles(targetElement);
if (targetElStyles) {
const marginTop = parseFloat(targetElStyles.marginTop);
const marginBottom = parseFloat(targetElStyles.marginBottom);
const marginLeft = parseFloat(targetElStyles.marginLeft);
const marginRight = parseFloat(targetElStyles.marginRight);
let topPosition = 0;
let leftPosition = 0;
switch (placementPrimary) {
case 'top':
topPosition =
hostElPosition.top -
(targetElement.offsetHeight + marginTop + marginBottom);
break;
case 'bottom':
topPosition = hostElPosition.top + hostElPosition.height;
break;
case 'left':
leftPosition =
hostElPosition.left -
(targetElement.offsetWidth + marginLeft + marginRight);
break;
case 'right':
leftPosition = hostElPosition.left + hostElPosition.width;
break;
}
switch (placementSecondary) {
case 'top':
topPosition = hostElPosition.top;
break;
case 'bottom':
topPosition =
hostElPosition.top +
hostElPosition.height -
targetElement.offsetHeight;
break;
case 'left':
leftPosition = hostElPosition.left;
break;
case 'right':
leftPosition =
hostElPosition.left +
hostElPosition.width -
targetElement.offsetWidth;
break;
case 'center':
if (placementPrimary === 'top' || placementPrimary === 'bottom') {
leftPosition =
hostElPosition.left +
hostElPosition.width / 2 -
targetElement.offsetWidth / 2;
}
else {
topPosition =
hostElPosition.top +
hostElPosition.height / 2 -
targetElement.offsetHeight / 2;
}
break;
}
targetElement.style.transform = `translate(${Math.round(leftPosition)}px, ${Math.round(topPosition)}px)`;
// Check if the targetElement is inside the viewport
const targetElBCR = targetElement.getBoundingClientRect();
const html = this.document.documentElement;
const windowHeight = ((_a = this.window) === null || _a === void 0 ? void 0 : _a.innerHeight) || html.clientHeight;
const windowWidth = ((_b = this.window) === null || _b === void 0 ? void 0 : _b.innerWidth) || html.clientWidth;
return (targetElBCR.left >= 0 &&
targetElBCR.top >= 0 &&
targetElBCR.right <= windowWidth &&
targetElBCR.bottom <= windowHeight);
}
return false;
}
/*
* Accept the placement array and applies the appropriate placement dependent on the viewport.
* Returns the applied placement.
* In case of auto placement, placements are selected in order
* 'top', 'bottom', 'left', 'right',
* 'top-left', 'top-right',
* 'bottom-left', 'bottom-right',
* 'left-top', 'left-bottom',
* 'right-top', 'right-bottom'.
* */
positionElements(hostElement, targetElement, placement, appendToBody) {
const placementVals = Array.isArray(placement)
? placement
: placement.split(this.placementSeparator);
let hasAuto = placementVals.findIndex((val) => val === 'auto');
if (hasAuto >= 0) {
this.allowedPlacements.forEach((obj) => {
if (placementVals.find((val) => val.search('^' + obj) !== -1) == null) {
placementVals.splice(hasAuto++, 1, obj);
}
});
}
const style = targetElement.style;
style.position = 'absolute';
style.top = '0';
style.left = '0';
let testPlacement = 'auto';
let isInViewport = false;
for (testPlacement of placementVals) {
if (this._positionElements(hostElement, targetElement, testPlacement, appendToBody)) {
isInViewport = true;
break;
}
}
if (!isInViewport) {
this._positionElements(hostElement, targetElement, testPlacement, appendToBody);
}
return testPlacement;
}
getPositioningClass(position, autoPositioning) {
let positionClass = `${position || 'top'}`;
if (autoPositioning && positionClass !== 'auto') {
positionClass = `${positionClass} auto`;
}
return positionClass;
}
}
PositioningService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: PositioningService, deps: [{ token: i1.WindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
PositioningService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: PositioningService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: PositioningService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.WindowRef }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zaXRpb25pbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvc2hhcmVkL3NlcnZpY2VzL3Bvc2l0aW9uaW5nL3Bvc2l0aW9uaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBVTNDLE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsWUFBc0IsTUFBaUI7UUFBakIsV0FBTSxHQUFOLE1BQU0sQ0FBVztJQUFHLENBQUM7SUFFM0MsSUFBYyxpQkFBaUI7UUFDN0IsT0FBTztZQUNMLEtBQUs7WUFDTCxRQUFRO1lBQ1IsTUFBTTtZQUNOLE9BQU87WUFDUCxVQUFVO1lBQ1YsV0FBVztZQUNYLGFBQWE7WUFDYixjQUFjO1lBQ2QsVUFBVTtZQUNWLGFBQWE7WUFDYixXQUFXO1lBQ1gsY0FBYztTQUNmLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBYyxrQkFBa0I7UUFDOUIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsSUFBYyxNQUFNO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7SUFDbEMsQ0FBQztJQUVELElBQWMsUUFBUTtRQUNwQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQzlCLENBQUM7SUFFUyxZQUFZLENBQ3BCLE9BQW9COztRQUVwQixPQUFPLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVTLHdCQUF3QixDQUFDLE9BQW9CO1FBQ3JELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFMUMsSUFBSSxNQUFNO1lBQUUsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksU0FBUyxDQUFDO0lBQ3JELENBQUM7SUFFUyxrQkFBa0IsQ0FBQyxPQUFvQjtRQUMvQyxPQUFPLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLFFBQVEsQ0FBQztJQUMzRSxDQUFDO0lBRVMsWUFBWSxDQUFDLE9BQW9CO1FBQ3pDLElBQUksY0FBYyxHQUNILE9BQU8sQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFFckUsT0FDRSxjQUFjO1lBQ2QsY0FBYyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZTtZQUNoRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLEVBQ3ZDO1lBQ0EsY0FBYyxHQUFnQixjQUFjLENBQUMsWUFBWSxDQUFDO1NBQzNEO1FBRUQsT0FBTyxjQUFjLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7SUFDekQsQ0FBQztJQUVTLFFBQVEsQ0FBQyxPQUFvQixFQUFFLEtBQUssR0FBRyxJQUFJO1FBQ25ELElBQUksVUFBc0IsQ0FBQztRQUMzQixJQUFJLFlBQVksR0FBZTtZQUM3QixLQUFLLEVBQUUsQ0FBQztZQUNSLE1BQU0sRUFBRSxDQUFDO1lBQ1QsR0FBRyxFQUFFLENBQUM7WUFDTixNQUFNLEVBQUUsQ0FBQztZQUNULElBQUksRUFBRSxDQUFDO1lBQ1AsS0FBSyxFQUFFLENBQUM7U0FDVCxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDLEtBQUssT0FBTyxFQUFFO1lBQ3RELFVBQVUsR0FBRyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUM3QyxVQUFVLEdBQUc7Z0JBQ1gsR0FBRyxFQUFFLFVBQVUsQ0FBQyxHQUFHO2dCQUNuQixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtnQkFDckIsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO2dCQUN2QixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSzthQUN4QixDQUFDO1NBQ0g7YUFBTTtZQUNMLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFbEQsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLElBQUksY0FBYyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFO2dCQUNwRCxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDbkQ7WUFFRCxZQUFZLENBQUMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxTQUFTLENBQUM7WUFDN0MsWUFBWSxDQUFDLElBQUksSUFBSSxjQUFjLENBQUMsVUFBVSxDQUFDO1NBQ2hEO1FBRUQsVUFBVSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDO1FBQ25DLFVBQVUsQ0FBQyxNQUFNLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQztRQUN0QyxVQUFVLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDckMsVUFBVSxDQUFDLEtBQUssSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDO1FBRXRDLElBQUksS0FBSyxFQUFFO1lBQ1QsVUFBVSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxVQUFVLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xELFVBQVUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNqRDtRQUVELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFUyxNQUFNLENBQUMsT0FBb0IsRUFBRSxLQUFLLEdBQUcsSUFBSTtRQUNqRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUM5QyxNQUFNLGNBQWMsR0FBRztZQUNyQixHQUFHLEVBQ0QsQ0FBQyxJQUFJLENBQUMsTUFBTTtnQkFDVixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUM7Z0JBQ3BFLENBQUM7WUFDSCxJQUFJLEVBQ0YsQ0FBQyxJQUFJLENBQUMsTUFBTTtnQkFDVixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUM7Z0JBQ3JFLENBQUM7U0FDSixDQUFDO1FBRUYsTUFBTSxRQUFRLEdBQUc7WUFDZixNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsWUFBWTtZQUM1QyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsV0FBVztZQUN6QyxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUcsR0FBRyxjQUFjLENBQUMsR0FBRztZQUNuQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sR0FBRyxjQUFjLENBQUMsR0FBRztZQUN6QyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSTtZQUN0QyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsSUFBSTtTQUN6QyxDQUFDO1FBRUYsSUFBSSxLQUFLLEVBQUU7WUFDVCxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QyxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM3QztRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7TUFFRTtJQUNRLGlCQUFpQixDQUN6QixXQUF3QixFQUN4QixhQUEwQixFQUMxQixTQUFpQixFQUNqQixZQUFzQjs7UUFFdEIsTUFBTSxDQUFDLGdCQUFnQixHQUFHLEtBQUssRUFBRSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsR0FDN0QsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV2QixNQUFNLGNBQWMsR0FBRyxZQUFZO1lBQ2pDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUM7WUFDakMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFeEQsSUFBSSxjQUFjLEVBQUU7WUFDbEIsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN2RCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzdELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekQsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUUzRCxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7WUFDcEIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBRXJCLFFBQVEsZ0JBQWdCLEVBQUU7Z0JBQ3hCLEtBQUssS0FBSztvQkFDUixXQUFXO3dCQUNULGNBQWMsQ0FBQyxHQUFHOzRCQUNsQixDQUFDLGFBQWEsQ0FBQyxZQUFZLEdBQUcsU0FBUyxHQUFHLFlBQVksQ0FBQyxDQUFDO29CQUMxRCxNQUFNO2dCQUNSLEtBQUssUUFBUTtvQkFDWCxXQUFXLEdBQUcsY0FBYyxDQUFDLEdBQUcsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDO29CQUN6RCxNQUFNO2dCQUNSLEtBQUssTUFBTTtvQkFDVCxZQUFZO3dCQUNWLGNBQWMsQ0FBQyxJQUFJOzRCQUNuQixDQUFDLGFBQWEsQ0FBQyxXQUFXLEdBQUcsVUFBVSxHQUFHLFdBQVcsQ0FBQyxDQUFDO29CQUN6RCxNQUFNO2dCQUNSLEtBQUssT0FBTztvQkFDVixZQUFZLEdBQUcsY0FBYyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDO29CQUMxRCxNQUFNO2FBQ1Q7WUFFRCxRQUFRLGtCQUFrQixFQUFFO2dCQUMxQixLQUFLLEtBQUs7b0JBQ1IsV0FBVyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUM7b0JBQ2pDLE1BQU07Z0JBQ1IsS0FBSyxRQUFRO29CQUNYLFdBQVc7d0JBQ1QsY0FBYyxDQUFDLEdBQUc7NEJBQ2xCLGNBQWMsQ0FBQyxNQUFNOzRCQUNyQixhQUFhLENBQUMsWUFBWSxDQUFDO29CQUM3QixNQUFNO2dCQUNSLEtBQUssTUFBTTtvQkFDVCxZQUFZLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQztvQkFDbkMsTUFBTTtnQkFDUixLQUFLLE9BQU87b0JBQ1YsWUFBWTt3QkFDVixjQUFjLENBQUMsSUFBSTs0QkFDbkIsY0FBYyxDQUFDLEtBQUs7NEJBQ3BCLGFBQWEsQ0FBQyxXQUFXLENBQUM7b0JBQzVCLE1BQU07Z0JBQ1IsS0FBSyxRQUFRO29CQUNYLElBQUksZ0JBQWdCLEtBQUssS0FBSyxJQUFJLGdCQUFnQixLQUFLLFFBQVEsRUFBRTt3QkFDL0QsWUFBWTs0QkFDVixjQUFjLENBQUMsSUFBSTtnQ0FDbkIsY0FBYyxDQUFDLEtBQUssR0FBRyxDQUFDO2dDQUN4QixhQUFhLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztxQkFDakM7eUJBQU07d0JBQ0wsV0FBVzs0QkFDVCxjQUFjLENBQUMsR0FBRztnQ0FDbEIsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDO2dDQUN6QixhQUFhLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztxQkFDbEM7b0JBQ0QsTUFBTTthQUNUO1lBRUQsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsYUFBYSxJQUFJLENBQUMsS0FBSyxDQUNyRCxZQUFZLENBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFFckMsb0RBQW9EO1lBQ3BELE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzFELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO1lBQzNDLE1BQU0sWUFBWSxHQUFHLENBQUEsTUFBQSxJQUFJLENBQUMsTUFBTSwwQ0FBRSxXQUFXLEtBQUksSUFBSSxDQUFDLFlBQVksQ0FBQztZQUNuRSxNQUFNLFdBQVcsR0FBRyxDQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsVUFBVSxLQUFJLElBQUksQ0FBQyxXQUFXLENBQUM7WUFFaEUsT0FBTyxDQUNMLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQztnQkFDckIsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO2dCQUNwQixXQUFXLENBQUMsS0FBSyxJQUFJLFdBQVc7Z0JBQ2hDLFdBQVcsQ0FBQyxNQUFNLElBQUksWUFBWSxDQUNuQyxDQUFDO1NBQ0g7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7Ozs7Ozs7O1NBU0s7SUFDTCxnQkFBZ0IsQ0FDZCxXQUF3QixFQUN4QixhQUEwQixFQUMxQixTQUEwRCxFQUMxRCxZQUFzQjtRQUV0QixNQUFNLGFBQWEsR0FBMkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7WUFDcEUsQ0FBQyxDQUFDLFNBQVM7WUFDWCxDQUFDLENBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQTRCLENBQUM7UUFFekUsSUFBSSxPQUFPLEdBQUcsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELElBQUksT0FBTyxJQUFJLENBQUMsRUFBRTtZQUNoQixJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ3JDLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUU7b0JBQ3JFLGFBQWEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQXNCLENBQUMsQ0FBQztpQkFDNUQ7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNKO1FBRUQsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQztRQUNsQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUM1QixLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNoQixLQUFLLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUVqQixJQUFJLGFBQWEsR0FBb0IsTUFBTSxDQUFDO1FBQzVDLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztRQUN6QixLQUFLLGFBQWEsSUFBSSxhQUFhLEVBQUU7WUFDbkMsSUFDRSxJQUFJLENBQUMsaUJBQWlCLENBQ3BCLFdBQVcsRUFDWCxhQUFhLEVBQ2IsYUFBYSxFQUNiLFlBQVksQ0FDYixFQUNEO2dCQUNBLFlBQVksR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLE1BQU07YUFDUDtTQUNGO1FBRUQsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNqQixJQUFJLENBQUMsaUJBQWlCLENBQ3BCLFdBQVcsRUFDWCxhQUFhLEVBQ2IsYUFBYSxFQUNiLFlBQVksQ0FDYixDQUFDO1NBQ0g7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRUQsbUJBQW1CLENBQ2pCLFFBQTBCLEVBQzFCLGVBQXlCO1FBRXpCLElBQUksYUFBYSxHQUFHLEdBQUcsUUFBUSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzNDLElBQUksZUFBZSxJQUFJLGFBQWEsS0FBSyxNQUFNLEVBQUU7WUFDL0MsYUFBYSxHQUFHLEdBQUcsYUFBYSxPQUFPLENBQUM7U0FDekM7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDOzsrR0E5VFUsa0JBQWtCO21IQUFsQixrQkFBa0IsY0FGakIsTUFBTTsyRkFFUCxrQkFBa0I7a0JBSDlCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgV2luZG93UmVmIH0gZnJvbSAnQHNwYXJ0YWN1cy9jb3JlJztcbmltcG9ydCB7XG4gIFBvcG92ZXJQb3NpdGlvbixcbiAgUG9wb3ZlclBvc2l0aW9uQXJyYXksXG59IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvcG9wb3Zlci9wb3BvdmVyLm1vZGVsJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFBvc2l0aW9uaW5nU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCB3aW5SZWY6IFdpbmRvd1JlZikge31cblxuICBwcm90ZWN0ZWQgZ2V0IGFsbG93ZWRQbGFjZW1lbnRzKCk6IEFycmF5PFBvcG92ZXJQb3NpdGlvbkFycmF5PiB7XG4gICAgcmV0dXJuIFtcbiAgICAgICd0b3AnLFxuICAgICAgJ2JvdHRvbScsXG4gICAgICAnbGVmdCcsXG4gICAgICAncmlnaHQnLFxuICAgICAgJ3RvcC1sZWZ0JyxcbiAgICAgICd0b3AtcmlnaHQnLFxuICAgICAgJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICdib3R0b20tcmlnaHQnLFxuICAgICAgJ2xlZnQtdG9wJyxcbiAgICAgICdsZWZ0LWJvdHRvbScsXG4gICAgICAncmlnaHQtdG9wJyxcbiAgICAgICdyaWdodC1ib3R0b20nLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHBsYWNlbWVudFNlcGFyYXRvcigpOiBSZWdFeHAge1xuICAgIHJldHVybiAvXFxzKy87XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHdpbmRvdygpOiBXaW5kb3cgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLndpblJlZi5uYXRpdmVXaW5kb3c7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGRvY3VtZW50KCk6IERvY3VtZW50IHtcbiAgICByZXR1cm4gdGhpcy53aW5SZWYuZG9jdW1lbnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QWxsU3R5bGVzKFxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICk6IENTU1N0eWxlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLndpbmRvdz8uZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRQb3NpdGlvblN0eWxlUHJvcGVydHkoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0eWxlcyA9IHRoaXMuZ2V0QWxsU3R5bGVzKGVsZW1lbnQpO1xuXG4gICAgaWYgKHN0eWxlcykgcmV0dXJuIHN0eWxlc1sncG9zaXRpb24nXSB8fCB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNTdGF0aWNQb3NpdGlvbmVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmdldFBvc2l0aW9uU3R5bGVQcm9wZXJ0eShlbGVtZW50KSB8fCAnc3RhdGljJykgPT09ICdzdGF0aWMnO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9mZnNldFBhcmVudChlbGVtZW50OiBIVE1MRWxlbWVudCk6IEhUTUxFbGVtZW50IHtcbiAgICBsZXQgb2Zmc2V0UGFyZW50RWwgPVxuICAgICAgPEhUTUxFbGVtZW50PmVsZW1lbnQub2Zmc2V0UGFyZW50IHx8IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4gICAgd2hpbGUgKFxuICAgICAgb2Zmc2V0UGFyZW50RWwgJiZcbiAgICAgIG9mZnNldFBhcmVudEVsICE9PSB0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJlxuICAgICAgdGhpcy5pc1N0YXRpY1Bvc2l0aW9uZWQob2Zmc2V0UGFyZW50RWwpXG4gICAgKSB7XG4gICAgICBvZmZzZXRQYXJlbnRFbCA9IDxIVE1MRWxlbWVudD5vZmZzZXRQYXJlbnRFbC5vZmZzZXRQYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldFBhcmVudEVsIHx8IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBvc2l0aW9uKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCByb3VuZCA9IHRydWUpOiBDbGllbnRSZWN0IHtcbiAgICBsZXQgZWxQb3NpdGlvbjogQ2xpZW50UmVjdDtcbiAgICBsZXQgcGFyZW50T2Zmc2V0OiBDbGllbnRSZWN0ID0ge1xuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgfTtcblxuICAgIGlmICh0aGlzLmdldFBvc2l0aW9uU3R5bGVQcm9wZXJ0eShlbGVtZW50KSA9PT0gJ2ZpeGVkJykge1xuICAgICAgZWxQb3NpdGlvbiA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBlbFBvc2l0aW9uID0ge1xuICAgICAgICB0b3A6IGVsUG9zaXRpb24udG9wLFxuICAgICAgICBib3R0b206IGVsUG9zaXRpb24uYm90dG9tLFxuICAgICAgICBsZWZ0OiBlbFBvc2l0aW9uLmxlZnQsXG4gICAgICAgIHJpZ2h0OiBlbFBvc2l0aW9uLnJpZ2h0LFxuICAgICAgICBoZWlnaHQ6IGVsUG9zaXRpb24uaGVpZ2h0LFxuICAgICAgICB3aWR0aDogZWxQb3NpdGlvbi53aWR0aCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9mZnNldFBhcmVudEVsID0gdGhpcy5vZmZzZXRQYXJlbnQoZWxlbWVudCk7XG5cbiAgICAgIGVsUG9zaXRpb24gPSB0aGlzLm9mZnNldChlbGVtZW50LCBmYWxzZSk7XG5cbiAgICAgIGlmIChvZmZzZXRQYXJlbnRFbCAhPT0gdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgICAgcGFyZW50T2Zmc2V0ID0gdGhpcy5vZmZzZXQob2Zmc2V0UGFyZW50RWwsIGZhbHNlKTtcbiAgICAgIH1cblxuICAgICAgcGFyZW50T2Zmc2V0LnRvcCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRUb3A7XG4gICAgICBwYXJlbnRPZmZzZXQubGVmdCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRMZWZ0O1xuICAgIH1cblxuICAgIGVsUG9zaXRpb24udG9wIC09IHBhcmVudE9mZnNldC50b3A7XG4gICAgZWxQb3NpdGlvbi5ib3R0b20gLT0gcGFyZW50T2Zmc2V0LnRvcDtcbiAgICBlbFBvc2l0aW9uLmxlZnQgLT0gcGFyZW50T2Zmc2V0LmxlZnQ7XG4gICAgZWxQb3NpdGlvbi5yaWdodCAtPSBwYXJlbnRPZmZzZXQubGVmdDtcblxuICAgIGlmIChyb3VuZCkge1xuICAgICAgZWxQb3NpdGlvbi50b3AgPSBNYXRoLnJvdW5kKGVsUG9zaXRpb24udG9wKTtcbiAgICAgIGVsUG9zaXRpb24uYm90dG9tID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLmJvdHRvbSk7XG4gICAgICBlbFBvc2l0aW9uLmxlZnQgPSBNYXRoLnJvdW5kKGVsUG9zaXRpb24ubGVmdCk7XG4gICAgICBlbFBvc2l0aW9uLnJpZ2h0ID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLnJpZ2h0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxQb3NpdGlvbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBvZmZzZXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSk6IENsaWVudFJlY3Qge1xuICAgIGNvbnN0IGVsQmNyID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB2aWV3cG9ydE9mZnNldCA9IHtcbiAgICAgIHRvcDpcbiAgICAgICAgKHRoaXMud2luZG93ICYmXG4gICAgICAgICAgdGhpcy53aW5kb3cucGFnZVlPZmZzZXQgLSB0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRUb3ApIHx8XG4gICAgICAgIDAsXG4gICAgICBsZWZ0OlxuICAgICAgICAodGhpcy53aW5kb3cgJiZcbiAgICAgICAgICB0aGlzLndpbmRvdy5wYWdlWE9mZnNldCAtIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudExlZnQpIHx8XG4gICAgICAgIDAsXG4gICAgfTtcblxuICAgIGNvbnN0IGVsT2Zmc2V0ID0ge1xuICAgICAgaGVpZ2h0OiBlbEJjci5oZWlnaHQgfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQsXG4gICAgICB3aWR0aDogZWxCY3Iud2lkdGggfHwgZWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICAgIHRvcDogZWxCY3IudG9wICsgdmlld3BvcnRPZmZzZXQudG9wLFxuICAgICAgYm90dG9tOiBlbEJjci5ib3R0b20gKyB2aWV3cG9ydE9mZnNldC50b3AsXG4gICAgICBsZWZ0OiBlbEJjci5sZWZ0ICsgdmlld3BvcnRPZmZzZXQubGVmdCxcbiAgICAgIHJpZ2h0OiBlbEJjci5yaWdodCArIHZpZXdwb3J0T2Zmc2V0LmxlZnQsXG4gICAgfTtcblxuICAgIGlmIChyb3VuZCkge1xuICAgICAgZWxPZmZzZXQuaGVpZ2h0ID0gTWF0aC5yb3VuZChlbE9mZnNldC5oZWlnaHQpO1xuICAgICAgZWxPZmZzZXQud2lkdGggPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LndpZHRoKTtcbiAgICAgIGVsT2Zmc2V0LnRvcCA9IE1hdGgucm91bmQoZWxPZmZzZXQudG9wKTtcbiAgICAgIGVsT2Zmc2V0LmJvdHRvbSA9IE1hdGgucm91bmQoZWxPZmZzZXQuYm90dG9tKTtcbiAgICAgIGVsT2Zmc2V0LmxlZnQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmxlZnQpO1xuICAgICAgZWxPZmZzZXQucmlnaHQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LnJpZ2h0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxPZmZzZXQ7XG4gIH1cblxuICAvKlxuICAgIFJldHVybiBmYWxzZSBpZiB0aGUgZWxlbWVudCB0byBwb3NpdGlvbiBpcyBvdXRzaWRlIHRoZSB2aWV3cG9ydC5cbiAgKi9cbiAgcHJvdGVjdGVkIF9wb3NpdGlvbkVsZW1lbnRzKFxuICAgIGhvc3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICBwbGFjZW1lbnQ6IHN0cmluZyxcbiAgICBhcHBlbmRUb0JvZHk/OiBib29sZWFuXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IFtwbGFjZW1lbnRQcmltYXJ5ID0gJ3RvcCcsIHBsYWNlbWVudFNlY29uZGFyeSA9ICdjZW50ZXInXSA9XG4gICAgICBwbGFjZW1lbnQuc3BsaXQoJy0nKTtcblxuICAgIGNvbnN0IGhvc3RFbFBvc2l0aW9uID0gYXBwZW5kVG9Cb2R5XG4gICAgICA/IHRoaXMub2Zmc2V0KGhvc3RFbGVtZW50LCBmYWxzZSlcbiAgICAgIDogdGhpcy5wb3NpdGlvbihob3N0RWxlbWVudCwgZmFsc2UpO1xuICAgIGNvbnN0IHRhcmdldEVsU3R5bGVzID0gdGhpcy5nZXRBbGxTdHlsZXModGFyZ2V0RWxlbWVudCk7XG5cbiAgICBpZiAodGFyZ2V0RWxTdHlsZXMpIHtcbiAgICAgIGNvbnN0IG1hcmdpblRvcCA9IHBhcnNlRmxvYXQodGFyZ2V0RWxTdHlsZXMubWFyZ2luVG9wKTtcbiAgICAgIGNvbnN0IG1hcmdpbkJvdHRvbSA9IHBhcnNlRmxvYXQodGFyZ2V0RWxTdHlsZXMubWFyZ2luQm90dG9tKTtcbiAgICAgIGNvbnN0IG1hcmdpbkxlZnQgPSBwYXJzZUZsb2F0KHRhcmdldEVsU3R5bGVzLm1hcmdpbkxlZnQpO1xuICAgICAgY29uc3QgbWFyZ2luUmlnaHQgPSBwYXJzZUZsb2F0KHRhcmdldEVsU3R5bGVzLm1hcmdpblJpZ2h0KTtcblxuICAgICAgbGV0IHRvcFBvc2l0aW9uID0gMDtcbiAgICAgIGxldCBsZWZ0UG9zaXRpb24gPSAwO1xuXG4gICAgICBzd2l0Y2ggKHBsYWNlbWVudFByaW1hcnkpIHtcbiAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICB0b3BQb3NpdGlvbiA9XG4gICAgICAgICAgICBob3N0RWxQb3NpdGlvbi50b3AgLVxuICAgICAgICAgICAgKHRhcmdldEVsZW1lbnQub2Zmc2V0SGVpZ2h0ICsgbWFyZ2luVG9wICsgbWFyZ2luQm90dG9tKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICB0b3BQb3NpdGlvbiA9IGhvc3RFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLmhlaWdodDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgbGVmdFBvc2l0aW9uID1cbiAgICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLmxlZnQgLVxuICAgICAgICAgICAgKHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggKyBtYXJnaW5MZWZ0ICsgbWFyZ2luUmlnaHQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgbGVmdFBvc2l0aW9uID0gaG9zdEVsUG9zaXRpb24ubGVmdCArIGhvc3RFbFBvc2l0aW9uLndpZHRoO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHBsYWNlbWVudFNlY29uZGFyeSkge1xuICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgIHRvcFBvc2l0aW9uID0gaG9zdEVsUG9zaXRpb24udG9wO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgIHRvcFBvc2l0aW9uID1cbiAgICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLnRvcCArXG4gICAgICAgICAgICBob3N0RWxQb3NpdGlvbi5oZWlnaHQgLVxuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgIGxlZnRQb3NpdGlvbiA9IGhvc3RFbFBvc2l0aW9uLmxlZnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICBsZWZ0UG9zaXRpb24gPVxuICAgICAgICAgICAgaG9zdEVsUG9zaXRpb24ubGVmdCArXG4gICAgICAgICAgICBob3N0RWxQb3NpdGlvbi53aWR0aCAtXG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgIGlmIChwbGFjZW1lbnRQcmltYXJ5ID09PSAndG9wJyB8fCBwbGFjZW1lbnRQcmltYXJ5ID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgbGVmdFBvc2l0aW9uID1cbiAgICAgICAgICAgICAgaG9zdEVsUG9zaXRpb24ubGVmdCArXG4gICAgICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLndpZHRoIC8gMiAtXG4gICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLyAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b3BQb3NpdGlvbiA9XG4gICAgICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLnRvcCArXG4gICAgICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLmhlaWdodCAvIDIgLVxuICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAvIDI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICB0YXJnZXRFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUoJHtNYXRoLnJvdW5kKFxuICAgICAgICBsZWZ0UG9zaXRpb25cbiAgICAgICl9cHgsICR7TWF0aC5yb3VuZCh0b3BQb3NpdGlvbil9cHgpYDtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIHRhcmdldEVsZW1lbnQgaXMgaW5zaWRlIHRoZSB2aWV3cG9ydFxuICAgICAgY29uc3QgdGFyZ2V0RWxCQ1IgPSB0YXJnZXRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgaHRtbCA9IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgY29uc3Qgd2luZG93SGVpZ2h0ID0gdGhpcy53aW5kb3c/LmlubmVySGVpZ2h0IHx8IGh0bWwuY2xpZW50SGVpZ2h0O1xuICAgICAgY29uc3Qgd2luZG93V2lkdGggPSB0aGlzLndpbmRvdz8uaW5uZXJXaWR0aCB8fCBodG1sLmNsaWVudFdpZHRoO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICB0YXJnZXRFbEJDUi5sZWZ0ID49IDAgJiZcbiAgICAgICAgdGFyZ2V0RWxCQ1IudG9wID49IDAgJiZcbiAgICAgICAgdGFyZ2V0RWxCQ1IucmlnaHQgPD0gd2luZG93V2lkdGggJiZcbiAgICAgICAgdGFyZ2V0RWxCQ1IuYm90dG9tIDw9IHdpbmRvd0hlaWdodFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKlxuICAgKiBBY2NlcHQgdGhlIHBsYWNlbWVudCBhcnJheSBhbmQgYXBwbGllcyB0aGUgYXBwcm9wcmlhdGUgcGxhY2VtZW50IGRlcGVuZGVudCBvbiB0aGUgdmlld3BvcnQuXG4gICAqIFJldHVybnMgdGhlIGFwcGxpZWQgcGxhY2VtZW50LlxuICAgKiBJbiBjYXNlIG9mIGF1dG8gcGxhY2VtZW50LCBwbGFjZW1lbnRzIGFyZSBzZWxlY3RlZCBpbiBvcmRlclxuICAgKiAgICd0b3AnLCAnYm90dG9tJywgJ2xlZnQnLCAncmlnaHQnLFxuICAgKiAgICd0b3AtbGVmdCcsICd0b3AtcmlnaHQnLFxuICAgKiAgICdib3R0b20tbGVmdCcsICdib3R0b20tcmlnaHQnLFxuICAgKiAgICdsZWZ0LXRvcCcsICdsZWZ0LWJvdHRvbScsXG4gICAqICAgJ3JpZ2h0LXRvcCcsICdyaWdodC1ib3R0b20nLlxuICAgKiAqL1xuICBwb3NpdGlvbkVsZW1lbnRzKFxuICAgIGhvc3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICBwbGFjZW1lbnQ6IHN0cmluZyB8IFBvcG92ZXJQb3NpdGlvbiB8IFBvcG92ZXJQb3NpdGlvbkFycmF5LFxuICAgIGFwcGVuZFRvQm9keT86IGJvb2xlYW5cbiAgKTogUG9wb3ZlclBvc2l0aW9uIHtcbiAgICBjb25zdCBwbGFjZW1lbnRWYWxzOiBBcnJheTxQb3BvdmVyUG9zaXRpb24+ID0gQXJyYXkuaXNBcnJheShwbGFjZW1lbnQpXG4gICAgICA/IHBsYWNlbWVudFxuICAgICAgOiAocGxhY2VtZW50LnNwbGl0KHRoaXMucGxhY2VtZW50U2VwYXJhdG9yKSBhcyBBcnJheTxQb3BvdmVyUG9zaXRpb24+KTtcblxuICAgIGxldCBoYXNBdXRvID0gcGxhY2VtZW50VmFscy5maW5kSW5kZXgoKHZhbCkgPT4gdmFsID09PSAnYXV0bycpO1xuICAgIGlmIChoYXNBdXRvID49IDApIHtcbiAgICAgIHRoaXMuYWxsb3dlZFBsYWNlbWVudHMuZm9yRWFjaCgob2JqKSA9PiB7XG4gICAgICAgIGlmIChwbGFjZW1lbnRWYWxzLmZpbmQoKHZhbCkgPT4gdmFsLnNlYXJjaCgnXicgKyBvYmopICE9PSAtMSkgPT0gbnVsbCkge1xuICAgICAgICAgIHBsYWNlbWVudFZhbHMuc3BsaWNlKGhhc0F1dG8rKywgMSwgb2JqIGFzIFBvcG92ZXJQb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHN0eWxlID0gdGFyZ2V0RWxlbWVudC5zdHlsZTtcbiAgICBzdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgc3R5bGUudG9wID0gJzAnO1xuICAgIHN0eWxlLmxlZnQgPSAnMCc7XG5cbiAgICBsZXQgdGVzdFBsYWNlbWVudDogUG9wb3ZlclBvc2l0aW9uID0gJ2F1dG8nO1xuICAgIGxldCBpc0luVmlld3BvcnQgPSBmYWxzZTtcbiAgICBmb3IgKHRlc3RQbGFjZW1lbnQgb2YgcGxhY2VtZW50VmFscykge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLl9wb3NpdGlvbkVsZW1lbnRzKFxuICAgICAgICAgIGhvc3RFbGVtZW50LFxuICAgICAgICAgIHRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgdGVzdFBsYWNlbWVudCxcbiAgICAgICAgICBhcHBlbmRUb0JvZHlcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIGlzSW5WaWV3cG9ydCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghaXNJblZpZXdwb3J0KSB7XG4gICAgICB0aGlzLl9wb3NpdGlvbkVsZW1lbnRzKFxuICAgICAgICBob3N0RWxlbWVudCxcbiAgICAgICAgdGFyZ2V0RWxlbWVudCxcbiAgICAgICAgdGVzdFBsYWNlbWVudCxcbiAgICAgICAgYXBwZW5kVG9Cb2R5XG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0ZXN0UGxhY2VtZW50O1xuICB9XG5cbiAgZ2V0UG9zaXRpb25pbmdDbGFzcyhcbiAgICBwb3NpdGlvbj86IFBvcG92ZXJQb3NpdGlvbixcbiAgICBhdXRvUG9zaXRpb25pbmc/OiBib29sZWFuXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IHBvc2l0aW9uQ2xhc3MgPSBgJHtwb3NpdGlvbiB8fCAndG9wJ31gO1xuICAgIGlmIChhdXRvUG9zaXRpb25pbmcgJiYgcG9zaXRpb25DbGFzcyAhPT0gJ2F1dG8nKSB7XG4gICAgICBwb3NpdGlvbkNsYXNzID0gYCR7cG9zaXRpb25DbGFzc30gYXV0b2A7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvc2l0aW9uQ2xhc3M7XG4gIH1cbn1cbiJdfQ==