@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
177 lines • 48.5 kB
JavaScript
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { ContextRouteService, DynamicComponentAlert, DynamicComponentAlertAggregator, gettext } from '@c8y/ngx-components';
import { BehaviorSubject, Observable, Subject, fromEvent, pipe } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, shareReplay, switchMap, takeUntil } from 'rxjs/operators';
import { AlarmsViewService } from './alarms-view.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "./alarms-view.service";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@angular/common";
import * as i5 from "ngx-bootstrap/tooltip";
import * as i6 from "@ngx-translate/core";
import * as i7 from "./alarms-icon.component";
import * as i8 from "./alarm-list-custom-indicator/alarm-list-indicator.pipe";
export class AlarmsListComponent {
constructor(activatedRoute, alarmsViewService, contextRouteService, router) {
this.activatedRoute = activatedRoute;
this.alarmsViewService = alarmsViewService;
this.contextRouteService = contextRouteService;
this.router = router;
this.alarmBadgeTooltip = gettext('Number of occurrences`number of occurrences of alarm`. First occurrence {{ alarmFirstOccurrenceTime }} (device time).');
this.alarmLastOccurrenceLabel = gettext('Last occurrence of this alarm (device time).');
this.hasPermissions = true;
/**
* Input property for the currently applied type filters.
*/
this.typeFilters = [];
/**
* Input property for receiving load more mode.
*/
this.loadMoreMode = 'hidden';
/**
* Defines options, how the alarm list should be navigated if a user
* clicks on an alarm.
*/
this.navigationOptions = {
allowNavigationToAlarmsView: true,
alwaysNavigateToAllAlarms: false,
includeClearedQueryParams: false,
queryParamsHandling: 'merge'
};
/**
* Controls the visibility of the loading bar
* When set to `false`, the alarm list is displayed. When set to `true`, the opacity of alarms list is changed and a loading bar is shown.
*/
this.isInitialLoading = false;
/**
* Controls the visibility and functionality of some components
* When set to `true`, means the list is displayed in a split view layout:
* the list on the first column and the selected record detail on the second column (the cockpit
* alarms view for example)
* When set to false, the list is displayed as a standalone component, opening the detail will
* redirect to the alarms
*/
this.splitView = false;
/**
* Emits an instance of a selected alarm when one is chosen from the list.
*/
this.onSelectedAlarm = new EventEmitter();
/**
* Emits a boolean value indicating the scrolling state: true when the user starts scrolling, and false when the user reaches the top of the list.
*/
this.onScrollingStateChange = new EventEmitter();
/**
* Current alarm or last alarm marked as active by the routerLinkActive directive.
*/
this.activeAlarm$ = new BehaviorSubject(null);
this.activeChildParam$ = new Observable();
this.isScrolling = false;
/**
* Determines whether the c8y-loading component should be displayed.
* The loading component is shown when no alarms are displayed in the view or when the request is initial,
* as we don't want to see empty space on alarm list during loading.
*/
this.isEmptyListLoading = true;
this.alertAggregator = new DynamicComponentAlertAggregator();
this.mapAlarmLink = pipe(map((alarms) => alarms.map((alarm) => {
alarm.link = this.getRouterLink(alarm);
return alarm;
})));
this.destroy$ = new Subject();
this.HIDE_INTERVAL_COUNTDOWN_SCROLL = 50;
this.verifyIfFiltersMatchingAlarm();
}
/**
* Handles the change of the active route.
*
* @param isActive - A boolean indicating whether the route is active or not.
* @param scrollAnchor - The ListItemComponent used as a scroll anchor.
* @param alarm - The IAlarm object representing the active alarm.
*/
activeRouteChanged(isActive, scrollAnchor, alarm) {
if (isActive) {
scrollAnchor.element.nativeElement.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
this.activeAlarm$.next(alarm);
}
}
ngOnChanges(changes) {
if (this.alarms && changes.alarms) {
this.activeAlarm$.next(null);
this.isEmptyListLoading = !this.alarms?.data?.length;
}
if (changes.hasPermissions?.currentValue === false) {
this.alertAggregator.addAlerts(new DynamicComponentAlert({
type: 'system',
text: gettext("You don't have permission to view alarms.")
}));
}
}
ngAfterViewInit() {
if (this.alarmsViewService.isIntervalRefresh()) {
const scrollElement = this.innerScrollWrapper.nativeElement;
fromEvent(scrollElement, 'scroll')
.pipe(takeUntil(this.destroy$), debounceTime(300))
.subscribe((event) => {
const target = event.target;
this.isScrolling = this.shouldCountdownIntervalBeHidden(target);
this.onScrollingStateChange.emit(this.isScrolling);
});
}
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
onAlarmOpen(alarm) {
this.onSelectedAlarm.emit(alarm);
}
getRouterLink(alarm) {
if (this.navigationOptions.alwaysNavigateToAllAlarms) {
return this.alarmsViewService.getRouterLink(null, alarm);
}
const contextData = this.contextRouteService.getContextData(this.activatedRoute);
return this.alarmsViewService.getRouterLink(contextData, alarm);
}
shouldCountdownIntervalBeHidden(target) {
const scrollTopPixels = target.scrollTop;
return scrollTopPixels > this.HIDE_INTERVAL_COUNTDOWN_SCROLL;
}
verifyIfFiltersMatchingAlarm() {
this.activeChildParam$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd && this.activatedRoute.children.length > 0), switchMap(() => this.activatedRoute.children[0].params), map(params => params.id), distinctUntilChanged(), shareReplay(), takeUntil(this.destroy$));
// done to get the first navigation
this.activeChildParam$.subscribe();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmsListComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.AlarmsViewService }, { token: i3.ContextRouteService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmsListComponent, selector: "c8y-alarms-list", inputs: { alarms: "alarms", hasPermissions: "hasPermissions", typeFilters: "typeFilters", loadMoreMode: "loadMoreMode", navigationOptions: "navigationOptions", isInitialLoading: "isInitialLoading", splitView: "splitView" }, outputs: { onSelectedAlarm: "onSelectedAlarm", onScrollingStateChange: "onScrollingStateChange" }, viewQueries: [{ propertyName: "innerScrollWrapper", first: true, predicate: ["scrollWrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"inner-scroll\"\n [ngClass]=\"{ 'split-view__list bg-level-1': splitView, 'bg-component': !splitView }\"\n data-cy=\"c8y-alarms-list\"\n #scrollWrapper\n>\n <div\n class=\"flex-wrap flex-no-shrink sticky-top m-b-16\"\n [ngClass]=\"{\n 'separator-bottom card-header p-b-0': splitView,\n 'd-flex fit-w separator-top-bottom widget-bar p-l-16 p-r-16':\n !splitView && navigationOptions.allowNavigationToAlarmsView\n }\"\n >\n <div\n class=\"h4 card-title\"\n *ngIf=\"splitView\"\n >\n {{ 'Alarms list' | translate }}\n </div>\n <div\n [ngClass]=\"{ 'fit-w d-flex a-i-center gap-16': !splitView, 'fit-h-20 m-l-auto': splitView }\"\n >\n <ng-content></ng-content>\n </div>\n <!-- Loading -->\n <div\n class=\"fit-w overflow-hidden\"\n [ngClass]=\"{ 'p-t-16': splitView }\"\n >\n <div\n class=\"loading-bar\"\n style=\"z-index: 101\"\n [ngClass]=\"{ active: isInitialLoading && !isEmptyListLoading }\"\n ></div>\n </div>\n\n <div\n class=\"alert alert-warning\"\n role=\"alert\"\n translate\n *ngIf=\"\n !isEmptyListLoading &&\n (activeChildParam$ | async) &&\n (activeAlarm$ | async)?.id !== (activeChildParam$ | async)\n \"\n >\n The selected alarm is not currently in the list, change your filter.\n </div>\n </div>\n <c8y-list-group\n class=\"p-r-16 interactive\"\n [ngStyle]=\"{ opacity: isInitialLoading && !isEmptyListLoading ? 0.2 : 1 }\"\n style=\"transition: opacity 0.15s linear\"\n data-cy=\"c8y-alarm-list--group\"\n >\n <c8y-li-timeline\n class=\"pointer\"\n role=\"button\"\n data-cy=\"c8y-alarm-list--timeline-repeat\"\n *c8yFor=\"let alarm of alarms; let i = index; pipe: mapAlarmLink; loadMore: loadMoreMode\"\n [routerLink]=\"navigationOptions.allowNavigationToAlarmsView ? alarm.link : null\"\n routerLinkActive=\"active\"\n [queryParamsHandling]=\"navigationOptions.queryParamsHandling\"\n (isActiveChange)=\"activeRouteChanged($event, liScrollAnchor, alarm)\"\n (click)=\"onAlarmOpen(alarm)\"\n [queryParams]=\"\n navigationOptions.includeClearedQueryParams\n ? { showCleared: alarm.status === 'CLEARED' }\n : {}\n \"\n >\n <span\n [attr.aria-label]=\"alarmLastOccurrenceLabel | translate\"\n [tooltip]=\"alarmLastOccurrenceLabel | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n >\n {{ alarm.time | c8yDate: 'mediumDate' }}\n {{ alarm.time | c8yDate: 'mediumTime' }}\n </span>\n <c8y-li\n style=\"scroll-margin-top: 56px\"\n #liScrollAnchor\n >\n <c8y-li-icon class=\"a-s-start\">\n <div class=\"alarm-icons\">\n <c8y-alarms-icon [typeFilters]=\"typeFilters\" [alarm]=\"alarm\"></c8y-alarms-icon>\n </div>\n <button\n class=\"btn-clean text-center\"\n [attr.aria-label]=\"\n alarmBadgeTooltip\n | translate\n : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n \"\n [tooltip]=\"\n alarmBadgeTooltip\n | translate\n : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n \"\n placement=\"right\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"alarm.firstOccurrenceTime\"\n (click)=\"$event.stopPropagation()\"\n [delay]=\"500\"\n >\n <span\n class=\"badge badge-info\"\n *ngIf=\"alarm.count > 1\"\n >\n {{ alarm.count }}\n </span>\n </button>\n </c8y-li-icon>\n <c8y-li-body class=\"a-s-stretch\">\n <div class=\"d-flex a-i-start fit-h\">\n <div class=\"min-width-0 flex-grow\">\n <p class=\"text-truncate-wrap p-b-4\">\n {{ alarm.text | translate }}\n </p>\n <div class=\"d-flex\">\n <p\n class=\"small text-muted text-truncate flex-grow\"\n [title]=\"alarm.source.name\"\n >\n <i [c8yIcon]=\"'exchange'\"></i>\n {{ alarm.source.name }}\n </p>\n <div class=\"d-flex\">\n <div\n [title]=\"item.title | translate\"\n *ngFor=\"let item of alarm | alarmListIndicator | async\"\n >\n <i\n [class]=\"item.class\"\n [c8yIcon]=\"item.icon\"\n ></i>\n </div>\n </div>\n </div>\n </div>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n <c8y-loading *ngIf=\"isInitialLoading && isEmptyListLoading\"></c8y-loading>\n <div\n class=\"p-relative p-l-24\"\n *ngIf=\"isEmptyListLoading && !isInitialLoading\"\n >\n <c8y-ui-empty-state\n [icon]=\"'c8y-alert-idle'\"\n [title]=\"'No alarms to display.' | translate\"\n data-cy=\"alarm-list--empty-state\"\n *ngIf=\"hasPermissions; else alertsA\"\n >\n <p c8y-guide-docs>\n <small\n translate\n ngNonBindable\n >\n Find out more in the\n <a\n c8y-guide-href=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n >\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n </c8y-list-group>\n</div>\n\n<ng-template #alertsA>\n <c8y-dynamic-component-alerts [alerts]=\"alertAggregator\"></c8y-dynamic-component-alerts>\n</ng-template>\n", dependencies: [{ kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: i3.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i3.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "component", type: i3.DynamicComponentAlertsComponent, selector: "c8y-dynamic-component-alerts", inputs: ["alerts"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: i5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: i6.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: i7.AlarmsIconComponent, selector: "c8y-alarms-icon", inputs: ["alarm", "typeFilters"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "pipe", type: i8.AlarmListIndicatorPipe, name: "alarmListIndicator" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmsListComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarms-list', template: "<div\n class=\"inner-scroll\"\n [ngClass]=\"{ 'split-view__list bg-level-1': splitView, 'bg-component': !splitView }\"\n data-cy=\"c8y-alarms-list\"\n #scrollWrapper\n>\n <div\n class=\"flex-wrap flex-no-shrink sticky-top m-b-16\"\n [ngClass]=\"{\n 'separator-bottom card-header p-b-0': splitView,\n 'd-flex fit-w separator-top-bottom widget-bar p-l-16 p-r-16':\n !splitView && navigationOptions.allowNavigationToAlarmsView\n }\"\n >\n <div\n class=\"h4 card-title\"\n *ngIf=\"splitView\"\n >\n {{ 'Alarms list' | translate }}\n </div>\n <div\n [ngClass]=\"{ 'fit-w d-flex a-i-center gap-16': !splitView, 'fit-h-20 m-l-auto': splitView }\"\n >\n <ng-content></ng-content>\n </div>\n <!-- Loading -->\n <div\n class=\"fit-w overflow-hidden\"\n [ngClass]=\"{ 'p-t-16': splitView }\"\n >\n <div\n class=\"loading-bar\"\n style=\"z-index: 101\"\n [ngClass]=\"{ active: isInitialLoading && !isEmptyListLoading }\"\n ></div>\n </div>\n\n <div\n class=\"alert alert-warning\"\n role=\"alert\"\n translate\n *ngIf=\"\n !isEmptyListLoading &&\n (activeChildParam$ | async) &&\n (activeAlarm$ | async)?.id !== (activeChildParam$ | async)\n \"\n >\n The selected alarm is not currently in the list, change your filter.\n </div>\n </div>\n <c8y-list-group\n class=\"p-r-16 interactive\"\n [ngStyle]=\"{ opacity: isInitialLoading && !isEmptyListLoading ? 0.2 : 1 }\"\n style=\"transition: opacity 0.15s linear\"\n data-cy=\"c8y-alarm-list--group\"\n >\n <c8y-li-timeline\n class=\"pointer\"\n role=\"button\"\n data-cy=\"c8y-alarm-list--timeline-repeat\"\n *c8yFor=\"let alarm of alarms; let i = index; pipe: mapAlarmLink; loadMore: loadMoreMode\"\n [routerLink]=\"navigationOptions.allowNavigationToAlarmsView ? alarm.link : null\"\n routerLinkActive=\"active\"\n [queryParamsHandling]=\"navigationOptions.queryParamsHandling\"\n (isActiveChange)=\"activeRouteChanged($event, liScrollAnchor, alarm)\"\n (click)=\"onAlarmOpen(alarm)\"\n [queryParams]=\"\n navigationOptions.includeClearedQueryParams\n ? { showCleared: alarm.status === 'CLEARED' }\n : {}\n \"\n >\n <span\n [attr.aria-label]=\"alarmLastOccurrenceLabel | translate\"\n [tooltip]=\"alarmLastOccurrenceLabel | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n >\n {{ alarm.time | c8yDate: 'mediumDate' }}\n {{ alarm.time | c8yDate: 'mediumTime' }}\n </span>\n <c8y-li\n style=\"scroll-margin-top: 56px\"\n #liScrollAnchor\n >\n <c8y-li-icon class=\"a-s-start\">\n <div class=\"alarm-icons\">\n <c8y-alarms-icon [typeFilters]=\"typeFilters\" [alarm]=\"alarm\"></c8y-alarms-icon>\n </div>\n <button\n class=\"btn-clean text-center\"\n [attr.aria-label]=\"\n alarmBadgeTooltip\n | translate\n : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n \"\n [tooltip]=\"\n alarmBadgeTooltip\n | translate\n : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n \"\n placement=\"right\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"alarm.firstOccurrenceTime\"\n (click)=\"$event.stopPropagation()\"\n [delay]=\"500\"\n >\n <span\n class=\"badge badge-info\"\n *ngIf=\"alarm.count > 1\"\n >\n {{ alarm.count }}\n </span>\n </button>\n </c8y-li-icon>\n <c8y-li-body class=\"a-s-stretch\">\n <div class=\"d-flex a-i-start fit-h\">\n <div class=\"min-width-0 flex-grow\">\n <p class=\"text-truncate-wrap p-b-4\">\n {{ alarm.text | translate }}\n </p>\n <div class=\"d-flex\">\n <p\n class=\"small text-muted text-truncate flex-grow\"\n [title]=\"alarm.source.name\"\n >\n <i [c8yIcon]=\"'exchange'\"></i>\n {{ alarm.source.name }}\n </p>\n <div class=\"d-flex\">\n <div\n [title]=\"item.title | translate\"\n *ngFor=\"let item of alarm | alarmListIndicator | async\"\n >\n <i\n [class]=\"item.class\"\n [c8yIcon]=\"item.icon\"\n ></i>\n </div>\n </div>\n </div>\n </div>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n <c8y-loading *ngIf=\"isInitialLoading && isEmptyListLoading\"></c8y-loading>\n <div\n class=\"p-relative p-l-24\"\n *ngIf=\"isEmptyListLoading && !isInitialLoading\"\n >\n <c8y-ui-empty-state\n [icon]=\"'c8y-alert-idle'\"\n [title]=\"'No alarms to display.' | translate\"\n data-cy=\"alarm-list--empty-state\"\n *ngIf=\"hasPermissions; else alertsA\"\n >\n <p c8y-guide-docs>\n <small\n translate\n ngNonBindable\n >\n Find out more in the\n <a\n c8y-guide-href=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n >\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n </c8y-list-group>\n</div>\n\n<ng-template #alertsA>\n <c8y-dynamic-component-alerts [alerts]=\"alertAggregator\"></c8y-dynamic-component-alerts>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.AlarmsViewService }, { type: i3.ContextRouteService }, { type: i1.Router }], propDecorators: { alarms: [{
type: Input
}], hasPermissions: [{
type: Input
}], typeFilters: [{
type: Input
}], loadMoreMode: [{
type: Input
}], navigationOptions: [{
type: Input
}], isInitialLoading: [{
type: Input
}], splitView: [{
type: Input
}], onSelectedAlarm: [{
type: Output
}], onScrollingStateChange: [{
type: Output
}], innerScrollWrapper: [{
type: ViewChild,
args: ['scrollWrapper']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxhcm1zLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWxhcm1zL2FsYXJtcy1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL2FsYXJtcy9hbGFybXMtbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFFTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsK0JBQStCLEVBRy9CLE9BQU8sRUFDUixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzdFLE9BQU8sRUFDTCxZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLE1BQU0sRUFDTixHQUFHLEVBQ0gsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7Ozs7OztBQVExRCxNQUFNLE9BQU8sbUJBQW1CO0lBbUc5QixZQUNVLGNBQThCLEVBQzlCLGlCQUFvQyxFQUNwQyxtQkFBd0MsRUFDeEMsTUFBYztRQUhkLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQXRHZixzQkFBaUIsR0FBRyxPQUFPLENBQ2xDLHVIQUF1SCxDQUN4SCxD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d0luaXQsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIE5hdmlnYXRpb25FbmQsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBJQWxhcm0sIElSZXN1bHRMaXN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHtcbiAgQ29udGV4dFJvdXRlU2VydmljZSxcbiAgRHluYW1pY0NvbXBvbmVudEFsZXJ0LFxuICBEeW5hbWljQ29tcG9uZW50QWxlcnRBZ2dyZWdhdG9yLFxuICBMaXN0SXRlbUNvbXBvbmVudCxcbiAgTG9hZE1vcmVNb2RlLFxuICBnZXR0ZXh0XG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBmcm9tRXZlbnQsIHBpcGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGRlYm91bmNlVGltZSxcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIGZpbHRlcixcbiAgbWFwLFxuICBzaGFyZVJlcGxheSxcbiAgc3dpdGNoTWFwLFxuICB0YWtlVW50aWxcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQWxhcm1zVmlld1NlcnZpY2UgfSBmcm9tICcuL2FsYXJtcy12aWV3LnNlcnZpY2UnO1xuaW1wb3J0IHsgQWxhcm1OYXZpZ2F0aW9uT3B0aW9ucyB9IGZyb20gJy4vYWxhcm1zLm1vZGVsJztcbmltcG9ydCB7IEFsYXJtRGV0YWlscyB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvYWxhcm0tZXZlbnQtc2VsZWN0b3InO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktYWxhcm1zLWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vYWxhcm1zLWxpc3QuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIEFsYXJtc0xpc3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHJlYWRvbmx5IGFsYXJtQmFkZ2VUb29sdGlwID0gZ2V0dGV4dChcbiAgICAnTnVtYmVyIG9mIG9jY3VycmVuY2VzYG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBhbGFybWAuIEZpcnN0IG9jY3VycmVuY2Uge3sgYWxhcm1GaXJzdE9jY3VycmVuY2VUaW1lIH19IChkZXZpY2UgdGltZSkuJ1xuICApO1xuICByZWFkb25seSBhbGFybUxhc3RPY2N1cnJlbmNlTGFiZWwgPSBnZXR0ZXh0KCdMYXN0IG9jY3VycmVuY2Ugb2YgdGhpcyBhbGFybSAoZGV2aWNlIHRpbWUpLicpO1xuXG4gIC8qKlxuICAgKiBJbnB1dCBwcm9wZXJ0eSBmb3IgcmVjZWl2aW5nIGEgbGlzdCBvZiBhbGFybXMuXG4gICAqL1xuICBASW5wdXQoKVxuICBhbGFybXM6IElSZXN1bHRMaXN0PElBbGFybSAmIHsgbGluaz86IHN0cmluZyB9PjtcblxuICBASW5wdXQoKSBoYXNQZXJtaXNzaW9ucyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIElucHV0IHByb3BlcnR5IGZvciB0aGUgY3VycmVudGx5IGFwcGxpZWQgdHlwZSBmaWx0ZXJzLlxuICAgKi9cbiAgQElucHV0KClcbiAgdHlwZUZpbHRlcnM6IEFsYXJtRGV0YWlsc1tdID0gW107XG5cbiAgLyoqXG4gICAqIElucHV0IHByb3BlcnR5IGZvciByZWNlaXZpbmcgbG9hZCBtb3JlIG1vZGUuXG4gICAqL1xuICBASW5wdXQoKVxuICBsb2FkTW9yZU1vZGU6IExvYWRNb3JlTW9kZSA9ICdoaWRkZW4nO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIG9wdGlvbnMsIGhvdyB0aGUgYWxhcm0gbGlzdCBzaG91bGQgYmUgbmF2aWdhdGVkIGlmIGEgdXNlclxuICAgKiBjbGlja3Mgb24gYW4gYWxhcm0uXG4gICAqL1xuICBASW5wdXQoKVxuICBuYXZpZ2F0aW9uT3B0aW9uczogQWxhcm1OYXZpZ2F0aW9uT3B0aW9ucyA9IHtcbiAgICBhbGxvd05hdmlnYXRpb25Ub0FsYXJtc1ZpZXc6IHRydWUsXG4gICAgYWx3YXlzTmF2aWdhdGVUb0FsbEFsYXJtczogZmFsc2UsXG4gICAgaW5jbHVkZUNsZWFyZWRRdWVyeVBhcmFtczogZmFsc2UsXG4gICAgcXVlcnlQYXJhbXNIYW5kbGluZzogJ21lcmdlJ1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb250cm9scyB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgbG9hZGluZyBiYXJcbiAgICogV2hlbiBzZXQgdG8gYGZhbHNlYCwgdGhlIGFsYXJtIGxpc3QgaXMgZGlzcGxheWVkLiBXaGVuIHNldCB0byBgdHJ1ZWAsIHRoZSBvcGFjaXR5IG9mIGFsYXJtcyBsaXN0IGlzIGNoYW5nZWQgYW5kIGEgbG9hZGluZyBiYXIgaXMgc2hvd24uXG4gICAqL1xuICBASW5wdXQoKVxuICBpc0luaXRpYWxMb2FkaW5nID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIENvbnRyb2xzIHRoZSB2aXNpYmlsaXR5IGFuZCBmdW5jdGlvbmFsaXR5IG9mIHNvbWUgY29tcG9uZW50c1xuICAgKiBXaGVuIHNldCB0byBgdHJ1ZWAsIG1lYW5zIHRoZSBsaXN0IGlzIGRpc3BsYXllZCBpbiBhIHNwbGl0IHZpZXcgbGF5b3V0OlxuICAgKiB0aGUgbGlzdCBvbiB0aGUgZmlyc3QgY29sdW1uIGFuZCB0aGUgc2VsZWN0ZWQgcmVjb3JkIGRldGFpbCBvbiB0aGUgc2Vjb25kIGNvbHVtbiAodGhlIGNvY2twaXRcbiAgICogYWxhcm1zIHZpZXcgZm9yIGV4YW1wbGUpXG4gICAqIFdoZW4gc2V0IHRvIGZhbHNlLCB0aGUgbGlzdCBpcyBkaXNwbGF5ZWQgYXMgYSBzdGFuZGFsb25lIGNvbXBvbmVudCwgb3BlbmluZyB0aGUgZGV0YWlsIHdpbGxcbiAgICogcmVkaXJlY3QgdG8gdGhlIGFsYXJtc1xuICAgKi9cbiAgQElucHV0KClcbiAgc3BsaXRWaWV3ID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEVtaXRzIGFuIGluc3RhbmNlIG9mIGEgc2VsZWN0ZWQgYWxhcm0gd2hlbiBvbmUgaXMgY2hvc2VuIGZyb20gdGhlIGxpc3QuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgb25TZWxlY3RlZEFsYXJtID0gbmV3IEV2ZW50RW1pdHRlcjxJQWxhcm0+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHRoZSBzY3JvbGxpbmcgc3RhdGU6IHRydWUgd2hlbiB0aGUgdXNlciBzdGFydHMgc2Nyb2xsaW5nLCBhbmQgZmFsc2Ugd2hlbiB0aGUgdXNlciByZWFjaGVzIHRoZSB0b3Agb2YgdGhlIGxpc3QuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgb25TY3JvbGxpbmdTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKipcbiAgICogQ3VycmVudCBhbGFybSBvciBsYXN0IGFsYXJtIG1hcmtlZCBhcyBhY3RpdmUgYnkgdGhlIHJvdXRlckxpbmtBY3RpdmUgZGlyZWN0aXZlLlxuICAgKi9cbiAgYWN0aXZlQWxhcm0kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJQWxhcm0+KG51bGwpO1xuICBhY3RpdmVDaGlsZFBhcmFtJCA9IG5ldyBPYnNlcnZhYmxlPHN0cmluZz4oKTtcblxuICBAVmlld0NoaWxkKCdzY3JvbGxXcmFwcGVyJylcbiAgaW5uZXJTY3JvbGxXcmFwcGVyOiBFbGVtZW50UmVmO1xuXG4gIGlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGM4eS1sb2FkaW5nIGNvbXBvbmVudCBzaG91bGQgYmUgZGlzcGxheWVkLlxuICAgKiBUaGUgbG9hZGluZyBjb21wb25lbnQgaXMgc2hvd24gd2hlbiBubyBhbGFybXMgYXJlIGRpc3BsYXllZCBpbiB0aGUgdmlldyBvciB3aGVuIHRoZSByZXF1ZXN0IGlzIGluaXRpYWwsXG4gICAqIGFzIHdlIGRvbid0IHdhbnQgdG8gc2VlIGVtcHR5IHNwYWNlIG9uIGFsYXJtIGxpc3QgZHVyaW5nIGxvYWRpbmcuXG4gICAqL1xuICBpc0VtcHR5TGlzdExvYWRpbmcgPSB0cnVlO1xuXG4gIGFsZXJ0QWdncmVnYXRvciA9IG5ldyBEeW5hbWljQ29tcG9uZW50QWxlcnRBZ2dyZWdhdG9yKCk7XG5cbiAgbWFwQWxhcm1MaW5rID0gcGlwZShcbiAgICBtYXAoKGFsYXJtczogSUFsYXJtW10pID0+XG4gICAgICBhbGFybXMubWFwKChhbGFybTogSUFsYXJtKSA9PiB7XG4gICAgICAgIGFsYXJtLmxpbmsgPSB0aGlzLmdldFJvdXRlckxpbmsoYWxhcm0pO1xuICAgICAgICByZXR1cm4gYWxhcm07XG4gICAgICB9KVxuICAgIClcbiAgKTtcblxuICBwcml2YXRlIGRlc3Ryb3kkOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBISURFX0lOVEVSVkFMX0NPVU5URE9XTl9TQ1JPTEwgPSA1MDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBwcml2YXRlIGFsYXJtc1ZpZXdTZXJ2aWNlOiBBbGFybXNWaWV3U2VydmljZSxcbiAgICBwcml2YXRlIGNvbnRleHRSb3V0ZVNlcnZpY2U6IENvbnRleHRSb3V0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlclxuICApIHtcbiAgICB0aGlzLnZlcmlmeUlmRmlsdGVyc01hdGNoaW5nQWxhcm0oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBjaGFuZ2Ugb2YgdGhlIGFjdGl2ZSByb3V0ZS5cbiAgICpcbiAgICogQHBhcmFtIGlzQWN0aXZlIC0gQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgcm91dGUgaXMgYWN0aXZlIG9yIG5vdC5cbiAgICogQHBhcmFtIHNjcm9sbEFuY2hvciAtIFRoZSBMaXN0SXRlbUNvbXBvbmVudCB1c2VkIGFzIGEgc2Nyb2xsIGFuY2hvci5cbiAgICogQHBhcmFtIGFsYXJtIC0gVGhlIElBbGFybSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBhY3RpdmUgYWxhcm0uXG4gICAqL1xuICBhY3RpdmVSb3V0ZUNoYW5nZWQoaXNBY3RpdmU6IGJvb2xlYW4sIHNjcm9sbEFuY2hvcjogTGlzdEl0ZW1Db21wb25lbnQsIGFsYXJtOiBJQWxhcm0pOiB2b2lkIHtcbiAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgIHNjcm9sbEFuY2hvci5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSW50b1ZpZXcoe1xuICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCcsXG4gICAgICAgIGJsb2NrOiAnbmVhcmVzdCdcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hY3RpdmVBbGFybSQubmV4dChhbGFybSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFsYXJtcyAmJiBjaGFuZ2VzLmFsYXJtcykge1xuICAgICAgdGhpcy5hY3RpdmVBbGFybSQubmV4dChudWxsKTtcbiAgICAgIHRoaXMuaXNFbXB0eUxpc3RMb2FkaW5nID0gIXRoaXMuYWxhcm1zPy5kYXRhPy5sZW5ndGg7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMuaGFzUGVybWlzc2lvbnM/LmN1cnJlbnRWYWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuYWxlcnRBZ2dyZWdhdG9yLmFkZEFsZXJ0cyhcbiAgICAgICAgbmV3IER5bmFtaWNDb21wb25lbnRBbGVydCh7XG4gICAgICAgICAgdHlwZTogJ3N5c3RlbScsXG4gICAgICAgICAgdGV4dDogZ2V0dGV4dChcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gdG8gdmlldyBhbGFybXMuXCIpXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbGFybXNWaWV3U2VydmljZS5pc0ludGVydmFsUmVmcmVzaCgpKSB7XG4gICAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5pbm5lclNjcm9sbFdyYXBwZXIubmF0aXZlRWxlbWVudDtcbiAgICAgIGZyb21FdmVudChzY3JvbGxFbGVtZW50LCAnc2Nyb2xsJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLCBkZWJvdW5jZVRpbWUoMzAwKSlcbiAgICAgICAgLnN1YnNjcmliZSgoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgIHRoaXMuaXNTY3JvbGxpbmcgPSB0aGlzLnNob3VsZENvdW50ZG93bkludGVydmFsQmVIaWRkZW4odGFyZ2V0KTtcbiAgICAgICAgICB0aGlzLm9uU2Nyb2xsaW5nU3RhdGVDaGFuZ2UuZW1pdCh0aGlzLmlzU2Nyb2xsaW5nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgb25BbGFybU9wZW4oYWxhcm06IElBbGFybSk6IHZvaWQge1xuICAgIHRoaXMub25TZWxlY3RlZEFsYXJtLmVtaXQoYWxhcm0pO1xuICB9XG5cbiAgZ2V0Um91dGVyTGluayhhbGFybTogSUFsYXJtKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5uYXZpZ2F0aW9uT3B0aW9ucy5hbHdheXNOYXZpZ2F0ZVRvQWxsQWxhcm1zKSB7XG4gICAgICByZXR1cm4gdGhpcy5hbGFybXNWaWV3U2VydmljZS5nZXRSb3V0ZXJMaW5rKG51bGwsIGFsYXJtKTtcbiAgICB9XG4gICAgY29uc3QgY29udGV4dERhdGEgPSB0aGlzLmNvbnRleHRSb3V0ZVNlcnZpY2UuZ2V0Q29udGV4dERhdGEodGhpcy5hY3RpdmF0ZWRSb3V0ZSk7XG4gICAgcmV0dXJuIHRoaXMuYWxhcm1zVmlld1NlcnZpY2UuZ2V0Um91dGVyTGluayhjb250ZXh0RGF0YSwgYWxhcm0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG91bGRDb3VudGRvd25JbnRlcnZhbEJlSGlkZGVuKHRhcmdldDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBzY3JvbGxUb3BQaXhlbHMgPSB0YXJnZXQuc2Nyb2xsVG9wO1xuICAgIHJldHVybiBzY3JvbGxUb3BQaXhlbHMgPiB0aGlzLkhJREVfSU5URVJWQUxfQ09VTlRET1dOX1NDUk9MTDtcbiAgfVxuXG4gIHByaXZhdGUgdmVyaWZ5SWZGaWx0ZXJzTWF0Y2hpbmdBbGFybSgpIHtcbiAgICB0aGlzLmFjdGl2ZUNoaWxkUGFyYW0kID0gdGhpcy5yb3V0ZXIuZXZlbnRzLnBpcGUoXG4gICAgICBmaWx0ZXIoZSA9PiBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCAmJiB0aGlzLmFjdGl2YXRlZFJvdXRlLmNoaWxkcmVuLmxlbmd0aCA+IDApLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuYWN0aXZhdGVkUm91dGUuY2hpbGRyZW5bMF0ucGFyYW1zKSxcbiAgICAgIG1hcChwYXJhbXMgPT4gcGFyYW1zLmlkKSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzaGFyZVJlcGxheSgpLFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgKTtcblxuICAgIC8vIGRvbmUgdG8gZ2V0IHRoZSBmaXJzdCBuYXZpZ2F0aW9uXG4gICAgdGhpcy5hY3RpdmVDaGlsZFBhcmFtJC5zdWJzY3JpYmUoKTtcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImlubmVyLXNjcm9sbFwiXG4gIFtuZ0NsYXNzXT1cInsgJ3NwbGl0LXZpZXdfX2xpc3QgYmctbGV2ZWwtMSc6IHNwbGl0VmlldywgJ2JnLWNvbXBvbmVudCc6ICFzcGxpdFZpZXcgfVwiXG4gIGRhdGEtY3k9XCJjOHktYWxhcm1zLWxpc3RcIlxuICAjc2Nyb2xsV3JhcHBlclxuPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJmbGV4LXdyYXAgZmxleC1uby1zaHJpbmsgc3RpY2t5LXRvcCBtLWItMTZcIlxuICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICdzZXBhcmF0b3ItYm90dG9tIGNhcmQtaGVhZGVyIHAtYi0wJzogc3BsaXRWaWV3LFxuICAgICAgJ2QtZmxleCBmaXQtdyBzZXBhcmF0b3ItdG9wLWJvdHRvbSB3aWRnZXQtYmFyIHAtbC0xNiBwLXItMTYnOlxuICAgICAgICAhc3BsaXRWaWV3ICYmIG5hdmlnYXRpb25PcHRpb25zLmFsbG93TmF2aWdhdGlvblRvQWxhcm1zVmlld1xuICAgIH1cIlxuICA+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJoNCBjYXJkLXRpdGxlXCJcbiAgICAgICpuZ0lmPVwic3BsaXRWaWV3XCJcbiAgICA+XG4gICAgICB7eyAnQWxhcm1zIGxpc3QnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgW25nQ2xhc3NdPVwieyAnZml0LXcgZC1mbGV4IGEtaS1jZW50ZXIgZ2FwLTE2JzogIXNwbGl0VmlldywgJ2ZpdC1oLTIwIG0tbC1hdXRvJzogc3BsaXRWaWV3IH1cIlxuICAgID5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgICA8IS0tICBMb2FkaW5nIC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiZml0LXcgb3ZlcmZsb3ctaGlkZGVuXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ3AtdC0xNic6IHNwbGl0VmlldyB9XCJcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwibG9hZGluZy1iYXJcIlxuICAgICAgICBzdHlsZT1cInotaW5kZXg6IDEwMVwiXG4gICAgICAgIFtuZ0NsYXNzXT1cInsgYWN0aXZlOiBpc0luaXRpYWxMb2FkaW5nICYmICFpc0VtcHR5TGlzdExvYWRpbmcgfVwiXG4gICAgICA+PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImFsZXJ0IGFsZXJ0LXdhcm5pbmdcIlxuICAgICAgcm9sZT1cImFsZXJ0XCJcbiAgICAgIHRyYW5zbGF0ZVxuICAgICAgKm5nSWY9XCJcbiAgICAgICAgIWlzRW1wdHlMaXN0TG9hZGluZyAmJlxuICAgICAgICAoYWN0aXZlQ2hpbGRQYXJhbSQgfCBhc3luYykgJiZcbiAgICAgICAgKGFjdGl2ZUFsYXJtJCB8IGFzeW5jKT8uaWQgIT09IChhY3RpdmVDaGlsZFBhcmFtJCB8IGFzeW5jKVxuICAgICAgXCJcbiAgICA+XG4gICAgICBUaGUgc2VsZWN0ZWQgYWxhcm0gaXMgbm90IGN1cnJlbnRseSBpbiB0aGUgbGlzdCwgY2hhbmdlIHlvdXIgZmlsdGVyLlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGM4eS1saXN0LWdyb3VwXG4gICAgY2xhc3M9XCJwLXItMTYgaW50ZXJhY3RpdmVcIlxuICAgIFtuZ1N0eWxlXT1cInsgb3BhY2l0eTogaXNJbml0aWFsTG9hZGluZyAmJiAhaXNFbXB0eUxpc3RMb2FkaW5nID8gMC4yIDogMSB9XCJcbiAgICBzdHlsZT1cInRyYW5zaXRpb246IG9wYWNpdHkgMC4xNXMgbGluZWFyXCJcbiAgICBkYXRhLWN5PVwiYzh5LWFsYXJtLWxpc3QtLWdyb3VwXCJcbiAgPlxuICAgIDxjOHktbGktdGltZWxpbmVcbiAgICAgIGNsYXNzPVwicG9pbnRlclwiXG4gICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgIGRhdGEtY3k9XCJjOHktYWxhcm0tbGlzdC0tdGltZWxpbmUtcmVwZWF0XCJcbiAgICAgICpjOHlGb3I9XCJsZXQgYWxhcm0gb2YgYWxhcm1zOyBsZXQgaSA9IGluZGV4OyBwaXBlOiBtYXBBbGFybUxpbms7IGxvYWRNb3JlOiBsb2FkTW9yZU1vZGVcIlxuICAgICAgW3JvdXRlckxpbmtdPVwibmF2aWdhdGlvbk9wdGlvbnMuYWxsb3dOYXZpZ2F0aW9uVG9BbGFybXNWaWV3ID8gYWxhcm0ubGluayA6IG51bGxcIlxuICAgICAgcm91dGVyTGlua0FjdGl2ZT1cImFjdGl2ZVwiXG4gICAgICBbcXVlcnlQYXJhbXNIYW5kbGluZ109XCJuYXZpZ2F0aW9uT3B0aW9ucy5xdWVyeVBhcmFtc0hhbmRsaW5nXCJcbiAgICAgIChpc0FjdGl2ZUNoYW5nZSk9XCJhY3RpdmVSb3V0ZUNoYW5nZWQoJGV2ZW50LCBsaVNjcm9sbEFuY2hvciwgYWxhcm0pXCJcbiAgICAgIChjbGljayk9XCJvbkFsYXJtT3BlbihhbGFybSlcIlxuICAgICAgW3F1ZXJ5UGFyYW1zXT1cIlxuICAgICAgICBuYXZpZ2F0aW9uT3B0aW9ucy5pbmNsdWRlQ2xlYXJlZFF1ZXJ5UGFyYW1zXG4gICAgICAgICAgPyB7IHNob3dDbGVhcmVkOiBhbGFybS5zdGF0dXMgPT09ICdDTEVBUkVEJyB9XG4gICAgICAgICAgOiB7fVxuICAgICAgXCJcbiAgICA+XG4gICAgICA8c3BhblxuICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFsYXJtTGFzdE9jY3VycmVuY2VMYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFt0b29sdGlwXT1cImFsYXJtTGFzdE9jY3VycmVuY2VMYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIHBsYWNlbWVudD1cInJpZ2h0XCJcbiAgICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAgIFtkZWxheV09XCI1MDBcIlxuICAgICAgPlxuICAgICAgICB7eyBhbGFybS50aW1lIHwgYzh5RGF0ZTogJ21lZGl1bURhdGUnIH19XG4gICAgICAgIHt7IGFsYXJtLnRpbWUgfCBjOHlEYXRlOiAnbWVkaXVtVGltZScgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxjOHktbGlcbiAgICAgICAgc3R5bGU9XCJzY3JvbGwtbWFyZ2luLXRvcDogNTZweFwiXG4gICAgICAgICNsaVNjcm9sbEFuY2hvclxuICAgICAgPlxuICAgICAgICA8Yzh5LWxpLWljb24gY2xhc3M9XCJhLXMtc3RhcnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxhcm0taWNvbnNcIj5cbiAgICAgICAgICAgIDxjOHktYWxhcm1zLWljb24gW3R5cGVGaWx0ZXJzXT1cInR5cGVGaWx0ZXJzXCIgW2FsYXJtXT1cImFsYXJtXCI+PC9jOHktYWxhcm1zLWljb24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJidG4tY2xlYW4gdGV4dC1jZW50ZXJcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJcbiAgICAgICAgICAgICAgYWxhcm1CYWRnZVRvb2x0aXBcbiAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgOiB7IGFsYXJtRmlyc3RPY2N1cnJlbmNlVGltZTogYWxhcm0uZmlyc3RPY2N1cnJlbmNlVGltZSB8IGM4eURhdGU6ICdtZWRpdW0nIH1cbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBbdG9vbHRpcF09XCJcbiAgICAgICAgICAgICAgYWxhcm1CYWRnZVRvb2x0aXBcbiAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgOiB7IGFsYXJtRmlyc3RPY2N1cnJlbmNlVGltZTogYWxhcm0uZmlyc3RPY2N1cnJlbmNlVGltZSB8IGM4eURhdGU6ICdtZWRpdW0nIH1cbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBwbGFjZW1lbnQ9XCJyaWdodFwiXG4gICAgICAgICAgICBjb250YWluZXI9XCJib2R5XCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgKm5nSWY9XCJhbGFybS5maXJzdE9jY3VycmVuY2VUaW1lXCJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgW2RlbGF5XT1cIjUwMFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgY2xhc3M9XCJiYWRnZSBiYWRnZS1pbmZvXCJcbiAgICAgICAgICAgICAgKm5nSWY9XCJhbGFybS5jb3VudCA+IDFcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBhbGFybS5jb3VudCB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2M4eS1saS1pY29uPlxuICAgICAgICA8Yzh5LWxpLWJvZHkgY2xhc3M9XCJhLXMtc3RyZXRjaFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYS1pLXN0YXJ0IGZpdC1oXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluLXdpZHRoLTAgZmxleC1ncm93XCI+XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC10cnVuY2F0ZS13cmFwIHAtYi00XCI+XG4gICAgICAgICAgICAgICAge3sgYWxhcm0udGV4dCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICAgICAgICAgICAgICA8cFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzbWFsbCB0ZXh0LW11dGVkIHRleHQtdHJ1bmNhdGUgZmxleC1ncm93XCJcbiAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJhbGFybS5zb3VyY2UubmFtZVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGkgW2M4eUljb25dPVwiJ2V4Y2hhbmdlJ1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgIHt7IGFsYXJtLnNvdXJjZS5uYW1lIH19XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIml0ZW0udGl0bGUgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBhbGFybSB8IGFsYXJtTGlzdEluZGljYXRvciB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGlcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiaXRlbS5jbGFzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgW2M4eUljb25dPVwiaXRlbS5pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvaT5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2M4eS1saS1ib2R5PlxuICAgICAgPC9jOHktbGk+XG4gICAgPC9jOHktbGktdGltZWxpbmU+XG4gICAgPGM4eS1sb2FkaW5nICpuZ0lmPVwiaXNJbml0aWFsTG9hZGluZyAmJiBpc0VtcHR5TGlzdExvYWRpbmdcIj48L2M4eS1sb2FkaW5nPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwicC1yZWxhdGl2ZSBwLWwtMjRcIlxuICAgICAgKm5nSWY9XCJpc0VtcHR5TGlzdExvYWRpbmcgJiYgIWlzSW5pdGlhbExvYWRpbmdcIlxuICAgID5cbiAgICAgIDxjOHktdWktZW1wdHktc3RhdGVcbiAgICAgICAgW2ljb25dPVwiJ2M4eS1hbGVydC1pZGxlJ1wiXG4gICAgICAgIFt0aXRsZV09XCInTm8gYWxhcm1zIHRvIGRpc3BsYXkuJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIGRhdGEtY3k9XCJhbGFybS1saXN0LS1lbXB0eS1zdGF0ZVwiXG4gICAgICAgICpuZ0lmPVwiaGFzUGVybWlzc2lvbnM7IGVsc2UgYWxlcnRzQVwiXG4gICAgICA+XG4gICAgICAgIDxwIGM4eS1ndWlkZS1kb2NzPlxuICAgICAgICAgIDxzbWFsbFxuICAgICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgICAgICBuZ05vbkJpbmRhYmxlXG4gICAgICAgICAgPlxuICAgICAgICAgICAgRmluZCBvdXQgbW9yZSBpbiB0aGVcbiAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgIGM4eS1ndWlkZS1ocmVmPVwiL2RvY3MvZGV2aWNlLW1hbmFnZW1lbnQtYXBwbGljYXRpb24vbW9uaXRvcmluZy1hbmQtY29udHJvbGxpbmctZGV2aWNlcy8jd29ya2luZy13aXRoLWFsYXJtc1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHVzZXIgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgLlxuICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgIDwvcD5cbiAgICAgIDwvYzh5LXVpLWVtcHR5LXN0YXRlPlxuICAgIDwvZGl2PlxuICA8L2M4eS1saXN0LWdyb3VwPlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZSAjYWxlcnRzQT5cbiAgPGM4eS1keW5hbWljLWNvbXBvbmVudC1hbGVydHMgW2FsZXJ0c109XCJhbGVydEFnZ3JlZ2F0b3JcIj48L2M4eS1keW5hbWljLWNvbXBvbmVudC1hbGVydHM+XG48L25nLXRlbXBsYXRlPlxuIl19