@hoso/ngx-contextmenu
Version:
An Angular component to show a context menu on an arbitrary component
164 lines • 28.9 kB
JavaScript
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=