UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

338 lines 31.1 kB
/** * @fileoverview added by tsickle * Generated from: modal.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; import { ComponentPortal, PortalInjector, TemplatePortal } from '@angular/cdk/portal'; import { Injectable, Injector, Optional, SkipSelf, TemplateRef } from '@angular/core'; import { NzConfigService } from 'ng-zorro-antd/core/config'; import { warn } from 'ng-zorro-antd/core/logger'; import { isNotNil } from 'ng-zorro-antd/core/util'; import { defer, Subject } from 'rxjs'; import { startWith } from 'rxjs/operators'; import { MODAL_MASK_CLASS_NAME, NZ_CONFIG_COMPONENT_NAME } from './modal-config'; import { NzModalConfirmContainerComponent } from './modal-confirm-container.component'; import { NzModalContainerComponent } from './modal-container.component'; import { NzModalRef } from './modal-ref'; import { ModalOptions } from './modal-types'; import { applyConfigDefaults, getValueWithConfig, setContentInstanceParams } from './utils'; export class NzModalService { /** * @param {?} overlay * @param {?} injector * @param {?} nzConfigService * @param {?} parentModal */ constructor(overlay, injector, nzConfigService, parentModal) { this.overlay = overlay; this.injector = injector; this.nzConfigService = nzConfigService; this.parentModal = parentModal; this.openModalsAtThisLevel = []; this.afterAllClosedAtThisLevel = new Subject(); this.afterAllClose = (/** @type {?} */ (defer((/** * @return {?} */ () => this.openModals.length ? this._afterAllClosed : this._afterAllClosed.pipe(startWith(undefined)))))); } /** * @return {?} */ get openModals() { return this.parentModal ? this.parentModal.openModals : this.openModalsAtThisLevel; } /** * @return {?} */ get _afterAllClosed() { /** @type {?} */ const parent = this.parentModal; return parent ? parent._afterAllClosed : this.afterAllClosedAtThisLevel; } /** * @template T, R * @param {?} config * @return {?} */ create(config) { return this.open((/** @type {?} */ (config.nzContent)), config); } /** * @return {?} */ closeAll() { this.closeModals(this.openModals); } /** * @template T * @param {?=} options * @param {?=} confirmType * @return {?} */ confirm(options = {}, confirmType = 'confirm') { if ('nzFooter' in options) { warn(`The Confirm-Modal doesn't support "nzFooter", this property will be ignored.`); } if (!('nzWidth' in options)) { options.nzWidth = 416; } if (!('nzMaskClosable' in options)) { options.nzMaskClosable = false; } options.nzModalType = 'confirm'; options.nzClassName = `ant-modal-confirm ant-modal-confirm-${confirmType} ${options.nzClassName || ''}`; return this.create(options); } /** * @template T * @param {?=} options * @return {?} */ info(options = {}) { return this.confirmFactory(options, 'info'); } /** * @template T * @param {?=} options * @return {?} */ success(options = {}) { return this.confirmFactory(options, 'success'); } /** * @template T * @param {?=} options * @return {?} */ error(options = {}) { return this.confirmFactory(options, 'error'); } /** * @template T * @param {?=} options * @return {?} */ warning(options = {}) { return this.confirmFactory(options, 'warning'); } /** * @private * @template T, R * @param {?} componentOrTemplateRef * @param {?=} config * @return {?} */ open(componentOrTemplateRef, config) { /** @type {?} */ const configMerged = applyConfigDefaults(config || {}, new ModalOptions()); /** @type {?} */ const overlayRef = this.createOverlay(configMerged); /** @type {?} */ const modalContainer = this.attachModalContainer(overlayRef, configMerged); /** @type {?} */ const modalRef = this.attachModalContent(componentOrTemplateRef, modalContainer, overlayRef, configMerged); modalContainer.modalRef = modalRef; this.openModals.push(modalRef); modalRef.afterClose.subscribe((/** * @return {?} */ () => this.removeOpenModal(modalRef))); return modalRef; } /** * @private * @param {?} modalRef * @return {?} */ removeOpenModal(modalRef) { /** @type {?} */ const index = this.openModals.indexOf(modalRef); if (index > -1) { this.openModals.splice(index, 1); if (!this.openModals.length) { this._afterAllClosed.next(); } } } /** * @private * @param {?} dialogs * @return {?} */ closeModals(dialogs) { /** @type {?} */ let i = dialogs.length; while (i--) { dialogs[i].close(); if (!this.openModals.length) { this._afterAllClosed.next(); } } } /** * @private * @param {?} config * @return {?} */ createOverlay(config) { /** @type {?} */ const globalConfig = this.nzConfigService.getConfigForComponent(NZ_CONFIG_COMPONENT_NAME) || {}; /** @type {?} */ const overlayConfig = new OverlayConfig({ hasBackdrop: true, scrollStrategy: this.overlay.scrollStrategies.block(), positionStrategy: this.overlay.position().global(), disposeOnNavigation: getValueWithConfig(config.nzCloseOnNavigation, globalConfig.nzCloseOnNavigation, true) }); if (getValueWithConfig(config.nzMask, globalConfig.nzMask, true)) { overlayConfig.backdropClass = MODAL_MASK_CLASS_NAME; } return this.overlay.create(overlayConfig); } /** * @private * @param {?} overlayRef * @param {?} config * @return {?} */ attachModalContainer(overlayRef, config) { /** @type {?} */ const userInjector = config && config.nzViewContainerRef && config.nzViewContainerRef.injector; /** @type {?} */ const injector = new PortalInjector(userInjector || this.injector, new WeakMap([ [OverlayRef, overlayRef], [ModalOptions, config] ])); /** @type {?} */ const ContainerComponent = config.nzModalType === 'confirm' ? // If the mode is `confirm`, use `NzModalConfirmContainerComponent` NzModalConfirmContainerComponent : // If the mode is not `confirm`, use `NzModalContainerComponent` NzModalContainerComponent; /** @type {?} */ const containerPortal = new ComponentPortal(ContainerComponent, config.nzViewContainerRef, injector); /** @type {?} */ const containerRef = overlayRef.attach(containerPortal); return containerRef.instance; } /** * @private * @template T, R * @param {?} componentOrTemplateRef * @param {?} modalContainer * @param {?} overlayRef * @param {?} config * @return {?} */ attachModalContent(componentOrTemplateRef, modalContainer, overlayRef, config) { /** @type {?} */ const modalRef = new NzModalRef(overlayRef, config, modalContainer); if (componentOrTemplateRef instanceof TemplateRef) { modalContainer.attachTemplatePortal(new TemplatePortal(componentOrTemplateRef, (/** @type {?} */ (null)), (/** @type {?} */ ({ $implicit: config.nzComponentParams, modalRef })))); } else if (isNotNil(componentOrTemplateRef) && typeof componentOrTemplateRef !== 'string') { /** @type {?} */ const injector = this.createInjector(modalRef, config); /** @type {?} */ const contentRef = modalContainer.attachComponentPortal(new ComponentPortal(componentOrTemplateRef, config.nzViewContainerRef, injector)); setContentInstanceParams(contentRef.instance, config.nzComponentParams); modalRef.componentInstance = contentRef.instance; } return modalRef; } /** * @private * @template T, R * @param {?} modalRef * @param {?} config * @return {?} */ createInjector(modalRef, config) { /** @type {?} */ const userInjector = config && config.nzViewContainerRef && config.nzViewContainerRef.injector; /** @type {?} */ const injectionTokens = new WeakMap([[NzModalRef, modalRef]]); return new PortalInjector(userInjector || this.injector, injectionTokens); } /** * @private * @template T * @param {?=} options * @param {?=} confirmType * @return {?} */ confirmFactory(options = {}, confirmType) { /** @type {?} */ const iconMap = { info: 'info-circle', success: 'check-circle', error: 'close-circle', warning: 'exclamation-circle' }; if (!('nzIconType' in options)) { options.nzIconType = iconMap[confirmType]; } if (!('nzCancelText' in options)) { // Remove the Cancel button if the user not specify a Cancel button options.nzCancelText = null; } return this.confirm(options, confirmType); } /** * @return {?} */ ngOnDestroy() { this.closeModals(this.openModalsAtThisLevel); this.afterAllClosedAtThisLevel.complete(); } } NzModalService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NzModalService.ctorParameters = () => [ { type: Overlay }, { type: Injector }, { type: NzConfigService }, { type: NzModalService, decorators: [{ type: Optional }, { type: SkipSelf }] } ]; if (false) { /** * @type {?} * @private */ NzModalService.prototype.openModalsAtThisLevel; /** * @type {?} * @private */ NzModalService.prototype.afterAllClosedAtThisLevel; /** @type {?} */ NzModalService.prototype.afterAllClose; /** * @type {?} * @private */ NzModalService.prototype.overlay; /** * @type {?} * @private */ NzModalService.prototype.injector; /** * @type {?} * @private */ NzModalService.prototype.nzConfigService; /** * @type {?} * @private */ NzModalService.prototype.parentModal; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXpvcnJvLWFudGQvbW9kYWwvIiwic291cmNlcyI6WyJtb2RhbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUtBLE9BQU8sRUFBaUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN6RixPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RixPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBYSxRQUFRLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDNUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRWpELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLHdCQUF3QixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakYsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFdkYsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDeEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQWUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUs1RixNQUFNLE9BQU8sY0FBYzs7Ozs7OztJQWlC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Q0FBQzs7O1lBNUxGLFVBQVU7Ozs7WUFwQmEsT0FBTztZQUVWLFFBQVE7WUFDcEIsZUFBZTtZQXVDeUIsY0FBYyx1QkFBMUQsUUFBUSxZQUFJLFFBQVE7Ozs7Ozs7SUFwQnZCLCtDQUFpRDs7Ozs7SUFDakQsbURBQWlFOztJQVdqRSx1Q0FFc0I7Ozs7O0lBR3BCLGlDQUF3Qjs7Ozs7SUFDeEIsa0NBQTBCOzs7OztJQUMxQix5Q0FBd0M7Ozs7O0lBQ3hDLHFDQUEyRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudFR5cGUsIE92ZXJsYXksIE92ZXJsYXlDb25maWcsIE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBDb21wb25lbnRQb3J0YWwsIFBvcnRhbEluamVjdG9yLCBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIE9uRGVzdHJveSwgT3B0aW9uYWwsIFNraXBTZWxmLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTnpDb25maWdTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyB3YXJuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2xvZ2dlcic7XG5pbXBvcnQgeyBJbmRleGFibGVPYmplY3QsIE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBpc05vdE5pbCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IGRlZmVyLCBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzdGFydFdpdGggfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE1PREFMX01BU0tfQ0xBU1NfTkFNRSwgTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FIH0gZnJvbSAnLi9tb2RhbC1jb25maWcnO1xuaW1wb3J0IHsgTnpNb2RhbENvbmZpcm1Db250YWluZXJDb21wb25lbnQgfSBmcm9tICcuL21vZGFsLWNvbmZpcm0tY29udGFpbmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCYXNlTW9kYWxDb250YWluZXIgfSBmcm9tICcuL21vZGFsLWNvbnRhaW5lcic7XG5pbXBvcnQgeyBOek1vZGFsQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9tb2RhbC1jb250YWluZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE56TW9kYWxSZWYgfSBmcm9tICcuL21vZGFsLXJlZic7XG5pbXBvcnQgeyBDb25maXJtVHlwZSwgTW9kYWxPcHRpb25zIH0gZnJvbSAnLi9tb2RhbC10eXBlcyc7XG5pbXBvcnQgeyBhcHBseUNvbmZpZ0RlZmF1bHRzLCBnZXRWYWx1ZVdpdGhDb25maWcsIHNldENvbnRlbnRJbnN0YW5jZVBhcmFtcyB9IGZyb20gJy4vdXRpbHMnO1xuXG50eXBlIENvbnRlbnRUeXBlPFQ+ID0gQ29tcG9uZW50VHlwZTxUPiB8IFRlbXBsYXRlUmVmPFQ+IHwgc3RyaW5nO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTnpNb2RhbFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIG9wZW5Nb2RhbHNBdFRoaXNMZXZlbDogTnpNb2RhbFJlZltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgYWZ0ZXJBbGxDbG9zZWRBdFRoaXNMZXZlbCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgZ2V0IG9wZW5Nb2RhbHMoKTogTnpNb2RhbFJlZltdIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnRNb2RhbCA/IHRoaXMucGFyZW50TW9kYWwub3Blbk1vZGFscyA6IHRoaXMub3Blbk1vZGFsc0F0VGhpc0xldmVsO1xuICB9XG5cbiAgZ2V0IF9hZnRlckFsbENsb3NlZCgpOiBTdWJqZWN0PHZvaWQ+IHtcbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLnBhcmVudE1vZGFsO1xuICAgIHJldHVybiBwYXJlbnQgPyBwYXJlbnQuX2FmdGVyQWxsQ2xvc2VkIDogdGhpcy5hZnRlckFsbENsb3NlZEF0VGhpc0xldmVsO1xuICB9XG5cbiAgcmVhZG9ubHkgYWZ0ZXJBbGxDbG9zZTogT2JzZXJ2YWJsZTx2b2lkPiA9IGRlZmVyKCgpID0+XG4gICAgdGhpcy5vcGVuTW9kYWxzLmxlbmd0aCA/IHRoaXMuX2FmdGVyQWxsQ2xvc2VkIDogdGhpcy5fYWZ0ZXJBbGxDbG9zZWQucGlwZShzdGFydFdpdGgodW5kZWZpbmVkKSlcbiAgKSBhcyBPYnNlcnZhYmxlPHZvaWQ+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgb3ZlcmxheTogT3ZlcmxheSxcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBTa2lwU2VsZigpIHByaXZhdGUgcGFyZW50TW9kYWw6IE56TW9kYWxTZXJ2aWNlXG4gICkge31cblxuICBjcmVhdGU8VCwgUiA9IE56U2FmZUFueT4oY29uZmlnOiBNb2RhbE9wdGlvbnM8VCwgUj4pOiBOek1vZGFsUmVmPFQsIFI+IHtcbiAgICByZXR1cm4gdGhpcy5vcGVuPFQsIFI+KGNvbmZpZy5uekNvbnRlbnQgYXMgQ29tcG9uZW50VHlwZTxUPiwgY29uZmlnKTtcbiAgfVxuXG4gIGNsb3NlQWxsKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VNb2RhbHModGhpcy5vcGVuTW9kYWxzKTtcbiAgfVxuXG4gIGNvbmZpcm08VD4ob3B0aW9uczogTW9kYWxPcHRpb25zPFQ+ID0ge30sIGNvbmZpcm1UeXBlOiBDb25maXJtVHlwZSA9ICdjb25maXJtJyk6IE56TW9kYWxSZWY8VD4ge1xuICAgIGlmICgnbnpGb290ZXInIGluIG9wdGlvbnMpIHtcbiAgICAgIHdhcm4oYFRoZSBDb25maXJtLU1vZGFsIGRvZXNuJ3Qgc3VwcG9ydCBcIm56Rm9vdGVyXCIsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkLmApO1xuICAgIH1cbiAgICBpZiAoISgnbnpXaWR0aCcgaW4gb3B0aW9ucykpIHtcbiAgICAgIG9wdGlvbnMubnpXaWR0aCA9IDQxNjtcbiAgICB9XG4gICAgaWYgKCEoJ256TWFza0Nsb3NhYmxlJyBpbiBvcHRpb25zKSkge1xuICAgICAgb3B0aW9ucy5uek1hc2tDbG9zYWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIG9wdGlvbnMubnpNb2RhbFR5cGUgPSAnY29uZmlybSc7XG4gICAgb3B0aW9ucy5uekNsYXNzTmFtZSA9IGBhbnQtbW9kYWwtY29uZmlybSBhbnQtbW9kYWwtY29uZmlybS0ke2NvbmZpcm1UeXBlfSAke29wdGlvbnMubnpDbGFzc05hbWUgfHwgJyd9YDtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUob3B0aW9ucyk7XG4gIH1cblxuICBpbmZvPFQ+KG9wdGlvbnM6IE1vZGFsT3B0aW9uczxUPiA9IHt9KTogTnpNb2RhbFJlZjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlybUZhY3Rvcnkob3B0aW9ucywgJ2luZm8nKTtcbiAgfVxuXG4gIHN1Y2Nlc3M8VD4ob3B0aW9uczogTW9kYWxPcHRpb25zPFQ+ID0ge30pOiBOek1vZGFsUmVmPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5jb25maXJtRmFjdG9yeShvcHRpb25zLCAnc3VjY2VzcycpO1xuICB9XG5cbiAgZXJyb3I8VD4ob3B0aW9uczogTW9kYWxPcHRpb25zPFQ+ID0ge30pOiBOek1vZGFsUmVmPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5jb25maXJtRmFjdG9yeShvcHRpb25zLCAnZXJyb3InKTtcbiAgfVxuXG4gIHdhcm5pbmc8VD4ob3B0aW9uczogTW9kYWxPcHRpb25zPFQ+ID0ge30pOiBOek1vZGFsUmVmPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5jb25maXJtRmFjdG9yeShvcHRpb25zLCAnd2FybmluZycpO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGVuPFQsIFI+KGNvbXBvbmVudE9yVGVtcGxhdGVSZWY6IENvbnRlbnRUeXBlPFQ+LCBjb25maWc/OiBNb2RhbE9wdGlvbnMpOiBOek1vZGFsUmVmPFQsIFI+IHtcbiAgICBjb25zdCBjb25maWdNZXJnZWQgPSBhcHBseUNvbmZpZ0RlZmF1bHRzKGNvbmZpZyB8fCB7fSwgbmV3IE1vZGFsT3B0aW9ucygpKTtcbiAgICBjb25zdCBvdmVybGF5UmVmID0gdGhpcy5jcmVhdGVPdmVybGF5KGNvbmZpZ01lcmdlZCk7XG4gICAgY29uc3QgbW9kYWxDb250YWluZXIgPSB0aGlzLmF0dGFjaE1vZGFsQ29udGFpbmVyKG92ZXJsYXlSZWYsIGNvbmZpZ01lcmdlZCk7XG4gICAgY29uc3QgbW9kYWxSZWYgPSB0aGlzLmF0dGFjaE1vZGFsQ29udGVudDxULCBSPihjb21wb25lbnRPclRlbXBsYXRlUmVmLCBtb2RhbENvbnRhaW5lciwgb3ZlcmxheVJlZiwgY29uZmlnTWVyZ2VkKTtcbiAgICBtb2RhbENvbnRhaW5lci5tb2RhbFJlZiA9IG1vZGFsUmVmO1xuXG4gICAgdGhpcy5vcGVuTW9kYWxzLnB1c2gobW9kYWxSZWYpO1xuICAgIG1vZGFsUmVmLmFmdGVyQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVtb3ZlT3Blbk1vZGFsKG1vZGFsUmVmKSk7XG5cbiAgICByZXR1cm4gbW9kYWxSZWY7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZU9wZW5Nb2RhbChtb2RhbFJlZjogTnpNb2RhbFJlZik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vcGVuTW9kYWxzLmluZGV4T2YobW9kYWxSZWYpO1xuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICB0aGlzLm9wZW5Nb2RhbHMuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgICAgaWYgKCF0aGlzLm9wZW5Nb2RhbHMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX2FmdGVyQWxsQ2xvc2VkLm5leHQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNsb3NlTW9kYWxzKGRpYWxvZ3M6IE56TW9kYWxSZWZbXSk6IHZvaWQge1xuICAgIGxldCBpID0gZGlhbG9ncy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgZGlhbG9nc1tpXS5jbG9zZSgpO1xuICAgICAgaWYgKCF0aGlzLm9wZW5Nb2RhbHMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX2FmdGVyQWxsQ2xvc2VkLm5leHQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU92ZXJsYXkoY29uZmlnOiBNb2RhbE9wdGlvbnMpOiBPdmVybGF5UmVmIHtcbiAgICBjb25zdCBnbG9iYWxDb25maWcgPSB0aGlzLm56Q29uZmlnU2VydmljZS5nZXRDb25maWdGb3JDb21wb25lbnQoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKSB8fCB7fTtcbiAgICBjb25zdCBvdmVybGF5Q29uZmlnID0gbmV3IE92ZXJsYXlDb25maWcoe1xuICAgICAgaGFzQmFja2Ryb3A6IHRydWUsXG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMuYmxvY2soKSxcbiAgICAgIHBvc2l0aW9uU3RyYXRlZ3k6IHRoaXMub3ZlcmxheS5wb3NpdGlvbigpLmdsb2JhbCgpLFxuICAgICAgZGlzcG9zZU9uTmF2aWdhdGlvbjogZ2V0VmFsdWVXaXRoQ29uZmlnKGNvbmZpZy5uekNsb3NlT25OYXZpZ2F0aW9uLCBnbG9iYWxDb25maWcubnpDbG9zZU9uTmF2aWdhdGlvbiwgdHJ1ZSlcbiAgICB9KTtcblxuICAgIGlmIChnZXRWYWx1ZVdpdGhDb25maWcoY29uZmlnLm56TWFzaywgZ2xvYmFsQ29uZmlnLm56TWFzaywgdHJ1ZSkpIHtcbiAgICAgIG92ZXJsYXlDb25maWcuYmFja2Ryb3BDbGFzcyA9IE1PREFMX01BU0tfQ0xBU1NfTkFNRTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vdmVybGF5LmNyZWF0ZShvdmVybGF5Q29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgYXR0YWNoTW9kYWxDb250YWluZXIob3ZlcmxheVJlZjogT3ZlcmxheVJlZiwgY29uZmlnOiBNb2RhbE9wdGlvbnMpOiBCYXNlTW9kYWxDb250YWluZXIge1xuICAgIGNvbnN0IHVzZXJJbmplY3RvciA9IGNvbmZpZyAmJiBjb25maWcubnpWaWV3Q29udGFpbmVyUmVmICYmIGNvbmZpZy5uelZpZXdDb250YWluZXJSZWYuaW5qZWN0b3I7XG4gICAgY29uc3QgaW5qZWN0b3IgPSBuZXcgUG9ydGFsSW5qZWN0b3IoXG4gICAgICB1c2VySW5qZWN0b3IgfHwgdGhpcy5pbmplY3RvcixcbiAgICAgIG5ldyBXZWFrTWFwPE56U2FmZUFueSwgTnpTYWZlQW55PihbXG4gICAgICAgIFtPdmVybGF5UmVmLCBvdmVybGF5UmVmXSxcbiAgICAgICAgW01vZGFsT3B0aW9ucywgY29uZmlnXVxuICAgICAgXSlcbiAgICApO1xuXG4gICAgY29uc3QgQ29udGFpbmVyQ29tcG9uZW50ID1cbiAgICAgIGNvbmZpZy5uek1vZGFsVHlwZSA9PT0gJ2NvbmZpcm0nXG4gICAgICAgID8gLy8gSWYgdGhlIG1vZGUgaXMgYGNvbmZpcm1gLCB1c2UgYE56TW9kYWxDb25maXJtQ29udGFpbmVyQ29tcG9uZW50YFxuICAgICAgICAgIE56TW9kYWxDb25maXJtQ29udGFpbmVyQ29tcG9uZW50XG4gICAgICAgIDogLy8gSWYgdGhlIG1vZGUgaXMgbm90IGBjb25maXJtYCwgdXNlIGBOek1vZGFsQ29udGFpbmVyQ29tcG9uZW50YFxuICAgICAgICAgIE56TW9kYWxDb250YWluZXJDb21wb25lbnQ7XG5cbiAgICBjb25zdCBjb250YWluZXJQb3J0YWwgPSBuZXcgQ29tcG9uZW50UG9ydGFsPEJhc2VNb2RhbENvbnRhaW5lcj4oQ29udGFpbmVyQ29tcG9uZW50LCBjb25maWcubnpWaWV3Q29udGFpbmVyUmVmLCBpbmplY3Rvcik7XG4gICAgY29uc3QgY29udGFpbmVyUmVmID0gb3ZlcmxheVJlZi5hdHRhY2g8QmFzZU1vZGFsQ29udGFpbmVyPihjb250YWluZXJQb3J0YWwpO1xuXG4gICAgcmV0dXJuIGNvbnRhaW5lclJlZi5pbnN0YW5jZTtcbiAgfVxuXG4gIHByaXZhdGUgYXR0YWNoTW9kYWxDb250ZW50PFQsIFI+KFxuICAgIGNvbXBvbmVudE9yVGVtcGxhdGVSZWY6IENvbnRlbnRUeXBlPFQ+LFxuICAgIG1vZGFsQ29udGFpbmVyOiBCYXNlTW9kYWxDb250YWluZXIsXG4gICAgb3ZlcmxheVJlZjogT3ZlcmxheVJlZixcbiAgICBjb25maWc6IE1vZGFsT3B0aW9uczxUPlxuICApOiBOek1vZGFsUmVmPFQsIFI+IHtcbiAgICBjb25zdCBtb2RhbFJlZiA9IG5ldyBOek1vZGFsUmVmPFQsIFI+KG92ZXJsYXlSZWYsIGNvbmZpZywgbW9kYWxDb250YWluZXIpO1xuXG4gICAgaWYgKGNvbXBvbmVudE9yVGVtcGxhdGVSZWYgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xuICAgICAgbW9kYWxDb250YWluZXIuYXR0YWNoVGVtcGxhdGVQb3J0YWwoXG4gICAgICAgIG5ldyBUZW1wbGF0ZVBvcnRhbDxUPihjb21wb25lbnRPclRlbXBsYXRlUmVmLCBudWxsISwgeyAkaW1wbGljaXQ6IGNvbmZpZy5uekNvbXBvbmVudFBhcmFtcywgbW9kYWxSZWYgfSBhcyBOelNhZmVBbnkpXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaXNOb3ROaWwoY29tcG9uZW50T3JUZW1wbGF0ZVJlZikgJiYgdHlwZW9mIGNvbXBvbmVudE9yVGVtcGxhdGVSZWYgIT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBpbmplY3RvciA9IHRoaXMuY3JlYXRlSW5qZWN0b3I8VCwgUj4obW9kYWxSZWYsIGNvbmZpZyk7XG4gICAgICBjb25zdCBjb250ZW50UmVmID0gbW9kYWxDb250YWluZXIuYXR0YWNoQ29tcG9uZW50UG9ydGFsPFQ+KFxuICAgICAgICBuZXcgQ29tcG9uZW50UG9ydGFsKGNvbXBvbmVudE9yVGVtcGxhdGVSZWYsIGNvbmZpZy5uelZpZXdDb250YWluZXJSZWYsIGluamVjdG9yKVxuICAgICAgKTtcbiAgICAgIHNldENvbnRlbnRJbnN0YW5jZVBhcmFtczxUPihjb250ZW50UmVmLmluc3RhbmNlLCBjb25maWcubnpDb21wb25lbnRQYXJhbXMpO1xuICAgICAgbW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2UgPSBjb250ZW50UmVmLmluc3RhbmNlO1xuICAgIH1cbiAgICByZXR1cm4gbW9kYWxSZWY7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUluamVjdG9yPFQsIFI+KG1vZGFsUmVmOiBOek1vZGFsUmVmPFQsIFI+LCBjb25maWc6IE1vZGFsT3B0aW9uczxUPik6IFBvcnRhbEluamVjdG9yIHtcbiAgICBjb25zdCB1c2VySW5qZWN0b3IgPSBjb25maWcgJiYgY29uZmlnLm56Vmlld0NvbnRhaW5lclJlZiAmJiBjb25maWcubnpWaWV3Q29udGFpbmVyUmVmLmluamVjdG9yO1xuICAgIGNvbnN0IGluamVjdGlvblRva2VucyA9IG5ldyBXZWFrTWFwPE56U2FmZUFueSwgTnpTYWZlQW55PihbW056TW9kYWxSZWYsIG1vZGFsUmVmXV0pO1xuXG4gICAgcmV0dXJuIG5ldyBQb3J0YWxJbmplY3Rvcih1c2VySW5qZWN0b3IgfHwgdGhpcy5pbmplY3RvciwgaW5qZWN0aW9uVG9rZW5zKTtcbiAgfVxuXG4gIHByaXZhdGUgY29uZmlybUZhY3Rvcnk8VD4ob3B0aW9uczogTW9kYWxPcHRpb25zPFQ+ID0ge30sIGNvbmZpcm1UeXBlOiBDb25maXJtVHlwZSk6IE56TW9kYWxSZWY8VD4ge1xuICAgIGNvbnN0IGljb25NYXA6IEluZGV4YWJsZU9iamVjdCA9IHtcbiAgICAgIGluZm86ICdpbmZvLWNpcmNsZScsXG4gICAgICBzdWNjZXNzOiAnY2hlY2stY2lyY2xlJyxcbiAgICAgIGVycm9yOiAnY2xvc2UtY2lyY2xlJyxcbiAgICAgIHdhcm5pbmc6ICdleGNsYW1hdGlvbi1jaXJjbGUnXG4gICAgfTtcbiAgICBpZiAoISgnbnpJY29uVHlwZScgaW4gb3B0aW9ucykpIHtcbiAgICAgIG9wdGlvbnMubnpJY29uVHlwZSA9IGljb25NYXBbY29uZmlybVR5cGVdO1xuICAgIH1cbiAgICBpZiAoISgnbnpDYW5jZWxUZXh0JyBpbiBvcHRpb25zKSkge1xuICAgICAgLy8gUmVtb3ZlIHRoZSBDYW5jZWwgYnV0dG9uIGlmIHRoZSB1c2VyIG5vdCBzcGVjaWZ5IGEgQ2FuY2VsIGJ1dHRvblxuICAgICAgb3B0aW9ucy5uekNhbmNlbFRleHQgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb25maXJtKG9wdGlvbnMsIGNvbmZpcm1UeXBlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VNb2RhbHModGhpcy5vcGVuTW9kYWxzQXRUaGlzTGV2ZWwpO1xuICAgIHRoaXMuYWZ0ZXJBbGxDbG9zZWRBdFRoaXNMZXZlbC5jb21wbGV0ZSgpO1xuICB9XG59XG4iXX0=