@ng-bootstrap/ng-bootstrap
Version:
Angular powered Bootstrap
216 lines • 21.1 kB
JavaScript
import { Attribute, Component, ContentChild, Directive, ElementRef, EventEmitter, inject, Input, NgZone, Output, TemplateRef, ViewEncapsulation, } from '@angular/core';
import { take } from 'rxjs/operators';
import { NgbToastConfig } from './toast-config';
import { ngbRunTransition } from '../util/transition/ngbTransition';
import { ngbToastFadeInTransition, ngbToastFadeOutTransition } from './toast-transition';
import { NgTemplateOutlet } from '@angular/common';
import * as i0 from "@angular/core";
/**
* This directive allows the usage of HTML markup or other directives
* inside of the toast's header.
*
* @since 5.0.0
*/
export class NgbToastHeader {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbToastHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbToastHeader, isStandalone: true, selector: "[ngbToastHeader]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbToastHeader, decorators: [{
type: Directive,
args: [{ selector: '[ngbToastHeader]', standalone: true }]
}] });
/**
* Toasts provide feedback messages as notifications to the user.
* Goal is to mimic the push notifications available both on mobile and desktop operating systems.
*
* @since 5.0.0
*/
export class NgbToast {
constructor(ariaLive) {
this.ariaLive = ariaLive;
this._config = inject(NgbToastConfig);
this._zone = inject(NgZone);
this._element = inject(ElementRef);
/**
* If `true`, toast opening and closing will be animated.
*
* Animation is triggered only when the `.hide()` or `.show()` functions are called
*
* @since 8.0.0
*/
this.animation = this._config.animation;
/**
* Delay after which the toast will hide (ms).
* default: `500` (ms) (inherited from NgbToastConfig)
*/
this.delay = this._config.delay;
/**
* Auto hide the toast after a delay in ms.
* default: `true` (inherited from NgbToastConfig)
*/
this.autohide = this._config.autohide;
/**
* A template like `<ng-template ngbToastHeader></ng-template>` can be
* used in the projected content to allow markup usage.
*/
this.contentHeaderTpl = null;
/**
* An event fired after the animation triggered by calling `.show()` method has finished.
*
* @since 8.0.0
*/
this.shown = new EventEmitter();
/**
* An event fired after the animation triggered by calling `.hide()` method has finished.
*
* It can only occur in 2 different scenarios:
* - `autohide` timeout fires
* - user clicks on a closing cross
*
* Additionally this output is purely informative. The toast won't be removed from DOM automatically, it's up
* to the user to take care of that.
*
* @since 8.0.0
*/
this.hidden = new EventEmitter();
this.ariaLive ??= this._config.ariaLive;
}
ngAfterContentInit() {
this._zone.onStable
.asObservable()
.pipe(take(1))
.subscribe(() => {
this._init();
this.show();
});
}
ngOnChanges(changes) {
if ('autohide' in changes) {
this._clearTimeout();
this._init();
}
}
/**
* Triggers toast closing programmatically.
*
* The returned observable will emit and be completed once the closing transition has finished.
* If the animations are turned off this happens synchronously.
*
* Alternatively you could listen or subscribe to the `(hidden)` output
*
* @since 8.0.0
*/
hide() {
this._clearTimeout();
const transition = ngbRunTransition(this._zone, this._element.nativeElement, ngbToastFadeOutTransition, {
animation: this.animation,
runningTransition: 'stop',
});
transition.subscribe(() => {
this.hidden.emit();
});
return transition;
}
/**
* Triggers toast opening programmatically.
*
* The returned observable will emit and be completed once the opening transition has finished.
* If the animations are turned off this happens synchronously.
*
* Alternatively you could listen or subscribe to the `(shown)` output
*
* @since 8.0.0
*/
show() {
const transition = ngbRunTransition(this._zone, this._element.nativeElement, ngbToastFadeInTransition, {
animation: this.animation,
runningTransition: 'continue',
});
transition.subscribe(() => {
this.shown.emit();
});
return transition;
}
_init() {
if (this.autohide && !this._timeoutID) {
this._timeoutID = setTimeout(() => this.hide(), this.delay);
}
}
_clearTimeout() {
if (this._timeoutID) {
clearTimeout(this._timeoutID);
this._timeoutID = null;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbToast, deps: [{ token: 'aria-live', attribute: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.0", type: NgbToast, isStandalone: true, selector: "ngb-toast", inputs: { animation: "animation", delay: "delay", autohide: "autohide", header: "header" }, outputs: { shown: "shown", hidden: "hidden" }, host: { attributes: { "role": "alert", "aria-atomic": "true" }, properties: { "attr.aria-live": "ariaLive", "class.fade": "animation" }, classAttribute: "toast" }, queries: [{ propertyName: "contentHeaderTpl", first: true, predicate: NgbToastHeader, descendants: true, read: TemplateRef, static: true }], exportAs: ["ngbToast"], usesOnChanges: true, ngImport: i0, template: `
<ng-template #headerTpl>
<strong class="me-auto">{{ header }}</strong>
</ng-template>
(contentHeaderTpl || header) {
<div class="toast-header">
<ng-template [ngTemplateOutlet]="contentHeaderTpl || headerTpl" />
<button
type="button"
class="btn-close"
aria-label="Close"
i18n-aria-label="@@ngb.toast.close-aria"
(click)="hide()"
>
</button>
</div>
}
<div class="toast-body">
<ng-content />
</div>
`, isInline: true, styles: ["ngb-toast{display:block}ngb-toast .toast-header .close{margin-left:auto;margin-bottom:.25rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbToast, decorators: [{
type: Component,
args: [{ selector: 'ngb-toast', exportAs: 'ngbToast', standalone: true, imports: [NgTemplateOutlet], encapsulation: ViewEncapsulation.None, host: {
role: 'alert',
'[attr.aria-live]': 'ariaLive',
'aria-atomic': 'true',
class: 'toast',
'[class.fade]': 'animation',
}, template: `
<ng-template #headerTpl>
<strong class="me-auto">{{ header }}</strong>
</ng-template>
(contentHeaderTpl || header) {
<div class="toast-header">
<ng-template [ngTemplateOutlet]="contentHeaderTpl || headerTpl" />
<button
type="button"
class="btn-close"
aria-label="Close"
i18n-aria-label="@@ngb.toast.close-aria"
(click)="hide()"
>
</button>
</div>
}
<div class="toast-body">
<ng-content />
</div>
`, styles: ["ngb-toast{display:block}ngb-toast .toast-header .close{margin-left:auto;margin-bottom:.25rem}\n"] }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Attribute,
args: ['aria-live']
}] }], propDecorators: { animation: [{
type: Input
}], delay: [{
type: Input
}], autohide: [{
type: Input
}], header: [{
type: Input
}], contentHeaderTpl: [{
type: ContentChild,
args: [NgbToastHeader, { read: TemplateRef, static: true }]
}], shown: [{
type: Output
}], hidden: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9hc3QvdG9hc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUVOLE1BQU0sRUFFTixXQUFXLEVBQ1gsaUJBQWlCLEdBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHlCQUF5QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDekYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBRW5EOzs7OztHQUtHO0FBRUgsTUFBTSxPQUFPLGNBQWM7OEdBQWQsY0FBYztrR0FBZCxjQUFjOzsyRkFBZCxjQUFjO2tCQUQxQixTQUFTO21CQUFDLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUU7O0FBRzdEOzs7OztHQUtHO0FBcUNILE1BQU0sT0FBTyxRQUFRO0lBNERwQixZQUEyQyxRQUFnQjtRQUFoQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBM0RuRCxZQUFPLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pDLFVBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkIsYUFBUSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUd0Qzs7Ozs7O1dBTUc7UUFDTSxjQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENB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QyxXQUFXLFlBQ1gsVUFBVSxjQUNSLElBQUksV0FDUCxDQUFDLGdCQUFnQixDQUFDLGlCQUNaLGlCQUFpQixDQUFDLElBQUksUUFDL0I7d0JBQ0wsSUFBSSxFQUFFLE9BQU87d0JBQ2Isa0JBQWtCLEVBQUUsVUFBVTt3QkFDOUIsYUFBYSxFQUFFLE1BQU07d0JBQ3JCLEtBQUssRUFBRSxPQUFPO3dCQUNkLGNBQWMsRUFBRSxXQUFXO3FCQUMzQixZQUNTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQW9CVDs7MEJBK0RZLFNBQVM7MkJBQUMsV0FBVzt5Q0EvQ3pCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBTUcsS0FBSztzQkFBYixLQUFLO2dCQU1HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsTUFBTTtzQkFBZCxLQUFLO2dCQU02RCxnQkFBZ0I7c0JBQWxGLFlBQVk7dUJBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQU92RCxLQUFLO3NCQUFkLE1BQU07Z0JBY0csTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0QWZ0ZXJDb250ZW50SW5pdCxcblx0QXR0cmlidXRlLFxuXHRDb21wb25lbnQsXG5cdENvbnRlbnRDaGlsZCxcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRFdmVudEVtaXR0ZXIsXG5cdGluamVjdCxcblx0SW5wdXQsXG5cdE5nWm9uZSxcblx0T25DaGFuZ2VzLFxuXHRPdXRwdXQsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdFRlbXBsYXRlUmVmLFxuXHRWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE5nYlRvYXN0Q29uZmlnIH0gZnJvbSAnLi90b2FzdC1jb25maWcnO1xuaW1wb3J0IHsgbmdiUnVuVHJhbnNpdGlvbiB9IGZyb20gJy4uL3V0aWwvdHJhbnNpdGlvbi9uZ2JUcmFuc2l0aW9uJztcbmltcG9ydCB7IG5nYlRvYXN0RmFkZUluVHJhbnNpdGlvbiwgbmdiVG9hc3RGYWRlT3V0VHJhbnNpdGlvbiB9IGZyb20gJy4vdG9hc3QtdHJhbnNpdGlvbic7XG5pbXBvcnQgeyBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBhbGxvd3MgdGhlIHVzYWdlIG9mIEhUTUwgbWFya3VwIG9yIG90aGVyIGRpcmVjdGl2ZXNcbiAqIGluc2lkZSBvZiB0aGUgdG9hc3QncyBoZWFkZXIuXG4gKlxuICogQHNpbmNlIDUuMC4wXG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tuZ2JUb2FzdEhlYWRlcl0nLCBzdGFuZGFsb25lOiB0cnVlIH0pXG5leHBvcnQgY2xhc3MgTmdiVG9hc3RIZWFkZXIge31cblxuLyoqXG4gKiBUb2FzdHMgcHJvdmlkZSBmZWVkYmFjayBtZXNzYWdlcyBhcyBub3RpZmljYXRpb25zIHRvIHRoZSB1c2VyLlxuICogR29hbCBpcyB0byBtaW1pYyB0aGUgcHVzaCBub3RpZmljYXRpb25zIGF2YWlsYWJsZSBib3RoIG9uIG1vYmlsZSBhbmQgZGVza3RvcCBvcGVyYXRpbmcgc3lzdGVtcy5cbiAqXG4gKiBAc2luY2UgNS4wLjBcbiAqL1xuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnbmdiLXRvYXN0Jyxcblx0ZXhwb3J0QXM6ICduZ2JUb2FzdCcsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGltcG9ydHM6IFtOZ1RlbXBsYXRlT3V0bGV0XSxcblx0ZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcblx0aG9zdDoge1xuXHRcdHJvbGU6ICdhbGVydCcsXG5cdFx0J1thdHRyLmFyaWEtbGl2ZV0nOiAnYXJpYUxpdmUnLFxuXHRcdCdhcmlhLWF0b21pYyc6ICd0cnVlJyxcblx0XHRjbGFzczogJ3RvYXN0Jyxcblx0XHQnW2NsYXNzLmZhZGVdJzogJ2FuaW1hdGlvbicsXG5cdH0sXG5cdHRlbXBsYXRlOiBgXG5cdFx0PG5nLXRlbXBsYXRlICNoZWFkZXJUcGw+XG5cdFx0XHQ8c3Ryb25nIGNsYXNzPVwibWUtYXV0b1wiPnt7IGhlYWRlciB9fTwvc3Ryb25nPlxuXHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0QGlmIChjb250ZW50SGVhZGVyVHBsIHx8IGhlYWRlcikge1xuXHRcdFx0PGRpdiBjbGFzcz1cInRvYXN0LWhlYWRlclwiPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udGVudEhlYWRlclRwbCB8fCBoZWFkZXJUcGxcIiAvPlxuXHRcdFx0XHQ8YnV0dG9uXG5cdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJidG4tY2xvc2VcIlxuXHRcdFx0XHRcdGFyaWEtbGFiZWw9XCJDbG9zZVwiXG5cdFx0XHRcdFx0aTE4bi1hcmlhLWxhYmVsPVwiQEBuZ2IudG9hc3QuY2xvc2UtYXJpYVwiXG5cdFx0XHRcdFx0KGNsaWNrKT1cImhpZGUoKVwiXG5cdFx0XHRcdD5cblx0XHRcdFx0PC9idXR0b24+XG5cdFx0XHQ8L2Rpdj5cblx0XHR9XG5cdFx0PGRpdiBjbGFzcz1cInRvYXN0LWJvZHlcIj5cblx0XHRcdDxuZy1jb250ZW50IC8+XG5cdFx0PC9kaXY+XG5cdGAsXG5cdHN0eWxlVXJsOiAnLi90b2FzdC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgTmdiVG9hc3QgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkNoYW5nZXMge1xuXHRwcml2YXRlIF9jb25maWcgPSBpbmplY3QoTmdiVG9hc3RDb25maWcpO1xuXHRwcml2YXRlIF96b25lID0gaW5qZWN0KE5nWm9uZSk7XG5cdHByaXZhdGUgX2VsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZik7XG5cblx0cHJpdmF0ZSBfdGltZW91dElEO1xuXHQvKipcblx0ICogSWYgYHRydWVgLCB0b2FzdCBvcGVuaW5nIGFuZCBjbG9zaW5nIHdpbGwgYmUgYW5pbWF0ZWQuXG5cdCAqXG5cdCAqIEFuaW1hdGlvbiBpcyB0cmlnZ2VyZWQgb25seSB3aGVuIHRoZSBgLmhpZGUoKWAgb3IgYC5zaG93KClgIGZ1bmN0aW9ucyBhcmUgY2FsbGVkXG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QElucHV0KCkgYW5pbWF0aW9uID0gdGhpcy5fY29uZmlnLmFuaW1hdGlvbjtcblxuXHQvKipcblx0ICogRGVsYXkgYWZ0ZXIgd2hpY2ggdGhlIHRvYXN0IHdpbGwgaGlkZSAobXMpLlxuXHQgKiBkZWZhdWx0OiBgNTAwYCAobXMpIChpbmhlcml0ZWQgZnJvbSBOZ2JUb2FzdENvbmZpZylcblx0ICovXG5cdEBJbnB1dCgpIGRlbGF5ID0gdGhpcy5fY29uZmlnLmRlbGF5O1xuXG5cdC8qKlxuXHQgKiBBdXRvIGhpZGUgdGhlIHRvYXN0IGFmdGVyIGEgZGVsYXkgaW4gbXMuXG5cdCAqIGRlZmF1bHQ6IGB0cnVlYCAoaW5oZXJpdGVkIGZyb20gTmdiVG9hc3RDb25maWcpXG5cdCAqL1xuXHRASW5wdXQoKSBhdXRvaGlkZSA9IHRoaXMuX2NvbmZpZy5hdXRvaGlkZTtcblxuXHQvKipcblx0ICogVGV4dCB0byBiZSB1c2VkIGFzIHRvYXN0J3MgaGVhZGVyLlxuXHQgKiBJZ25vcmVkIGlmIGEgQ29udGVudENoaWxkIHRlbXBsYXRlIGlzIHNwZWNpZmllZCBhdCB0aGUgc2FtZSB0aW1lLlxuXHQgKi9cblx0QElucHV0KCkgaGVhZGVyOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIEEgdGVtcGxhdGUgbGlrZSBgPG5nLXRlbXBsYXRlIG5nYlRvYXN0SGVhZGVyPjwvbmctdGVtcGxhdGU+YCBjYW4gYmVcblx0ICogdXNlZCBpbiB0aGUgcHJvamVjdGVkIGNvbnRlbnQgdG8gYWxsb3cgbWFya3VwIHVzYWdlLlxuXHQgKi9cblx0QENvbnRlbnRDaGlsZChOZ2JUb2FzdEhlYWRlciwgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pIGNvbnRlbnRIZWFkZXJUcGw6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsID0gbnVsbDtcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZmlyZWQgYWZ0ZXIgdGhlIGFuaW1hdGlvbiB0cmlnZ2VyZWQgYnkgY2FsbGluZyBgLnNob3coKWAgbWV0aG9kIGhhcyBmaW5pc2hlZC5cblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgc2hvd24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cblx0LyoqXG5cdCAqIEFuIGV2ZW50IGZpcmVkIGFmdGVyIHRoZSBhbmltYXRpb24gdHJpZ2dlcmVkIGJ5IGNhbGxpbmcgYC5oaWRlKClgIG1ldGhvZCBoYXMgZmluaXNoZWQuXG5cdCAqXG5cdCAqIEl0IGNhbiBvbmx5IG9jY3VyIGluIDIgZGlmZmVyZW50IHNjZW5hcmlvczpcblx0ICogLSBgYXV0b2hpZGVgIHRpbWVvdXQgZmlyZXNcblx0ICogLSB1c2VyIGNsaWNrcyBvbiBhIGNsb3NpbmcgY3Jvc3Ncblx0ICpcblx0ICogQWRkaXRpb25hbGx5IHRoaXMgb3V0cHV0IGlzIHB1cmVseSBpbmZvcm1hdGl2ZS4gVGhlIHRvYXN0IHdvbid0IGJlIHJlbW92ZWQgZnJvbSBET00gYXV0b21hdGljYWxseSwgaXQncyB1cFxuXHQgKiB0byB0aGUgdXNlciB0byB0YWtlIGNhcmUgb2YgdGhhdC5cblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgaGlkZGVuID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG5cdGNvbnN0cnVjdG9yKEBBdHRyaWJ1dGUoJ2FyaWEtbGl2ZScpIHB1YmxpYyBhcmlhTGl2ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5hcmlhTGl2ZSA/Pz0gdGhpcy5fY29uZmlnLmFyaWFMaXZlO1xuXHR9XG5cblx0bmdBZnRlckNvbnRlbnRJbml0KCkge1xuXHRcdHRoaXMuX3pvbmUub25TdGFibGVcblx0XHRcdC5hc09ic2VydmFibGUoKVxuXHRcdFx0LnBpcGUodGFrZSgxKSlcblx0XHRcdC5zdWJzY3JpYmUoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLl9pbml0KCk7XG5cdFx0XHRcdHRoaXMuc2hvdygpO1xuXHRcdFx0fSk7XG5cdH1cblxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG5cdFx0aWYgKCdhdXRvaGlkZScgaW4gY2hhbmdlcykge1xuXHRcdFx0dGhpcy5fY2xlYXJUaW1lb3V0KCk7XG5cdFx0XHR0aGlzLl9pbml0KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyaWdnZXJzIHRvYXN0IGNsb3NpbmcgcHJvZ3JhbW1hdGljYWxseS5cblx0ICpcblx0ICogVGhlIHJldHVybmVkIG9ic2VydmFibGUgd2lsbCBlbWl0IGFuZCBiZSBjb21wbGV0ZWQgb25jZSB0aGUgY2xvc2luZyB0cmFuc2l0aW9uIGhhcyBmaW5pc2hlZC5cblx0ICogSWYgdGhlIGFuaW1hdGlvbnMgYXJlIHR1cm5lZCBvZmYgdGhpcyBoYXBwZW5zIHN5bmNocm9ub3VzbHkuXG5cdCAqXG5cdCAqIEFsdGVybmF0aXZlbHkgeW91IGNvdWxkIGxpc3RlbiBvciBzdWJzY3JpYmUgdG8gdGhlIGAoaGlkZGVuKWAgb3V0cHV0XG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0aGlkZSgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcblx0XHR0aGlzLl9jbGVhclRpbWVvdXQoKTtcblx0XHRjb25zdCB0cmFuc2l0aW9uID0gbmdiUnVuVHJhbnNpdGlvbih0aGlzLl96b25lLCB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIG5nYlRvYXN0RmFkZU91dFRyYW5zaXRpb24sIHtcblx0XHRcdGFuaW1hdGlvbjogdGhpcy5hbmltYXRpb24sXG5cdFx0XHRydW5uaW5nVHJhbnNpdGlvbjogJ3N0b3AnLFxuXHRcdH0pO1xuXHRcdHRyYW5zaXRpb24uc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdHRoaXMuaGlkZGVuLmVtaXQoKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdHJhbnNpdGlvbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmlnZ2VycyB0b2FzdCBvcGVuaW5nIHByb2dyYW1tYXRpY2FsbHkuXG5cdCAqXG5cdCAqIFRoZSByZXR1cm5lZCBvYnNlcnZhYmxlIHdpbGwgZW1pdCBhbmQgYmUgY29tcGxldGVkIG9uY2UgdGhlIG9wZW5pbmcgdHJhbnNpdGlvbiBoYXMgZmluaXNoZWQuXG5cdCAqIElmIHRoZSBhbmltYXRpb25zIGFyZSB0dXJuZWQgb2ZmIHRoaXMgaGFwcGVucyBzeW5jaHJvbm91c2x5LlxuXHQgKlxuXHQgKiBBbHRlcm5hdGl2ZWx5IHlvdSBjb3VsZCBsaXN0ZW4gb3Igc3Vic2NyaWJlIHRvIHRoZSBgKHNob3duKWAgb3V0cHV0XG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0c2hvdygpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcblx0XHRjb25zdCB0cmFuc2l0aW9uID0gbmdiUnVuVHJhbnNpdGlvbih0aGlzLl96b25lLCB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIG5nYlRvYXN0RmFkZUluVHJhbnNpdGlvbiwge1xuXHRcdFx0YW5pbWF0aW9uOiB0aGlzLmFuaW1hdGlvbixcblx0XHRcdHJ1bm5pbmdUcmFuc2l0aW9uOiAnY29udGludWUnLFxuXHRcdH0pO1xuXHRcdHRyYW5zaXRpb24uc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdHRoaXMuc2hvd24uZW1pdCgpO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0cmFuc2l0aW9uO1xuXHR9XG5cblx0cHJpdmF0ZSBfaW5pdCgpIHtcblx0XHRpZiAodGhpcy5hdXRvaGlkZSAmJiAhdGhpcy5fdGltZW91dElEKSB7XG5cdFx0XHR0aGlzLl90aW1lb3V0SUQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaGlkZSgpLCB0aGlzLmRlbGF5KTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIF9jbGVhclRpbWVvdXQoKSB7XG5cdFx0aWYgKHRoaXMuX3RpbWVvdXRJRCkge1xuXHRcdFx0Y2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXRJRCk7XG5cdFx0XHR0aGlzLl90aW1lb3V0SUQgPSBudWxsO1xuXHRcdH1cblx0fVxufVxuIl19