UNPKG

carbon-components-angular

Version:
189 lines 22.3 kB
import { EventEmitter, Injectable } from "@angular/core"; import { Notification } from "./notification.component"; import { Toast } from "./toast.component"; import { ActionableNotification } from "./actionable-notification.component"; import * as i0 from "@angular/core"; /** * Provides a way to use the notification component. * * Notifications are displayed toward the top of the UI and do not interrupt the user’s work. */ export class NotificationService { /** * Constructs Notification Service */ constructor(injector, viewContainer, ngZone) { this.injector = injector; this.viewContainer = viewContainer; this.ngZone = ngZone; /** * An array containing `ComponentRef`s to all the notifications this service instance * is responsible for. * */ this.notificationRefs = new Array(); this.onClose = new EventEmitter(); } /** * Shows the notification based on the `notificationObj`. * * @param notificationObj Can have `type`, `message`, `target`, `duration` and `smart` members. * * **Members:** * * * `type` can be one of `"info"`, `"warning"`, `"danger"`, `"success"` * * `message` is message for notification to display * * `target` is css selector defining an element to append notification to. If not provided, * `showNotification()` creates a place for the notification in `body` * * `duration` is number of ms to close the notification after. If used in combination with `smart`, * it's added to the calculated timeout * * `smart`, set to `true` if you want to use smart notification. * * **Example:** * ```typescript * // Info notification, saying "Sample message." added to the element with id notification-container * // uses smart timeout with added duration of 1 second. * { * type: "info", * message: "Sample message.", * target: "#notification-container", * duration: 1000, * smart: true * } * ``` * * @param [notificationComp=Notification] If provided, used to resolve component factory */ showNotification(notificationObj, notificationComp = Notification) { const notificationRef = this.viewContainer.createComponent(notificationComp); notificationRef.instance.notificationObj = notificationObj; this.notificationRefs.push(notificationRef); this.onClose = notificationRef.instance.close; if (notificationObj.target) { document.querySelector(notificationObj.target).appendChild(notificationRef.location.nativeElement); } else { let body = document.querySelector("body"); // get or create a container for alert list let notificationClassName = "notification-overlay"; let notificationList = body.querySelector(`.${notificationClassName}`); if (!notificationList) { notificationList = document.createElement("div"); notificationList.className = notificationClassName; body.appendChild(notificationList); } // add the notification to the top of the list if (notificationList.firstChild) { notificationList.insertBefore(notificationRef.location.nativeElement, notificationList.firstChild); } else { notificationList.appendChild(notificationRef.location.nativeElement); } } if (notificationObj.duration && notificationObj.duration > 0) { this.ngZone.runOutsideAngular(() => { setTimeout(() => { this.ngZone.run(() => { this.close(notificationRef); }); }, notificationObj.duration); }); } if (notificationObj.smart) { this.ngZone.runOutsideAngular(() => { // let it disappear after calculated timeout setTimeout(() => { this.ngZone.run(() => { this.close(notificationRef); }); }, this.getSmartTimeout(notificationObj)); }); } this.onClose.subscribe(() => { this.close(notificationRef); }); notificationRef.instance.componentRef = notificationRef; return notificationRef.instance; } showToast(notificationObj, notificationComp = Toast) { return this.showNotification(notificationObj, notificationComp); } showActionable(notificationObj, notificationComp = ActionableNotification) { return this.showNotification(notificationObj, notificationComp); } /** * Programatically closes notification based on `notificationRef`. * * @param notificationRef `ComponentRef` of a notification or `Notification` component you wish to close */ close(notificationRef) { if (notificationRef) { if (notificationRef instanceof Notification) { this.close(notificationRef.componentRef); } else { notificationRef.destroy(); const index = this.notificationRefs.indexOf(notificationRef); if (index !== -1) { this.notificationRefs.splice(index, 1); } } } } /** * Calculates the amount of time user needs to read the message in the notification. * * @param notificationObj Same object used to instantiate notification. * * In addition to `type` and `message` members, use `duration` member to add * some extra time (in ms) to timeout if you need to. * @returns calculated timeout (in ms) for smart notification */ getSmartTimeout(notificationObj) { // calculate timeout let timeout = 600; // start with reaction time // custom duration timeout += notificationObj.duration || 0; // message type switch (notificationObj.type) { case "info": case "info-square": case "success": default: { break; } case "danger": { timeout += 3000; break; } case "warning": case "warning-alt": { timeout += 1500; break; } } // message length // average reader reads around 200 words per minute, or it takes them ~0.3s per word // let's use 1.5 factor for below average speed readers and have 0.45s per word let wordCount = notificationObj.message.trim().split(/\s+/).length; timeout += wordCount * 450; return timeout; } /** * OnDestroy hook. * * Destroys all living notifications it is responsible for. * */ ngOnDestroy() { this.notificationRefs.forEach((ref) => { ref.destroy(); }); } } NotificationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationService, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); NotificationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: i0.NgZone }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTixZQUFZLEVBQ1osVUFBVSxFQUtWLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDMUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUNBQXFDLENBQUM7O0FBRTdFOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sbUJBQW1CO0lBUy9COztPQUVHO0lBQ0gsWUFDVyxRQUFrQixFQUNsQixhQUErQixFQUMvQixNQUFjO1FBRmQsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUFDL0IsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQWR6Qjs7OztXQUlHO1FBQ0kscUJBQWdCLEdBQUcsSUFBSSxLQUFLLEVBQXFCLENBQUM7UUFDbEQsWUFBTyxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBU3BELENBQUM7SUFFSjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E2Qkc7SUFDSCxnQkFBZ0IsQ0FDZixlQUF1RSxFQUN2RSxnQkFBZ0IsR0FBRyxZQUFZO1FBRS9CLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0UsZUFBZSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDO1FBQzNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUss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QUMsTUFBTSxDQUFDO1FBQ25FLE9BQU8sSUFBSSxTQUFTLEdBQUcsR0FBRyxDQUFDO1FBRTNCLE9BQU8sT0FBTyxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFdBQVc7UUFDVixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDckMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUM7SUFDSixDQUFDOztnSEE5TFcsbUJBQW1CO29IQUFuQixtQkFBbUI7MkZBQW5CLG1CQUFtQjtrQkFEL0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudFJlZixcblx0RXZlbnRFbWl0dGVyLFxuXHRJbmplY3RhYmxlLFxuXHRPbkRlc3Ryb3ksXG5cdE5nWm9uZSxcblx0Vmlld0NvbnRhaW5lclJlZixcblx0SW5qZWN0b3Jcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuaW1wb3J0IHsgTm90aWZpY2F0aW9uQ29udGVudCwgVG9hc3RDb250ZW50LCBBY3Rpb25hYmxlQ29udGVudCB9IGZyb20gXCIuL25vdGlmaWNhdGlvbi1jb250ZW50LmludGVyZmFjZVwiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uIH0gZnJvbSBcIi4vbm90aWZpY2F0aW9uLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgVG9hc3QgfSBmcm9tIFwiLi90b2FzdC5jb21wb25lbnRcIjtcbmltcG9ydCB7IEFjdGlvbmFibGVOb3RpZmljYXRpb24gfSBmcm9tIFwiLi9hY3Rpb25hYmxlLW5vdGlmaWNhdGlvbi5jb21wb25lbnRcIjtcblxuLyoqXG4gKiBQcm92aWRlcyBhIHdheSB0byB1c2UgdGhlIG5vdGlmaWNhdGlvbiBjb21wb25lbnQuXG4gKlxuICogTm90aWZpY2F0aW9ucyBhcmUgZGlzcGxheWVkIHRvd2FyZCB0aGUgdG9wIG9mIHRoZSBVSSBhbmQgZG8gbm90IGludGVycnVwdCB0aGUgdXNlcuKAmXMgd29yay5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvblNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXHQvKipcblx0ICogQW4gYXJyYXkgY29udGFpbmluZyBgQ29tcG9uZW50UmVmYHMgdG8gYWxsIHRoZSBub3RpZmljYXRpb25zIHRoaXMgc2VydmljZSBpbnN0YW5jZVxuXHQgKiBpcyByZXNwb25zaWJsZSBmb3IuXG5cdCAqXG5cdCAqL1xuXHRwdWJsaWMgbm90aWZpY2F0aW9uUmVmcyA9IG5ldyBBcnJheTxDb21wb25lbnRSZWY8YW55Pj4oKTtcblx0cHVibGljIG9uQ2xvc2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdC8qKlxuXHQgKiBDb25zdHJ1Y3RzIE5vdGlmaWNhdGlvbiBTZXJ2aWNlXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcm90ZWN0ZWQgaW5qZWN0b3I6IEluamVjdG9yLFxuXHRcdHByb3RlY3RlZCB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuXHRcdHByb3RlY3RlZCBuZ1pvbmU6IE5nWm9uZVxuXHQpIHt9XG5cblx0LyoqXG5cdCAqIFNob3dzIHRoZSBub3RpZmljYXRpb24gYmFzZWQgb24gdGhlIGBub3RpZmljYXRpb25PYmpgLlxuXHQgKlxuXHQgKiBAcGFyYW0gbm90aWZpY2F0aW9uT2JqIENhbiBoYXZlIGB0eXBlYCwgYG1lc3NhZ2VgLCBgdGFyZ2V0YCwgYGR1cmF0aW9uYCBhbmQgYHNtYXJ0YCBtZW1iZXJzLlxuXHQgKlxuXHQgKiAqKk1lbWJlcnM6Kipcblx0ICpcblx0ICogKiBgdHlwZWAgY2FuIGJlIG9uZSBvZiBgXCJpbmZvXCJgLCBgXCJ3YXJuaW5nXCJgLCBgXCJkYW5nZXJcImAsIGBcInN1Y2Nlc3NcImBcblx0ICogKiBgbWVzc2FnZWAgaXMgbWVzc2FnZSBmb3Igbm90aWZpY2F0aW9uIHRvIGRpc3BsYXlcblx0ICogKiBgdGFyZ2V0YCBpcyBjc3Mgc2VsZWN0b3IgZGVmaW5pbmcgYW4gZWxlbWVudCB0byBhcHBlbmQgbm90aWZpY2F0aW9uIHRvLiBJZiBub3QgcHJvdmlkZWQsXG5cdCAqIGBzaG93Tm90aWZpY2F0aW9uKClgIGNyZWF0ZXMgYSBwbGFjZSBmb3IgdGhlIG5vdGlmaWNhdGlvbiBpbiBgYm9keWBcblx0ICogKiBgZHVyYXRpb25gIGlzIG51bWJlciBvZiBtcyB0byBjbG9zZSB0aGUgbm90aWZpY2F0aW9uIGFmdGVyLiBJZiB1c2VkIGluIGNvbWJpbmF0aW9uIHdpdGggYHNtYXJ0YCxcblx0ICogaXQncyBhZGRlZCB0byB0aGUgY2FsY3VsYXRlZCB0aW1lb3V0XG5cdCAqICogYHNtYXJ0YCwgc2V0IHRvIGB0cnVlYCBpZiB5b3Ugd2FudCB0byB1c2Ugc21hcnQgbm90aWZpY2F0aW9uLlxuXHQgKlxuXHQgKiAqKkV4YW1wbGU6Kipcblx0ICogYGBgdHlwZXNjcmlwdFxuXHQgKiAvLyBJbmZvIG5vdGlmaWNhdGlvbiwgc2F5aW5nIFwiU2FtcGxlIG1lc3NhZ2UuXCIgYWRkZWQgdG8gdGhlIGVsZW1lbnQgd2l0aCBpZCBub3RpZmljYXRpb24tY29udGFpbmVyXG5cdCAqIC8vIHVzZXMgc21hcnQgdGltZW91dCB3aXRoIGFkZGVkIGR1cmF0aW9uIG9mIDEgc2Vjb25kLlxuXHQgKiB7XG5cdCAqXHR0eXBlOiBcImluZm9cIixcblx0ICpcdG1lc3NhZ2U6IFwiU2FtcGxlIG1lc3NhZ2UuXCIsXG5cdCAqXHR0YXJnZXQ6IFwiI25vdGlmaWNhdGlvbi1jb250YWluZXJcIixcblx0ICpcdGR1cmF0aW9uOiAxMDAwLFxuXHQgKlx0c21hcnQ6IHRydWVcblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogQHBhcmFtIFtub3RpZmljYXRpb25Db21wPU5vdGlmaWNhdGlvbl0gSWYgcHJvdmlkZWQsIHVzZWQgdG8gcmVzb2x2ZSBjb21wb25lbnQgZmFjdG9yeVxuXHQgKi9cblx0c2hvd05vdGlmaWNhdGlvbihcblx0XHRub3RpZmljYXRpb25PYmo6IE5vdGlmaWNhdGlvbkNvbnRlbnQgfCBUb2FzdENvbnRlbnQgfCBBY3Rpb25hYmxlQ29udGVudCxcblx0XHRub3RpZmljYXRpb25Db21wID0gTm90aWZpY2F0aW9uXG5cdCkge1xuXHRcdGNvbnN0IG5vdGlmaWNhdGlvblJlZiA9IHRoaXMudmlld0NvbnRhaW5lci5jcmVhdGVDb21wb25lbnQobm90aWZpY2F0aW9uQ29tcCk7XG5cdFx0bm90aWZpY2F0aW9uUmVmLmluc3RhbmNlLm5vdGlmaWNhdGlvbk9iaiA9IG5vdGlmaWNhdGlvbk9iajtcblx0XHR0aGlzLm5vdGlmaWNhdGlvblJlZnMucHVzaChub3RpZmljYXRpb25SZWYpO1xuXG5cdFx0dGhpcy5vbkNsb3NlID0gbm90aWZpY2F0aW9uUmVmLmluc3RhbmNlLmNsb3NlO1xuXG5cdFx0aWYgKG5vdGlmaWNhdGlvbk9iai50YXJnZXQpIHtcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iobm90aWZpY2F0aW9uT2JqLnRhcmdldCkuYXBwZW5kQ2hpbGQobm90aWZpY2F0aW9uUmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZXQgYm9keSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpO1xuXG5cdFx0XHQvLyBnZXQgb3IgY3JlYXRlIGEgY29udGFpbmVyIGZvciBhbGVydCBsaXN0XG5cdFx0XHRsZXQgbm90aWZpY2F0aW9uQ2xhc3NOYW1lID0gXCJub3RpZmljYXRpb24tb3ZlcmxheVwiO1xuXHRcdFx0bGV0IG5vdGlmaWNhdGlvbkxpc3QgPSBib2R5LnF1ZXJ5U2VsZWN0b3IoYC4ke25vdGlmaWNhdGlvbkNsYXNzTmFtZX1gKTtcblx0XHRcdGlmICghbm90aWZpY2F0aW9uTGlzdCkge1xuXHRcdFx0XHRub3RpZmljYXRpb25MaXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblx0XHRcdFx0bm90aWZpY2F0aW9uTGlzdC5jbGFzc05hbWUgPSBub3RpZmljYXRpb25DbGFzc05hbWU7XG5cdFx0XHRcdGJvZHkuYXBwZW5kQ2hpbGQobm90aWZpY2F0aW9uTGlzdCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGFkZCB0aGUgbm90aWZpY2F0aW9uIHRvIHRoZSB0b3Agb2YgdGhlIGxpc3Rcblx0XHRcdGlmIChub3RpZmljYXRpb25MaXN0LmZpcnN0Q2hpbGQpIHtcblx0XHRcdFx0bm90aWZpY2F0aW9uTGlzdC5pbnNlcnRCZWZvcmUobm90aWZpY2F0aW9uUmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQsIG5vdGlmaWNhdGlvbkxpc3QuZmlyc3RDaGlsZCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRub3RpZmljYXRpb25MaXN0LmFwcGVuZENoaWxkKG5vdGlmaWNhdGlvblJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAobm90aWZpY2F0aW9uT2JqLmR1cmF0aW9uICYmIG5vdGlmaWNhdGlvbk9iai5kdXJhdGlvbiA+IDApIHtcblx0XHRcdHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuY2xvc2Uobm90aWZpY2F0aW9uUmVmKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSwgbm90aWZpY2F0aW9uT2JqLmR1cmF0aW9uKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmIChub3RpZmljYXRpb25PYmouc21hcnQpIHtcblx0XHRcdHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblx0XHRcdFx0Ly8gbGV0IGl0IGRpc2FwcGVhciBhZnRlciBjYWxjdWxhdGVkIHRpbWVvdXRcblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuY2xvc2Uobm90aWZpY2F0aW9uUmVmKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSwgdGhpcy5nZXRTbWFydFRpbWVvdXQobm90aWZpY2F0aW9uT2JqKSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHR0aGlzLm9uQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdHRoaXMuY2xvc2Uobm90aWZpY2F0aW9uUmVmKTtcblx0XHR9KTtcblxuXHRcdG5vdGlmaWNhdGlvblJlZi5pbnN0YW5jZS5jb21wb25lbnRSZWYgPSBub3RpZmljYXRpb25SZWY7XG5cdFx0cmV0dXJuIG5vdGlmaWNhdGlvblJlZi5pbnN0YW5jZTtcblx0fVxuXG5cdHNob3dUb2FzdChub3RpZmljYXRpb25PYmo6IE5vdGlmaWNhdGlvbkNvbnRlbnQgfCBUb2FzdENvbnRlbnQsIG5vdGlmaWNhdGlvbkNvbXAgPSBUb2FzdCkge1xuXHRcdHJldHVybiB0aGlzLnNob3dOb3RpZmljYXRpb24obm90aWZpY2F0aW9uT2JqLCBub3RpZmljYXRpb25Db21wIGFzIGFueSk7XG5cdH1cblxuXHRzaG93QWN0aW9uYWJsZShub3RpZmljYXRpb25PYmo6IEFjdGlvbmFibGVDb250ZW50LCBub3RpZmljYXRpb25Db21wID0gQWN0aW9uYWJsZU5vdGlmaWNhdGlvbikge1xuXHRcdHJldHVybiB0aGlzLnNob3dOb3RpZmljYXRpb24obm90aWZpY2F0aW9uT2JqLCBub3RpZmljYXRpb25Db21wIGFzIGFueSk7XG5cdH1cblxuXHQvKipcblx0ICogUHJvZ3JhbWF0aWNhbGx5IGNsb3NlcyBub3RpZmljYXRpb24gYmFzZWQgb24gYG5vdGlmaWNhdGlvblJlZmAuXG5cdCAqXG5cdCAqIEBwYXJhbSBub3RpZmljYXRpb25SZWYgYENvbXBvbmVudFJlZmAgb2YgYSBub3RpZmljYXRpb24gb3IgYE5vdGlmaWNhdGlvbmAgY29tcG9uZW50IHlvdSB3aXNoIHRvIGNsb3NlXG5cdCAqL1xuXHRjbG9zZShub3RpZmljYXRpb25SZWY6IGFueSkge1xuXHRcdGlmIChub3RpZmljYXRpb25SZWYpIHtcblx0XHRcdGlmIChub3RpZmljYXRpb25SZWYgaW5zdGFuY2VvZiBOb3RpZmljYXRpb24pIHtcblx0XHRcdFx0dGhpcy5jbG9zZShub3RpZmljYXRpb25SZWYuY29tcG9uZW50UmVmKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5vdGlmaWNhdGlvblJlZi5kZXN0cm95KCk7XG5cdFx0XHRcdGNvbnN0IGluZGV4ID0gdGhpcy5ub3RpZmljYXRpb25SZWZzLmluZGV4T2Yobm90aWZpY2F0aW9uUmVmKTtcblx0XHRcdFx0aWYgKGluZGV4ICE9PSAtMSkge1xuXHRcdFx0XHRcdHRoaXMubm90aWZpY2F0aW9uUmVmcy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZXMgdGhlIGFtb3VudCBvZiB0aW1lIHVzZXIgbmVlZHMgdG8gcmVhZCB0aGUgbWVzc2FnZSBpbiB0aGUgbm90aWZpY2F0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0gbm90aWZpY2F0aW9uT2JqIFNhbWUgb2JqZWN0IHVzZWQgdG8gaW5zdGFudGlhdGUgbm90aWZpY2F0aW9uLlxuXHQgKlxuXHQgKiBJbiBhZGRpdGlvbiB0byBgdHlwZWAgYW5kIGBtZXNzYWdlYCBtZW1iZXJzLCB1c2UgYGR1cmF0aW9uYCBtZW1iZXIgdG8gYWRkXG5cdCAqIHNvbWUgZXh0cmEgdGltZSAoaW4gbXMpIHRvIHRpbWVvdXQgaWYgeW91IG5lZWQgdG8uXG5cdCAqIEByZXR1cm5zIGNhbGN1bGF0ZWQgdGltZW91dCAoaW4gbXMpIGZvciBzbWFydCBub3RpZmljYXRpb25cblx0ICovXG5cdGdldFNtYXJ0VGltZW91dChub3RpZmljYXRpb25PYmopOiBudW1iZXIge1xuXHRcdC8vIGNhbGN1bGF0ZSB0aW1lb3V0XG5cdFx0bGV0IHRpbWVvdXQgPSA2MDA7IC8vIHN0YXJ0IHdpdGggcmVhY3Rpb24gdGltZVxuXG5cdFx0Ly8gY3VzdG9tIGR1cmF0aW9uXG5cdFx0dGltZW91dCArPSBub3RpZmljYXRpb25PYmouZHVyYXRpb24gfHwgMDtcblxuXHRcdC8vIG1lc3NhZ2UgdHlwZVxuXHRcdHN3aXRjaCAobm90aWZpY2F0aW9uT2JqLnR5cGUpIHtcblx0XHRcdGNhc2UgXCJpbmZvXCI6XG5cdFx0XHRjYXNlIFwiaW5mby1zcXVhcmVcIjpcblx0XHRcdGNhc2UgXCJzdWNjZXNzXCI6XG5cdFx0XHRkZWZhdWx0OiB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Y2FzZSBcImRhbmdlclwiOiB7XG5cdFx0XHRcdHRpbWVvdXQgKz0gMzAwMDtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRjYXNlIFwid2FybmluZ1wiOlxuXHRcdFx0Y2FzZSBcIndhcm5pbmctYWx0XCI6IHtcblx0XHRcdFx0dGltZW91dCArPSAxNTAwO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBtZXNzYWdlIGxlbmd0aFxuXHRcdC8vIGF2ZXJhZ2UgcmVhZGVyIHJlYWRzIGFyb3VuZCAyMDAgd29yZHMgcGVyIG1pbnV0ZSwgb3IgaXQgdGFrZXMgdGhlbSB+MC4zcyBwZXIgd29yZFxuXHRcdC8vIGxldCdzIHVzZSAxLjUgZmFjdG9yIGZvciBiZWxvdyBhdmVyYWdlIHNwZWVkIHJlYWRlcnMgYW5kIGhhdmUgMC40NXMgcGVyIHdvcmRcblx0XHRsZXQgd29yZENvdW50ID0gbm90aWZpY2F0aW9uT2JqLm1lc3NhZ2UudHJpbSgpLnNwbGl0KC9cXHMrLykubGVuZ3RoO1xuXHRcdHRpbWVvdXQgKz0gd29yZENvdW50ICogNDUwO1xuXG5cdFx0cmV0dXJuIHRpbWVvdXQ7XG5cdH1cblxuXHQvKipcblx0ICogT25EZXN0cm95IGhvb2suXG5cdCAqXG5cdCAqIERlc3Ryb3lzIGFsbCBsaXZpbmcgbm90aWZpY2F0aW9ucyBpdCBpcyByZXNwb25zaWJsZSBmb3IuXG5cdCAqXG5cdCAqL1xuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLm5vdGlmaWNhdGlvblJlZnMuZm9yRWFjaCgocmVmKSA9PiB7XG5cdFx0XHRyZWYuZGVzdHJveSgpO1xuXHRcdH0pO1xuXHR9XG59XG4iXX0=