UNPKG

@hoso/ngx-contextmenu

Version:

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

164 lines 28.9 kB
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'; export class ContextMenuService { 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, }) }; } openContextMenu(context) { const { anchorElement, event, parentContextMenu } = context; if (!parentContextMenu) { const mouseEvent = 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 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 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 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); } } attachContextMenu(overlay, context) { const { event, item, menuItems, menuClass } = context; const 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; overlay.contextMenu = contextMenuContent.instance; const 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(); } closeAllContextMenus(closeEvent) { if (this.overlays) { this.close.next(closeEvent); this.overlays.forEach((overlay, index) => { overlay.detach(); overlay.dispose(); }); } this.overlays = []; } getLastAttachedOverlay() { let 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; } destroyLeafMenu({ exceptRootMenu, event } = {}) { if (this.isDestroyingLeafMenu) { return; } this.isDestroyingLeafMenu = true; setTimeout(() => { const 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 newLeaf = this.getLastAttachedOverlay(); if (newLeaf) { newLeaf.contextMenu.isLeaf = true; } this.isDestroyingLeafMenu = false; }); } destroySubMenus(contextMenu) { const overlay = contextMenu.overlay; const index = this.overlays.indexOf(overlay); this.overlays.slice(index + 1).forEach(subMenuOverlay => { subMenuOverlay.detach(); subMenuOverlay.dispose(); }); } isLeafMenu(contextMenuContent) { const overlay = this.getLastAttachedOverlay(); return contextMenuContent.overlay === overlay; } } ContextMenuService.decorators = [ { type: Injectable } ]; /** @nocollapse */ ContextMenuService.ctorParameters = () => [ { type: Overlay }, { type: ScrollStrategyOptions } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jb250ZXh0bWVudS9zcmMvbGliL2NvbnRleHRNZW51LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBYyxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQWdCLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJN0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFtQzdFLE1BQU0sT0FBTyxrQkFBa0I7SUFvQjdCLFlBQ1UsT0FBZ0IsRUFDaEIsY0FBcUM7UUFEckMsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNoQixtQkFBYyxHQUFkLGNBQWMsQ0FBdUI7UUFyQnhDLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUU3QixTQUFJLEdBQW9DLElBQUksT0FBTyxFQUEwQixDQUFDO1FBQzlFLGlCQUFZLEdBQXlDLElBQUksT0FBTyxFQUFFLENBQUM7UUFDbkUsVUFBSyxHQUFtQyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBR3JELGFBQVEsR0FBaUIsRUFBRSxDQUFDO1FBQzVCLGdCQUFXLEdBQVE7WUFDekIscUJBQXFCLEVBQUUsR0FBZSxFQUFFLENBQUMsQ0FBQztnQkFDeEMsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLENBQUM7Z0JBQ1AsS0FBSyxFQUFFLENBQUM7Z0JBQ1IsR0FBRyxFQUFFLENBQUM7Z0JBQ04sS0FBSyxFQUFFLENBQUM7YUFDVCxDQUFDO1NBQ0gsQ0FBQztJQUtFLENBQUM7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QUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRCxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2pCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUNuQjtZQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQzlDLElBQUksT0FBTyxFQUFFO2dCQUNYLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQzthQUNuQztZQUVELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sZUFBZSxDQUFDLFdBQXdDO1FBQzdELE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFDcEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUN0RCxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDeEIsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFVBQVUsQ0FBQyxrQkFBK0M7UUFDL0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDOUMsT0FBTyxrQkFBa0IsQ0FBQyxPQUFPLEtBQUssT0FBTyxDQUFDO0lBQ2hELENBQUM7OztZQTdMRixVQUFVOzs7O1lBekNGLE9BQU87WUFBYyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPdmVybGF5LCBPdmVybGF5UmVmLCBTY3JvbGxTdHJhdGVneU9wdGlvbnMgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBDb21wb25lbnRQb3J0YWwgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7IENvbXBvbmVudFJlZiwgSW5qZWN0YWJsZSwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IENvbnRleHRNZW51Q29tcG9uZW50IH0gZnJvbSAnLi9jb250ZXh0TWVudS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi9jb250ZXh0TWVudS5pdGVtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQgfSBmcm9tICcuL2NvbnRleHRNZW51Q29udGVudC5jb21wb25lbnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElDb250ZXh0TWVudUNsaWNrRXZlbnQge1xuICBhbmNob3JFbGVtZW50PzogRWxlbWVudCB8IEV2ZW50VGFyZ2V0O1xuICBjb250ZXh0TWVudT86IENvbnRleHRNZW51Q29tcG9uZW50O1xuICBldmVudD86IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50O1xuICBwYXJlbnRDb250ZXh0TWVudT86IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudDtcbiAgaXRlbTogYW55O1xuICBhY3RpdmVNZW51SXRlbUluZGV4PzogbnVtYmVyO1xufVxuZXhwb3J0IGludGVyZmFjZSBJQ29udGV4dE1lbnVDb250ZXh0IGV4dGVuZHMgSUNvbnRleHRNZW51Q2xpY2tFdmVudCB7XG4gIG1lbnVJdGVtczogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlW107XG4gIG1lbnVDbGFzczogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBDbG9zZUxlYWZNZW51RXZlbnQge1xuICBleGNlcHRSb290TWVudT86IGJvb2xlYW47XG4gIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG59XG5leHBvcnQgaW50ZXJmYWNlIE92ZXJsYXlSZWZXaXRoQ29udGV4dE1lbnUgZXh0ZW5kcyBPdmVybGF5UmVmIHtcbiAgY29udGV4dE1lbnU/OiBDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuY2VsQ29udGV4dE1lbnVFdmVudCB7XG4gIGV2ZW50VHlwZTogJ2NhbmNlbCc7XG4gIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG59XG5leHBvcnQgaW50ZXJmYWNlIEV4ZWN1dGVDb250ZXh0TWVudUV2ZW50IHtcbiAgZXZlbnRUeXBlOiAnZXhlY3V0ZSc7XG4gIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG4gIGl0ZW06IGFueTtcbiAgbWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZTtcbn1cbmV4cG9ydCB0eXBlIENsb3NlQ29udGV4dE1lbnVFdmVudCA9IEV4ZWN1dGVDb250ZXh0TWVudUV2ZW50IHwgQ2FuY2VsQ29udGV4dE1lbnVFdmVudDtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbnRleHRNZW51U2VydmljZSB7XG4gIHB1YmxpYyBpc0Rlc3Ryb3lpbmdMZWFmTWVudSA9IGZhbHNlO1xuXG4gIHB1YmxpYyBzaG93OiBTdWJqZWN0PElDb250ZXh0TWVudUNsaWNrRXZlbnQ+ID0gbmV3IFN1YmplY3Q8SUNvbnRleHRNZW51Q2xpY2tFdmVudD4oKTtcbiAgcHVibGljIHRyaWdnZXJDbG9zZTogU3ViamVjdDxDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQ+ID0gbmV3IFN1YmplY3QoKTtcbiAgcHVibGljIGNsb3NlOiBTdWJqZWN0PENsb3NlQ29udGV4dE1lbnVFdmVudD4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIHByaXZhdGUgY29udGV4dE1lbnVDb250ZW50OiBDb21wb25lbnRSZWY8Q29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50PjtcbiAgcHJpdmF0ZSBvdmVybGF5czogT3ZlcmxheVJlZltdID0gW107XG4gIHByaXZhdGUgZmFrZUVsZW1lbnQ6IGFueSA9IHtcbiAgICBnZXRCb3VuZGluZ0NsaWVudFJlY3Q6ICgpOiBDbGllbnRSZWN0ID0+ICh7XG4gICAgICBib3R0b206IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogMCxcbiAgICB9KVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgb3ZlcmxheTogT3ZlcmxheSxcbiAgICBwcml2YXRlIHNjcm9sbFN0cmF0ZWd5OiBTY3JvbGxTdHJhdGVneU9wdGlvbnMsXG4gICkgeyB9XG5cbiAgcHVibGljIG9wZW5Db250ZXh0TWVudShjb250ZXh0OiBJQ29udGV4dE1lbnVDb250ZXh0KSB7XG4gICAgY29uc3QgeyBhbmNob3JFbGVtZW50LCBldmVudCwgcGFyZW50Q29udGV4dE1lbnUgfSA9IGNvbnRleHQ7XG5cbiAgICBpZiAoIXBhcmVudENvbnRleHRNZW51KSB7XG4gICAgICBjb25zdCBtb3VzZUV2ZW50ID0gZXZlbnQgYXMgTW91c2VFdmVudDtcbiAgICAgIHRoaXMuZmFrZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID0gKCk6IENsaWVudFJlY3QgPT4gKHtcbiAgICAgICAgYm90dG9tOiBtb3VzZUV2ZW50LmNsaWVudFksXG4gICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgbGVmdDogbW91c2VFdmVudC5jbGllbnRYLFxuICAgICAgICByaWdodDogbW91c2VFdmVudC5jbGllbnRYLFxuICAgICAgICB0b3A6IG1vdXNlRXZlbnQuY2xpZW50WSxcbiAgICAgICAgd2lkdGg6IDAsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2xvc2VBbGxDb250ZXh0TWVudXMoeyBldmVudFR5cGU6ICdjYW5jZWwnLCBldmVudCB9KTtcbiAgICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3kgPSB0aGlzLm92ZXJsYXkucG9zaXRpb24oKS5jb25uZWN0ZWRUbyhcbiAgICAgICAgbmV3IEVsZW1lbnRSZWYoYW5jaG9yRWxlbWVudCB8fCB0aGlzLmZha2VFbGVtZW50KSxcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnYm90dG9tJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSlcbiAgICAgICAgLndpdGhGYWxsYmFja1Bvc2l0aW9uKFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnYm90dG9tJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ2VuZCcsIG9yaWdpblk6ICd0b3AnIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ2VuZCcsIG92ZXJsYXlZOiAndG9wJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ2VuZCcsIG9yaWdpblk6ICdjZW50ZXInIH0sXG4gICAgICAgIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9KVxuICAgICAgICAud2l0aEZhbGxiYWNrUG9zaXRpb24oXG4gICAgICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ2NlbnRlcicgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ2VuZCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9KVxuICAgICAgICA7XG4gICAgICB0aGlzLm92ZXJsYXlzID0gW3RoaXMub3ZlcmxheS5jcmVhdGUoe1xuICAgICAgICBwb3NpdGlvblN0cmF0ZWd5LFxuICAgICAgICBwYW5lbENsYXNzOiAnbmd4LWNvbnRleHRtZW51JyxcbiAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMuc2Nyb2xsU3RyYXRlZ3kuY2xvc2UoKSxcbiAgICAgIH0pXTtcbiAgICAgIHRoaXMuYXR0YWNoQ29udGV4dE1lbnUodGhpcy5vdmVybGF5c1swXSwgY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3kgPSB0aGlzLm92ZXJsYXkucG9zaXRpb24oKS5jb25uZWN0ZWRUbyhcbiAgICAgICAgbmV3IEVsZW1lbnRSZWYoZXZlbnQgPyBldmVudC50YXJnZXQgOiBhbmNob3JFbGVtZW50KSxcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ3RvcCcgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAndG9wJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICd0b3AnIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2JvdHRvbScgfSxcbiAgICAgICAgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH0pXG4gICAgICAgIC53aXRoRmFsbGJhY2tQb3NpdGlvbihcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnYm90dG9tJyB9LFxuICAgICAgICB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICdib3R0b20nIH0pXG4gICAgICAgIDtcbiAgICAgIGNvbnN0IG5ld092ZXJsYXkgPSB0aGlzLm92ZXJsYXkuY3JlYXRlKHtcbiAgICAgICAgcG9zaXRpb25TdHJhdGVneSxcbiAgICAgICAgcGFuZWxDbGFzczogJ25neC1jb250ZXh0bWVudScsXG4gICAgICAgIHNjcm9sbFN0cmF0ZWd5OiB0aGlzLnNjcm9sbFN0cmF0ZWd5LmNsb3NlKCksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZGVzdHJveVN1Yk1lbnVzKHBhcmVudENvbnRleHRNZW51KTtcbiAgICAgIHRoaXMub3ZlcmxheXMgPSB0aGlzLm92ZXJsYXlzLmNvbmNhdChuZXdPdmVybGF5KTtcbiAgICAgIHRoaXMuYXR0YWNoQ29udGV4dE1lbnUobmV3T3ZlcmxheSwgY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGF0dGFjaENvbnRleHRNZW51KG92ZXJsYXk6IE92ZXJsYXlSZWYsIGNvbnRleHQ6IElDb250ZXh0TWVudUNvbnRleHQpOiB2b2lkIHtcbiAgICBjb25zdCB7IGV2ZW50LCBpdGVtLCBtZW51SXRlbXMsIG1lbnVDbGFzcyB9ID0gY29udGV4dDtcblxuICAgIGNvbnN0IGNvbnRleHRNZW51Q29udGVudDogQ29tcG9uZW50UmVmPENvbnRleHRNZW51Q29udGVudENvbXBvbmVudD4gPSBvdmVybGF5LmF0dGFjaChuZXcgQ29tcG9uZW50UG9ydGFsKENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCkpO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5ldmVudCA9IGV2ZW50O1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5pdGVtID0gaXRlbTtcbiAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UubWVudUl0ZW1zID0gbWVudUl0ZW1zO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5vdmVybGF5ID0gb3ZlcmxheTtcbiAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UuaXNMZWFmID0gdHJ1ZTtcbiAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UubWVudUNsYXNzID0gbWVudUNsYXNzO1xuICAgICg8T3ZlcmxheVJlZldpdGhDb250ZXh0TWVudT5vdmVybGF5KS5jb250ZXh0TWVudSA9IGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZTtcblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgICBzdWJzY3JpcHRpb25zLmFkZChjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UuZXhlY3V0ZS5hc09ic2VydmFibGUoKVxuICAgICAgLnN1YnNjcmliZSgoZXhlY3V0ZUV2ZW50KSA9PiB0aGlzLmNsb3NlQWxsQ29udGV4dE1lbnVzKHsgZXZlbnRUeXBlOiAnZXhlY3V0ZScsIC4uLmV4ZWN1dGVFdmVudCB9KSkpO1xuICAgIHN1YnNjcmlwdGlvbnMuYWRkKGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5jbG9zZUFsbE1lbnVzLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAuc3Vic2NyaWJlKChjbG9zZUFsbEV2ZW50KSA9PiB0aGlzLmNsb3NlQWxsQ29udGV4dE1lbnVzKHsgZXZlbnRUeXBlOiAnY2FuY2VsJywgLi4uY2xvc2VBbGxFdmVudCB9KSkpO1xuICAgIHN1YnNjcmlwdGlvbnMuYWRkKGNvbnRleHRNZW51Q29udGVudC5pbnN0YW5jZS5jbG9zZUxlYWZNZW51LmFzT2JzZXJ2YWJsZSgpXG4gICAgICAuc3Vic2NyaWJlKGNsb3NlTGVhZk1lbnVFdmVudCA9PiB0aGlzLmRlc3Ryb3lMZWFmTWVudShjbG9zZUxlYWZNZW51RXZlbnQpKSk7XG4gICAgc3Vic2NyaXB0aW9ucy5hZGQoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLm9wZW5TdWJNZW51LmFzT2JzZXJ2YWJsZSgpXG4gICAgICAuc3Vic2NyaWJlKChzdWJNZW51RXZlbnQ6IElDb250ZXh0TWVudUNvbnRleHQpID0+IHtcbiAgICAgICAgdGhpcy5kZXN0cm95U3ViTWVudXMoY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlKTtcbiAgICAgICAgaWYgKCFzdWJNZW51RXZlbnQuY29udGV4dE1lbnUpIHtcbiAgICAgICAgICBjb250ZXh0TWVudUNvbnRlbnQuaW5zdGFuY2UuaXNMZWFmID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dE1lbnVDb250ZW50Lmluc3RhbmNlLmlzTGVhZiA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNob3cubmV4dChzdWJNZW51RXZlbnQpO1xuICAgICAgfSkpO1xuICAgIGNvbnRleHRNZW51Q29udGVudC5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgbWVudUl0ZW1zLmZvckVhY2gobWVudUl0ZW0gPT4gbWVudUl0ZW0uaXNBY3RpdmUgPSBmYWxzZSk7XG4gICAgICBzdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgfSk7XG4gICAgY29udGV4dE1lbnVDb250ZW50LmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBjbG9zZUFsbENvbnRleHRNZW51cyhjbG9zZUV2ZW50OiBDbG9zZUNvbnRleHRNZW51RXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vdmVybGF5cykge1xuICAgICAgdGhpcy5jbG9zZS5uZXh0KGNsb3NlRXZlbnQpO1xuICAgICAgdGhpcy5vdmVybGF5cy5mb3JFYWNoKChvdmVybGF5LCBpbmRleCkgPT4ge1xuICAgICAgICBvdmVybGF5LmRldGFjaCgpO1xuICAgICAgICBvdmVybGF5LmRpc3Bvc2UoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLm92ZXJsYXlzID0gW107XG4gIH1cblxuICBwdWJsaWMgZ2V0TGFzdEF0dGFjaGVkT3ZlcmxheSgpOiBPdmVybGF5UmVmV2l0aENvbnRleHRNZW51IHtcbiAgICBsZXQgb3ZlcmxheTogT3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheXNbdGhpcy5vdmVybGF5cy5sZW5ndGggLSAxXTtcbiAgICB3aGlsZSAodGhpcy5vdmVybGF5cy5sZW5ndGggPiAxICYmIG92ZXJsYXkgJiYgIW92ZXJsYXkuaGFzQXR0YWNoZWQoKSkge1xuICAgICAgb3ZlcmxheS5kZXRhY2goKTtcbiAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5vdmVybGF5cyA9IHRoaXMub3ZlcmxheXMuc2xpY2UoMCwgLTEpO1xuICAgICAgb3ZlcmxheSA9IHRoaXMub3ZlcmxheXNbdGhpcy5vdmVybGF5cy5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgcmV0dXJuIG92ZXJsYXk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveUxlYWZNZW51KHsgZXhjZXB0Um9vdE1lbnUsIGV2ZW50IH06IENsb3NlTGVhZk1lbnVFdmVudCA9IHt9KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNEZXN0cm95aW5nTGVhZk1lbnUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pc0Rlc3Ryb3lpbmdMZWFmTWVudSA9IHRydWU7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IG92ZXJsYXkgPSB0aGlzLmdldExhc3RBdHRhY2hlZE92ZXJsYXkoKTtcbiAgICAgIGlmICh0aGlzLm92ZXJsYXlzLmxlbmd0aCA+IDEgJiYgb3ZlcmxheSkge1xuICAgICAgICBvdmVybGF5LmRldGFjaCgpO1xuICAgICAgICBvdmVybGF5LmRpc3Bvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhjZXB0Um9vdE1lbnUgJiYgdGhpcy5vdmVybGF5cy5sZW5ndGggPiAwICYmIG92ZXJsYXkpIHtcbiAgICAgICAgdGhpcy5jbG9zZS5uZXh0KHsgZXZlbnRUeXBlOiAnY2FuY2VsJywgZXZlbnQgfSk7XG4gICAgICAgIG92ZXJsYXkuZGV0YWNoKCk7XG4gICAgICAgIG92ZXJsYXkuZGlzcG9zZSgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdMZWFmID0gdGhpcy5nZXRMYXN0QXR0YWNoZWRPdmVybGF5KCk7XG4gICAgICBpZiAobmV3TGVhZikge1xuICAgICAgICBuZXdMZWFmLmNvbnRleHRNZW51LmlzTGVhZiA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaXNEZXN0cm95aW5nTGVhZk1lbnUgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95U3ViTWVudXMoY29udGV4dE1lbnU6IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudCk6IHZvaWQge1xuICAgIGNvbnN0IG92ZXJsYXkgPSBjb250ZXh0TWVudS5vdmVybGF5O1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vdmVybGF5cy5pbmRleE9mKG92ZXJsYXkpO1xuICAgIHRoaXMub3ZlcmxheXMuc2xpY2UoaW5kZXggKyAxKS5mb3JFYWNoKHN1Yk1lbnVPdmVybGF5ID0+IHtcbiAgICAgIHN1Yk1lbnVPdmVybGF5LmRldGFjaCgpO1xuICAgICAgc3ViTWVudU92ZXJsYXkuZGlzcG9zZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGlzTGVhZk1lbnUoY29udGV4dE1lbnVDb250ZW50OiBDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBvdmVybGF5ID0gdGhpcy5nZXRMYXN0QXR0YWNoZWRPdmVybGF5KCk7XG4gICAgcmV0dXJuIGNvbnRleHRNZW51Q29udGVudC5vdmVybGF5ID09PSBvdmVybGF5O1xuICB9XG59XG4iXX0=