UNPKG

@universis/common

Version:

Universis - common directives and services

510 lines 60.8 kB
import { Component, Input, ElementRef, ViewEncapsulation, Renderer2 } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { ButtonTypes } from './ButtonTypes'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/common"; import * as i3 from "@ngx-translate/core"; export class RouterModalComponent { constructor(_element, _activatedRoute, _router, _renderer) { this._element = _element; this._activatedRoute = _activatedRoute; this._router = _router; this._renderer = _renderer; this.componentModalChanges = null; this.componentButtonChanges = null; this.waiting = false; this.modalTitle = ''; // these properties are here as inputs in order to have a way to customize text and class of each button this.okButtonText = ButtonTypes.ok.buttonText; this.okButtonClass = ButtonTypes.ok.buttonClass; this.cancelButtonText = ButtonTypes.cancel.buttonText; this.cancelButtonClass = ButtonTypes.cancel.buttonClass; this.yesButtonText = ButtonTypes.yes.buttonText; this.yesButtonClass = ButtonTypes.yes.buttonClass; this.noButtonText = ButtonTypes.no.buttonText; this.noButtonClass = ButtonTypes.no.buttonClass; this.abortButtonText = ButtonTypes.abort.buttonText; this.abortButtonClass = ButtonTypes.abort.buttonClass; this.retryButtonText = ButtonTypes.retry.buttonText; this.retryButtonClass = ButtonTypes.retry.buttonClass; this.ignoreButtonText = ButtonTypes.ignore.buttonText; this.ignoreButtonClass = ButtonTypes.ignore.buttonClass; this.previousButtonText = ButtonTypes.previous.buttonText; this.previousButtonClass = ButtonTypes.previous.buttonClass; this.nextButtonText = ButtonTypes.next.buttonText; this.nextButtonClass = ButtonTypes.next.buttonClass; // default instance buttons this.instanceButtons = { ok: null, cancel: null, yes: null, no: null, abort: null, retry: null, ignore: null, previous: null, next: null }; } async cancel() { try { if (this.componentReference) { // set waiting this.waiting = true; // if component has cancel() method if (typeof this.componentReference.cancel === 'function') { // do cancel await this.componentReference.cancel(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async ok() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.ok === 'function') { // do submit await this.componentReference.ok(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async abort() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.abort === 'function') { // do submit await this.componentReference.abort(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async retry() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.retry === 'function') { // do submit await this.componentReference.retry(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async ignore() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.ignore === 'function') { // do submit await this.componentReference.ignore(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async previous() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.previous === 'function') { // do submit await this.componentReference.previous(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async next() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.next === 'function') { // do submit await this.componentReference.next(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async yes() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.yes === 'function') { // do submit await this.componentReference.yes(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } async no() { try { if (this.componentReference) { // set waiting this.waiting = true; if (typeof this.componentReference.no === 'function') { // do submit await this.componentReference.no(); } else { await this._router.navigate(['../'], { relativeTo: this._activatedRoute }); } // unset waiting this.waiting = false; } } catch (err) { this.waiting = false; } } onActivate(event) { this.componentReference = event; // get router outlet component if (this.componentReference) { if (this.componentReference.buttonChanges) { // subscribe for any button changes this.componentButtonChanges = this.componentReference.buttonChanges .subscribe((buttonChange) => { if (buttonChange) { // assign button changes Object.assign(this.instanceButtons, buttonChange); } }); } if (this.componentReference.modalChanges) { // get modal changes this.componentModalChanges = this.componentReference.modalChanges.subscribe((modalChanges) => { this.modalInstanceTitle = modalChanges.modalTitle; if (modalChanges.modalClass) { this.modalInstanceClass = modalChanges.modalClass; } }); } // get title this.modalInstanceTitle = this.componentReference.modalTitle; // get class this.modalInstanceClass = this.componentReference.modalClass; // hold this to validate buttons let hasAtLeastOneButton = false; this.instanceButtons = { ok: null, cancel: null, yes: null, no: null, abort: null, retry: null, ignore: null, previous: null, next: null }; // enumerate button types Object.keys(ButtonTypes).forEach(key => { // search if component has a method with the same name if (typeof this.componentReference[key] === 'function') { // enable button this.instanceButtons[key] = Object.assign({}, ButtonTypes[key]); hasAtLeastOneButton = true; const buttonTextProperty = `${key}ButtonText`; if (this.componentReference.hasOwnProperty(buttonTextProperty)) { this.instanceButtons[key].buttonText = this.componentReference[buttonTextProperty]; } else { // get property from this component this.instanceButtons[key].buttonText = this[buttonTextProperty]; } const buttonClassProperty = `${key}ButtonClass`; if (this.componentReference.hasOwnProperty(buttonClassProperty)) { this.instanceButtons[key].buttonClass = this.componentReference[buttonClassProperty]; } else { // get property from this component this.instanceButtons[key].buttonClass = this[buttonClassProperty]; } } }); if (!hasAtLeastOneButton) { // there are no buttons, so add only ok this.instanceButtons.ok = Object.assign({}, ButtonTypes.ok); } } const backdropElement = this._element.nativeElement.querySelector('.modal-backdrop'); this._element.nativeElement.querySelector('.bd-modal').classList.remove('d-none'); this._renderer.addClass(document.body, 'overflow-hidden'); this._renderer.addClass(document.body, 'pr-3'); // add large modal default styles // this operation adds scrolling to modal container // in cases where modal overflows the height of the container const modalElement = this._element.nativeElement.querySelector('.modal'); if (modalElement) { modalElement.style.setProperty('overflow-x', 'hidden'); modalElement.style.setProperty('overflow-y', 'auto'); } if (backdropElement) { // remove d-none backdropElement.classList.remove('d-none'); // add show backdropElement.classList.add('show'); } return false; } // noinspection JSUnusedLocalSymbols onDeactivate(event) { if (this.componentModalChanges) { this.componentModalChanges.unsubscribe(); this.componentModalChanges = null; } if (this.componentButtonChanges) { this.componentButtonChanges.unsubscribe(); this.componentButtonChanges = null; } // restore properties this.modalInstanceTitle = this.modalTitle; this.modalInstanceClass = this.modalClass; this.componentReference = null; const backdropElement = this._element.nativeElement.querySelector('.modal-backdrop'); this._element.nativeElement.querySelector('.bd-modal').classList.add('d-none'); this._renderer.removeClass(document.body, 'overflow-hidden'); this._renderer.removeClass(document.body, 'pr-3'); if (backdropElement) { // remove show backdropElement.classList.remove('show'); // add d-none backdropElement.classList.add('d-none'); } return false; } } RouterModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RouterModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); RouterModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RouterModalComponent, selector: "router-modal", inputs: { modalTitle: "modalTitle", modalClass: "modalClass", okButtonText: "okButtonText", okButtonClass: "okButtonClass", cancelButtonText: "cancelButtonText", cancelButtonClass: "cancelButtonClass", yesButtonText: "yesButtonText", yesButtonClass: "yesButtonClass", noButtonText: "noButtonText", noButtonClass: "noButtonClass", abortButtonText: "abortButtonText", abortButtonClass: "abortButtonClass", retryButtonText: "retryButtonText", retryButtonClass: "retryButtonClass", ignoreButtonText: "ignoreButtonText", ignoreButtonClass: "ignoreButtonClass", previousButtonText: "previousButtonText", previousButtonClass: "previousButtonClass", nextButtonText: "nextButtonText", nextButtonClass: "nextButtonClass" }, ngImport: i0, template: ` <div class="bd-modal d-none"> <div class="modal-backdrop fade d-none"></div> <div class="modal" tabindex="-1" role="dialog" [ngClass]="{ 'modal-waiting': waiting }"> <div class="modal-dialog" [ngClass]="modalInstanceClass" role="document"> <div class="modal-content"> <div class="modal-header" *ngIf="modalInstanceTitle"> <h5 class="modal-title">{{modalInstanceTitle | translate}}</h5> <button *ngIf="instanceButtons.cancel" [disabled]="waiting || instanceButtons.cancel.buttonDisabled" (click)="cancel()" type="button" class="close" data-dismiss="modal" aria-label="Cancel"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <router-outlet (activate)="onActivate($event)" (deactivate)="onDeactivate($event)" name="modal"></router-outlet> </div> <div class="modal-footer justify-content-end"> <button *ngIf="instanceButtons.previous" [disabled]="waiting || instanceButtons.previous.buttonDisabled" (click)="previous()" type="button" [ngClass]="instanceButtons.previous.buttonClass"> {{instanceButtons.previous.buttonText | translate}} </button> <button *ngIf="instanceButtons.ok" [disabled]="waiting || instanceButtons.ok.buttonDisabled" (click)="ok()" type="button" [ngClass]="instanceButtons.ok.buttonClass"> {{instanceButtons.ok.buttonText | translate}} </button> <button *ngIf="instanceButtons.yes" [disabled]="waiting || instanceButtons.yes.buttonDisabled" (click)="yes()" type="button" [ngClass]="instanceButtons.yes.buttonClass"> {{instanceButtons.yes.buttonText | translate}} </button> <button *ngIf="instanceButtons.no" [disabled]="waiting || instanceButtons.no.buttonDisabled" (click)="no()" type="button" [ngClass]="instanceButtons.no.buttonClass"> {{instanceButtons.no.buttonText | translate}} </button> <button *ngIf="instanceButtons.next" [disabled]="waiting || instanceButtons.next.buttonDisabled" (click)="next()" type="button" [ngClass]="instanceButtons.next.buttonClass"> {{instanceButtons.next.buttonText | translate}} </button> <button *ngIf="instanceButtons.cancel" [disabled]="waiting || instanceButtons.cancel.buttonDisabled" (click)="cancel()" type="button" [ngClass]="instanceButtons.cancel.buttonClass" data-dismiss="modal"> {{instanceButtons.cancel.buttonText | translate}} </button> <button *ngIf="instanceButtons.abort" [disabled]="waiting || instanceButtons.abort.buttonDisabled" (click)="abort()" type="button" [ngClass]="instanceButtons.abort.buttonClass"> {{instanceButtons.abort.buttonText | translate}} </button> <button *ngIf="instanceButtons.retry" [disabled]="waiting || instanceButtons.retry.buttonDisabled" (click)="retry()" type="button" [ngClass]="instanceButtons.retry.buttonClass"> {{instanceButtons.retry.buttonText | translate}} </button> <button *ngIf="instanceButtons.ignore" [disabled]="waiting || instanceButtons.ignore.buttonDisabled" (click)="ignore()" type="button" [ngClass]="instanceButtons.ignore.buttonClass" data-dismiss="modal"> {{instanceButtons.ignore.buttonText | translate}} </button> </div> </div> </div> </div> </div> `, isInline: true, styles: [".bd-modal .modal{position:fixed;right:auto;bottom:auto;z-index:1045;display:block}.bd-modal .modal .modal-body{margin-top:0;margin-bottom:0}.bd-modal .modal.modal-waiting{opacity:.6}\n"], dependencies: [{ kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RouterModalComponent, decorators: [{ type: Component, args: [{ selector: 'router-modal', template: ` <div class="bd-modal d-none"> <div class="modal-backdrop fade d-none"></div> <div class="modal" tabindex="-1" role="dialog" [ngClass]="{ 'modal-waiting': waiting }"> <div class="modal-dialog" [ngClass]="modalInstanceClass" role="document"> <div class="modal-content"> <div class="modal-header" *ngIf="modalInstanceTitle"> <h5 class="modal-title">{{modalInstanceTitle | translate}}</h5> <button *ngIf="instanceButtons.cancel" [disabled]="waiting || instanceButtons.cancel.buttonDisabled" (click)="cancel()" type="button" class="close" data-dismiss="modal" aria-label="Cancel"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <router-outlet (activate)="onActivate($event)" (deactivate)="onDeactivate($event)" name="modal"></router-outlet> </div> <div class="modal-footer justify-content-end"> <button *ngIf="instanceButtons.previous" [disabled]="waiting || instanceButtons.previous.buttonDisabled" (click)="previous()" type="button" [ngClass]="instanceButtons.previous.buttonClass"> {{instanceButtons.previous.buttonText | translate}} </button> <button *ngIf="instanceButtons.ok" [disabled]="waiting || instanceButtons.ok.buttonDisabled" (click)="ok()" type="button" [ngClass]="instanceButtons.ok.buttonClass"> {{instanceButtons.ok.buttonText | translate}} </button> <button *ngIf="instanceButtons.yes" [disabled]="waiting || instanceButtons.yes.buttonDisabled" (click)="yes()" type="button" [ngClass]="instanceButtons.yes.buttonClass"> {{instanceButtons.yes.buttonText | translate}} </button> <button *ngIf="instanceButtons.no" [disabled]="waiting || instanceButtons.no.buttonDisabled" (click)="no()" type="button" [ngClass]="instanceButtons.no.buttonClass"> {{instanceButtons.no.buttonText | translate}} </button> <button *ngIf="instanceButtons.next" [disabled]="waiting || instanceButtons.next.buttonDisabled" (click)="next()" type="button" [ngClass]="instanceButtons.next.buttonClass"> {{instanceButtons.next.buttonText | translate}} </button> <button *ngIf="instanceButtons.cancel" [disabled]="waiting || instanceButtons.cancel.buttonDisabled" (click)="cancel()" type="button" [ngClass]="instanceButtons.cancel.buttonClass" data-dismiss="modal"> {{instanceButtons.cancel.buttonText | translate}} </button> <button *ngIf="instanceButtons.abort" [disabled]="waiting || instanceButtons.abort.buttonDisabled" (click)="abort()" type="button" [ngClass]="instanceButtons.abort.buttonClass"> {{instanceButtons.abort.buttonText | translate}} </button> <button *ngIf="instanceButtons.retry" [disabled]="waiting || instanceButtons.retry.buttonDisabled" (click)="retry()" type="button" [ngClass]="instanceButtons.retry.buttonClass"> {{instanceButtons.retry.buttonText | translate}} </button> <button *ngIf="instanceButtons.ignore" [disabled]="waiting || instanceButtons.ignore.buttonDisabled" (click)="ignore()" type="button" [ngClass]="instanceButtons.ignore.buttonClass" data-dismiss="modal"> {{instanceButtons.ignore.buttonText | translate}} </button> </div> </div> </div> </div> </div> `, encapsulation: ViewEncapsulation.None, styles: [".bd-modal .modal{position:fixed;right:auto;bottom:auto;z-index:1045;display:block}.bd-modal .modal .modal-body{margin-top:0;margin-bottom:0}.bd-modal .modal.modal-waiting{opacity:.6}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i0.Renderer2 }]; }, propDecorators: { modalTitle: [{ type: Input }], modalClass: [{ type: Input }], okButtonText: [{ type: Input }], okButtonClass: [{ type: Input }], cancelButtonText: [{ type: Input }], cancelButtonClass: [{ type: Input }], yesButtonText: [{ type: Input }], yesButtonClass: [{ type: Input }], noButtonText: [{ type: Input }], noButtonClass: [{ type: Input }], abortButtonText: [{ type: Input }], abortButtonClass: [{ type: Input }], retryButtonText: [{ type: Input }], retryButtonClass: [{ type: Input }], ignoreButtonText: [{ type: Input }], ignoreButtonClass: [{ type: Input }], previousButtonText: [{ type: Input }], previousButtonClass: [{ type: Input }], nextButtonText: [{ type: Input }], nextButtonClass: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUm91dGVyTW9kYWxDb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9yb3V0aW5nL3NyYy9Sb3V0ZXJNb2RhbENvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQWdCLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2RyxPQUFPLEVBQUMsY0FBYyxFQUFFLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRXZELE9BQU8sRUFBRSxXQUFXLEVBQWMsTUFBTSxlQUFlLENBQUM7Ozs7O0FBeUZ4RCxNQUFNLE9BQU8sb0JBQW9CO0lBaUUvQixZQUFvQixRQUFvQixFQUN0QixlQUErQixFQUMvQixPQUFlLEVBQ2YsU0FBb0I7UUFIbEIsYUFBUSxHQUFSLFFBQVEsQ0FBWTtRQUN0QixvQkFBZSxHQUFmLGVBQWUsQ0FBZ0I7UUFDL0IsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUNmLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFqRTlCLDBCQUFxQixHQUF3QixJQUFJLENBQUM7UUFDbEQsMkJBQXNCLEdBQXdCLElBQUksQ0FBQztRQUNwRCxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2QsZUFBVSxHQUFHLEVBQUUsQ0FBQztRQUd6Qix3R0FBd0c7UUFFL0YsaUJBQVksR0FBRyxXQUFXLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQztRQUN6QyxrQkFBYSxHQUFHLFdBQVcsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDO1FBRTNDLHFCQUFnQixHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ2pELHNCQUFpQixHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRW5ELGtCQUFhLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUU7UUFDNUMsbUJBQWMsR0FBRyxXQUFXLENBQUMsR0FBRyxD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YixlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUN6QztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQzs7a0hBMVdVLG9CQUFvQjtzR0FBcEIsb0JBQW9CLDh2QkE3RXJCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMERUOzRGQW1CVSxvQkFBb0I7a0JBaEZoQyxTQUFTOytCQUVFLGNBQWMsWUFDZDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBEVCxpQkFpQmMsaUJBQWlCLENBQUMsSUFBSTsyS0FRNUIsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUlHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFFRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUVHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFFRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBRUcsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFFRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBJbnB1dCwgRWxlbWVudFJlZiwgVmlld0VuY2Fwc3VsYXRpb24sIEV2ZW50RW1pdHRlciwgUmVuZGVyZXIyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QWN0aXZhdGVkUm91dGUsIFJvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEJ1dHRvblR5cGVzLCBCdXR0b25UeXBlIH0gZnJvbSAnLi9CdXR0b25UeXBlcyc7XG5pbXBvcnQgeyBNb2RhbENoYW5nZXMgfSBmcm9tICcuL1JvdXRlck1vZGFsJztcblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIFJvdXRlck1vZGFsT3V0bGV0Q29tcG9uZW50IHtcbiAgbW9kYWxUaXRsZTogc3RyaW5nO1xuICBtb2RhbENsYXNzOiBzdHJpbmc7XG4gIHN0YXR1c0NoYW5nZXM6IEV2ZW50RW1pdHRlcjxhbnk+O1xufVxuXG5AQ29tcG9uZW50KHtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ3JvdXRlci1tb2RhbCcsXG4gIHRlbXBsYXRlOiBgXG4gIDxkaXYgY2xhc3M9XCJiZC1tb2RhbCBkLW5vbmVcIj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYmFja2Ryb3AgZmFkZSBkLW5vbmVcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWxcIiB0YWJpbmRleD1cIi0xXCIgcm9sZT1cImRpYWxvZ1wiIFtuZ0NsYXNzXT1cInsgJ21vZGFsLXdhaXRpbmcnOiB3YWl0aW5nIH1cIj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZGlhbG9nXCIgW25nQ2xhc3NdPVwibW9kYWxJbnN0YW5jZUNsYXNzXCIgcm9sZT1cImRvY3VtZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCIgKm5nSWY9XCJtb2RhbEluc3RhbmNlVGl0bGVcIj5cbiAgICAgICAgICA8aDUgY2xhc3M9XCJtb2RhbC10aXRsZVwiPnt7bW9kYWxJbnN0YW5jZVRpdGxlIHwgdHJhbnNsYXRlfX08L2g1PlxuICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpbnN0YW5jZUJ1dHRvbnMuY2FuY2VsXCIgW2Rpc2FibGVkXT1cIndhaXRpbmcgfHwgaW5zdGFuY2VCdXR0b25zLmNhbmNlbC5idXR0b25EaXNhYmxlZFwiIChjbGljayk9XCJjYW5jZWwoKVwiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGRhdGEtZGlzbWlzcz1cIm1vZGFsXCIgYXJpYS1sYWJlbD1cIkNhbmNlbFwiPlxuICAgICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnRpbWVzOzwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgPHJvdXRlci1vdXRsZXQgKGFjdGl2YXRlKT1cIm9uQWN0aXZhdGUoJGV2ZW50KVwiIChkZWFjdGl2YXRlKT1cIm9uRGVhY3RpdmF0ZSgkZXZlbnQpXCIgbmFtZT1cIm1vZGFsXCI+PC9yb3V0ZXItb3V0bGV0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlciBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImluc3RhbmNlQnV0dG9ucy5wcmV2aW91c1wiIFtkaXNhYmxlZF09XCJ3YWl0aW5nIHx8IGluc3RhbmNlQnV0dG9ucy5wcmV2aW91cy5idXR0b25EaXNhYmxlZFwiIChjbGljayk9XCJwcmV2aW91cygpXCJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBbbmdDbGFzc109XCJpbnN0YW5jZUJ1dHRvbnMucHJldmlvdXMuYnV0dG9uQ2xhc3NcIj5cbiAgICAgICAgICAgIHt7aW5zdGFuY2VCdXR0b25zLnByZXZpb3VzLmJ1dHRvblRleHQgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpbnN0YW5jZUJ1dHRvbnMub2tcIiBbZGlzYWJsZWRdPVwid2FpdGluZyB8fCBpbnN0YW5jZUJ1dHRvbnMub2suYnV0dG9uRGlzYWJsZWRcIiAoY2xpY2spPVwib2soKVwiXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgW25nQ2xhc3NdPVwiaW5zdGFuY2VCdXR0b25zLm9rLmJ1dHRvbkNsYXNzXCI+XG4gICAgICAgICAgICB7e2luc3RhbmNlQnV0dG9ucy5vay5idXR0b25UZXh0IHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaW5zdGFuY2VCdXR0b25zLnllc1wiIFtkaXNhYmxlZF09XCJ3YWl0aW5nIHx8IGluc3RhbmNlQnV0dG9ucy55ZXMuYnV0dG9uRGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInllcygpXCIgdHlwZT1cImJ1dHRvblwiIFtuZ0NsYXNzXT1cImluc3RhbmNlQnV0dG9ucy55ZXMuYnV0dG9uQ2xhc3NcIj5cbiAgICAgICAgICAgIHt7aW5zdGFuY2VCdXR0b25zLnllcy5idXR0b25UZXh0IHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaW5zdGFuY2VCdXR0b25zLm5vXCIgW2Rpc2FibGVkXT1cIndhaXRpbmcgfHwgaW5zdGFuY2VCdXR0b25zLm5vLmJ1dHRvbkRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJubygpXCIgdHlwZT1cImJ1dHRvblwiIFtuZ0NsYXNzXT1cImluc3RhbmNlQnV0dG9ucy5uby5idXR0b25DbGFzc1wiPlxuICAgICAgICAgICAge3tpbnN0YW5jZUJ1dHRvbnMubm8uYnV0dG9uVGV4dCB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImluc3RhbmNlQnV0dG9ucy5uZXh0XCIgW2Rpc2FibGVkXT1cIndhaXRpbmcgfHwgaW5zdGFuY2VCdXR0b25zLm5leHQuYnV0dG9uRGlzYWJsZWRcIiAoY2xpY2spPVwibmV4dCgpXCJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBbbmdDbGFzc109XCJpbnN0YW5jZUJ1dHRvbnMubmV4dC5idXR0b25DbGFzc1wiPlxuICAgICAgICAgICAge3tpbnN0YW5jZUJ1dHRvbnMubmV4dC5idXR0b25UZXh0IHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaW5zdGFuY2VCdXR0b25zLmNhbmNlbFwiIFtkaXNhYmxlZF09XCJ3YWl0aW5nIHx8IGluc3RhbmNlQnV0dG9ucy5jYW5jZWwuYnV0dG9uRGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNhbmNlbCgpXCIgdHlwZT1cImJ1dHRvblwiIFtuZ0NsYXNzXT1cImluc3RhbmNlQnV0dG9ucy5jYW5jZWwuYnV0dG9uQ2xhc3NcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiPlxuICAgICAgICAgICAge3tpbnN0YW5jZUJ1dHRvbnMuY2FuY2VsLmJ1dHRvblRleHQgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpbnN0YW5jZUJ1dHRvbnMuYWJvcnRcIiBbZGlzYWJsZWRdPVwid2FpdGluZyB8fCBpbnN0YW5jZUJ1dHRvbnMuYWJvcnQuYnV0dG9uRGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFib3J0KClcIiB0eXBlPVwiYnV0dG9uXCIgW25nQ2xhc3NdPVwiaW5zdGFuY2VCdXR0b25zLmFib3J0LmJ1dHRvbkNsYXNzXCI+XG4gICAgICAgICAgICB7e2luc3RhbmNlQnV0dG9ucy5hYm9ydC5idXR0b25UZXh0IHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiaW5zdGFuY2VCdXR0b25zLnJldHJ5XCIgW2Rpc2FibGVkXT1cIndhaXRpbmcgfHwgaW5zdGFuY2VCdXR0b25zLnJldHJ5LmJ1dHRvbkRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXRyeSgpXCIgdHlwZT1cImJ1dHRvblwiIFtuZ0NsYXNzXT1cImluc3RhbmNlQnV0dG9ucy5yZXRyeS5idXR0b25DbGFzc1wiPlxuICAgICAgICAgICAge3tpbnN0YW5jZUJ1dHRvbnMucmV0cnkuYnV0dG9uVGV4dCB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImluc3RhbmNlQnV0dG9ucy5pZ25vcmVcIiBbZGlzYWJsZWRdPVwid2FpdGluZyB8fCBpbnN0YW5jZUJ1dHRvbnMuaWdub3JlLmJ1dHRvbkRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJpZ25vcmUoKVwiIHR5cGU9XCJidXR0b25cIiBbbmdDbGFzc109XCJpbnN0YW5jZUJ1dHRvbnMuaWdub3JlLmJ1dHRvbkNsYXNzXCIgZGF0YS1kaXNtaXNzPVwibW9kYWxcIj5cbiAgICAgICAgICAgIHt7aW5zdGFuY2VCdXR0b25zLmlnbm9yZS5idXR0b25UZXh0IHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLmJkLW1vZGFsIC5tb2RhbCB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgICAgIGJvdHRvbTogYXV0bztcbiAgICAgICAgei1pbmRleDogMTA0NTtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIH1cbiAgICAgICAgLmJkLW1vZGFsIC5tb2RhbCAubW9kYWwtYm9keSB7XG4gICAgICAgICAgICAgICAgbWFyZ2luLXRvcDogMDtcbiAgICAgICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgLmJkLW1vZGFsIC5tb2RhbC5tb2RhbC13YWl0aW5nIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDAuNjtcbiAgICAgICAgICB9XG4gIGBdLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIFJvdXRlck1vZGFsQ29tcG9uZW50IHtcblxuICBwcml2YXRlIGNvbXBvbmVudFJlZmVyZW5jZTogYW55O1xuICBwcml2YXRlIGNvbXBvbmVudE1vZGFsQ2hhbmdlczogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY29tcG9uZW50QnV0dG9uQ2hhbmdlczogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyB3YWl0aW5nID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1vZGFsVGl0bGUgPSAnJztcbiAgQElucHV0KCkgbW9kYWxDbGFzczogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8vIHRoZXNlIHByb3BlcnRpZXMgYXJlIGhlcmUgYXMgaW5wdXRzIGluIG9yZGVyIHRvIGhhdmUgYSB3YXkgdG8gY3VzdG9taXplIHRleHQgYW5kIGNsYXNzIG9mIGVhY2ggYnV0dG9uXG5cbiAgQElucHV0KCkgb2tCdXR0b25UZXh0ID0gQnV0dG9uVHlwZXMub2suYnV0dG9uVGV4dDtcbiAgQElucHV0KCkgb2tCdXR0b25DbGFzcyA9IEJ1dHRvblR5cGVzLm9rLmJ1dHRvbkNsYXNzO1xuXG4gIEBJbnB1dCgpIGNhbmNlbEJ1dHRvblRleHQgPSBCdXR0b25UeXBlcy5jYW5jZWwuYnV0dG9uVGV4dDtcbiAgQElucHV0KCkgY2FuY2VsQnV0dG9uQ2xhc3MgPSBCdXR0b25UeXBlcy5jYW5jZWwuYnV0dG9uQ2xhc3M7XG5cbiAgQElucHV0KCkgeWVzQnV0dG9uVGV4dCA9IEJ1dHRvblR5cGVzLnllcy5idXR0b25UZXh0IDtcbiAgQElucHV0KCkgeWVzQnV0dG9uQ2xhc3MgPSBCdXR0b25UeXBlcy55ZXMuYnV0dG9uQ2xhc3M7XG5cbiAgQElucHV0KCkgbm9CdXR0b25UZXh0ID0gQnV0dG9uVHlwZXMubm8uYnV0dG9uVGV4dCA7XG4gIEBJbnB1dCgpIG5vQnV0dG9uQ2xhc3MgPSBCdXR0b25UeXBlcy5uby5idXR0b25DbGFzcztcblxuICBASW5wdXQoKSBhYm9ydEJ1dHRvblRleHQgPSBCdXR0b25UeXBlcy5hYm9ydC5idXR0b25UZXh0O1xuICBASW5wdXQoKSBhYm9ydEJ1dHRvbkNsYXNzID0gQnV0dG9uVHlwZXMuYWJvcnQuYnV0dG9uQ2xhc3M7XG5cbiAgQElucHV0KCkgcmV0cnlCdXR0b25UZXh0ID0gQnV0dG9uVHlwZXMucmV0cnkuYnV0dG9uVGV4dDtcbiAgQElucHV0KCkgcmV0cnlCdXR0b25DbGFzcyA9IEJ1dHRvblR5cGVzLnJldHJ5LmJ1dHRvbkNsYXNzO1xuXG4gIEBJbnB1dCgpIGlnbm9yZUJ1dHRvblRleHQgPSBCdXR0b25UeXBlcy5pZ25vcmUuYnV0dG9uVGV4dDtcbiAgQElucHV0KCkgaWdub3JlQnV0dG9uQ2xhc3MgPSBCdXR0b25UeXBlcy5pZ25vcmUuYnV0dG9uQ2xhc3M7XG5cbiAgQElucHV0KCkgcHJldmlvdXNCdXR0b25UZXh0ID0gQnV0dG9uVHlwZXMucHJldmlvdXMuYnV0dG9uVGV4dDtcbiAgQElucHV0KCkgcHJldmlvdXNCdXR0b25DbGFzcyA9IEJ1dHRvblR5cGVzLnByZXZpb3VzLmJ1dHRvbkNsYXNzO1xuXG4gIEBJbnB1dCgpIG5leHRCdXR0b25UZXh0ID0gQnV0dG9uVHlwZXMubmV4dC5idXR0b25UZXh0O1xuICBASW5wdXQoKSBuZXh0QnV0dG9uQ2xhc3MgPSBCdXR0b25UeXBlcy5uZXh0LmJ1dHRvbkNsYXNzO1xuXG4gIHB1YmxpYyBtb2RhbEluc3RhbmNlVGl0bGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHVibGljIG1vZGFsSW5zdGFuY2VDbGFzczogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8vIGRlZmF1bHQgaW5zdGFuY2UgYnV0dG9uc1xuXG4gIHB1YmxpYyBpbnN0YW5jZUJ1dHRvbnM6IHtcbiAgICBvazogQnV0dG9uVHlwZSB8IG51bGwsXG4gICAgY2FuY2VsOiBCdXR0b25UeXBlIHwgbnVsbCxcbiAgICB5ZXM6IEJ1dHRvblR5cGUgfCBudWxsLFxuICAgIG5vOiBCdXR0b25UeXBlIHwgbnVsbCxcbiAgICBhYm9ydDogQnV0dG9uVHlwZSB8IG51bGwsXG4gICAgcmV0cnk6IEJ1dHRvblR5cGUgfCBudWxsLFxuICAgIGlnbm9yZTogQnV0dG9uVHlwZSB8IG51bGwsXG4gICAgcHJldmlvdXM6IEJ1dHRvblR5cGUgfCBudWxsLFxuICAgIG5leHQ6IEJ1dHRvblR5cGUgfCBudWxsXG4gIH0gPSB7XG4gICAgb2s6IG51bGwsXG4gICAgY2FuY2VsOiBudWxsLFxuICAgIHllczogbnVsbCxcbiAgICBubzogbnVsbCxcbiAgICBhYm9ydDogbnVsbCxcbiAgICByZXRyeTogbnVsbCxcbiAgICBpZ25vcmU6IG51bGwsXG4gICAgcHJldmlvdXM6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICBwcml2YXRlIF9hY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgICAgICBwcml2YXRlIF9yb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgICAgIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIpIHtcblxuICB9XG5cbiAgYXN5bmMgY2FuY2VsKCkge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5jb21wb25lbnRSZWZlcmVuY2UpIHtcblxuICAgICAgICAvLyBzZXQgd2FpdGluZ1xuICAgICAgICB0aGlzLndhaXRpbmcgPSB0cnVlO1xuICAgICAgICAvLyBpZiBjb21wb25lbnQgaGFzIGNhbmNlbCgpIG1ldGhvZFxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuY29tcG9uZW50UmVmZXJlbmNlLmNhbmNlbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIC8vIGRvIGNhbmNlbFxuICAgICAgICAgIGF3YWl0IHRoaXMuY29tcG9uZW50UmVmZXJlbmNlLmNhbmNlbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShbJy4uLyddLCB7IHJlbGF0aXZlVG86IHRoaXMuX2FjdGl2YXRlZFJvdXRlIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVuc2V0IHdhaXRpbmdcbiAgICAgICAgdGhpcy53YWl0aW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLndhaXRpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBvaygpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVmZXJlbmNlKSB7XG4gICAgICAgIC8vIHNldCB3YWl0aW5nXG4gICAgICAgIHRoaXMud2FpdGluZyA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5jb21wb25lbnRSZWZlcmVuY2Uub2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBkbyBzdWJtaXRcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbXBvbmVudFJlZmVyZW5jZS5vaygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShbJy4uLyddLCB7IHJlbGF0aXZlVG86IHRoaXMuX2FjdGl2YXRlZFJvdXRlIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVuc2V0IHdhaXRpbmdcbiAgICAgICAgdGhpcy53YWl0aW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLndhaXRpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBhYm9ydCgpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVmZXJlbmNlKSB7XG4gICAgICAgIC8vIHNldCB3YWl0aW5nXG4gICAgICAgIHRoaXMud2FpdGluZyA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5jb21wb25lbnRSZWZlcmVuY2UuYWJvcnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBkbyBzdWJtaXRcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbXBvbmVudFJlZmVyZW5jZS5hYm9ydCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0