UNPKG

ngx-modal-ease

Version:

ngx-modal-ease is a versatile Angular library providing a lightweight, simple, and performant modal. This library supports data communication between components, opening of multiple modals, custom animations, and a range of customisable options.

137 lines 24.7 kB
import { Component, ViewChild, ChangeDetectionStrategy, ViewEncapsulation, } from '@angular/core'; import { CommonModule } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "./modal.service"; export class ModalComponent { constructor(modalService, element) { this.modalService = modalService; this.element = element; this.modalLeaveAnimation = ''; this.overlayLeaveAnimation = ''; this.overlayClosed = false; this.modalClosed = false; this.layerLevel = 0; /** * Multiple modals might register multiple event listener, hence the 'layerLevel' variable and two times the condition check for the escape option. * Arrow function to respect the this instance. */ this.handleEscape = (event) => { if (event.key === 'Escape') { if (this.options?.actions?.escape === false) return; if (this.layerLevel === this.modalService.layerLevel) { this.modalService.closedOnClickOrEscape = true; this.modalService.close(); } } }; } ngOnInit() { this.options = this.modalService.options; this.modalService.modalInstances.push(this); this.modalService.layerLevel += 1; this.layerLevel = this.modalService.layerLevel; if (this.options?.actions?.escape === false) return; document.addEventListener('keydown', this.handleEscape); } ngAfterViewInit() { this.addOptionsAndAnimations(); } onClose() { if (this.options?.actions?.click === false) return; this.modalService.closedOnClickOrEscape = true; this.modalService.close(); } /** * Add options and animations * Apply user style and animations, listen to animation ends. Apply z-indexes on overlay and modal, with 1000 as incremental value. */ addOptionsAndAnimations() { this.modal.nativeElement.style.width = this.options?.size?.width || ''; this.modal.nativeElement.style.maxWidth = this.options?.size?.maxWidth || ''; this.modal.nativeElement.style.height = this.options?.size?.height || ''; this.modal.nativeElement.style.maxHeight = this.options?.size?.maxHeight || ''; this.modal.nativeElement.style.padding = this.options?.size?.padding || '0.5rem'; const overlayZIndex = 1000 * this.modalService.modalInstances.length; this.overlay.nativeElement.style.zIndex = `${overlayZIndex}`; this.modal.nativeElement.style.zIndex = `${overlayZIndex + 1000}`; this.modalLeaveAnimation = this.options?.modal?.leave || ''; this.overlayLeaveAnimation = this.options?.overlay?.leave || ''; this.modal.nativeElement.style.animation = this.options?.modal?.enter || ''; this.modal.nativeElement.style.top = this.options?.modal?.top || '50%'; this.modal.nativeElement.style.left = this.options?.modal?.left || '50%'; this.overlay.nativeElement.style.animation = this.options?.overlay?.enter || ''; this.overlay.nativeElement.style.backgroundColor = this.options?.overlay?.backgroundColor || ''; } removeElementIfNotAnimated(element, animation) { if (!animation) { element.remove(); if (element.classList.contains('ngx-modal')) { this.modalClosed = true; } else { this.overlayClosed = true; } } } /** * Clean the DOM * Apply the leaving animations and clean the DOM. Three different use cases. * Last In First Out */ close(contentCp) { this.modalService.layerLevel -= 1; this.modal.nativeElement.style.animation = this.modalLeaveAnimation; this.overlay.nativeElement.style.animation = this.overlayLeaveAnimation; document.removeEventListener('keydown', this.handleEscape); // First: no animations on both elements if (!this.modalLeaveAnimation && !this.overlayLeaveAnimation) { this.element.nativeElement.remove(); contentCp.contentCpRef.destroy(); return; } // Second: 1/2 animated, remove directly element if not animated this.removeElementIfNotAnimated(this.modal.nativeElement, this.modalLeaveAnimation); this.removeElementIfNotAnimated(this.overlay?.nativeElement, this.overlayLeaveAnimation); // Third: Both animated with differents animation time, remove modal component as soon as last one ends this.modal.nativeElement.addEventListener('animationend', () => { this.modal.nativeElement.remove(); this.modalClosed = true; this.removeModalComponent(contentCp); }); this.overlay.nativeElement.addEventListener('animationend', () => { this.overlay.nativeElement.remove(); this.overlayClosed = true; this.removeModalComponent(contentCp); }); } /** * Remove modal when both animations come to an end. */ removeModalComponent(contentCp) { if (this.modalClosed && this.overlayClosed) { this.element.nativeElement.remove(); contentCp.contentCpRef.destroy(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: ModalComponent, deps: [{ token: i1.ModalService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.9", type: ModalComponent, isStandalone: true, selector: "app-modal", viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }, { propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], ngImport: i0, template: "<div class=\"modal-container\">\n <section class=\"ngx-modal\" #modal>\n <ng-content></ng-content>\n </section>\n\n <div class=\"ngx-overlay\" #overlay (click)=\"onClose()\"></div>\n</div>\n", styles: [".ngx-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0006;z-index:1000}.ngx-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);padding:.5rem;max-width:100%;z-index:2000}@keyframes enter-going-down{0%{transform:translate(-50%,-60%)}to{transform:translate(-50%,-50%)}}@keyframes enter-scaling{0%{transform:scale(.8) translate(-50%,-50%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}@keyframes enter-scale-down{0%{transform:scale(1.5) translate(-50%,-60%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes bounce-in{0%{transform:translate(-50%,-85%)}20%,80%,to{transform:translate(-50%,-50%)}60%{transform:translate(-50%,-65%)}90%{transform:translate(-50%,-53%)}}@keyframes scale-rotate{30%{transform:scale(1.05) translate(-50%,-50%);transform-origin:left}40%,60%{transform:rotate(-3deg) scale(1.05) translate(-50%,-50%);transform-origin:left}50%{transform:rotate(3deg) scale(1.05) translate(-50%,-50%);transform-origin:left}70%{transform:rotate(0) scale(1.05) translate(-50%,-50%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: ModalComponent, decorators: [{ type: Component, args: [{ selector: 'app-modal', imports: [CommonModule], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"modal-container\">\n <section class=\"ngx-modal\" #modal>\n <ng-content></ng-content>\n </section>\n\n <div class=\"ngx-overlay\" #overlay (click)=\"onClose()\"></div>\n</div>\n", styles: [".ngx-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0006;z-index:1000}.ngx-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);padding:.5rem;max-width:100%;z-index:2000}@keyframes enter-going-down{0%{transform:translate(-50%,-60%)}to{transform:translate(-50%,-50%)}}@keyframes enter-scaling{0%{transform:scale(.8) translate(-50%,-50%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}@keyframes enter-scale-down{0%{transform:scale(1.5) translate(-50%,-60%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes bounce-in{0%{transform:translate(-50%,-85%)}20%,80%,to{transform:translate(-50%,-50%)}60%{transform:translate(-50%,-65%)}90%{transform:translate(-50%,-53%)}}@keyframes scale-rotate{30%{transform:scale(1.05) translate(-50%,-50%);transform-origin:left}40%,60%{transform:rotate(-3deg) scale(1.05) translate(-50%,-50%);transform-origin:left}50%{transform:rotate(3deg) scale(1.05) translate(-50%,-50%);transform-origin:left}70%{transform:rotate(0) scale(1.05) translate(-50%,-50%);transform-origin:left}to{transform:scale(1) translate(-50%,-50%);transform-origin:left}}\n"] }] }], ctorParameters: () => [{ type: i1.ModalService }, { type: i0.ElementRef }], propDecorators: { modal: [{ type: ViewChild, args: ['modal'] }], overlay: [{ type: ViewChild, args: ['overlay'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1vZGFsLWVhc2Uvc3JjL2xpYi9tb2RhbC9tb2RhbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbW9kYWwtZWFzZS9zcmMvbGliL21vZGFsL21vZGFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsU0FBUyxFQUVULHVCQUF1QixFQUN2QixpQkFBaUIsR0FFbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7QUFjL0MsTUFBTSxPQUFPLGNBQWM7SUFVekIsWUFDVSxZQUEwQixFQUMxQixPQUFnQztRQURoQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixZQUFPLEdBQVAsT0FBTyxDQUF5QjtRQVIxQyx3QkFBbUIsR0FBRyxFQUFFLENBQUM7UUFDekIsMEJBQXFCLEdBQUcsRUFBRSxDQUFDO1FBQzNCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFzQmY7OztXQUdHO1FBQ0gsaUJBQVksR0FBRyxDQUFDLEtBQW9CLEVBQUUsRUFBRTtZQUN0QyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssUUFBUSxFQUFFO2dCQUMxQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sS0FBSyxLQUFLO29CQUFFLE9BQU87Z0JBRXBELElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRTtvQkFDcEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7b0JBQy9DLElBQUksQ0FBQyxZQUFZLENBQUMs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YSxFQUFFO1lBQzFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BDLFNBQVMsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDbEM7SUFDSCxDQUFDOzhHQS9JVSxjQUFjO2tHQUFkLGNBQWMsMFBDdkIzQixzTUFPQSw4MENEV1ksWUFBWTs7MkZBS1gsY0FBYztrQkFUMUIsU0FBUzsrQkFDRSxXQUFXLFdBR1osQ0FBQyxZQUFZLENBQUMsY0FDWCxJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0saUJBQ2hDLGlCQUFpQixDQUFDLElBQUk7MEdBR2pCLEtBQUs7c0JBQXhCLFNBQVM7dUJBQUMsT0FBTztnQkFDSSxPQUFPO3NCQUE1QixTQUFTO3VCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIFZpZXdDaGlsZCxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG4gIE9uSW5pdCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgTW9kYWxTZXJ2aWNlIH0gZnJvbSAnLi9tb2RhbC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgT3B0aW9ucyB9IGZyb20gJy4vbW9kYWwtb3B0aW9ucyc7XHJcbmltcG9ydCB7IFByb21pc2VNb2RhbCB9IGZyb20gJy4vaW50ZXJuYWwtaW50ZXJmYWNlcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1tb2RhbCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21vZGFsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9tb2RhbC5jb21wb25lbnQuY3NzJ10sXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTW9kYWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xyXG4gIEBWaWV3Q2hpbGQoJ21vZGFsJykgbW9kYWwhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdvdmVybGF5Jykgb3ZlcmxheSE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xyXG4gIG9wdGlvbnMhOiBPcHRpb25zIHwgdW5kZWZpbmVkO1xyXG4gIG1vZGFsTGVhdmVBbmltYXRpb24gPSAnJztcclxuICBvdmVybGF5TGVhdmVBbmltYXRpb24gPSAnJztcclxuICBvdmVybGF5Q2xvc2VkID0gZmFsc2U7XHJcbiAgbW9kYWxDbG9zZWQgPSBmYWxzZTtcclxuICBsYXllckxldmVsID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTW9kYWxTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PlxyXG4gICkge31cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLm1vZGFsU2VydmljZS5vcHRpb25zO1xyXG4gICAgdGhpcy5tb2RhbFNlcnZpY2UubW9kYWxJbnN0YW5jZXMucHVzaCh0aGlzKTtcclxuICAgIHRoaXMubW9kYWxTZXJ2aWNlLmxheWVyTGV2ZWwgKz0gMTtcclxuICAgIHRoaXMubGF5ZXJMZXZlbCA9IHRoaXMubW9kYWxTZXJ2aWNlLmxheWVyTGV2ZWw7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucz8uYWN0aW9ucz8uZXNjYXBlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZUVzY2FwZSk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLmFkZE9wdGlvbnNBbmRBbmltYXRpb25zKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNdWx0aXBsZSBtb2RhbHMgbWlnaHQgcmVnaXN0ZXIgbXVsdGlwbGUgZXZlbnQgbGlzdGVuZXIsIGhlbmNlIHRoZSAnbGF5ZXJMZXZlbCcgdmFyaWFibGUgYW5kIHR3byB0aW1lcyB0aGUgY29uZGl0aW9uIGNoZWNrIGZvciB0aGUgZXNjYXBlIG9wdGlvbi5cclxuICAgKiBBcnJvdyBmdW5jdGlvbiB0byByZXNwZWN0IHRoZSB0aGlzIGluc3RhbmNlLlxyXG4gICAqL1xyXG4gIGhhbmRsZUVzY2FwZSA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpIHtcclxuICAgICAgaWYgKHRoaXMub3B0aW9ucz8uYWN0aW9ucz8uZXNjYXBlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgaWYgKHRoaXMubGF5ZXJMZXZlbCA9PT0gdGhpcy5tb2RhbFNlcnZpY2UubGF5ZXJMZXZlbCkge1xyXG4gICAgICAgIHRoaXMubW9kYWxTZXJ2aWNlLmNsb3NlZE9uQ2xpY2tPckVzY2FwZSA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5tb2RhbFNlcnZpY2UuY2xvc2UoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIG9uQ2xvc2UoKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zPy5hY3Rpb25zPy5jbGljayA9PT0gZmFsc2UpIHJldHVybjtcclxuICAgIHRoaXMubW9kYWxTZXJ2aWNlLmNsb3NlZE9uQ2xpY2tPckVzY2FwZSA9IHRydWU7XHJcbiAgICB0aGlzLm1vZGFsU2VydmljZS5jbG9zZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkIG9wdGlvbnMgYW5kIGFuaW1hdGlvbnNcclxuICAgKiBBcHBseSB1c2VyIHN0eWxlIGFuZCBhbmltYXRpb25zLCBsaXN0ZW4gdG8gYW5pbWF0aW9uIGVuZHMuIEFwcGx5IHotaW5kZXhlcyBvbiBvdmVybGF5IGFuZCBtb2RhbCwgd2l0aCAxMDAwIGFzIGluY3JlbWVudGFsIHZhbHVlLlxyXG4gICAqL1xyXG4gIGFkZE9wdGlvbnNBbmRBbmltYXRpb25zKCkge1xyXG4gICAgdGhpcy5tb2RhbC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy5vcHRpb25zPy5zaXplPy53aWR0aCB8fCAnJztcclxuICAgIHRoaXMubW9kYWwubmF0aXZlRWxlbWVudC5zdHlsZS5tYXhXaWR0aCA9XHJcbiAgICAgIHRoaXMub3B0aW9ucz8uc2l6ZT8ubWF4V2lkdGggfHwgJyc7XHJcbiAgICB0aGlzLm1vZGFsLm5hdGl2ZUVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5vcHRpb25zPy5zaXplPy5oZWlnaHQgfHwgJyc7XHJcbiAgICB0aGlzLm1vZGFsLm5hdGl2ZUVsZW1lbnQuc3R5bGUubWF4SGVpZ2h0ID1cclxuICAgICAgdGhpcy5vcHRpb25zPy5zaXplPy5tYXhIZWlnaHQgfHwgJyc7XHJcbiAgICB0aGlzLm1vZGFsLm5hdGl2ZUVsZW1lbnQuc3R5bGUucGFkZGluZyA9XHJcbiAgICAgIHRoaXMub3B0aW9ucz8uc2l6ZT8ucGFkZGluZyB8fCAnMC41cmVtJztcclxuXHJcbiAgICBjb25zdCBvdmVybGF5WkluZGV4ID0gMTAwMCAqIHRoaXMubW9kYWxTZXJ2aWNlLm1vZGFsSW5zdGFuY2VzLmxlbmd0aDtcclxuICAgIHRoaXMub3ZlcmxheS5uYXRpdmVFbGVtZW50LnN0eWxlLnpJbmRleCA9IGAke292ZXJsYXlaSW5kZXh9YDtcclxuICAgIHRoaXMubW9kYWwubmF0aXZlRWxlbWVudC5zdHlsZS56SW5kZXggPSBgJHtvdmVybGF5WkluZGV4ICsgMTAwMH1gO1xyXG5cclxuICAgIHRoaXMubW9kYWxMZWF2ZUFuaW1hdGlvbiA9IHRoaXMub3B0aW9ucz8ubW9kYWw/LmxlYXZlIHx8ICcnO1xyXG4gICAgdGhpcy5vdmVybGF5TGVhdmVBbmltYXRpb24gPSB0aGlzLm9wdGlvbnM/Lm92ZXJsYXk/LmxlYXZlIHx8ICcnO1xyXG4gICAgdGhpcy5tb2RhbC5uYXRpdmVFbGVtZW50LnN0eWxlLmFuaW1hdGlvbiA9IHRoaXMub3B0aW9ucz8ubW9kYWw/LmVudGVyIHx8ICcnO1xyXG4gICAgdGhpcy5tb2RhbC5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCA9IHRoaXMub3B0aW9ucz8ubW9kYWw/LnRvcCB8fCAnNTAlJztcclxuICAgIHRoaXMubW9kYWwubmF0aXZlRWxlbWVudC5zdHlsZS5sZWZ0ID0gdGhpcy5vcHRpb25zPy5tb2RhbD8ubGVmdCB8fCAnNTAlJztcclxuXHJcbiAgICB0aGlzLm92ZXJsYXkubmF0aXZlRWxlbWVudC5zdHlsZS5hbmltYXRpb24gPVxyXG4gICAgICB0aGlzLm9wdGlvbnM/Lm92ZXJsYXk/LmVudGVyIHx8ICcnO1xyXG4gICAgdGhpcy5vdmVybGF5Lm5hdGl2ZUVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID1cclxuICAgICAgdGhpcy5vcHRpb25zPy5vdmVybGF5Py5iYWNrZ3JvdW5kQ29sb3IgfHwgJyc7XHJcbiAgfVxyXG5cclxuICByZW1vdmVFbGVtZW50SWZOb3RBbmltYXRlZChlbGVtZW50OiBIVE1MRGl2RWxlbWVudCwgYW5pbWF0aW9uOiBzdHJpbmcpIHtcclxuICAgIGlmICghYW5pbWF0aW9uKSB7XHJcbiAgICAgIGVsZW1lbnQucmVtb3ZlKCk7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ25neC1tb2RhbCcpKSB7XHJcbiAgICAgICAgdGhpcy5tb2RhbENsb3NlZCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5vdmVybGF5Q2xvc2VkID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYW4gdGhlIERPTVxyXG4gICAqIEFwcGx5IHRoZSBsZWF2aW5nIGFuaW1hdGlvbnMgYW5kIGNsZWFuIHRoZSBET00uIFRocmVlIGRpZmZlcmVudCB1c2UgY2FzZXMuXHJcbiAgICogTGFzdCBJbiBGaXJzdCBPdXRcclxuICAgKi9cclxuICBjbG9zZShjb250ZW50Q3A6IFByb21pc2VNb2RhbCkge1xyXG4gICAgdGhpcy5tb2RhbFNlcnZpY2UubGF5ZXJMZXZlbCAtPSAxO1xyXG5cclxuICAgIHRoaXMubW9kYWwubmF0aXZlRWxlbWVudC5zdHlsZS5hbmltYXRpb24gPSB0aGlzLm1vZGFsTGVhdmVBbmltYXRpb247XHJcbiAgICB0aGlzLm92ZXJsYXkubmF0aXZlRWxlbWVudC5zdHlsZS5hbmltYXRpb24gPSB0aGlzLm92ZXJsYXlMZWF2ZUFuaW1hdGlvbjtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZUVzY2FwZSk7XHJcblxyXG4gICAgLy8gRmlyc3Q6IG5vIGFuaW1hdGlvbnMgb24gYm90aCBlbGVtZW50c1xyXG4gICAgaWYgKCF0aGlzLm1vZGFsTGVhdmVBbmltYXRpb24gJiYgIXRoaXMub3ZlcmxheUxlYXZlQW5pbWF0aW9uKSB7XHJcbiAgICAgIHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LnJlbW92ZSgpO1xyXG4gICAgICBjb250ZW50Q3AuY29udGVudENwUmVmLmRlc3Ryb3koKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNlY29uZDogMS8yIGFuaW1hdGVkLCByZW1vdmUgZGlyZWN0bHkgZWxlbWVudCBpZiBub3QgYW5pbWF0ZWRcclxuICAgIHRoaXMucmVtb3ZlRWxlbWVudElmTm90QW5pbWF0ZWQoXHJcbiAgICAgIHRoaXMubW9kYWwubmF0aXZlRWxlbWVudCxcclxuICAgICAgdGhpcy5tb2RhbExlYXZlQW5pbWF0aW9uXHJcbiAgICApO1xyXG4gICAgdGhpcy5yZW1vdmVFbGVtZW50SWZOb3RBbmltYXRlZChcclxuICAgICAgdGhpcy5vdmVybGF5Py5uYXRpdmVFbGVtZW50LFxyXG4gICAgICB0aGlzLm92ZXJsYXlMZWF2ZUFuaW1hdGlvblxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBUaGlyZDogQm90aCBhbmltYXRlZCB3aXRoIGRpZmZlcmVudHMgYW5pbWF0aW9uIHRpbWUsIHJlbW92ZSBtb2RhbCBjb21wb25lbnQgYXMgc29vbiBhcyBsYXN0IG9uZSBlbmRzXHJcbiAgICB0aGlzLm1vZGFsLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignYW5pbWF0aW9uZW5kJywgKCkgPT4ge1xyXG4gICAgICB0aGlzLm1vZGFsLm5hdGl2ZUVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICAgIHRoaXMubW9kYWxDbG9zZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLnJlbW92ZU1vZGFsQ29tcG9uZW50KGNvbnRlbnRDcCk7XHJcbiAgICB9KTtcclxuICAgIHRoaXMub3ZlcmxheS5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2FuaW1hdGlvbmVuZCcsICgpID0+IHtcclxuICAgICAgdGhpcy5vdmVybGF5Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICAgIHRoaXMub3ZlcmxheUNsb3NlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMucmVtb3ZlTW9kYWxDb21wb25lbnQoY29udGVudENwKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlIG1vZGFsIHdoZW4gYm90aCBhbmltYXRpb25zIGNvbWUgdG8gYW4gZW5kLlxyXG4gICAqL1xyXG4gIHJlbW92ZU1vZGFsQ29tcG9uZW50KGNvbnRlbnRDcDogUHJvbWlzZU1vZGFsKSB7XHJcbiAgICBpZiAodGhpcy5tb2RhbENsb3NlZCAmJiB0aGlzLm92ZXJsYXlDbG9zZWQpIHtcclxuICAgICAgdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICAgIGNvbnRlbnRDcC5jb250ZW50Q3BSZWYuZGVzdHJveSgpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwibW9kYWwtY29udGFpbmVyXCI+XG4gIDxzZWN0aW9uIGNsYXNzPVwibmd4LW1vZGFsXCIgI21vZGFsPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgPC9zZWN0aW9uPlxuXG4gIDxkaXYgY2xhc3M9XCJuZ3gtb3ZlcmxheVwiICNvdmVybGF5IChjbGljayk9XCJvbkNsb3NlKClcIj48L2Rpdj5cbjwvZGl2PlxuIl19