UNPKG

@ng-bootstrap/ng-bootstrap

Version:
234 lines 35.7 kB
import { DOCUMENT } from '@angular/common'; import { createComponent, EnvironmentInjector, EventEmitter, Inject, Injectable, Injector, TemplateRef, } from '@angular/core'; import { Subject } from 'rxjs'; import { ngbFocusTrap } from '../util/focus-trap'; import { ContentRef } from '../util/popup'; import { isDefined, isString } from '../util/util'; import { NgbModalBackdrop } from './modal-backdrop'; import { NgbActiveModal, NgbModalRef } from './modal-ref'; import { NgbModalWindow } from './modal-window'; import { take } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../util/scrollbar"; class NgbModalStack { constructor(_applicationRef, _injector, _environmentInjector, _document, _scrollBar, _rendererFactory, _ngZone) { this._applicationRef = _applicationRef; this._injector = _injector; this._environmentInjector = _environmentInjector; this._document = _document; this._scrollBar = _scrollBar; this._rendererFactory = _rendererFactory; this._ngZone = _ngZone; this._activeWindowCmptHasChanged = new Subject(); this._ariaHiddenValues = new Map(); this._scrollBarRestoreFn = null; this._modalRefs = []; this._windowCmpts = []; this._activeInstances = new EventEmitter(); // Trap focus on active WindowCmpt this._activeWindowCmptHasChanged.subscribe(() => { if (this._windowCmpts.length) { const activeWindowCmpt = this._windowCmpts[this._windowCmpts.length - 1]; ngbFocusTrap(this._ngZone, activeWindowCmpt.location.nativeElement, this._activeWindowCmptHasChanged); this._revertAriaHidden(); this._setAriaHidden(activeWindowCmpt.location.nativeElement); } }); } _restoreScrollBar() { const scrollBarRestoreFn = this._scrollBarRestoreFn; if (scrollBarRestoreFn) { this._scrollBarRestoreFn = null; scrollBarRestoreFn(); } } _hideScrollBar() { if (!this._scrollBarRestoreFn) { this._scrollBarRestoreFn = this._scrollBar.hide(); } } open(contentInjector, content, options) { const containerEl = options.container instanceof HTMLElement ? options.container : isDefined(options.container) ? this._document.querySelector(options.container) : this._document.body; const renderer = this._rendererFactory.createRenderer(null, null); if (!containerEl) { throw new Error(`The specified modal container "${options.container || 'body'}" was not found in the DOM.`); } this._hideScrollBar(); const activeModal = new NgbActiveModal(); contentInjector = options.injector || contentInjector; const environmentInjector = contentInjector.get(EnvironmentInjector, null) || this._environmentInjector; const contentRef = this._getContentRef(contentInjector, environmentInjector, content, activeModal, options); let backdropCmptRef = options.backdrop !== false ? this._attachBackdrop(containerEl) : undefined; let windowCmptRef = this._attachWindowComponent(containerEl, contentRef.nodes); let ngbModalRef = new NgbModalRef(windowCmptRef, contentRef, backdropCmptRef, options.beforeDismiss); this._registerModalRef(ngbModalRef); this._registerWindowCmpt(windowCmptRef); // We have to cleanup DOM after the last modal when BOTH 'hidden' was emitted and 'result' promise was resolved: // - with animations OFF, 'hidden' emits synchronously, then 'result' is resolved asynchronously // - with animations ON, 'result' is resolved asynchronously, then 'hidden' emits asynchronously ngbModalRef.hidden.pipe(take(1)).subscribe(() => Promise.resolve(true).then(() => { if (!this._modalRefs.length) { renderer.removeClass(this._document.body, 'modal-open'); this._restoreScrollBar(); this._revertAriaHidden(); } })); activeModal.close = (result) => { ngbModalRef.close(result); }; activeModal.dismiss = (reason) => { ngbModalRef.dismiss(reason); }; activeModal.update = (options) => { ngbModalRef.update(options); }; ngbModalRef.update(options); if (this._modalRefs.length === 1) { renderer.addClass(this._document.body, 'modal-open'); } if (backdropCmptRef && backdropCmptRef.instance) { backdropCmptRef.changeDetectorRef.detectChanges(); } windowCmptRef.changeDetectorRef.detectChanges(); return ngbModalRef; } get activeInstances() { return this._activeInstances; } dismissAll(reason) { this._modalRefs.forEach((ngbModalRef) => ngbModalRef.dismiss(reason)); } hasOpenModals() { return this._modalRefs.length > 0; } _attachBackdrop(containerEl) { let backdropCmptRef = createComponent(NgbModalBackdrop, { environmentInjector: this._applicationRef.injector, elementInjector: this._injector, }); this._applicationRef.attachView(backdropCmptRef.hostView); containerEl.appendChild(backdropCmptRef.location.nativeElement); return backdropCmptRef; } _attachWindowComponent(containerEl, projectableNodes) { let windowCmptRef = createComponent(NgbModalWindow, { environmentInjector: this._applicationRef.injector, elementInjector: this._injector, projectableNodes, }); this._applicationRef.attachView(windowCmptRef.hostView); containerEl.appendChild(windowCmptRef.location.nativeElement); return windowCmptRef; } _getContentRef(contentInjector, environmentInjector, content, activeModal, options) { if (!content) { return new ContentRef([]); } else if (content instanceof TemplateRef) { return this._createFromTemplateRef(content, activeModal); } else if (isString(content)) { return this._createFromString(content); } else { return this._createFromComponent(contentInjector, environmentInjector, content, activeModal, options); } } _createFromTemplateRef(templateRef, activeModal) { const context = { $implicit: activeModal, close(result) { activeModal.close(result); }, dismiss(reason) { activeModal.dismiss(reason); }, }; const viewRef = templateRef.createEmbeddedView(context); this._applicationRef.attachView(viewRef); return new ContentRef([viewRef.rootNodes], viewRef); } _createFromString(content) { const component = this._document.createTextNode(`${content}`); return new ContentRef([[component]]); } _createFromComponent(contentInjector, environmentInjector, componentType, context, options) { const elementInjector = Injector.create({ providers: [{ provide: NgbActiveModal, useValue: context }], parent: contentInjector, }); const componentRef = createComponent(componentType, { environmentInjector, elementInjector, }); const componentNativeEl = componentRef.location.nativeElement; if (options.scrollable) { componentNativeEl.classList.add('component-host-scrollable'); } this._applicationRef.attachView(componentRef.hostView); // FIXME: we should here get rid of the component nativeElement // and use `[Array.from(componentNativeEl.childNodes)]` instead and remove the above CSS class. return new ContentRef([[componentNativeEl]], componentRef.hostView, componentRef); } _setAriaHidden(element) { const parent = element.parentElement; if (parent && element !== this._document.body) { Array.from(parent.children).forEach((sibling) => { if (sibling !== element && sibling.nodeName !== 'SCRIPT') { this._ariaHiddenValues.set(sibling, sibling.getAttribute('aria-hidden')); sibling.setAttribute('aria-hidden', 'true'); } }); this._setAriaHidden(parent); } } _revertAriaHidden() { this._ariaHiddenValues.forEach((value, element) => { if (value) { element.setAttribute('aria-hidden', value); } else { element.removeAttribute('aria-hidden'); } }); this._ariaHiddenValues.clear(); } _registerModalRef(ngbModalRef) { const unregisterModalRef = () => { const index = this._modalRefs.indexOf(ngbModalRef); if (index > -1) { this._modalRefs.splice(index, 1); this._activeInstances.emit(this._modalRefs); } }; this._modalRefs.push(ngbModalRef); this._activeInstances.emit(this._modalRefs); ngbModalRef.result.then(unregisterModalRef, unregisterModalRef); } _registerWindowCmpt(ngbWindowCmpt) { this._windowCmpts.push(ngbWindowCmpt); this._activeWindowCmptHasChanged.next(); ngbWindowCmpt.onDestroy(() => { const index = this._windowCmpts.indexOf(ngbWindowCmpt); if (index > -1) { this._windowCmpts.splice(index, 1); this._activeWindowCmptHasChanged.next(); } }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbModalStack, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }, { token: i0.EnvironmentInjector }, { token: DOCUMENT }, { token: i1.ScrollBar }, { token: i0.RendererFactory2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbModalStack, providedIn: 'root' }); } } export { NgbModalStack }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbModalStack, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i0.EnvironmentInjector }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i1.ScrollBar }, { type: i0.RendererFactory2 }, { type: i0.NgZone }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbW9kYWwvbW9kYWwtc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFHTixlQUFlLEVBQ2YsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixNQUFNLEVBQ04sVUFBVSxFQUNWLFFBQVEsRUFHUixXQUFXLEdBRVgsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFFdEMsTUFDYSxhQUFhO0lBUXpCLFlBQ1MsZUFBK0IsRUFDL0IsU0FBbUIsRUFDbkIsb0JBQXlDLEVBQ3ZCLFNBQWMsRUFDaEMsVUFBcUIsRUFDckIsZ0JBQWtDLEVBQ2xDLE9BQWU7UUFOZixvQkFBZSxHQUFmLGVBQWUsQ0FBZ0I7UUFDL0IsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUNuQix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXFCO1FBQ3ZCLGNBQVMsR0FBVCxTQUFTLENBQUs7UUFDaEMsZUFBVSxHQUFWLFVBQVUsQ0FBVztRQUNyQixxQkFBZ0IsR0FBaEIsZ0JBQWdC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QUFDLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDeEM7UUFDRixDQUFDLENBQUMsQ0FBQztJQUNKLENBQUM7OEdBNVBXLGFBQWEsMkdBWWhCLFFBQVE7a0hBWkwsYUFBYSxjQURBLE1BQU07O1NBQ25CLGFBQWE7MkZBQWIsYUFBYTtrQkFEekIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQWEvQixNQUFNOzJCQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuXHRBcHBsaWNhdGlvblJlZixcblx0Q29tcG9uZW50UmVmLFxuXHRjcmVhdGVDb21wb25lbnQsXG5cdEVudmlyb25tZW50SW5qZWN0b3IsXG5cdEV2ZW50RW1pdHRlcixcblx0SW5qZWN0LFxuXHRJbmplY3RhYmxlLFxuXHRJbmplY3Rvcixcblx0Tmdab25lLFxuXHRSZW5kZXJlckZhY3RvcnkyLFxuXHRUZW1wbGF0ZVJlZixcblx0VHlwZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IG5nYkZvY3VzVHJhcCB9IGZyb20gJy4uL3V0aWwvZm9jdXMtdHJhcCc7XG5pbXBvcnQgeyBDb250ZW50UmVmIH0gZnJvbSAnLi4vdXRpbC9wb3B1cCc7XG5pbXBvcnQgeyBTY3JvbGxCYXIgfSBmcm9tICcuLi91dGlsL3Njcm9sbGJhcic7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcbmltcG9ydCB7IE5nYk1vZGFsQmFja2Ryb3AgfSBmcm9tICcuL21vZGFsLWJhY2tkcm9wJztcbmltcG9ydCB7IE5nYk1vZGFsT3B0aW9ucywgTmdiTW9kYWxVcGRhdGFibGVPcHRpb25zIH0gZnJvbSAnLi9tb2RhbC1jb25maWcnO1xuaW1wb3J0IHsgTmdiQWN0aXZlTW9kYWwsIE5nYk1vZGFsUmVmIH0gZnJvbSAnLi9tb2RhbC1yZWYnO1xuaW1wb3J0IHsgTmdiTW9kYWxXaW5kb3cgfSBmcm9tICcuL21vZGFsLXdpbmRvdyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIE5nYk1vZGFsU3RhY2sge1xuXHRwcml2YXRlIF9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cdHByaXZhdGUgX2FyaWFIaWRkZW5WYWx1ZXM6IE1hcDxFbGVtZW50LCBzdHJpbmcgfCBudWxsPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBfc2Nyb2xsQmFyUmVzdG9yZUZuOiBudWxsIHwgKCgpID0+IHZvaWQpID0gbnVsbDtcblx0cHJpdmF0ZSBfbW9kYWxSZWZzOiBOZ2JNb2RhbFJlZltdID0gW107XG5cdHByaXZhdGUgX3dpbmRvd0NtcHRzOiBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+W10gPSBbXTtcblx0cHJpdmF0ZSBfYWN0aXZlSW5zdGFuY2VzOiBFdmVudEVtaXR0ZXI8TmdiTW9kYWxSZWZbXT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBfYXBwbGljYXRpb25SZWY6IEFwcGxpY2F0aW9uUmVmLFxuXHRcdHByaXZhdGUgX2luamVjdG9yOiBJbmplY3Rvcixcblx0XHRwcml2YXRlIF9lbnZpcm9ubWVudEluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yLFxuXHRcdEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgX2RvY3VtZW50OiBhbnksXG5cdFx0cHJpdmF0ZSBfc2Nyb2xsQmFyOiBTY3JvbGxCYXIsXG5cdFx0cHJpdmF0ZSBfcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLFxuXHRcdHByaXZhdGUgX25nWm9uZTogTmdab25lLFxuXHQpIHtcblx0XHQvLyBUcmFwIGZvY3VzIG9uIGFjdGl2ZSBXaW5kb3dDbXB0XG5cdFx0dGhpcy5fYWN0aXZlV2luZG93Q21wdEhhc0NoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdGlmICh0aGlzLl93aW5kb3dDbXB0cy5sZW5ndGgpIHtcblx0XHRcdFx0Y29uc3QgYWN0aXZlV2luZG93Q21wdCA9IHRoaXMuX3dpbmRvd0NtcHRzW3RoaXMuX3dpbmRvd0NtcHRzLmxlbmd0aCAtIDFdO1xuXHRcdFx0XHRuZ2JGb2N1c1RyYXAodGhpcy5fbmdab25lLCBhY3RpdmVXaW5kb3dDbXB0LmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQsIHRoaXMuX2FjdGl2ZVdpbmRvd0NtcHRIYXNDaGFuZ2VkKTtcblx0XHRcdFx0dGhpcy5fcmV2ZXJ0QXJpYUhpZGRlbigpO1xuXHRcdFx0XHR0aGlzLl9zZXRBcmlhSGlkZGVuKGFjdGl2ZVdpbmRvd0NtcHQubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIF9yZXN0b3JlU2Nyb2xsQmFyKCkge1xuXHRcdGNvbnN0IHNjcm9sbEJhclJlc3RvcmVGbiA9IHRoaXMuX3Njcm9sbEJhclJlc3RvcmVGbjtcblx0XHRpZiAoc2Nyb2xsQmFyUmVzdG9yZUZuKSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxCYXJSZXN0b3JlRm4gPSBudWxsO1xuXHRcdFx0c2Nyb2xsQmFyUmVzdG9yZUZuKCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfaGlkZVNjcm9sbEJhcigpIHtcblx0XHRpZiAoIXRoaXMuX3Njcm9sbEJhclJlc3RvcmVGbikge1xuXHRcdFx0dGhpcy5fc2Nyb2xsQmFyUmVzdG9yZUZuID0gdGhpcy5fc2Nyb2xsQmFyLmhpZGUoKTtcblx0XHR9XG5cdH1cblxuXHRvcGVuKGNvbnRlbnRJbmplY3RvcjogSW5qZWN0b3IsIGNvbnRlbnQ6IGFueSwgb3B0aW9uczogTmdiTW9kYWxPcHRpb25zKTogTmdiTW9kYWxSZWYge1xuXHRcdGNvbnN0IGNvbnRhaW5lckVsID1cblx0XHRcdG9wdGlvbnMuY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTEVsZW1lbnRcblx0XHRcdFx0PyBvcHRpb25zLmNvbnRhaW5lclxuXHRcdFx0XHQ6IGlzRGVmaW5lZChvcHRpb25zLmNvbnRhaW5lcilcblx0XHRcdFx0PyB0aGlzLl9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKG9wdGlvbnMuY29udGFpbmVyKVxuXHRcdFx0XHQ6IHRoaXMuX2RvY3VtZW50LmJvZHk7XG5cdFx0Y29uc3QgcmVuZGVyZXIgPSB0aGlzLl9yZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIobnVsbCwgbnVsbCk7XG5cblx0XHRpZiAoIWNvbnRhaW5lckVsKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYFRoZSBzcGVjaWZpZWQgbW9kYWwgY29udGFpbmVyIFwiJHtvcHRpb25zLmNvbnRhaW5lciB8fCAnYm9keSd9XCIgd2FzIG5vdCBmb3VuZCBpbiB0aGUgRE9NLmApO1xuXHRcdH1cblxuXHRcdHRoaXMuX2hpZGVTY3JvbGxCYXIoKTtcblxuXHRcdGNvbnN0IGFjdGl2ZU1vZGFsID0gbmV3IE5nYkFjdGl2ZU1vZGFsKCk7XG5cblx0XHRjb250ZW50SW5qZWN0b3IgPSBvcHRpb25zLmluamVjdG9yIHx8IGNvbnRlbnRJbmplY3Rvcjtcblx0XHRjb25zdCBlbnZpcm9ubWVudEluamVjdG9yID0gY29udGVudEluamVjdG9yLmdldChFbnZpcm9ubWVudEluamVjdG9yLCBudWxsKSB8fCB0aGlzLl9lbnZpcm9ubWVudEluamVjdG9yO1xuXHRcdGNvbnN0IGNvbnRlbnRSZWYgPSB0aGlzLl9nZXRDb250ZW50UmVmKGNvbnRlbnRJbmplY3RvciwgZW52aXJvbm1lbnRJbmplY3RvciwgY29udGVudCwgYWN0aXZlTW9kYWwsIG9wdGlvbnMpO1xuXG5cdFx0bGV0IGJhY2tkcm9wQ21wdFJlZjogQ29tcG9uZW50UmVmPE5nYk1vZGFsQmFja2Ryb3A+IHwgdW5kZWZpbmVkID1cblx0XHRcdG9wdGlvbnMuYmFja2Ryb3AgIT09IGZhbHNlID8gdGhpcy5fYXR0YWNoQmFja2Ryb3AoY29udGFpbmVyRWwpIDogdW5kZWZpbmVkO1xuXHRcdGxldCB3aW5kb3dDbXB0UmVmOiBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+ID0gdGhpcy5fYXR0YWNoV2luZG93Q29tcG9uZW50KGNvbnRhaW5lckVsLCBjb250ZW50UmVmLm5vZGVzKTtcblx0XHRsZXQgbmdiTW9kYWxSZWY6IE5nYk1vZGFsUmVmID0gbmV3IE5nYk1vZGFsUmVmKHdpbmRvd0NtcHRSZWYsIGNvbnRlbnRSZWYsIGJhY2tkcm9wQ21wdFJlZiwgb3B0aW9ucy5iZWZvcmVEaXNtaXNzKTtcblxuXHRcdHRoaXMuX3JlZ2lzdGVyTW9kYWxSZWYobmdiTW9kYWxSZWYpO1xuXHRcdHRoaXMuX3JlZ2lzdGVyV2luZG93Q21wdCh3aW5kb3dDbXB0UmVmKTtcblxuXHRcdC8vIFdlIGhhdmUgdG8gY2xlYW51cCBET00gYWZ0ZXIgdGhlIGxhc3QgbW9kYWwgd2hlbiBCT1RIICdoaWRkZW4nIHdhcyBlbWl0dGVkIGFuZCAncmVzdWx0JyBwcm9taXNlIHdhcyByZXNvbHZlZDpcblx0XHQvLyAtIHdpdGggYW5pbWF0aW9ucyBPRkYsICdoaWRkZW4nIGVtaXRzIHN5bmNocm9ub3VzbHksIHRoZW4gJ3Jlc3VsdCcgaXMgcmVzb2x2ZWQgYXN5bmNocm9ub3VzbHlcblx0XHQvLyAtIHdpdGggYW5pbWF0aW9ucyBPTiwgJ3Jlc3VsdCcgaXMgcmVzb2x2ZWQgYXN5bmNocm9ub3VzbHksIHRoZW4gJ2hpZGRlbicgZW1pdHMgYXN5bmNocm9ub3VzbHlcblx0XHRuZ2JNb2RhbFJlZi5oaWRkZW4ucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT5cblx0XHRcdFByb21pc2UucmVzb2x2ZSh0cnVlKS50aGVuKCgpID0+IHtcblx0XHRcdFx0aWYgKCF0aGlzLl9tb2RhbFJlZnMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0cmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5fZG9jdW1lbnQuYm9keSwgJ21vZGFsLW9wZW4nKTtcblx0XHRcdFx0XHR0aGlzLl9yZXN0b3JlU2Nyb2xsQmFyKCk7XG5cdFx0XHRcdFx0dGhpcy5fcmV2ZXJ0QXJpYUhpZGRlbigpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KSxcblx0XHQpO1xuXG5cdFx0YWN0aXZlTW9kYWwuY2xvc2UgPSAocmVzdWx0OiBhbnkpID0+IHtcblx0XHRcdG5nYk1vZGFsUmVmLmNsb3NlKHJlc3VsdCk7XG5cdFx0fTtcblx0XHRhY3RpdmVNb2RhbC5kaXNtaXNzID0gKHJlYXNvbjogYW55KSA9PiB7XG5cdFx0XHRuZ2JNb2RhbFJlZi5kaXNtaXNzKHJlYXNvbik7XG5cdFx0fTtcblxuXHRcdGFjdGl2ZU1vZGFsLnVwZGF0ZSA9IChvcHRpb25zOiBOZ2JNb2RhbFVwZGF0YWJsZU9wdGlvbnMpID0+IHtcblx0XHRcdG5nYk1vZGFsUmVmLnVwZGF0ZShvcHRpb25zKTtcblx0XHR9O1xuXG5cdFx0bmdiTW9kYWxSZWYudXBkYXRlKG9wdGlvbnMpO1xuXHRcdGlmICh0aGlzLl9tb2RhbFJlZnMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRyZW5kZXJlci5hZGRDbGFzcyh0aGlzLl9kb2N1bWVudC5ib2R5LCAnbW9kYWwtb3BlbicpO1xuXHRcdH1cblxuXHRcdGlmIChiYWNrZHJvcENtcHRSZWYgJiYgYmFja2Ryb3BDbXB0UmVmLmluc3RhbmNlKSB7XG5cdFx0XHRiYWNrZHJvcENtcHRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHRcdH1cblx0XHR3aW5kb3dDbXB0UmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcblx0XHRyZXR1cm4gbmdiTW9kYWxSZWY7XG5cdH1cblxuXHRnZXQgYWN0aXZlSW5zdGFuY2VzKCkge1xuXHRcdHJldHVybiB0aGlzLl9hY3RpdmVJbnN0YW5jZXM7XG5cdH1cblxuXHRkaXNtaXNzQWxsKHJlYXNvbj86IGFueSkge1xuXHRcdHRoaXMuX21vZGFsUmVmcy5mb3JFYWNoKChuZ2JNb2RhbFJlZikgPT4gbmdiTW9kYWxSZWYuZGlzbWlzcyhyZWFzb24pKTtcblx0fVxuXG5cdGhhc09wZW5Nb2RhbHMoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX21vZGFsUmVmcy5sZW5ndGggPiAwO1xuXHR9XG5cblx0cHJpdmF0ZSBfYXR0YWNoQmFja2Ryb3AoY29udGFpbmVyRWw6IEVsZW1lbnQpOiBDb21wb25lbnRSZWY8TmdiTW9kYWxCYWNrZHJvcD4ge1xuXHRcdGxldCBiYWNrZHJvcENtcHRSZWYgPSBjcmVhdGVDb21wb25lbnQoTmdiTW9kYWxCYWNrZHJvcCwge1xuXHRcdFx0ZW52aXJvbm1lbnRJbmplY3RvcjogdGhpcy5fYXBwbGljYXRpb25SZWYuaW5qZWN0b3IsXG5cdFx0XHRlbGVtZW50SW5qZWN0b3I6IHRoaXMuX2luamVjdG9yLFxuXHRcdH0pO1xuXHRcdHRoaXMuX2FwcGxpY2F0aW9uUmVmLmF0dGFjaFZpZXcoYmFja2Ryb3BDbXB0UmVmLmhvc3RWaWV3KTtcblx0XHRjb250YWluZXJFbC5hcHBlbmRDaGlsZChiYWNrZHJvcENtcHRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG5cdFx0cmV0dXJuIGJhY2tkcm9wQ21wdFJlZjtcblx0fVxuXG5cdHByaXZhdGUgX2F0dGFjaFdpbmRvd0NvbXBvbmVudChjb250YWluZXJFbDogRWxlbWVudCwgcHJvamVjdGFibGVOb2RlczogTm9kZVtdW10pOiBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+IHtcblx0XHRsZXQgd2luZG93Q21wdFJlZiA9IGNyZWF0ZUNvbXBvbmVudChOZ2JNb2RhbFdpbmRvdywge1xuXHRcdFx0ZW52aXJvbm1lbnRJbmplY3RvcjogdGhpcy5fYXBwbGljYXRpb25SZWYuaW5qZWN0b3IsXG5cdFx0XHRlbGVtZW50SW5qZWN0b3I6IHRoaXMuX2luamVjdG9yLFxuXHRcdFx0cHJvamVjdGFibGVOb2Rlcyxcblx0XHR9KTtcblx0XHR0aGlzLl9hcHBsaWNhdGlvblJlZi5hdHRhY2hWaWV3KHdpbmRvd0NtcHRSZWYuaG9zdFZpZXcpO1xuXHRcdGNvbnRhaW5lckVsLmFwcGVuZENoaWxkKHdpbmRvd0NtcHRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG5cdFx0cmV0dXJuIHdpbmRvd0NtcHRSZWY7XG5cdH1cblxuXHRwcml2YXRlIF9nZXRDb250ZW50UmVmKFxuXHRcdGNvbnRlbnRJbmplY3RvcjogSW5qZWN0b3IsXG5cdFx0ZW52aXJvbm1lbnRJbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3Rvcixcblx0XHRjb250ZW50OiBUeXBlPGFueT4gfCBUZW1wbGF0ZVJlZjxhbnk+IHwgc3RyaW5nLFxuXHRcdGFjdGl2ZU1vZGFsOiBOZ2JBY3RpdmVNb2RhbCxcblx0XHRvcHRpb25zOiBOZ2JNb2RhbE9wdGlvbnMsXG5cdCk6IENvbnRlbnRSZWYge1xuXHRcdGlmICghY29udGVudCkge1xuXHRcdFx0cmV0dXJuIG5ldyBDb250ZW50UmVmKFtdKTtcblx0XHR9IGVsc2UgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xuXHRcdFx0cmV0dXJuIHRoaXMuX2NyZWF0ZUZyb21UZW1wbGF0ZVJlZihjb250ZW50LCBhY3RpdmVNb2RhbCk7XG5cdFx0fSBlbHNlIGlmIChpc1N0cmluZyhjb250ZW50KSkge1xuXHRcdFx0cmV0dXJuIHRoaXMuX2NyZWF0ZUZyb21TdHJpbmcoY29udGVudCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB0aGlzLl9jcmVhdGVGcm9tQ29tcG9uZW50KGNvbnRlbnRJbmplY3RvciwgZW52aXJvbm1lbnRJbmplY3RvciwgY29udGVudCwgYWN0aXZlTW9kYWwsIG9wdGlvbnMpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgX2NyZWF0ZUZyb21UZW1wbGF0ZVJlZih0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55PiwgYWN0aXZlTW9kYWw6IE5nYkFjdGl2ZU1vZGFsKTogQ29udGVudFJlZiB7XG5cdFx0Y29uc3QgY29udGV4dCA9IHtcblx0XHRcdCRpbXBsaWNpdDogYWN0aXZlTW9kYWwsXG5cdFx0XHRjbG9zZShyZXN1bHQpIHtcblx0XHRcdFx0YWN0aXZlTW9kYWwuY2xvc2UocmVzdWx0KTtcblx0XHRcdH0sXG5cdFx0XHRkaXNtaXNzKHJlYXNvbikge1xuXHRcdFx0XHRhY3RpdmVNb2RhbC5kaXNtaXNzKHJlYXNvbik7XG5cdFx0XHR9LFxuXHRcdH07XG5cdFx0Y29uc3Qgdmlld1JlZiA9IHRlbXBsYXRlUmVmLmNyZWF0ZUVtYmVkZGVkVmlldyhjb250ZXh0KTtcblx0XHR0aGlzLl9hcHBsaWNhdGlvblJlZi5hdHRhY2hWaWV3KHZpZXdSZWYpO1xuXHRcdHJldHVybiBuZXcgQ29udGVudFJlZihbdmlld1JlZi5yb290Tm9kZXNdLCB2aWV3UmVmKTtcblx0fVxuXG5cdHByaXZhdGUgX2NyZWF0ZUZyb21TdHJpbmcoY29udGVudDogc3RyaW5nKTogQ29udGVudFJlZiB7XG5cdFx0Y29uc3QgY29tcG9uZW50ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoYCR7Y29udGVudH1gKTtcblx0XHRyZXR1cm4gbmV3IENvbnRlbnRSZWYoW1tjb21wb25lbnRdXSk7XG5cdH1cblxuXHRwcml2YXRlIF9jcmVhdGVGcm9tQ29tcG9uZW50KFxuXHRcdGNvbnRlbnRJbmplY3RvcjogSW5qZWN0b3IsXG5cdFx0ZW52aXJvbm1lbnRJbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3Rvcixcblx0XHRjb21wb25lbnRUeXBlOiBUeXBlPGFueT4sXG5cdFx0Y29udGV4dDogTmdiQWN0aXZlTW9kYWwsXG5cdFx0b3B0aW9uczogTmdiTW9kYWxPcHRpb25zLFxuXHQpOiBDb250ZW50UmVmIHtcblx0XHRjb25zdCBlbGVtZW50SW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUoe1xuXHRcdFx0cHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOZ2JBY3RpdmVNb2RhbCwgdXNlVmFsdWU6IGNvbnRleHQgfV0sXG5cdFx0XHRwYXJlbnQ6IGNvbnRlbnRJbmplY3Rvcixcblx0XHR9KTtcblx0XHRjb25zdCBjb21wb25lbnRSZWYgPSBjcmVhdGVDb21wb25lbnQoY29tcG9uZW50VHlwZSwge1xuXHRcdFx0ZW52aXJvbm1lbnRJbmplY3Rvcixcblx0XHRcdGVsZW1lbnRJbmplY3Rvcixcblx0XHR9KTtcblx0XHRjb25zdCBjb21wb25lbnROYXRpdmVFbCA9IGNvbXBvbmVudFJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuXHRcdGlmIChvcHRpb25zLnNjcm9sbGFibGUpIHtcblx0XHRcdChjb21wb25lbnROYXRpdmVFbCBhcyBIVE1MRWxlbWVudCkuY2xhc3NMaXN0LmFkZCgnY29tcG9uZW50LWhvc3Qtc2Nyb2xsYWJsZScpO1xuXHRcdH1cblx0XHR0aGlzLl9hcHBsaWNhdGlvblJlZi5hdHRhY2hWaWV3KGNvbXBvbmVudFJlZi5ob3N0Vmlldyk7XG5cdFx0Ly8gRklYTUU6IHdlIHNob3VsZCBoZXJlIGdldCByaWQgb2YgdGhlIGNvbXBvbmVudCBuYXRpdmVFbGVtZW50XG5cdFx0Ly8gYW5kIHVzZSBgW0FycmF5LmZyb20oY29tcG9uZW50TmF0aXZlRWwuY2hpbGROb2RlcyldYCBpbnN0ZWFkIGFuZCByZW1vdmUgdGhlIGFib3ZlIENTUyBjbGFzcy5cblx0XHRyZXR1cm4gbmV3IENvbnRlbnRSZWYoW1tjb21wb25lbnROYXRpdmVFbF1dLCBjb21wb25lbnRSZWYuaG9zdFZpZXcsIGNvbXBvbmVudFJlZik7XG5cdH1cblxuXHRwcml2YXRlIF9zZXRBcmlhSGlkZGVuKGVsZW1lbnQ6IEVsZW1lbnQpIHtcblx0XHRjb25zdCBwYXJlbnQgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ7XG5cdFx0aWYgKHBhcmVudCAmJiBlbGVtZW50ICE9PSB0aGlzLl9kb2N1bWVudC5ib2R5KSB7XG5cdFx0XHRBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuZm9yRWFjaCgoc2libGluZykgPT4ge1xuXHRcdFx0XHRpZiAoc2libGluZyAhPT0gZWxlbWVudCAmJiBzaWJsaW5nLm5vZGVOYW1lICE9PSAnU0NSSVBUJykge1xuXHRcdFx0XHRcdHRoaXMuX2FyaWFIaWRkZW5WYWx1ZXMuc2V0KHNpYmxpbmcsIHNpYmxpbmcuZ2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicpKTtcblx0XHRcdFx0XHRzaWJsaW5nLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0dGhpcy5fc2V0QXJpYUhpZGRlbihwYXJlbnQpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgX3JldmVydEFyaWFIaWRkZW4oKSB7XG5cdFx0dGhpcy5fYXJpYUhpZGRlblZhbHVlcy5mb3JFYWNoKCh2YWx1ZSwgZWxlbWVudCkgPT4ge1xuXHRcdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsIHZhbHVlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWhpZGRlbicpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHRoaXMuX2FyaWFIaWRkZW5WYWx1ZXMuY2xlYXIoKTtcblx0fVxuXG5cdHByaXZhdGUgX3JlZ2lzdGVyTW9kYWxSZWYobmdiTW9kYWxSZWY6IE5nYk1vZGFsUmVmKSB7XG5cdFx0Y29uc3QgdW5yZWdpc3Rlck1vZGFsUmVmID0gKCkgPT4ge1xuXHRcdFx0Y29uc3QgaW5kZXggPSB0aGlzLl9tb2RhbFJlZnMuaW5kZXhPZihuZ2JNb2RhbFJlZik7XG5cdFx0XHRpZiAoaW5kZXggPiAtMSkge1xuXHRcdFx0XHR0aGlzLl9tb2RhbFJlZnMuc3BsaWNlKGluZGV4LCAxKTtcblx0XHRcdFx0dGhpcy5fYWN0aXZlSW5zdGFuY2VzLmVtaXQodGhpcy5fbW9kYWxSZWZzKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdHRoaXMuX21vZGFsUmVmcy5wdXNoKG5nYk1vZGFsUmVmKTtcblx0XHR0aGlzLl9hY3RpdmVJbnN0YW5jZXMuZW1pdCh0aGlzLl9tb2RhbFJlZnMpO1xuXHRcdG5nYk1vZGFsUmVmLnJlc3VsdC50aGVuKHVucmVnaXN0ZXJNb2RhbFJlZiwgdW5yZWdpc3Rlck1vZGFsUmVmKTtcblx0fVxuXG5cdHByaXZhdGUgX3JlZ2lzdGVyV2luZG93Q21wdChuZ2JXaW5kb3dDbXB0OiBDb21wb25lbnRSZWY8TmdiTW9kYWxXaW5kb3c+KSB7XG5cdFx0dGhpcy5fd2luZG93Q21wdHMucHVzaChuZ2JXaW5kb3dDbXB0KTtcblx0XHR0aGlzLl9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZC5uZXh0KCk7XG5cblx0XHRuZ2JXaW5kb3dDbXB0Lm9uRGVzdHJveSgoKSA9PiB7XG5cdFx0XHRjb25zdCBpbmRleCA9IHRoaXMuX3dpbmRvd0NtcHRzLmluZGV4T2YobmdiV2luZG93Q21wdCk7XG5cdFx0XHRpZiAoaW5kZXggPiAtMSkge1xuXHRcdFx0XHR0aGlzLl93aW5kb3dDbXB0cy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdFx0XHR0aGlzLl9hY3RpdmVXaW5kb3dDbXB0SGFzQ2hhbmdlZC5uZXh0KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cbiJdfQ==