stimulsoft-forms
Version:
Stimulsoft PDF Forms
192 lines • 32.8 kB
JavaScript
import { Injectable } from "@angular/core";
import { StiFormPageElement } from "../elements/StiFormPageElement";
import StiRectangleGeometry from "../properties/StiRectangleGeometry";
import * as i0 from "@angular/core";
import * as i1 from "../services/model.service";
import * as i2 from "../services/sti-name.service";
export default class StiRectangleGeometryLayout {
constructor(model, nameService) {
this.model = model;
this.nameService = nameService;
}
insertElement(newElement, contentAreaWidth = 0) {
// let fixedGeometry = this.fixForInsert(newElement.geometry);
let parentElement = this.model.getElementPage(newElement) ?? this.model.getElementPanel(newElement);
let otherElements = Array.from(parentElement.elements);
otherElements.splice(otherElements.indexOf(newElement), 1);
if (newElement) {
let fixedGeometry = newElement.geometry;
this.insertFixed(fixedGeometry, newElement, otherElements, contentAreaWidth);
}
}
isHigherThan(left, right) {
return left.bottom <= right.y;
}
isHigherThan2(left, right) {
return left.bottom - left.height / 2 <= right.y;
}
removeElement(elementToRemove, otherElements) {
let elementsAbove = [];
let elementsBelow = [];
for (let element of otherElements) {
if (this.isHigherThan(element.geometry, elementToRemove.geometry)) {
elementsAbove.push(element);
}
else {
elementsBelow.push(element);
}
}
this.snapBelowsToAboves(elementsBelow, elementsAbove);
}
changeElementGeometry(elementToChange, otherElements, contentAreaWidth = 0) {
let fixedGeometry = elementToChange.geometry;
this.insertFixed(fixedGeometry, elementToChange, otherElements, contentAreaWidth);
}
fitWidth(fixedGeometry, otherElements, contentAreaWidth) {
if (contentAreaWidth > 0) {
let right = contentAreaWidth;
let rect = new StiRectangleGeometry(fixedGeometry.width - fixedGeometry.minWidth, fixedGeometry.height / 2);
rect.x = fixedGeometry.x + fixedGeometry.minWidth;
rect.y = fixedGeometry.y;
otherElements.forEach((element) => {
if (element.geometry.intersectWith(rect)) {
right = Math.min(right, element.geometry.x);
}
});
let newWidth = fixedGeometry.width - (fixedGeometry.right - right);
if (newWidth + StiRectangleGeometry.DELTA > fixedGeometry.minWidth &&
newWidth <= fixedGeometry.width + StiRectangleGeometry.DELTA) {
fixedGeometry.width = newWidth;
}
}
}
insertFixed(fixedGeometry, elementToInsert, otherElements, contentAreaWidth) {
let elementsAbove = [];
let elementsBelow = [];
for (let element of otherElements) {
if (this.isHigherThan2(element.geometry, fixedGeometry)) {
elementsAbove.push(element);
}
else {
elementsBelow.push(element);
}
}
this.fitWidth(fixedGeometry, otherElements, contentAreaWidth);
let snappedNewGeometry = this.snapOneToAboves(fixedGeometry, elementsAbove, true);
elementToInsert.geometry = snappedNewGeometry;
elementsAbove.push(elementToInsert);
this.moveDown(elementsBelow, 2 * snappedNewGeometry.height);
this.snapBelowsToAboves(elementsBelow, elementsAbove);
this.fitWidth(snappedNewGeometry, otherElements, contentAreaWidth);
}
snapOneToAboves(geometry, elementsAboveToSnap, canShrink = false) {
let elementsExcatlyAbove = elementsAboveToSnap.filter((element) => element.geometry.xProjectionIntersectsWith(geometry));
if (elementsExcatlyAbove.length > 0) {
let max = elementsExcatlyAbove.reduce((acc, curr) => (acc.geometry.bottom > curr.geometry.bottom ? acc : curr));
return geometry.withY(max.geometry.bottom);
}
else
return geometry.withY(0);
}
moveDown(elementsToMoveDown, distance) {
for (let element of elementsToMoveDown) {
element.geometry = element.geometry.withY(element.geometry.y + distance);
}
}
snapBelowsToAboves(belows, aboves) {
belows.sort(function (left, right) {
let difference = left.geometry.y - right.geometry.y;
if (difference < StiRectangleGeometry.DELTA) {
return -1;
}
else if (difference > StiRectangleGeometry.DELTA) {
return 1;
}
else {
return 0;
}
});
for (let element of belows) {
let snappedFromBelow = this.snapOneToAboves(element.geometry, aboves);
element.geometry = snappedFromBelow;
aboves.push(element);
}
}
getFreeToBottomResizeArea(currentResizeElement, otherElements) {
let currentContainer = this.model.getElementPage(currentResizeElement) ?? this.model.getElementPanel(currentResizeElement);
let geometry = currentResizeElement.geometry;
let bottomElements = otherElements?.filter((element) => element.y >= geometry.bottom);
let elementsExcatlyBelow = bottomElements?.filter((element) => element.geometry.xProjectionIntersectsWith(geometry));
let bottomPoints = elementsExcatlyBelow?.map((element) => {
return element.geometry.bottom;
});
let topPoints = elementsExcatlyBelow?.map((element) => {
return element.geometry.y;
});
let maxBottomPoint = Math.max(...bottomPoints);
let minTopPoint = Math.min(...topPoints);
let bottomElementsHeight = maxBottomPoint - minTopPoint;
return (currentContainer.contentAreaHeight -
geometry.bottom -
(elementsExcatlyBelow.length > 0 ? bottomElementsHeight : 0));
}
checkOutputs(usedPage) {
let outputElements = [];
let summaryHeight = 0;
usedPage?.elements.forEach((element) => {
if (element.geometry.bottom > usedPage.contentAreaHeight) {
outputElements.push(element);
}
});
if (outputElements.length > 0) {
outputElements.forEach((element) => {
summaryHeight += element.height;
usedPage.elements.splice(usedPage.elements.indexOf(element), 1);
this.removeElement(element, usedPage.elements);
});
if (this.model.form.pages[this.model.form.pages.indexOf(usedPage) + 1]) {
let nextPage = this.model.form.pages[this.model.form.pages.indexOf(usedPage) + 1];
if (nextPage.contentAreaHeight - Math.max(...nextPage.elements.map((element) => element.geometry.bottom)) >
summaryHeight) {
let currentBottomPoint = 0;
outputElements.forEach((element, index) => {
nextPage.elements.splice(index, 0, element);
element.y = currentBottomPoint;
this.insertElement(element);
currentBottomPoint += element.height;
});
}
else {
let page1 = new StiFormPageElement(this.model.form);
page1.name = this.nameService.getElementName(page1);
this.model.form.pages.splice(this.model.form.pages.indexOf(nextPage), 0, page1);
let currentBottomPoint = 0;
outputElements.forEach((element, index) => {
page1.elements.splice(index, 0, element);
element.y = currentBottomPoint;
this.insertElement(element);
currentBottomPoint += element.height;
});
}
}
else {
let page1 = new StiFormPageElement(this.model.form);
page1.name = this.nameService.getElementName(page1);
this.model.form.pages.push(page1);
let currentBottomPoint = 0;
outputElements.forEach((element, index) => {
page1.elements.splice(index, 0, element);
element.y = currentBottomPoint;
this.insertElement(element);
currentBottomPoint += element.geometry.bottom;
});
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout, deps: [{ token: i1.StiModelService }, { token: i2.StiNameService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiRectangleGeometryLayout, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.StiModelService }, { type: i2.StiNameService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdGltdWxzb2Z0LWZvcm1zL3NyYy9saWIvY29tcHV0ZWQvU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLG9CQUFvQixNQUFNLG9DQUFvQyxDQUFDOzs7O0FBS3RFLE1BQU0sQ0FBQyxPQUFPLE9BQU8sMEJBQTBCO0lBRzdDLFlBQW1CLEtBQXNCLEVBQVMsV0FBMkI7UUFBMUQsVUFBSyxHQUFMLEtBQUssQ0FBaUI7UUFBUyxnQkFBVyxHQUFYLFdBQVcsQ0FBZ0I7SUFBSSxDQUFDO0lBQzNFLGFBQWEsQ0FBQyxVQUEwQixFQUFFLG1CQUEyQixDQUFDO1FBQzNFLDhEQUE4RDtRQUM5RCxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwRyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2RCxhQUFhLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDeEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQy9FLENBQUM7SUFD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QixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM1QixrQkFBa0IsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztnQkFDaEQsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7K0dBN01rQiwwQkFBMEI7bUhBQTFCLDBCQUEwQjs7NEZBQTFCLDBCQUEwQjtrQkFEOUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBTdGlGb3JtRWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9iYXNlL1N0aUZvcm1FbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aUZvcm1QYWdlRWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9TdGlGb3JtUGFnZUVsZW1lbnRcIjtcclxuaW1wb3J0IFN0aVJlY3RhbmdsZUdlb21ldHJ5IGZyb20gXCIuLi9wcm9wZXJ0aWVzL1N0aVJlY3RhbmdsZUdlb21ldHJ5XCI7XHJcbmltcG9ydCB7IFN0aU1vZGVsU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9tb2RlbC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aU5hbWVTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3N0aS1uYW1lLnNlcnZpY2VcIjtcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXQge1xyXG4gIHB1YmxpYyB3aWR0aDogbnVtYmVyO1xyXG4gIHB1YmxpYyBoZWlnaHQ6IG51bWJlcjtcclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbW9kZWw6IFN0aU1vZGVsU2VydmljZSwgcHVibGljIG5hbWVTZXJ2aWNlOiBTdGlOYW1lU2VydmljZSkgeyB9XHJcbiAgcHVibGljIGluc2VydEVsZW1lbnQobmV3RWxlbWVudDogU3RpRm9ybUVsZW1lbnQsIGNvbnRlbnRBcmVhV2lkdGg6IG51bWJlciA9IDApIHtcclxuICAgIC8vIGxldCBmaXhlZEdlb21ldHJ5ID0gdGhpcy5maXhGb3JJbnNlcnQobmV3RWxlbWVudC5nZW9tZXRyeSk7XHJcbiAgICBsZXQgcGFyZW50RWxlbWVudCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudFBhZ2UobmV3RWxlbWVudCkgPz8gdGhpcy5tb2RlbC5nZXRFbGVtZW50UGFuZWwobmV3RWxlbWVudCk7XHJcbiAgICBsZXQgb3RoZXJFbGVtZW50cyA9IEFycmF5LmZyb20ocGFyZW50RWxlbWVudC5lbGVtZW50cyk7XHJcbiAgICBvdGhlckVsZW1lbnRzLnNwbGljZShvdGhlckVsZW1lbnRzLmluZGV4T2YobmV3RWxlbWVudCksIDEpO1xyXG4gICAgaWYgKG5ld0VsZW1lbnQpIHtcclxuICAgICAgbGV0IGZpeGVkR2VvbWV0cnkgPSBuZXdFbGVtZW50Lmdlb21ldHJ5O1xyXG4gICAgICB0aGlzLmluc2VydEZpeGVkKGZpeGVkR2VvbWV0cnksIG5ld0VsZW1lbnQsIG90aGVyRWxlbWVudHMsIGNvbnRlbnRBcmVhV2lkdGgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGlzSGlnaGVyVGhhbihsZWZ0OiBTdGlSZWN0YW5nbGVHZW9tZXRyeSwgcmlnaHQ6IFN0aVJlY3RhbmdsZUdlb21ldHJ5KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gbGVmdC5ib3R0b20gPD0gcmlnaHQueTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpc0hpZ2hlclRoYW4yKGxlZnQ6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LCByaWdodDogU3RpUmVjdGFuZ2xlR2VvbWV0cnkpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBsZWZ0LmJvdHRvbSAtIGxlZnQuaGVpZ2h0IC8gMiA8PSByaWdodC55O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlbW92ZUVsZW1lbnQoZWxlbWVudFRvUmVtb3ZlOiBTdGlGb3JtRWxlbWVudCwgb3RoZXJFbGVtZW50czogU3RpRm9ybUVsZW1lbnRbXSkge1xyXG4gICAgbGV0IGVsZW1lbnRzQWJvdmU6IFN0aUZvcm1FbGVtZW50W10gPSBbXTtcclxuICAgIGxldCBlbGVtZW50c0JlbG93OiBTdGlGb3JtRWxlbWVudFtdID0gW107XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIG90aGVyRWxlbWVudHMpIHtcclxuICAgICAgaWYgKHRoaXMuaXNIaWdoZXJUaGFuKGVsZW1lbnQuZ2VvbWV0cnksIGVsZW1lbnRUb1JlbW92ZS5nZW9tZXRyeSkpIHtcclxuICAgICAgICBlbGVtZW50c0Fib3ZlLnB1c2goZWxlbWVudCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZWxlbWVudHNCZWxvdy5wdXNoKGVsZW1lbnQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLnNuYXBCZWxvd3NUb0Fib3ZlcyhlbGVtZW50c0JlbG93LCBlbGVtZW50c0Fib3ZlKTtcclxuICB9XHJcbiAgcHVibGljIGNoYW5nZUVsZW1lbnRHZW9tZXRyeShcclxuICAgIGVsZW1lbnRUb0NoYW5nZTogU3RpRm9ybUVsZW1lbnQsXHJcbiAgICBvdGhlckVsZW1lbnRzOiBTdGlGb3JtRWxlbWVudFtdLFxyXG4gICAgY29udGVudEFyZWFXaWR0aDogbnVtYmVyID0gMFxyXG4gICkge1xyXG4gICAgbGV0IGZpeGVkR2VvbWV0cnkgPSBlbGVtZW50VG9DaGFuZ2UuZ2VvbWV0cnk7XHJcbiAgICB0aGlzLmluc2VydEZpeGVkKGZpeGVkR2VvbWV0cnksIGVsZW1lbnRUb0NoYW5nZSwgb3RoZXJFbGVtZW50cywgY29udGVudEFyZWFXaWR0aCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZpdFdpZHRoKGZpeGVkR2VvbWV0cnk6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LCBvdGhlckVsZW1lbnRzOiBTdGlGb3JtRWxlbWVudFtdLCBjb250ZW50QXJlYVdpZHRoOiBudW1iZXIpIHtcclxuICAgIGlmIChjb250ZW50QXJlYVdpZHRoID4gMCkge1xyXG4gICAgICBsZXQgcmlnaHQgPSBjb250ZW50QXJlYVdpZHRoO1xyXG4gICAgICBsZXQgcmVjdCA9IG5ldyBTdGlSZWN0YW5nbGVHZW9tZXRyeShmaXhlZEdlb21ldHJ5LndpZHRoIC0gZml4ZWRHZW9tZXRyeS5taW5XaWR0aCwgZml4ZWRHZW9tZXRyeS5oZWlnaHQgLyAyKTtcclxuICAgICAgcmVjdC54ID0gZml4ZWRHZW9tZXRyeS54ICsgZml4ZWRHZW9tZXRyeS5taW5XaWR0aDtcclxuICAgICAgcmVjdC55ID0gZml4ZWRHZW9tZXRyeS55O1xyXG5cclxuICAgICAgb3RoZXJFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQuZ2VvbWV0cnkuaW50ZXJzZWN0V2l0aChyZWN0KSkge1xyXG4gICAgICAgICAgcmlnaHQgPSBNYXRoLm1pbihyaWdodCwgZWxlbWVudC5nZW9tZXRyeS54KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbGV0IG5ld1dpZHRoID0gZml4ZWRHZW9tZXRyeS53aWR0aCAtIChmaXhlZEdlb21ldHJ5LnJpZ2h0IC0gcmlnaHQpO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgbmV3V2lkdGggKyBTdGlSZWN0YW5nbGVHZW9tZXRyeS5ERUxUQSA+IGZpeGVkR2VvbWV0cnkubWluV2lkdGggJiZcclxuICAgICAgICBuZXdXaWR0aCA8PSBmaXhlZEdlb21ldHJ5LndpZHRoICsgU3RpUmVjdGFuZ2xlR2VvbWV0cnkuREVMVEFcclxuICAgICAgKSB7XHJcbiAgICAgICAgZml4ZWRHZW9tZXRyeS53aWR0aCA9IG5ld1dpZHRoO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluc2VydEZpeGVkKFxyXG4gICAgZml4ZWRHZW9tZXRyeTogU3RpUmVjdGFuZ2xlR2VvbWV0cnksXHJcbiAgICBlbGVtZW50VG9JbnNlcnQ6IFN0aUZvcm1FbGVtZW50LFxyXG4gICAgb3RoZXJFbGVtZW50czogU3RpRm9ybUVsZW1lbnRbXSxcclxuICAgIGNvbnRlbnRBcmVhV2lkdGg6IG51bWJlclxyXG4gICkge1xyXG4gICAgbGV0IGVsZW1lbnRzQWJvdmU6IFN0aUZvcm1FbGVtZW50W10gPSBbXTtcclxuICAgIGxldCBlbGVtZW50c0JlbG93OiBTdGlGb3JtRWxlbWVudFtdID0gW107XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIG90aGVyRWxlbWVudHMpIHtcclxuICAgICAgaWYgKHRoaXMuaXNIaWdoZXJUaGFuMihlbGVtZW50Lmdlb21ldHJ5LCBmaXhlZEdlb21ldHJ5KSkge1xyXG4gICAgICAgIGVsZW1lbnRzQWJvdmUucHVzaChlbGVtZW50KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlbGVtZW50c0JlbG93LnB1c2goZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmZpdFdpZHRoKGZpeGVkR2VvbWV0cnksIG90aGVyRWxlbWVudHMsIGNvbnRlbnRBcmVhV2lkdGgpO1xyXG5cclxuICAgIGxldCBzbmFwcGVkTmV3R2VvbWV0cnkgPSB0aGlzLnNuYXBPbmVUb0Fib3ZlcyhmaXhlZEdlb21ldHJ5LCBlbGVtZW50c0Fib3ZlLCB0cnVlKTtcclxuICAgIGVsZW1lbnRUb0luc2VydC5nZW9tZXRyeSA9IHNuYXBwZWROZXdHZW9tZXRyeTtcclxuICAgIGVsZW1lbnRzQWJvdmUucHVzaChlbGVtZW50VG9JbnNlcnQpO1xyXG4gICAgdGhpcy5tb3ZlRG93bihlbGVtZW50c0JlbG93LCAyICogc25hcHBlZE5ld0dlb21ldHJ5LmhlaWdodCk7XHJcbiAgICB0aGlzLnNuYXBCZWxvd3NUb0Fib3ZlcyhlbGVtZW50c0JlbG93LCBlbGVtZW50c0Fib3ZlKTtcclxuXHJcbiAgICB0aGlzLmZpdFdpZHRoKHNuYXBwZWROZXdHZW9tZXRyeSwgb3RoZXJFbGVtZW50cywgY29udGVudEFyZWFXaWR0aCk7XHJcbiAgfVxyXG4gIHByaXZhdGUgc25hcE9uZVRvQWJvdmVzKFxyXG4gICAgZ2VvbWV0cnk6IFN0aVJlY3RhbmdsZUdlb21ldHJ5LFxyXG4gICAgZWxlbWVudHNBYm92ZVRvU25hcDogU3RpRm9ybUVsZW1lbnRbXSxcclxuICAgIGNhblNocmluayA9IGZhbHNlXHJcbiAgKTogU3RpUmVjdGFuZ2xlR2VvbWV0cnkge1xyXG4gICAgbGV0IGVsZW1lbnRzRXhjYXRseUFib3ZlID0gZWxlbWVudHNBYm92ZVRvU25hcC5maWx0ZXIoKGVsZW1lbnQpID0+XHJcbiAgICAgIGVsZW1lbnQuZ2VvbWV0cnkueFByb2plY3Rpb25JbnRlcnNlY3RzV2l0aChnZW9tZXRyeSlcclxuICAgICk7XHJcbiAgICBpZiAoZWxlbWVudHNFeGNhdGx5QWJvdmUubGVuZ3RoID4gMCkge1xyXG4gICAgICBsZXQgbWF4ID0gZWxlbWVudHNFeGNhdGx5QWJvdmUucmVkdWNlKChhY2MsIGN1cnIpID0+IChhY2MuZ2VvbWV0cnkuYm90dG9tID4gY3Vyci5nZW9tZXRyeS5ib3R0b20gPyBhY2MgOiBjdXJyKSk7XHJcbiAgICAgIHJldHVybiBnZW9tZXRyeS53aXRoWShtYXguZ2VvbWV0cnkuYm90dG9tKTtcclxuICAgIH0gZWxzZSByZXR1cm4gZ2VvbWV0cnkud2l0aFkoMCk7XHJcbiAgfVxyXG4gIHByaXZhdGUgbW92ZURvd24oZWxlbWVudHNUb01vdmVEb3duOiBTdGlGb3JtRWxlbWVudFtdLCBkaXN0YW5jZTogbnVtYmVyKSB7XHJcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIGVsZW1lbnRzVG9Nb3ZlRG93bikge1xyXG4gICAgICBlbGVtZW50Lmdlb21ldHJ5ID0gZWxlbWVudC5nZW9tZXRyeS53aXRoWShlbGVtZW50Lmdlb21ldHJ5LnkgKyBkaXN0YW5jZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHByaXZhdGUgc25hcEJlbG93c1RvQWJvdmVzKGJlbG93czogU3RpRm9ybUVsZW1lbnRbXSwgYWJvdmVzOiBTdGlGb3JtRWxlbWVudFtdKSB7XHJcbiAgICBiZWxvd3Muc29ydChmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHtcclxuICAgICAgbGV0IGRpZmZlcmVuY2UgPSBsZWZ0Lmdlb21ldHJ5LnkgLSByaWdodC5nZW9tZXRyeS55O1xyXG4gICAgICBpZiAoZGlmZmVyZW5jZSA8IFN0aVJlY3RhbmdsZUdlb21ldHJ5LkRFTFRBKSB7XHJcbiAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICB9IGVsc2UgaWYgKGRpZmZlcmVuY2UgPiBTdGlSZWN0YW5nbGVHZW9tZXRyeS5ERUxUQSkge1xyXG4gICAgICAgIHJldHVybiAxO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGZvciAobGV0IGVsZW1lbnQgb2YgYmVsb3dzKSB7XHJcbiAgICAgIGxldCBzbmFwcGVkRnJvbUJlbG93ID0gdGhpcy5zbmFwT25lVG9BYm92ZXMoZWxlbWVudC5nZW9tZXRyeSwgYWJvdmVzKTtcclxuICAgICAgZWxlbWVudC5nZW9tZXRyeSA9IHNuYXBwZWRGcm9tQmVsb3c7XHJcbiAgICAgIGFib3Zlcy5wdXNoKGVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuICBwdWJsaWMgZ2V0RnJlZVRvQm90dG9tUmVzaXplQXJlYShjdXJyZW50UmVzaXplRWxlbWVudDogU3RpRm9ybUVsZW1lbnQsIG90aGVyRWxlbWVudHM6IFN0aUZvcm1FbGVtZW50W10pOiBudW1iZXIge1xyXG4gICAgbGV0IGN1cnJlbnRDb250YWluZXIgPVxyXG4gICAgICB0aGlzLm1vZGVsLmdldEVsZW1lbnRQYWdlKGN1cnJlbnRSZXNpemVFbGVtZW50KSA/PyB0aGlzLm1vZGVsLmdldEVsZW1lbnRQYW5lbChjdXJyZW50UmVzaXplRWxlbWVudCk7XHJcbiAgICBsZXQgZ2VvbWV0cnkgPSBjdXJyZW50UmVzaXplRWxlbWVudC5nZW9tZXRyeTtcclxuICAgIGxldCBib3R0b21FbGVtZW50cyA9IG90aGVyRWxlbWVudHM/LmZpbHRlcigoZWxlbWVudCkgPT4gZWxlbWVudC55ID49IGdlb21ldHJ5LmJvdHRvbSk7XHJcbiAgICBsZXQgZWxlbWVudHNFeGNhdGx5QmVsb3cgPSBib3R0b21FbGVtZW50cz8uZmlsdGVyKChlbGVtZW50KSA9PlxyXG4gICAgICBlbGVtZW50Lmdlb21ldHJ5LnhQcm9qZWN0aW9uSW50ZXJzZWN0c1dpdGgoZ2VvbWV0cnkpXHJcbiAgICApO1xyXG4gICAgbGV0IGJvdHRvbVBvaW50cyA9IGVsZW1lbnRzRXhjYXRseUJlbG93Py5tYXAoKGVsZW1lbnQpID0+IHtcclxuICAgICAgcmV0dXJuIGVsZW1lbnQuZ2VvbWV0cnkuYm90dG9tO1xyXG4gICAgfSk7XHJcbiAgICBsZXQgdG9wUG9pbnRzID0gZWxlbWVudHNFeGNhdGx5QmVsb3c/Lm1hcCgoZWxlbWVudCkgPT4ge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC5nZW9tZXRyeS55O1xyXG4gICAgfSk7XHJcbiAgICBsZXQgbWF4Qm90dG9tUG9pbnQgPSBNYXRoLm1heCguLi5ib3R0b21Qb2ludHMpO1xyXG4gICAgbGV0IG1pblRvcFBvaW50ID0gTWF0aC5taW4oLi4udG9wUG9pbnRzKTtcclxuICAgIGxldCBib3R0b21FbGVtZW50c0hlaWdodCA9IG1heEJvdHRvbVBvaW50IC0gbWluVG9wUG9pbnQ7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgY3VycmVudENvbnRhaW5lci5jb250ZW50QXJlYUhlaWdodCAtXHJcbiAgICAgIGdlb21ldHJ5LmJvdHRvbSAtXHJcbiAgICAgIChlbGVtZW50c0V4Y2F0bHlCZWxvdy5sZW5ndGggPiAwID8gYm90dG9tRWxlbWVudHNIZWlnaHQgOiAwKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjaGVja091dHB1dHModXNlZFBhZ2U6IFN0aUZvcm1QYWdlRWxlbWVudCkge1xyXG4gICAgbGV0IG91dHB1dEVsZW1lbnRzID0gW107XHJcbiAgICBsZXQgc3VtbWFyeUhlaWdodDogbnVtYmVyID0gMDtcclxuICAgIHVzZWRQYWdlPy5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgIGlmIChlbGVtZW50Lmdlb21ldHJ5LmJvdHRvbSA+IHVzZWRQYWdlLmNvbnRlbnRBcmVhSGVpZ2h0KSB7XHJcbiAgICAgICAgb3V0cHV0RWxlbWVudHMucHVzaChlbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICBpZiAob3V0cHV0RWxlbWVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBvdXRwdXRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgc3VtbWFyeUhlaWdodCArPSBlbGVtZW50LmhlaWdodDtcclxuICAgICAgICB1c2VkUGFnZS5lbGVtZW50cy5zcGxpY2UodXNlZFBhZ2UuZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSwgMSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVFbGVtZW50KGVsZW1lbnQsIHVzZWRQYWdlLmVsZW1lbnRzKTtcclxuICAgICAgfSk7XHJcbiAgICAgIGlmICh0aGlzLm1vZGVsLmZvcm0ucGFnZXNbdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLmluZGV4T2YodXNlZFBhZ2UpICsgMV0pIHtcclxuICAgICAgICBsZXQgbmV4dFBhZ2UgPSB0aGlzLm1vZGVsLmZvcm0ucGFnZXNbdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLmluZGV4T2YodXNlZFBhZ2UpICsgMV07XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgbmV4dFBhZ2UuY29udGVudEFyZWFIZWlnaHQgLSBNYXRoLm1heCguLi5uZXh0UGFnZS5lbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZ2VvbWV0cnkuYm90dG9tKSkgPlxyXG4gICAgICAgICAgc3VtbWFyeUhlaWdodFxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgbGV0IGN1cnJlbnRCb3R0b21Qb2ludDogbnVtYmVyID0gMDtcclxuICAgICAgICAgIG91dHB1dEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIG5leHRQYWdlLmVsZW1lbnRzLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQueSA9IGN1cnJlbnRCb3R0b21Qb2ludDtcclxuICAgICAgICAgICAgdGhpcy5pbnNlcnRFbGVtZW50KGVsZW1lbnQpO1xyXG4gICAgICAgICAgICBjdXJyZW50Qm90dG9tUG9pbnQgKz0gZWxlbWVudC5oZWlnaHQ7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbGV0IHBhZ2UxID0gbmV3IFN0aUZvcm1QYWdlRWxlbWVudCh0aGlzLm1vZGVsLmZvcm0pO1xyXG4gICAgICAgICAgcGFnZTEubmFtZSA9IHRoaXMubmFtZVNlcnZpY2UuZ2V0RWxlbWVudE5hbWUocGFnZTEpO1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLnNwbGljZSh0aGlzLm1vZGVsLmZvcm0ucGFnZXMuaW5kZXhPZihuZXh0UGFnZSksIDAsIHBhZ2UxKTtcclxuICAgICAgICAgIGxldCBjdXJyZW50Qm90dG9tUG9pbnQ6IG51bWJlciA9IDA7XHJcbiAgICAgICAgICBvdXRwdXRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBwYWdlMS5lbGVtZW50cy5zcGxpY2UoaW5kZXgsIDAsIGVsZW1lbnQpO1xyXG4gICAgICAgICAgICBlbGVtZW50LnkgPSBjdXJyZW50Qm90dG9tUG9pbnQ7XHJcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0RWxlbWVudChlbGVtZW50KTtcclxuICAgICAgICAgICAgY3VycmVudEJvdHRvbVBvaW50ICs9IGVsZW1lbnQuaGVpZ2h0O1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBwYWdlMSA9IG5ldyBTdGlGb3JtUGFnZUVsZW1lbnQodGhpcy5tb2RlbC5mb3JtKTtcclxuICAgICAgICBwYWdlMS5uYW1lID0gdGhpcy5uYW1lU2VydmljZS5nZXRFbGVtZW50TmFtZShwYWdlMSk7XHJcbiAgICAgICAgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLnB1c2gocGFnZTEpO1xyXG4gICAgICAgIGxldCBjdXJyZW50Qm90dG9tUG9pbnQ6IG51bWJlciA9IDA7XHJcbiAgICAgICAgb3V0cHV0RWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcclxuICAgICAgICAgIHBhZ2UxLmVsZW1lbnRzLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XHJcbiAgICAgICAgICBlbGVtZW50LnkgPSBjdXJyZW50Qm90dG9tUG9pbnQ7XHJcbiAgICAgICAgICB0aGlzLmluc2VydEVsZW1lbnQoZWxlbWVudCk7XHJcbiAgICAgICAgICBjdXJyZW50Qm90dG9tUG9pbnQgKz0gZWxlbWVudC5nZW9tZXRyeS5ib3R0b207XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19