UNPKG

ngx-modialog-11

Version:
223 lines 27.3 kB
import { Component, ElementRef, ViewChild, ViewContainerRef, ViewEncapsulation, Renderer2, TemplateRef, HostListener } from '@angular/core'; import { PromiseCompleter, supportsKey } from '../framework/utils'; import { DialogRef } from '../models/dialog-ref'; import { BaseDynamicComponent } from '../components/index'; // TODO: use DI factory for this. // TODO: consolidate dup code const isDoc = !(typeof document === 'undefined' || !document); /** * Represents the modal overlay. */ // tslint:disable-next-line:component-class-suffix export class ModalOverlay extends BaseDynamicComponent { constructor(dialogRef, vcr, el, renderer) { super(el, renderer); this.dialogRef = dialogRef; this.vcr = vcr; this.activateAnimationListener(); } /** * @internal */ getProjectables(content) { let nodes; if (typeof content === 'string') { nodes = [[this.renderer.createText(`${content}`)]]; } else if (content instanceof TemplateRef) { nodes = [this.vcr.createEmbeddedView(content, { $implicit: this.dialogRef.context, dialogRef: this.dialogRef }).rootNodes]; } else { nodes = [this.embedComponent({ component: content }).rootNodes]; } return nodes; } embedComponent(config) { const ctx = config; return this.vcr.createEmbeddedView(this.template, { $implicit: ctx }); } addComponent(type, projectableNodes = []) { return super._addComponent({ component: type, vcRef: this.innerVcr, projectableNodes }); } fullscreen() { const style = { position: 'fixed', top: 0, left: 0, bottom: 0, right: 0, 'z-index': 1500 }; Object.keys(style).forEach(k => this.setStyle(k, style[k])); } insideElement() { const style = { position: 'absolute', overflow: 'hidden', width: '100%', height: '100%', top: 0, left: 0, bottom: 0, right: 0 }; Object.keys(style).forEach(k => this.setStyle(k, style[k])); } /** * Set a specific inline style for the container of the whole dialog component * The dialog component root element is the host of this component, it contains only 1 direct * child which is the container. * * Structure: * * ```html * <modal-overlay> * <div> * <!-- BACKDROP ELEMENT --> * <!-- DIALOG CONTAINER ELEMENT --> * </div> * </modal-overlay> * ``` * * @param prop The style key * @param value The value, undefined to remove */ setContainerStyle(prop, value) { this.renderer.setStyle(this.container.nativeElement, prop, value); return this; } /** * Define an element that click inside it will not trigger modal close. * Since events bubble, clicking on a dialog will bubble up to the overlay, a plugin * must define an element that represent the dialog, the overlay will make sure no to close when * it was clicked. * @param element */ setClickBoundary(element) { let target; const elListener = event => target = event.target; const docListener = event => { if (this.dialogRef.context.isBlocking || !this.dialogRef.overlay.isTopMost(this.dialogRef)) { return; } let current = event.target; // on click, this will hit. if (current === target) { return; } // on mouse down -> drag -> release the current might not be 'target', it might be // a sibling or a child (i.e: not part of the tree-up direction). It might also be a release // outside the dialog... so we compare to the boundary element do { if (current === element) { return; } } while (current.parentNode && (current = current.parentNode)); this.dialogRef.dismiss(); }; if (isDoc) { this.dialogRef.onDestroy.subscribe(() => { element.removeEventListener('click', elListener, false); element.removeEventListener('touchstart', elListener, false); document.removeEventListener('click', docListener, false); document.removeEventListener('touchend', docListener, false); }); setTimeout(() => { element.addEventListener('mousedown', elListener, false); element.addEventListener('touchstart', docListener, false); document.addEventListener('click', docListener, false); document.addEventListener('touchend', docListener, false); }); } } /** * Temp workaround for animation where destruction of the top level component does not * trigger child animations. Solution should be found either in animation module or in design * of the modal component tree. */ canDestroy() { const completer = new PromiseCompleter(); if (!Array.isArray(this.beforeDestroyHandlers)) { completer.resolve(); } else { // run destroy notification but protect against halt. let id = setTimeout(() => { id = null; completer.reject(); }, 1000); const resolve = () => { if (id === null) { return; } clearTimeout(id); completer.resolve(); }; Promise.all(this.beforeDestroyHandlers.map(fn => fn())) .then(resolve) .catch(resolve); } return completer.promise; } /** * A handler running before destruction of the overlay * use to delay destruction due to animation. * This is part of the workaround for animation, see canDestroy. * * NOTE: There is no guarantee that the listeners will fire, use dialog.onDestory for that. * @param fn */ beforeDestroy(fn) { if (!this.beforeDestroyHandlers) { this.beforeDestroyHandlers = []; } this.beforeDestroyHandlers.push(fn); } documentKeypress(event) { // check that this modal is the last in the stack. if (!this.dialogRef.overlay.isTopMost(this.dialogRef)) { return; } if (supportsKey(event.keyCode, this.dialogRef.context.keyboard)) { this.dialogRef.dismiss(); } } ngOnDestroy() { super.ngOnDestroy(); if (this.dialogRef.destroyed !== true) { // if we're here the overlay is destroyed by an external event that is not user invoked. // i.e: The user did no call dismiss or close and dialogRef.destroy() did not invoke. // this will happen when routing or killing an element containing a blocked overlay (ngIf) // we bail out, i.e gracefully shutting down. this.dialogRef.bailOut(); } } } ModalOverlay.decorators = [ { type: Component, args: [{ // tslint:disable-next-line:component-selector selector: 'modal-overlay', encapsulation: ViewEncapsulation.None, template: "<div #container>\r\n <ng-template #innerView></ng-template>\r\n</div>\r\n<ng-template #template let-ctx>\r\n <ng-container *ngComponentOutlet=\"ctx.component; injector: ctx.injector; content: ctx.projectableNodes\"></ng-container>\r\n</ng-template>" },] } ]; /** @nocollapse */ ModalOverlay.ctorParameters = () => [ { type: DialogRef }, { type: ViewContainerRef }, { type: ElementRef }, { type: Renderer2 } ]; ModalOverlay.propDecorators = { container: [{ type: ViewChild, args: ['container', { read: ElementRef, static: true },] }], innerVcr: [{ type: ViewChild, args: ['innerView', { read: ViewContainerRef, static: true },] }], template: [{ type: ViewChild, args: ['template', { static: true },] }], documentKeypress: [{ type: HostListener, args: ['body:keydown', ['$event'],] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbW9kaWFsb2ctMTEvc3JjL2xpYi9vdmVybGF5L292ZXJsYXkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFDTCxTQUFTLEVBRVQsVUFBVSxFQUdWLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxXQUFXLEVBQUUsWUFBWSxFQUMxQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTNELGlDQUFpQztBQUNqQyw2QkFBNkI7QUFDN0IsTUFBTSxLQUFLLEdBQVksQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBT3ZFOztHQUVHO0FBT0gsa0RBQWtEO0FBQ2xELE1BQU0sT0FBTyxZQUFhLFNBQVEsb0JBQW9CO0lBT3BELFlBQW9CLFNBQXlCLEVBQ3pCLEdBQXFCLEVBQzdCLEVBQWMsRUFDZCxRQUFtQjtRQUM3QixLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBSkYsY0FBUyxHQUFULFNBQVMsQ0FBZ0I7UUFDekIsUUFBRyxHQUFILEdBQUcsQ0FBa0I7UUFJdkMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZSxDQUFJLE9BQXlCO1FBRTFDLElBQUksS0FBWSxDQUFDO1FBQ2pCLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQy9CLEtBQUssR0FBRyxDQUFDLENBQUMsSUFB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QUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTsrQkFtTXRDLFlBQVksU0FBQyxjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIGNvbnN0IGNsZWFyVGltZW91dDogYW55O1xyXG5cclxuaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgQ29tcG9uZW50UmVmLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRW1iZWRkZWRWaWV3UmVmLFxyXG4gIEluamVjdG9yLFxyXG4gIFZpZXdDaGlsZCxcclxuICBWaWV3Q29udGFpbmVyUmVmLFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG4gIFJlbmRlcmVyMixcclxuICBUZW1wbGF0ZVJlZiwgSG9zdExpc3RlbmVyXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBQcm9taXNlQ29tcGxldGVyLCBzdXBwb3J0c0tleSB9IGZyb20gJy4uL2ZyYW1ld29yay91dGlscyc7XHJcbmltcG9ydCB7IERpYWxvZ1JlZiB9IGZyb20gJy4uL21vZGVscy9kaWFsb2ctcmVmJztcclxuaW1wb3J0IHsgQ29udGFpbmVyQ29udGVudCB9IGZyb20gJy4uL21vZGVscy90b2tlbnMnO1xyXG5pbXBvcnQgeyBCYXNlRHluYW1pY0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvaW5kZXgnO1xyXG5cclxuLy8gVE9ETzogdXNlIERJIGZhY3RvcnkgZm9yIHRoaXMuXHJcbi8vIFRPRE86IGNvbnNvbGlkYXRlIGR1cCBjb2RlXHJcbmNvbnN0IGlzRG9jOiBib29sZWFuID0gISh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICFkb2N1bWVudCk7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEVtYmVkQ29tcG9uZW50Q29uZmlnIHtcclxuICBjb21wb25lbnQ6IGFueTtcclxuICBwcm9qZWN0YWJsZU5vZGVzPzogYW55W11bXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlcHJlc2VudHMgdGhlIG1vZGFsIG92ZXJsYXkuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y29tcG9uZW50LXNlbGVjdG9yXHJcbiAgc2VsZWN0b3I6ICdtb2RhbC1vdmVybGF5JyxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9vdmVybGF5LmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y29tcG9uZW50LWNsYXNzLXN1ZmZpeFxyXG5leHBvcnQgY2xhc3MgTW9kYWxPdmVybGF5IGV4dGVuZHMgQmFzZUR5bmFtaWNDb21wb25lbnQge1xyXG4gIHByaXZhdGUgYmVmb3JlRGVzdHJveUhhbmRsZXJzOiBBcnJheTwoKSA9PiBQcm9taXNlPHZvaWQ+PjtcclxuXHJcbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywge3JlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZX0pIHB1YmxpYyBjb250YWluZXI6IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnaW5uZXJWaWV3Jywge3JlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgaW5uZXJWY3I6IFZpZXdDb250YWluZXJSZWY7XHJcbiAgQFZpZXdDaGlsZCgndGVtcGxhdGUnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nUmVmOiBEaWFsb2dSZWY8YW55PixcclxuICAgICAgICAgICAgICBwcml2YXRlIHZjcjogVmlld0NvbnRhaW5lclJlZixcclxuICAgICAgICAgICAgICBlbDogRWxlbWVudFJlZixcclxuICAgICAgICAgICAgICByZW5kZXJlcjogUmVuZGVyZXIyKSB7XHJcbiAgICBzdXBlcihlbCwgcmVuZGVyZXIpO1xyXG4gICAgdGhpcy5hY3RpdmF0ZUFuaW1hdGlvbkxpc3RlbmVyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAaW50ZXJuYWxcclxuICAgKi9cclxuICBnZXRQcm9qZWN0YWJsZXM8VD4oY29udGVudDogQ29udGFpbmVyQ29udGVudCk6IGFueVtdW10ge1xyXG5cclxuICAgIGxldCBub2RlczogYW55W107XHJcbiAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIG5vZGVzID0gW1t0aGlzLnJlbmRlcmVyLmNyZWF0ZVRleHQoYCR7Y29udGVudH1gKV1dO1xyXG4gICAgfSBlbHNlIGlmIChjb250ZW50IGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcclxuICAgICAgbm9kZXMgPSBbdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KGNvbnRlbnQsIHskaW1wbGljaXQ6IHRoaXMuZGlhbG9nUmVmLmNvbnRleHQsIGRpYWxvZ1JlZjogdGhpcy5kaWFsb2dSZWZ9KS5yb290Tm9kZXNdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbm9kZXMgPSBbdGhpcy5lbWJlZENvbXBvbmVudCh7Y29tcG9uZW50OiBjb250ZW50fSkucm9vdE5vZGVzXTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbm9kZXM7XHJcbiAgfVxyXG5cclxuICBlbWJlZENvbXBvbmVudChjb25maWc6IEVtYmVkQ29tcG9uZW50Q29uZmlnKTogRW1iZWRkZWRWaWV3UmVmPEVtYmVkQ29tcG9uZW50Q29uZmlnPiB7XHJcbiAgICBjb25zdCBjdHg6IEVtYmVkQ29tcG9uZW50Q29uZmlnICYgeyBpbmplY3RvcjogSW5qZWN0b3IgfSA9IDxhbnk+Y29uZmlnO1xyXG5cclxuICAgIHJldHVybiB0aGlzLnZjci5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy50ZW1wbGF0ZSwgPGFueT57XHJcbiAgICAgICRpbXBsaWNpdDogY3R4XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGFkZENvbXBvbmVudDxUPih0eXBlOiBhbnksIHByb2plY3RhYmxlTm9kZXM6IGFueVtdW10gPSBbXSk6IENvbXBvbmVudFJlZjxUPiB7XHJcbiAgICByZXR1cm4gc3VwZXIuX2FkZENvbXBvbmVudDxUPih7XHJcbiAgICAgIGNvbXBvbmVudDogdHlwZSxcclxuICAgICAgdmNSZWY6IHRoaXMuaW5uZXJWY3IsXHJcbiAgICAgIHByb2plY3RhYmxlTm9kZXNcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVsbHNjcmVlbigpOiB2b2lkIHtcclxuICAgIGNvbnN0IHN0eWxlID0ge1xyXG4gICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcclxuICAgICAgdG9wOiAwLFxyXG4gICAgICBsZWZ0OiAwLFxyXG4gICAgICBib3R0b206IDAsXHJcbiAgICAgIHJpZ2h0OiAwLFxyXG4gICAgICAnei1pbmRleCc6IDE1MDBcclxuICAgIH07XHJcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrID0+IHRoaXMuc2V0U3R5bGUoaywgc3R5bGVba10pKTtcclxuICB9XHJcblxyXG4gIGluc2lkZUVsZW1lbnQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBzdHlsZSA9IHtcclxuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXHJcbiAgICAgIG92ZXJmbG93OiAnaGlkZGVuJyxcclxuICAgICAgd2lkdGg6ICcxMDAlJyxcclxuICAgICAgaGVpZ2h0OiAnMTAwJScsXHJcbiAgICAgIHRvcDogMCxcclxuICAgICAgbGVmdDogMCxcclxuICAgICAgYm90dG9tOiAwLFxyXG4gICAgICByaWdodDogMFxyXG4gICAgfTtcclxuICAgIE9iamVjdC5rZXlzKHN0eWxlKS5mb3JFYWNoKGsgPT4gdGhpcy5zZXRTdHlsZShrLCBzdHlsZVtrXSkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IGEgc3BlY2lmaWMgaW5saW5lIHN0eWxlIGZvciB0aGUgY29udGFpbmVyIG9mIHRoZSB3aG9sZSBkaWFsb2cgY29tcG9uZW50XHJcbiAgICogVGhlIGRpYWxvZyBjb21wb25lbnQgcm9vdCBlbGVtZW50IGlzIHRoZSBob3N0IG9mIHRoaXMgY29tcG9uZW50LCBpdCBjb250YWlucyBvbmx5IDEgZGlyZWN0XHJcbiAgICogY2hpbGQgd2hpY2ggaXMgdGhlIGNvbnRhaW5lci5cclxuICAgKlxyXG4gICAqIFN0cnVjdHVyZTpcclxuICAgKlxyXG4gICAqIGBgYGh0bWxcclxuICAgKiA8bW9kYWwtb3ZlcmxheT5cclxuICAgKiAgIDxkaXY+XHJcbiAgICogICAgIDwhLS0gQkFDS0RST1AgRUxFTUVOVCAtLT5cclxuICAgKiAgICAgPCEtLSBESUFMT0cgQ09OVEFJTkVSIEVMRU1FTlQgLS0+XHJcbiAgICogICA8L2Rpdj5cclxuICAgKiA8L21vZGFsLW92ZXJsYXk+XHJcbiAgICogYGBgXHJcbiAgICpcclxuICAgKiBAcGFyYW0gcHJvcCBUaGUgc3R5bGUga2V5XHJcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSwgdW5kZWZpbmVkIHRvIHJlbW92ZVxyXG4gICAqL1xyXG4gIHNldENvbnRhaW5lclN0eWxlKHByb3A6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHRoaXMge1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCBwcm9wLCB2YWx1ZSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluZSBhbiBlbGVtZW50IHRoYXQgY2xpY2sgaW5zaWRlIGl0IHdpbGwgbm90IHRyaWdnZXIgbW9kYWwgY2xvc2UuXHJcbiAgICogU2luY2UgZXZlbnRzIGJ1YmJsZSwgY2xpY2tpbmcgb24gYSBkaWFsb2cgd2lsbCBidWJibGUgdXAgdG8gdGhlIG92ZXJsYXksIGEgcGx1Z2luXHJcbiAgICogbXVzdCBkZWZpbmUgYW4gZWxlbWVudCB0aGF0IHJlcHJlc2VudCB0aGUgZGlhbG9nLCB0aGUgb3ZlcmxheSB3aWxsIG1ha2Ugc3VyZSBubyB0byBjbG9zZSB3aGVuXHJcbiAgICogaXQgd2FzIGNsaWNrZWQuXHJcbiAgICogQHBhcmFtIGVsZW1lbnRcclxuICAgKi9cclxuICBzZXRDbGlja0JvdW5kYXJ5KGVsZW1lbnQ6IEVsZW1lbnQpOiB2b2lkIHtcclxuICAgIGxldCB0YXJnZXQ6IEVsZW1lbnQ7XHJcbiAgICBjb25zdCBlbExpc3RlbmVyID0gZXZlbnQgPT4gdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIGFueTtcclxuICAgIGNvbnN0IGRvY0xpc3RlbmVyID0gZXZlbnQgPT4ge1xyXG4gICAgICBpZiAodGhpcy5kaWFsb2dSZWYuY29udGV4dC5pc0Jsb2NraW5nIHx8ICF0aGlzLmRpYWxvZ1JlZi5vdmVybGF5LmlzVG9wTW9zdCh0aGlzLmRpYWxvZ1JlZikpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBjdXJyZW50OiBhbnkgPSBldmVudC50YXJnZXQ7XHJcblxyXG4gICAgICAvLyBvbiBjbGljaywgdGhpcyB3aWxsIGhpdC5cclxuICAgICAgaWYgKGN1cnJlbnQgPT09IHRhcmdldCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gb24gbW91c2UgZG93biAtPiBkcmFnIC0+IHJlbGVhc2UgdGhlIGN1cnJlbnQgbWlnaHQgbm90IGJlICd0YXJnZXQnLCBpdCBtaWdodCBiZVxyXG4gICAgICAvLyBhIHNpYmxpbmcgb3IgYSBjaGlsZCAoaS5lOiBub3QgcGFydCBvZiB0aGUgdHJlZS11cCBkaXJlY3Rpb24pLiBJdCBtaWdodCBhbHNvIGJlIGEgcmVsZWFzZVxyXG4gICAgICAvLyBvdXRzaWRlIHRoZSBkaWFsb2cuLi4gc28gd2UgY29tcGFyZSB0byB0aGUgYm91bmRhcnkgZWxlbWVudFxyXG4gICAgICBkbyB7XHJcbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IGVsZW1lbnQpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgIH0gd2hpbGUgKGN1cnJlbnQucGFyZW50Tm9kZSAmJiAoY3VycmVudCA9IGN1cnJlbnQucGFyZW50Tm9kZSkpO1xyXG4gICAgICB0aGlzLmRpYWxvZ1JlZi5kaXNtaXNzKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGlmIChpc0RvYykge1xyXG4gICAgICB0aGlzLmRpYWxvZ1JlZi5vbkRlc3Ryb3kuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZWxMaXN0ZW5lciwgZmFsc2UpO1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGVsTGlzdGVuZXIsIGZhbHNlKTtcclxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XHJcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xyXG4gICAgICB9KTtcclxuXHJcblxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGVsTGlzdGVuZXIsIGZhbHNlKTtcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xyXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcclxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGVtcCB3b3JrYXJvdW5kIGZvciBhbmltYXRpb24gd2hlcmUgZGVzdHJ1Y3Rpb24gb2YgdGhlIHRvcCBsZXZlbCBjb21wb25lbnQgZG9lcyBub3RcclxuICAgKiB0cmlnZ2VyIGNoaWxkIGFuaW1hdGlvbnMuIFNvbHV0aW9uIHNob3VsZCBiZSBmb3VuZCBlaXRoZXIgaW4gYW5pbWF0aW9uIG1vZHVsZSBvciBpbiBkZXNpZ25cclxuICAgKiBvZiB0aGUgbW9kYWwgY29tcG9uZW50IHRyZWUuXHJcbiAgICovXHJcbiAgY2FuRGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGNvbXBsZXRlciA9IG5ldyBQcm9taXNlQ29tcGxldGVyPHZvaWQ+KCk7XHJcblxyXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzKSkge1xyXG4gICAgICBjb21wbGV0ZXIucmVzb2x2ZSgpO1xyXG4gICAgfSBlbHNlIHtcclxuXHJcbiAgICAgIC8vIHJ1biBkZXN0cm95IG5vdGlmaWNhdGlvbiBidXQgcHJvdGVjdCBhZ2FpbnN0IGhhbHQuXHJcbiAgICAgIGxldCBpZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGlkID0gbnVsbDtcclxuICAgICAgICBjb21wbGV0ZXIucmVqZWN0KCk7XHJcbiAgICAgIH0sIDEwMDApO1xyXG5cclxuICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IHtcclxuICAgICAgICBpZiAoaWQgPT09IG51bGwpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNsZWFyVGltZW91dChpZCk7XHJcbiAgICAgICAgY29tcGxldGVyLnJlc29sdmUoKTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIFByb21pc2UuYWxsKHRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzLm1hcChmbiA9PiBmbigpKSlcclxuICAgICAgICAudGhlbihyZXNvbHZlKVxyXG4gICAgICAgIC5jYXRjaChyZXNvbHZlKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNvbXBsZXRlci5wcm9taXNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBoYW5kbGVyIHJ1bm5pbmcgYmVmb3JlIGRlc3RydWN0aW9uIG9mIHRoZSBvdmVybGF5XHJcbiAgICogdXNlIHRvIGRlbGF5IGRlc3RydWN0aW9uIGR1ZSB0byBhbmltYXRpb24uXHJcbiAgICogVGhpcyBpcyBwYXJ0IG9mIHRoZSB3b3JrYXJvdW5kIGZvciBhbmltYXRpb24sIHNlZSBjYW5EZXN0cm95LlxyXG4gICAqXHJcbiAgICogTk9URTogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGxpc3RlbmVycyB3aWxsIGZpcmUsIHVzZSBkaWFsb2cub25EZXN0b3J5IGZvciB0aGF0LlxyXG4gICAqIEBwYXJhbSBmblxyXG4gICAqL1xyXG4gIGJlZm9yZURlc3Ryb3koZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcclxuICAgIGlmICghdGhpcy5iZWZvcmVEZXN0cm95SGFuZGxlcnMpIHtcclxuICAgICAgdGhpcy5iZWZvcmVEZXN0cm95SGFuZGxlcnMgPSBbXTtcclxuICAgIH1cclxuICAgIHRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzLnB1c2goZm4pO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignYm9keTprZXlkb3duJywgWyckZXZlbnQnXSlcclxuICBkb2N1bWVudEtleXByZXNzKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICAvLyBjaGVjayB0aGF0IHRoaXMgbW9kYWwgaXMgdGhlIGxhc3QgaW4gdGhlIHN0YWNrLlxyXG4gICAgaWYgKCF0aGlzLmRpYWxvZ1JlZi5vdmVybGF5LmlzVG9wTW9zdCh0aGlzLmRpYWxvZ1JlZikpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBpZiAoc3VwcG9ydHNLZXkoZXZlbnQua2V5Q29kZSwgPGFueT50aGlzLmRpYWxvZ1JlZi5jb250ZXh0LmtleWJvYXJkKSkge1xyXG4gICAgICB0aGlzLmRpYWxvZ1JlZi5kaXNtaXNzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XHJcbiAgICBpZiAodGhpcy5kaWFsb2dSZWYuZGVzdHJveWVkICE9PSB0cnVlKSB7XHJcbiAgICAgIC8vIGlmIHdlJ3JlIGhlcmUgdGhlIG92ZXJsYXkgaXMgZGVzdHJveWVkIGJ5IGFuIGV4dGVybmFsIGV2ZW50IHRoYXQgaXMgbm90IHVzZXIgaW52b2tlZC5cclxuICAgICAgLy8gaS5lOiBUaGUgdXNlciBkaWQgbm8gY2FsbCBkaXNtaXNzIG9yIGNsb3NlIGFuZCBkaWFsb2dSZWYuZGVzdHJveSgpIGRpZCBub3QgaW52b2tlLlxyXG4gICAgICAvLyB0aGlzIHdpbGwgaGFwcGVuIHdoZW4gcm91dGluZyBvciBraWxsaW5nIGFuIGVsZW1lbnQgY29udGFpbmluZyBhIGJsb2NrZWQgb3ZlcmxheSAobmdJZilcclxuICAgICAgLy8gd2UgYmFpbCBvdXQsIGkuZSBncmFjZWZ1bGx5IHNodXR0aW5nIGRvd24uXHJcbiAgICAgIHRoaXMuZGlhbG9nUmVmLmJhaWxPdXQoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19