@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
124 lines • 21.8 kB
JavaScript
import { animate, state, style, transition, trigger } from '@angular/animations';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, inject, Input, Renderer2, ViewChildren } from '@angular/core';
import { Subject } from 'rxjs';
import { map, takeUntil, withLatestFrom } from 'rxjs/operators';
import { tick } from '../../common/index';
import { NotificationService } from './notification.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class NotificationListComponent {
constructor() {
this._notificationService = inject(NotificationService);
this._changeDetectorRef = inject(ChangeDetectorRef);
this._renderer = inject(Renderer2);
/** Sets the position of the list of notifications within the browser window. */
this.position = 'bottom-right';
/** The list of notifications that have not been dismissed */
this.notifications$ = this._notificationService.notifications$.pipe(map(() => this._notifications));
/** Unsubscribe from all subscriptions on component destroy */
this._onDestroy = new Subject();
}
/**
* Sets the order in which notifications are displayed:
`above` - newer notifications will appear above older ones.
`below` - newer notifications will appear below older ones.
*/
set direction(direction) {
this._notificationService.direction = direction;
}
/** Filter out any hidden notifications */
get _notifications() {
return this._notificationService.notifications.filter(notification => notification.visible);
}
ngAfterViewInit() {
// whenever the notifications change we want to recalculate the positions and height
this._elements.changes.pipe(takeUntil(this._onDestroy), tick(), map(changes => changes.toArray()), withLatestFrom(this.notifications$)).subscribe(([elements, notifications]) => {
// Set the `top` style property of each element
this.applyElementPositions(elements, notifications);
this.updateListPosition(elements, notifications);
this._changeDetectorRef.markForCheck();
});
}
ngOnChanges() {
if (this._elements) {
this.updateListPosition(this._elements.toArray(), this._notifications);
}
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
applyElementPositions(elements, notifications) {
let top = 0;
for (let i = 0; i < elements.length; i += 1) {
const element = elements[i].nativeElement;
const notification = notifications[i];
this._renderer.setStyle(element, 'top', `${top}px`);
top = top + this.getNotificationHeightInPixels(notification, elements[i]);
}
}
updateListPosition(elements, notifications) {
if (this.position === 'bottom-left' || this.position === 'bottom-right') {
this._bottom = notifications.reduce((totalHeight, notification, index) => totalHeight + this.getNotificationHeightInPixels(notification, elements[index]), 0);
}
else {
// In a top position, bottom should be unset.
this._bottom = undefined;
}
}
/** Get the height of the notification, including spacing if configured. */
getNotificationHeightInPixels(notification, elementRef) {
if (notification.spacing === undefined) {
return this.getElementOuterHeightInPixels(elementRef);
}
return elementRef.nativeElement.offsetHeight + notification.spacing;
}
/** Get the total height of the element including margins. */
getElementOuterHeightInPixels(elementRef) {
const element = elementRef.nativeElement;
const { marginTop, marginBottom } = getComputedStyle(element);
return element.offsetHeight + parseInt(marginTop) + parseInt(marginBottom);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NotificationListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: NotificationListComponent, selector: "ux-notification-list", inputs: { direction: "direction", position: "position" }, host: { properties: { "class": "this.position", "style.bottom.px": "this._bottom" } }, viewQueries: [{ propertyName: "_elements", predicate: ["notification"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@for (notificationRef of notifications$ | async; track notificationRef; let index = $index) {\n <div #notification\n class=\"notification\"\n [style.height.px]=\"notificationRef.height\"\n [style.background-color]=\"notificationRef.backgroundColor\"\n [@notificationState]>\n <!-- Notification Content -->\n <ng-container\n [ngTemplateOutlet]=\"notificationRef.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: notificationRef, data: notificationRef.data }\">\n </ng-container>\n </div>\n}\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], animations: [
trigger('notificationState', [
state('in', style({ transform: 'translateY(0)', opacity: 0.9 })),
transition(':enter', [
style({ transform: 'translateY(-50px)', opacity: 0 }),
animate(500)
]),
transition(':leave', [
animate(500, style({ transform: 'translateY(50px)', opacity: 0 }))
])
])
], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NotificationListComponent, decorators: [{
type: Component,
args: [{ selector: 'ux-notification-list', changeDetection: ChangeDetectionStrategy.OnPush, animations: [
trigger('notificationState', [
state('in', style({ transform: 'translateY(0)', opacity: 0.9 })),
transition(':enter', [
style({ transform: 'translateY(-50px)', opacity: 0 }),
animate(500)
]),
transition(':leave', [
animate(500, style({ transform: 'translateY(50px)', opacity: 0 }))
])
])
], template: "@for (notificationRef of notifications$ | async; track notificationRef; let index = $index) {\n <div #notification\n class=\"notification\"\n [style.height.px]=\"notificationRef.height\"\n [style.background-color]=\"notificationRef.backgroundColor\"\n [@notificationState]>\n <!-- Notification Content -->\n <ng-container\n [ngTemplateOutlet]=\"notificationRef.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: notificationRef, data: notificationRef.data }\">\n </ng-container>\n </div>\n}\n" }]
}], propDecorators: { direction: [{
type: Input
}], position: [{
type: Input
}, {
type: HostBinding,
args: ['class']
}], _bottom: [{
type: HostBinding,
args: ['style.bottom.px']
}], _elements: [{
type: ViewChildren,
args: ['notification']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL25vdGlmaWNhdGlvbi9ub3RpZmljYXRpb24tbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pGLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFjLFdBQVcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFtQyxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZNLE9BQU8sRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzFDLE9BQU8sRUFBOEMsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7O0FBbUJ6RyxNQUFNLE9BQU8seUJBQXlCO0lBakJ0QztRQWtCcUIseUJBQW9CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFbkQsdUJBQWtCLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFL0MsY0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQVkvQyxnRkFBZ0Y7UUFHaEYsYUFBUSxHQUE0QixjQUFjLENBQUM7UUFFbkQsNkRBQTZEO1FBQzdELG1CQUFjLEdBQWtDLElBQUksQ0FBQyxvQkFB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QUMsUUFBUSxFQUFFO29CQUNqQixPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDckUsQ0FBQzthQUNMLENBQUM7U0FDTDs7NEZBRVEseUJBQXlCO2tCQWpCckMsU0FBUzsrQkFDSSxzQkFBc0IsbUJBRWYsdUJBQXVCLENBQUMsTUFBTSxjQUNuQzt3QkFDUixPQUFPLENBQUMsbUJBQW1CLEVBQUU7NEJBQ3pCLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzs0QkFDaEUsVUFBVSxDQUFDLFFBQVEsRUFBRTtnQ0FDakIsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztnQ0FDckQsT0FBTyxDQUFDLEdBQUcsQ0FBQzs2QkFDZixDQUFDOzRCQUNGLFVBQVUsQ0FBQyxRQUFRLEVBQUU7Z0NBQ2pCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDOzZCQUNyRSxDQUFDO3lCQUNMLENBQUM7cUJBQ0w7OEJBZUcsU0FBUztzQkFEWixLQUFLO2dCQVFOLFFBQVE7c0JBRlAsS0FBSzs7c0JBQ0wsV0FBVzt1QkFBQyxPQUFPO2dCQVFwQixPQUFPO3NCQUROLFdBQVc7dUJBQUMsaUJBQWlCO2dCQUlBLFNBQVM7c0JBQXRDLFlBQVk7dUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFuaW1hdGUsIHN0YXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBpbmplY3QsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgUXVlcnlMaXN0LCBSZW5kZXJlcjIsIFZpZXdDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCB0YWtlVW50aWwsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgdGljayB9IGZyb20gJy4uLy4uL2NvbW1vbi9pbmRleCc7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25MaXN0RGlyZWN0aW9uLCBOb3RpZmljYXRpb25SZWYsIE5vdGlmaWNhdGlvblNlcnZpY2UgfSBmcm9tICcuL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICd1eC1ub3RpZmljYXRpb24tbGlzdCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL25vdGlmaWNhdGlvbi1saXN0LmNvbXBvbmVudC5odG1sJyxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBhbmltYXRpb25zOiBbXG4gICAgICAgIHRyaWdnZXIoJ25vdGlmaWNhdGlvblN0YXRlJywgW1xuICAgICAgICAgICAgc3RhdGUoJ2luJywgc3R5bGUoeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKDApJywgb3BhY2l0eTogMC45IH0pKSxcbiAgICAgICAgICAgIHRyYW5zaXRpb24oJzplbnRlcicsIFtcbiAgICAgICAgICAgICAgICBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTUwcHgpJywgb3BhY2l0eTogMCB9KSxcbiAgICAgICAgICAgICAgICBhbmltYXRlKDUwMClcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgdHJhbnNpdGlvbignOmxlYXZlJywgW1xuICAgICAgICAgICAgICAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoNTBweCknLCBvcGFjaXR5OiAwIH0pKVxuICAgICAgICAgICAgXSlcbiAgICAgICAgXSlcbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvbkxpc3RDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfbm90aWZpY2F0aW9uU2VydmljZSA9IGluamVjdChOb3RpZmljYXRpb25TZXJ2aWNlKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5nZURldGVjdG9yUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3JlbmRlcmVyID0gaW5qZWN0KFJlbmRlcmVyMik7XG5cbiAgICAvKipcbiAgICAgKiAgU2V0cyB0aGUgb3JkZXIgaW4gd2hpY2ggbm90aWZpY2F0aW9ucyBhcmUgZGlzcGxheWVkOlxuICAgICAgICBgYWJvdmVgIC0gbmV3ZXIgbm90aWZpY2F0aW9ucyB3aWxsIGFwcGVhciBhYm92ZSBvbGRlciBvbmVzLlxuICAgICAgICBgYmVsb3dgIC0gbmV3ZXIgbm90aWZpY2F0aW9ucyB3aWxsIGFwcGVhciBiZWxvdyBvbGRlciBvbmVzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgc2V0IGRpcmVjdGlvbihkaXJlY3Rpb246IE5vdGlmaWNhdGlvbkxpc3REaXJlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgfVxuXG4gICAgLyoqIFNldHMgdGhlIHBvc2l0aW9uIG9mIHRoZSBsaXN0IG9mIG5vdGlmaWNhdGlvbnMgd2l0aGluIHRoZSBicm93c2VyIHdpbmRvdy4gKi9cbiAgICBASW5wdXQoKVxuICAgIEBIb3N0QmluZGluZygnY2xhc3MnKVxuICAgIHBvc2l0aW9uOiBOb3RpZmljYXRpb25MaXN0UG9zdGlvbiA9ICdib3R0b20tcmlnaHQnO1xuXG4gICAgLyoqIFRoZSBsaXN0IG9mIG5vdGlmaWNhdGlvbnMgdGhhdCBoYXZlIG5vdCBiZWVuIGRpc21pc3NlZCAqL1xuICAgIG5vdGlmaWNhdGlvbnMkOiBPYnNlcnZhYmxlPE5vdGlmaWNhdGlvblJlZltdPiA9IHRoaXMuX25vdGlmaWNhdGlvblNlcnZpY2Uubm90aWZpY2F0aW9ucyQucGlwZShtYXAoKCkgPT4gdGhpcy5fbm90aWZpY2F0aW9ucykpO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBib3R0b20gcG9zaXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvbiBsaXN0ICovXG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS5ib3R0b20ucHgnKVxuICAgIF9ib3R0b206IG51bWJlcjtcblxuICAgIC8qKiBTdG9yZSBhIGxpc3Qgb2YgYWxsIGVsZW1lbnQgcmVmcyAqL1xuICAgIEBWaWV3Q2hpbGRyZW4oJ25vdGlmaWNhdGlvbicpIF9lbGVtZW50czogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xuXG4gICAgLyoqIEZpbHRlciBvdXQgYW55IGhpZGRlbiBub3RpZmljYXRpb25zICovXG4gICAgcHJpdmF0ZSBnZXQgX25vdGlmaWNhdGlvbnMoKTogTm90aWZpY2F0aW9uUmVmW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbm90aWZpY2F0aW9uU2VydmljZS5ub3RpZmljYXRpb25zLmZpbHRlcihub3RpZmljYXRpb24gPT4gbm90aWZpY2F0aW9uLnZpc2libGUpO1xuICAgIH1cblxuICAgIC8qKiBVbnN1YnNjcmliZSBmcm9tIGFsbCBzdWJzY3JpcHRpb25zIG9uIGNvbXBvbmVudCBkZXN0cm95ICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcblxuICAgICAgICAvLyB3aGVuZXZlciB0aGUgbm90aWZpY2F0aW9ucyBjaGFuZ2Ugd2Ugd2FudCB0byByZWNhbGN1bGF0ZSB0aGUgcG9zaXRpb25zIGFuZCBoZWlnaHRcbiAgICAgICAgdGhpcy5fZWxlbWVudHMuY2hhbmdlcy5waXBlKFxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSksXG4gICAgICAgICAgICB0aWNrKCksXG4gICAgICAgICAgICBtYXAoY2hhbmdlcyA9PiBjaGFuZ2VzLnRvQXJyYXkoKSBhcyBFbGVtZW50UmVmW10pLFxuICAgICAgICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5ub3RpZmljYXRpb25zJClcbiAgICAgICAgKS5zdWJzY3JpYmUoKFtlbGVtZW50cywgbm90aWZpY2F0aW9uc10pID0+IHtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBgdG9wYCBzdHlsZSBwcm9wZXJ0eSBvZiBlYWNoIGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMuYXBwbHlFbGVtZW50UG9zaXRpb25zKGVsZW1lbnRzLCBub3RpZmljYXRpb25zKTtcblxuICAgICAgICAgICAgdGhpcy51cGRhdGVMaXN0UG9zaXRpb24oZWxlbWVudHMsIG5vdGlmaWNhdGlvbnMpO1xuXG4gICAgICAgICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9lbGVtZW50cykge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVMaXN0UG9zaXRpb24odGhpcy5fZWxlbWVudHMudG9BcnJheSgpLCB0aGlzLl9ub3RpZmljYXRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5RWxlbWVudFBvc2l0aW9ucyhlbGVtZW50czogRWxlbWVudFJlZltdLCBub3RpZmljYXRpb25zOiBOb3RpZmljYXRpb25SZWZbXSk6IHZvaWQge1xuICAgICAgICBsZXQgdG9wID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW2ldLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBub3RpZmljYXRpb24gPSBub3RpZmljYXRpb25zW2ldO1xuICAgICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUoZWxlbWVudCwgJ3RvcCcsIGAke3RvcH1weGApO1xuICAgICAgICAgICAgdG9wID0gdG9wICsgdGhpcy5nZXROb3RpZmljYXRpb25IZWlnaHRJblBpeGVscyhub3RpZmljYXRpb24sIGVsZW1lbnRzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlTGlzdFBvc2l0aW9uKGVsZW1lbnRzOiBFbGVtZW50UmVmW10sIG5vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvblJlZltdKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnBvc2l0aW9uID09PSAnYm90dG9tLWxlZnQnIHx8IHRoaXMucG9zaXRpb24gPT09ICdib3R0b20tcmlnaHQnKSB7XG4gICAgICAgICAgICB0aGlzLl9ib3R0b20gPSBub3RpZmljYXRpb25zLnJlZHVjZSgodG90YWxIZWlnaHQsIG5vdGlmaWNhdGlvbiwgaW5kZXgpID0+XG4gICAgICAgICAgICAgICAgdG90YWxIZWlnaHQgKyB0aGlzLmdldE5vdGlmaWNhdGlvbkhlaWdodEluUGl4ZWxzKG5vdGlmaWNhdGlvbiwgZWxlbWVudHNbaW5kZXhdKSwgMCk7XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIC8vIEluIGEgdG9wIHBvc2l0aW9uLCBib3R0b20gc2hvdWxkIGJlIHVuc2V0LlxuICAgICAgICAgICAgdGhpcy5fYm90dG9tID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEdldCB0aGUgaGVpZ2h0IG9mIHRoZSBub3RpZmljYXRpb24sIGluY2x1ZGluZyBzcGFjaW5nIGlmIGNvbmZpZ3VyZWQuICovXG4gICAgcHJpdmF0ZSBnZXROb3RpZmljYXRpb25IZWlnaHRJblBpeGVscyhub3RpZmljYXRpb246IE5vdGlmaWNhdGlvblJlZiwgZWxlbWVudFJlZjogRWxlbWVudFJlZik6IG51bWJlciB7XG4gICAgICAgIGlmIChub3RpZmljYXRpb24uc3BhY2luZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50T3V0ZXJIZWlnaHRJblBpeGVscyhlbGVtZW50UmVmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0ICsgbm90aWZpY2F0aW9uLnNwYWNpbmc7XG4gICAgfVxuXG4gICAgLyoqIEdldCB0aGUgdG90YWwgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IGluY2x1ZGluZyBtYXJnaW5zLiAqL1xuICAgIHByaXZhdGUgZ2V0RWxlbWVudE91dGVySGVpZ2h0SW5QaXhlbHMoZWxlbWVudFJlZjogRWxlbWVudFJlZik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHsgbWFyZ2luVG9wLCBtYXJnaW5Cb3R0b20gfSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG5cbiAgICAgICAgcmV0dXJuIGVsZW1lbnQub2Zmc2V0SGVpZ2h0ICsgcGFyc2VJbnQobWFyZ2luVG9wKSArIHBhcnNlSW50KG1hcmdpbkJvdHRvbSk7XG4gICAgfVxufVxuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25MaXN0UG9zdGlvbiA9ICd0b3AtbGVmdCcgfCAndG9wLXJpZ2h0JyB8ICdib3R0b20tbGVmdCcgfCAnYm90dG9tLXJpZ2h0JztcbiIsIkBmb3IgKG5vdGlmaWNhdGlvblJlZiBvZiBub3RpZmljYXRpb25zJCB8IGFzeW5jOyB0cmFjayBub3RpZmljYXRpb25SZWY7IGxldCBpbmRleCA9ICRpbmRleCkge1xuICA8ZGl2ICNub3RpZmljYXRpb25cbiAgICBjbGFzcz1cIm5vdGlmaWNhdGlvblwiXG4gICAgW3N0eWxlLmhlaWdodC5weF09XCJub3RpZmljYXRpb25SZWYuaGVpZ2h0XCJcbiAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJub3RpZmljYXRpb25SZWYuYmFja2dyb3VuZENvbG9yXCJcbiAgICBbQG5vdGlmaWNhdGlvblN0YXRlXT5cbiAgICA8IS0tIE5vdGlmaWNhdGlvbiBDb250ZW50IC0tPlxuICAgIDxuZy1jb250YWluZXJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5vdGlmaWNhdGlvblJlZi50ZW1wbGF0ZVJlZlwiXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IG5vdGlmaWNhdGlvblJlZiwgZGF0YTogbm90aWZpY2F0aW9uUmVmLmRhdGEgfVwiPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbn1cbiJdfQ==