| /** |
| * @fileoverview added by tsickle |
| * Generated from: resizable-draggable-dialog/resizable-draggable-dialog.ts |
| * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| import { merge, fromEvent } from 'rxjs'; |
| /** @enum {string} */ |
| const corners = { |
| topRight: "topRight", |
| bottomRight: "bottomRight", |
| bottomLeft: "bottomLeft", |
| topLeft: "topLeft", |
| }; |
| /** @enum {string} */ |
| const cursors = { |
| nesw: "nesw-resize", |
| nwse: "nwse-resize", |
| }; |
| /** @enum {string} */ |
| const verticalAlignment = { |
| top: "top", |
| bottom: "bottom", |
| }; |
| /** @enum {string} */ |
| const horizontalAlignment = { |
| right: "right", |
| left: "left", |
| }; |
| /** @type {?} */ |
| const cornerWidth = '16px'; |
| /** @type {?} */ |
| const offset = '0px'; |
| /** @type {?} */ |
| const minWidth = 200; |
| /** @type {?} */ |
| const minHeight = 200; |
| /** |
| * @param {?} sizeString |
| * @return {?} |
| */ |
| function getPixels(sizeString) { |
| return parseFloat((sizeString || '').replace('px', '')); |
| } |
| /** |
| * @param {?} min |
| * @param {?} num |
| * @param {?} max |
| * @return {?} |
| */ |
| function clamp(min, num, max) { |
| return Math.min(Math.max(num, min), max); |
| } |
| export class ResizableDraggableDialog { |
| /** |
| * @param {?} _document |
| * @param {?} _renderer2 |
| * @param {?} _dialogRef |
| * @param {?} _dragRef |
| */ |
| constructor(_document, _renderer2, _dialogRef, _dragRef) { |
| this._document = _document; |
| this._renderer2 = _renderer2; |
| this._dialogRef = _dialogRef; |
| this._dragRef = _dragRef; |
| this.cornerElements = []; |
| this.pointerDownSubs = []; |
| this._initialPositionReset(); |
| this._attachCorners(); |
| } |
| /** |
| * @return {?} |
| */ |
| attach() { |
| this.detach(); |
| this._attachCorners(); |
| } |
| /** |
| * @return {?} |
| */ |
| detach() { |
| this.pointerDownSubs.forEach((/** |
| * @param {?} sub |
| * @return {?} |
| */ |
| (sub) => sub.unsubscribe())); |
| this.pointerDownSubs = []; |
| this.cornerElements.forEach((/** |
| * @param {?} elem |
| * @return {?} |
| */ |
| (elem) => this._renderer2.removeChild(this._getDialogWrapper(), elem))); |
| this.cornerElements = []; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _getDialogWrapper() { |
| return ((/** @type {?} */ (this._document.getElementById(this._dialogRef.id))) || {}).parentElement; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _getViewportDimensions() { |
| return this._getDialogWrapper().parentElement.getBoundingClientRect(); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _getDialogWrapperDimensions() { |
| /** @type {?} */ |
| const dimensions = getComputedStyle(this._getDialogWrapper()); |
| return { |
| width: getPixels(dimensions.width), |
| height: getPixels(dimensions.height), |
| }; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _initialPositionReset() { |
| const { right: viewportWidth, bottom: viewportHeight } = this._getViewportDimensions(); |
| const { width, height } = this._getDialogWrapperDimensions(); |
| const { marginRight: originalDialogRight, marginLeft: originalDialogLeft, marginBottom: originalDialogBottom, marginTop: originalDialogTop, } = this._getDialogWrapper().style; |
| /** @type {?} */ |
| let x; |
| if (originalDialogLeft) { |
| x = getPixels(originalDialogLeft); |
| } |
| else if (originalDialogRight) { |
| x = viewportWidth - getPixels(originalDialogRight) - width; |
| } |
| else { |
| x = (viewportWidth - width) / 2; |
| } |
| /** @type {?} */ |
| let y; |
| if (originalDialogTop) { |
| y = getPixels(originalDialogTop); |
| } |
| else if (originalDialogBottom) { |
| y = viewportHeight - getPixels(originalDialogBottom) - height; |
| } |
| else { |
| y = (viewportHeight - height) / 2; |
| } |
| // use drag ref's mechanisms for positioning instead of the dialog's |
| this._dialogRef.updatePosition({ top: '0px', right: '0px', bottom: '0px', left: '0px' }); |
| this._dragRef.setFreeDragPosition({ x, y }); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _attachCorners() { |
| Object.values(corners).forEach((/** |
| * @param {?} corner |
| * @return {?} |
| */ |
| (corner) => { |
| /** @type {?} */ |
| const element = this._renderer2.createElement('div'); |
| this.cornerElements = [...this.cornerElements, element]; |
| this._renderer2.setStyle(element, 'position', 'absolute'); |
| this._renderer2.setStyle(element, 'width', cornerWidth); |
| this._renderer2.setStyle(element, 'height', cornerWidth); |
| this._renderer2.appendChild(this._getDialogWrapper(), element); |
| /** @type {?} */ |
| let cursor; |
| /** @type {?} */ |
| let topBottom; |
| /** @type {?} */ |
| let rightLeft; |
| if (corner === corners.topRight) { |
| cursor = cursors.nesw; |
| topBottom = verticalAlignment.top; |
| rightLeft = horizontalAlignment.right; |
| } |
| else if (corner === corners.bottomRight) { |
| cursor = cursors.nwse; |
| topBottom = verticalAlignment.bottom; |
| rightLeft = horizontalAlignment.right; |
| /** @type {?} */ |
| const icon = this._renderer2.createElement('i'); |
| this._renderer2.addClass(icon, 'material-icons'); |
| this._renderer2.appendChild(icon, this._renderer2.createText('filter_list')); |
| this._renderer2.appendChild(element, icon); |
| this._renderer2.setStyle(icon, 'transform', `rotate(${315}deg) translate(0px, ${offset})`); |
| this._renderer2.setStyle(icon, 'font-size', cornerWidth); |
| } |
| else if (corner === corners.bottomLeft) { |
| cursor = cursors.nesw; |
| topBottom = verticalAlignment.bottom; |
| rightLeft = horizontalAlignment.left; |
| } |
| else if (corner === corners.topLeft) { |
| cursor = cursors.nwse; |
| topBottom = verticalAlignment.top; |
| rightLeft = horizontalAlignment.left; |
| } |
| this._renderer2.setStyle(element, topBottom, offset); |
| this._renderer2.setStyle(element, rightLeft, offset); |
| this._renderer2.setStyle(element, 'cursor', cursor); |
| /** @type {?} */ |
| const pointerDownSub = fromEvent(element, 'pointerdown').subscribe((/** |
| * @param {?} event |
| * @return {?} |
| */ |
| (event) => { |
| this._handleMouseDown(event, corner); |
| })); |
| this.pointerDownSubs = [...this.pointerDownSubs, pointerDownSub]; |
| })); |
| } |
| /** |
| * @private |
| * @param {?} event |
| * @param {?} corner |
| * @return {?} |
| */ |
| _handleMouseDown(event, corner) { |
| this._renderer2.setStyle((/** @type {?} */ (this._document.body)), 'user-select', 'none'); |
| const { width: originalWidth, height: originalHeight } = this._getDialogWrapperDimensions(); |
| /** @type {?} */ |
| const originalMouseX = event.pageX; |
| /** @type {?} */ |
| const originalMouseY = event.pageY; |
| const { x: currentTransformX, y: currentTransformY } = this._dragRef.getFreeDragPosition(); |
| const { bottom: distanceFromBottom, right: distanceFromRight } = this._getDialogWrapper().getBoundingClientRect(); |
| const { right: viewportWidth, bottom: viewportHeight } = this._getViewportDimensions(); |
| /** @type {?} */ |
| const mouseMoveSub = fromEvent(window, 'pointermove').subscribe((/** |
| * @param {?} e |
| * @return {?} |
| */ |
| (e) => { |
| e.preventDefault(); // prevent highlighting of text when dragging |
| // prevent highlighting of text when dragging |
| /** @type {?} */ |
| const yDelta = clamp(0, e.pageY, viewportHeight) - originalMouseY; |
| /** @type {?} */ |
| const xDelta = clamp(0, e.pageX, viewportWidth) - originalMouseX; |
| /** @type {?} */ |
| let newHeight; |
| /** @type {?} */ |
| let newWidth; |
| /** @type {?} */ |
| let newTransformY = 0; |
| /** @type {?} */ |
| let newTransformX = 0; |
| // top right |
| if (corner === corners.topRight) { |
| newHeight = clamp(minHeight, originalHeight - yDelta, viewportHeight); |
| newWidth = clamp(minWidth, originalWidth + xDelta, viewportWidth); |
| newTransformY = clamp(0, currentTransformY + yDelta, distanceFromBottom - newHeight); |
| newTransformX = currentTransformX; |
| } |
| // bottom right |
| else if (corner === corners.bottomRight) { |
| newHeight = clamp(minHeight, originalHeight + yDelta, viewportHeight); |
| newWidth = clamp(minWidth, originalWidth + xDelta, viewportWidth); |
| newTransformY = currentTransformY; |
| newTransformX = currentTransformX; |
| } |
| // bottom left |
| else if (corner === corners.bottomLeft) { |
| newHeight = clamp(minHeight, originalHeight + yDelta, viewportHeight); |
| newWidth = clamp(minWidth, originalWidth - xDelta, viewportWidth); |
| newTransformY = currentTransformY; |
| newTransformX = clamp(0, currentTransformX + xDelta, distanceFromRight - newWidth); |
| } |
| // top left |
| else if (corner === corners.topLeft) { |
| newHeight = clamp(minHeight, originalHeight - yDelta, viewportHeight); |
| newWidth = clamp(minWidth, originalWidth - xDelta, viewportWidth); |
| newTransformX = clamp(0, currentTransformX + xDelta, distanceFromRight - newWidth); |
| newTransformY = clamp(0, currentTransformY + yDelta, distanceFromBottom - newHeight); |
| } |
| this._dialogRef.updateSize(`${newWidth}px`, `${newHeight}px`); |
| this._dragRef.setFreeDragPosition({ |
| x: newTransformX, |
| y: newTransformY, |
| }); |
| })); |
| /** @type {?} */ |
| const mouseUpSub = merge(fromEvent(window, 'pointerup'), fromEvent(window, 'pointercancel')).subscribe((/** |
| * @return {?} |
| */ |
| () => { |
| this._renderer2.removeStyle((/** @type {?} */ (this._document.body)), 'user-select'); |
| mouseMoveSub.unsubscribe(); |
| mouseUpSub.unsubscribe(); |
| })); |
| } |
| } |
| if (false) { |
| /** @type {?} */ |
| ResizableDraggableDialog.prototype.cornerElements; |
| /** @type {?} */ |
| ResizableDraggableDialog.prototype.pointerDownSubs; |
| /** |
| * @type {?} |
| * @private |
| */ |
| ResizableDraggableDialog.prototype._document; |
| /** |
| * @type {?} |
| * @private |
| */ |
| ResizableDraggableDialog.prototype._renderer2; |
| /** |
| * @type {?} |
| * @private |
| */ |
| ResizableDraggableDialog.prototype._dialogRef; |
| /** |
| * @type {?} |
| * @private |
| */ |
| ResizableDraggableDialog.prototype._dragRef; |
| } |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLWRyYWdnYWJsZS1kaWFsb2cuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vLi4vc3JjL3BsYXRmb3JtL2NvcmUvZGlhbG9ncy8iLCJzb3VyY2VzIjpbInJlc2l6YWJsZS1kcmFnZ2FibGUtZGlhbG9nL3Jlc2l6YWJsZS1kcmFnZ2FibGUtZGlhbG9nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBR0EsT0FBTyxFQUFFLEtBQUssRUFBZ0IsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQUd0RCxNQUFLLE9BQU87SUFDVixRQUFRLFlBQWE7SUFDckIsV0FBVyxlQUFnQjtJQUMzQixVQUFVLGNBQWU7SUFDekIsT0FBTyxXQUFZO0VBQ3BCOztBQUNELE1BQUssT0FBTztJQUNWLElBQUksZUFBZ0I7SUFDcEIsSUFBSSxlQUFnQjtFQUNyQjs7QUFDRCxNQUFLLGlCQUFpQjtJQUNwQixHQUFHLE9BQVE7SUFDWCxNQUFNLFVBQVc7RUFDbEI7O0FBQ0QsTUFBSyxtQkFBbUI7SUFDdEIsS0FBSyxTQUFVO0lBQ2YsSUFBSSxRQUFTO0VBQ2Q7O01BRUssV0FBVyxHQUFXLE1BQU07O01BQzVCLE1BQU0sR0FBVyxLQUFLOztNQUN0QixRQUFRLEdBQVcsR0FBRzs7TUFDdEIsU0FBUyxHQUFXLEdBQUc7Ozs7O0FBRTdCLFNBQVMsU0FBUyxDQUFDLFVBQWtCO0lBQ25DLE9BQU8sVUFBVSxDQUFDLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxRCxDQUFDOzs7Ozs7O0FBRUQsU0FBUyxLQUFLLENBQUMsR0FBVyxFQUFFLEdBQVcsRUFBRSxHQUFXO0lBQ2xELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQsTUFBTSxPQUFPLHdC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QixHQUFHLE1BQU0sRUFBRSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsQ0FBQztnQkFDbkYsYUFBYSxHQUFHLEtBQUssQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLEdBQUcsTUFBTSxFQUFFLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxDQUFDO2FBQ3RGO1lBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLElBQUksRUFBRSxHQUFHLFNBQVMsSUFBSSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQztnQkFDaEMsQ0FBQyxFQUFFLGFBQWE7Z0JBQ2hCLENBQUMsRUFBRSxhQUFhO2FBQ2pCLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBQzs7Y0FFSSxVQUFVLEdBQWlCLEtBQUssQ0FDcEMsU0FBUyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsRUFDOUIsU0FBUyxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FDbkMsQ0FBQyxTQUFTOzs7UUFBQyxHQUFHLEVBQUU7WUFDZixJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxtQkFBYSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBQSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQzdFLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixVQUFVLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0IsQ0FBQyxFQUFDO0lBQ0osQ0FBQztDQUNGOzs7SUF4TEMsa0RBQW1DOztJQUNuQyxtREFBcUM7Ozs7O0lBR25DLDZDQUFzQjs7Ozs7SUFDdEIsOENBQTZCOzs7OztJQUM3Qiw4Q0FBcUM7Ozs7O0lBQ3JDLDRDQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IERyYWdSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7IG1lcmdlLCBTdWJzY3JpcHRpb24sIGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgUG9pbnQgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wL2RyYWctcmVmJztcblxuZW51bSBjb3JuZXJzIHtcbiAgdG9wUmlnaHQgPSAndG9wUmlnaHQnLFxuICBib3R0b21SaWdodCA9ICdib3R0b21SaWdodCcsXG4gIGJvdHRvbUxlZnQgPSAnYm90dG9tTGVmdCcsXG4gIHRvcExlZnQgPSAndG9wTGVmdCcsXG59XG5lbnVtIGN1cnNvcnMge1xuICBuZXN3ID0gJ25lc3ctcmVzaXplJyxcbiAgbndzZSA9ICdud3NlLXJlc2l6ZScsXG59XG5lbnVtIHZlcnRpY2FsQWxpZ25tZW50IHtcbiAgdG9wID0gJ3RvcCcsXG4gIGJvdHRvbSA9ICdib3R0b20nLFxufVxuZW51bSBob3Jpem9udGFsQWxpZ25tZW50IHtcbiAgcmlnaHQgPSAncmlnaHQnLFxuICBsZWZ0ID0gJ2xlZnQnLFxufVxuXG5jb25zdCBjb3JuZXJXaWR0aDogc3RyaW5nID0gJzE2cHgnO1xuY29uc3Qgb2Zmc2V0OiBzdHJpbmcgPSAnMHB4JztcbmNvbnN0IG1pbldpZHRoOiBudW1iZXIgPSAyMDA7XG5jb25zdCBtaW5IZWlnaHQ6IG51bWJlciA9IDIwMDtcblxuZnVuY3Rpb24gZ2V0UGl4ZWxzKHNpemVTdHJpbmc6IHN0cmluZyk6IG51bWJlciB7XG4gIHJldHVybiBwYXJzZUZsb2F0KChzaXplU3RyaW5nIHx8ICcnKS5yZXBsYWNlKCdweCcsICcnKSk7XG59XG5cbmZ1bmN0aW9uIGNsYW1wKG1pbjogbnVtYmVyLCBudW06IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgobnVtLCBtaW4pLCBtYXgpO1xufVxuXG5leHBvcnQgY2xhc3MgUmVzaXphYmxlRHJhZ2dhYmxlRGlhbG9nIHtcbiAgY29ybmVyRWxlbWVudHM6IEhUTUxFbGVtZW50W10gPSBbXTtcbiAgcG9pbnRlckRvd25TdWJzOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2RvY3VtZW50OiBhbnksXG4gICAgcHJpdmF0ZSBfcmVuZGVyZXIyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBfZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8YW55PixcbiAgICBwcml2YXRlIF9kcmFnUmVmOiBEcmFnUmVmLFxuICApIHtcbiAgICB0aGlzLl9pbml0aWFsUG9zaXRpb25SZXNldCgpO1xuICAgIHRoaXMuX2F0dGFjaENvcm5lcnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBhdHRhY2goKTogdm9pZCB7XG4gICAgdGhpcy5kZXRhY2goKTtcbiAgICB0aGlzLl9hdHRhY2hDb3JuZXJzKCk7XG4gIH1cblxuICBwdWJsaWMgZGV0YWNoKCk6IHZvaWQge1xuICAgIHRoaXMucG9pbnRlckRvd25TdWJzLmZvckVhY2goKHN1YjogU3Vic2NyaXB0aW9uKSA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gICAgdGhpcy5wb2ludGVyRG93blN1YnMgPSBbXTtcbiAgICB0aGlzLmNvcm5lckVsZW1lbnRzLmZvckVhY2goKGVsZW06IEhUTUxFbGVtZW50KSA9PiB0aGlzLl9yZW5kZXJlcjIucmVtb3ZlQ2hpbGQodGhpcy5fZ2V0RGlhbG9nV3JhcHBlcigpLCBlbGVtKSk7XG4gICAgdGhpcy5jb3JuZXJFbGVtZW50cyA9IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0RGlhbG9nV3JhcHBlcigpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuICg8SFRNTEVsZW1lbnQ+dGhpcy5fZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5fZGlhbG9nUmVmLmlkKSB8fCB7fSkucGFyZW50RWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFZpZXdwb3J0RGltZW5zaW9ucygpOiBDbGllbnRSZWN0IHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0RGlhbG9nV3JhcHBlcigpLnBhcmVudEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIH1cblxuICBwcml2YXRlIF9nZXREaWFsb2dXcmFwcGVyRGltZW5zaW9ucygpOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0ge1xuICAgIGNvbnN0IGRpbWVuc2lvbnM6IENTU1N0eWxlRGVjbGFyYXRpb24gPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMuX2dldERpYWxvZ1dyYXBwZXIoKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiBnZXRQaXhlbHMoZGltZW5zaW9ucy53aWR0aCksXG4gICAgICBoZWlnaHQ6IGdldFBpeGVscyhkaW1lbnNpb25zLmhlaWdodCksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX2luaXRpYWxQb3NpdGlvblJlc2V0KCk6IHZvaWQge1xuICAgIGNvbnN0IHsgcmlnaHQ6IHZpZXdwb3J0V2lkdGgsIGJvdHRvbTogdmlld3BvcnRIZWlnaHQgfTogQ2xpZW50UmVjdCA9IHRoaXMuX2dldFZpZXdwb3J0RGltZW5zaW9ucygpO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5fZ2V0RGlhbG9nV3JhcHBlckRpbWVuc2lvbnMoKTtcbiAgICBjb25zdCB7XG4gICAgICBtYXJnaW5SaWdodDogb3JpZ2luYWxEaWFsb2dSaWdodCxcbiAgICAgIG1hcmdpbkxlZnQ6IG9yaWdpbmFsRGlhbG9nTGVmdCxcbiAgICAgIG1hcmdpbkJvdHRvbTogb3JpZ2luYWxEaWFsb2dCb3R0b20sXG4gICAgICBtYXJnaW5Ub3A6IG9yaWdpbmFsRGlhbG9nVG9wLFxuICAgIH0gPSB0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCkuc3R5bGU7XG4gICAgbGV0IHg6IG51bWJlcjtcbiAgICBpZiAob3JpZ2luYWxEaWFsb2dMZWZ0KSB7XG4gICAgICB4ID0gZ2V0UGl4ZWxzKG9yaWdpbmFsRGlhbG9nTGVmdCk7XG4gICAgfSBlbHNlIGlmIChvcmlnaW5hbERpYWxvZ1JpZ2h0KSB7XG4gICAgICB4ID0gdmlld3BvcnRXaWR0aCAtIGdldFBpeGVscyhvcmlnaW5hbERpYWxvZ1JpZ2h0KSAtIHdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB4ID0gKHZpZXdwb3J0V2lkdGggLSB3aWR0aCkgLyAyO1xuICAgIH1cbiAgICBsZXQgeTogbnVtYmVyO1xuICAgIGlmIChvcmlnaW5hbERpYWxvZ1RvcCkge1xuICAgICAgeSA9IGdldFBpeGVscyhvcmlnaW5hbERpYWxvZ1RvcCk7XG4gICAgfSBlbHNlIGlmIChvcmlnaW5hbERpYWxvZ0JvdHRvbSkge1xuICAgICAgeSA9IHZpZXdwb3J0SGVpZ2h0IC0gZ2V0UGl4ZWxzKG9yaWdpbmFsRGlhbG9nQm90dG9tKSAtIGhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgeSA9ICh2aWV3cG9ydEhlaWdodCAtIGhlaWdodCkgLyAyO1xuICAgIH1cbiAgICAvLyB1c2UgZHJhZyByZWYncyBtZWNoYW5pc21zIGZvciBwb3NpdGlvbmluZyBpbnN0ZWFkIG9mIHRoZSBkaWFsb2cnc1xuICAgIHRoaXMuX2RpYWxvZ1JlZi51cGRhdGVQb3NpdGlvbih7IHRvcDogJzBweCcsIHJpZ2h0OiAnMHB4JywgYm90dG9tOiAnMHB4JywgbGVmdDogJzBweCcgfSk7XG4gICAgdGhpcy5fZHJhZ1JlZi5zZXRGcmVlRHJhZ1Bvc2l0aW9uKHsgeCwgeSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2F0dGFjaENvcm5lcnMoKTogdm9pZCB7XG4gICAgT2JqZWN0LnZhbHVlcyhjb3JuZXJzKS5mb3JFYWNoKChjb3JuZXI6IGNvcm5lcnMpID0+IHtcbiAgICAgIGNvbnN0IGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gdGhpcy5fcmVuZGVyZXIyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgdGhpcy5jb3JuZXJFbGVtZW50cyA9IFsuLi50aGlzLmNvcm5lckVsZW1lbnRzLCBlbGVtZW50XTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5zZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nLCAnYWJzb2x1dGUnKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5zZXRTdHlsZShlbGVtZW50LCAnd2lkdGgnLCBjb3JuZXJXaWR0aCk7XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgJ2hlaWdodCcsIGNvcm5lcldpZHRoKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5hcHBlbmRDaGlsZCh0aGlzLl9nZXREaWFsb2dXcmFwcGVyKCksIGVsZW1lbnQpO1xuXG4gICAgICBsZXQgY3Vyc29yOiBjdXJzb3JzO1xuICAgICAgbGV0IHRvcEJvdHRvbTogdmVydGljYWxBbGlnbm1lbnQ7XG4gICAgICBsZXQgcmlnaHRMZWZ0OiBob3Jpem9udGFsQWxpZ25tZW50O1xuXG4gICAgICBpZiAoY29ybmVyID09PSBjb3JuZXJzLnRvcFJpZ2h0KSB7XG4gICAgICAgIGN1cnNvciA9IGN1cnNvcnMubmVzdztcbiAgICAgICAgdG9wQm90dG9tID0gdmVydGljYWxBbGlnbm1lbnQudG9wO1xuICAgICAgICByaWdodExlZnQgPSBob3Jpem9udGFsQWxpZ25tZW50LnJpZ2h0O1xuICAgICAgfSBlbHNlIGlmIChjb3JuZXIgPT09IGNvcm5lcnMuYm90dG9tUmlnaHQpIHtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29ycy5ud3NlO1xuICAgICAgICB0b3BCb3R0b20gPSB2ZXJ0aWNhbEFsaWdubWVudC5ib3R0b207XG4gICAgICAgIHJpZ2h0TGVmdCA9IGhvcml6b250YWxBbGlnbm1lbnQucmlnaHQ7XG5cbiAgICAgICAgY29uc3QgaWNvbjogSFRNTEVsZW1lbnQgPSB0aGlzLl9yZW5kZXJlcjIuY3JlYXRlRWxlbWVudCgnaScpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlcjIuYWRkQ2xhc3MoaWNvbiwgJ21hdGVyaWFsLWljb25zJyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyMi5hcHBlbmRDaGlsZChpY29uLCB0aGlzLl9yZW5kZXJlcjIuY3JlYXRlVGV4dCgnZmlsdGVyX2xpc3QnKSk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyMi5hcHBlbmRDaGlsZChlbGVtZW50LCBpY29uKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKGljb24sICd0cmFuc2Zvcm0nLCBgcm90YXRlKCR7MzE1fWRlZykgdHJhbnNsYXRlKDBweCwgJHtvZmZzZXR9KWApO1xuICAgICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoaWNvbiwgJ2ZvbnQtc2l6ZScsIGNvcm5lcldpZHRoKTtcbiAgICAgIH0gZWxzZSBpZiAoY29ybmVyID09PSBjb3JuZXJzLmJvdHRvbUxlZnQpIHtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29ycy5uZXN3O1xuICAgICAgICB0b3BCb3R0b20gPSB2ZXJ0aWNhbEFsaWdubWVudC5ib3R0b207XG4gICAgICAgIHJpZ2h0TGVmdCA9IGhvcml6b250YWxBbGlnbm1lbnQubGVmdDtcbiAgICAgIH0gZWxzZSBpZiAoY29ybmVyID09PSBjb3JuZXJzLnRvcExlZnQpIHtcbiAgICAgICAgY3Vyc29yID0gY3Vyc29ycy5ud3NlO1xuICAgICAgICB0b3BCb3R0b20gPSB2ZXJ0aWNhbEFsaWdubWVudC50b3A7XG4gICAgICAgIHJpZ2h0TGVmdCA9IGhvcml6b250YWxBbGlnbm1lbnQubGVmdDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3JlbmRlcmVyMi5zZXRTdHlsZShlbGVtZW50LCB0b3BCb3R0b20sIG9mZnNldCk7XG4gICAgICB0aGlzLl9yZW5kZXJlcjIuc2V0U3R5bGUoZWxlbWVudCwgcmlnaHRMZWZ0LCBvZmZzZXQpO1xuICAgICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKGVsZW1lbnQsICdjdXJzb3InLCBjdXJzb3IpO1xuXG4gICAgICBjb25zdCBwb2ludGVyRG93blN1YjogU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KGVsZW1lbnQsICdwb2ludGVyZG93bicpLnN1YnNjcmliZSgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgICB0aGlzLl9oYW5kbGVNb3VzZURvd24oZXZlbnQsIGNvcm5lcik7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucG9pbnRlckRvd25TdWJzID0gWy4uLnRoaXMucG9pbnRlckRvd25TdWJzLCBwb2ludGVyRG93blN1Yl07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9oYW5kbGVNb3VzZURvd24oZXZlbnQ6IFBvaW50ZXJFdmVudCwgY29ybmVyOiBjb3JuZXJzKTogdm9pZCB7XG4gICAgdGhpcy5fcmVuZGVyZXIyLnNldFN0eWxlKDxIVE1MRWxlbWVudD50aGlzLl9kb2N1bWVudC5ib2R5LCAndXNlci1zZWxlY3QnLCAnbm9uZScpO1xuICAgIGNvbnN0IHsgd2lkdGg6IG9yaWdpbmFsV2lkdGgsIGhlaWdodDogb3JpZ2luYWxIZWlnaHQgfSA9IHRoaXMuX2dldERpYWxvZ1dyYXBwZXJEaW1lbnNpb25zKCk7XG4gICAgY29uc3Qgb3JpZ2luYWxNb3VzZVg6IG51bWJlciA9IGV2ZW50LnBhZ2VYO1xuICAgIGNvbnN0IG9yaWdpbmFsTW91c2VZOiBudW1iZXIgPSBldmVudC5wYWdlWTtcbiAgICBjb25zdCB7IHg6IGN1cnJlbnRUcmFuc2Zvcm1YLCB5OiBjdXJyZW50VHJhbnNmb3JtWSB9OiBQb2ludCA9IHRoaXMuX2RyYWdSZWYuZ2V0RnJlZURyYWdQb3NpdGlvbigpO1xuICAgIGNvbnN0IHsgYm90dG9tOiBkaXN0YW5jZUZyb21Cb3R0b20sIHJpZ2h0OiBkaXN0YW5jZUZyb21SaWdodCB9OiBDbGllbnRSZWN0ID1cbiAgICAgIHRoaXMuX2dldERpYWxvZ1dyYXBwZXIoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB7IHJpZ2h0OiB2aWV3cG9ydFdpZHRoLCBib3R0b206IHZpZXdwb3J0SGVpZ2h0IH06IENsaWVudFJlY3QgPSB0aGlzLl9nZXRWaWV3cG9ydERpbWVuc2lvbnMoKTtcblxuICAgIGNvbnN0IG1vdXNlTW92ZVN1YjogU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KHdpbmRvdywgJ3BvaW50ZXJtb3ZlJykuc3Vic2NyaWJlKChlOiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTsgLy8gcHJldmVudCBoaWdobGlnaHRpbmcgb2YgdGV4dCB3aGVuIGRyYWdnaW5nXG5cbiAgICAgIGNvbnN0IHlEZWx0YTogbnVtYmVyID0gY2xhbXAoMCwgZS5wYWdlWSwgdmlld3BvcnRIZWlnaHQpIC0gb3JpZ2luYWxNb3VzZVk7XG4gICAgICBjb25zdCB4RGVsdGE6IG51bWJlciA9IGNsYW1wKDAsIGUucGFnZVgsIHZpZXdwb3J0V2lkdGgpIC0gb3JpZ2luYWxNb3VzZVg7XG4gICAgICBsZXQgbmV3SGVpZ2h0OiBudW1iZXI7XG4gICAgICBsZXQgbmV3V2lkdGg6IG51bWJlcjtcbiAgICAgIGxldCBuZXdUcmFuc2Zvcm1ZOiBudW1iZXIgPSAwO1xuICAgICAgbGV0IG5ld1RyYW5zZm9ybVg6IG51bWJlciA9IDA7XG5cbiAgICAgIC8vIHRvcCByaWdodFxuICAgICAgaWYgKGNvcm5lciA9PT0gY29ybmVycy50b3BSaWdodCkge1xuICAgICAgICBuZXdIZWlnaHQgPSBjbGFtcChtaW5IZWlnaHQsIG9yaWdpbmFsSGVpZ2h0IC0geURlbHRhLCB2aWV3cG9ydEhlaWdodCk7XG4gICAgICAgIG5ld1dpZHRoID0gY2xhbXAobWluV2lkdGgsIG9yaWdpbmFsV2lkdGggKyB4RGVsdGEsIHZpZXdwb3J0V2lkdGgpO1xuICAgICAgICBuZXdUcmFuc2Zvcm1ZID0gY2xhbXAoMCwgY3VycmVudFRyYW5zZm9ybVkgKyB5RGVsdGEsIGRpc3RhbmNlRnJvbUJvdHRvbSAtIG5ld0hlaWdodCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVggPSBjdXJyZW50VHJhbnNmb3JtWDtcbiAgICAgIH1cbiAgICAgIC8vIGJvdHRvbSByaWdodFxuICAgICAgZWxzZSBpZiAoY29ybmVyID09PSBjb3JuZXJzLmJvdHRvbVJpZ2h0KSB7XG4gICAgICAgIG5ld0hlaWdodCA9IGNsYW1wKG1pbkhlaWdodCwgb3JpZ2luYWxIZWlnaHQgKyB5RGVsdGEsIHZpZXdwb3J0SGVpZ2h0KTtcbiAgICAgICAgbmV3V2lkdGggPSBjbGFtcChtaW5XaWR0aCwgb3JpZ2luYWxXaWR0aCArIHhEZWx0YSwgdmlld3BvcnRXaWR0aCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVkgPSBjdXJyZW50VHJhbnNmb3JtWTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWCA9IGN1cnJlbnRUcmFuc2Zvcm1YO1xuICAgICAgfVxuICAgICAgLy8gYm90dG9tIGxlZnRcbiAgICAgIGVsc2UgaWYgKGNvcm5lciA9PT0gY29ybmVycy5ib3R0b21MZWZ0KSB7XG4gICAgICAgIG5ld0hlaWdodCA9IGNsYW1wKG1pbkhlaWdodCwgb3JpZ2luYWxIZWlnaHQgKyB5RGVsdGEsIHZpZXdwb3J0SGVpZ2h0KTtcbiAgICAgICAgbmV3V2lkdGggPSBjbGFtcChtaW5XaWR0aCwgb3JpZ2luYWxXaWR0aCAtIHhEZWx0YSwgdmlld3BvcnRXaWR0aCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVkgPSBjdXJyZW50VHJhbnNmb3JtWTtcbiAgICAgICAgbmV3VHJhbnNmb3JtWCA9IGNsYW1wKDAsIGN1cnJlbnRUcmFuc2Zvcm1YICsgeERlbHRhLCBkaXN0YW5jZUZyb21SaWdodCAtIG5ld1dpZHRoKTtcbiAgICAgIH1cbiAgICAgIC8vIHRvcCBsZWZ0XG4gICAgICBlbHNlIGlmIChjb3JuZXIgPT09IGNvcm5lcnMudG9wTGVmdCkge1xuICAgICAgICBuZXdIZWlnaHQgPSBjbGFtcChtaW5IZWlnaHQsIG9yaWdpbmFsSGVpZ2h0IC0geURlbHRhLCB2aWV3cG9ydEhlaWdodCk7XG4gICAgICAgIG5ld1dpZHRoID0gY2xhbXAobWluV2lkdGgsIG9yaWdpbmFsV2lkdGggLSB4RGVsdGEsIHZpZXdwb3J0V2lkdGgpO1xuXG4gICAgICAgIG5ld1RyYW5zZm9ybVggPSBjbGFtcCgwLCBjdXJyZW50VHJhbnNmb3JtWCArIHhEZWx0YSwgZGlzdGFuY2VGcm9tUmlnaHQgLSBuZXdXaWR0aCk7XG4gICAgICAgIG5ld1RyYW5zZm9ybVkgPSBjbGFtcCgwLCBjdXJyZW50VHJhbnNmb3JtWSArIHlEZWx0YSwgZGlzdGFuY2VGcm9tQm90dG9tIC0gbmV3SGVpZ2h0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2RpYWxvZ1JlZi51cGRhdGVTaXplKGAke25ld1dpZHRofXB4YCwgYCR7bmV3SGVpZ2h0fXB4YCk7XG4gICAgICB0aGlzLl9kcmFnUmVmLnNldEZyZWVEcmFnUG9zaXRpb24oe1xuICAgICAgICB4OiBuZXdUcmFuc2Zvcm1YLFxuICAgICAgICB5OiBuZXdUcmFuc2Zvcm1ZLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBtb3VzZVVwU3ViOiBTdWJzY3JpcHRpb24gPSBtZXJnZShcbiAgICAgIGZyb21FdmVudCh3aW5kb3csICdwb2ludGVydXAnKSxcbiAgICAgIGZyb21FdmVudCh3aW5kb3csICdwb2ludGVyY2FuY2VsJyksXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5fcmVuZGVyZXIyLnJlbW92ZVN0eWxlKDxIVE1MRWxlbWVudD50aGlzLl9kb2N1bWVudC5ib2R5LCAndXNlci1zZWxlY3QnKTtcbiAgICAgIG1vdXNlTW92ZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgbW91c2VVcFN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH0pO1xuICB9XG59XG4iXX0= |