UNPKG

ng-alertbar

Version:

A configurable alertbar for Angular

349 lines 26.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { Subject, timer } from 'rxjs'; import { filter, mapTo, switchMap, take, takeUntil } from 'rxjs/operators'; import { slide } from './animations'; import { defaults } from './defaults'; import { NgAlertbarService } from './ng-alertbar.service'; /** @type {?} */ const ALERT_LEAVE_ANIMATION_DURATION = 200; export class NgAlertbarComponent { /** * @param {?} alertBarService * @param {?} domSanitizer */ constructor(alertBarService, domSanitizer) { this.alertBarService = alertBarService; this.domSanitizer = domSanitizer; this.queue = []; this.queuePop = new Subject(); this.queueing = defaults.queueingEnabled; this.lifeTime = defaults.lifeTimeMs; this.showDelay = defaults.showDelayMs; this.backgroundColor = defaults.backgroundColor; this.borderColor = defaults.borderColor; this.textColor = defaults.textColor; this.widthMode = defaults.widthMode; this.closeButton = defaults.closeButtonEnabled; this.html = defaults.useHtml; this.open = new EventEmitter(); this.close = new EventEmitter(); this.show = false; this.destroy = new Subject(); } /** * @return {?} */ get isFullWidth() { if (this.tempWidthMode) { return this.tempWidthMode === 'full'; } return this.widthMode === 'full'; } /** * @return {?} */ get showCloseButton() { if (this.tempCloseButton != null) { return this.tempCloseButton; } return this.closeButton; } /** * @return {?} */ get useHtml() { if (this.tempHtml != null) { return this.tempHtml; } return this.html; } /** * @return {?} */ get htmlMessage() { return this.domSanitizer.bypassSecurityTrustHtml(this.message); } /** * The trigger stream after waiting the specified showDelay since the alert was triggered * @return {?} */ get openTriggerPostDelay$() { return this.alertBarService.trigger$.pipe(switchMap((/** * @param {?} trigger * @return {?} */ trigger => { /** @type {?} */ const options = trigger.options; /** @type {?} */ const showDelay = (options && options.showDelay) || this.showDelay; return timer(showDelay).pipe(mapTo(trigger)); })), takeUntil(this.destroy)); } /** * The trigger stream after waiting the specified lifetime since the alert opened * @return {?} */ get postAlertLifetime$() { return this.open.pipe(filter((/** * @param {?} __0 * @return {?} */ ({ options }) => this.shouldAlertAutoClose(options))), switchMap((/** * @param {?} __0 * @return {?} */ ({ options }) => { /** @type {?} */ const lifeTime = (options && options.lifeTime) || this.lifeTime; return timer(lifeTime); })), takeUntil(this.destroy)); } /** * The service cancel trigger * @return {?} */ get cancelTrigger$() { return this.alertBarService.cancel$.pipe(takeUntil(this.destroy)); } /** * Timer representing the delay taken for an alert to animate when exiting * @return {?} */ get alertLeaveTimer() { return timer(ALERT_LEAVE_ANIMATION_DURATION).pipe(take(1)); } /** * @return {?} */ ngOnInit() { this.openTriggerPostDelay$.subscribe((/** * @param {?} trigger * @return {?} */ trigger => this.onTrigger(trigger))); this.queuePop.subscribe((/** * @param {?} trigger * @return {?} */ trigger => this.showAlert(trigger))); this.postAlertLifetime$.subscribe((/** * @return {?} */ () => this.onClose())); this.cancelTrigger$.subscribe((/** * @return {?} */ () => this.onClose())); } /** * @return {?} */ ngOnDestroy() { this.destroy.next(); } /** * @private * @param {?} trigger * @return {?} */ onTrigger(trigger) { if (this.queueing && !(trigger.options && trigger.options.bypassQueue) && this.show) { this.queue.push(trigger); return; } this.showAlert(trigger); } /** * Sets up temp variables and shows the alert * @private * @param {?} trigger The trigger to display * @return {?} */ showAlert(trigger) { this.clearTempOptions(); // Clear previous temporary options this.assignTempOptions(trigger.options); this.message = trigger.message; this.show = true; this.open.emit(trigger); } /** * Closes any open alert. If there are any alerts waiting in the queue, * the alert is popped off the queue and emitted for opening * @return {?} */ onClose() { this.closeAlert(); if (this.queue.length > 0) { this.alertLeaveTimer.subscribe((/** * @return {?} */ () => { this.queuePop.next(this.queue.shift()); })); } } /** * @private * @return {?} */ closeAlert() { this.show = false; this.close.emit(); } /** * Clears out any temporary config options so that they * do not persist beyond their single use * @private * @return {?} */ clearTempOptions() { this.tempBackgroundColor = null; this.tempBorderColor = null; this.tempTextColor = null; this.tempWidthMode = null; this.tempCloseButton = null; this.tempHtml = null; } /** * Assigns the options included in the trigger to the temporary * config variables so they can apply for the upcoming alert * @private * @param {?} options The options passed in the trigger * @return {?} */ assignTempOptions(options) { if (!options) { return; } this.tempBackgroundColor = options.backgroundColor; this.tempBorderColor = options.borderColor; this.tempTextColor = options.textColor; this.tempWidthMode = options.widthMode; this.tempCloseButton = options.closeButton; this.tempHtml = options.html; } /** * @private * @param {?} options * @return {?} */ shouldAlertAutoClose(options) { if (options && options.lifeTime != null) { return options.lifeTime > 0; } return this.lifeTime > 0; // Fallback to component setting } } NgAlertbarComponent.decorators = [ { type: Component, args: [{ selector: 'ng-alertbar', template: ` <div *ngIf="show" [@slide] class="ng-alert-bar-wrapper"> <div class="ng-alert-bar" [class.full-width]="isFullWidth" [style.background]="tempBackgroundColor || backgroundColor" [style.border-color]="tempBorderColor || borderColor" > <span class="ng-alert-bar-text" [style.color]="tempTextColor || textColor"> <span *ngIf="!useHtml; else htmlMessageContainer">{{ message }}</span> <ng-template #htmlMessageContainer><span [innerHTML]="htmlMessage"></span></ng-template> <span *ngIf="showCloseButton" class="ng-alert-close" (click)="onClose()">&times;</span> </span> </div> </div> `, animations: [slide], styles: [".ng-alert-bar-wrapper{position:absolute;top:0;left:0;width:100%;text-align:center;pointer-events:none}.ng-alert-bar{pointer-events:all}.ng-alert-bar:not(.full-width){display:inline-block}.ng-alert-close{font-size:1.1em;margin-left:.25rem;vertical-align:middle;cursor:pointer}"] }] } ]; /** @nocollapse */ NgAlertbarComponent.ctorParameters = () => [ { type: NgAlertbarService }, { type: DomSanitizer } ]; NgAlertbarComponent.propDecorators = { queueing: [{ type: Input }], lifeTime: [{ type: Input }], showDelay: [{ type: Input }], backgroundColor: [{ type: Input }], borderColor: [{ type: Input }], textColor: [{ type: Input }], widthMode: [{ type: Input }], closeButton: [{ type: Input }], html: [{ type: Input }], open: [{ type: Output }], close: [{ type: Output }] }; if (false) { /** * @type {?} * @private */ NgAlertbarComponent.prototype.queue; /** * @type {?} * @private */ NgAlertbarComponent.prototype.queuePop; /** @type {?} */ NgAlertbarComponent.prototype.queueing; /** @type {?} */ NgAlertbarComponent.prototype.lifeTime; /** @type {?} */ NgAlertbarComponent.prototype.showDelay; /** @type {?} */ NgAlertbarComponent.prototype.backgroundColor; /** @type {?} */ NgAlertbarComponent.prototype.tempBackgroundColor; /** @type {?} */ NgAlertbarComponent.prototype.borderColor; /** @type {?} */ NgAlertbarComponent.prototype.tempBorderColor; /** @type {?} */ NgAlertbarComponent.prototype.textColor; /** @type {?} */ NgAlertbarComponent.prototype.tempTextColor; /** @type {?} */ NgAlertbarComponent.prototype.widthMode; /** @type {?} */ NgAlertbarComponent.prototype.tempWidthMode; /** @type {?} */ NgAlertbarComponent.prototype.closeButton; /** @type {?} */ NgAlertbarComponent.prototype.tempCloseButton; /** @type {?} */ NgAlertbarComponent.prototype.html; /** @type {?} */ NgAlertbarComponent.prototype.tempHtml; /** @type {?} */ NgAlertbarComponent.prototype.open; /** @type {?} */ NgAlertbarComponent.prototype.close; /** @type {?} */ NgAlertbarComponent.prototype.show; /** @type {?} */ NgAlertbarComponent.prototype.message; /** * @type {?} * @private */ NgAlertbarComponent.prototype.destroy; /** * @type {?} * @private */ NgAlertbarComponent.prototype.alertBarService; /** * @type {?} * @private */ NgAlertbarComponent.prototype.domSanitizer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctYWxlcnRiYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctYWxlcnRiYXIvIiwic291cmNlcyI6WyJsaWIvbmctYWxlcnRiYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFdEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7O01BRXBELDhCQUE4QixHQUFHLEdBQUc7QUF1QjFDLE1BQU0sT0FBTyxtQkFBbUI7Ozs7O0lBZ0c5QixZQUFvQixlQUFrQyxFQUFVLFlBQTBCO1FBQXRFLG9CQUFlLEdBQWYsZUFBZSxDQUFtQjtRQUFVLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBL0ZsRixVQUFLLEdBQW1CLEVBQUUsQ0FBQztRQUMzQixhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQWdCLENBQUM7UUFFdEMsYUFBUSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFDcEMsYUFBUSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFDL0IsY0FBUyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7UUFFakMsb0JBQWUsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO1FBRTNDLGdCQUFXLEdBQUcsUUFBUSxDQUFDLFdB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Ozs7SUFxRTFCLDhDQUEwQzs7Ozs7SUFBRSwyQ0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgU3ViamVjdCwgdGltZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwVG8sIHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgc2xpZGUgfSBmcm9tICcuL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgZGVmYXVsdHMgfSBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IEFsZXJ0T3B0aW9ucywgQWxlcnRUcmlnZ2VyIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTmdBbGVydGJhclNlcnZpY2UgfSBmcm9tICcuL25nLWFsZXJ0YmFyLnNlcnZpY2UnO1xuXG5jb25zdCBBTEVSVF9MRUFWRV9BTklNQVRJT05fRFVSQVRJT04gPSAyMDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25nLWFsZXJ0YmFyJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICpuZ0lmPVwic2hvd1wiIFtAc2xpZGVdIGNsYXNzPVwibmctYWxlcnQtYmFyLXdyYXBwZXJcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJuZy1hbGVydC1iYXJcIlxuICAgICAgICBbY2xhc3MuZnVsbC13aWR0aF09XCJpc0Z1bGxXaWR0aFwiXG4gICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cInRlbXBCYWNrZ3JvdW5kQ29sb3IgfHwgYmFja2dyb3VuZENvbG9yXCJcbiAgICAgICAgW3N0eWxlLmJvcmRlci1jb2xvcl09XCJ0ZW1wQm9yZGVyQ29sb3IgfHwgYm9yZGVyQ29sb3JcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm5nLWFsZXJ0LWJhci10ZXh0XCIgW3N0eWxlLmNvbG9yXT1cInRlbXBUZXh0Q29sb3IgfHwgdGV4dENvbG9yXCI+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCIhdXNlSHRtbDsgZWxzZSBodG1sTWVzc2FnZUNvbnRhaW5lclwiPnt7IG1lc3NhZ2UgfX08L3NwYW4+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNodG1sTWVzc2FnZUNvbnRhaW5lcj48c3BhbiBbaW5uZXJIVE1MXT1cImh0bWxNZXNzYWdlXCI+PC9zcGFuPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJzaG93Q2xvc2VCdXR0b25cIiBjbGFzcz1cIm5nLWFsZXJ0LWNsb3NlXCIgKGNsaWNrKT1cIm9uQ2xvc2UoKVwiPiZ0aW1lczs8L3NwYW4+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZVVybHM6IFsnLi9uZy1hbGVydGJhci5jb21wb25lbnQuY3NzJ10sXG4gIGFuaW1hdGlvbnM6IFtzbGlkZV1cbn0pXG5leHBvcnQgY2xhc3MgTmdBbGVydGJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBxdWV1ZTogQWxlcnRUcmlnZ2VyW10gPSBbXTtcbiAgcHJpdmF0ZSBxdWV1ZVBvcCA9IG5ldyBTdWJqZWN0PEFsZXJ0VHJpZ2dlcj4oKTtcblxuICBASW5wdXQoKSBxdWV1ZWluZyA9IGRlZmF1bHRzLnF1ZXVlaW5nRW5hYmxlZDtcbiAgQElucHV0KCkgbGlmZVRpbWUgPSBkZWZhdWx0cy5saWZlVGltZU1zO1xuICBASW5wdXQoKSBzaG93RGVsYXkgPSBkZWZhdWx0cy5zaG93RGVsYXlNcztcblxuICBASW5wdXQoKSBiYWNrZ3JvdW5kQ29sb3IgPSBkZWZhdWx0cy5iYWNrZ3JvdW5kQ29sb3I7XG4gIHRlbXBCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgQElucHV0KCkgYm9yZGVyQ29sb3IgPSBkZWZhdWx0cy5ib3JkZXJDb2xvcjtcbiAgdGVtcEJvcmRlckNvbG9yOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHRleHRDb2xvciA9IGRlZmF1bHRzLnRleHRDb2xvcjtcbiAgdGVtcFRleHRDb2xvcjogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHdpZHRoTW9kZSA9IGRlZmF1bHRzLndpZHRoTW9kZTtcbiAgdGVtcFdpZHRoTW9kZTogJ2Z1bGwnIHwgJ3BhcnRpYWwnO1xuICBASW5wdXQoKSBjbG9zZUJ1dHRvbiA9IGRlZmF1bHRzLmNsb3NlQnV0dG9uRW5hYmxlZDtcbiAgdGVtcENsb3NlQnV0dG9uOiBib29sZWFuO1xuICBASW5wdXQoKSBodG1sID0gZGVmYXVsdHMudXNlSHRtbDtcbiAgdGVtcEh0bWw6IGJvb2xlYW47XG5cbiAgQE91dHB1dCgpIG9wZW4gPSBuZXcgRXZlbnRFbWl0dGVyPEFsZXJ0VHJpZ2dlcj4oKTtcbiAgQE91dHB1dCgpIGNsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHNob3cgPSBmYWxzZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBwcml2YXRlIGRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGdldCBpc0Z1bGxXaWR0aCgpIHtcbiAgICBpZiAodGhpcy50ZW1wV2lkdGhNb2RlKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZW1wV2lkdGhNb2RlID09PSAnZnVsbCc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLndpZHRoTW9kZSA9PT0gJ2Z1bGwnO1xuICB9XG5cbiAgZ2V0IHNob3dDbG9zZUJ1dHRvbigpIHtcbiAgICBpZiAodGhpcy50ZW1wQ2xvc2VCdXR0b24gIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMudGVtcENsb3NlQnV0dG9uO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbG9zZUJ1dHRvbjtcbiAgfVxuXG4gIGdldCB1c2VIdG1sKCkge1xuICAgIGlmICh0aGlzLnRlbXBIdG1sICE9IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLnRlbXBIdG1sO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odG1sO1xuICB9XG5cbiAgZ2V0IGh0bWxNZXNzYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmRvbVNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbCh0aGlzLm1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0cmlnZ2VyIHN0cmVhbSBhZnRlciB3YWl0aW5nIHRoZSBzcGVjaWZpZWQgc2hvd0RlbGF5IHNpbmNlIHRoZSBhbGVydCB3YXMgdHJpZ2dlcmVkXG4gICAqL1xuICBnZXQgb3BlblRyaWdnZXJQb3N0RGVsYXkkKCkge1xuICAgIHJldHVybiB0aGlzLmFsZXJ0QmFyU2VydmljZS50cmlnZ2VyJC5waXBlKFxuICAgICAgc3dpdGNoTWFwKHRyaWdnZXIgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdHJpZ2dlci5vcHRpb25zO1xuICAgICAgICBjb25zdCBzaG93RGVsYXkgPSAob3B0aW9ucyAmJiBvcHRpb25zLnNob3dEZWxheSkgfHwgdGhpcy5zaG93RGVsYXk7XG4gICAgICAgIHJldHVybiB0aW1lcihzaG93RGVsYXkpLnBpcGUobWFwVG8odHJpZ2dlcikpO1xuICAgICAgfSksXG4gICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRyaWdnZXIgc3RyZWFtIGFmdGVyIHdhaXRpbmcgdGhlIHNwZWNpZmllZCBsaWZldGltZSBzaW5jZSB0aGUgYWxlcnQgb3BlbmVkXG4gICAqL1xuICBnZXQgcG9zdEFsZXJ0TGlmZXRpbWUkKCkge1xuICAgIHJldHVybiB0aGlzLm9wZW4ucGlwZShcbiAgICAgIGZpbHRlcigoeyBvcHRpb25zIH0pID0+IHRoaXMuc2hvdWxkQWxlcnRBdXRvQ2xvc2Uob3B0aW9ucykpLFxuICAgICAgc3dpdGNoTWFwKCh7IG9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBsaWZlVGltZSA9IChvcHRpb25zICYmIG9wdGlvbnMubGlmZVRpbWUpIHx8IHRoaXMubGlmZVRpbWU7XG4gICAgICAgIHJldHVybiB0aW1lcihsaWZlVGltZSk7XG4gICAgICB9KSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBjYW5jZWwgdHJpZ2dlclxuICAgKi9cbiAgZ2V0IGNhbmNlbFRyaWdnZXIkKCkge1xuICAgIHJldHVybiB0aGlzLmFsZXJ0QmFyU2VydmljZS5jYW5jZWwkLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRpbWVyIHJlcHJlc2VudGluZyB0aGUgZGVsYXkgdGFrZW4gZm9yIGFuIGFsZXJ0IHRvIGFuaW1hdGUgd2hlbiBleGl0aW5nXG4gICAqL1xuICBnZXQgYWxlcnRMZWF2ZVRpbWVyKCkge1xuICAgIHJldHVybiB0aW1lcihBTEVSVF9MRUFWRV9BTklNQVRJT05fRFVSQVRJT04pLnBpcGUodGFrZSgxKSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFsZXJ0QmFyU2VydmljZTogTmdBbGVydGJhclNlcnZpY2UsIHByaXZhdGUgZG9tU2FuaXRpemVyOiBEb21TYW5pdGl6ZXIpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5vcGVuVHJpZ2dlclBvc3REZWxheSQuc3Vic2NyaWJlKHRyaWdnZXIgPT4gdGhpcy5vblRyaWdnZXIodHJpZ2dlcikpO1xuICAgIHRoaXMucXVldWVQb3Auc3Vic2NyaWJlKHRyaWdnZXIgPT4gdGhpcy5zaG93QWxlcnQodHJpZ2dlcikpO1xuICAgIHRoaXMucG9zdEFsZXJ0TGlmZXRpbWUkLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uQ2xvc2UoKSk7XG4gICAgdGhpcy5jYW5jZWxUcmlnZ2VyJC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbkNsb3NlKCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95Lm5leHQoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25UcmlnZ2VyKHRyaWdnZXI6IEFsZXJ0VHJpZ2dlcikge1xuICAgIGlmICh0aGlzLnF1ZXVlaW5nICYmICEodHJpZ2dlci5vcHRpb25zICYmIHRyaWdnZXIub3B0aW9ucy5ieXBhc3NRdWV1ZSkgJiYgdGhpcy5zaG93KSB7XG4gICAgICB0aGlzLnF1ZXVlLnB1c2godHJpZ2dlcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc2hvd0FsZXJ0KHRyaWdnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdXAgdGVtcCB2YXJpYWJsZXMgYW5kIHNob3dzIHRoZSBhbGVydFxuICAgKiBAcGFyYW0gdHJpZ2dlciBUaGUgdHJpZ2dlciB0byBkaXNwbGF5XG4gICAqL1xuICBwcml2YXRlIHNob3dBbGVydCh0cmlnZ2VyOiBBbGVydFRyaWdnZXIpIHtcbiAgICB0aGlzLmNsZWFyVGVtcE9wdGlvbnMoKTsgLy8gQ2xlYXIgcHJldmlvdXMgdGVtcG9yYXJ5IG9wdGlvbnNcbiAgICB0aGlzLmFzc2lnblRlbXBPcHRpb25zKHRyaWdnZXIub3B0aW9ucyk7XG4gICAgdGhpcy5tZXNzYWdlID0gdHJpZ2dlci5tZXNzYWdlO1xuICAgIHRoaXMuc2hvdyA9IHRydWU7XG4gICAgdGhpcy5vcGVuLmVtaXQodHJpZ2dlcik7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFueSBvcGVuIGFsZXJ0LiBJZiB0aGVyZSBhcmUgYW55IGFsZXJ0cyB3YWl0aW5nIGluIHRoZSBxdWV1ZSxcbiAgICogdGhlIGFsZXJ0IGlzIHBvcHBlZCBvZmYgdGhlIHF1ZXVlIGFuZCBlbWl0dGVkIGZvciBvcGVuaW5nXG4gICAqL1xuICBvbkNsb3NlKCkge1xuICAgIHRoaXMuY2xvc2VBbGVydCgpO1xuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYWxlcnRMZWF2ZVRpbWVyLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucXVldWVQb3AubmV4dCh0aGlzLnF1ZXVlLnNoaWZ0KCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZUFsZXJ0KCkge1xuICAgIHRoaXMuc2hvdyA9IGZhbHNlO1xuICAgIHRoaXMuY2xvc2UuZW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBvdXQgYW55IHRlbXBvcmFyeSBjb25maWcgb3B0aW9ucyBzbyB0aGF0IHRoZXlcbiAgICogZG8gbm90IHBlcnNpc3QgYmV5b25kIHRoZWlyIHNpbmdsZSB1c2VcbiAgICovXG4gIHByaXZhdGUgY2xlYXJUZW1wT3B0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnRlbXBCYWNrZ3JvdW5kQ29sb3IgPSBudWxsO1xuICAgIHRoaXMudGVtcEJvcmRlckNvbG9yID0gbnVsbDtcbiAgICB0aGlzLnRlbXBUZXh0Q29sb3IgPSBudWxsO1xuICAgIHRoaXMudGVtcFdpZHRoTW9kZSA9IG51bGw7XG4gICAgdGhpcy50ZW1wQ2xvc2VCdXR0b24gPSBudWxsO1xuICAgIHRoaXMudGVtcEh0bWwgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2lnbnMgdGhlIG9wdGlvbnMgaW5jbHVkZWQgaW4gdGhlIHRyaWdnZXIgdG8gdGhlIHRlbXBvcmFyeVxuICAgKiBjb25maWcgdmFyaWFibGVzIHNvIHRoZXkgY2FuIGFwcGx5IGZvciB0aGUgdXBjb21pbmcgYWxlcnRcbiAgICogQHBhcmFtIG9wdGlvbnMgVGhlIG9wdGlvbnMgcGFzc2VkIGluIHRoZSB0cmlnZ2VyXG4gICAqL1xuICBwcml2YXRlIGFzc2lnblRlbXBPcHRpb25zKG9wdGlvbnM6IEFsZXJ0T3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnRlbXBCYWNrZ3JvdW5kQ29sb3IgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICB0aGlzLnRlbXBCb3JkZXJDb2xvciA9IG9wdGlvbnMuYm9yZGVyQ29sb3I7XG4gICAgdGhpcy50ZW1wVGV4dENvbG9yID0gb3B0aW9ucy50ZXh0Q29sb3I7XG4gICAgdGhpcy50ZW1wV2lkdGhNb2RlID0gb3B0aW9ucy53aWR0aE1vZGU7XG4gICAgdGhpcy50ZW1wQ2xvc2VCdXR0b24gPSBvcHRpb25zLmNsb3NlQnV0dG9uO1xuICAgIHRoaXMudGVtcEh0bWwgPSBvcHRpb25zLmh0bWw7XG4gIH1cblxuICBwcml2YXRlIHNob3VsZEFsZXJ0QXV0b0Nsb3NlKG9wdGlvbnM6IEFsZXJ0T3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMubGlmZVRpbWUgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMubGlmZVRpbWUgPiAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5saWZlVGltZSA+IDA7IC8vIEZhbGxiYWNrIHRvIGNvbXBvbmVudCBzZXR0aW5nXG4gIH1cbn1cbiJdfQ==