UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

199 lines 32.7 kB
import { __decorate, __metadata } from "tslib"; import { Component, ContentChildren, QueryList, Input } from '@angular/core'; import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators'; import { EditableLayoutItemComponent } from './editable-layout-item.component'; import { LayoutComponent } from './layout.component'; import * as i0 from "@angular/core"; const _c0 = [[["sme-editable-layout-item"]]]; const _c1 = ["sme-editable-layout-item"]; export class EditableLayoutComponent extends LayoutComponent { /** * The source name to use for logging */ get logSourceName() { return 'EditableLayoutComponent'; } getInitialHostClasses() { return super.getInitialHostClasses().concat([ 'sme-layout-relative', 'sme-position-stretch', 'sme-arrange-overflow-auto' ]); } ngOnChanges() { this.changeDraggable(this.isEditMode); } /** * Method to change (start/stop) the draggable behavior of this layout. * @param isDraggable flag to start/stop draggable behavior of all the layout inside this layout. */ changeDraggable(isDraggable) { if (this.editableLayoutItems) { const editableLayoutItems = this.editableLayoutItems.toArray(); for (let i = 0; i < editableLayoutItems.length; i++) { editableLayoutItems[i].isLayoutItemDraggable = isDraggable; } } } ngAfterViewInit() { this.snapToGrid(); this.editableLayoutItems.forEach((childComponent) => { this.subscriptions.push(childComponent.dragEnd.subscribe((item) => { this.dragEnd(item); })); }); } get gridHeight() { const editableLayoutItems = this.editableLayoutItems.toArray(); const itemsByMaxY = editableLayoutItems.map(item => item.yCoordInGrid + item.heightInGrid).sort((a, b) => a > b ? 1 : -1); return Math.max(itemsByMaxY.last() + EditableLayoutComponent.gridPaddingSize, this.hostElement.nativeElement.clientHeight); } get gridWidth() { const editableLayoutItems = this.editableLayoutItems.toArray(); const itemsByMaxX = editableLayoutItems.map(item => item.xCoordInGrid + item.widthInGrid).sort((a, b) => a > b ? 1 : -1); return Math.max(itemsByMaxX.last() + EditableLayoutComponent.gridPaddingSize, this.hostElement.nativeElement.clientWidth); } /** * This method will be called once child/item layout is dragged to change the their position or * their corners are being dragged to resize them. This will be called on onMouseUp and onMouseLeave event. * @param item layout that is just dragged. */ dragEnd(item) { const editableLayoutItems = this.editableLayoutItems.toArray(); const draggedItemId = new Array(); draggedItemId.push(item.id); const idOfLastElement = draggedItemId.pop(); for (let i = 0; i < editableLayoutItems.length; i++) { const draggedItemY1 = item.yCoordInGrid; const draggedItemX1 = item.xCoordInGrid; const draggedItemY2 = draggedItemY1 + item.heightInGrid; const draggedItemX2 = draggedItemX1 + item.widthInGrid; if (idOfLastElement !== editableLayoutItems[i].id) { const existingItemY1 = editableLayoutItems[i].yCoordInGrid; const existingItemX1 = editableLayoutItems[i].xCoordInGrid; const existingItemX2 = existingItemX1 + editableLayoutItems[i].widthInGrid; const existingItemY2 = existingItemY1 + editableLayoutItems[i].heightInGrid; const isXOverlapping = this.areElementsOverlapping(draggedItemX1, draggedItemX2, existingItemX1, existingItemX2); const isYOverlapping = this.areElementsOverlapping(draggedItemY1, draggedItemY2, existingItemY1, existingItemY2); if ((isXOverlapping && isYOverlapping)) { if (existingItemY1 >= draggedItemY1) { draggedItemId.push(editableLayoutItems[i].id); editableLayoutItems[i].yCoordInGrid = draggedItemY2; } else { item.yCoordInGrid = existingItemY2; draggedItemId.push(item.id); } } } if (i === editableLayoutItems.length - 1 && draggedItemId.length > 0) { this.dragEnd(editableLayoutItems[draggedItemId.pop()]); } } this.snapToGrid(); } /** * This method will check overlapping when coordinates are out of conflicting area, like bigger div is dragged over smaller div. * @param pointOneOfDraggedDiv Y/X starting point of Vertical/Horizontal point of dragged div * @param pointTwoOfDraggedDiv Y/X ending point of Vertical/Horizontal point of dragged div * @param pointOneOfExistingDiv Y/X starting point of Vertical/Horizontal div over which new div is dragged * @param pointTwoOfExistingDiv Y/X ending point of Vertical/Horizontal div over which new div is dragged */ areElementsOverlapping(pointOneOfDraggedDiv, pointTwoOfDraggedDiv, pointOneOfExistingDiv, pointTwoOfExistingDiv) { return (this.checkBetween(pointOneOfExistingDiv, pointTwoOfExistingDiv, pointOneOfDraggedDiv) || this.checkBetween(pointOneOfExistingDiv, pointTwoOfExistingDiv, pointTwoOfDraggedDiv)) || (pointOneOfDraggedDiv <= pointOneOfExistingDiv && pointTwoOfDraggedDiv >= pointTwoOfExistingDiv); } /** * Just to check if searched item is fall under certain range. * @param start start of range * @param end end of range * @param search item being searched */ checkBetween(start, end, search) { return (search > start) && (search < end) ? true : false; } /** * This method is adjust all the div with to fall on the boundary of grid with 72 x 72. */ snapToGrid() { this.editableLayoutItems.forEach((childComponent) => { const remainderX = childComponent.xCoordInGrid % EditableLayoutComponent.gridSquareSize; const remainderY = childComponent.yCoordInGrid % EditableLayoutComponent.gridSquareSize; const remainderHeight = childComponent.heightInGrid % EditableLayoutComponent.gridSquareSize; const remainderWidth = childComponent.widthInGrid % EditableLayoutComponent.gridSquareSize; if (remainderX !== 0) { childComponent.xCoordInGrid = Math.max(childComponent.xCoordInGrid - remainderX, 0); } if (remainderY !== 0) { childComponent.yCoordInGrid = Math.max(childComponent.yCoordInGrid - remainderY, 0); } if (remainderHeight !== 0) { childComponent.heightInGrid = Math.max(childComponent.heightInGrid - remainderHeight, EditableLayoutComponent.gridSquareSize); } if (remainderWidth !== 0) { childComponent.widthInGrid = Math.max(childComponent.widthInGrid - remainderWidth, EditableLayoutComponent.gridSquareSize); } // adjust for minimum area bounds if (childComponent.area < childComponent.minArea) { let widthModifier = 0; let heightModifier = 0; if (childComponent.widthInGrid >= childComponent.heightInGrid) { widthModifier = EditableLayoutComponent.gridSquareSize; } if (childComponent.heightInGrid >= childComponent.widthInGrid) { heightModifier = EditableLayoutComponent.gridSquareSize; } childComponent.widthInGrid += widthModifier; childComponent.heightInGrid += heightModifier; } }); } updateLayout() { if (this.editableLayoutItems) { const layoutWidth = this.hostElement.nativeElement.clientWidth || 0; if (!layoutWidth) { return; } // calculate coords and boxSize const editableLayoutItems = this.editableLayoutItems.toArray(); for (let i = 0; i < editableLayoutItems.length; i++) { editableLayoutItems[i].widthInGrid = editableLayoutItems[i].widthInGrid; editableLayoutItems[i].heightInGrid = editableLayoutItems[i].heightInGrid; } } } } EditableLayoutComponent.gridSquareSize = 72; EditableLayoutComponent.gridPaddingSize = 8; /** @nocollapse */ EditableLayoutComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵEditableLayoutComponent_BaseFactory; return function EditableLayoutComponent_Factory(t) { returnEditableLayoutComponent_BaseFactory || (ɵEditableLayoutComponent_BaseFactory = i0.ɵɵgetInheritedFactory(EditableLayoutComponent)))(t || EditableLayoutComponent); }; }(); /** @nocollapse */ EditableLayoutComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: EditableLayoutComponent, selectors: [["sme-editable-layout"]], contentQueries: function EditableLayoutComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { i0.ɵɵcontentQuery(dirIndex, EditableLayoutItemComponent, 4); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.editableLayoutItems = _t); } }, inputs: { isEditMode: "isEditMode" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c1, decls: 2, vars: 4, consts: [[1, "sme-editable-layout-grid"]], template: function EditableLayoutComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(_c0); i0.ɵɵelementStart(0, "div", 0); i0.ɵɵprojection(1); i0.ɵɵelementEnd(); } if (rf & 2) { i0.ɵɵstyleProp("height", ctx.gridHeight, "px")("width", ctx.gridWidth, "px"); } }, encapsulation: 2 }); __decorate([ Debounce(0), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], EditableLayoutComponent.prototype, "updateLayout", null); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EditableLayoutComponent, [{ type: Component, args: [{ selector: 'sme-editable-layout', template: "<div class=\"sme-editable-layout-grid\" [style.height.px]=\"gridHeight\" [style.width.px]=\"gridWidth\">\r\n<ng-content select=\"sme-editable-layout-item\"></ng-content>\r\n</div>\r\n" }] }], null, { editableLayoutItems: [{ type: ContentChildren, args: [EditableLayoutItemComponent] }], isEditMode: [{ type: Input }], updateLayout: [] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtbGF5b3V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL2xheW91dC9lZGl0YWJsZS1sYXlvdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvbGF5b3V0L2VkaXRhYmxlLWxheW91dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFpQixTQUFTLEVBQUUsZUFBZSxFQUFhLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhFQUE4RSxDQUFDO0FBQ3hHLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7OztBQU1yRCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsZUFBZTtJQUd4RDs7T0FFRztJQUNILElBQWMsYUFBYTtRQUN2QixPQUFPLHlCQUF5QixDQUFDO0lBQ3JDLENBQUM7SUFRUyxxQkFBcUI7UUFDM0IsT0FBTyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDeEMscUJBQXFCO1lBQ3JCLHNCQUFzQjtZQUN0QiwyQkFBMkI7U0FDOUIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVNLFdBQVc7UUFDZCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0Q7OztPQUdHO0lBQ0ksZUFBZSxDQUFDLFdBQW9CO1FBQ3ZDLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQzFCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQy9ELEtB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QUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGRyZW4sIE9uQ2hhbmdlcywgUXVlcnlMaXN0LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEZWJvdW5jZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL2RlYm91bmNlLmRlY29yYXRvcnMnO1xyXG5pbXBvcnQgeyBFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2VkaXRhYmxlLWxheW91dC1pdGVtLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IExheW91dENvbXBvbmVudCB9IGZyb20gJy4vbGF5b3V0LmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnc21lLWVkaXRhYmxlLWxheW91dCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZWRpdGFibGUtbGF5b3V0LmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRWRpdGFibGVMYXlvdXRDb21wb25lbnQgZXh0ZW5kcyBMYXlvdXRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMge1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ3JpZFNxdWFyZVNpemUgPSA3MjtcclxuICAgIHByaXZhdGUgc3RhdGljIGdyaWRQYWRkaW5nU2l6ZSA9IDg7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzb3VyY2UgbmFtZSB0byB1c2UgZm9yIGxvZ2dpbmdcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldCBsb2dTb3VyY2VOYW1lKCkge1xyXG4gICAgICAgIHJldHVybiAnRWRpdGFibGVMYXlvdXRDb21wb25lbnQnO1xyXG4gICAgfVxyXG5cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oRWRpdGFibGVMYXlvdXRJdGVtQ29tcG9uZW50KVxyXG4gICAgcHJvdGVjdGVkIGVkaXRhYmxlTGF5b3V0SXRlbXM6IFF1ZXJ5TGlzdDxFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQ+O1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgaXNFZGl0TW9kZTogYm9vbGVhbjtcclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0SW5pdGlhbEhvc3RDbGFzc2VzKCkge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5nZXRJbml0aWFsSG9zdENsYXNzZXMoKS5jb25jYXQoW1xyXG4gICAgICAgICAgICAnc21lLWxheW91dC1yZWxhdGl2ZScsXHJcbiAgICAgICAgICAgICdzbWUtcG9zaXRpb24tc3RyZXRjaCcsXHJcbiAgICAgICAgICAgICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvJ1xyXG4gICAgICAgIF0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcygpIHtcclxuICAgICAgICB0aGlzLmNoYW5nZURyYWdnYWJsZSh0aGlzLmlzRWRpdE1vZGUpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRob2QgdG8gY2hhbmdlIChzdGFydC9zdG9wKSB0aGUgZHJhZ2dhYmxlIGJlaGF2aW9yIG9mIHRoaXMgbGF5b3V0LlxyXG4gICAgICogQHBhcmFtIGlzRHJhZ2dhYmxlIGZsYWcgdG8gc3RhcnQvc3RvcCBkcmFnZ2FibGUgYmVoYXZpb3Igb2YgYWxsIHRoZSBsYXlvdXQgaW5zaWRlIHRoaXMgbGF5b3V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2hhbmdlRHJhZ2dhYmxlKGlzRHJhZ2dhYmxlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcykge1xyXG4gICAgICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGl0YWJsZUxheW91dEl0ZW1zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLmlzTGF5b3V0SXRlbURyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAgICAgdGhpcy5zbmFwVG9HcmlkKCk7XHJcbiAgICAgICAgdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLmZvckVhY2goKGNoaWxkQ29tcG9uZW50OiBFZGl0YWJsZUxheW91dEl0ZW1Db21wb25lbnQpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goY2hpbGRDb21wb25lbnQuZHJhZ0VuZC5zdWJzY3JpYmUoKGl0ZW0pID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VuZChpdGVtKTtcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZ3JpZEhlaWdodCgpIHtcclxuICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICBjb25zdCBpdGVtc0J5TWF4WSA9IGVkaXRhYmxlTGF5b3V0SXRlbXMubWFwKGl0ZW0gPT4gaXRlbS55Q29vcmRJbkdyaWQgKyBpdGVtLmhlaWdodEluR3JpZCkuc29ydCgoYSwgYikgPT4gYSA+IGIgPyAxIDogLTEpO1xyXG4gICAgICAgIHJldHVybiBNYXRoLm1heChpdGVtc0J5TWF4WS5sYXN0KCkgKyBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkUGFkZGluZ1NpemUsIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZ3JpZFdpZHRoKCkge1xyXG4gICAgICAgIGNvbnN0IGVkaXRhYmxlTGF5b3V0SXRlbXMgPSB0aGlzLmVkaXRhYmxlTGF5b3V0SXRlbXMudG9BcnJheSgpO1xyXG4gICAgICAgIGNvbnN0IGl0ZW1zQnlNYXhYID0gZWRpdGFibGVMYXlvdXRJdGVtcy5tYXAoaXRlbSA9PiBpdGVtLnhDb29yZEluR3JpZCArIGl0ZW0ud2lkdGhJbkdyaWQpLnNvcnQoKGEsIGIpID0+IGEgPiBiID8gMSA6IC0xKTtcclxuICAgICAgICByZXR1cm4gTWF0aC5tYXgoaXRlbXNCeU1heFgubGFzdCgpICsgRWRpdGFibGVMYXlvdXRDb21wb25lbnQuZ3JpZFBhZGRpbmdTaXplLCB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgb25jZSBjaGlsZC9pdGVtIGxheW91dCBpcyBkcmFnZ2VkIHRvIGNoYW5nZSB0aGUgdGhlaXIgcG9zaXRpb24gb3JcclxuICAgICAqIHRoZWlyIGNvcm5lcnMgYXJlIGJlaW5nIGRyYWdnZWQgdG8gcmVzaXplIHRoZW0uIFRoaXMgd2lsbCBiZSBjYWxsZWQgb24gb25Nb3VzZVVwIGFuZCBvbk1vdXNlTGVhdmUgZXZlbnQuXHJcbiAgICAgKiBAcGFyYW0gaXRlbSBsYXlvdXQgdGhhdCBpcyBqdXN0IGRyYWdnZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkcmFnRW5kKGl0ZW0pIHtcclxuICAgICAgICBjb25zdCBlZGl0YWJsZUxheW91dEl0ZW1zID0gdGhpcy5lZGl0YWJsZUxheW91dEl0ZW1zLnRvQXJyYXkoKTtcclxuICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbUlkID0gbmV3IEFycmF5KCk7XHJcbiAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGl0ZW0uaWQpO1xyXG4gICAgICAgIGNvbnN0IGlkT2ZMYXN0RWxlbWVudCA9IGRyYWdnZWRJdGVtSWQucG9wKCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGl0YWJsZUxheW91dEl0ZW1zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRyYWdnZWRJdGVtWTEgPSBpdGVtLnlDb29yZEluR3JpZDtcclxuICAgICAgICAgICAgY29uc3QgZHJhZ2dlZEl0ZW1YMSA9IGl0ZW0ueENvb3JkSW5HcmlkO1xyXG4gICAgICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbVkyID0gZHJhZ2dlZEl0ZW1ZMSArIGl0ZW0uaGVpZ2h0SW5HcmlkO1xyXG4gICAgICAgICAgICBjb25zdCBkcmFnZ2VkSXRlbVgyID0gZHJhZ2dlZEl0ZW1YMSArIGl0ZW0ud2lkdGhJbkdyaWQ7XHJcbiAgICAgICAgICAgIGlmIChpZE9mTGFzdEVsZW1lbnQgIT09IGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0uaWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSXRlbVkxID0gZWRpdGFibGVMYXlvdXRJdGVtc1tpXS55Q29vcmRJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0l0ZW1YMSA9IGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ueENvb3JkSW5HcmlkO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdJdGVtWDIgPSBleGlzdGluZ0l0ZW1YMSArIGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ud2lkdGhJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0l0ZW1ZMiA9IGV4aXN0aW5nSXRlbVkxICsgZWRpdGFibGVMYXlvdXRJdGVtc1tpXS5oZWlnaHRJbkdyaWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpc1hPdmVybGFwcGluZyA9IHRoaXMuYXJlRWxlbWVudHNPdmVybGFwcGluZyhkcmFnZ2VkSXRlbVgxLCBkcmFnZ2VkSXRlbVgyLCBleGlzdGluZ0l0ZW1YMSwgZXhpc3RpbmdJdGVtWDIpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNZT3ZlcmxhcHBpbmcgPSB0aGlzLmFyZUVsZW1lbnRzT3ZlcmxhcHBpbmcoZHJhZ2dlZEl0ZW1ZMSwgZHJhZ2dlZEl0ZW1ZMiwgZXhpc3RpbmdJdGVtWTEsIGV4aXN0aW5nSXRlbVkyKTtcclxuICAgICAgICAgICAgICAgIGlmICgoaXNYT3ZlcmxhcHBpbmcgJiYgaXNZT3ZlcmxhcHBpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nSXRlbVkxID49IGRyYWdnZWRJdGVtWTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0uaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLnlDb29yZEluR3JpZCA9IGRyYWdnZWRJdGVtWTI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS55Q29vcmRJbkdyaWQgPSBleGlzdGluZ0l0ZW1ZMjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dlZEl0ZW1JZC5wdXNoKGl0ZW0uaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaSA9PT0gZWRpdGFibGVMYXlvdXRJdGVtcy5sZW5ndGggLSAxICYmIGRyYWdnZWRJdGVtSWQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnRW5kKGVkaXRhYmxlTGF5b3V0SXRlbXNbZHJhZ2dlZEl0ZW1JZC5wb3AoKV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc25hcFRvR3JpZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2Qgd2lsbCBjaGVjayBvdmVybGFwcGluZyB3aGVuIGNvb3JkaW5hdGVzIGFyZSBvdXQgb2YgY29uZmxpY3RpbmcgYXJlYSwgbGlrZSBiaWdnZXIgZGl2IGlzIGRyYWdnZWQgb3ZlciBzbWFsbGVyIGRpdi5cclxuICAgICAqIEBwYXJhbSBwb2ludE9uZU9mRHJhZ2dlZERpdiBZL1ggc3RhcnRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBwb2ludCBvZiBkcmFnZ2VkIGRpdlxyXG4gICAgICogQHBhcmFtIHBvaW50VHdvT2ZEcmFnZ2VkRGl2IFkvWCBlbmRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBwb2ludCBvZiBkcmFnZ2VkIGRpdlxyXG4gICAgICogQHBhcmFtIHBvaW50T25lT2ZFeGlzdGluZ0RpdiBZL1ggc3RhcnRpbmcgcG9pbnQgb2YgVmVydGljYWwvSG9yaXpvbnRhbCBkaXYgb3ZlciB3aGljaCBuZXcgZGl2IGlzIGRyYWdnZWRcclxuICAgICAqIEBwYXJhbSBwb2ludFR3b09mRXhpc3RpbmdEaXYgWS9YIGVuZGluZyBwb2ludCBvZiBWZXJ0aWNhbC9Ib3Jpem9udGFsIGRpdiBvdmVyIHdoaWNoIG5ldyBkaXYgaXMgZHJhZ2dlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXJlRWxlbWVudHNPdmVybGFwcGluZyhcclxuICAgICAgICBwb2ludE9uZU9mRHJhZ2dlZERpdjogbnVtYmVyLFxyXG4gICAgICAgIHBvaW50VHdvT2ZEcmFnZ2VkRGl2OiBudW1iZXIsXHJcbiAgICAgICAgcG9pbnRPbmVPZkV4aXN0aW5nRGl2OiBudW1iZXIsXHJcbiAgICAgICAgcG9pbnRUd29PZkV4aXN0aW5nRGl2OiBudW1iZXIpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuY2hlY2tCZXR3ZWVuKHBvaW50T25lT2ZFeGlzdGluZ0RpdiwgcG9pbnRUd29PZkV4aXN0aW5nRGl2LCBwb2ludE9uZU9mRHJhZ2dlZERpdilcclxuICAgICAgICAgICAgfHwgdGhpcy5jaGVja0JldHdlZW4ocG9pbnRPbmVPZkV4aXN0aW5nRGl2LCBwb2ludFR3b09mRXhpc3RpbmdEaXYsIHBvaW50VHdvT2ZEcmFnZ2VkRGl2KSlcclxuICAgICAgICAgICAgfHwgKHBvaW50T25lT2ZEcmFnZ2VkRGl2IDw9IHBvaW50T25lT2ZFeGlzdGluZ0RpdiAmJiBwb2ludFR3b09mRHJhZ2dlZERpdiA+PSBwb2ludFR3b09mRXhpc3RpbmdEaXYpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSnVzdCB0byBjaGVjayBpZiBzZWFyY2hlZCBpdGVtIGlzIGZhbGwgdW5kZXIgY2VydGFpbiByYW5nZS5cclxuICAgICAqIEBwYXJhbSBzdGFydCBzdGFydCBvZiByYW5nZVxyXG4gICAgICogQHBhcmFtIGVuZCBlbmQgb2YgcmFuZ2VcclxuICAgICAqIEBwYXJhbSBzZWFyY2ggaXRlbSBiZWluZyBzZWFyY2hlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2hlY2tCZXR3ZWVuKHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBzZWFyY2g6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAoc2VhcmNoID4gc3RhcnQpICYmIChzZWFyY2ggPCBlbmQpID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgYWRqdXN0IGFsbCB0aGUgZGl2IHdpdGggdG8gZmFsbCBvbiB0aGUgYm91bmRhcnkgb2YgZ3JpZCB3aXRoIDcyIHggNzIuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzbmFwVG9HcmlkKCkge1xyXG4gICAgICAgIHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcy5mb3JFYWNoKChjaGlsZENvbXBvbmVudDogRWRpdGFibGVMYXlvdXRJdGVtQ29tcG9uZW50KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmRlclggPSBjaGlsZENvbXBvbmVudC54Q29vcmRJbkdyaWQgJSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyWSA9IGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCAlIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplO1xyXG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXJIZWlnaHQgPSBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQgJSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyV2lkdGggPSBjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCAlIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplO1xyXG4gICAgICAgICAgICBpZiAocmVtYWluZGVyWCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgY2hpbGRDb21wb25lbnQueENvb3JkSW5HcmlkID0gTWF0aC5tYXgoY2hpbGRDb21wb25lbnQueENvb3JkSW5HcmlkIC0gcmVtYWluZGVyWCwgMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbWFpbmRlclkgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCA9IE1hdGgubWF4KGNoaWxkQ29tcG9uZW50LnlDb29yZEluR3JpZCAtIHJlbWFpbmRlclksIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZW1haW5kZXJIZWlnaHQgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LmhlaWdodEluR3JpZCA9XHJcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgoY2hpbGRDb21wb25lbnQuaGVpZ2h0SW5HcmlkIC0gcmVtYWluZGVySGVpZ2h0LCBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbWFpbmRlcldpZHRoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCA9IE1hdGgubWF4KGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkIC0gcmVtYWluZGVyV2lkdGgsIEVkaXRhYmxlTGF5b3V0Q29tcG9uZW50LmdyaWRTcXVhcmVTaXplKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gYWRqdXN0IGZvciBtaW5pbXVtIGFyZWEgYm91bmRzXHJcbiAgICAgICAgICAgIGlmIChjaGlsZENvbXBvbmVudC5hcmVhIDwgY2hpbGRDb21wb25lbnQubWluQXJlYSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHdpZHRoTW9kaWZpZXIgPSAwO1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlaWdodE1vZGlmaWVyID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZENvbXBvbmVudC53aWR0aEluR3JpZCA+PSBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aWR0aE1vZGlmaWVyID0gRWRpdGFibGVMYXlvdXRDb21wb25lbnQuZ3JpZFNxdWFyZVNpemU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRDb21wb25lbnQuaGVpZ2h0SW5HcmlkID49IGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0TW9kaWZpZXIgPSBFZGl0YWJsZUxheW91dENvbXBvbmVudC5ncmlkU3F1YXJlU2l6ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNoaWxkQ29tcG9uZW50LndpZHRoSW5HcmlkICs9IHdpZHRoTW9kaWZpZXI7XHJcbiAgICAgICAgICAgICAgICBjaGlsZENvbXBvbmVudC5oZWlnaHRJbkdyaWQgKz0gaGVpZ2h0TW9kaWZpZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBARGVib3VuY2UoMClcclxuICAgIHByb3RlY3RlZCB1cGRhdGVMYXlvdXQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcykge1xyXG4gICAgICAgICAgICBjb25zdCBsYXlvdXRXaWR0aCA9IHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aCB8fCAwO1xyXG4gICAgICAgICAgICBpZiAoIWxheW91dFdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBjb29yZHMgYW5kIGJveFNpemVcclxuICAgICAgICAgICAgY29uc3QgZWRpdGFibGVMYXlvdXRJdGVtcyA9IHRoaXMuZWRpdGFibGVMYXlvdXRJdGVtcy50b0FycmF5KCk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVkaXRhYmxlTGF5b3V0SXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGVkaXRhYmxlTGF5b3V0SXRlbXNbaV0ud2lkdGhJbkdyaWQgPSBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLndpZHRoSW5HcmlkO1xyXG4gICAgICAgICAgICAgICAgZWRpdGFibGVMYXlvdXRJdGVtc1tpXS5oZWlnaHRJbkdyaWQgPSBlZGl0YWJsZUxheW91dEl0ZW1zW2ldLmhlaWdodEluR3JpZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwic21lLWVkaXRhYmxlLWxheW91dC1ncmlkXCIgW3N0eWxlLmhlaWdodC5weF09XCJncmlkSGVpZ2h0XCIgW3N0eWxlLndpZHRoLnB4XT1cImdyaWRXaWR0aFwiPlxyXG48bmctY29udGVudCBzZWxlY3Q9XCJzbWUtZWRpdGFibGUtbGF5b3V0LWl0ZW1cIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG4iXX0=