@c8y/ngx-components 1021.52.0 → 1021.54.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.d.ts +10 -2
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.d.ts +11 -0
- package/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.d.ts.map +1 -0
- package/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.d.ts +10 -4
- package/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.d.ts +3 -1
- package/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.d.ts.map +1 -1
- package/alarm-event-selector/alarm-event-selector.model.d.ts +7 -0
- package/alarm-event-selector/alarm-event-selector.model.d.ts.map +1 -1
- package/core/application/app-icon.component.d.ts.map +1 -1
- package/core/dashboard/dashboard-child-action.component.d.ts +1 -1
- package/core/dashboard/dashboard-child-action.component.d.ts.map +1 -1
- package/core/dashboard/dashboard.module.d.ts +29 -29
- package/core/dashboard/index.d.ts +3 -0
- package/core/dashboard/index.d.ts.map +1 -1
- package/core/dashboard/widgets-dashboard.component.d.ts +1 -1
- package/core/dashboard/widgets-dashboard.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-date-range.service.d.ts +10 -0
- package/core/dashboard/wiget-time-context/widget-time-context-date-range.service.d.ts.map +1 -0
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +7 -4
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts +0 -1
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts.map +1 -1
- package/core/date-picker/date-picker.component.d.ts +1 -1
- package/core/date-picker/date-picker.component.d.ts.map +1 -1
- package/core/date-picker/date-picker.module.d.ts +9 -9
- package/core/date-time-picker/close-date-picker.directive.d.ts +1 -1
- package/core/date-time-picker/close-date-picker.directive.d.ts.map +1 -1
- package/core/date-time-picker/date-time-picker.component.d.ts +6 -3
- package/core/date-time-picker/date-time-picker.component.d.ts.map +1 -1
- package/core/date-time-picker/date-time-picker.module.d.ts +11 -11
- package/core/date-time-picker/date-time-picker.module.d.ts.map +1 -1
- package/core/forms/forms.module.d.ts +18 -18
- package/core/forms/required-input-placeholder.directive.d.ts +1 -1
- package/core/forms/required-input-placeholder.directive.d.ts.map +1 -1
- package/core/router/router.service.d.ts.map +1 -1
- package/core/user/user-menu.service.d.ts +36 -11
- package/core/user/user-menu.service.d.ts.map +1 -1
- package/datapoint-explorer/c8y-ngx-components-datapoint-explorer.d.ts.map +1 -0
- package/datapoint-explorer/datapoint-explorer.module.d.ts +7 -0
- package/datapoint-explorer/datapoint-explorer.module.d.ts.map +1 -0
- package/datapoint-explorer/index.d.ts +2 -0
- package/datapoint-explorer/index.d.ts.map +1 -0
- package/datapoint-explorer/view/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/naming-dictionary.d.ts +3 -0
- package/datapoint-explorer/view/configuration/naming-dictionary.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.component.d.ts +38 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.component.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.model.d.ts +7 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.model.d.ts.map +1 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.service.d.ts +15 -0
- package/datapoint-explorer/view/configuration/workspace-configuration.service.d.ts.map +1 -0
- package/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.d.ts +25 -0
- package/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.d.ts.map +1 -0
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts +67 -0
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts.map +1 -0
- package/datapoint-explorer/view/datapoint-explorer.service.d.ts +9 -0
- package/datapoint-explorer/view/datapoint-explorer.service.d.ts.map +1 -0
- package/datapoint-explorer/view/index.d.ts +2 -0
- package/datapoint-explorer/view/index.d.ts.map +1 -0
- package/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.d.ts +23 -0
- package/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.d.ts.map +1 -0
- package/echart/c8y-ngx-components-echart.d.ts.map +1 -0
- package/echart/chart-alerts/chart-alerts.component.d.ts +8 -0
- package/echart/chart-alerts/chart-alerts.component.d.ts.map +1 -0
- package/echart/charts.component.d.ts +63 -0
- package/echart/charts.component.d.ts.map +1 -0
- package/echart/index.d.ts +5 -0
- package/echart/index.d.ts.map +1 -0
- package/echart/models/c8y-ngx-components-echart-models.d.ts.map +1 -0
- package/echart/models/chart.model.d.ts +37 -0
- package/echart/models/chart.model.d.ts.map +1 -0
- package/echart/models/datapoints-graph-widget.model.d.ts +126 -0
- package/echart/models/datapoints-graph-widget.model.d.ts.map +1 -0
- package/echart/models/index.d.ts +4 -0
- package/echart/models/index.d.ts.map +1 -0
- package/echart/models/svg-icons.model.d.ts +22 -0
- package/echart/models/svg-icons.model.d.ts.map +1 -0
- package/echart/services/chart-alarms.service.d.ts +17 -0
- package/echart/services/chart-alarms.service.d.ts.map +1 -0
- package/echart/services/chart-events.service.d.ts +17 -0
- package/echart/services/chart-events.service.d.ts.map +1 -0
- package/echart/services/chart-realtime.service.d.ts +35 -0
- package/echart/services/chart-realtime.service.d.ts.map +1 -0
- package/echart/services/chart-types.service.d.ts +15 -0
- package/echart/services/chart-types.service.d.ts.map +1 -0
- package/echart/services/custom-measurements.service.d.ts +12 -0
- package/echart/services/custom-measurements.service.d.ts.map +1 -0
- package/echart/services/echarts-options.service.d.ts +143 -0
- package/echart/services/echarts-options.service.d.ts.map +1 -0
- package/echart/services/y-axis.service.d.ts +17 -0
- package/echart/services/y-axis.service.d.ts.map +1 -0
- package/esm2022/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.component.mjs +37 -12
- package/esm2022/alarm-event-selector/alarm-event-attributes-form/alarm-event-attributes-form.model.mjs +2 -0
- package/esm2022/alarm-event-selector/alarm-event-selection-list/alarm-event-selection-list.component.mjs +39 -12
- package/esm2022/alarm-event-selector/alarm-event-selector-list-item/alarm-event-selector-list-item.component.mjs +6 -4
- package/esm2022/alarm-event-selector/alarm-event-selector.component.mjs +1 -1
- package/esm2022/alarm-event-selector/alarm-event-selector.model.mjs +1 -1
- package/esm2022/alarm-event-selector/custom-alarm-event-form/custom-alarm-event-form.component.mjs +1 -1
- package/esm2022/alarms/alarms-filter.component.mjs +3 -3
- package/esm2022/core/application/app-icon.component.mjs +4 -4
- package/esm2022/core/dashboard/dashboard-child-action.component.mjs +3 -3
- package/esm2022/core/dashboard/dashboard.module.mjs +17 -14
- package/esm2022/core/dashboard/index.mjs +4 -1
- package/esm2022/core/dashboard/widgets-dashboard.component.mjs +9 -9
- package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +11 -9
- package/esm2022/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.mjs +8 -7
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-date-range.service.mjs +23 -0
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +70 -26
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.model.mjs +1 -1
- package/esm2022/core/date-picker/date-picker.component.mjs +29 -14
- package/esm2022/core/date-picker/date-picker.module.mjs +9 -7
- package/esm2022/core/date-time-picker/close-date-picker.directive.mjs +4 -3
- package/esm2022/core/date-time-picker/date-time-picker.component.mjs +57 -29
- package/esm2022/core/date-time-picker/date-time-picker.module.mjs +11 -7
- package/esm2022/core/forms/forms.module.mjs +3 -3
- package/esm2022/core/forms/ip-range-input-list.component.mjs +5 -5
- package/esm2022/core/forms/required-input-placeholder.directive.mjs +4 -3
- package/esm2022/core/router/router.service.mjs +1 -1
- package/esm2022/core/time-interval/time-interval.component.mjs +3 -3
- package/esm2022/core/user/user-menu.service.mjs +57 -17
- package/esm2022/datapoint-explorer/c8y-ngx-components-datapoint-explorer.mjs +5 -0
- package/esm2022/datapoint-explorer/datapoint-explorer.module.mjs +65 -0
- package/esm2022/datapoint-explorer/index.mjs +2 -0
- package/esm2022/datapoint-explorer/view/c8y-ngx-components-datapoint-explorer-view.mjs +5 -0
- package/esm2022/datapoint-explorer/view/configuration/naming-dictionary.mjs +65 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.component.mjs +169 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.model.mjs +2 -0
- package/esm2022/datapoint-explorer/view/configuration/workspace-configuration.service.mjs +40 -0
- package/esm2022/datapoint-explorer/view/create-new-report-modal/create-new-report-modal.component.mjs +64 -0
- package/esm2022/datapoint-explorer/view/datapoint-explorer.component.mjs +279 -0
- package/esm2022/datapoint-explorer/view/datapoint-explorer.service.mjs +23 -0
- package/esm2022/datapoint-explorer/view/index.mjs +2 -0
- package/esm2022/datapoint-explorer/view/send-as-widget-to-report-modal/send-as-widget-to-report-modal.component.mjs +48 -0
- package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.mjs +3 -3
- package/esm2022/datapoint-selector/datapoint-selector-list-item/datapoint-selector-list-item.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +3 -3
- package/esm2022/device-list/add-smart-group.component.mjs +3 -3
- package/esm2022/echart/c8y-ngx-components-echart.mjs +5 -0
- package/esm2022/echart/chart-alerts/chart-alerts.component.mjs +16 -0
- package/esm2022/echart/charts.component.mjs +560 -0
- package/esm2022/echart/index.mjs +5 -0
- package/esm2022/echart/models/c8y-ngx-components-echart-models.mjs +5 -0
- package/esm2022/echart/models/chart.model.mjs +2 -0
- package/esm2022/echart/models/datapoints-graph-widget.model.mjs +17 -0
- package/esm2022/echart/models/index.mjs +4 -0
- package/esm2022/echart/models/svg-icons.model.mjs +22 -0
- package/esm2022/echart/services/chart-alarms.service.mjs +58 -0
- package/esm2022/echart/services/chart-events.service.mjs +44 -0
- package/esm2022/echart/services/chart-realtime.service.mjs +193 -0
- package/esm2022/echart/services/chart-types.service.mjs +102 -0
- package/esm2022/echart/services/custom-measurements.service.mjs +52 -0
- package/esm2022/echart/services/echarts-options.service.mjs +857 -0
- package/esm2022/echart/services/y-axis.service.mjs +150 -0
- package/esm2022/interval-picker/interval-picker.component.mjs +3 -3
- package/esm2022/interval-picker/interval-picker.model.mjs +1 -1
- package/esm2022/map/map.component.mjs +4 -1
- package/esm2022/report-dashboard/index.mjs +2 -1
- package/esm2022/time-context/c8y-ngx-components-time-context.mjs +5 -0
- package/esm2022/time-context/index.mjs +2 -0
- package/esm2022/time-context/time-context.component.mjs +217 -0
- package/esm2022/time-context/time-context.service.mjs +83 -0
- package/esm2022/tracking/tracking.component.mjs +5 -6
- package/esm2022/tracking/tracking.service.mjs +7 -3
- package/esm2022/translation-editor/lazy/translation-editor/translation-editor.component.mjs +6 -5
- package/esm2022/widgets/cockpit-exports/index.mjs +8 -1
- package/esm2022/widgets/definitions/datapoints-graph/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +5 -0
- package/esm2022/widgets/definitions/datapoints-graph/index.mjs +31 -0
- package/esm2022/widgets/definitions/index.mjs +3 -2
- package/esm2022/widgets/implementations/datapoints-graph/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +5 -0
- package/esm2022/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.mjs +239 -0
- package/esm2022/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.mjs +241 -0
- package/esm2022/widgets/implementations/datapoints-graph/index.mjs +3 -0
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs +80 -28
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs +2 -2
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +658 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs +72 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +4 -4
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +4 -4
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-list.mjs +2 -2
- package/fesm2022/c8y-ngx-components-device-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart-models.mjs +46 -0
- package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-echart.mjs +2023 -0
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-interval-picker.mjs +2 -2
- package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-map.mjs +3 -0
- package/fesm2022/c8y-ngx-components-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-report-dashboard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-time-context.mjs +300 -0
- package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-tracking.mjs +10 -7
- package/fesm2022/c8y-ngx-components-tracking.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +5 -4
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs +7 -0
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +38 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +2 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +467 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components.mjs +433 -281
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/interval-picker/interval-picker.component.d.ts.map +1 -1
- package/interval-picker/interval-picker.model.d.ts.map +1 -1
- package/locales/de.po +206 -279
- package/locales/es.po +206 -279
- package/locales/fr.po +206 -279
- package/locales/ja_JP.po +196 -279
- package/locales/ko.po +455 -444
- package/locales/locales.pot +200 -0
- package/locales/nl.po +206 -279
- package/locales/pl.po +206 -279
- package/locales/pt_BR.po +206 -279
- package/locales/zh_CN.po +450 -443
- package/locales/zh_TW.po +452 -445
- package/map/map.component.d.ts.map +1 -1
- package/package.json +1 -1
- package/report-dashboard/index.d.ts +1 -0
- package/report-dashboard/index.d.ts.map +1 -1
- package/time-context/c8y-ngx-components-time-context.d.ts.map +1 -0
- package/time-context/index.d.ts +2 -0
- package/time-context/index.d.ts.map +1 -0
- package/time-context/time-context.component.d.ts +61 -0
- package/time-context/time-context.component.d.ts.map +1 -0
- package/time-context/time-context.service.d.ts +25 -0
- package/time-context/time-context.service.d.ts.map +1 -0
- package/tracking/tracking.component.d.ts.map +1 -1
- package/tracking/tracking.service.d.ts.map +1 -1
- package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts.map +1 -1
- package/widgets/cockpit-exports/index.d.ts +6 -0
- package/widgets/cockpit-exports/index.d.ts.map +1 -1
- package/widgets/definitions/datapoints-graph/c8y-ngx-components-widgets-definitions-datapoints-graph.d.ts.map +1 -0
- package/widgets/definitions/datapoints-graph/index.d.ts +16 -0
- package/widgets/definitions/datapoints-graph/index.d.ts.map +1 -0
- package/widgets/definitions/index.d.ts +1 -0
- package/widgets/definitions/index.d.ts.map +1 -1
- package/widgets/implementations/datapoints-graph/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.d.ts +43 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-config/datapoints-graph-widget-config.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts +54 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-graph/index.d.ts +3 -0
- package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { Component, ElementRef, EventEmitter, inject, Input, Output, ViewChild } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, forkJoin, lastValueFrom, of } from 'rxjs';
|
|
4
|
+
import { map, switchMap, tap } from 'rxjs/operators';
|
|
5
|
+
import { CustomMeasurementService } from './services/custom-measurements.service';
|
|
6
|
+
import { AlarmRealtimeService, CoreModule, DismissAlertStrategy, DynamicComponentAlert, DynamicComponentAlertAggregator, EventRealtimeService, gettext, MeasurementRealtimeService, WidgetTimeContextDateRangeService } from '@c8y/ngx-components';
|
|
7
|
+
import { EchartsOptionsService } from './services/echarts-options.service';
|
|
8
|
+
import { ChartRealtimeService } from './services/chart-realtime.service';
|
|
9
|
+
import { ChartTypesService } from './services/chart-types.service';
|
|
10
|
+
import { CommonModule } from '@angular/common';
|
|
11
|
+
import { NGX_ECHARTS_CONFIG, NgxEchartsModule } from 'ngx-echarts';
|
|
12
|
+
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
|
13
|
+
import { PopoverModule } from 'ngx-bootstrap/popover';
|
|
14
|
+
import { YAxisService } from './services/y-axis.service';
|
|
15
|
+
import { ChartAlertsComponent } from './chart-alerts/chart-alerts.component';
|
|
16
|
+
import { aggregationType, AlarmStatus } from '@c8y/client';
|
|
17
|
+
import { ChartEventsService } from './services/chart-events.service';
|
|
18
|
+
import { ChartAlarmsService } from './services/chart-alarms.service';
|
|
19
|
+
import { AlarmSeverityToIconPipe, AlarmSeverityToLabelPipe, AlarmsModule } from '@c8y/ngx-components/alarms';
|
|
20
|
+
import { INTERVALS } from '@c8y/ngx-components/interval-picker';
|
|
21
|
+
import * as i0 from "@angular/core";
|
|
22
|
+
import * as i1 from "@angular/common";
|
|
23
|
+
import * as i2 from "@c8y/ngx-components";
|
|
24
|
+
import * as i3 from "ngx-echarts";
|
|
25
|
+
export class ChartsComponent {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.showLoadMore = false;
|
|
28
|
+
this.alarms = [];
|
|
29
|
+
this.events = [];
|
|
30
|
+
this.sliderZoomUsed = false;
|
|
31
|
+
this.configChangeOnZoomOut = new EventEmitter();
|
|
32
|
+
this.timeRangeChangeOnRealtime = new EventEmitter();
|
|
33
|
+
this.datapointOutOfSync = new EventEmitter();
|
|
34
|
+
this.updateAlarmsAndEvents = new EventEmitter();
|
|
35
|
+
this.isMarkedAreaEnabled = new EventEmitter();
|
|
36
|
+
this.configChangedSubject = new BehaviorSubject(null);
|
|
37
|
+
this.measurementService = inject(CustomMeasurementService);
|
|
38
|
+
this.echartsOptionsService = inject(EchartsOptionsService);
|
|
39
|
+
this.chartRealtimeService = inject(ChartRealtimeService);
|
|
40
|
+
this.chartEventsService = inject(ChartEventsService);
|
|
41
|
+
this.chartAlarmsService = inject(ChartAlarmsService);
|
|
42
|
+
this.widgetTimeContextDateRangeService = inject(WidgetTimeContextDateRangeService);
|
|
43
|
+
this.chartOption$ = this.configChangedSubject.pipe(switchMap(() => this.loadAlarmsAndEvents()), switchMap(() => this.fetchSeriesForDatapoints$()), switchMap((datapointsWithValues) => {
|
|
44
|
+
if (datapointsWithValues.length === 0) {
|
|
45
|
+
this.echartsInstance?.clear();
|
|
46
|
+
this.showLoadMore = false;
|
|
47
|
+
return of(this.getDefaultChartOptions());
|
|
48
|
+
}
|
|
49
|
+
return this.getChartOptions(datapointsWithValues);
|
|
50
|
+
}), tap(v => {
|
|
51
|
+
if (v['empty']) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.chartRealtimeService.stopRealtime();
|
|
55
|
+
this.startRealtimeIfPossible();
|
|
56
|
+
if (this.echartsInstance) {
|
|
57
|
+
this.echartsInstance.setOption(v, true);
|
|
58
|
+
const options = this.echartsInstance.getOption();
|
|
59
|
+
const dataZoom = options['dataZoom'][0];
|
|
60
|
+
if (dataZoom.start !== 0) {
|
|
61
|
+
this.showLoadMore = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
this.sliderZoomUsed = false;
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
ngOnChanges() {
|
|
68
|
+
this.configChangedSubject.next();
|
|
69
|
+
}
|
|
70
|
+
ngOnInit() {
|
|
71
|
+
if (this.alerts) {
|
|
72
|
+
this.alerts.setAlertGroupDismissStrategy('warning', DismissAlertStrategy.TEMPORARY_OR_PERMANENT);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
ngOnDestroy() {
|
|
76
|
+
this.chartRealtimeService.stopRealtime();
|
|
77
|
+
}
|
|
78
|
+
onChartInit(ec) {
|
|
79
|
+
this.echartsInstance = ec;
|
|
80
|
+
this.echartsOptionsService.echartsInstance = this.echartsInstance;
|
|
81
|
+
this.startRealtimeIfPossible();
|
|
82
|
+
const dataZoomHandler = (evt) => {
|
|
83
|
+
if (evt.batch?.[0]?.start === 0 || evt['start'] === 0) {
|
|
84
|
+
this.showLoadMore = true;
|
|
85
|
+
}
|
|
86
|
+
const options = this.echartsInstance.getOption();
|
|
87
|
+
const dataZoom = options['dataZoom'][0];
|
|
88
|
+
this.sliderZoomUsed = true;
|
|
89
|
+
this.configChangeOnZoomOut.emit({
|
|
90
|
+
dateFrom: new Date(dataZoom['startValue']),
|
|
91
|
+
dateTo: new Date(dataZoom['endValue']),
|
|
92
|
+
interval: 'custom'
|
|
93
|
+
});
|
|
94
|
+
this.echartsInstance.setOption(options);
|
|
95
|
+
this.chartRealtimeService.stopRealtime();
|
|
96
|
+
};
|
|
97
|
+
const debouncedDataZoomHandler = this.config.realtime
|
|
98
|
+
? dataZoomHandler
|
|
99
|
+
: this.debounce(dataZoomHandler, 1000);
|
|
100
|
+
this.echartsInstance.on('dataZoom', debouncedDataZoomHandler);
|
|
101
|
+
this.echartsInstance.on('click', this.onChartClick.bind(this));
|
|
102
|
+
let originalFormatter = null;
|
|
103
|
+
this.echartsInstance.on('mouseover', (params) => {
|
|
104
|
+
if (params?.componentType !== 'markLine' && params?.componentType !== 'markPoint') {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const options = this.echartsInstance.getOption();
|
|
108
|
+
if (!options.tooltip || !Array.isArray(options.tooltip) || !options.tooltip[0]) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
originalFormatter = originalFormatter ?? options['tooltip'][0].formatter;
|
|
112
|
+
const updatedOptions = {
|
|
113
|
+
tooltip: options['tooltip'][0]
|
|
114
|
+
};
|
|
115
|
+
if (!updatedOptions.tooltip) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
updatedOptions.tooltip.formatter = (tooltipParams) => {
|
|
119
|
+
return this.echartsOptionsService.getTooltipFormatterForAlarmAndEvents(tooltipParams, params, this.events, this.alarms);
|
|
120
|
+
};
|
|
121
|
+
this.echartsInstance.setOption(updatedOptions);
|
|
122
|
+
});
|
|
123
|
+
this.echartsInstance.on('mouseout', () => {
|
|
124
|
+
const options = this.echartsInstance.getOption();
|
|
125
|
+
if (originalFormatter) {
|
|
126
|
+
options['tooltip'][0].formatter = originalFormatter;
|
|
127
|
+
this.echartsInstance.setOption(options);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
onChartClick(params) {
|
|
132
|
+
const options = this.echartsInstance.getOption();
|
|
133
|
+
if (!this.isAlarmClick(params)) {
|
|
134
|
+
this.echartsInstance.setOption({
|
|
135
|
+
tooltip: { triggerOn: 'mousemove' },
|
|
136
|
+
series: [
|
|
137
|
+
{
|
|
138
|
+
markArea: {
|
|
139
|
+
data: []
|
|
140
|
+
},
|
|
141
|
+
markLine: {
|
|
142
|
+
data: []
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const clickedAlarms = this.alarms.filter(alarm => alarm.type === params.data.itemType);
|
|
150
|
+
this.isMarkedAreaEnabled.emit(this.hasMarkArea(options));
|
|
151
|
+
const updatedOptions = !this.hasMarkArea(options)
|
|
152
|
+
? {
|
|
153
|
+
tooltip: {
|
|
154
|
+
enterable: true,
|
|
155
|
+
triggerOn: 'click'
|
|
156
|
+
},
|
|
157
|
+
series: [
|
|
158
|
+
{
|
|
159
|
+
markArea: {
|
|
160
|
+
label: {
|
|
161
|
+
show: false
|
|
162
|
+
},
|
|
163
|
+
data: this.getMarkedAreaData(clickedAlarms)
|
|
164
|
+
},
|
|
165
|
+
markLine: {
|
|
166
|
+
showSymbol: true,
|
|
167
|
+
symbol: ['none', 'none'],
|
|
168
|
+
data: this.getMarkedLineData(clickedAlarms)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
: // if markArea already exists, remove it and remove lastUpdated from markLine
|
|
174
|
+
{
|
|
175
|
+
tooltip: { triggerOn: 'mousemove' },
|
|
176
|
+
series: [
|
|
177
|
+
{
|
|
178
|
+
markArea: {
|
|
179
|
+
data: []
|
|
180
|
+
},
|
|
181
|
+
markLine: {
|
|
182
|
+
data: []
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
};
|
|
187
|
+
this.echartsInstance.setOption(updatedOptions);
|
|
188
|
+
}
|
|
189
|
+
isAlarmClick(params) {
|
|
190
|
+
return this.alarms.some(alarm => alarm.type === params.data.itemType);
|
|
191
|
+
}
|
|
192
|
+
hasMarkArea(options) {
|
|
193
|
+
return options?.series?.[0]?.markArea?.data?.length > 0;
|
|
194
|
+
}
|
|
195
|
+
saveAsImage() {
|
|
196
|
+
this.echartsInstance.setOption({
|
|
197
|
+
legend: {
|
|
198
|
+
show: true
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
const url = this.echartsInstance.getDataURL({
|
|
202
|
+
pixelRatio: 2,
|
|
203
|
+
backgroundColor: '#fff',
|
|
204
|
+
type: 'png'
|
|
205
|
+
});
|
|
206
|
+
const link = document.createElement('a');
|
|
207
|
+
link.href = url;
|
|
208
|
+
link.download = 'datapoints-graph-screenshot';
|
|
209
|
+
document.body.appendChild(link);
|
|
210
|
+
link.click();
|
|
211
|
+
document.body.removeChild(link);
|
|
212
|
+
this.echartsInstance.setOption({
|
|
213
|
+
legend: {
|
|
214
|
+
show: false
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
loadMoreData() {
|
|
219
|
+
const currentTimeRangeInMs = this.echartsOptionsService.calculateExtendedIntervalInMs(this.config.interval || 'custom', {
|
|
220
|
+
dateTo: this.widgetTimeContextDateRangeService.initialTimeRange().dateTo,
|
|
221
|
+
dateFrom: this.widgetTimeContextDateRangeService.initialTimeRange().dateFrom
|
|
222
|
+
});
|
|
223
|
+
this.widgetTimeContextDateRangeService.updateInitialTimeRange({
|
|
224
|
+
dateFrom: new Date(new Date(this.widgetTimeContextDateRangeService.initialTimeRange().dateFrom).valueOf() -
|
|
225
|
+
currentTimeRangeInMs / 4).toISOString(),
|
|
226
|
+
dateTo: this.widgetTimeContextDateRangeService.initialTimeRange().dateTo,
|
|
227
|
+
interval: 'custom'
|
|
228
|
+
});
|
|
229
|
+
const options = this.echartsInstance.getOption();
|
|
230
|
+
const dataZoom = options['dataZoom'][0];
|
|
231
|
+
this.configChangeOnZoomOut.emit({
|
|
232
|
+
dateFrom: new Date(dataZoom['startValue']),
|
|
233
|
+
dateTo: new Date(dataZoom['endValue']),
|
|
234
|
+
interval: 'custom'
|
|
235
|
+
});
|
|
236
|
+
this.showLoadMore = false;
|
|
237
|
+
}
|
|
238
|
+
debounce(func, wait) {
|
|
239
|
+
let timeout;
|
|
240
|
+
return (...args) => {
|
|
241
|
+
clearTimeout(timeout);
|
|
242
|
+
timeout = setTimeout(() => func(...args), wait);
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
getDefaultChartOptions() {
|
|
246
|
+
return {
|
|
247
|
+
title: {
|
|
248
|
+
text: gettext('No data available')
|
|
249
|
+
},
|
|
250
|
+
empty: true,
|
|
251
|
+
xAxis: {
|
|
252
|
+
type: 'category',
|
|
253
|
+
data: []
|
|
254
|
+
},
|
|
255
|
+
yAxis: {
|
|
256
|
+
type: 'value'
|
|
257
|
+
},
|
|
258
|
+
series: []
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
getMarkedAreaData(clickedAlarms) {
|
|
262
|
+
const timeRange = this.getTimeRange();
|
|
263
|
+
const clearedAlarmColor = 'rgba(221,255,221,1.00)';
|
|
264
|
+
const activeAlarmColor = 'rgba(255, 173, 177, 0.4)';
|
|
265
|
+
return clickedAlarms.map(clickedAlarm => {
|
|
266
|
+
return [
|
|
267
|
+
{
|
|
268
|
+
name: clickedAlarm.type,
|
|
269
|
+
xAxis: clickedAlarm.creationTime,
|
|
270
|
+
itemStyle: {
|
|
271
|
+
color: clickedAlarm.status === AlarmStatus.CLEARED ? clearedAlarmColor : activeAlarmColor
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
xAxis: clickedAlarm['lastUpdated'] === clickedAlarm.creationTime ||
|
|
276
|
+
clickedAlarm.status !== AlarmStatus.CLEARED
|
|
277
|
+
? timeRange.dateTo
|
|
278
|
+
: clickedAlarm['lastUpdated']
|
|
279
|
+
}
|
|
280
|
+
];
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
getMarkedLineData(clickedAlarms) {
|
|
284
|
+
return clickedAlarms.reduce((acc, alarm) => {
|
|
285
|
+
const isClickedAlarmCleared = alarm.status === AlarmStatus.CLEARED;
|
|
286
|
+
if (isClickedAlarmCleared) {
|
|
287
|
+
return acc.concat([
|
|
288
|
+
{
|
|
289
|
+
xAxis: alarm.creationTime,
|
|
290
|
+
itemType: alarm.type,
|
|
291
|
+
label: {
|
|
292
|
+
show: false,
|
|
293
|
+
formatter: () => alarm.type
|
|
294
|
+
},
|
|
295
|
+
itemStyle: { color: alarm['color'] }
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
xAxis: alarm['lastUpdated'],
|
|
299
|
+
itemType: alarm.type,
|
|
300
|
+
label: {
|
|
301
|
+
show: false,
|
|
302
|
+
formatter: () => alarm.type
|
|
303
|
+
},
|
|
304
|
+
itemStyle: { color: alarm['color'] }
|
|
305
|
+
}
|
|
306
|
+
]);
|
|
307
|
+
}
|
|
308
|
+
return acc.concat([
|
|
309
|
+
{
|
|
310
|
+
xAxis: alarm.creationTime,
|
|
311
|
+
itemType: alarm.type,
|
|
312
|
+
label: {
|
|
313
|
+
show: false,
|
|
314
|
+
formatter: () => alarm.type
|
|
315
|
+
},
|
|
316
|
+
itemStyle: { color: alarm['color'] }
|
|
317
|
+
}
|
|
318
|
+
]);
|
|
319
|
+
}, []);
|
|
320
|
+
}
|
|
321
|
+
async loadAlarmsAndEvents(customTimeRange) {
|
|
322
|
+
const timeRange = this.getTimeRange();
|
|
323
|
+
const updatedTimeRange = {
|
|
324
|
+
lastUpdatedFrom: customTimeRange ? customTimeRange.dateFrom : timeRange.dateFrom,
|
|
325
|
+
createdTo: customTimeRange ? customTimeRange.dateTo : timeRange.dateTo
|
|
326
|
+
};
|
|
327
|
+
if (!this.config.alarmsEventsConfigs)
|
|
328
|
+
return;
|
|
329
|
+
const visibleAlarmsOrEvents = this.config.alarmsEventsConfigs?.filter(alarmOrEvent => !alarmOrEvent.__hidden && alarmOrEvent.__active);
|
|
330
|
+
const alarms = visibleAlarmsOrEvents?.filter(alarmOrEvent => alarmOrEvent.timelineType === 'ALARM');
|
|
331
|
+
const events = visibleAlarmsOrEvents?.filter(alarmOrEvent => alarmOrEvent.timelineType === 'EVENT');
|
|
332
|
+
const [listedEvents, listedAlarms] = await Promise.all([
|
|
333
|
+
this.chartEventsService.listEvents(updatedTimeRange, events),
|
|
334
|
+
this.chartAlarmsService.listAlarms(updatedTimeRange, alarms)
|
|
335
|
+
]);
|
|
336
|
+
this.events = listedEvents;
|
|
337
|
+
this.alarms = listedAlarms;
|
|
338
|
+
await this.addActiveAlarms(alarms);
|
|
339
|
+
this.updateAlarmsAndEvents.emit(this.config.alarmsEventsConfigs);
|
|
340
|
+
}
|
|
341
|
+
startRealtimeIfPossible() {
|
|
342
|
+
const activeDatapoints = this.config?.datapoints?.filter(dp => dp.__active);
|
|
343
|
+
if (activeDatapoints && this.config.realtime && this.echartsInstance) {
|
|
344
|
+
this.chartRealtimeService.startRealtime(this.echartsInstance, activeDatapoints, this.getTimeRange(), dp => this.datapointOutOfSync.emit(dp), timeRange => this.timeRangeChangeOnRealtime.emit(timeRange), this.config.alarmsEventsConfigs, {
|
|
345
|
+
displayMarkedLine: this.config.displayMarkedLine || false,
|
|
346
|
+
displayMarkedPoint: this.config.displayMarkedPoint || false
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/*
|
|
351
|
+
This method should check and add active alarms from the begining of time to the alarm array
|
|
352
|
+
*/
|
|
353
|
+
async addActiveAlarms(alarms) {
|
|
354
|
+
const timeRange = this.getTimeRange();
|
|
355
|
+
const params = {
|
|
356
|
+
dateFrom: '1970-01-01T01:00:00+01:00',
|
|
357
|
+
dateTo: timeRange.dateTo,
|
|
358
|
+
status: AlarmStatus.ACTIVE
|
|
359
|
+
};
|
|
360
|
+
const activeAlarms = await this.chartAlarmsService.listAlarms(params, alarms);
|
|
361
|
+
this.config.activeAlarmTypesOutOfRange = [];
|
|
362
|
+
// iterate through the activeAlarms and check if the alarm is in the alarms array, if not update the config.activeAlarmTypesOutOfRange prop
|
|
363
|
+
activeAlarms.forEach(activeAlarm => {
|
|
364
|
+
const alarmType = activeAlarm.type;
|
|
365
|
+
const alarm = this.alarms.find(alarm => alarm.type === alarmType);
|
|
366
|
+
if (!alarm && this.config.activeAlarmTypesOutOfRange) {
|
|
367
|
+
this.config.activeAlarmTypesOutOfRange.push(alarmType);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async getChartOptions(datapointsWithValues) {
|
|
372
|
+
const timeRange = { ...this.getTimeRange(), interval: this.config.interval };
|
|
373
|
+
if (!this.widgetTimeContextDateRangeService.initialTimeRange()) {
|
|
374
|
+
this.widgetTimeContextDateRangeService.updateInitialTimeRange(timeRange);
|
|
375
|
+
const aggregatedDatapoints = await lastValueFrom(this.fetchSeriesForDatapoints$({
|
|
376
|
+
dateFrom: new Date(new Date(timeRange.dateFrom).valueOf() -
|
|
377
|
+
this.echartsOptionsService.calculateExtendedIntervalInMs(this.config.interval || 'custom', {
|
|
378
|
+
dateFrom: timeRange.dateFrom,
|
|
379
|
+
dateTo: timeRange.dateTo
|
|
380
|
+
})).toISOString(),
|
|
381
|
+
dateTo: timeRange.dateTo
|
|
382
|
+
}));
|
|
383
|
+
return this.echartsOptionsService.getChartOptions(datapointsWithValues, timeRange, {
|
|
384
|
+
YAxis: this.config.yAxisSplitLines || false,
|
|
385
|
+
XAxis: this.config.xAxisSplitLines || false
|
|
386
|
+
}, this.events, this.alarms, {
|
|
387
|
+
displayMarkedLine: this.config.displayMarkedLine || false,
|
|
388
|
+
displayMarkedPoint: this.config.displayMarkedPoint || false,
|
|
389
|
+
mergeMatchingDatapoints: this.config.mergeMatchingDatapoints || false,
|
|
390
|
+
showLabelAndUnit: this.config.showLabelAndUnit || false,
|
|
391
|
+
showSlider: this.config.showSlider || false
|
|
392
|
+
}, undefined, aggregatedDatapoints);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
const aggregatedDatapoints = await lastValueFrom(this.fetchSeriesForDatapoints$({
|
|
396
|
+
dateFrom: new Date(new Date(this.widgetTimeContextDateRangeService.initialTimeRange().dateFrom).valueOf() -
|
|
397
|
+
this.echartsOptionsService.calculateExtendedIntervalInMs(this.config.interval || 'custom', {
|
|
398
|
+
dateFrom: this.widgetTimeContextDateRangeService.initialTimeRange().dateFrom,
|
|
399
|
+
dateTo: this.widgetTimeContextDateRangeService.initialTimeRange().dateTo
|
|
400
|
+
})).toISOString(),
|
|
401
|
+
dateTo: new Date(this.widgetTimeContextDateRangeService.initialTimeRange().dateTo).toISOString()
|
|
402
|
+
}));
|
|
403
|
+
return this.echartsOptionsService.getChartOptions(datapointsWithValues, this.widgetTimeContextDateRangeService.initialTimeRange(), {
|
|
404
|
+
YAxis: this.config.yAxisSplitLines || false,
|
|
405
|
+
XAxis: this.config.xAxisSplitLines || false
|
|
406
|
+
}, this.events, this.alarms, {
|
|
407
|
+
displayMarkedLine: this.config.displayMarkedLine || false,
|
|
408
|
+
displayMarkedPoint: this.config.displayMarkedPoint || false,
|
|
409
|
+
mergeMatchingDatapoints: this.config.mergeMatchingDatapoints || false,
|
|
410
|
+
showLabelAndUnit: this.config.showLabelAndUnit || false,
|
|
411
|
+
showSlider: this.config.showSlider || false
|
|
412
|
+
}, timeRange, aggregatedDatapoints, true);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
fetchSeriesForDatapoints$(customTimeRange) {
|
|
416
|
+
const activeDatapoints = this.config?.datapoints?.filter(dp => dp.__active);
|
|
417
|
+
if (!activeDatapoints || activeDatapoints.length === 0) {
|
|
418
|
+
return of([]);
|
|
419
|
+
}
|
|
420
|
+
const datapointsWithValuesRequests = [];
|
|
421
|
+
const timeRange = this.getTimeRange(60_000);
|
|
422
|
+
for (const dp of activeDatapoints) {
|
|
423
|
+
const request = this.measurementService
|
|
424
|
+
.listSeries$({
|
|
425
|
+
...(customTimeRange ? customTimeRange : timeRange),
|
|
426
|
+
source: dp.__target?.id || '',
|
|
427
|
+
series: [`${dp.fragment}.${dp.series}`],
|
|
428
|
+
...(this.config.aggregation || customTimeRange
|
|
429
|
+
? {
|
|
430
|
+
aggregationType: customTimeRange ? aggregationType.HOURLY : this.config.aggregation
|
|
431
|
+
}
|
|
432
|
+
: {})
|
|
433
|
+
})
|
|
434
|
+
.pipe(map(res => {
|
|
435
|
+
const values = res.data.values;
|
|
436
|
+
if (res.data.truncated && this.config.dateFrom) {
|
|
437
|
+
values[new Date(this.config.dateFrom).toISOString()] = [{ min: null, max: null }];
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
if (this.alerts) {
|
|
441
|
+
this.alerts.clear();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return { ...dp, values, truncated: res.data.truncated };
|
|
445
|
+
}));
|
|
446
|
+
datapointsWithValuesRequests.push(request);
|
|
447
|
+
}
|
|
448
|
+
return forkJoin(datapointsWithValuesRequests).pipe(tap((dpsWithValues) => {
|
|
449
|
+
if (dpsWithValues.some(dp => dp['truncated'])) {
|
|
450
|
+
this.addTruncatedDataAlert();
|
|
451
|
+
}
|
|
452
|
+
}));
|
|
453
|
+
}
|
|
454
|
+
addTruncatedDataAlert() {
|
|
455
|
+
if (this.alerts?.alertGroups.find(a => a.type === 'warning')?.value?.alerts?.length) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const alert = new DynamicComponentAlert({
|
|
459
|
+
type: 'warning',
|
|
460
|
+
text: gettext('Truncated data. Change aggregation or select shorter date range.')
|
|
461
|
+
});
|
|
462
|
+
this.alerts?.addAlerts(alert);
|
|
463
|
+
}
|
|
464
|
+
getTimeRange(additionalPadding) {
|
|
465
|
+
let timeRange;
|
|
466
|
+
if (this.config.widgetInstanceGlobalTimeContext ||
|
|
467
|
+
(this.config.interval === 'custom' && !this.config.realtime)) {
|
|
468
|
+
timeRange = {
|
|
469
|
+
dateFrom: new Date(this.config.dateFrom),
|
|
470
|
+
dateTo: new Date(this.config.dateTo)
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
let timeRangeInMs = 0;
|
|
475
|
+
if (this.config.interval && this.config.interval !== 'custom') {
|
|
476
|
+
timeRangeInMs = INTERVALS.find(i => i.id === this.config.interval)?.timespanInMs || 0;
|
|
477
|
+
}
|
|
478
|
+
else if (this.config.realtime) {
|
|
479
|
+
timeRangeInMs =
|
|
480
|
+
new Date(this.config.dateTo).valueOf() -
|
|
481
|
+
new Date(this.config.dateFrom).valueOf();
|
|
482
|
+
}
|
|
483
|
+
const now = new Date();
|
|
484
|
+
timeRange = {
|
|
485
|
+
dateFrom: new Date(now.valueOf() - timeRangeInMs),
|
|
486
|
+
dateTo: now
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
if (additionalPadding) {
|
|
490
|
+
timeRange.dateFrom = new Date(timeRange.dateFrom.valueOf() - additionalPadding);
|
|
491
|
+
timeRange.dateTo = new Date(timeRange.dateTo.valueOf() + additionalPadding);
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
dateFrom: timeRange.dateFrom.toISOString(),
|
|
495
|
+
dateTo: timeRange.dateTo.toISOString()
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ChartsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
499
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: ChartsComponent, isStandalone: true, selector: "c8y-charts", inputs: { config: "config", alerts: "alerts" }, outputs: { configChangeOnZoomOut: "configChangeOnZoomOut", timeRangeChangeOnRealtime: "timeRangeChangeOnRealtime", datapointOutOfSync: "datapointOutOfSync", updateAlarmsAndEvents: "updateAlarmsAndEvents", isMarkedAreaEnabled: "isMarkedAreaEnabled" }, providers: [
|
|
500
|
+
{
|
|
501
|
+
provide: NGX_ECHARTS_CONFIG,
|
|
502
|
+
useFactory: () => ({ echarts: () => import('echarts') })
|
|
503
|
+
},
|
|
504
|
+
ChartRealtimeService,
|
|
505
|
+
MeasurementRealtimeService,
|
|
506
|
+
AlarmRealtimeService,
|
|
507
|
+
EventRealtimeService,
|
|
508
|
+
ChartTypesService,
|
|
509
|
+
EchartsOptionsService,
|
|
510
|
+
CustomMeasurementService,
|
|
511
|
+
YAxisService,
|
|
512
|
+
AlarmSeverityToIconPipe,
|
|
513
|
+
AlarmSeverityToLabelPipe
|
|
514
|
+
], viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"p-relative fit-h chart-container\"\n>\n <div\n class=\"fit-w fit-h\"\n #chart\n echarts\n [options]=\"chartOption$ | async\"\n (chartInit)=\"onChartInit($event)\"\n ></div>\n\n <c8y-chart-alerts [alerts]=\"alerts\"></c8y-chart-alerts>\n\n <div *ngIf=\"showLoadMore\" class=\"chart-load-more\">\n <button\n class=\"btn btn-primary btn-sm btn-block\"\n (click)=\"loadMoreData()\"\n >\n <i c8yIcon=\"restore\"></i>\n {{ 'Load more' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "ngmodule", type: NgxEchartsModule }, { kind: "directive", type: i3.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: ChartAlertsComponent, selector: "c8y-chart-alerts", inputs: ["alerts"] }, { kind: "ngmodule", type: AlarmsModule }] }); }
|
|
515
|
+
}
|
|
516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ChartsComponent, decorators: [{
|
|
517
|
+
type: Component,
|
|
518
|
+
args: [{ selector: 'c8y-charts', providers: [
|
|
519
|
+
{
|
|
520
|
+
provide: NGX_ECHARTS_CONFIG,
|
|
521
|
+
useFactory: () => ({ echarts: () => import('echarts') })
|
|
522
|
+
},
|
|
523
|
+
ChartRealtimeService,
|
|
524
|
+
MeasurementRealtimeService,
|
|
525
|
+
AlarmRealtimeService,
|
|
526
|
+
EventRealtimeService,
|
|
527
|
+
ChartTypesService,
|
|
528
|
+
EchartsOptionsService,
|
|
529
|
+
CustomMeasurementService,
|
|
530
|
+
YAxisService,
|
|
531
|
+
AlarmSeverityToIconPipe,
|
|
532
|
+
AlarmSeverityToLabelPipe
|
|
533
|
+
], standalone: true, imports: [
|
|
534
|
+
CommonModule,
|
|
535
|
+
CoreModule,
|
|
536
|
+
NgxEchartsModule,
|
|
537
|
+
TooltipModule,
|
|
538
|
+
PopoverModule,
|
|
539
|
+
ChartAlertsComponent,
|
|
540
|
+
AlarmsModule
|
|
541
|
+
], template: "<div\n class=\"p-relative fit-h chart-container\"\n>\n <div\n class=\"fit-w fit-h\"\n #chart\n echarts\n [options]=\"chartOption$ | async\"\n (chartInit)=\"onChartInit($event)\"\n ></div>\n\n <c8y-chart-alerts [alerts]=\"alerts\"></c8y-chart-alerts>\n\n <div *ngIf=\"showLoadMore\" class=\"chart-load-more\">\n <button\n class=\"btn btn-primary btn-sm btn-block\"\n (click)=\"loadMoreData()\"\n >\n <i c8yIcon=\"restore\"></i>\n {{ 'Load more' | translate }}\n </button>\n </div>\n</div>\n" }]
|
|
542
|
+
}], ctorParameters: () => [], propDecorators: { config: [{
|
|
543
|
+
type: Input
|
|
544
|
+
}], alerts: [{
|
|
545
|
+
type: Input
|
|
546
|
+
}], configChangeOnZoomOut: [{
|
|
547
|
+
type: Output
|
|
548
|
+
}], timeRangeChangeOnRealtime: [{
|
|
549
|
+
type: Output
|
|
550
|
+
}], datapointOutOfSync: [{
|
|
551
|
+
type: Output
|
|
552
|
+
}], updateAlarmsAndEvents: [{
|
|
553
|
+
type: Output
|
|
554
|
+
}], isMarkedAreaEnabled: [{
|
|
555
|
+
type: Output
|
|
556
|
+
}], chart: [{
|
|
557
|
+
type: ViewChild,
|
|
558
|
+
args: ['chart']
|
|
559
|
+
}] } });
|
|
560
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2VjaGFydC9jaGFydHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vZWNoYXJ0L2NoYXJ0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBSUwsTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQVd2QixPQUFPLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2xGLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsVUFBVSxFQUNWLG9CQUFvQixFQUNwQixxQkFBcUIsRUFDckIsK0JBQStCLEVBQy9CLG9CQUFvQixFQUNwQixPQUFPLEVBQ1AsMEJBQTBCLEVBQzFCLGlDQUFpQyxFQUNsQyxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBTXpFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQWtCLE1BQU0sYUFBYSxDQUFDO0FBQzNFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBR3JFLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsd0JBQXdCLEVBQ3hCLFlBQVksRUFDYixNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFBWSxTQUFTLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7QUFnQzFFLE1BQU0sT0FBTyxlQUFlO0lBOEIxQjtRQTNCQSxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixXQUFNLEdBQWEsRUFBRSxDQUFDO1FBQ3RCLFdBQU0sR0FBYSxFQUFFLENBQUM7UUFDdEIsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFHYiwwQkFBcUIsR0FBRyxJQUFJLFlBQVksRUFJOUMsQ0FBQztRQUNLLDhCQUF5QixHQUFHLElBQUksWUFBWSxFQUVuRCxDQUFDO1FBQ00sdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQTZCLENBQUM7UUFDbkUsMEJBQXFCLEdBQUcsSUFBSSxZQUFZLEVBQTBCLENBQUM7UUFDbkUsd0JBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUVwRCx5QkFBb0IsR0FBRyxJQUFJLGVBQWUsQ0FBYyxJQUFJLENBQUMsQ0FBQztRQUVyRCx1QkFBa0IsR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUN0RCwwQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN0RCx5QkFBb0IsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNwRCx1QkFBa0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNoRCx1QkFBa0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNoRCxzQ0FBaUMsR0FBRyxNQUFNLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUc3RixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQ2hELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxFQUMzQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUMsRUFDakQsU0FBUyxDQUFDLENBQUMsb0JBQW9DLEVBQUUsRUFBRTtZQUNqRCxJQUFJLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7Z0JBQzFCLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ2YsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFFL0IsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDeEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDakQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxJQUFJLFFBQVEsQ0FBQyxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO2dCQUM1QixDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLENBQ3RDLFNBQVMsRUFDVCxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FDNUMsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsV0FBVyxDQUFDLEVBQVc7UUFDckIsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQ2xFLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBRS9CLE1BQU0sZUFBZSxHQUFHLENBQUMsR0FBa0IsRUFBRSxFQUFFO1lBQzdDLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUMzQixDQUFDO1lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQztnQkFDOUIsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDMUMsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDdEMsUUFBUSxFQUFFLFFBQVE7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzNDLENBQUMsQ0FBQztRQUVGLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO1lBQ25ELENBQUMsQ0FBQyxlQUFlO1lBQ2pCLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV6QyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUUvRCxJQUFJLGlCQUFpQixHQUlMLElBQUksQ0FBQztRQUVyQixJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFXLEVBQUUsRUFBRTtZQUNuRCxJQUFJLE1BQU0sRUFBRSxhQUFhLEtBQUssVUFBVSxJQUFJLE1BQU0sRUFBRSxhQUFhLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2xGLE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQW1CLENBQUM7WUFDbEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDL0UsT0FBTztZQUNULENBQUM7WUFDRCxpQkFBaUIsR0FBRyxpQkFBaUIsSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBRXpFLE1BQU0sY0FBYyxHQUEwQjtnQkFDNUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDL0IsQ0FBQztZQUVGLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVCLE9BQU87WUFDVCxDQUFDO1lBQ0QsY0FBYyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxhQUFpQyxFQUFFLEVBQUU7Z0JBQ3ZFLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLG9DQUFvQyxDQUNwRSxhQUFhLEVBQ2IsTUFBTSxFQUNOLElBQUksQ0FBQyxNQUFNLEVBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FDWixDQUFDO1lBQ0osQ0FBQyxDQUFDO1lBRUYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFO1lBQ3ZDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUEwQixDQUFDO1lBQ3pFLElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDdEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQztnQkFDcEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFzQztRQUNqRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUM7Z0JBQzdCLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUU7Z0JBQ25DLE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxRQUFRLEVBQUU7NEJBQ1IsSUFBSSxFQUFFLEVBQUU7eUJBQ1Q7d0JBQ0QsUUFBUSxFQUFFOzRCQUNSLElBQUksRUFBRSxFQUFFO3lCQUNUO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV2RixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUN6RCxNQUFNLGNBQWMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDO1lBQy9DLENBQUMsQ0FBQztnQkFDRSxPQUFPLEVBQUU7b0JBQ1AsU0FBUyxFQUFFLElBQUk7b0JBQ2YsU0FBUyxFQUFFLE9BQU87aUJBQ25CO2dCQUNELE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxRQUFRLEVBQUU7NEJBQ1IsS0FBSyxFQUFFO2dDQUNMLElBQUksRUFBRSxLQUFLOzZCQUNaOzRCQUNELElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDO3lCQUM1Qzt3QkFDRCxRQUFRLEVBQUU7NEJBQ1IsVUFBVSxFQUFFLElBQUk7NEJBQ2hCLE1BQU0sRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7NEJBQ3hCLElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDO3lCQUM1QztxQkFDRjtpQkFDRjthQUNGO1lBQ0gsQ0FBQyxDQUFDLDZFQUE2RTtnQkFDN0U7b0JBQ0UsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRTtvQkFDbkMsTUFBTSxFQUFFO3dCQUNOOzRCQUNFLFFBQVEsRUFBRTtnQ0FDUixJQUFJLEVBQUUsRUFBRTs2QkFDVDs0QkFDRCxRQUFRLEVBQUU7Z0NBQ1IsSUFBSSxFQUFFLEVBQUU7NkJBQ1Q7eUJBQ0Y7cUJBQ0Y7aUJBQ0YsQ0FBQztRQUVOLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxZQUFZLENBQUMsTUFBVztRQUN0QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBWTtRQUN0QixPQUFPLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQztZQUM3QixNQUFNLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLElBQUk7YUFDWDtTQUNGLENBQUMsQ0FBQztRQUNILE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDO1lBQzFDLFVBQVUsRUFBRSxDQUFDO1lBQ2IsZUFBZSxFQUFFLE1BQU07WUFDdkIsSUFBSSxFQUFFLEtBQUs7U0FDWixDQUFDLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsNkJBQTZCLENBQUM7UUFDOUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2IsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUM7WUFDN0IsTUFBTSxFQUFFO2dCQUNOLElBQUksRUFBRSxLQUFLO2FBQ1o7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsWUFBWTtRQUNWLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLDZCQUE2QixDQUNuRixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxRQUFRLEVBQ2hDO1lBQ0UsTUFBTSxFQUFFLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE1BQU07WUFDeEUsUUFBUSxFQUFFLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVE7U0FDN0UsQ0FDRixDQUFDO1FBQ0YsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLHNCQUFzQixDQUFDO1lBQzVELFFBQVEsRUFBRSxJQUFJLElBQUksQ0FDaEIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxFQUFFO2dCQUNwRixvQkFBb0IsR0FBRyxDQUFDLENBQzNCLENBQUMsV0FBVyxFQUFFO1lBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE1BQU07WUFDeEUsUUFBUSxFQUFFLFFBQVE7U0FDbkIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQztZQUM5QixRQUFRLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDdEMsUUFBUSxFQUFFLFFBQVE7U0FDbkIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFDNUIsQ0FBQztJQUVELFFBQVEsQ0FDTixJQUFPLEVBQ1AsSUFBWTtRQUVaLElBQUksT0FBc0MsQ0FBQztRQUMzQyxPQUFPLENBQUMsR0FBRyxJQUFtQixFQUFFLEVBQUU7WUFDaEMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLE9BQU8sR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbEQsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVPLHNCQUFzQjtRQUM1QixPQUFPO1lBQ0wsS0FBSyxFQUFFO2dCQUNMLElBQUksRUFBRSxPQUFPLENBQUMsbUJBQW1CLENBQUM7YUFDbkM7WUFDRCxLQUFLLEVBQUUsSUFBSTtZQUNYLEtBQUssRUFBRTtnQkFDTCxJQUFJLEVBQUUsVUFBVTtnQkFDaEIsSUFBSSxFQUFFLEVBQUU7YUFDVDtZQUNELEtBQUssRUFBRTtnQkFDTCxJQUFJLEVBQUUsT0FBTzthQUNkO1lBQ0QsTUFBTSxFQUFFLEVBQUU7U0FDWCxDQUFDO0lBQ0osQ0FBQztJQUVPLGlCQUFpQixDQUFDLGFBQXVCO1FBQy9DLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QyxNQUFNLGlCQUFpQixHQUFHLHdCQUF3QixDQUFDO1FBQ25ELE1BQU0sZ0JBQWdCLEdBQUcsMEJBQTBCLENBQUM7UUFFcEQsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQ3RDLE9BQU87Z0JBQ0w7b0JBQ0UsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJO29CQUN2QixLQUFLLEVBQUUsWUFBWSxDQUFDLFlBQVk7b0JBQ2hDLFNBQVMsRUFBRTt3QkFDVCxLQUFLLEVBQ0gsWUFBWSxDQUFDLE1BQU0sS0FBSyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCO3FCQUNyRjtpQkFDRjtnQkFDRDtvQkFDRSxLQUFLLEVBQ0gsWUFBWSxDQUFDLGFBQWEsQ0FBQyxLQUFLLFlBQVksQ0FBQyxZQUFZO3dCQUN6RCxZQUFZLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxPQUFPO3dCQUN6QyxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU07d0JBQ2xCLENBQUMsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDO2lCQUNsQzthQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxhQUF1QjtRQUMvQyxPQUFPLGFBQWEsQ0FBQyxNQUFNLENBQWlCLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3pELE1BQU0scUJBQXFCLEdBQUcsS0FBSyxDQUFDLE1BQU0sS0FBSyxXQUFXLENBQUMsT0FBTyxDQUFDO1lBQ25FLElBQUkscUJBQXFCLEVBQUUsQ0FBQztnQkFDMUIsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDO29CQUNoQjt3QkFDRSxLQUFLLEVBQUUsS0FBSyxDQUFDLFlBQVk7d0JBQ3pCLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSTt3QkFDcEIsS0FBSyxFQUFFOzRCQUNMLElBQUksRUFBRSxLQUFLOzRCQUNYLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSTt5QkFDNUI7d0JBQ0QsU0FBUyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtxQkFDckM7b0JBQ0Q7d0JBQ0UsS0FBSyxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUM7d0JBQzNCLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSTt3QkFDcEIsS0FBSyxFQUFFOzRCQUNMLElBQUksRUFBRSxLQUFLOzRCQUNYLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSTt5QkFDNUI7d0JBQ0QsU0FBUyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtxQkFDckM7aUJBQ0YsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFDaEI7b0JBQ0UsS0FBSyxFQUFFLEtBQUssQ0FBQyxZQUFZO29CQUN6QixRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUk7b0JBQ3BCLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsS0FBSzt3QkFDWCxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUk7cUJBQzVCO29CQUNELFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7aUJBQ3JDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1QsQ0FBQztJQUVPLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxlQUFxQjtRQUNyRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEMsTUFBTSxnQkFBZ0IsR0FBRztZQUN2QixlQUFlLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsUUFBUTtZQUNoRixTQUFTLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTTtTQUN2RSxDQUFDO1FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CO1lBQUUsT0FBTztRQUM3QyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsTUFBTSxDQUNuRSxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFDLFFBQVEsSUFBSSxZQUFZLENBQUMsUUFBUSxDQUNoRSxDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQUcscUJBQXFCLEVBQUUsTUFBTSxDQUMxQyxZQUFZLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEtBQUssT0FBTyxDQUM1QixDQUFDO1FBQzVCLE1BQU0sTUFBTSxHQUFHLHFCQUFxQixFQUFFLE1BQU0sQ0FDMUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FDNUIsQ0FBQztRQUU1QixNQUFNLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNyRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztZQUM1RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztTQUM3RCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUMzQixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVPLHVCQUF1QjtRQUM3QixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1RSxJQUFJLGdCQUFnQixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUNyQyxJQUFJLENBQUMsZUFBZSxFQUNwQixnQkFBZ0IsRUFDaEIsSUFBSSxDQUFDLFlBQVksRUFBRSxFQUNuQixFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQ3RDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFDM0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsRUFDL0I7Z0JBQ0UsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsSUFBSSxLQUFLO2dCQUN6RCxrQkFBa0IsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixJQUFJLEtBQUs7YUFDNUQsQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7TUFFRTtJQUNNLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBOEI7UUFDMUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sTUFBTSxHQUFHO1lBQ2IsUUFBUSxFQUFFLDJCQUEyQjtZQUNyQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDeEIsTUFBTSxFQUFFLFdBQVcsQ0FBQyxNQUFNO1NBQzNCLENBQUM7UUFFRixNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzlFLElBQUksQ0FBQyxNQUFNLENBQUMsMEJBQTBCLEdBQUcsRUFBRSxDQUFDO1FBQzVDLDJJQUEySTtRQUMzSSxZQUFZLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ2pDLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxvQkFBb0M7UUFDaEUsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM3RSxJQUFJLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQztZQUMvRCxJQUFJLENBQUMsaUNBQWlDLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDekUsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLGFBQWEsQ0FDOUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDO2dCQUM3QixRQUFRLEVBQUUsSUFBSSxJQUFJLENBQ2hCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUU7b0JBQ3BDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyw2QkFBNkIsQ0FDdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksUUFBUSxFQUNoQzt3QkFDRSxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7d0JBQzVCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTtxQkFDekIsQ0FDRixDQUNKLENBQUMsV0FBVyxFQUFFO2dCQUNmLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTthQUN6QixDQUFDLENBQ0gsQ0FBQztZQUNGLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLGVBQWUsQ0FDL0Msb0JBQW9CLEVBQ3BCLFNBQVMsRUFDVDtnQkFDRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLElBQUksS0FBSztnQkFDM0MsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxJQUFJLEtBQUs7YUFDNUMsRUFDRCxJQUFJLENBQUMsTUFBTSxFQUNYLElBQUksQ0FBQyxNQUFNLEVBQ1g7Z0JBQ0UsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsSUFBSSxLQUFLO2dCQUN6RCxrQkFBa0IsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixJQUFJLEtBQUs7Z0JBQzNELHVCQUF1QixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQXVCLElBQUksS0FBSztnQkFDckUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsSUFBSSxLQUFLO2dCQUN2RCxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksS0FBSzthQUM1QyxFQUNELFNBQVMsRUFDVCxvQkFBb0IsQ0FDckIsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxvQkFBb0IsR0FBRyxNQUFNLGFBQWEsQ0FDOUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDO2dCQUM3QixRQUFRLEVBQUUsSUFBSSxJQUFJLENBQ2hCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sRUFBRTtvQkFDcEYsSUFBSSxDQUFDLHFCQUFxQixDQUFDLDZCQUE2QixDQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxRQUFRLEVBQ2hDO3dCQUNFLFFBQVEsRUFBRSxJQUFJLENBQUMsaUNBQWlDLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRO3dCQUM1RSxNQUFNLEVBQUUsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixFQUFFLENBQUMsTUFBTTtxQkFDekUsQ0FDRixDQUNKLENBQUMsV0FBVyxFQUFFO2dCQUNmLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FDZCxJQUFJLENBQUMsaUNBQWlDLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxNQUFNLENBQ2pFLENBQUMsV0FBVyxFQUFFO2FBQ2hCLENBQUMsQ0FDSCxDQUFDO1lBQ0YsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsZUFBZSxDQUMvQyxvQkFBb0IsRUFDcEIsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixFQUFFLEVBQ3pEO2dCQUNFLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsSUFBSSxLQUFLO2dCQUMzQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLElBQUksS0FBSzthQUM1QyxFQUNELElBQUksQ0FBQyxNQUFNLEVBQ1gsSUFBSSxDQUFDLE1BQU0sRUFDWDtnQkFDRSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixJQUFJLEtBQUs7Z0JBQ3pELGtCQUFrQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLElBQUksS0FBSztnQkFDM0QsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsSUFBSSxLQUFLO2dCQUNyRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixJQUFJLEtBQUs7Z0JBQ3ZELFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxLQUFLO2FBQzVDLEVBQ0QsU0FBUyxFQUNULG9CQUFvQixFQUNwQixJQUFJLENBQ0wsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRU8seUJBQXlCLENBQUMsZUFBcUI7UUFDckQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLGdCQUFnQixJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQixDQUFDO1FBQ0QsTUFBTSw0QkFBNEIsR0FBK0IsRUFBRSxDQUFDO1FBQ3BFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUMsS0FBSyxNQUFNLEVBQUUsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0I7aUJBQ3BDLFdBQVcsQ0FBQztnQkFDWCxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDbEQsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUU7Z0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxlQUFlO29CQUM1QyxDQUFDLENBQUM7d0JBQ0UsZUFBZSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXO3FCQUNwRjtvQkFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQ1IsQ0FBQztpQkFDRCxJQUFJLENBQ0gsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNSLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUMvQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQy9DLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3BGLENBQUM7cUJBQU0sQ0FBQztvQkFDTixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzt3QkFDaEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDdEIsQ0FBQztnQkFDSCxDQUFDO2dCQUNELE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDMUQsQ0FBQyxDQUFDLENBQ0gsQ0FBQztZQUVKLDRCQUE0QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsT0FBTyxRQUFRLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxJQUFJLENBQ2hELEdBQUcsQ0FBQyxDQUFDLGFBQTZCLEVBQUUsRUFBRTtZQUNwQyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDcEYsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLHFCQUFxQixDQUFDO1lBQ3RDLElBQUksRUFBRSxTQUFTO1lBQ2YsSUFBSSxFQUFFLE9BQU8sQ0FBQyxrRUFBa0UsQ0FBQztTQUNsRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRU8sWUFBWSxDQUFDLGlCQUEwQjtRQUk3QyxJQUFJLFNBQTJDLENBQUM7UUFDaEQsSUFDRSxJQUFJLENBQUMsTUFBTSxDQUFDLCtCQUErQjtZQUMzQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQzVELENBQUM7WUFDRCxTQUFTLEdBQUc7Z0JBQ1YsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBZ0IsQ0FBQztnQkFDaEQsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBYyxDQUFDO2FBQzdDLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUM5RCxhQUFhLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLElBQUksQ0FBQyxDQUFDO1lBQ3hGLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNoQyxhQUFhO29CQUNYLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBYyxDQUFDLENBQUMsT0FBTyxFQUFFO3dCQUM5QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQWdCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNyRCxDQUFDO1lBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixTQUFTLEdBQUc7Z0JBQ1YsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxhQUFhLENBQUM7Z0JBQ2pELE1BQU0sRUFBRSxHQUFHO2FBQ1osQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDdEIsU0FBUyxDQUFDLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixDQUFDLENBQUM7WUFDaEYsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELE9BQU87WUFDTCxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUU7WUFDMUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFO1NBQ3ZDLENBQUM7SUFDSixDQUFDOzhHQS9sQlUsZUFBZTtrR0FBZixlQUFlLG9XQTNCZjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxrQkFBa0I7Z0JBQzNCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2FBQ3pEO1lBQ0Qsb0JBQW9CO1lBQ3BCLDBCQUEwQjtZQUMxQixvQkFBb0I7WUFDcEIsb0JBQW9CO1lBQ3BCLGlCQUFpQjtZQUNqQixxQkFBcUI7WUFDckIsd0JBQXdCO1lBQ3hCLFlBQVk7WUFDWix1QkFBdUI7WUFDdkIsd0JBQXdCO1NBQ3pCLCtJQ2pGSCw2aEJBdUJBLDJDRDZESSxZQUFZLHVMQUNaLFVBQVUseUxBQ1YsZ0JBQWdCLGtqQ0FDaEIsYUFBYSw4QkFDYixhQUFhLCtCQUNiLG9CQUFvQixnRkFDcEIsWUFBWTs7MkZBR0gsZUFBZTtrQkE5QjNCLFNBQVM7K0JBQ0UsWUFBWSxhQUVYO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxrQkFBa0I7NEJBQzNCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO3lCQUN6RDt3QkFDRCxvQkFBb0I7d0JBQ3BCLDBCQUEwQjt3QkFDMUIsb0JBQW9CO3dCQUNwQixvQkFBb0I7d0JBQ3BCLGlCQUFpQjt3QkFDakIscUJBQXFCO3dCQUNyQix3QkFBd0I7d0JBQ3hCLFlBQVk7d0JBQ1osdUJBQXVCO3dCQUN2Qix3QkFBd0I7cUJBQ3pCLGNBQ1csSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osVUFBVTt3QkFDVixnQkFBZ0I7d0JBQ2hCLGFBQWE7d0JBQ2IsYUFBYTt3QkFDYixvQkFBb0I7d0JBQ3BCLFlBQVk7cUJBQ2I7d0RBU1EsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDSSxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBS0cseUJBQXlCO3NCQUFsQyxNQUFNO2dCQUdHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNhLEtBQUs7c0JBQXhCLFNBQVM7dUJBQUMsT0FBTyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBpbmplY3QsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgRUNoYXJ0cywgRUNoYXJ0c09wdGlvbiwgU2VyaWVzT3B0aW9uIH0gZnJvbSAnZWNoYXJ0cyc7XG5pbXBvcnQge1xuICBBbGFybURldGFpbHNFeHRlbmRlZCxcbiAgQWxhcm1PckV2ZW50RXh0ZW5kZWQsXG4gIERhdGFwb2ludHNHcmFwaEtQSURldGFpbHMsXG4gIERhdGFwb2ludHNHcmFwaFdpZGdldENvbmZpZyxcbiAgRHBXaXRoVmFsdWVzLFxuICBFdmVudERldGFpbHNFeHRlbmRlZCxcbiAgTWFya0xpbmVEYXRhXG59IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZm9ya0pvaW4sIGxhc3RWYWx1ZUZyb20sIE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ3VzdG9tTWVhc3VyZW1lbnRTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9jdXN0b20tbWVhc3VyZW1lbnRzLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQWxhcm1SZWFsdGltZVNlcnZpY2UsXG4gIENvcmVNb2R1bGUsXG4gIERpc21pc3NBbGVydFN0cmF0ZWd5LFxuICBEeW5hbWljQ29tcG9uZW50QWxlcnQsXG4gIER5bmFtaWNDb21wb25lbnRBbGVydEFnZ3JlZ2F0b3IsXG4gIEV2ZW50UmVhbHRpbWVTZXJ2aWNlLFxuICBnZXR0ZXh0LFxuICBNZWFzdXJlbWVudFJlYWx0aW1lU2VydmljZSxcbiAgV2lkZ2V0VGltZUNvbnRleHREYXRlUmFuZ2VTZXJ2aWNlXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgRWNoYXJ0c09wdGlvbnNTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9lY2hhcnRzLW9wdGlvbnMuc2VydmljZSc7XG5pbXBvcnQgeyBDaGFydFJlYWx0aW1lU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvY2hhcnQtcmVhbHRpbWUuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7XG4gIENhbGxiYWNrRGF0YVBhcmFtcyxcbiAgRUNBY3Rpb25FdmVudCxcbiAgVG9vbHRpcEZvcm1hdHRlckNhbGxiYWNrXG59IGZyb20gJ2VjaGFydHMvdHlwZXMvc3JjL3V0aWwvdHlwZXMnO1xuaW1wb3J0IHsgQ2hhcnRUeXBlc1NlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2NoYXJ0LXR5cGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE5HWF9FQ0hBUlRTX0NPTkZJRywgTmd4RWNoYXJ0c01vZHVsZSB9IGZyb20gJ25neC1lY2hhcnRzJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICduZ3gtYm9vdHN0cmFwL3Rvb2x0aXAnO1xuaW1wb3J0IHsgUG9wb3Zlck1vZHVsZSB9IGZyb20gJ25neC1ib290c3RyYXAvcG9wb3Zlcic7XG5pbXBvcnQgeyBZQXhpc1NlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL3ktYXhpcy5zZXJ2aWNlJztcbmltcG9ydCB7IENoYXJ0QWxlcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9jaGFydC1hbGVydHMvY2hhcnQtYWxlcnRzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBhZ2dyZWdhdGlvblR5cGUsIEFsYXJtU3RhdHVzLCBJQWxhcm0sIElFdmVudCB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IENoYXJ0RXZlbnRzU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvY2hhcnQtZXZlbnRzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2hhcnRBbGFybXNTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9jaGFydC1hbGFybXMuc2VydmljZSc7XG5pbXBvcnQgeyBFY2hhcnRzQ3VzdG9tT3B0aW9ucyB9IGZyb20gJy4vbW9kZWxzL2NoYXJ0Lm1vZGVsJztcbmltcG9ydCB7IFRvcExldmVsRm9ybWF0dGVyUGFyYW1zIH0gZnJvbSAnZWNoYXJ0cy90eXBlcy9zcmMvY29tcG9uZW50L3Rvb2x0aXAvVG9vbHRpcE1vZGVsJztcbmltcG9ydCB7XG4gIEFsYXJtU2V2ZXJpdHlUb0ljb25QaXBlLFxuICBBbGFybVNldmVyaXR5VG9MYWJlbFBpcGUsXG4gIEFsYXJtc01vZHVsZVxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2FsYXJtcyc7XG5pbXBvcnQgeyBJbnRlcnZhbCwgSU5URVJWQUxTIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9pbnRlcnZhbC1waWNrZXInO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktY2hhcnRzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NoYXJ0cy5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HWF9FQ0hBUlRTX0NPTkZJRyxcbiAgICAgIHVzZUZhY3Rvcnk6ICgpID0+ICh7IGVjaGFydHM6ICgpID0+IGltcG9ydCgnZWNoYXJ0cycpIH0pXG4gICAgfSxcbiAgICBDaGFydFJlYWx0aW1lU2VydmljZSxcbiAgICBNZWFzdXJlbWVudFJlYWx0aW1lU2VydmljZSxcbiAgICBBbGFybVJlYWx0aW1lU2VydmljZSxcbiAgICBFdmVudFJlYWx0aW1lU2VydmljZSxcbiAgICBDaGFydFR5cGVzU2VydmljZSxcbiAgICBFY2hhcnRzT3B0aW9uc1NlcnZpY2UsXG4gICAgQ3VzdG9tTWVhc3VyZW1lbnRTZXJ2aWNlLFxuICAgIFlBeGlzU2VydmljZSxcbiAgICBBbGFybVNldmVyaXR5VG9JY29uUGlwZSxcbiAgICBBbGFybVNldmVyaXR5VG9MYWJlbFBpcGVcbiAgXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBDb3JlTW9kdWxlLFxuICAgIE5neEVjaGFydHNNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBQb3BvdmVyTW9kdWxlLFxuICAgIENoYXJ0QWxlcnRzQ29tcG9uZW50LFxuICAgIEFsYXJtc01vZHVsZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIENoYXJ0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBjaGFydE9wdGlvbiQ6IE9ic2VydmFibGU8RUNoYXJ0c09wdGlvbj47XG4gIGVjaGFydHNJbnN0YW5jZSE6IEVDaGFydHM7XG4gIHNob3dMb2FkTW9yZSA9IGZhbHNlO1xuICBhbGFybXM6IElBbGFybVtdID0gW107XG4gIGV2ZW50czogSUV2ZW50W10gPSBbXTtcbiAgc2xpZGVyWm9vbVVzZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgY29uZmlnITogRGF0YXBvaW50c0dyYXBoV2lkZ2V0Q29uZmlnO1xuICBASW5wdXQoKSBhbGVydHMhOiBEeW5hbWljQ29tcG9uZW50QWxlcnRBZ2dyZWdhdG9yO1xuICBAT3V0cHV0KCkgY29uZmlnQ2hhbmdlT25ab29tT3V0ID0gbmV3IEV2ZW50RW1pdHRlcjx7XG4gICAgZGF0ZUZyb206IERhdGU7XG4gICAgZGF0ZVRvOiBEYXRlO1xuICAgIGludGVydmFsPzogSW50ZXJ2YWxbJ2lkJ107XG4gIH0+KCk7XG4gIEBPdXRwdXQoKSB0aW1lUmFuZ2VDaGFuZ2VPblJlYWx0aW1lID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBQaWNrPERhdGFwb2ludHNHcmFwaFdpZGdldENvbmZpZywgJ2RhdGVGcm9tJyB8ICdkYXRlVG8nPlxuICA+KCk7XG4gIEBPdXRwdXQoKSBkYXRhcG9pbnRPdXRPZlN5bmMgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGFwb2ludHNHcmFwaEtQSURldGFpbHM+KCk7XG4gIEBPdXRwdXQoKSB1cGRhdGVBbGFybXNBbmRFdmVudHMgPSBuZXcgRXZlbnRFbWl0dGVyPEFsYXJtT3JFdmVudEV4dGVuZGVkW10+KCk7XG4gIEBPdXRwdXQoKSBpc01hcmtlZEFyZWFFbmFibGVkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICBAVmlld0NoaWxkKCdjaGFydCcpIGNoYXJ0OiBFbGVtZW50UmVmO1xuICBwcml2YXRlIGNvbmZpZ0NoYW5nZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDx2b2lkIHwgbnVsbD4obnVsbCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBtZWFzdXJlbWVudFNlcnZpY2UgPSBpbmplY3QoQ3VzdG9tTWVhc3VyZW1lbnRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBlY2hhcnRzT3B0aW9uc1NlcnZpY2UgPSBpbmplY3QoRWNoYXJ0c09wdGlvbnNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjaGFydFJlYWx0aW1lU2VydmljZSA9IGluamVjdChDaGFydFJlYWx0aW1lU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhcnRFdmVudHNTZXJ2aWNlID0gaW5qZWN0KENoYXJ0RXZlbnRzU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhcnRBbGFybXNTZXJ2aWNlID0gaW5qZWN0KENoYXJ0QWxhcm1zU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgd2lkZ2V0VGltZUNvbnRleHREYXRlUmFuZ2VTZXJ2aWNlID0gaW5qZWN0KFdpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jaGFydE9wdGlvbiQgPSB0aGlzLmNvbmZpZ0NoYW5nZWRTdWJqZWN0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5sb2FkQWxhcm1zQW5kRXZlbnRzKCkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuZmV0Y2hTZXJpZXNGb3JEYXRhcG9pbnRzJCgpKSxcbiAgICAgIHN3aXRjaE1hcCgoZGF0YXBvaW50c1dpdGhWYWx1ZXM6IERwV2l0aFZhbHVlc1tdKSA9PiB7XG4gICAgICAgIGlmIChkYXRhcG9pbnRzV2l0aFZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLmVjaGFydHNJbnN0YW5jZT8uY2xlYXIoKTtcbiAgICAgICAgICB0aGlzLnNob3dMb2FkTW9yZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBvZih0aGlzLmdldERlZmF1bHRDaGFydE9wdGlvbnMoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hhcnRPcHRpb25zKGRhdGFwb2ludHNXaXRoVmFsdWVzKTtcbiAgICAgIH0pLFxuICAgICAgdGFwKHYgPT4ge1xuICAgICAgICBpZiAodlsnZW1wdHknXSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoYXJ0UmVhbHRpbWVTZXJ2aWNlLnN0b3BSZWFsdGltZSgpO1xuICAgICAgICB0aGlzLnN0YXJ0UmVhbHRpbWVJZlBvc3NpYmxlKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZWNoYXJ0c0luc3RhbmNlKSB7XG4gICAgICAgICAgdGhpcy5lY2hhcnRzSW5zdGFuY2Uuc2V0T3B0aW9uKHYsIHRydWUpO1xuICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmVjaGFydHNJbnN0YW5jZS5nZXRPcHRpb24oKTtcbiAgICAgICAgICBjb25zdCBkYXRhWm9vbSA9IG9wdGlvbnNbJ2RhdGFab29tJ11bMF07XG4gICAgICAgICAgaWYgKGRhdGFab29tLnN0YXJ0ICE9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dMb2FkTW9yZSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNsaWRlclpvb21Vc2VkID0gZmFsc2U7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLmNvbmZpZ0NoYW5nZWRTdWJqZWN0Lm5leHQoKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLmFsZXJ0cykge1xuICAgICAgdGhpcy5hbGVydHMuc2V0QWxlcnRHcm91cERpc21pc3NTdHJhdGVneShcbiAgICAgICAgJ3dhcm5pbmcnLFxuICAgICAgICBEaXNtaXNzQWxlcnRTdHJhdGVneS5URU1QT1JBUllfT1JfUEVSTUFORU5UXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuY2hhcnRSZWFsdGltZVNlcnZpY2Uuc3RvcFJlYWx0aW1lKCk7XG4gIH1cblxuICBvbkNoYXJ0SW5pdChlYzogRUNoYXJ0cykge1xuICAgIHRoaXMuZWNoYXJ0c0luc3RhbmNlID0gZWM7XG4gICAgdGhpcy5lY2hhcnRzT3B0aW9uc1NlcnZpY2UuZWNoYXJ0c0luc3RhbmNlID0gdGhpcy5lY2hhcnRzSW5zdGFuY2U7XG4gICAgdGhpcy5zdGFydFJlYWx0aW1lSWZQb3NzaWJsZSgpO1xuXG4gICAgY29uc3QgZGF0YVpvb21IYW5kbGVyID0gKGV2dDogRUNBY3Rpb25FdmVudCkgPT4ge1xuICAgICAgaWYgKGV2dC5iYXRjaD8uWzBdPy5zdGFydCA9PT0gMCB8fCBldnRbJ3N0YXJ0J10gPT09IDApIHtcbiAgICAgICAgdGhpcy5zaG93TG9hZE1vcmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5lY2hhcnRzSW5zdGFuY2UuZ2V0T3B0aW9uKCk7XG4gICAgICBjb25zdCBkYXRhWm9vbSA9IG9wdGlvbnNbJ2RhdGFab29tJ11bMF07XG4gICAgICB0aGlzLnNsaWRlclpvb21Vc2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMuY29uZmlnQ2hhbmdlT25ab29tT3V0LmVtaXQoe1xuICAgICAgICBkYXRlRnJvbTogbmV3IERhdGUoZGF0YVpvb21bJ3N0YXJ0VmFsdWUnXSksXG4gICAgICAgIGRhdGVUbzogbmV3IERhdGUoZGF0YVpvb21bJ2VuZFZhbHVlJ10pLFxuICAgICAgICBpbnRlcnZhbDogJ2N1c3RvbSdcbiAgICAgIH0pO1xuICAgICAgdGhpcy5lY2hhcnRzSW5zdGFuY2Uuc2V0T3B0aW9uKG9wdGlvbnMpO1xuICAgICAgdGhpcy5jaGFydFJlYWx0aW1lU2VydmljZS5zdG9wUmVhbHRpbWUoKTtcbiAgICB9O1xuXG4gICAgY29uc3QgZGVib3VuY2VkRGF0YVpvb21IYW5kbGVyID0gdGhpcy5jb25maWcucmVhbHRpbWVcbiAgICAgID8gZGF0YVpvb21IYW5kbGVyXG4gICAgICA6IHRoaXMuZGVib3VuY2UoZGF0YVpvb21IYW5kbGVyLCAxMDAwKTtcblxuICAgIHRoaXMuZWNoYXJ0c0luc3RhbmNlLm9uKCdkYXRhWm9vbScsIGRlYm91bmNlZERhdGFab29tSGFuZGxlcik7XG4gICAgdGhpcy5lY2hhcnRzSW5zdGFuY2Uub24oJ2NsaWNrJywgdGhpcy5vbkNoYXJ0Q2xpY2suYmluZCh0aGlzKSk7XG5cbiAgICBsZXQgb3JpZ2luYWxGb3JtYXR0ZXI6XG4gICAgICB8IFRvb2x0aXBGb3JtYXR0ZXJDYWxsYmFjazxUb3BMZXZlbEZvcm1hdHRlclBhcmFtcz5cbiAgICAgIHwgc3RyaW5nXG4gICAgICB8IG51bGxcbiAgICAgIHwgdW5kZWZpbmVkID0gbnVsbDtcblxuICAgIHRoaXMuZWNoYXJ0c0luc3RhbmNlLm9uKCdtb3VzZW92ZXInLCAocGFyYW1zOiBhbnkpID0+IHtcbiAgICAgIGlmIChwYXJhbXM/LmNvbXBvbmVudFR5cGUgIT09ICdtYXJrTGluZScgJiYgcGFyYW1zPy5jb21wb25lbnRUeXBlICE9PSAnbWFya1BvaW50Jykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmVjaGFydHNJbnN0YW5jZS5nZXRPcHRpb24oKSBhcyBFQ2hhcnRzT3B0aW9uO1xuICAgICAgaWYgKCFvcHRpb25zLnRvb2x0aXAgfHwgIUFycmF5LmlzQXJyYXkob3B0aW9ucy50b29sdGlwKSB8fCAhb3B0aW9ucy50b29sdGlwWzBdKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG9yaWdpbmFsRm9ybWF0dGVyID0gb3JpZ2luYWxGb3JtYXR0ZXIgPz8gb3B0aW9uc1sndG9vbHRpcCddWzBdLmZvcm1hdHRlcjtcblxuICAgICAgY29uc3QgdXBkYXRlZE9wdGlvbnM6IFBhcnRpYWw8U2VyaWVzT3B0aW9uPiA9IHtcbiAgICAgICAgdG9vbHRpcDogb3B0aW9uc1sndG9vbHRpcCddWzBdXG4gICAgICB9O1xuXG4gICAgICBpZiAoIXVwZGF0ZWRPcHRpb25zLnRvb2x0aXApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdXBkYXRlZE9wdGlvbnMudG9vbHRpcC5mb3JtYXR0ZXIgPSAodG9vbHRpcFBhcmFtczogQ2FsbGJhY2tEYXRhUGFyYW1zKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmVjaGFydHNPcHRpb25zU2VydmljZS5nZXRUb29sdGlwRm9ybWF0dGVyRm9yQWxhcm1BbmRFdmVudHMoXG4gICAgICAgICAgdG9vbHRpcFBhcmFtcyxcbiAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgdGhpcy5ldmVudHMsXG4gICAgICAgICAgdGhpcy5hbGFybXNcbiAgICAgICAgKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuZWNoYXJ0c0luc3RhbmNlLnNldE9wdGlvbih1cGRhdGVkT3B0aW9ucyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVjaGFydHNJbnN0YW5jZS5vbignbW91c2VvdXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5lY2hhcnRzSW5zdGFuY2UuZ2V0T3B0aW9uKCkgYXMgRWNoYXJ0c0N1c3RvbU9wdGlvbnM7XG4gICAgICBpZiAob3JpZ2luYWxGb3JtYXR0ZXIpIHtcbiAgICAgICAgb3B0aW9uc1sndG9vbHRpcCddWzBdLmZvcm1hdHRlciA9IG9yaWdpbmFsRm9ybWF0dGVyO1xuICAgICAgICB0aGlzLmVjaGFydHNJbnN0YW5jZS5zZXRPcHRpb24ob3B0aW9ucyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkNoYXJ0Q2xpY2socGFyYW1zOiB7IGRhdGE6IHsgaXRlbVR5cGU6IHN0cmluZyB9IH0pOiB2b2lkIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5lY2hhcnRzSW5zdGFuY2UuZ2V0T3B0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmlzQWxhcm1DbGljayhwYXJhbXMpKSB7XG4gICAgICB0aGlzLmVjaGFydHNJbnN0YW5jZS5zZXRPcHRpb24oe1xuICAgICAgICB0b29sdGlwOiB7IHRyaWdnZXJPbjogJ21vdXNlbW92ZScgfSxcbiAgICAgICAgc2VyaWVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFya0FyZWE6IHtcbiAgICAgICAgICAgICAgZGF0YTogW11cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtYXJrTGluZToge1xuICAgICAgICAgICAgICBkYXRhOiBbXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2xpY2tlZEFsYXJtcyA9IHRoaXMuYWxhcm1zLmZpbHRlcihhbGFybSA9PiBhbGFybS50eXBlID09PSBwYXJhbXMuZGF0YS5pdGVtVHlwZSk7XG5cbiAgICB0aGlzLmlzTWFya2VkQXJlYUVuYWJsZWQuZW1pdCh0aGlzLmhhc01hcmtBcmVhKG9wdGlvbnMpKTtcbiAgICBjb25zdCB1cGRhdGVkT3B0aW9ucyA9ICF0aGlzLmhhc01hcmtBcmVhKG9wdGlvbnMpXG4gICAgICA/IHtcbiAgICAgICAgICB0b29sdGlwOiB7XG4gICAgICAgICAgICBlbnRlcmFibGU6IHRydWUsXG4gICAgICAgICAgICB0cmlnZ2VyT246ICdjbGljaydcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNlcmllczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtYXJrQXJlYToge1xuICAgICAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgICAgICBzaG93OiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGF0YTogdGhpcy5nZXRNYXJrZWRBcmVhRGF0YShjbGlja2VkQWxhcm1zKVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtYXJrTGluZToge1xuICAgICAgICAgICAgICAgIHNob3dTeW1ib2w6IHRydWUsXG4gICAgICAgICAgICAgICAgc3ltYm9sOiBbJ25vbmUnLCAnbm9uZSddLFxuICAgICAgICAgICAgICAgIGRhdGE6IHRoaXMuZ2V0TWFya2VkTGluZURhdGEoY2xpY2tlZEFsYXJtcylcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgICAgOiAvLyBpZiBtYXJrQXJlYSBhbHJlYWR5IGV4aXN0cywgcmVtb3ZlIGl0IGFuZCByZW1vdmUgbGFzdFVwZGF0ZWQgZnJvbSBtYXJrTGluZVxuICAgICAgICB7XG4gICAgICAgICAgdG9vbHRpcDogeyB0cmlnZ2VyT246ICdtb3VzZW1vdmUnIH0sXG4gICAgICAgICAgc2VyaWVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1hcmtBcmVhOiB7XG4gICAgICAgICAgICAgICAgZGF0YTogW11cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbWFya0xpbmU6IHtcbiAgICAgICAgICAgICAgICBkYXRhOiBbXVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9O1xuXG4gICAgdGhpcy5lY2hhcnRzSW5zdGFuY2Uuc2V0T3B0aW9uKHVwZGF0ZWRPcHRpb25zKTtcbiAgfVxuXG4gIGlzQWxhcm1DbGljayhwYXJhbXM6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFsYXJtcy5zb21lKGFsYXJtID0+IGFsYXJtLnR5cGUgPT09IHBhcmFtcy5kYXRhLml0ZW1UeXBlKTtcbiAgfVxuXG4gIGhhc01hcmtBcmVhKG9wdGlvbnM6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBvcHRpb25zPy5zZXJpZXM/LlswXT8ubWFya0FyZWE/LmRhdGE/Lmxlbmd0aCA+IDA7XG4gIH1cblxuICBzYXZlQXNJbWFnZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVjaGFydHNJbnN0YW5jZS5zZXRPcHRpb24oe1xuICAgICAgbGVnZW5kOiB7XG4gICAgICAgIHNob3c6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmVjaGFydHNJbnN0YW5jZS5nZXREYXRhVVJMKHtcbiAgICAgIHBpeGVsUmF0aW86IDIsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmZmJyxcbiAgICAgIHR5cGU6ICdwbmcnXG4gICAgfSk7XG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsaW5rLmhyZWYgPSB1cmw7XG4gICAgbGluay5kb3dubG9hZCA9ICdkYXRhcG9pbnRzLWdyYXBoLXNjcmVlbnNob3QnO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgdGhpcy5lY2hhcnRzSW5zdGFuY2Uuc2V0T3B0aW9uKHtcbiAgICAgIGxlZ2VuZDoge1xuICAgICAgICBzaG93OiBmYWxzZVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbG9hZE1vcmVEYXRhKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lUmFuZ2VJbk1zID0gdGhpcy5lY2hhcnRzT3B0aW9uc1NlcnZpY2UuY2FsY3VsYXRlRXh0ZW5kZWRJbnRlcnZhbEluTXMoXG4gICAgICB0aGlzLmNvbmZpZy5pbnRlcnZhbCB8fCAnY3VzdG9tJyxcbiAgICAgIHtcbiAgICAgICAgZGF0ZVRvOiB0aGlzLndpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZS5pbml0aWFsVGltZVJhbmdlKCkuZGF0ZVRvLFxuICAgICAgICBkYXRlRnJvbTogdGhpcy53aWRnZXRUaW1lQ29udGV4dERhdGVSYW5nZVNlcnZpY2UuaW5pdGlhbFRpbWVSYW5nZSgpLmRhdGVGcm9tXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLndpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZS51cGRhdGVJbml0aWFsVGltZVJhbmdlKHtcbiAgICAgIGRhdGVGcm9tOiBuZXcgRGF0ZShcbiAgICAgICAgbmV3IERhdGUodGhpcy53aWRnZXRUaW1lQ29udGV4dERhdGVSYW5nZVNlcnZpY2UuaW5pdGlhbFRpbWVSYW5nZSgpLmRhdGVGcm9tKS52YWx1ZU9mKCkgLVxuICAgICAgICAgIGN1cnJlbnRUaW1lUmFuZ2VJbk1zIC8gNFxuICAgICAgKS50b0lTT1N0cmluZygpLFxuICAgICAgZGF0ZVRvOiB0aGlzLndpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZS5pbml0aWFsVGltZVJhbmdlKCkuZGF0ZVRvLFxuICAgICAgaW50ZXJ2YWw6ICdjdXN0b20nXG4gICAgfSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZWNoYXJ0c0luc3RhbmNlLmdldE9wdGlvbigpO1xuICAgIGNvbnN0IGRhdGFab29tID0gb3B0aW9uc1snZGF0YVpvb20nXVswXTtcbiAgICB0aGlzLmNvbmZpZ0NoYW5nZU9uWm9vbU91dC5lbWl0KHtcbiAgICAgIGRhdGVGcm9tOiBuZXcgRGF0ZShkYXRhWm9vbVsnc3RhcnRWYWx1ZSddKSxcbiAgICAgIGRhdGVUbzogbmV3IERhdGUoZGF0YVpvb21bJ2VuZFZhbHVlJ10pLFxuICAgICAgaW50ZXJ2YWw6ICdjdXN0b20nXG4gICAgfSk7XG4gICAgdGhpcy5zaG93TG9hZE1vcmUgPSBmYWxzZTtcbiAgfVxuXG4gIGRlYm91bmNlPFQgZXh0ZW5kcyAoLi4uYXJnczogYW55W10pID0+IHZvaWQ+KFxuICAgIGZ1bmM6IFQsXG4gICAgd2FpdDogbnVtYmVyXG4gICk6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPFQ+KSA9PiB2b2lkIHtcbiAgICBsZXQgdGltZW91dDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG4gICAgcmV0dXJuICguLi5hcmdzOiBQYXJhbWV0ZXJzPFQ+KSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiBmdW5jKC4uLmFyZ3MpLCB3YWl0KTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWZhdWx0Q2hhcnRPcHRpb25zKCk6IEVDaGFydHNPcHRpb24ge1xuICAgIHJldHVybiB7XG4gICAgICB0aXRsZToge1xuICAgICAgICB0ZXh0OiBnZXR0ZXh0KCdObyBkYXRhIGF2YWlsYWJsZScpXG4gICAgICB9LFxuICAgICAgZW1wdHk6IHRydWUsXG4gICAgICB4QXhpczoge1xuICAgICAgICB0eXBlOiAnY2F0ZWdvcnknLFxuICAgICAgICBkYXRhOiBbXVxuICAgICAgfSxcbiAgICAgIHlBeGlzOiB7XG4gICAgICAgIHR5cGU6ICd2YWx1ZSdcbiAgICAgIH0sXG4gICAgICBzZXJpZXM6IFtdXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWFya2VkQXJlYURhdGEoY2xpY2tlZEFsYXJtczogSUFsYXJtW10pIHtcbiAgICBjb25zdCB0aW1lUmFuZ2UgPSB0aGlzLmdldFRpbWVSYW5nZSgpO1xuICAgIGNvbnN0IGNsZWFyZWRBbGFybUNvbG9yID0gJ3JnYmEoMjIxLDI1NSwyMjEsMS4wMCknO1xuICAgIGNvbnN0IGFjdGl2ZUFsYXJtQ29sb3IgPSAncmdiYSgyNTUsIDE3MywgMTc3LCAwLjQpJztcblxuICAgIHJldHVybiBjbGlja2VkQWxhcm1zLm1hcChjbGlja2VkQWxhcm0gPT4ge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IGNsaWNrZWRBbGFybS50eXBlLFxuICAgICAgICAgIHhBeGlzOiBjbGlja2VkQWxhcm0uY3JlYXRpb25UaW1lLFxuICAgICAgICAgIGl0ZW1TdHlsZToge1xuICAgICAgICAgICAgY29sb3I6XG4gICAgICAgICAgICAgIGNsaWNrZWRBbGFybS5zdGF0dXMgPT09IEFsYXJtU3RhdHVzLkNMRUFSRUQgPyBjbGVhcmVkQWxhcm1Db2xvciA6IGFjdGl2ZUFsYXJtQ29sb3JcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB4QXhpczpcbiAgICAgICAgICAgIGNsaWNrZWRBbGFybVsnbGFzdFVwZGF0ZWQnXSA9PT0gY2xpY2tlZEFsYXJtLmNyZWF0aW9uVGltZSB8fFxuICAgICAgICAgICAgY2xpY2tlZEFsYXJtLnN0YXR1cyAhPT0gQWxhcm1TdGF0dXMuQ0xFQVJFRFxuICAgICAgICAgICAgICA/IHRpbWVSYW5nZS5kYXRlVG9cbiAgICAgICAgICAgICAgOiBjbGlja2VkQWxhcm1bJ2xhc3RVcGRhdGVkJ11cbiAgICAgICAgfVxuICAgICAgXTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWFya2VkTGluZURhdGEoY2xpY2tlZEFsYXJtczogSUFsYXJtW10pIHtcbiAgICByZXR1cm4gY2xpY2tlZEFsYXJtcy5yZWR1Y2U8TWFya0xpbmVEYXRhW10+KChhY2MsIGFsYXJtKSA9PiB7XG4gICAgICBjb25zdCBpc0NsaWNrZWRBbGFybUNsZWFyZWQgPSBhbGFybS5zdGF0dXMgPT09IEFsYXJtU3RhdHVzLkNMRUFSRUQ7XG4gICAgICBpZiAoaXNDbGlja2VkQWxhcm1DbGVhcmVkKSB7XG4gICAgICAgIHJldHVybiBhY2MuY29uY2F0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4QXhpczogYWxhcm0uY3JlYXRpb25UaW1lLFxuICAgICAgICAgICAgaXRlbVR5cGU6IGFsYXJtLnR5cGUsXG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICBzaG93OiBmYWxzZSxcbiAgICAgICAgICAgICAgZm9ybWF0dGVyOiAoKSA9PiBhbGFybS50eXBlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7IGNvbG9yOiBhbGFybVsnY29sb3InXSB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4QXhpczogYWxhcm1bJ2xhc3RVcGRhdGVkJ10sXG4gICAgICAgICAgICBpdGVtVHlwZTogYWxhcm0udHlwZSxcbiAgICAgICAgICAgIGxhYmVsOiB7XG4gICAgICAgICAgICAgIHNob3c6IGZhbHNlLFxuICAgICAgICAgICAgICBmb3JtYXR0ZXI6ICgpID0+IGFsYXJtLnR5cGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGFsYXJtWydjb2xvciddIH1cbiAgICAgICAgICB9XG4gICAgICAgIF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYy5jb25jYXQoW1xuICAgICAgICB7XG4gICAgICAgICAgeEF4aXM6IGFsYXJtLmNyZWF0aW9uVGltZSxcbiAgICAgICAgICBpdGVtVHlwZTogYWxhcm0udHlwZSxcbiAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgc2hvdzogZmFsc2UsXG4gICAgICAgICAgICBmb3JtYXR0ZXI6ICgpID0+IGFsYXJtLnR5cGVcbiAgICAgICAgICB9LFxuICAgICAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogYWxhcm1bJ2NvbG9yJ10gfVxuICAgICAgICB9XG4gICAgICBdKTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRBbGFybXNBbmRFdmVudHMoY3VzdG9tVGltZVJhbmdlPzogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGltZVJhbmdlID0gdGhpcy5nZXRUaW1lUmFuZ2UoKTtcbiAgICBjb25zdCB1cGRhdGVkVGltZVJhbmdlID0ge1xuICAgICAgbGFzdFVwZGF0ZWRGcm9tOiBjdXN0b21UaW1lUmFuZ2UgPyBjdXN0b21UaW1lUmFuZ2UuZGF0ZUZyb20gOiB0aW1lUmFuZ2UuZGF0ZUZyb20sXG4gICAgICBjcmVhdGVkVG86IGN1c3RvbVRpbWVSYW5nZSA/IGN1c3RvbVRpbWVSYW5nZS5kYXRlVG8gOiB0aW1lUmFuZ2UuZGF0ZVRvXG4gICAgfTtcbiAgICBpZiAoIXRoaXMuY29uZmlnLmFsYXJtc0V2ZW50c0NvbmZpZ3MpIHJldHVybjtcbiAgICBjb25zdCB2aXNpYmxlQWxhcm1zT3JFdmVudHMgPSB0aGlzLmNvbmZpZy5hbGFybXNFdmVudHNDb25maWdzPy5maWx0ZXIoXG4gICAgICBhbGFybU9yRXZlbnQgPT4gIWFsYXJtT3JFdmVudC5fX2hpZGRlbiAmJiBhbGFybU9yRXZlbnQuX19hY3RpdmVcbiAgICApO1xuICAgIGNvbnN0IGFsYXJtcyA9IHZpc2libGVBbGFybXNPckV2ZW50cz8uZmlsdGVyKFxuICAgICAgYWxhcm1PckV2ZW50ID0+IGFsYXJtT3JFdmVudC50aW1lbGluZVR5cGUgPT09ICdBTEFSTSdcbiAgICApIGFzIEFsYXJtRGV0YWlsc0V4dGVuZGVkW107XG4gICAgY29uc3QgZXZlbnRzID0gdmlzaWJsZUFsYXJtc09yRXZlbnRzPy5maWx0ZXIoXG4gICAgICBhbGFybU9yRXZlbnQgPT4gYWxhcm1PckV2ZW50LnRpbWVsaW5lVHlwZSA9PT0gJ0VWRU5UJ1xuICAgICkgYXMgRXZlbnREZXRhaWxzRXh0ZW5kZWRbXTtcblxuICAgIGNvbnN0IFtsaXN0ZWRFdmVudHMsIGxpc3RlZEFsYXJtc10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmNoYXJ0RXZlbnRzU2VydmljZS5saXN0RXZlbnRzKHVwZGF0ZWRUaW1lUmFuZ2UsIGV2ZW50cyksXG4gICAgICB0aGlzLmNoYXJ0QWxhcm1zU2VydmljZS5saXN0QWxhcm1zKHVwZGF0ZWRUaW1lUmFuZ2UsIGFsYXJtcylcbiAgICBdKTtcblxuICAgIHRoaXMuZXZlbnRzID0gbGlzdGVkRXZlbnRzO1xuICAgIHRoaXMuYWxhcm1zID0gbGlzdGVkQWxhcm1zO1xuICAgIGF3YWl0IHRoaXMuYWRkQWN0aXZlQWxhcm1zKGFsYXJtcyk7XG5cbiAgICB0aGlzLnVwZGF0ZUFsYXJtc0FuZEV2ZW50cy5lbWl0KHRoaXMuY29uZmlnLmFsYXJtc0V2ZW50c0NvbmZpZ3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFJlYWx0aW1lSWZQb3NzaWJsZSgpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVEYXRhcG9pbnRzID0gdGhpcy5jb25maWc/LmRhdGFwb2ludHM/LmZpbHRlcihkcCA9PiBkcC5fX2FjdGl2ZSk7XG4gICAgaWYgKGFjdGl2ZURhdGFwb2ludHMgJiYgdGhpcy5jb25maWcucmVhbHRpbWUgJiYgdGhpcy5lY2hhcnRzSW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuY2hhcnRSZWFsdGltZVNlcnZpY2Uuc3RhcnRSZWFsdGltZShcbiAgICAgICAgdGhpcy5lY2hhcnRzSW5zdGFuY2UsXG4gICAgICAgIGFjdGl2ZURhdGFwb2ludHMsXG4gICAgICAgIHRoaXMuZ2V0VGltZVJhbmdlKCksXG4gICAgICAgIGRwID0+IHRoaXMuZGF0YXBvaW50T3V0T2ZTeW5jLmVtaXQoZHApLFxuICAgICAgICB0aW1lUmFuZ2UgPT4gdGhpcy50aW1lUmFuZ2VDaGFuZ2VPblJlYWx0aW1lLmVtaXQodGltZVJhbmdlKSxcbiAgICAgICAgdGhpcy5jb25maWcuYWxhcm1zRXZlbnRzQ29uZmlncyxcbiAgICAgICAge1xuICAgICAgICAgIGRpc3BsYXlNYXJrZWRMaW5lOiB0aGlzLmNvbmZpZy5kaXNwbGF5TWFya2VkTGluZSB8fCBmYWxzZSxcbiAgICAgICAgICBkaXNwbGF5TWFya2VkUG9pbnQ6IHRoaXMuY29uZmlnLmRpc3BsYXlNYXJrZWRQb2ludCB8fCBmYWxzZVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gIFRoaXMgbWV0aG9kIHNob3VsZCBjaGVjayBhbmQgYWRkIGFjdGl2ZSBhbGFybXMgZnJvbSB0aGUgYmVnaW5pbmcgb2YgdGltZSB0byB0aGUgYWxhcm0gYXJyYXlcbiAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhZGRBY3RpdmVBbGFybXMoYWxhcm1zOiBBbGFybURldGFpbHNFeHRlbmRlZFtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGltZVJhbmdlID0gdGhpcy5nZXRUaW1lUmFuZ2UoKTtcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICBkYXRlRnJvbTogJzE5NzAtMDEtMDFUMDE6MDA6MDArMDE6MDAnLFxuICAgICAgZGF0ZVRvOiB0aW1lUmFuZ2UuZGF0ZVRvLFxuICAgICAgc3RhdHVzOiBBbGFybVN0YXR1cy5BQ1RJVkVcbiAgICB9O1xuXG4gICAgY29uc3QgYWN0aXZlQWxhcm1zID0gYXdhaXQgdGhpcy5jaGFydEFsYXJtc1NlcnZpY2UubGlzdEFsYXJtcyhwYXJhbXMsIGFsYXJtcyk7XG4gICAgdGhpcy5jb25maWcuYWN0aXZlQWxhcm1UeXBlc091dE9mUmFuZ2UgPSBbXTtcbiAgICAvLyBpdGVyYXRlIHRocm91Z2ggdGhlIGFjdGl2ZUFsYXJtcyBhbmQgY2hlY2sgaWYgdGhlIGFsYXJtIGlzIGluIHRoZSBhbGFybXMgYXJyYXksIGlmIG5vdCB1cGRhdGUgdGhlIGNvbmZpZy5hY3RpdmVBbGFybVR5cGVzT3V0T2ZSYW5nZSBwcm9wXG4gICAgYWN0aXZlQWxhcm1zLmZvckVhY2goYWN0aXZlQWxhcm0gPT4ge1xuICAgICAgY29uc3QgYWxhcm1UeXBlID0gYWN0aXZlQWxhcm0udHlwZTtcbiAgICAgIGNvbnN0IGFsYXJtID0gdGhpcy5hbGFybXMuZmluZChhbGFybSA9PiBhbGFybS50eXBlID09PSBhbGFybVR5cGUpO1xuICAgICAgaWYgKCFhbGFybSAmJiB0aGlzLmNvbmZpZy5hY3RpdmVBbGFybVR5cGVzT3V0T2ZSYW5nZSkge1xuICAgICAgICB0aGlzLmNvbmZpZy5hY3RpdmVBbGFybVR5cGVzT3V0T2ZSYW5nZS5wdXNoKGFsYXJtVHlwZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldENoYXJ0T3B0aW9ucyhkYXRhcG9pbnRzV2l0aFZhbHVlczogRHBXaXRoVmFsdWVzW10pOiBQcm9taXNlPEVDaGFydHNPcHRpb24+IHtcbiAgICBjb25zdCB0aW1lUmFuZ2UgPSB7IC4uLnRoaXMuZ2V0VGltZVJhbmdlKCksIGludGVydmFsOiB0aGlzLmNvbmZpZy5pbnRlcnZhbCB9O1xuICAgIGlmICghdGhpcy53aWRnZXRUaW1lQ29udGV4dERhdGVSYW5nZVNlcnZpY2UuaW5pdGlhbFRpbWVSYW5nZSgpKSB7XG4gICAgICB0aGlzLndpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZS51cGRhdGVJbml0aWFsVGltZVJhbmdlKHRpbWVSYW5nZSk7XG4gICAgICBjb25zdCBhZ2dyZWdhdGVkRGF0YXBvaW50cyA9IGF3YWl0IGxhc3RWYWx1ZUZyb20oXG4gICAgICAgIHRoaXMuZmV0Y2hTZXJpZXNGb3JEYXRhcG9pbnRzJCh7XG4gICAgICAgICAgZGF0ZUZyb206IG5ldyBEYXRlKFxuICAgICAgICAgICAgbmV3IERhdGUodGltZVJhbmdlLmRhdGVGcm9tKS52YWx1ZU9mKCkgLVxuICAgICAgICAgICAgICB0aGlzLmVjaGFydHNPcHRpb25zU2VydmljZS5jYWxjdWxhdGVFeHRlbmRlZEludGVydmFsSW5NcyhcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5pbnRlcnZhbCB8fCAnY3VzdG9tJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBkYXRlRnJvbTogdGltZVJhbmdlLmRhdGVGcm9tLFxuICAgICAgICAgICAgICAgICAgZGF0ZVRvOiB0aW1lUmFuZ2UuZGF0ZVRvXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIGRhdGVUbzogdGltZVJhbmdlLmRhdGVUb1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHJldHVybiB0aGlzLmVjaGFydHNPcHRpb25zU2VydmljZS5nZXRDaGFydE9wdGlvbnMoXG4gICAgICAgIGRhdGFwb2ludHNXaXRoVmFsdWVzLFxuICAgICAgICB0aW1lUmFuZ2UsXG4gICAgICAgIHtcbiAgICAgICAgICBZQXhpczogdGhpcy5jb25maWcueUF4aXNTcGxpdExpbmVzIHx8IGZhbHNlLFxuICAgICAgICAgIFhBeGlzOiB0aGlzLmNvbmZpZy54QXhpc1NwbGl0TGluZXMgfHwgZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5ldmVudHMsXG4gICAgICAgIHRoaXMuYWxhcm1zLFxuICAgICAgICB7XG4gICAgICAgICAgZGlzcGxheU1hcmtlZExpbmU6IHRoaXMuY29uZmlnLmRpc3BsYXlNYXJrZWRMaW5lIHx8IGZhbHNlLFxuICAgICAgICAgIGRpc3BsYXlNYXJrZWRQb2ludDogdGhpcy5jb25maWcuZGlzcGxheU1hcmtlZFBvaW50IHx8IGZhbHNlLFxuICAgICAgICAgIG1lcmdlTWF0Y2hpbmdEYXRhcG9pbnRzOiB0aGlzLmNvbmZpZy5tZXJnZU1hdGNoaW5nRGF0YXBvaW50cyB8fCBmYWxzZSxcbiAgICAgICAgICBzaG93TGFiZWxBbmRVbml0OiB0aGlzLmNvbmZpZy5zaG93TGFiZWxBbmRVbml0IHx8IGZhbHNlLFxuICAgICAgICAgIHNob3dTbGlkZXI6IHRoaXMuY29uZmlnLnNob3dTbGlkZXIgfHwgZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICBhZ2dyZWdhdGVkRGF0YXBvaW50c1xuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYWdncmVnYXRlZERhdGFwb2ludHMgPSBhd2FpdCBsYXN0VmFsdWVGcm9tKFxuICAgICAgICB0aGlzLmZldGNoU2VyaWVzRm9yRGF0YXBvaW50cyQoe1xuICAgICAgICAgIGRhdGVGcm9tOiBuZXcgRGF0ZShcbiAgICAgICAgICAgIG5ldyBEYXRlKHRoaXMud2lkZ2V0VGltZUNvbnRleHREYXRlUmFuZ2VTZXJ2aWNlLmluaXRpYWxUaW1lUmFuZ2UoKS5kYXRlRnJvbSkudmFsdWVPZigpIC1cbiAgICAgICAgICAgICAgdGhpcy5lY2hhcnRzT3B0aW9uc1NlcnZpY2UuY2FsY3VsYXRlRXh0ZW5kZWRJbnRlcnZhbEluTXMoXG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuaW50ZXJ2YWwgfHwgJ2N1c3RvbScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZGF0ZUZyb206IHRoaXMud2lkZ2V0VGltZUNvbnRleHREYXRlUmFuZ2VTZXJ2aWNlLmluaXRpYWxUaW1lUmFuZ2UoKS5kYXRlRnJvbSxcbiAgICAgICAgICAgICAgICAgIGRhdGVUbzogdGhpcy53aWRnZXRUaW1lQ29udGV4dERhdGVSYW5nZVNlcnZpY2UuaW5pdGlhbFRpbWVSYW5nZSgpLmRhdGVUb1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICBkYXRlVG86IG5ldyBEYXRlKFxuICAgICAgICAgICAgdGhpcy53aWRnZXRUaW1lQ29udGV4dERhdGVSYW5nZVNlcnZpY2UuaW5pdGlhbFRpbWVSYW5nZSgpLmRhdGVUb1xuICAgICAgICAgICkudG9JU09TdHJpbmcoKVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHJldHVybiB0aGlzLmVjaGFydHNPcHRpb25zU2VydmljZS5nZXRDaGFydE9wdGlvbnMoXG4gICAgICAgIGRhdGFwb2ludHNXaXRoVmFsdWVzLFxuICAgICAgICB0aGlzLndpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZS5pbml0aWFsVGltZVJhbmdlKCksXG4gICAgICAgIHtcbiAgICAgICAgICBZQXhpczogdGhpcy5jb25maWcueUF4aXNTcGxpdExpbmVzIHx8IGZhbHNlLFxuICAgICAgICAgIFhBeGlzOiB0aGlzLmNvbmZpZy54QXhpc1NwbGl0TGluZXMgfHwgZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5ldmVudHMsXG4gICAgICAgIHRoaXMuYWxhcm1zLFxuICAgICAgICB7XG4gICAgICAgICAgZGlzcGxheU1hcmtlZExpbmU6IHRoaXMuY29uZmlnLmRpc3BsYXlNYXJrZWRMaW5lIHx8IGZhbHNlLFxuICAgICAgICAgIGRpc3BsYXlNYXJrZWRQb2ludDogdGhpcy5jb25maWcuZGlzcGxheU1hcmtlZFBvaW50IHx8IGZhbHNlLFxuICAgICAgICAgIG1lcmdlTWF0Y2hpbmdEYXRhcG9pbnRzOiB0aGlzLmNvbmZpZy5tZXJnZU1hdGNoaW5nRGF0YXBvaW50cyB8fCBmYWxzZSxcbiAgICAgICAgICBzaG93TGFiZWxBbmRVbml0OiB0aGlzLmNvbmZpZy5zaG93TGFiZWxBbmRVbml0IHx8IGZhbHNlLFxuICAgICAgICAgIHNob3dTbGlkZXI6IHRoaXMuY29uZmlnLnNob3dTbGlkZXIgfHwgZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgdGltZVJhbmdlLFxuICAgICAgICBhZ2dyZWdhdGVkRGF0YXBvaW50cyxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZldGNoU2VyaWVzRm9yRGF0YXBvaW50cyQoY3VzdG9tVGltZVJhbmdlPzogYW55KTogT2JzZXJ2YWJsZTxEcFdpdGhWYWx1ZXNbXT4ge1xuICAgIGNvbnN0IGFjdGl2ZURhdGFwb2ludHMgPSB0aGlzLmNvbmZpZz8uZGF0YXBvaW50cz8uZmlsdGVyKGRwID0+IGRwLl9fYWN0aXZlKTtcbiAgICBpZiAoIWFjdGl2ZURhdGFwb2ludHMgfHwgYWN0aXZlRGF0YXBvaW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBvZihbXSk7XG4gICAgfVxuICAgIGNvbnN0IGRhdGFwb2ludHNXaXRoVmFsdWVzUmVxdWVzdHM6IE9ic2VydmFibGU8RHBXaXRoVmFsdWVzPltdID0gW107XG4gICAgY29uc3QgdGltZVJhbmdlID0gdGhpcy5nZXRUaW1lUmFuZ2UoNjBfMDAwKTtcbiAgICBmb3IgKGNvbnN0IGRwIG9mIGFjdGl2ZURhdGFwb2ludHMpIHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLm1lYXN1cmVtZW50U2VydmljZVxuICAgICAgICAubGlzdFNlcmllcyQoe1xuICAgICAgICAgIC4uLihjdXN0b21UaW1lUmFuZ2UgPyBjdXN0b21UaW1lUmFuZ2UgOiB0aW1lUmFuZ2UpLFxuICAgICAgICAgIHNvdXJjZTogZHAuX190YXJnZXQ/LmlkIHx8ICcnLFxuICAgICAgICAgIHNlcmllczogW2Ake2RwLmZyYWdtZW50fS4ke2RwLnNlcmllc31gXSxcbiAgICAgICAgICAuLi4odGhpcy5jb25maWcuYWdncmVnYXRpb24gfHwgY3VzdG9tVGltZVJhbmdlXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGlvblR5cGU6IGN1c3RvbVRpbWVSYW5nZSA/IGFnZ3JlZ2F0aW9uVHlwZS5IT1VSTFkgOiB0aGlzLmNvbmZpZy5hZ2dyZWdhdGlvblxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9KVxuICAgICAgICB9KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBtYXAocmVzID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IHJlcy5kYXRhLnZhbHVlcztcbiAgICAgICAgICAgIGlmIChyZXMuZGF0YS50cnVuY2F0ZWQgJiYgdGhpcy5jb25maWcuZGF0ZUZyb20pIHtcbiAgICAgICAgICAgICAgdmFsdWVzW25ldyBEYXRlKHRoaXMuY29uZmlnLmRhdGVGcm9tKS50b0lTT1N0cmluZygpXSA9IFt7IG1pbjogbnVsbCwgbWF4OiBudWxsIH1dO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuYWxlcnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hbGVydHMuY2xlYXIoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHsgLi4uZHAsIHZhbHVlcywgdHJ1bmNhdGVkOiByZXMuZGF0YS50cnVuY2F0ZWQgfTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICBkYXRhcG9pbnRzV2l0aFZhbHVlc1JlcXVlc3RzLnB1c2gocmVxdWVzdCk7XG4gICAgfVxuICAgIHJldHVybiBmb3JrSm9pbihkYXRhcG9pbnRzV2l0aFZhbHVlc1JlcXVlc3RzKS5waXBlKFxuICAgICAgdGFwKChkcHNXaXRoVmFsdWVzOiBEcFdpdGhWYWx1ZXNbXSkgPT4ge1xuICAgICAgICBpZiAoZHBzV2l0aFZhbHVlcy5zb21lKGRwID0+IGRwWyd0cnVuY2F0ZWQnXSkpIHtcbiAgICAgICAgICB0aGlzLmFkZFRydW5jYXRlZERhdGFBbGVydCgpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRydW5jYXRlZERhdGFBbGVydCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbGVydHM/LmFsZXJ0R3JvdXBzLmZpbmQoYSA9PiBhLnR5cGUgPT09ICd3YXJuaW5nJyk/LnZhbHVlPy5hbGVydHM/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhbGVydCA9IG5ldyBEeW5hbWljQ29tcG9uZW50QWxlcnQoe1xuICAgICAgdHlwZTogJ3dhcm5pbmcnLFxuICAgICAgdGV4dDogZ2V0dGV4dCgnVHJ1bmNhdGVkIGRhdGEuIENoYW5nZSBhZ2dyZWdhdGlvbiBvciBzZWxlY3Qgc2hvcnRlciBkYXRlIHJhbmdlLicpXG4gICAgfSk7XG5cbiAgICB0aGlzLmFsZXJ0cz8uYWRkQWxlcnRzKGFsZXJ0KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGltZVJhbmdlKGFkZGl0aW9uYWxQYWRkaW5nPzogbnVtYmVyKToge1xuICAgIGRhdGVGcm9tOiBzdHJpbmc7XG4gICAgZGF0ZVRvOiBzdHJpbmc7XG4gIH0ge1xuICAgIGxldCB0aW1lUmFuZ2U6IHsgZGF0ZUZyb206IERhdGU7IGRhdGVUbzogRGF0ZSB9O1xuICAgIGlmIChcbiAgICAgIHRoaXMuY29uZmlnLndpZGdldEluc3RhbmNlR2xvYmFsVGltZUNvbnRleHQgfHxcbiAgICAgICh0aGlzLmNvbmZpZy5pbnRlcnZhbCA9PT0gJ2N1c3RvbScgJiYgIXRoaXMuY29uZmlnLnJlYWx0aW1lKVxuICAgICkge1xuICAgICAgdGltZVJhbmdlID0ge1xuICAgICAgICBkYXRlRnJvbTogbmV3IERhdGUodGhpcy5jb25maWcuZGF0ZUZyb20gYXMgRGF0ZSksXG4gICAgICAgIGRhdGVUbzogbmV3IERhdGUodGhpcy5jb25maWcuZGF0ZVRvIGFzIERhdGUpXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdGltZVJhbmdlSW5NcyA9IDA7XG4gICAgICBpZiAodGhpcy5jb25maWcuaW50ZXJ2YWwgJiYgdGhpcy5jb25maWcuaW50ZXJ2YWwgIT09ICdjdXN0b20nKSB7XG4gICAgICAgIHRpbWVSYW5nZUluTXMgPSBJTlRFUlZBTFMuZmluZChpID0+IGkuaWQgPT09IHRoaXMuY29uZmlnLmludGVydmFsKT8udGltZXNwYW5Jbk1zIHx8IDA7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY29uZmlnLnJlYWx0aW1lKSB7XG4gICAgICAgIHRpbWVSYW5nZUluTXMgPVxuICAgICAgICAgIG5ldyBEYXRlKHRoaXMuY29uZmlnLmRhdGVUbyBhcyBEYXRlKS52YWx1ZU9mKCkgLVxuICAgICAgICAgIG5ldyBEYXRlKHRoaXMuY29uZmlnLmRhdGVGcm9tIGFzIERhdGUpLnZhbHVlT2YoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICB0aW1lUmFuZ2UgPSB7XG4gICAgICAgIGRhdGVGcm9tOiBuZXcgRGF0ZShub3cudmFsdWVPZigpIC0gdGltZVJhbmdlSW5NcyksXG4gICAgICAgIGRhdGVUbzogbm93XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoYWRkaXRpb25hbFBhZGRpbmcpIHtcbiAgICAgIHRpbWVSYW5nZS5kYXRlRnJvbSA9IG5ldyBEYXRlKHRpbWVSYW5nZS5kYXRlRnJvbS52YWx1ZU9mKCkgLSBhZGRpdGlvbmFsUGFkZGluZyk7XG4gICAgICB0aW1lUmFuZ2UuZGF0ZVRvID0gbmV3IERhdGUodGltZVJhbmdlLmRhdGVUby52YWx1ZU9mKCkgKyBhZGRpdGlvbmFsUGFkZGluZyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBkYXRlRnJvbTogdGltZVJhbmdlLmRhdGVGcm9tLnRvSVNPU3RyaW5nKCksXG4gICAgICBkYXRlVG86IHRpbWVSYW5nZS5kYXRlVG8udG9JU09TdHJpbmcoKVxuICAgIH07XG4gIH1cbn1cbiIsIjxkaXZcbiAgY2xhc3M9XCJwLXJlbGF0aXZlIGZpdC1oIGNoYXJ0LWNvbnRhaW5lclwiXG4+XG4gIDxkaXZcbiAgICBjbGFzcz1cImZpdC13IGZpdC1oXCJcbiAgICAjY2hhcnRcbiAgICBlY2hhcnRzXG4gICAgW29wdGlvbnNdPVwiY2hhcnRPcHRpb24kIHwgYXN5bmNcIlxuICAgIChjaGFydEluaXQpPVwib25DaGFydEluaXQoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8Yzh5LWNoYXJ0LWFsZXJ0cyBbYWxlcnRzXT1cImFsZXJ0c1wiPjwvYzh5LWNoYXJ0LWFsZXJ0cz5cblxuICA8ZGl2ICpuZ0lmPVwic2hvd0xvYWRNb3JlXCIgY2xhc3M9XCJjaGFydC1sb2FkLW1vcmVcIj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tc20gYnRuLWJsb2NrXCJcbiAgICAgIChjbGljayk9XCJsb2FkTW9yZURhdGEoKVwiXG4gICAgPlxuICAgICAgPGkgYzh5SWNvbj1cInJlc3RvcmVcIj48L2k+XG4gICAgICB7eyAnTG9hZCBtb3JlJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
|