UNPKG

ngx-modialog-10

Version:
347 lines 29.6 kB
/** * @fileoverview added by tsickle * Generated from: lib/overlay/overlay.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ 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 /** @type {?} */ const isDoc = !(typeof document === 'undefined' || !document); /** * @record */ export function EmbedComponentConfig() { } if (false) { /** @type {?} */ EmbedComponentConfig.prototype.component; /** @type {?|undefined} */ EmbedComponentConfig.prototype.projectableNodes; } /** * Represents the modal overlay. */ // tslint:disable-next-line:component-class-suffix export class ModalOverlay extends BaseDynamicComponent { /** * @param {?} dialogRef * @param {?} vcr * @param {?} el * @param {?} renderer */ constructor(dialogRef, vcr, el, renderer) { super(el, renderer); this.dialogRef = dialogRef; this.vcr = vcr; this.activateAnimationListener(); } /** * \@internal * @template T * @param {?} content * @return {?} */ getProjectables(content) { /** @type {?} */ 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; } /** * @param {?} config * @return {?} */ embedComponent(config) { /** @type {?} */ const ctx = (/** @type {?} */ (config)); return this.vcr.createEmbeddedView(this.template, (/** @type {?} */ ({ $implicit: ctx }))); } /** * @template T * @param {?} type * @param {?=} projectableNodes * @return {?} */ addComponent(type, projectableNodes = []) { return super._addComponent({ component: type, vcRef: this.innerVcr, projectableNodes }); } /** * @return {?} */ fullscreen() { /** @type {?} */ const style = { position: 'fixed', top: 0, left: 0, bottom: 0, right: 0, 'z-index': 1500 }; Object.keys(style).forEach((/** * @template THIS * @this {THIS} * @param {?} k * @return {THIS} */ k => this.setStyle(k, style[k]))); } /** * @return {?} */ insideElement() { /** @type {?} */ const style = { position: 'absolute', overflow: 'hidden', width: '100%', height: '100%', top: 0, left: 0, bottom: 0, right: 0 }; Object.keys(style).forEach((/** * @template THIS * @this {THIS} * @param {?} k * @return {THIS} */ 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> * ``` * * @template THIS * @this {THIS} * @param {?} prop The style key * @param {?} value The value, undefined to remove * @return {THIS} */ setContainerStyle(prop, value) { (/** @type {?} */ (this)).renderer.setStyle((/** @type {?} */ (this)).container.nativeElement, prop, value); return (/** @type {?} */ (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 * @return {?} */ setClickBoundary(element) { /** @type {?} */ let target; /** @type {?} */ const elListener = (/** * @param {?} event * @return {?} */ event => target = (/** @type {?} */ (event.target))); /** @type {?} */ const docListener = (/** * @param {?} event * @return {?} */ event => { if (this.dialogRef.context.isBlocking || !this.dialogRef.overlay.isTopMost(this.dialogRef)) { return; } /** @type {?} */ 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((/** * @return {?} */ () => { element.removeEventListener('click', elListener, false); element.removeEventListener('touchstart', elListener, false); document.removeEventListener('click', docListener, false); document.removeEventListener('touchend', docListener, false); })); setTimeout((/** * @return {?} */ () => { 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. * @return {?} */ canDestroy() { /** @type {?} */ const completer = new PromiseCompleter(); if (!Array.isArray(this.beforeDestroyHandlers)) { completer.resolve(); } else { // run destroy notification but protect against halt. /** @type {?} */ let id = setTimeout((/** * @return {?} */ () => { id = null; completer.reject(); }), 1000); /** @type {?} */ const resolve = (/** * @return {?} */ () => { if (id === null) { return; } clearTimeout(id); completer.resolve(); }); Promise.all(this.beforeDestroyHandlers.map((/** * @param {?} fn * @return {?} */ 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 * @return {?} */ beforeDestroy(fn) { if (!this.beforeDestroyHandlers) { this.beforeDestroyHandlers = []; } this.beforeDestroyHandlers.push(fn); } /** * @param {?} event * @return {?} */ documentKeypress(event) { // check that this modal is the last in the stack. if (!this.dialogRef.overlay.isTopMost(this.dialogRef)) { return; } if (supportsKey(event.keyCode, (/** @type {?} */ (this.dialogRef.context.keyboard)))) { this.dialogRef.dismiss(); } } /** * @return {?} */ 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>\n <ng-template #innerView></ng-template>\n</div>\n<ng-template #template let-ctx>\n <ng-container *ngComponentOutlet=\"ctx.component; injector: ctx.injector; content: ctx.projectableNodes\"></ng-container>\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'],] }] }; if (false) { /** * @type {?} * @private */ ModalOverlay.prototype.beforeDestroyHandlers; /** @type {?} */ ModalOverlay.prototype.container; /** @type {?} */ ModalOverlay.prototype.innerVcr; /** @type {?} */ ModalOverlay.prototype.template; /** * @type {?} * @private */ ModalOverlay.prototype.dialogRef; /** * @type {?} * @private */ ModalOverlay.prototype.vcr; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtbW9kaWFsb2ctMTAvIiwic291cmNlcyI6WyJsaWIvb3ZlcmxheS9vdmVybGF5LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLE9BQU8sRUFDTCxTQUFTLEVBRVQsVUFBVSxFQUdWLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxXQUFXLEVBQUUsWUFBWSxFQUMxQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7O01BSXJELEtBQUssR0FBWSxDQUFDLENBQUMsT0FBTyxRQUFRLEtBQUssV0FBVyxJQUFJLENBQUMsUUFBUSxDQUFDOzs7O0FBRXRFLDBDQUdDOzs7SUFGQyx5Q0FBZTs7SUFDZixnREFBMkI7Ozs7O0FBWTdCLGtEQUFrRDtBQUNsRCxNQUFNLE9BQU8sWUFBYSxTQUFRLG9CQUFvQjs7Ozs7OztJQU9wRCxZQUFvQixTQUF5QixFQUN6QixHQUFxQixFQUM3QixFQUFjLEVBQ2QsUUFBbUI7UUFDN0IsS0FBSyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUpGLGNBQVMsR0FBVCxTQUFTLENBQWdCO1FBQ3pCLFFBQUcsR0FBSCxHQUFHLENBQWtCO1FBSXZDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO0lBQ25DLENBQUM7Ozs7Ozs7SUFLRCxlQUFlLENBQUksT0FBeUI7O1lBRXRDLEtBQVk7UUFDaEIsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUU7WUFDL0IsS0FBSyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FB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LEVBQUUsSUFBSSxFQUFFOytCQW1NdEMsWUFBWSxTQUFDLGNBQWMsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7Ozs7OztJQXZNeEMsNkNBQTBEOztJQUUxRCxpQ0FBdUY7O0lBQ3ZGLGdDQUFtRzs7SUFDbkcsZ0NBQTJFOzs7OztJQUUvRCxpQ0FBaUM7Ozs7O0lBQ2pDLDJCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImRlY2xhcmUgY29uc3QgY2xlYXJUaW1lb3V0OiBhbnk7XG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29tcG9uZW50UmVmLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEluamVjdG9yLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLCBIb3N0TGlzdGVuZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFByb21pc2VDb21wbGV0ZXIsIHN1cHBvcnRzS2V5IH0gZnJvbSAnLi4vZnJhbWV3b3JrL3V0aWxzJztcbmltcG9ydCB7IERpYWxvZ1JlZiB9IGZyb20gJy4uL21vZGVscy9kaWFsb2ctcmVmJztcbmltcG9ydCB7IENvbnRhaW5lckNvbnRlbnQgfSBmcm9tICcuLi9tb2RlbHMvdG9rZW5zJztcbmltcG9ydCB7IEJhc2VEeW5hbWljQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cy9pbmRleCc7XG5cbi8vIFRPRE86IHVzZSBESSBmYWN0b3J5IGZvciB0aGlzLlxuLy8gVE9ETzogY29uc29saWRhdGUgZHVwIGNvZGVcbmNvbnN0IGlzRG9jOiBib29sZWFuID0gISh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICFkb2N1bWVudCk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW1iZWRDb21wb25lbnRDb25maWcge1xuICBjb21wb25lbnQ6IGFueTtcbiAgcHJvamVjdGFibGVOb2Rlcz86IGFueVtdW107XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgbW9kYWwgb3ZlcmxheS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdtb2RhbC1vdmVybGF5JyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGVVcmw6ICcuL292ZXJsYXkuY29tcG9uZW50Lmh0bWwnXG59KVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNvbXBvbmVudC1jbGFzcy1zdWZmaXhcbmV4cG9ydCBjbGFzcyBNb2RhbE92ZXJsYXkgZXh0ZW5kcyBCYXNlRHluYW1pY0NvbXBvbmVudCB7XG4gIHByaXZhdGUgYmVmb3JlRGVzdHJveUhhbmRsZXJzOiBBcnJheTwoKSA9PiBQcm9taXNlPHZvaWQ+PjtcblxuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7cmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlfSkgcHVibGljIGNvbnRhaW5lcjogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW5uZXJWaWV3Jywge3JlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgaW5uZXJWY3I6IFZpZXdDb250YWluZXJSZWY7XG4gIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlJywgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nUmVmOiBEaWFsb2dSZWY8YW55PixcbiAgICAgICAgICAgICAgcHJpdmF0ZSB2Y3I6IFZpZXdDb250YWluZXJSZWYsXG4gICAgICAgICAgICAgIGVsOiBFbGVtZW50UmVmLFxuICAgICAgICAgICAgICByZW5kZXJlcjogUmVuZGVyZXIyKSB7XG4gICAgc3VwZXIoZWwsIHJlbmRlcmVyKTtcbiAgICB0aGlzLmFjdGl2YXRlQW5pbWF0aW9uTGlzdGVuZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldFByb2plY3RhYmxlczxUPihjb250ZW50OiBDb250YWluZXJDb250ZW50KTogYW55W11bXSB7XG5cbiAgICBsZXQgbm9kZXM6IGFueVtdO1xuICAgIGlmICh0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG5vZGVzID0gW1t0aGlzLnJlbmRlcmVyLmNyZWF0ZVRleHQoYCR7Y29udGVudH1gKV1dO1xuICAgIH0gZWxzZSBpZiAoY29udGVudCBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmKSB7XG4gICAgICBub2RlcyA9IFt0aGlzLnZjci5jcmVhdGVFbWJlZGRlZFZpZXcoY29udGVudCwgeyRpbXBsaWNpdDogdGhpcy5kaWFsb2dSZWYuY29udGV4dCwgZGlhbG9nUmVmOiB0aGlzLmRpYWxvZ1JlZn0pLnJvb3ROb2Rlc107XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGVzID0gW3RoaXMuZW1iZWRDb21wb25lbnQoe2NvbXBvbmVudDogY29udGVudH0pLnJvb3ROb2Rlc107XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgZW1iZWRDb21wb25lbnQoY29uZmlnOiBFbWJlZENvbXBvbmVudENvbmZpZyk6IEVtYmVkZGVkVmlld1JlZjxFbWJlZENvbXBvbmVudENvbmZpZz4ge1xuICAgIGNvbnN0IGN0eDogRW1iZWRDb21wb25lbnRDb25maWcgJiB7IGluamVjdG9yOiBJbmplY3RvciB9ID0gPGFueT5jb25maWc7XG5cbiAgICByZXR1cm4gdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMudGVtcGxhdGUsIDxhbnk+e1xuICAgICAgJGltcGxpY2l0OiBjdHhcbiAgICB9KTtcbiAgfVxuXG4gIGFkZENvbXBvbmVudDxUPih0eXBlOiBhbnksIHByb2plY3RhYmxlTm9kZXM6IGFueVtdW10gPSBbXSk6IENvbXBvbmVudFJlZjxUPiB7XG4gICAgcmV0dXJuIHN1cGVyLl9hZGRDb21wb25lbnQ8VD4oe1xuICAgICAgY29tcG9uZW50OiB0eXBlLFxuICAgICAgdmNSZWY6IHRoaXMuaW5uZXJWY3IsXG4gICAgICBwcm9qZWN0YWJsZU5vZGVzXG4gICAgfSk7XG4gIH1cblxuICBmdWxsc2NyZWVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICB0b3A6IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgYm90dG9tOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICAnei1pbmRleCc6IDE1MDBcbiAgICB9O1xuICAgIE9iamVjdC5rZXlzKHN0eWxlKS5mb3JFYWNoKGsgPT4gdGhpcy5zZXRTdHlsZShrLCBzdHlsZVtrXSkpO1xuICB9XG5cbiAgaW5zaWRlRWxlbWVudCgpOiB2b2lkIHtcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgdG9wOiAwLFxuICAgICAgbGVmdDogMCxcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIHJpZ2h0OiAwXG4gICAgfTtcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrID0+IHRoaXMuc2V0U3R5bGUoaywgc3R5bGVba10pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzcGVjaWZpYyBpbmxpbmUgc3R5bGUgZm9yIHRoZSBjb250YWluZXIgb2YgdGhlIHdob2xlIGRpYWxvZyBjb21wb25lbnRcbiAgICogVGhlIGRpYWxvZyBjb21wb25lbnQgcm9vdCBlbGVtZW50IGlzIHRoZSBob3N0IG9mIHRoaXMgY29tcG9uZW50LCBpdCBjb250YWlucyBvbmx5IDEgZGlyZWN0XG4gICAqIGNoaWxkIHdoaWNoIGlzIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIFN0cnVjdHVyZTpcbiAgICpcbiAgICogYGBgaHRtbFxuICAgKiA8bW9kYWwtb3ZlcmxheT5cbiAgICogICA8ZGl2PlxuICAgKiAgICAgPCEtLSBCQUNLRFJPUCBFTEVNRU5UIC0tPlxuICAgKiAgICAgPCEtLSBESUFMT0cgQ09OVEFJTkVSIEVMRU1FTlQgLS0+XG4gICAqICAgPC9kaXY+XG4gICAqIDwvbW9kYWwtb3ZlcmxheT5cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wIFRoZSBzdHlsZSBrZXlcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSwgdW5kZWZpbmVkIHRvIHJlbW92ZVxuICAgKi9cbiAgc2V0Q29udGFpbmVyU3R5bGUocHJvcDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCBwcm9wLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lIGFuIGVsZW1lbnQgdGhhdCBjbGljayBpbnNpZGUgaXQgd2lsbCBub3QgdHJpZ2dlciBtb2RhbCBjbG9zZS5cbiAgICogU2luY2UgZXZlbnRzIGJ1YmJsZSwgY2xpY2tpbmcgb24gYSBkaWFsb2cgd2lsbCBidWJibGUgdXAgdG8gdGhlIG92ZXJsYXksIGEgcGx1Z2luXG4gICAqIG11c3QgZGVmaW5lIGFuIGVsZW1lbnQgdGhhdCByZXByZXNlbnQgdGhlIGRpYWxvZywgdGhlIG92ZXJsYXkgd2lsbCBtYWtlIHN1cmUgbm8gdG8gY2xvc2Ugd2hlblxuICAgKiBpdCB3YXMgY2xpY2tlZC5cbiAgICogQHBhcmFtIGVsZW1lbnRcbiAgICovXG4gIHNldENsaWNrQm91bmRhcnkoZWxlbWVudDogRWxlbWVudCk6IHZvaWQge1xuICAgIGxldCB0YXJnZXQ6IEVsZW1lbnQ7XG4gICAgY29uc3QgZWxMaXN0ZW5lciA9IGV2ZW50ID0+IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBhbnk7XG4gICAgY29uc3QgZG9jTGlzdGVuZXIgPSBldmVudCA9PiB7XG4gICAgICBpZiAodGhpcy5kaWFsb2dSZWYuY29udGV4dC5pc0Jsb2NraW5nIHx8ICF0aGlzLmRpYWxvZ1JlZi5vdmVybGF5LmlzVG9wTW9zdCh0aGlzLmRpYWxvZ1JlZikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgY3VycmVudDogYW55ID0gZXZlbnQudGFyZ2V0O1xuXG4gICAgICAvLyBvbiBjbGljaywgdGhpcyB3aWxsIGhpdC5cbiAgICAgIGlmIChjdXJyZW50ID09PSB0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBvbiBtb3VzZSBkb3duIC0+IGRyYWcgLT4gcmVsZWFzZSB0aGUgY3VycmVudCBtaWdodCBub3QgYmUgJ3RhcmdldCcsIGl0IG1pZ2h0IGJlXG4gICAgICAvLyBhIHNpYmxpbmcgb3IgYSBjaGlsZCAoaS5lOiBub3QgcGFydCBvZiB0aGUgdHJlZS11cCBkaXJlY3Rpb24pLiBJdCBtaWdodCBhbHNvIGJlIGEgcmVsZWFzZVxuICAgICAgLy8gb3V0c2lkZSB0aGUgZGlhbG9nLi4uIHNvIHdlIGNvbXBhcmUgdG8gdGhlIGJvdW5kYXJ5IGVsZW1lbnRcbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKGN1cnJlbnQucGFyZW50Tm9kZSAmJiAoY3VycmVudCA9IGN1cnJlbnQucGFyZW50Tm9kZSkpO1xuICAgICAgdGhpcy5kaWFsb2dSZWYuZGlzbWlzcygpO1xuICAgIH07XG5cbiAgICBpZiAoaXNEb2MpIHtcbiAgICAgIHRoaXMuZGlhbG9nUmVmLm9uRGVzdHJveS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZWxMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBlbExpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgfSk7XG5cblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZWxMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUZW1wIHdvcmthcm91bmQgZm9yIGFuaW1hdGlvbiB3aGVyZSBkZXN0cnVjdGlvbiBvZiB0aGUgdG9wIGxldmVsIGNvbXBvbmVudCBkb2VzIG5vdFxuICAgKiB0cmlnZ2VyIGNoaWxkIGFuaW1hdGlvbnMuIFNvbHV0aW9uIHNob3VsZCBiZSBmb3VuZCBlaXRoZXIgaW4gYW5pbWF0aW9uIG1vZHVsZSBvciBpbiBkZXNpZ25cbiAgICogb2YgdGhlIG1vZGFsIGNvbXBvbmVudCB0cmVlLlxuICAgKi9cbiAgY2FuRGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb21wbGV0ZXIgPSBuZXcgUHJvbWlzZUNvbXBsZXRlcjx2b2lkPigpO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzKSkge1xuICAgICAgY29tcGxldGVyLnJlc29sdmUoKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBydW4gZGVzdHJveSBub3RpZmljYXRpb24gYnV0IHByb3RlY3QgYWdhaW5zdCBoYWx0LlxuICAgICAgbGV0IGlkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlkID0gbnVsbDtcbiAgICAgICAgY29tcGxldGVyLnJlamVjdCgpO1xuICAgICAgfSwgMTAwMCk7XG5cbiAgICAgIGNvbnN0IHJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgIGlmIChpZCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyVGltZW91dChpZCk7XG4gICAgICAgIGNvbXBsZXRlci5yZXNvbHZlKCk7XG4gICAgICB9O1xuXG4gICAgICBQcm9taXNlLmFsbCh0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycy5tYXAoZm4gPT4gZm4oKSkpXG4gICAgICAgIC50aGVuKHJlc29sdmUpXG4gICAgICAgIC5jYXRjaChyZXNvbHZlKTtcblxuICAgIH1cblxuICAgIHJldHVybiBjb21wbGV0ZXIucHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGhhbmRsZXIgcnVubmluZyBiZWZvcmUgZGVzdHJ1Y3Rpb24gb2YgdGhlIG92ZXJsYXlcbiAgICogdXNlIHRvIGRlbGF5IGRlc3RydWN0aW9uIGR1ZSB0byBhbmltYXRpb24uXG4gICAqIFRoaXMgaXMgcGFydCBvZiB0aGUgd29ya2Fyb3VuZCBmb3IgYW5pbWF0aW9uLCBzZWUgY2FuRGVzdHJveS5cbiAgICpcbiAgICogTk9URTogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGxpc3RlbmVycyB3aWxsIGZpcmUsIHVzZSBkaWFsb2cub25EZXN0b3J5IGZvciB0aGF0LlxuICAgKiBAcGFyYW0gZm5cbiAgICovXG4gIGJlZm9yZURlc3Ryb3koZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBpZiAoIXRoaXMuYmVmb3JlRGVzdHJveUhhbmRsZXJzKSB7XG4gICAgICB0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycy5wdXNoKGZuKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2JvZHk6a2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIGRvY3VtZW50S2V5cHJlc3MoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAvLyBjaGVjayB0aGF0IHRoaXMgbW9kYWwgaXMgdGhlIGxhc3QgaW4gdGhlIHN0YWNrLlxuICAgIGlmICghdGhpcy5kaWFsb2dSZWYub3ZlcmxheS5pc1RvcE1vc3QodGhpcy5kaWFsb2dSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICBpZiAoc3VwcG9ydHNLZXkoZXZlbnQua2V5Q29kZSwgPGFueT50aGlzLmRpYWxvZ1JlZi5jb250ZXh0LmtleWJvYXJkKSkge1xuICAgICAgdGhpcy5kaWFsb2dSZWYuZGlzbWlzcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgaWYgKHRoaXMuZGlhbG9nUmVmLmRlc3Ryb3llZCAhPT0gdHJ1ZSkge1xuICAgICAgLy8gaWYgd2UncmUgaGVyZSB0aGUgb3ZlcmxheSBpcyBkZXN0cm95ZWQgYnkgYW4gZXh0ZXJuYWwgZXZlbnQgdGhhdCBpcyBub3QgdXNlciBpbnZva2VkLlxuICAgICAgLy8gaS5lOiBUaGUgdXNlciBkaWQgbm8gY2FsbCBkaXNtaXNzIG9yIGNsb3NlIGFuZCBkaWFsb2dSZWYuZGVzdHJveSgpIGRpZCBub3QgaW52b2tlLlxuICAgICAgLy8gdGhpcyB3aWxsIGhhcHBlbiB3aGVuIHJvdXRpbmcgb3Iga2lsbGluZyBhbiBlbGVtZW50IGNvbnRhaW5pbmcgYSBibG9ja2VkIG92ZXJsYXkgKG5nSWYpXG4gICAgICAvLyB3ZSBiYWlsIG91dCwgaS5lIGdyYWNlZnVsbHkgc2h1dHRpbmcgZG93bi5cbiAgICAgIHRoaXMuZGlhbG9nUmVmLmJhaWxPdXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==