UNPKG

@avdbrink/ngx-contextmenu

Version:

An Angular component to show a context menu on an arbitrary component

291 lines (290 loc) 32.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import { Overlay, ScrollStrategyOptions } from '@angular/cdk/overlay'; import { ComponentPortal } from '@angular/cdk/portal'; import { Injectable, ElementRef } from '@angular/core'; import { Subject, Subscription } from 'rxjs'; import { ContextMenuContentComponent } from './contextMenuContent.component'; /** * @record */ export function IContextMenuClickEvent() { } function IContextMenuClickEvent_tsickle_Closure_declarations() { /** @type {?|undefined} */ IContextMenuClickEvent.prototype.anchorElement; /** @type {?|undefined} */ IContextMenuClickEvent.prototype.contextMenu; /** @type {?|undefined} */ IContextMenuClickEvent.prototype.event; /** @type {?|undefined} */ IContextMenuClickEvent.prototype.parentContextMenu; /** @type {?} */ IContextMenuClickEvent.prototype.item; /** @type {?|undefined} */ IContextMenuClickEvent.prototype.activeMenuItemIndex; } /** * @record */ export function IContextMenuContext() { } function IContextMenuContext_tsickle_Closure_declarations() { /** @type {?} */ IContextMenuContext.prototype.menuItems; /** @type {?} */ IContextMenuContext.prototype.menuClass; } /** * @record */ export function CloseLeafMenuEvent() { } function CloseLeafMenuEvent_tsickle_Closure_declarations() { /** @type {?|undefined} */ CloseLeafMenuEvent.prototype.exceptRootMenu; /** @type {?|undefined} */ CloseLeafMenuEvent.prototype.event; } /** * @record */ export function OverlayRefWithContextMenu() { } function OverlayRefWithContextMenu_tsickle_Closure_declarations() { /** @type {?|undefined} */ OverlayRefWithContextMenu.prototype.contextMenu; } /** * @record */ export function CancelContextMenuEvent() { } function CancelContextMenuEvent_tsickle_Closure_declarations() { /** @type {?} */ CancelContextMenuEvent.prototype.eventType; /** @type {?|undefined} */ CancelContextMenuEvent.prototype.event; } /** * @record */ export function ExecuteContextMenuEvent() { } function ExecuteContextMenuEvent_tsickle_Closure_declarations() { /** @type {?} */ ExecuteContextMenuEvent.prototype.eventType; /** @type {?|undefined} */ ExecuteContextMenuEvent.prototype.event; /** @type {?} */ ExecuteContextMenuEvent.prototype.item; /** @type {?} */ ExecuteContextMenuEvent.prototype.menuItem; } export class ContextMenuService { /** * @param {?} overlay * @param {?} scrollStrategy */ constructor(overlay, scrollStrategy) { this.overlay = overlay; this.scrollStrategy = scrollStrategy; this.isDestroyingLeafMenu = false; this.show = new Subject(); this.triggerClose = new Subject(); this.close = new Subject(); this.overlays = []; this.fakeElement = { getBoundingClientRect: () => ({ bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0, }) }; } /** * @param {?} context * @return {?} */ openContextMenu(context) { const { anchorElement, event, parentContextMenu } = context; if (!parentContextMenu) { const /** @type {?} */ mouseEvent = /** @type {?} */ (event); this.fakeElement.getBoundingClientRect = () => ({ bottom: mouseEvent.clientY, height: 0, left: mouseEvent.clientX, right: mouseEvent.clientX, top: mouseEvent.clientY, width: 0, }); this.closeAllContextMenus({ eventType: 'cancel', event }); const /** @type {?} */ positionStrategy = this.overlay.position().connectedTo(new ElementRef(anchorElement || this.fakeElement), { originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }) .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }) .withFallbackPosition({ originX: 'end', originY: 'top' }, { overlayX: 'start', overlayY: 'top' }) .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' }) .withFallbackPosition({ originX: 'end', originY: 'center' }, { overlayX: 'start', overlayY: 'center' }) .withFallbackPosition({ originX: 'start', originY: 'center' }, { overlayX: 'end', overlayY: 'center' }); this.overlays = [this.overlay.create({ positionStrategy, panelClass: 'ngx-contextmenu', scrollStrategy: this.scrollStrategy.close(), })]; this.attachContextMenu(this.overlays[0], context); } else { const /** @type {?} */ positionStrategy = this.overlay.position().connectedTo(new ElementRef(event ? event.target : anchorElement), { originX: 'end', originY: 'top' }, { overlayX: 'start', overlayY: 'top' }) .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' }) .withFallbackPosition({ originX: 'end', originY: 'bottom' }, { overlayX: 'start', overlayY: 'bottom' }) .withFallbackPosition({ originX: 'start', originY: 'bottom' }, { overlayX: 'end', overlayY: 'bottom' }); const /** @type {?} */ newOverlay = this.overlay.create({ positionStrategy, panelClass: 'ngx-contextmenu', scrollStrategy: this.scrollStrategy.close(), }); this.destroySubMenus(parentContextMenu); this.overlays = this.overlays.concat(newOverlay); this.attachContextMenu(newOverlay, context); } } /** * @param {?} overlay * @param {?} context * @return {?} */ attachContextMenu(overlay, context) { const { event, item, menuItems, menuClass } = context; const /** @type {?} */ contextMenuContent = overlay.attach(new ComponentPortal(ContextMenuContentComponent)); contextMenuContent.instance.event = event; contextMenuContent.instance.item = item; contextMenuContent.instance.menuItems = menuItems; contextMenuContent.instance.overlay = overlay; contextMenuContent.instance.isLeaf = true; contextMenuContent.instance.menuClass = menuClass; (/** @type {?} */ (overlay)).contextMenu = contextMenuContent.instance; const /** @type {?} */ subscriptions = new Subscription(); subscriptions.add(contextMenuContent.instance.execute.asObservable() .subscribe((executeEvent) => this.closeAllContextMenus(Object.assign({ eventType: 'execute' }, executeEvent)))); subscriptions.add(contextMenuContent.instance.closeAllMenus.asObservable() .subscribe((closeAllEvent) => this.closeAllContextMenus(Object.assign({ eventType: 'cancel' }, closeAllEvent)))); subscriptions.add(contextMenuContent.instance.closeLeafMenu.asObservable() .subscribe(closeLeafMenuEvent => this.destroyLeafMenu(closeLeafMenuEvent))); subscriptions.add(contextMenuContent.instance.openSubMenu.asObservable() .subscribe((subMenuEvent) => { this.destroySubMenus(contextMenuContent.instance); if (!subMenuEvent.contextMenu) { contextMenuContent.instance.isLeaf = true; return; } contextMenuContent.instance.isLeaf = false; this.show.next(subMenuEvent); })); contextMenuContent.onDestroy(() => { menuItems.forEach(menuItem => menuItem.isActive = false); subscriptions.unsubscribe(); }); contextMenuContent.changeDetectorRef.detectChanges(); } /** * @param {?} closeEvent * @return {?} */ closeAllContextMenus(closeEvent) { if (this.overlays) { this.close.next(closeEvent); this.overlays.forEach((overlay, index) => { overlay.detach(); overlay.dispose(); }); } this.overlays = []; } /** * @return {?} */ getLastAttachedOverlay() { let /** @type {?} */ overlay = this.overlays[this.overlays.length - 1]; while (this.overlays.length > 1 && overlay && !overlay.hasAttached()) { overlay.detach(); overlay.dispose(); this.overlays = this.overlays.slice(0, -1); overlay = this.overlays[this.overlays.length - 1]; } return overlay; } /** * @param {?=} __0 * @return {?} */ destroyLeafMenu({ exceptRootMenu, event } = {}) { if (this.isDestroyingLeafMenu) { return; } this.isDestroyingLeafMenu = true; setTimeout(() => { const /** @type {?} */ overlay = this.getLastAttachedOverlay(); if (this.overlays.length > 1 && overlay) { overlay.detach(); overlay.dispose(); } if (!exceptRootMenu && this.overlays.length > 0 && overlay) { this.close.next({ eventType: 'cancel', event }); overlay.detach(); overlay.dispose(); } const /** @type {?} */ newLeaf = this.getLastAttachedOverlay(); if (newLeaf) { newLeaf.contextMenu.isLeaf = true; } this.isDestroyingLeafMenu = false; }); } /** * @param {?} contextMenu * @return {?} */ destroySubMenus(contextMenu) { const /** @type {?} */ overlay = contextMenu.overlay; const /** @type {?} */ index = this.overlays.indexOf(overlay); this.overlays.slice(index + 1).forEach(subMenuOverlay => { subMenuOverlay.detach(); subMenuOverlay.dispose(); }); } /** * @param {?} contextMenuContent * @return {?} */ isLeafMenu(contextMenuContent) { const /** @type {?} */ overlay = this.getLastAttachedOverlay(); return contextMenuContent.overlay === overlay; } } ContextMenuService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ContextMenuService.ctorParameters = () => [ { type: Overlay }, { type: ScrollStrategyOptions } ]; function ContextMenuService_tsickle_Closure_declarations() { /** @type {?} */ ContextMenuService.prototype.isDestroyingLeafMenu; /** @type {?} */ ContextMenuService.prototype.show; /** @type {?} */ ContextMenuService.prototype.triggerClose; /** @type {?} */ ContextMenuService.prototype.close; /** @type {?} */ ContextMenuService.prototype.contextMenuContent; /** @type {?} */ ContextMenuService.prototype.overlays; /** @type {?} */ ContextMenuService.prototype.fakeElement; /** @type {?} */ ContextMenuService.prototype.overlay; /** @type {?} */ ContextMenuService.prototype.scrollStrategy; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhdmRicmluay9uZ3gtY29udGV4dG1lbnUvIiwic291cmNlcyI6WyJsaWIvY29udGV4dE1lbnUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLE9BQU8sRUFBYyxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQWdCLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJN0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbUM3RSxNQUFNOzs7OztJQW9CSixZQUNVLFNBQ0E7UUFEQSxZQUFPLEdBQVAsT0FBTztRQUNQLG1CQUFjLEdBQWQsY0FBYztvQ0FyQk0sS0FBSztvQkFFWSxJQUFJLE9BQU8sRUFBMEI7NEJBQ3hCLElBQUksT0FBTyxFQUFFO3FCQUMxQixJQUFJLE9BQU8sRUFBRTt3QkFHM0IsRUFBRTsyQkFDUjtZQUN6QixxQkFBcUIsRUFBRSxHQUFlLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLEVBQUUsQ0FBQztnQkFDVCxNQUFNLEVBQUUsQ0FBQztnQkFDVCxJQUFJLEVBQUUsQ0FBQztnQkFDUCxLQUFLLEVBQUUsQ0FBQztnQkFDUixHQUFHLEVBQUUsQ0FBQztnQkFDTixLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7U0FDSDtLQUtJOzs7OztJQUVFLGVBQWUsQ0FBQyxPQUE0QjtRQUNqRCxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFB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ZWd5T3B0aW9ucyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBJbmplY3RhYmxlLCBFbGVtZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQ29udGV4dE1lbnVDb21wb25lbnQgfSBmcm9tICcuL2NvbnRleHRNZW51LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL2NvbnRleHRNZW51Lml0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCB9IGZyb20gJy4vY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNvbnRleHRNZW51Q2xpY2tFdmVudCB7XG4gIGFuY2hvckVsZW1lbnQ/OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQ7XG4gIGNvbnRleHRNZW51PzogQ29udGV4dE1lbnVDb21wb25lbnQ7XG4gIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG4gIHBhcmVudENvbnRleHRNZW51PzogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50O1xuICBpdGVtOiBhbnk7XG4gIGFjdGl2ZU1lbnVJdGVtSW5kZXg/OiBudW1iZXI7XG59XG5leHBvcnQgaW50ZXJmYWNlIElDb250ZXh0TWVudUNvbnRleHQgZXh0ZW5kcyBJQ29udGV4dE1lbnVDbGlja0V2ZW50IHtcbiAgbWVudUl0ZW1zOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmVbXTtcbiAgbWVudUNsYXNzOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIENsb3NlTGVhZk1lbnVFdmVudCB7XG4gIGV4Y2VwdFJvb3RNZW51PzogYm9vbGVhbjtcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVJlZldpdGhDb250ZXh0TWVudSBleHRlbmRzIE92ZXJsYXlSZWYge1xuICBjb250ZXh0TWVudT86IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYW5jZWxDb250ZXh0TWVudUV2ZW50IHtcbiAgZXZlbnRUeXBlOiAnY2FuY2VsJztcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRXhlY3V0ZUNvbnRleHRNZW51RXZlbnQge1xuICBldmVudFR5cGU6ICdleGVjdXRlJztcbiAgZXZlbnQ/OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudDtcbiAgaXRlbTogYW55O1xuICBtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlO1xufVxuZXhwb3J0IHR5cGUgQ2xvc2VDb250ZXh0TWVudUV2ZW50ID0gRXhlY3V0ZUNvbnRleHRNZW51RXZlbnQgfCBDYW5jZWxDb250ZXh0TWVudUV2ZW50O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udGV4dE1lbnVTZXJ2aWNlIHtcbiAgcHVibGljIGlzRGVzdHJveWluZ0xlYWZNZW51ID0gZmFsc2U7XG5cbiAgcHVibGljIHNob3c6IFN1YmplY3Q8SUNvbnRleHRNZW51Q2xpY2tFdmVudD4gPSBuZXcgU3ViamVjdDxJQ29udGV4dE1lbnVDbGlja0V2ZW50PigpO1xuICBwdWJsaWMgdHJpZ2dlckNsb3NlOiBTdWJqZWN0PENvbnRleHRNZW51Q29udGVudENvbXBvbmVudD4gPSBuZXcgU3ViamVjdCgpO1xuICBwdWJsaWMgY2xvc2U6IFN1YmplY3Q8Q2xvc2VDb250ZXh0TWVudUV2ZW50PiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgcHJpdmF0ZSBjb250ZXh0TWVudUNvbnRlbnQ6IENvbXBvbmVudFJlZjxDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQ+O1xuICBwcml2YXRlIG92ZXJsYXlzOiBPdmVybGF5UmVmW10gPSBbXTtcbiAgcHJpdmF0ZSBmYWtlRWxlbWVudDogYW55ID0ge1xuICAgIGdldEJvdW5kaW5nQ2xpZW50UmVjdDogKCk6IENsaWVudFJlY3QgPT4gKHtcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICByaWdodDogMCxcbiAgICAgIHRvcDogMCxcbiAgICAgIHdpZHRoOiAwLFxuICAgIH0pXG4gIH07XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBvdmVybGF5OiBPdmVybGF5LFxuICAgIHByaXZhdGUgc2Nyb2xsU3RyYXRlZ3k6IFNjcm9sbFN0cmF0ZWd5T3B0aW9ucyxcbiAgKSB7IH1cblxuICBwdWJsaWMgb3BlbkNvbnRleHRNZW51KGNvbnRleHQ6IElDb250ZXh0TWVudUNvbnRleHQpIHtcbiAgICBjb25zdCB7IGFuY2hvckVsZW1lbnQsIGV2ZW50LCBwYXJlbnRDb250ZXh0TWVudSB9ID0gY29udGV4dDtcblxuICAgIGlmICghcGFyZW50Q29udGV4dE1lbnUpIHtcbiAgICAgIGNvbnN0IG1vdXNlRXZlbnQgPSBldmVudCBhcyBNb3VzZUV2ZW50O1xuICAgICAgdGhpcy5mYWtlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPSAoKTogQ2xpZW50UmVjdCA9PiAoe1xuICAgICAgICBib3R0b206IG1vdXNlRXZlbnQuY2xpZW50WSxcbiAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICBsZWZ0OiBtb3VzZUV2ZW50LmNsaWVudFgsXG4gICAgICAgIHJpZ2h0OiBtb3VzZUV2ZW50LmNsaWVudFgsXG4gICAgICAgIHRvcDogbW91c2VFdmVudC5jbGllbnRZLFxuICAgICAgICB3aWR0aDogMCxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jbG9zZUFsbENvbnRleHRNZW51cyh7IGV2ZW50VHlwZTogJ2NhbmNlbCcsIGV2ZW50IH0pO1xuICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMub3ZlcmxheS5wb3NpdGlvbigpLmNvbm5lY3RlZFRvKFxuICAgICAgICBuZXcgRWxlbWVudFJlZihhbmNob3JFbGVtZW50IHx8IHRoaXMuZmFrZUVsZW1lbnQpLFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICdib3R0b20nIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAndG9wJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdjZW50ZXInIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICdjZW50ZXInIH0pXG4gICAgICAgIDtcbiAgICAgIHRoaXMub3ZlcmxheXMgPSBbdGhpcy5vdmVybGF5LmNyZWF0ZSh7XG4gICAgICAgIHBvc2l0aW9uU3RyYXRlZ3ksXG4gICAgICAgIHBhbmVsQ2xhc3M6ICduZ3gtY29udGV4dG1lbnUnLFxuICAgICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5zY3JvbGxTdHJhdGVneS5jbG9zZSgpLFxuICAgICAgfSldO1xuICAgICAgdGhpcy5hdHRhY2hDb250ZXh0TWVudSh0aGlzLm92ZXJsYXlzWzBdLCBjb250ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMub3ZlcmxheS5wb3NpdGlvbigpLmNvbm5lY3RlZFRvKFxuICAgICAgICBuZXcgRWxlbWVudFJlZihldmVudCA/IGV2ZW50LnRhcmdldCA6IGFuY2hvckVsZW1lbnQpLFxuICAgICAgICB7IG9yaWdpblg6ICdlbmQnLCBvcmlnaW5ZOiAndG9wJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdlbmQnLCBvcmlnaW5ZOiAnYm90dG9tJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ2JvdHRvbScgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICdib3R0b20nIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ2JvdHRvbScgfSlcbiAgICAgICAgO1xuICAgICAgY29uc3QgbmV3T3ZlcmxheSA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xuICAgICAgICBwb3NpdGlvblN0cmF0ZWd5LFxuICAgICAgICBwYW5lbENsYXNzOiAnbmd4LWNvbnRleHRtZW51JyxcbiAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMuc2Nyb2xsU3RyYXRlZ3kuY2xvc2UoKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZXN0cm95U3ViTWVudXMocGFyZW50Q29udGV4dE1lbnUpO1xuICAgICAgdGhpcy5vdmVybGF5cyA9IHRoaXMub3ZlcmxheXMuY29uY2F0KG5ld092ZXJsYXkpO1xuICAgICAgdGhpcy5hdHRhY2hDb250ZXh0TWVudShuZXdPdmVybGF5LCBjb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXR0YWNoQ29udGV4dE1lbnUob3ZlcmxheTogT3ZlcmxheVJlZiwgY29udGV4dDogSUNvbnRleHRNZW51Q29udGV4dCk6IHZvaWQge1xuICAgIGNvbnN0IHsgZXZlbnQsIGl0ZW0sIG1lbnVJdGVtcywgbWVudUNsYXNzIH0gPSBjb250ZXh0O1xuXG4gICAgY29uc3QgY29udGV4dE1lbnVDb250ZW50OiBDb21wb25lbnRSZWY8Q29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50PiA9IG92ZXJsYXkuYXR0YWNoKG5ldyBDb21wb25lbnRQb3J0YWwoQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50KSk7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmV2ZW50ID0gZXZlbnQ7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLml0ZW0gPSBpdGVtO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5tZW51SXRlbXMgPSBtZW51SXRlbXM7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLm92ZXJsYXkgPSBvdmVybGF5O1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5pc0xlYWYgPSB0cnVlO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5tZW51Q2xhc3MgPSBtZW51Q2xhc3M7XG4gICAgKDxPdmVybGF5UmVmV2l0aENvbnRleHRNZW51Pm92ZXJsYXkpLmNvbnRleHRNZW51ID0gY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlO1xuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICAgIHN1YnNjcmlwdGlvbnMuYWRkKGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5leGVjdXRlLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAuc3Vic2NyaWJlKChleGVjdXRlRXZlbnQpID0+IHRoaXMuY2xvc2VBbGxDb250ZXh0TWVudXMoeyBldmVudFR5cGU6ICdleGVjdXRlJywgLi4uZXhlY3V0ZUV2ZW50IH0pKSk7XG4gICAgc3Vic2NyaXB0aW9ucy5hZGQoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmNsb3NlQWxsTWVudXMuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoKGNsb3NlQWxsRXZlbnQpID0+IHRoaXMuY2xvc2VBbGxDb250ZXh0TWVudXMoeyBldmVudFR5cGU6ICdjYW5jZWwnLCAuLi5jbG9zZUFsbEV2ZW50IH0pKSk7XG4gICAgc3Vic2NyaXB0aW9ucy5hZGQoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmNsb3NlTGVhZk1lbnUuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoY2xvc2VMZWFmTWVudUV2ZW50ID0+IHRoaXMuZGVzdHJveUxlYWZNZW51KGNsb3NlTGVhZk1lbnVFdmVudCkpKTtcbiAgICBzdWJzY3JpcHRpb25zLmFkZChjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2Uub3BlblN1Yk1lbnUuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5zdWJzY3JpYmUoKHN1Yk1lbnVFdmVudDogSUNvbnRleHRNZW51Q29udGV4dCkgPT4ge1xuICAgICAgICB0aGlzLmRlc3Ryb3lTdWJNZW51cyhjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UpO1xuICAgICAgICBpZiAoIXN1Yk1lbnVFdmVudC5jb250ZXh0TWVudSkge1xuICAgICAgICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5pc0xlYWYgPSB0cnVlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UuaXNMZWFmID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2hvdy5uZXh0KHN1Yk1lbnVFdmVudCk7XG4gICAgICB9KSk7XG4gICAgY29udGV4dE1lbnVDb250ZW50Lm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICBtZW51SXRlbXMuZm9yRWFjaChtZW51SXRlbSA9PiBtZW51SXRlbS5pc0FjdGl2ZSA9IGZhbHNlKTtcbiAgICAgIHN1YnNjcmlwdGlvbnMudW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcbiAgICBjb250ZXh0TWVudUNvbnRlbnQuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIGNsb3NlQWxsQ29udGV4dE1lbnVzKGNsb3NlRXZlbnQ6IENsb3NlQ29udGV4dE1lbnVFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm92ZXJsYXlzKSB7XG4gICAgICB0aGlzLmNsb3NlLm5leHQoY2xvc2VFdmVudCk7XG4gICAgICB0aGlzLm92ZXJsYXlzLmZvckVhY2goKG92ZXJsYXksIGluZGV4KSA9PiB7XG4gICAgICAgIG92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMub3ZlcmxheXMgPSBbXTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRMYXN0QXR0YWNoZWRPdmVybGF5KCk6IE92ZXJsYXlSZWZXaXRoQ29udGV4dE1lbnUge1xuICAgIGxldCBvdmVybGF5OiBPdmVybGF5UmVmID0gdGhpcy5vdmVybGF5c1t0aGlzLm92ZXJsYXlzLmxlbmd0aCAtIDFdO1xuICAgIHdoaWxlICh0aGlzLm92ZXJsYXlzLmxlbmd0aCA+IDEgJiYgb3ZlcmxheSAmJiAhb3ZlcmxheS5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICBvdmVybGF5LmRldGFjaCgpO1xuICAgICAgb3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgICB0aGlzLm92ZXJsYXlzID0gdGhpcy5vdmVybGF5cy5zbGljZSgwLCAtMSk7XG4gICAgICBvdmVybGF5ID0gdGhpcy5vdmVybGF5c1t0aGlzLm92ZXJsYXlzLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgICByZXR1cm4gb3ZlcmxheTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95TGVhZk1lbnUoeyBleGNlcHRSb290TWVudSwgZXZlbnQgfTogQ2xvc2VMZWFmTWVudUV2ZW50ID0ge30pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0Rlc3Ryb3lpbmdMZWFmTWVudSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzRGVzdHJveWluZ0xlYWZNZW51ID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3Qgb3ZlcmxheSA9IHRoaXMuZ2V0TGFzdEF0dGFjaGVkT3ZlcmxheSgpO1xuICAgICAgaWYgKHRoaXMub3ZlcmxheXMubGVuZ3RoID4gMSAmJiBvdmVybGF5KSB7XG4gICAgICAgIG92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgfVxuICAgICAgaWYgKCFleGNlcHRSb290TWVudSAmJiB0aGlzLm92ZXJsYXlzLmxlbmd0aCA+IDAgJiYgb3ZlcmxheSkge1xuICAgICAgICB0aGlzLmNsb3NlLm5leHQoeyBldmVudFR5cGU6ICdjYW5jZWwnLCBldmVudCB9KTtcbiAgICAgICAgb3ZlcmxheS5kZXRhY2goKTtcbiAgICAgICAgb3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld0xlYWYgPSB0aGlzLmdldExhc3RBdHRhY2hlZE92ZXJsYXkoKTtcbiAgICAgIGlmIChuZXdMZWFmKSB7XG4gICAgICAgIG5ld0xlYWYuY29udGV4dE1lbnUuaXNMZWFmID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc0Rlc3Ryb3lpbmdMZWFmTWVudSA9IGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGRlc3Ryb3lTdWJNZW51cyhjb250ZXh0TWVudTogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50KTogdm9pZCB7XG4gICAgY29uc3Qgb3ZlcmxheSA9IGNvbnRleHRNZW51Lm92ZXJsYXk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm92ZXJsYXlzLmluZGV4T2Yob3ZlcmxheSk7XG4gICAgdGhpcy5vdmVybGF5cy5zbGljZShpbmRleCArIDEpLmZvckVhY2goc3ViTWVudU92ZXJsYXkgPT4ge1xuICAgICAgc3ViTWVudU92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICBzdWJNZW51T3ZlcmxheS5kaXNwb3NlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaXNMZWFmTWVudShjb250ZXh0TWVudUNvbnRlbnQ6IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG92ZXJsYXkgPSB0aGlzLmdldExhc3RBdHRhY2hlZE92ZXJsYXkoKTtcbiAgICByZXR1cm4gY29udGV4dE1lbnVDb250ZW50Lm92ZXJsYXkgPT09IG92ZXJsYXk7XG4gIH1cbn1cbiJdfQ==