UNPKG

ngx-modialog-10

Version:
465 lines 34.4 kB
/** * @fileoverview added by tsickle * Generated from: lib/overlay/overlay.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { __extends } from "tslib"; 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 {?} */ var isDoc = !(typeof document === 'undefined' || !document); /** * @record */ export function EmbedComponentConfig() { } if (false) { /** @type {?} */ EmbedComponentConfig.prototype.component; /** @type {?|undefined} */ EmbedComponentConfig.prototype.projectableNodes; } /** * Represents the modal overlay. */ var ModalOverlay = /** @class */ (function (_super) { __extends(ModalOverlay, _super); function ModalOverlay(dialogRef, vcr, el, renderer) { var _this = _super.call(this, el, renderer) || this; _this.dialogRef = dialogRef; _this.vcr = vcr; _this.activateAnimationListener(); return _this; } /** * @internal */ /** * \@internal * @template T * @param {?} content * @return {?} */ ModalOverlay.prototype.getProjectables = /** * \@internal * @template T * @param {?} content * @return {?} */ function (content) { /** @type {?} */ var 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 {?} */ ModalOverlay.prototype.embedComponent = /** * @param {?} config * @return {?} */ function (config) { /** @type {?} */ var ctx = (/** @type {?} */ (config)); return this.vcr.createEmbeddedView(this.template, (/** @type {?} */ ({ $implicit: ctx }))); }; /** * @template T * @param {?} type * @param {?=} projectableNodes * @return {?} */ ModalOverlay.prototype.addComponent = /** * @template T * @param {?} type * @param {?=} projectableNodes * @return {?} */ function (type, projectableNodes) { if (projectableNodes === void 0) { projectableNodes = []; } return _super.prototype._addComponent.call(this, { component: type, vcRef: this.innerVcr, projectableNodes: projectableNodes }); }; /** * @return {?} */ ModalOverlay.prototype.fullscreen = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var 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} */ function (k) { return _this.setStyle(k, style[k]); })); }; /** * @return {?} */ ModalOverlay.prototype.insideElement = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var 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} */ function (k) { return _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 */ /** * 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} */ ModalOverlay.prototype.setContainerStyle = /** * 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} */ function (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 */ /** * 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 {?} */ ModalOverlay.prototype.setClickBoundary = /** * 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 {?} */ function (element) { var _this = this; /** @type {?} */ var target; /** @type {?} */ var elListener = (/** * @param {?} event * @return {?} */ function (event) { return target = (/** @type {?} */ (event.target)); }); /** @type {?} */ var docListener = (/** * @param {?} event * @return {?} */ function (event) { if (_this.dialogRef.context.isBlocking || !_this.dialogRef.overlay.isTopMost(_this.dialogRef)) { return; } /** @type {?} */ var 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 {?} */ function () { element.removeEventListener('click', elListener, false); element.removeEventListener('touchstart', elListener, false); document.removeEventListener('click', docListener, false); document.removeEventListener('touchend', docListener, false); })); setTimeout((/** * @return {?} */ function () { 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. */ /** * 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 {?} */ ModalOverlay.prototype.canDestroy = /** * 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 {?} */ function () { /** @type {?} */ var completer = new PromiseCompleter(); if (!Array.isArray(this.beforeDestroyHandlers)) { completer.resolve(); } else { // run destroy notification but protect against halt. /** @type {?} */ var id_1 = setTimeout((/** * @return {?} */ function () { id_1 = null; completer.reject(); }), 1000); /** @type {?} */ var resolve = (/** * @return {?} */ function () { if (id_1 === null) { return; } clearTimeout(id_1); completer.resolve(); }); Promise.all(this.beforeDestroyHandlers.map((/** * @param {?} fn * @return {?} */ function (fn) { return 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 */ /** * 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 {?} */ ModalOverlay.prototype.beforeDestroy = /** * 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 {?} */ function (fn) { if (!this.beforeDestroyHandlers) { this.beforeDestroyHandlers = []; } this.beforeDestroyHandlers.push(fn); }; /** * @param {?} event * @return {?} */ ModalOverlay.prototype.documentKeypress = /** * @param {?} event * @return {?} */ function (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 {?} */ ModalOverlay.prototype.ngOnDestroy = /** * @return {?} */ function () { _super.prototype.ngOnDestroy.call(this); 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 = function () { return [ { 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'],] }] }; return ModalOverlay; }(BaseDynamicComponent)); export { ModalOverlay }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtbW9kaWFsb2ctMTAvIiwic291cmNlcyI6WyJsaWIvb3ZlcmxheS9vdmVybGF5LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFVBQVUsRUFHVixTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsV0FBVyxFQUFFLFlBQVksRUFDMUIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7OztJQUlyRCxLQUFLLEdBQVksQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7OztBQUV0RSwwQ0FHQzs7O0lBRkMseUNBQWU7O0lBQ2YsZ0RBQTJCOzs7OztBQU03QjtJQU9rQyxnQ0FBb0I7SUFPcEQsc0JBQW9CLFNBQXlCLEVBQ3pCLEdBQXFCLEVBQzdCLEVBQWMsRUFDZCxRQUFtQjtRQUgvQixZQUlFLGtCQUFNLEVBQUUsRUFBRSxRQUFRLENBQUMsU0FFcEI7UUFObUIsZUFBUyxHQUFULFNBQVMsQ0FBZ0I7UUFDekIsU0FBRyxHQUFILEdBQUcsQ0FBa0I7UUFJdkMsS0FBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7O0lBQ25DLENBQUM7SUFFRDs7T0FFRzs7Ozs7OztJQUNILHNDQUFlOzs7Ozs7SUFBZixVQUFtQixPQUF5Qjs7WUFFdEMsS0FBWTtRQUNoQixJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtZQUMvQixLQUFLLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEtB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QUN4Qzs7OztnQkFyQlEsU0FBUztnQkFQaEIsZ0JBQWdCO2dCQUpoQixVQUFVO2dCQU1WLFNBQVM7Ozs0QkErQlIsU0FBUyxTQUFDLFdBQVcsRUFBRSxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQzsyQkFDdkQsU0FBUyxTQUFDLFdBQVcsRUFBRSxFQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFOzJCQUM5RCxTQUFTLFNBQUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTttQ0FtTXRDLFlBQVksU0FBQyxjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUM7O0lBdUIxQyxtQkFBQztDQUFBLEFBdE9ELENBT2tDLG9CQUFvQixHQStOckQ7U0EvTlksWUFBWTs7Ozs7O0lBQ3ZCLDZDQUEwRDs7SUFFMUQsaUNBQXVGOztJQUN2RixnQ0FBbUc7O0lBQ25HLGdDQUEyRTs7Ozs7SUFFL0QsaUNBQWlDOzs7OztJQUNqQywyQkFBNkIiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIGNvbnN0IGNsZWFyVGltZW91dDogYW55O1xuXG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIENvbXBvbmVudFJlZixcbiAgRWxlbWVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBJbmplY3RvcixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgUmVuZGVyZXIyLFxuICBUZW1wbGF0ZVJlZiwgSG9zdExpc3RlbmVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBQcm9taXNlQ29tcGxldGVyLCBzdXBwb3J0c0tleSB9IGZyb20gJy4uL2ZyYW1ld29yay91dGlscyc7XG5pbXBvcnQgeyBEaWFsb2dSZWYgfSBmcm9tICcuLi9tb2RlbHMvZGlhbG9nLXJlZic7XG5pbXBvcnQgeyBDb250YWluZXJDb250ZW50IH0gZnJvbSAnLi4vbW9kZWxzL3Rva2Vucyc7XG5pbXBvcnQgeyBCYXNlRHluYW1pY0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvaW5kZXgnO1xuXG4vLyBUT0RPOiB1c2UgREkgZmFjdG9yeSBmb3IgdGhpcy5cbi8vIFRPRE86IGNvbnNvbGlkYXRlIGR1cCBjb2RlXG5jb25zdCBpc0RvYzogYm9vbGVhbiA9ICEodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyB8fCAhZG9jdW1lbnQpO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVtYmVkQ29tcG9uZW50Q29uZmlnIHtcbiAgY29tcG9uZW50OiBhbnk7XG4gIHByb2plY3RhYmxlTm9kZXM/OiBhbnlbXVtdO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIG1vZGFsIG92ZXJsYXkuXG4gKi9cbkBDb21wb25lbnQoe1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbW9kYWwtb3ZlcmxheScsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHRlbXBsYXRlVXJsOiAnLi9vdmVybGF5LmNvbXBvbmVudC5odG1sJ1xufSlcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtY2xhc3Mtc3VmZml4XG5leHBvcnQgY2xhc3MgTW9kYWxPdmVybGF5IGV4dGVuZHMgQmFzZUR5bmFtaWNDb21wb25lbnQge1xuICBwcml2YXRlIGJlZm9yZURlc3Ryb3lIYW5kbGVyczogQXJyYXk8KCkgPT4gUHJvbWlzZTx2b2lkPj47XG5cbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywge3JlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZX0pIHB1YmxpYyBjb250YWluZXI6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lubmVyVmlldycsIHtyZWFkOiBWaWV3Q29udGFpbmVyUmVmLCBzdGF0aWM6IHRydWUgfSkgcHVibGljIGlubmVyVmNyOiBWaWV3Q29udGFpbmVyUmVmO1xuICBAVmlld0NoaWxkKCd0ZW1wbGF0ZScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyB0ZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpYWxvZ1JlZjogRGlhbG9nUmVmPGFueT4sXG4gICAgICAgICAgICAgIHByaXZhdGUgdmNyOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgICAgICAgICAgICBlbDogRWxlbWVudFJlZixcbiAgICAgICAgICAgICAgcmVuZGVyZXI6IFJlbmRlcmVyMikge1xuICAgIHN1cGVyKGVsLCByZW5kZXJlcik7XG4gICAgdGhpcy5hY3RpdmF0ZUFuaW1hdGlvbkxpc3RlbmVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBnZXRQcm9qZWN0YWJsZXM8VD4oY29udGVudDogQ29udGFpbmVyQ29udGVudCk6IGFueVtdW10ge1xuXG4gICAgbGV0IG5vZGVzOiBhbnlbXTtcbiAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBub2RlcyA9IFtbdGhpcy5yZW5kZXJlci5jcmVhdGVUZXh0KGAke2NvbnRlbnR9YCldXTtcbiAgICB9IGVsc2UgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xuICAgICAgbm9kZXMgPSBbdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KGNvbnRlbnQsIHskaW1wbGljaXQ6IHRoaXMuZGlhbG9nUmVmLmNvbnRleHQsIGRpYWxvZ1JlZjogdGhpcy5kaWFsb2dSZWZ9KS5yb290Tm9kZXNdO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlcyA9IFt0aGlzLmVtYmVkQ29tcG9uZW50KHtjb21wb25lbnQ6IGNvbnRlbnR9KS5yb290Tm9kZXNdO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlcztcbiAgfVxuXG4gIGVtYmVkQ29tcG9uZW50KGNvbmZpZzogRW1iZWRDb21wb25lbnRDb25maWcpOiBFbWJlZGRlZFZpZXdSZWY8RW1iZWRDb21wb25lbnRDb25maWc+IHtcbiAgICBjb25zdCBjdHg6IEVtYmVkQ29tcG9uZW50Q29uZmlnICYgeyBpbmplY3RvcjogSW5qZWN0b3IgfSA9IDxhbnk+Y29uZmlnO1xuXG4gICAgcmV0dXJuIHRoaXMudmNyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLnRlbXBsYXRlLCA8YW55PntcbiAgICAgICRpbXBsaWNpdDogY3R4XG4gICAgfSk7XG4gIH1cblxuICBhZGRDb21wb25lbnQ8VD4odHlwZTogYW55LCBwcm9qZWN0YWJsZU5vZGVzOiBhbnlbXVtdID0gW10pOiBDb21wb25lbnRSZWY8VD4ge1xuICAgIHJldHVybiBzdXBlci5fYWRkQ29tcG9uZW50PFQ+KHtcbiAgICAgIGNvbXBvbmVudDogdHlwZSxcbiAgICAgIHZjUmVmOiB0aGlzLmlubmVyVmNyLFxuICAgICAgcHJvamVjdGFibGVOb2Rlc1xuICAgIH0pO1xuICB9XG5cbiAgZnVsbHNjcmVlbigpOiB2b2lkIHtcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgICAgdG9wOiAwLFxuICAgICAgbGVmdDogMCxcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIHJpZ2h0OiAwLFxuICAgICAgJ3otaW5kZXgnOiAxNTAwXG4gICAgfTtcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrID0+IHRoaXMuc2V0U3R5bGUoaywgc3R5bGVba10pKTtcbiAgfVxuXG4gIGluc2lkZUVsZW1lbnQoKTogdm9pZCB7XG4gICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIG92ZXJmbG93OiAnaGlkZGVuJyxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIHRvcDogMCxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICByaWdodDogMFxuICAgIH07XG4gICAgT2JqZWN0LmtleXMoc3R5bGUpLmZvckVhY2goayA9PiB0aGlzLnNldFN0eWxlKGssIHN0eWxlW2tdKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgc3BlY2lmaWMgaW5saW5lIHN0eWxlIGZvciB0aGUgY29udGFpbmVyIG9mIHRoZSB3aG9sZSBkaWFsb2cgY29tcG9uZW50XG4gICAqIFRoZSBkaWFsb2cgY29tcG9uZW50IHJvb3QgZWxlbWVudCBpcyB0aGUgaG9zdCBvZiB0aGlzIGNvbXBvbmVudCwgaXQgY29udGFpbnMgb25seSAxIGRpcmVjdFxuICAgKiBjaGlsZCB3aGljaCBpcyB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBTdHJ1Y3R1cmU6XG4gICAqXG4gICAqIGBgYGh0bWxcbiAgICogPG1vZGFsLW92ZXJsYXk+XG4gICAqICAgPGRpdj5cbiAgICogICAgIDwhLS0gQkFDS0RST1AgRUxFTUVOVCAtLT5cbiAgICogICAgIDwhLS0gRElBTE9HIENPTlRBSU5FUiBFTEVNRU5UIC0tPlxuICAgKiAgIDwvZGl2PlxuICAgKiA8L21vZGFsLW92ZXJsYXk+XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gcHJvcCBUaGUgc3R5bGUga2V5XG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUsIHVuZGVmaW5lZCB0byByZW1vdmVcbiAgICovXG4gIHNldENvbnRhaW5lclN0eWxlKHByb3A6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCwgcHJvcCwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlZmluZSBhbiBlbGVtZW50IHRoYXQgY2xpY2sgaW5zaWRlIGl0IHdpbGwgbm90IHRyaWdnZXIgbW9kYWwgY2xvc2UuXG4gICAqIFNpbmNlIGV2ZW50cyBidWJibGUsIGNsaWNraW5nIG9uIGEgZGlhbG9nIHdpbGwgYnViYmxlIHVwIHRvIHRoZSBvdmVybGF5LCBhIHBsdWdpblxuICAgKiBtdXN0IGRlZmluZSBhbiBlbGVtZW50IHRoYXQgcmVwcmVzZW50IHRoZSBkaWFsb2csIHRoZSBvdmVybGF5IHdpbGwgbWFrZSBzdXJlIG5vIHRvIGNsb3NlIHdoZW5cbiAgICogaXQgd2FzIGNsaWNrZWQuXG4gICAqIEBwYXJhbSBlbGVtZW50XG4gICAqL1xuICBzZXRDbGlja0JvdW5kYXJ5KGVsZW1lbnQ6IEVsZW1lbnQpOiB2b2lkIHtcbiAgICBsZXQgdGFyZ2V0OiBFbGVtZW50O1xuICAgIGNvbnN0IGVsTGlzdGVuZXIgPSBldmVudCA9PiB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgYW55O1xuICAgIGNvbnN0IGRvY0xpc3RlbmVyID0gZXZlbnQgPT4ge1xuICAgICAgaWYgKHRoaXMuZGlhbG9nUmVmLmNvbnRleHQuaXNCbG9ja2luZyB8fCAhdGhpcy5kaWFsb2dSZWYub3ZlcmxheS5pc1RvcE1vc3QodGhpcy5kaWFsb2dSZWYpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGN1cnJlbnQ6IGFueSA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgLy8gb24gY2xpY2ssIHRoaXMgd2lsbCBoaXQuXG4gICAgICBpZiAoY3VycmVudCA9PT0gdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gb24gbW91c2UgZG93biAtPiBkcmFnIC0+IHJlbGVhc2UgdGhlIGN1cnJlbnQgbWlnaHQgbm90IGJlICd0YXJnZXQnLCBpdCBtaWdodCBiZVxuICAgICAgLy8gYSBzaWJsaW5nIG9yIGEgY2hpbGQgKGkuZTogbm90IHBhcnQgb2YgdGhlIHRyZWUtdXAgZGlyZWN0aW9uKS4gSXQgbWlnaHQgYWxzbyBiZSBhIHJlbGVhc2VcbiAgICAgIC8vIG91dHNpZGUgdGhlIGRpYWxvZy4uLiBzbyB3ZSBjb21wYXJlIHRvIHRoZSBib3VuZGFyeSBlbGVtZW50XG4gICAgICBkbyB7XG4gICAgICAgIGlmIChjdXJyZW50ID09PSBlbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlIChjdXJyZW50LnBhcmVudE5vZGUgJiYgKGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudE5vZGUpKTtcbiAgICAgIHRoaXMuZGlhbG9nUmVmLmRpc21pc3MoKTtcbiAgICB9O1xuXG4gICAgaWYgKGlzRG9jKSB7XG4gICAgICB0aGlzLmRpYWxvZ1JlZi5vbkRlc3Ryb3kuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGVsTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgZWxMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGVsTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgZG9jTGlzdGVuZXIsIGZhbHNlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBkb2NMaXN0ZW5lciwgZmFsc2UpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIGRvY0xpc3RlbmVyLCBmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGVtcCB3b3JrYXJvdW5kIGZvciBhbmltYXRpb24gd2hlcmUgZGVzdHJ1Y3Rpb24gb2YgdGhlIHRvcCBsZXZlbCBjb21wb25lbnQgZG9lcyBub3RcbiAgICogdHJpZ2dlciBjaGlsZCBhbmltYXRpb25zLiBTb2x1dGlvbiBzaG91bGQgYmUgZm91bmQgZWl0aGVyIGluIGFuaW1hdGlvbiBtb2R1bGUgb3IgaW4gZGVzaWduXG4gICAqIG9mIHRoZSBtb2RhbCBjb21wb25lbnQgdHJlZS5cbiAgICovXG4gIGNhbkRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29tcGxldGVyID0gbmV3IFByb21pc2VDb21wbGV0ZXI8dm9pZD4oKTtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycykpIHtcbiAgICAgIGNvbXBsZXRlci5yZXNvbHZlKCk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gcnVuIGRlc3Ryb3kgbm90aWZpY2F0aW9uIGJ1dCBwcm90ZWN0IGFnYWluc3QgaGFsdC5cbiAgICAgIGxldCBpZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZCA9IG51bGw7XG4gICAgICAgIGNvbXBsZXRlci5yZWplY3QoKTtcbiAgICAgIH0sIDEwMDApO1xuXG4gICAgICBjb25zdCByZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICBpZiAoaWQgPT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjbGVhclRpbWVvdXQoaWQpO1xuICAgICAgICBjb21wbGV0ZXIucmVzb2x2ZSgpO1xuICAgICAgfTtcblxuICAgICAgUHJvbWlzZS5hbGwodGhpcy5iZWZvcmVEZXN0cm95SGFuZGxlcnMubWFwKGZuID0+IGZuKCkpKVxuICAgICAgICAudGhlbihyZXNvbHZlKVxuICAgICAgICAuY2F0Y2gocmVzb2x2ZSk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGxldGVyLnByb21pc2U7XG4gIH1cblxuICAvKipcbiAgICogQSBoYW5kbGVyIHJ1bm5pbmcgYmVmb3JlIGRlc3RydWN0aW9uIG9mIHRoZSBvdmVybGF5XG4gICAqIHVzZSB0byBkZWxheSBkZXN0cnVjdGlvbiBkdWUgdG8gYW5pbWF0aW9uLlxuICAgKiBUaGlzIGlzIHBhcnQgb2YgdGhlIHdvcmthcm91bmQgZm9yIGFuaW1hdGlvbiwgc2VlIGNhbkRlc3Ryb3kuXG4gICAqXG4gICAqIE5PVEU6IFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZSBsaXN0ZW5lcnMgd2lsbCBmaXJlLCB1c2UgZGlhbG9nLm9uRGVzdG9yeSBmb3IgdGhhdC5cbiAgICogQHBhcmFtIGZuXG4gICAqL1xuICBiZWZvcmVEZXN0cm95KGZuOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgaWYgKCF0aGlzLmJlZm9yZURlc3Ryb3lIYW5kbGVycykge1xuICAgICAgdGhpcy5iZWZvcmVEZXN0cm95SGFuZGxlcnMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5iZWZvcmVEZXN0cm95SGFuZGxlcnMucHVzaChmbik7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdib2R5OmtleWRvd24nLCBbJyRldmVudCddKVxuICBkb2N1bWVudEtleXByZXNzKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgLy8gY2hlY2sgdGhhdCB0aGlzIG1vZGFsIGlzIHRoZSBsYXN0IGluIHRoZSBzdGFjay5cbiAgICBpZiAoIXRoaXMuZGlhbG9nUmVmLm92ZXJsYXkuaXNUb3BNb3N0KHRoaXMuZGlhbG9nUmVmKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgaWYgKHN1cHBvcnRzS2V5KGV2ZW50LmtleUNvZGUsIDxhbnk+dGhpcy5kaWFsb2dSZWYuY29udGV4dC5rZXlib2FyZCkpIHtcbiAgICAgIHRoaXMuZGlhbG9nUmVmLmRpc21pc3MoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIGlmICh0aGlzLmRpYWxvZ1JlZi5kZXN0cm95ZWQgIT09IHRydWUpIHtcbiAgICAgIC8vIGlmIHdlJ3JlIGhlcmUgdGhlIG92ZXJsYXkgaXMgZGVzdHJveWVkIGJ5IGFuIGV4dGVybmFsIGV2ZW50IHRoYXQgaXMgbm90IHVzZXIgaW52b2tlZC5cbiAgICAgIC8vIGkuZTogVGhlIHVzZXIgZGlkIG5vIGNhbGwgZGlzbWlzcyBvciBjbG9zZSBhbmQgZGlhbG9nUmVmLmRlc3Ryb3koKSBkaWQgbm90IGludm9rZS5cbiAgICAgIC8vIHRoaXMgd2lsbCBoYXBwZW4gd2hlbiByb3V0aW5nIG9yIGtpbGxpbmcgYW4gZWxlbWVudCBjb250YWluaW5nIGEgYmxvY2tlZCBvdmVybGF5IChuZ0lmKVxuICAgICAgLy8gd2UgYmFpbCBvdXQsIGkuZSBncmFjZWZ1bGx5IHNodXR0aW5nIGRvd24uXG4gICAgICB0aGlzLmRpYWxvZ1JlZi5iYWlsT3V0KCk7XG4gICAgfVxuICB9XG59XG4iXX0=