@c8y/ngx-components 1021.49.12 → 1021.51.1
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/core/aggregation/aggregation.model.d.ts.map +1 -0
- package/core/aggregation/aggregation.service.d.ts +44 -0
- package/core/aggregation/aggregation.service.d.ts.map +1 -0
- package/core/aggregation/index.d.ts +3 -0
- package/core/aggregation/index.d.ts.map +1 -0
- package/core/common/index.d.ts +0 -2
- package/core/common/index.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +2 -2
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
- package/core/i18n/pattern-messages.data.d.ts +18 -0
- package/core/i18n/pattern-messages.data.d.ts.map +1 -1
- package/core/index.d.ts +1 -0
- package/core/index.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts +54 -42
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts +28 -8
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts +3 -52
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts +5 -14
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts.map +1 -1
- package/device-grid/device-grid.component.d.ts.map +1 -1
- package/device-grid/device-grid.service.d.ts +2 -0
- package/device-grid/device-grid.service.d.ts.map +1 -1
- package/esm2022/alarms/alarms-type-filter.component.mjs +3 -3
- package/esm2022/core/aggregation/aggregation.model.mjs +46 -0
- package/esm2022/core/aggregation/aggregation.service.mjs +76 -0
- package/esm2022/core/aggregation/index.mjs +3 -0
- package/esm2022/core/common/index.mjs +1 -3
- package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +2 -2
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.mjs +2 -2
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +4 -4
- package/esm2022/core/i18n/pattern-messages.data.mjs +19 -1
- package/esm2022/core/index.mjs +2 -1
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.mjs +166 -164
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.mjs +82 -48
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.mjs +5 -95
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector.model.mjs +1 -9
- package/esm2022/device-grid/device-grid.component.mjs +3 -3
- package/esm2022/device-grid/device-grid.service.mjs +16 -1
- package/esm2022/device-list/add-smart-group.component.mjs +3 -3
- package/esm2022/interval-picker/interval-picker.model.mjs +5 -1
- package/esm2022/operations/bulk-operation-list-item/bulk-operation-list-item.service.mjs +5 -4
- package/esm2022/operations/operation-details/operation-details.module.mjs +7 -7
- package/esm2022/operations/operations-list/device-control.feature.mjs +20 -0
- package/esm2022/operations/operations-list/index.mjs +4 -3
- package/esm2022/operations/operations-list/operations-list-item.component.mjs +11 -9
- package/esm2022/operations/operations-list/operations-list.component.mjs +15 -10
- package/esm2022/operations/operations-list/operations-list.module.mjs +16 -41
- package/esm2022/operations/operations-list/operations-list.service.mjs +4 -3
- package/esm2022/operations/operations.module.mjs +21 -14
- package/esm2022/operations/shared/operations.service.mjs +4 -3
- package/esm2022/services/index.mjs +14 -3
- package/esm2022/services/service-command-tab/c8y-ngx-components-services-service-command-tab.mjs +5 -0
- package/esm2022/services/service-command-tab/index.mjs +3 -0
- package/esm2022/services/service-command-tab/service-command-tab.component.mjs +33 -0
- package/esm2022/services/service-command-tab/service-command.feature.mjs +14 -0
- package/esm2022/services/services-device-tab/index.mjs +9 -3
- package/esm2022/services/services-device-tab/services-device-tab.component.mjs +3 -4
- package/esm2022/services/services-device-tab/services-device-tab.guard.mjs +2 -2
- package/esm2022/services/services-device-tab/services.breadcrumb-factory.mjs +13 -1
- package/esm2022/services/services.module.mjs +4 -2
- package/esm2022/services/shared/c8y-ngx-components-services-shared.mjs +5 -0
- package/esm2022/services/shared/index.mjs +3 -0
- package/esm2022/services/shared/service-command.service.mjs +118 -0
- package/esm2022/services/shared/services.model.mjs +23 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.mjs +25 -41
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +3 -3
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.mjs +55 -49
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.mjs +25 -73
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-widget.model.mjs +20 -20
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table.service.mjs +19 -19
- package/fesm2022/c8y-ngx-components-alarms.mjs +2 -2
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +248 -308
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-grid.mjs +17 -2
- package/fesm2022/c8y-ngx-components-device-grid.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-interval-picker.mjs +5 -1
- package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs +3 -2
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operation-details.mjs +5 -5
- package/fesm2022/c8y-ngx-components-operations-operation-details.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs +57 -52
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-shared.mjs +3 -2
- package/fesm2022/c8y-ngx-components-operations-shared.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations.mjs +42 -35
- package/fesm2022/c8y-ngx-components-operations.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-services-service-command-tab.mjs +49 -0
- package/fesm2022/c8y-ngx-components-services-service-command-tab.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-services-shared.mjs +145 -0
- package/fesm2022/c8y-ngx-components-services-shared.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-services.mjs +20 -113
- package/fesm2022/c8y-ngx-components-services.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1075 -1253
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +136 -76
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/interval-picker/interval-picker.model.d.ts +6 -0
- package/interval-picker/interval-picker.model.d.ts.map +1 -1
- package/locales/de.po +52 -41
- package/locales/es.po +52 -41
- package/locales/fr.po +51 -40
- package/locales/ja_JP.po +53 -43
- package/locales/ko.po +51 -34
- package/locales/locales.pot +42 -31
- package/locales/nl.po +52 -41
- package/locales/pl.po +52 -40
- package/locales/pt_BR.po +51 -40
- package/locales/zh_CN.po +50 -33
- package/locales/zh_TW.po +50 -33
- package/operations/bulk-operation-list-item/bulk-operation-list-item.service.d.ts +2 -2
- package/operations/bulk-operation-list-item/bulk-operation-list-item.service.d.ts.map +1 -1
- package/operations/operation-details/operation-details.module.d.ts +1 -1
- package/operations/operations-list/device-control.feature.d.ts +4 -0
- package/operations/operations-list/device-control.feature.d.ts.map +1 -0
- package/operations/operations-list/index.d.ts +3 -2
- package/operations/operations-list/index.d.ts.map +1 -1
- package/operations/operations-list/operations-list-item.component.d.ts +1 -1
- package/operations/operations-list/operations-list-item.component.d.ts.map +1 -1
- package/operations/operations-list/operations-list.component.d.ts +3 -1
- package/operations/operations-list/operations-list.component.d.ts.map +1 -1
- package/operations/operations-list/operations-list.module.d.ts +3 -9
- package/operations/operations-list/operations-list.module.d.ts.map +1 -1
- package/operations/operations.module.d.ts +1 -2
- package/operations/operations.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/services/index.d.ts +13 -2
- package/services/index.d.ts.map +1 -1
- package/services/service-command-tab/c8y-ngx-components-services-service-command-tab.d.ts.map +1 -0
- package/services/service-command-tab/index.d.ts +3 -0
- package/services/service-command-tab/index.d.ts.map +1 -0
- package/services/service-command-tab/service-command-tab.component.d.ts +12 -0
- package/services/service-command-tab/service-command-tab.component.d.ts.map +1 -0
- package/services/service-command-tab/service-command.feature.d.ts +3 -0
- package/services/service-command-tab/service-command.feature.d.ts.map +1 -0
- package/services/services-device-tab/index.d.ts +8 -2
- package/services/services-device-tab/index.d.ts.map +1 -1
- package/services/services-device-tab/services-device-tab.component.d.ts +2 -2
- package/services/services-device-tab/services-device-tab.component.d.ts.map +1 -1
- package/services/services-device-tab/services.breadcrumb-factory.d.ts.map +1 -1
- package/services/services.module.d.ts.map +1 -1
- package/services/shared/c8y-ngx-components-services-shared.d.ts.map +1 -0
- package/services/shared/index.d.ts +3 -0
- package/services/shared/index.d.ts.map +1 -0
- package/services/{services-device-tab → shared}/service-command.service.d.ts +10 -7
- package/services/shared/service-command.service.d.ts.map +1 -0
- package/services/shared/services.model.d.ts +31 -0
- package/services/shared/services.model.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts +3 -5
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts +7 -2
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts +7 -27
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts +4 -3
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts +5 -5
- package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts.map +1 -1
- package/core/common/aggregation/aggregation.model.d.ts.map +0 -1
- package/core/common/aggregation/aggregation.service.d.ts +0 -17
- package/core/common/aggregation/aggregation.service.d.ts.map +0 -1
- package/esm2022/core/common/aggregation/aggregation.model.mjs +0 -46
- package/esm2022/core/common/aggregation/aggregation.service.mjs +0 -34
- package/esm2022/services/services-device-tab/service-command.service.mjs +0 -113
- package/esm2022/services/services-device-tab/service-device-tab.model.mjs +0 -2
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.mjs +0 -124
- package/services/services-device-tab/service-command.service.d.ts.map +0 -1
- package/services/services-device-tab/service-device-tab.model.d.ts +0 -11
- package/services/services-device-tab/service-device-tab.model.d.ts.map +0 -1
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts +0 -56
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts.map +0 -1
- /package/core/{common/aggregation → aggregation}/aggregation.model.d.ts +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
|
-
import { DomSanitizer } from '@angular/platform-browser';
|
|
3
2
|
import { MeasurementService } from '@c8y/client';
|
|
4
3
|
import { AGGREGATION_VALUES, AlertService, gettext } from '@c8y/ngx-components';
|
|
5
4
|
import { TranslateService } from '@ngx-translate/core';
|
|
@@ -8,14 +7,12 @@ import { UtilsService } from './utils.service';
|
|
|
8
7
|
import * as i0 from "@angular/core";
|
|
9
8
|
import * as i1 from "@c8y/ngx-components";
|
|
10
9
|
import * as i2 from "@c8y/client";
|
|
11
|
-
import * as i3 from "@
|
|
12
|
-
import * as i4 from "
|
|
13
|
-
import * as i5 from "./utils.service";
|
|
10
|
+
import * as i3 from "@ngx-translate/core";
|
|
11
|
+
import * as i4 from "./utils.service";
|
|
14
12
|
export class DataFetchingService {
|
|
15
|
-
constructor(alertService, measurementService,
|
|
13
|
+
constructor(alertService, measurementService, translateService, utilsService) {
|
|
16
14
|
this.alertService = alertService;
|
|
17
15
|
this.measurementService = measurementService;
|
|
18
|
-
this.sanitizer = sanitizer;
|
|
19
16
|
this.translateService = translateService;
|
|
20
17
|
this.utilsService = utilsService;
|
|
21
18
|
}
|
|
@@ -58,6 +55,7 @@ export class DataFetchingService {
|
|
|
58
55
|
}
|
|
59
56
|
catch (error) {
|
|
60
57
|
this.alertService.addServerFailure(error);
|
|
58
|
+
return null;
|
|
61
59
|
}
|
|
62
60
|
});
|
|
63
61
|
const results = await Promise.all(promises);
|
|
@@ -85,7 +83,7 @@ export class DataFetchingService {
|
|
|
85
83
|
<li><strong>{{$emailDeliverableCount}}</strong> datapoint(s) exports require further processing. The files will be sent to you via separate emails once completed, which may take some time.</li>
|
|
86
84
|
<li><strong>{{$nonRetrievableCount}}</strong> datapoint(s) exports exceeded 1,000,000 records, which is the limit for backend processing. To export these data, please reduce the date range. Otherwise, the data will neither be downloaded nor sent via email.</li>
|
|
87
85
|
</ul>
|
|
88
|
-
<p>The total number of data points that can be exported is: <strong>{{$totalExportableDatapointsCount}} out of {{$totalDatapointsSelectedForExportCount}}</strong
|
|
86
|
+
<p>The total number of data points that can be exported is: <strong>{{$totalExportableDatapointsCount}} out of {{$totalDatapointsSelectedForExportCount}}</strong>.</p>
|
|
89
87
|
<p><strong>Note:</strong> The file name convention of files within zip file is: <code>[source]_[fragment_series].[csv/xls]</code></p>`), {
|
|
90
88
|
$browserDownloadableCount: browserDownloadableCount,
|
|
91
89
|
$emailDeliverableCount: emailDeliverableCount,
|
|
@@ -100,6 +98,33 @@ export class DataFetchingService {
|
|
|
100
98
|
]);
|
|
101
99
|
return trimmedMessage;
|
|
102
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Trims the given HTML message by removing list items that correspond to zero counts.
|
|
103
|
+
*
|
|
104
|
+
* @param message - The HTML string containing the message with list items.
|
|
105
|
+
* @param counts - An array of number values corresponding to each list item.
|
|
106
|
+
* @param countToTrim - A count that will be trimmed with corresponding list item.
|
|
107
|
+
* @returns A trimmed HTML string with list items removed where the corresponding count is zero.
|
|
108
|
+
*
|
|
109
|
+
* Example:
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const message = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
|
|
112
|
+
* const counts = [1, 0, 2];
|
|
113
|
+
* const trimmedMessage = this.removeZeroCountListItems(message, counts);
|
|
114
|
+
* // Result: '<ul><li>Item 1</li><li>Item 3</li></ul>'
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
removeZeroCountListItems(message, counts, countToTrim = 0) {
|
|
118
|
+
const parser = new DOMParser();
|
|
119
|
+
const doc = parser.parseFromString(message, 'text/html');
|
|
120
|
+
const listItems = doc.querySelectorAll('ul li');
|
|
121
|
+
listItems.forEach((item, index) => {
|
|
122
|
+
if (counts[index] === countToTrim) {
|
|
123
|
+
item.remove();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return doc.body.innerHTML;
|
|
127
|
+
}
|
|
103
128
|
/**
|
|
104
129
|
* Displays an information alert about sending data via email.
|
|
105
130
|
*
|
|
@@ -123,8 +148,8 @@ export class DataFetchingService {
|
|
|
123
148
|
const filePromises = exportConfig.datapointDetails.map(details => this.fetchAndProcessMeasurementFile(details, measurementFileConfig));
|
|
124
149
|
return Promise.all(filePromises);
|
|
125
150
|
}
|
|
126
|
-
async fetchAndProcessMeasurementFile(details, measurementFileConfig) {
|
|
127
|
-
const filter = this.prepareMeasurementsFilter(details, measurementFileConfig.exportConfig);
|
|
151
|
+
async fetchAndProcessMeasurementFile(details, measurementFileConfig, roundSeconds = false) {
|
|
152
|
+
const filter = this.prepareMeasurementsFilter(details, measurementFileConfig.exportConfig, roundSeconds);
|
|
128
153
|
const header = { accept: measurementFileConfig.acceptFileType };
|
|
129
154
|
try {
|
|
130
155
|
const measurementFileResponse = await this.measurementService.getMeasurementsFile(filter, header);
|
|
@@ -151,6 +176,77 @@ export class DataFetchingService {
|
|
|
151
176
|
? await this.fetchAndPrepareMeasurementDataToExportForPreview(exportConfig)
|
|
152
177
|
: await this.fetchAndPrepareSeriesDataToExport(exportConfig);
|
|
153
178
|
}
|
|
179
|
+
prepareMeasurementsFilter(details, exportConfig, roundSeconds, pageSize) {
|
|
180
|
+
const filter = {
|
|
181
|
+
dateFrom: this.adjustDate(exportConfig.dateFrom, 0, roundSeconds),
|
|
182
|
+
dateTo: this.adjustDate(exportConfig.dateTo, 0, roundSeconds),
|
|
183
|
+
source: details.source,
|
|
184
|
+
valueFragmentSeries: details.valueFragmentSeries,
|
|
185
|
+
valueFragmentType: details.valueFragmentType
|
|
186
|
+
};
|
|
187
|
+
if (pageSize) {
|
|
188
|
+
filter.pageSize = pageSize;
|
|
189
|
+
}
|
|
190
|
+
return filter;
|
|
191
|
+
}
|
|
192
|
+
processMeasurementDataForPreview(details, data) {
|
|
193
|
+
const unit = data[0][details.valueFragmentType][details.valueFragmentSeries]?.unit || '';
|
|
194
|
+
const values = {};
|
|
195
|
+
data.forEach(measurement => {
|
|
196
|
+
values[measurement.time] =
|
|
197
|
+
measurement[details.valueFragmentType][details.valueFragmentSeries].value;
|
|
198
|
+
});
|
|
199
|
+
return { ...details, unit, timeValueMap: values };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Returns a map of active data points device IDs with their corresponding series.
|
|
203
|
+
*
|
|
204
|
+
* Example output:
|
|
205
|
+
* ```typescript
|
|
206
|
+
* new Map([
|
|
207
|
+
* ['844657202', ['c8y_Temperature.T']],
|
|
208
|
+
* ['32666427', ['c8y_Battery.Battery']]
|
|
209
|
+
* ]);
|
|
210
|
+
* ```
|
|
211
|
+
* @param datapointDetails - An array of data points details.
|
|
212
|
+
* @returns A map where the key is the data point ID and the value is an array of data point series.
|
|
213
|
+
*/
|
|
214
|
+
groupSeriesByDeviceId(datapointDetails) {
|
|
215
|
+
return datapointDetails.reduce((map, { valueFragmentType, valueFragmentSeries, source }) => {
|
|
216
|
+
const value = `${valueFragmentType}.${valueFragmentSeries}`;
|
|
217
|
+
const existingValue = map.get(source) ?? [];
|
|
218
|
+
map.set(source, [...existingValue, value]);
|
|
219
|
+
return map;
|
|
220
|
+
}, new Map());
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Processes the fetched series data and prepares it for export.
|
|
224
|
+
*
|
|
225
|
+
* @param datapointDetails - An array of data point details.
|
|
226
|
+
* @param fetchedDataMap - A map of fetched series data grouped by source.
|
|
227
|
+
* @returns An array of DataToExport objects.
|
|
228
|
+
*/
|
|
229
|
+
processSeriesData(datapointDetails, fetchedDataMap) {
|
|
230
|
+
const valuesGroupedBySource = this.utilsService.transformDataStructure(fetchedDataMap);
|
|
231
|
+
return datapointDetails.map((details) => {
|
|
232
|
+
let unit;
|
|
233
|
+
let data;
|
|
234
|
+
/**
|
|
235
|
+
* Unique key to distinguish between different series from same source,
|
|
236
|
+
* e.g.: c8y_Acceleration.accelerationX, c8y_Acceleration.accelerationY, c8y_Acceleration.accelerationZ
|
|
237
|
+
*/
|
|
238
|
+
const seriesKey = `${details.valueFragmentType}.${details.valueFragmentSeries}`;
|
|
239
|
+
if (valuesGroupedBySource[details.source][seriesKey]) {
|
|
240
|
+
unit = valuesGroupedBySource[details.source][seriesKey].seriesDetails.unit;
|
|
241
|
+
data = valuesGroupedBySource[details.source][seriesKey].values;
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
...details,
|
|
245
|
+
unit,
|
|
246
|
+
timeValueMap: data
|
|
247
|
+
};
|
|
248
|
+
});
|
|
249
|
+
}
|
|
154
250
|
async getSourcesWithPermissionsToRead(datapointDetails) {
|
|
155
251
|
const dateFrom = new Date();
|
|
156
252
|
const dateTo = new Date(dateFrom);
|
|
@@ -175,6 +271,56 @@ export class DataFetchingService {
|
|
|
175
271
|
const fetchedSources = await Promise.all(fetchedDataPromises);
|
|
176
272
|
return fetchedSources.filter((source) => source !== null);
|
|
177
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
|
|
276
|
+
*
|
|
277
|
+
* @param date - The date to be adjusted in string format.
|
|
278
|
+
* @param minutes - The number of minutes to add to the date.
|
|
279
|
+
* @param roundSeconds - Whether to round the seconds or not.
|
|
280
|
+
* If true, the seconds will be rounded to 0.
|
|
281
|
+
* If false, the seconds will be displayed as they are.
|
|
282
|
+
* @returns The adjusted date in ISO string format.
|
|
283
|
+
*/
|
|
284
|
+
adjustDate(date, minutes, roundSeconds = true) {
|
|
285
|
+
const dateTime = new Date(date);
|
|
286
|
+
if (isNaN(dateTime.getTime())) {
|
|
287
|
+
throw new Error('Invalid date');
|
|
288
|
+
}
|
|
289
|
+
dateTime.setUTCMinutes(dateTime.getUTCMinutes() + minutes);
|
|
290
|
+
if (roundSeconds) {
|
|
291
|
+
dateTime.setUTCSeconds(0, 0);
|
|
292
|
+
}
|
|
293
|
+
return dateTime.toISOString();
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Asynchronously loads series data based on the provided parameters.
|
|
297
|
+
*
|
|
298
|
+
* This method constructs a filter for retrieving series data within a specified date range,
|
|
299
|
+
* from a specific source, and optionally applying an aggregation type.
|
|
300
|
+
*
|
|
301
|
+
* @param rawFilter - The parameters for loading series data, including date range, source, series names, and aggregation type.
|
|
302
|
+
* @param roundSeconds - Indicates whether to round the seconds in the date range to the nearest whole number.
|
|
303
|
+
* @returns A promise that resolves to series data wrapped in result object.
|
|
304
|
+
*/
|
|
305
|
+
async fetchSeriesData(rawFilter, roundSeconds = false) {
|
|
306
|
+
let seriesData;
|
|
307
|
+
const filter = this.prepareSeriesFilter({
|
|
308
|
+
dateFrom: rawFilter.dateFrom,
|
|
309
|
+
dateTo: rawFilter.dateTo,
|
|
310
|
+
source: rawFilter.source,
|
|
311
|
+
series: rawFilter.series,
|
|
312
|
+
aggregationType: rawFilter.aggregationType
|
|
313
|
+
}, roundSeconds);
|
|
314
|
+
try {
|
|
315
|
+
// TODO: consider adding a cache mechanism -> MTM-60289, MTM-59233
|
|
316
|
+
// When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
|
|
317
|
+
seriesData = await this.measurementService.listSeries(filter);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
this.alertService.addServerFailure(error);
|
|
321
|
+
}
|
|
322
|
+
return seriesData;
|
|
323
|
+
}
|
|
178
324
|
/**
|
|
179
325
|
* Fetches and prepares measurement data for preview.
|
|
180
326
|
*
|
|
@@ -183,11 +329,12 @@ export class DataFetchingService {
|
|
|
183
329
|
* CSV/Excel files are generated by the backend for measurements.
|
|
184
330
|
*
|
|
185
331
|
* @param exportConfig - The export configuration.
|
|
332
|
+
* @param roundSeconds - Indicates whether to round the seconds in the date range to the nearest whole number.
|
|
186
333
|
* @returns A promise that resolves to an array of DataToExport objects or null when no data is fetched.
|
|
187
334
|
*/
|
|
188
|
-
async fetchAndPrepareMeasurementDataToExportForPreview(exportConfig) {
|
|
335
|
+
async fetchAndPrepareMeasurementDataToExportForPreview(exportConfig, roundSeconds = false) {
|
|
189
336
|
const dataToExportPromises = exportConfig.datapointDetails.map(async (details) => {
|
|
190
|
-
const fetchedMeasurementData = await this.fetchMeasurementDataForPreview(details, exportConfig);
|
|
337
|
+
const fetchedMeasurementData = await this.fetchMeasurementDataForPreview(details, exportConfig, roundSeconds);
|
|
191
338
|
if (fetchedMeasurementData?.data?.length) {
|
|
192
339
|
return this.processMeasurementDataForPreview(details, fetchedMeasurementData.data);
|
|
193
340
|
}
|
|
@@ -195,9 +342,9 @@ export class DataFetchingService {
|
|
|
195
342
|
});
|
|
196
343
|
return await Promise.all(dataToExportPromises);
|
|
197
344
|
}
|
|
198
|
-
async fetchMeasurementDataForPreview(details, exportConfig) {
|
|
345
|
+
async fetchMeasurementDataForPreview(details, exportConfig, roundSeconds) {
|
|
199
346
|
let measurements;
|
|
200
|
-
const filter = this.prepareMeasurementsFilter(details, exportConfig, MEASUREMENTS_PREVIEW_ITEMS_LIMIT);
|
|
347
|
+
const filter = this.prepareMeasurementsFilter(details, exportConfig, roundSeconds, MEASUREMENTS_PREVIEW_ITEMS_LIMIT);
|
|
201
348
|
try {
|
|
202
349
|
// TODO: consider adding a cache mechanism -> MTM-60289
|
|
203
350
|
// When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
|
|
@@ -208,30 +355,6 @@ export class DataFetchingService {
|
|
|
208
355
|
}
|
|
209
356
|
return measurements;
|
|
210
357
|
}
|
|
211
|
-
prepareMeasurementsFilter(details, exportConfig, pageSize) {
|
|
212
|
-
const filter = {
|
|
213
|
-
// Round the 'from' time to the previous full minute.
|
|
214
|
-
dateFrom: this.adjustDate(exportConfig.dateFrom, -1),
|
|
215
|
-
// Round the 'to' time to the nearest full minute.
|
|
216
|
-
dateTo: this.adjustDate(exportConfig.dateTo, 1),
|
|
217
|
-
source: details.source,
|
|
218
|
-
valueFragmentSeries: details.valueFragmentSeries,
|
|
219
|
-
valueFragmentType: details.valueFragmentType
|
|
220
|
-
};
|
|
221
|
-
if (pageSize) {
|
|
222
|
-
filter.pageSize = pageSize;
|
|
223
|
-
}
|
|
224
|
-
return filter;
|
|
225
|
-
}
|
|
226
|
-
processMeasurementDataForPreview(details, data) {
|
|
227
|
-
const unit = data[0][details.valueFragmentType][details.valueFragmentSeries]?.unit || '';
|
|
228
|
-
const values = {};
|
|
229
|
-
data.forEach(measurement => {
|
|
230
|
-
values[measurement.time] =
|
|
231
|
-
measurement[details.valueFragmentType][details.valueFragmentSeries].value;
|
|
232
|
-
});
|
|
233
|
-
return { ...details, unit, timeValueMap: values };
|
|
234
|
-
}
|
|
235
358
|
async fetchAndPrepareSeriesDataToExport(exportConfig) {
|
|
236
359
|
const datapointsValuesDataMap = this.groupSeriesByDeviceId(exportConfig.datapointDetails);
|
|
237
360
|
const fetchedDataPromises = Array.from(datapointsValuesDataMap).map(async ([source, series]) => {
|
|
@@ -249,52 +372,10 @@ export class DataFetchingService {
|
|
|
249
372
|
const fetchedDataGroupedBySource = await Promise.all(fetchedDataPromises);
|
|
250
373
|
return this.processSeriesData(exportConfig.datapointDetails, fetchedDataGroupedBySource);
|
|
251
374
|
}
|
|
252
|
-
|
|
253
|
-
* Returns a map of active data points device IDs with their corresponding series.
|
|
254
|
-
*
|
|
255
|
-
* Example output:
|
|
256
|
-
* ```typescript
|
|
257
|
-
* new Map([
|
|
258
|
-
* ['844657202', ['c8y_Temperature.T']],
|
|
259
|
-
* ['32666427', ['c8y_Battery.Battery']]
|
|
260
|
-
* ]);
|
|
261
|
-
* ```
|
|
262
|
-
* @param datapointDetails - An array of data points details.
|
|
263
|
-
* @returns A map where the key is the data point ID and the value is an array of data point series.
|
|
264
|
-
*/
|
|
265
|
-
groupSeriesByDeviceId(datapointDetails) {
|
|
266
|
-
return datapointDetails.reduce((map, { valueFragmentType, valueFragmentSeries, source }) => {
|
|
267
|
-
const value = `${valueFragmentType}.${valueFragmentSeries}`;
|
|
268
|
-
const existingValue = map.get(source) ?? [];
|
|
269
|
-
map.set(source, [...existingValue, value]);
|
|
270
|
-
return map;
|
|
271
|
-
}, new Map());
|
|
272
|
-
}
|
|
273
|
-
async fetchSeriesData(rawFilter) {
|
|
274
|
-
let seriesData;
|
|
275
|
-
const filter = this.prepareSeriesFilter({
|
|
276
|
-
dateFrom: rawFilter.dateFrom,
|
|
277
|
-
dateTo: rawFilter.dateTo,
|
|
278
|
-
source: rawFilter.source,
|
|
279
|
-
series: rawFilter.series,
|
|
280
|
-
aggregationType: rawFilter.aggregationType
|
|
281
|
-
});
|
|
282
|
-
try {
|
|
283
|
-
// TODO: consider adding a cache mechanism -> MTM-60289
|
|
284
|
-
// When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
|
|
285
|
-
seriesData = await this.measurementService.listSeries(filter);
|
|
286
|
-
}
|
|
287
|
-
catch (error) {
|
|
288
|
-
this.alertService.addServerFailure(error);
|
|
289
|
-
}
|
|
290
|
-
return seriesData;
|
|
291
|
-
}
|
|
292
|
-
prepareSeriesFilter(filters) {
|
|
375
|
+
prepareSeriesFilter(filters, roundSeconds) {
|
|
293
376
|
const { dateFrom, dateTo, source, series, aggregationType } = filters;
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
// Round the 'to' time to the nearest full minute.
|
|
297
|
-
const to = this.adjustDate(dateTo, 1);
|
|
377
|
+
const from = this.adjustDate(dateFrom, 0, roundSeconds);
|
|
378
|
+
const to = this.adjustDate(dateTo, 0, roundSeconds);
|
|
298
379
|
const filter = {
|
|
299
380
|
dateFrom: from,
|
|
300
381
|
dateTo: to,
|
|
@@ -316,86 +397,7 @@ export class DataFetchingService {
|
|
|
316
397
|
}
|
|
317
398
|
return filter;
|
|
318
399
|
}
|
|
319
|
-
|
|
320
|
-
* Processes the fetched series data and prepares it for export.
|
|
321
|
-
*
|
|
322
|
-
* @param datapointDetails - An array of data point details.
|
|
323
|
-
* @param fetchedDataMap - A map of fetched series data grouped by source.
|
|
324
|
-
* @returns An array of DataToExport objects.
|
|
325
|
-
*/
|
|
326
|
-
processSeriesData(datapointDetails, fetchedDataMap) {
|
|
327
|
-
const valuesGroupedBySource = this.utilsService.transformDataStructure(fetchedDataMap);
|
|
328
|
-
return datapointDetails.map((details) => {
|
|
329
|
-
let unit;
|
|
330
|
-
let data;
|
|
331
|
-
/**
|
|
332
|
-
* Unique key to distinguish between different series from same source,
|
|
333
|
-
* e.g.: c8y_Acceleration.accelerationX, c8y_Acceleration.accelerationY, c8y_Acceleration.accelerationZ
|
|
334
|
-
*/
|
|
335
|
-
const seriesKey = `${details.valueFragmentType}.${details.valueFragmentSeries}`;
|
|
336
|
-
if (valuesGroupedBySource[details.source][seriesKey]) {
|
|
337
|
-
unit = valuesGroupedBySource[details.source][seriesKey].seriesDetails.unit;
|
|
338
|
-
data = valuesGroupedBySource[details.source][seriesKey].values;
|
|
339
|
-
}
|
|
340
|
-
return {
|
|
341
|
-
...details,
|
|
342
|
-
unit,
|
|
343
|
-
timeValueMap: data
|
|
344
|
-
};
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
|
|
349
|
-
*
|
|
350
|
-
* @param date - The date to be adjusted in string format.
|
|
351
|
-
* @param minutes - The number of minutes to add to the date.
|
|
352
|
-
* @returns The adjusted date in the format 'YYYY-MM-DDTHH:mm:ss+HH:MM'.
|
|
353
|
-
*/
|
|
354
|
-
adjustDate(date, minutes) {
|
|
355
|
-
const dateTime = new Date(date);
|
|
356
|
-
dateTime.setMinutes(dateTime.getMinutes() + minutes);
|
|
357
|
-
dateTime.setSeconds(0);
|
|
358
|
-
const offset = -dateTime.getTimezoneOffset();
|
|
359
|
-
const offsetSign = offset >= 0 ? '+' : '-';
|
|
360
|
-
const pad = (num) => (num < 10 ? '0' + num : num.toString());
|
|
361
|
-
const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
|
|
362
|
-
const offsetMinutes = pad(Math.abs(offset) % 60);
|
|
363
|
-
const year = dateTime.getFullYear();
|
|
364
|
-
const month = pad(dateTime.getMonth() + 1);
|
|
365
|
-
const day = pad(dateTime.getDate());
|
|
366
|
-
const hours = pad(dateTime.getHours());
|
|
367
|
-
const minutesString = pad(dateTime.getMinutes());
|
|
368
|
-
const seconds = '00';
|
|
369
|
-
return `${year}-${month}-${day}T${hours}:${minutesString}:${seconds}${offsetSign}${offsetHours}:${offsetMinutes}`;
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Trims the given HTML message by removing list items that correspond to zero counts.
|
|
373
|
-
*
|
|
374
|
-
* @param message - The HTML string containing the message with list items.
|
|
375
|
-
* @param counts - An array of number values corresponding to each list item.
|
|
376
|
-
* @param countToTrim - A count that will be trimmed with corresponding list item.
|
|
377
|
-
* @returns A trimmed HTML string with list items removed where the corresponding count is zero.
|
|
378
|
-
*
|
|
379
|
-
* Example:
|
|
380
|
-
* ```typescript
|
|
381
|
-
* const message = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
|
|
382
|
-
* const counts = [1, 0, 2];
|
|
383
|
-
* const trimmedMessage = this.removeZeroCountListItems(message, counts);
|
|
384
|
-
* // Result: '<ul><li>Item 1</li><li>Item 3</li></ul>'
|
|
385
|
-
* ```
|
|
386
|
-
*/
|
|
387
|
-
removeZeroCountListItems(message, counts, countToTrim = 0) {
|
|
388
|
-
const parser = new DOMParser();
|
|
389
|
-
const doc = parser.parseFromString(message, 'text/html');
|
|
390
|
-
const listItems = doc.querySelectorAll('ul li');
|
|
391
|
-
listItems.forEach((item, index) => {
|
|
392
|
-
if (counts[index] === countToTrim) {
|
|
393
|
-
item.remove();
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
|
-
return doc.body.innerHTML;
|
|
397
|
-
}
|
|
398
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, deps: [{ token: i1.AlertService }, { token: i2.MeasurementService }, { token: i3.DomSanitizer }, { token: i4.TranslateService }, { token: i5.UtilsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
400
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, deps: [{ token: i1.AlertService }, { token: i2.MeasurementService }, { token: i3.TranslateService }, { token: i4.UtilsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
399
401
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, providedIn: 'root' }); }
|
|
400
402
|
}
|
|
401
403
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, decorators: [{
|
|
@@ -403,5 +405,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
403
405
|
args: [{
|
|
404
406
|
providedIn: 'root'
|
|
405
407
|
}]
|
|
406
|
-
}], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.MeasurementService }, { type: i3.
|
|
407
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mZXRjaGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3IvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItbW9kYWwvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItZmlsZS1leHBvcnRlci9kYXRhLWZldGNoaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQVNMLGtCQUFrQixFQUNuQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFRTCxnQ0FBZ0MsRUFFakMsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQWMsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7Ozs7QUFLM0QsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixZQUNVLFlBQTBCLEVBQzFCLGtCQUFzQyxFQUN0QyxTQUF1QixFQUN2QixnQkFBa0MsRUFDbEMsWUFBMEI7UUFKMUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxjQUFTLEdBQVQsU0FBUyxDQUFjO1FBQ3ZCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7SUFDakMsQ0FBQztJQUVKOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLDJCQUEyQixDQUMvQixZQUEwQjtRQUUxQixNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FB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QUssSUFBSSxhQUFhLElBQUksT0FBTyxHQUFHLFVBQVUsR0FBRyxXQUFXLElBQUksYUFBYSxFQUFFLENBQUM7SUFDcEgsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNLLHdCQUF3QixDQUFDLE9BQWUsRUFBRSxNQUFnQixFQUFFLFdBQVcsR0FBRyxDQUFDO1FBQ2pGLE1BQU0sTUFBTSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDekQsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzVCLENBQUM7OEdBcmdCVSxtQkFBbUI7a0hBQW5CLG1CQUFtQixjQUZsQixNQUFNOzsyRkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQge1xuICBhZ2dyZWdhdGlvblR5cGUsXG4gIElGZXRjaFJlc3BvbnNlLFxuICBJTWVhc3VyZW1lbnQsXG4gIElNZWFzdXJlbWVudEZpbHRlcixcbiAgSVJlc3VsdCxcbiAgSVJlc3VsdExpc3QsXG4gIElTZXJpZXMsXG4gIElTZXJpZXNGaWx0ZXIsXG4gIE1lYXN1cmVtZW50U2VydmljZVxufSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBBR0dSRUdBVElPTl9WQUxVRVMsIEFsZXJ0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtcbiAgRGF0YXBvaW50RGV0YWlscyxcbiAgRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0LFxuICBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCxcbiAgRGF0YVRvRXhwb3J0LFxuICBEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlLFxuICBFeHBvcnRDb25maWcsXG4gIE1lYXN1cmVtZW50RmlsZUNvbmZpZyxcbiAgTUVBU1VSRU1FTlRTX1BSRVZJRVdfSVRFTVNfTElNSVQsXG4gIFRpbWVTZXJpZXNEYXRhXG59IGZyb20gJy4uLy4uL2RhdGFwb2ludHMtZXhwb3J0LXNlbGVjdG9yLm1vZGVsJztcbmltcG9ydCB7IFNvdXJjZUl0ZW0sIFV0aWxzU2VydmljZSB9IGZyb20gJy4vdXRpbHMuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIERhdGFGZXRjaGluZ1NlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFsZXJ0U2VydmljZTogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWVhc3VyZW1lbnRTZXJ2aWNlOiBNZWFzdXJlbWVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhbnkgb2YgbWVhc3VyZW1lbnRzIHJlcXVlc3RzIG1heSBleGNlZWRlZCB0aGUgbGltaXQsXG4gICAqIGFmdGVyIHdoaWNoIHRoZSBleHBvcnQgZGF0YSBpcyBwcm9jZXNzZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHRoZSBnZW5lcmF0ZWQgQ1NWL0V4Y2VsIGZpbGUgaXMgc2VudCBieSBlbWFpbC5cbiAgICpcbiAgICogVGhlIHRocmVzaG9sZCBpcyBzZXQgdG8gNTBfMDAwIHJlY29yZHMgaW4gYXBwbGljYXRpb24ncyBjb3JlIHByb3BlcnRpZXMgKGV4cG9ydC5kYXRhLnN5bmNocm9ub3VzLmxpbWl0KS5cbiAgICpcbiAgICogQHBhcmFtIGV4cG9ydENvbmZpZyAtIFRoZSBleHBvcnQgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmV0dXJucyBhbiBhcnJheSBvZiBvYmplY3RzIHJlcHJlc2VudGluZyBkYXRhcG9pbnRzIGZpbGVzIHRoYXQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0KFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W10+IHtcbiAgICBjb25zdCBiYWNrZW5kUHJvY2Vzc2luZ0xpbWl0ID0gNTBfMDAwO1xuXG4gICAgY29uc3QgcHJvbWlzZXM6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0PltdID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKFxuICAgICAgYXN5bmMgZGV0YWlscyA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICAgICAgICBkYXRlRnJvbTogZXhwb3J0Q29uZmlnLmRhdGVGcm9tLFxuICAgICAgICAgICAgZGF0ZVRvOiBleHBvcnRDb25maWcuZGF0ZVRvLFxuICAgICAgICAgICAgcGFnZVNpemU6IDEsXG4gICAgICAgICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGUsXG4gICAgICAgICAgICB3aXRoVG90YWxFbGVtZW50czogdHJ1ZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3QoZmlsdGVyKTtcblxuICAgICAgICAgIGlmIChyZXNwb25zZT8ucGFnaW5nPy50b3RhbEVsZW1lbnRzID4gYmFja2VuZFByb2Nlc3NpbmdMaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZGF0YXBvaW50RGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgICAgICAgICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG90YWxFbGVtZW50czogcmVzcG9uc2UucGFnaW5nLnRvdGFsRWxlbWVudHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzOiBEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRbXSA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblxuICAgIGNvbnN0IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdCA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiByZXN1bHQgIT09IG51bGwpO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIHdoZW4gdGhlIGxpbWl0IG9mIGRhdGFwb2ludHMgaXMgZXhjZWVkZWQgZHVyaW5nIGZpbGUgZXhwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gaGFzTm9FeHBvcnRhYmxlRGF0YSAtIEluZGljYXRlcyBpZiB0aGVyZSBpcyBubyBleHBvcnRhYmxlIGRhdGEgYmVjYXVzZSB0aGUgZGF0ZSByYW5nZSBvZiBhbGwgc2VsZWN0ZWQgZGF0YXBvaW50cyBleGNlZWRzIDEsMDAwLDAwMCByZWNvcmRzLlxuICAgKiBAcGFyYW0gZW1haWxEZWxpdmVyYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGV4Y2VlZCB0aGUgbGltaXQsIHdpbGwgYmUgcHJvY2VlZGVkIGJ5IHRoZSBiYWNrZW5kIGFuZCBzZW50IGJ5IGVtYWlsLlxuICAgKiBAcGFyYW0gYnJvd3NlckRvd25sb2FkYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGNhbiBiZSBkb3dubG9hZGVkIGRpcmVjdGx5LlxuICAgKiBAcGFyYW0gc2tpcHBlZERhdGFwb2ludENvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyBza2lwcGVkIGR1ZSB0byBleGNlZWRpbmcgdGhlIG1lYXN1cmVtZW50cyBBUEkgbGltaXQgb2YgMSwwMDAsMDAwIHJlY29yZHMuXG4gICAqIEBwYXJhbSB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50IC0gVG90YWwgbnVtYmVyIG9mIGRhdGFwb2ludCBzZWxlY3RlZCBmb3IgZXhwb3J0cy5cbiAgICogQHJldHVybnMgVGhlIG1lc3NhZ2UgdGhhdCBjYW4gYmUgaW5qZWN0ZWQuXG4gICAqL1xuICBnZXRMaW1pdEV4Y2VlZGVkTWVzc2FnZShcbiAgICBoYXNOb0V4cG9ydGFibGVEYXRhOiBib29sZWFuLFxuICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudD86IG51bWJlcixcbiAgICBicm93c2VyRG93bmxvYWRhYmxlQ291bnQ/OiBudW1iZXIsXG4gICAgbm9uUmV0cmlldmFibGVDb3VudD86IG51bWJlcixcbiAgICB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50PzogbnVtYmVyXG4gICk6IHN0cmluZyB7XG4gICAgaWYgKGhhc05vRXhwb3J0YWJsZURhdGEpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgZ2V0dGV4dChcbiAgICAgICAgICBgVGhlIGRhdGEgZm9yIHNlbGVjdGVkIGRhdGFwb2ludChzKSBleGNlZWQgMSwwMDAsMDAwIHJlY29yZHMsIHdoaWNoIGlzIHRoZSBsaW1pdCBmb3IgYmFja2VuZCBwcm9jZXNzaW5nLiBUbyBleHBvcnQgdGhpcyBkYXRhLCBwbGVhc2UgcmVkdWNlIHRoZSBkYXRlIHJhbmdlLmBcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgIGdldHRleHQoXG4gICAgICAgIGBBZnRlciBjbGlja2luZyBcIkRvd25sb2FkXCI6PGJyPlxuICAgICAgICA8dWw+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skYnJvd3NlckRvd25sb2FkYWJsZUNvdW50fX08L3N0cm9uZz4gZGF0YXBvaW50KHMpIGV4cG9ydHMgd2lsbCBiZSBkb3dubG9hZGVkIGRpcmVjdGx5IHdpdGhpbiBvbmUgZmlsZTogPGVtPmV4cG9ydGVkX1tjc3YvZXhjZWxdLnppcDwvZW0+PC9saT5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRlbWFpbERlbGl2ZXJhYmxlQ291bnR9fTwvc3Ryb25nPiBkYXRhcG9pbnQocykgZXhwb3J0cyByZXF1aXJlIGZ1cnRoZXIgcHJvY2Vzc2luZy4gVGhlIGZpbGVzIHdpbGwgYmUgc2VudCB0byB5b3UgdmlhIHNlcGFyYXRlIGVtYWlscyBvbmNlIGNvbXBsZXRlZCwgd2hpY2ggbWF5IHRha2Ugc29tZSB0aW1lLjwvbGk+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skbm9uUmV0cmlldmFibGVDb3VudH19PC9zdHJvbmc+IGRhdGFwb2ludChzKSBleHBvcnRzIGV4Y2VlZGVkIDEsMDAwLDAwMCByZWNvcmRzLCB3aGljaCBpcyB0aGUgbGltaXQgZm9yIGJhY2tlbmQgcHJvY2Vzc2luZy4gVG8gZXhwb3J0IHRoZXNlIGRhdGEsIHBsZWFzZSByZWR1Y2UgdGhlIGRhdGUgcmFuZ2UuIE90aGVyd2lzZSwgdGhlIGRhdGEgd2lsbCBuZWl0aGVyIGJlIGRvd25sb2FkZWQgbm9yIHNlbnQgdmlhIGVtYWlsLjwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICAgIDxwPlRoZSB0b3RhbCBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBjYW4gYmUgZXhwb3J0ZWQgaXM6IDxzdHJvbmc+e3skdG90YWxFeHBvcnRhYmxlRGF0YXBvaW50c0NvdW50fX0gb3V0IG9mIHt7JHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnR9fTwvc3Ryb25nPi5cbiAgICAgICAgPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmlsZSBuYW1lIGNvbnZlbnRpb24gb2YgZmlsZXMgd2l0aGluIHppcCBmaWxlIGlzOiA8Y29kZT5bc291cmNlXV9bZnJhZ21lbnRfc2VyaWVzXS5bY3N2L3hsc108L2NvZGU+PC9wPmBcbiAgICAgICksXG4gICAgICB7XG4gICAgICAgICRicm93c2VyRG93bmxvYWRhYmxlQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgICAgJGVtYWlsRGVsaXZlcmFibGVDb3VudDogZW1haWxEZWxpdmVyYWJsZUNvdW50LFxuICAgICAgICAkbm9uUmV0cmlldmFibGVDb3VudDogbm9uUmV0cmlldmFibGVDb3VudCxcbiAgICAgICAgJHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ6IHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQsXG4gICAgICAgICR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCArIGVtYWlsRGVsaXZlcmFibGVDb3VudFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCB0cmltbWVkTWVzc2FnZSA9IHRoaXMucmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2UsIFtcbiAgICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudCxcbiAgICAgIG5vblJldHJpZXZhYmxlQ291bnRcbiAgICBdKTtcblxuICAgIHJldHVybiB0cmltbWVkTWVzc2FnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBhbiBpbmZvcm1hdGlvbiBhbGVydCBhYm91dCBzZW5kaW5nIGRhdGEgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBPbmx5IG1lYXN1cmVtZW50cyBBUEkgY2FuIHNlbmQgZmlsZXMgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZVR5cGUgLSBUaGUgdHlwZSBvZiBmaWxlIHRvIGJlIHNlbnQuXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQgLSBUaGUgYXJyYXkgb2YgZGF0YXBvaW50cyBleGNlZWRpbmcgdGhlIGxpbWl0LlxuICAgKi9cbiAgc2hvd1NlbmRWaWFFbWFpbEluZm9BbGVydChcbiAgICBmaWxlVHlwZTogc3RyaW5nLFxuICAgIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDogRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZVRlbXBsYXRlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KGBZb3Ugd2lsbCBnZXQge3skZmlsZVR5cGVUZXh0fX0gZmlsZShzKSBmb3Ige3skY291bnR9fSBzZXJpZXMgdmlhIGVtYWlsLmApLFxuICAgICAgeyAkY291bnQ6IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdC5sZW5ndGgsICRmaWxlVHlwZVRleHQ6IGZpbGVUeXBlIH1cbiAgICApO1xuICAgIGNvbnN0IGZvcm1hdHRlZExpc3QgPSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRcbiAgICAgIC5tYXAoXG4gICAgICAgIGRhdGFwb2ludCA9PlxuICAgICAgICAgIGDigKIgJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnNvdXJjZX1fJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnZhbHVlRnJhZ21lbnRUeXBlfV8ke2RhdGFwb2ludC5kYXRhcG9pbnREZXRhaWwudmFsdWVGcmFnbWVudFNlcmllc31gXG4gICAgICApXG4gICAgICAuam9pbignXFxuJyk7XG5cbiAgICB0aGlzLmFsZXJ0U2VydmljZS5pbmZvKG1lc3NhZ2VUZW1wbGF0ZSwgZm9ybWF0dGVkTGlzdCk7XG4gIH1cblxuICBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZpbGVzQW5kUGFpcldpdGhTb3VyY2VEZXRhaWxzKFxuICAgIGFjY2VwdEZpbGVUeXBlOiBzdHJpbmcsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlW10+IHtcbiAgICBjb25zdCBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyA9IHtcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIGFjY2VwdEZpbGVUeXBlXG4gICAgfTtcbiAgICBjb25zdCBmaWxlUHJvbWlzZXMgPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoZGV0YWlscyA9PlxuICAgICAgdGhpcy5mZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlQ29uZmlnKVxuICAgICk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGZpbGVQcm9taXNlcyk7XG4gIH1cblxuICBhc3luYyBmZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZ1xuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGUgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBtZWFzdXJlbWVudEZpbGVDb25maWcuZXhwb3J0Q29uZmlnXG4gICAgKTtcbiAgICBjb25zdCBoZWFkZXIgPSB7IGFjY2VwdDogbWVhc3VyZW1lbnRGaWxlQ29uZmlnLmFjY2VwdEZpbGVUeXBlIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2U6IElGZXRjaFJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UuZ2V0TWVhc3VyZW1lbnRzRmlsZShmaWx0ZXIsIGhlYWRlcik7XG5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAwLCB0aGVuIHRoZSBmaWxlIGlzIGluIHRoZSByZXNwb25zZS5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAyLCB0aGVuIHRoZSBmaWxlIGlzIGJlaW5nIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgICAgaWYgKG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lcmdlTWVhc3VyZW1lbnRzV2l0aEl0c1NvdXJjZURldGFpbHMoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBtZXJnZU1lYXN1cmVtZW50c1dpdGhJdHNTb3VyY2VEZXRhaWxzKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgbWVhc3VyZW1lbnRGaWxlOiBJRmV0Y2hSZXNwb25zZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgIHZhbHVlRnJhZ21lbnRUeXBlOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlLFxuICAgICAgZmV0Y2hlZE1lYXN1cmVtZW50c0Jsb2JGaWxlOiBhd2FpdCBtZWFzdXJlbWVudEZpbGUuYmxvYigpXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoQW5kUHJlcGFyZURhdGFUb0V4cG9ydChcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICBpc01lYXN1cmVtZW50OiBib29sZWFuXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHtcbiAgICByZXR1cm4gaXNNZWFzdXJlbWVudFxuICAgICAgPyBhd2FpdCB0aGlzLmZldGNoQW5kUHJlcGFyZU1lYXN1cmVtZW50RGF0YVRvRXhwb3J0Rm9yUHJldmlldyhleHBvcnRDb25maWcpXG4gICAgICA6IGF3YWl0IHRoaXMuZmV0Y2hBbmRQcmVwYXJlU2VyaWVzRGF0YVRvRXhwb3J0KGV4cG9ydENvbmZpZyk7XG4gIH1cblxuICBhc3luYyBnZXRTb3VyY2VzV2l0aFBlcm1pc3Npb25zVG9SZWFkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBkYXRlRnJvbSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgZGF0ZVRvID0gbmV3IERhdGUoZGF0ZUZyb20pO1xuXG4gICAgY29uc3QgZmV0Y2hlZERhdGFQcm9taXNlcyA9IGRhdGFwb2ludERldGFpbHMubWFwKGFzeW5jIGRhdGFwb2ludCA9PiB7XG4gICAgICBjb25zdCByYXdGaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICAgIGRhdGVGcm9tLFxuICAgICAgICBkYXRlVG8sXG4gICAgICAgIHNvdXJjZTogZGF0YXBvaW50LnNvdXJjZVxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyByZXMgfTogSVJlc3VsdDxJU2VyaWVzPiA9IGF3YWl0IHRoaXMuZmV0Y2hTZXJpZXNEYXRhKHJhd0ZpbHRlcik7XG4gICAgICAgIGlmIChyZXM/LnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFwb2ludC5zb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGZldGNoLCByZXR1cm4gbnVsbCB0byBwcmV2ZW50IHByb21pc2UgcmVqZWN0aW9uXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZmV0Y2hlZFNvdXJjZXMgPSBhd2FpdCBQcm9taXNlLmFsbChmZXRjaGVkRGF0YVByb21pc2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZFNvdXJjZXMuZmlsdGVyKChzb3VyY2UpOiBzb3VyY2UgaXMgc3RyaW5nID0+IHNvdXJjZSAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2hlcyBhbmQgcHJlcGFyZXMgbWVhc3VyZW1lbnQgZGF0YSBmb3IgcHJldmlldy5cbiAgICpcbiAgICogRW1wdHkgRGF0YVRvRXhwb3J0IG9iamVjdCBjYW4gYmUgcmV0dXJuZWQsIGJlY2F1c2UgdW5saWtlIHNlcmllcyBkYXRhLFxuICAgKiBtZWFzdXJlbWVudCBkYXRhIGlzIG5vdCBmdXJ0aGVyIHByb2Nlc3NlZCBiZXNpZGVzIHNob3dpbmcgb25seSBpbiB0aGUgcHJldmlldy5cbiAgICogQ1NWL0V4Y2VsIGZpbGVzIGFyZSBnZW5lcmF0ZWQgYnkgdGhlIGJhY2tlbmQgZm9yIG1lYXN1cmVtZW50cy5cbiAgICpcbiAgICogQHBhcmFtIGV4cG9ydENvbmZpZyAtIFRoZSBleHBvcnQgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgRGF0YVRvRXhwb3J0IG9iamVjdHMgb3IgbnVsbCB3aGVuIG5vIGRhdGEgaXMgZmV0Y2hlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hBbmRQcmVwYXJlTWVhc3VyZW1lbnREYXRhVG9FeHBvcnRGb3JQcmV2aWV3KFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHwgbnVsbCB7XG4gICAgY29uc3QgZGF0YVRvRXhwb3J0UHJvbWlzZXM6IFByb21pc2U8RGF0YVRvRXhwb3J0PltdID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKFxuICAgICAgYXN5bmMgZGV0YWlscyA9PiB7XG4gICAgICAgIGNvbnN0IGZldGNoZWRNZWFzdXJlbWVudERhdGE6IElSZXN1bHRMaXN0PElNZWFzdXJlbWVudD4gPVxuICAgICAgICAgIGF3YWl0IHRoaXMuZmV0Y2hNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KGRldGFpbHMsIGV4cG9ydENvbmZpZyk7XG5cbiAgICAgICAgaWYgKGZldGNoZWRNZWFzdXJlbWVudERhdGE/LmRhdGE/Lmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KGRldGFpbHMsIGZldGNoZWRNZWFzdXJlbWVudERhdGEuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChkYXRhVG9FeHBvcnRQcm9taXNlcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8SVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50Pj4gfCB1bmRlZmluZWQge1xuICAgIGxldCBtZWFzdXJlbWVudHM6IElSZXN1bHRMaXN0PElNZWFzdXJlbWVudD4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBleHBvcnRDb25maWcsXG4gICAgICBNRUFTVVJFTUVOVFNfUFJFVklFV19JVEVNU19MSU1JVFxuICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gVE9ETzogY29uc2lkZXIgYWRkaW5nIGEgY2FjaGUgbWVjaGFuaXNtIC0+IE1UTS02MDI4OVxuICAgICAgLy8gV2hlbiB1c2VyIHN3aXRjaGVzIGJldHdlZW4gcmVwb3J0IHR5cGVzLCBhbmQgcmVzdCBvZiB0aGUgc2V0dGluZ3MgYXJlIHRoZSBzYW1lLCB0aGVuIHRoZSBkYXRhIHNob3VsZCBub3QgYmUgZmV0Y2hlZCBhZ2Fpbj9cbiAgICAgIG1lYXN1cmVtZW50cyA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3QoZmlsdGVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lYXN1cmVtZW50cztcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnLFxuICAgIHBhZ2VTaXplPzogbnVtYmVyXG4gICk6IElNZWFzdXJlbWVudEZpbHRlciB7XG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICAvLyBSb3VuZCB0aGUgJ2Zyb20nIHRpbWUgdG8gdGhlIHByZXZpb3VzIGZ1bGwgbWludXRlLlxuICAgICAgZGF0ZUZyb206IHRoaXMuYWRqdXN0RGF0ZShleHBvcnRDb25maWcuZGF0ZUZyb20sIC0xKSxcbiAgICAgIC8vIFJvdW5kIHRoZSAndG8nIHRpbWUgdG8gdGhlIG5lYXJlc3QgZnVsbCBtaW51dGUuXG4gICAgICBkYXRlVG86IHRoaXMuYWRqdXN0RGF0ZShleHBvcnRDb25maWcuZGF0ZVRvLCAxKSxcbiAgICAgIHNvdXJjZTogZGV0YWlscy5zb3VyY2UsXG4gICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZVxuICAgIH07XG5cbiAgICBpZiAocGFnZVNpemUpIHtcbiAgICAgIGZpbHRlci5wYWdlU2l6ZSA9IHBhZ2VTaXplO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXI7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgZGF0YTogSU1lYXN1cmVtZW50W11cbiAgKTogRGF0YVRvRXhwb3J0IHtcbiAgICBjb25zdCB1bml0ID0gZGF0YVswXVtkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlXVtkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXNdPy51bml0IHx8ICcnO1xuXG4gICAgY29uc3QgdmFsdWVzOiB7IFt0aW1lc3RhbXA6IHN0cmluZ106IG51bWJlciB9ID0ge307XG4gICAgZGF0YS5mb3JFYWNoKG1lYXN1cmVtZW50ID0+IHtcbiAgICAgIHZhbHVlc1ttZWFzdXJlbWVudC50aW1lXSA9XG4gICAgICAgIG1lYXN1cmVtZW50W2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGVdW2RldGFpbHMudmFsdWVGcmFnbWVudFNlcmllc10udmFsdWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyAuLi5kZXRhaWxzLCB1bml0LCB0aW1lVmFsdWVNYXA6IHZhbHVlcyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVTZXJpZXNEYXRhVG9FeHBvcnQoZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcpIHtcbiAgICBjb25zdCBkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAgPSB0aGlzLmdyb3VwU2VyaWVzQnlEZXZpY2VJZChcbiAgICAgIGV4cG9ydENvbmZpZy5kYXRhcG9pbnREZXRhaWxzXG4gICAgKTtcblxuICAgIGNvbnN0IGZldGNoZWREYXRhUHJvbWlzZXMgPSBBcnJheS5mcm9tKGRhdGFwb2ludHNWYWx1ZXNEYXRhTWFwKS5tYXAoXG4gICAgICBhc3luYyAoW3NvdXJjZSwgc2VyaWVzXSkgPT4ge1xuICAgICAgICBjb25zdCB7IGRhdGVGcm9tLCBkYXRlVG8sIGFnZ3JlZ2F0aW9uIH0gPSBleHBvcnRDb25maWc7XG5cbiAgICAgICAgY29uc3QgcmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyID0ge1xuICAgICAgICAgIGRhdGVGcm9tLFxuICAgICAgICAgIGRhdGVUbyxcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgc2VyaWVzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogYWdncmVnYXRpb24gYXMgYWdncmVnYXRpb25UeXBlXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgeyBkYXRhIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmZldGNoU2VyaWVzRGF0YShyYXdGaWx0ZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHNvdXJjZSwgZGF0YSB9O1xuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCBmZXRjaGVkRGF0YUdyb3VwZWRCeVNvdXJjZTogU291cmNlSXRlbVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoZmV0Y2hlZERhdGFQcm9taXNlcyk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzU2VyaWVzRGF0YShleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscywgZmV0Y2hlZERhdGFHcm91cGVkQnlTb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBtYXAgb2YgYWN0aXZlIGRhdGEgcG9pbnRzIGRldmljZSBJRHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHNlcmllcy5cbiAgICpcbiAgICogRXhhbXBsZSBvdXRwdXQ6XG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IE1hcChbXG4gICAqICAgWyc4NDQ2NTcyMDInLCBbJ2M4eV9UZW1wZXJhdHVyZS5UJ11dLFxuICAgKiAgIFsnMzI2NjY0MjcnLCBbJ2M4eV9CYXR0ZXJ5LkJhdHRlcnknXV1cbiAgICogXSk7XG4gICAqIGBgYFxuICAgKiBAcGFyYW0gZGF0YXBvaW50RGV0YWlscyAtIEFuIGFycmF5IG9mIGRhdGEgcG9pbnRzIGRldGFpbHMuXG4gICAqIEByZXR1cm5zIEEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgdGhlIGRhdGEgcG9pbnQgSUQgYW5kIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSBvZiBkYXRhIHBvaW50IHNlcmllcy5cbiAgICovXG4gIHByaXZhdGUgZ3JvdXBTZXJpZXNCeURldmljZUlkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwIHtcbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIG1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gICAgICAgIHsgdmFsdWVGcmFnbWVudFR5cGUsIHZhbHVlRnJhZ21lbnRTZXJpZXMsIHNvdXJjZSB9OiBEYXRhcG9pbnREZXRhaWxzXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBgJHt2YWx1ZUZyYWdtZW50VHlwZX0uJHt2YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSBtYXAuZ2V0KHNvdXJjZSkgPz8gW107XG4gICAgICAgIG1hcC5zZXQoc291cmNlLCBbLi4uZXhpc3RpbmdWYWx1ZSwgdmFsdWVdKTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgIH0sXG4gICAgICBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaFNlcmllc0RhdGEocmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyKTogUHJvbWlzZTxJUmVzdWx0PElTZXJpZXM+PiB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IHNlcmllc0RhdGE6IElSZXN1bHQ8SVNlcmllcz4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB0aGlzLnByZXBhcmVTZXJpZXNGaWx0ZXIoe1xuICAgICAgZGF0ZUZyb206IHJhd0ZpbHRlci5kYXRlRnJvbSxcbiAgICAgIGRhdGVUbzogcmF3RmlsdGVyLmRhdGVUbyxcbiAgICAgIHNvdXJjZTogcmF3RmlsdGVyLnNvdXJjZSxcbiAgICAgIHNlcmllczogcmF3RmlsdGVyLnNlcmllcyxcbiAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogcmF3RmlsdGVyLmFnZ3JlZ2F0aW9uVHlwZVxuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBhIGNhY2hlIG1lY2hhbmlzbSAtPiBNVE0tNjAyODlcbiAgICAgIC8vIFdoZW4gdXNlciBzd2l0Y2hlcyBiZXR3ZWVuIHJlcG9ydCB0eXBlcywgYW5kIHJlc3Qgb2YgdGhlIHNldHRpbmdzIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZGF0YSBzaG91bGQgbm90IGJlIGZldGNoZWQgYWdhaW4/XG4gICAgICBzZXJpZXNEYXRhID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdFNlcmllcyhmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWVzRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZVNlcmllc0ZpbHRlcihmaWx0ZXJzOiBJU2VyaWVzRmlsdGVyKTogSVNlcmllc0ZpbHRlciB7XG4gICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvLCBzb3VyY2UsIHNlcmllcywgYWdncmVnYXRpb25UeXBlIH0gPSBmaWx0ZXJzO1xuICAgIC8vIFJvdW5kIHRoZSAnZnJvbScgdGltZSB0byB0aGUgcHJldmlvdXMgZnVsbCBtaW51dGUuXG4gICAgY29uc3QgZnJvbSA9IHRoaXMuYWRqdXN0RGF0ZShkYXRlRnJvbSwgLTEpO1xuICAgIC8vIFJvdW5kIHRoZSAndG8nIHRpbWUgdG8gdGhlIG5lYXJlc3QgZnVsbCBtaW51dGUuXG4gICAgY29uc3QgdG8gPSB0aGlzLmFkanVzdERhdGUoZGF0ZVRvLCAxKTtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHtcbiAgICAgIGRhdGVGcm9tOiBmcm9tLFxuICAgICAgZGF0ZVRvOiB0byxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgcmV2ZXJ0OiB0cnVlXG4gICAgfTtcblxuICAgIC8vIFRoZSAnTk9ORScgYWdncmVnYXRpb24gdHlwZSBpcyBub3QgaGFuZGxlZCBieSBhIGJhY2tlbmQsIHNvIGV2ZW4gd2hlbiBpcyBzZWxlY3RlZCwgaXQgaXMgbm90IHBhc3NlZCBhcyBhIGZpbHRlciBwYXJhbWV0ZXIuXG4gICAgaWYgKGFnZ3JlZ2F0aW9uVHlwZSAmJiBhZ2dyZWdhdGlvblR5cGUgIT09IChBR0dSRUdBVElPTl9WQUxVRVMubm9uZSBhcyBhZ2dyZWdhdGlvblR5cGUpKSB7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRpb25UeXBlID0gYWdncmVnYXRpb25UeXBlO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGl0IGlzIGEgdGVtcG9yYWwgd29ya2Fyb3VuZCBmb3IgYSBidWcgaW4gdGhlIGJhY2tlbmQsXG4gICAgLy8gd2hlcmUgdGhlIHNlcmllcyB3aXRoIG1vcmUgdGhhbiBvbmUgZG90IGFyZSBpbXBvc3NpYmxlIHRvIHJldHJpZXZlOlxuICAgIC8vIGh0dHBzOi8vY3VtdWxvY2l0eS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9NVE0tNTkyNzdcbiAgICBpZiAoc2VyaWVzKSB7XG4gICAgICBjb25zdCBoYXNNb3JlVGhhbk9uZURvdCA9IChzZXJpZXMgYXMgc3RyaW5nW10pLnNvbWUocyA9PiBzLnNwbGl0KCcuJykubGVuZ3RoID4gMik7XG4gICAgICBpZiAoIWhhc01vcmVUaGFuT25lRG90KSB7XG4gICAgICAgIGZpbHRlci5zZXJpZXMgPSBzZXJpZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgdGhlIGZldGNoZWQgc2VyaWVzIGRhdGEgYW5kIHByZXBhcmVzIGl0IGZvciBleHBvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhcG9pbnREZXRhaWxzIC0gQW4gYXJyYXkgb2YgZGF0YSBwb2ludCBkZXRhaWxzLlxuICAgKiBAcGFyYW0gZmV0Y2hlZERhdGFNYXAgLSBBIG1hcCBvZiBmZXRjaGVkIHNlcmllcyBkYXRhIGdyb3VwZWQgYnkgc291cmNlLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBEYXRhVG9FeHBvcnQgb2JqZWN0cy5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc1Nlcmllc0RhdGEoZGF0YXBvaW50RGV0YWlsczogRGF0YXBvaW50RGV0YWlsc1tdLCBmZXRjaGVkRGF0YU1hcDogU291cmNlSXRlbVtdKSB7XG4gICAgY29uc3QgdmFsdWVzR3JvdXBlZEJ5U291cmNlID0gdGhpcy51dGlsc1NlcnZpY2UudHJhbnNmb3JtRGF0YVN0cnVjdHVyZShmZXRjaGVkRGF0YU1hcCk7XG5cbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5tYXAoKGRldGFpbHM6IERhdGFwb2ludERldGFpbHMpID0+IHtcbiAgICAgIGxldCB1bml0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBsZXQgZGF0YTogVGltZVNlcmllc0RhdGE7XG5cbiAgICAgIC8qKlxuICAgICAgICogVW5pcXVlIGtleSB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGRpZmZlcmVudCBzZXJpZXMgZnJvbSBzYW1lIHNvdXJjZSxcbiAgICAgICAqIGUuZy46IGM4eV9BY2NlbGVyYXRpb24uYWNjZWxlcmF0aW9uWCwgYzh5X0FjY2VsZXJhdGlvbi5hY2NlbGVyYXRpb25ZLCBjOHlfQWNjZWxlcmF0aW9uLmFjY2VsZXJhdGlvblpcbiAgICAgICAqL1xuICAgICAgY29uc3Qgc2VyaWVzS2V5ID0gYCR7ZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZX0uJHtkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXN9YDtcblxuICAgICAgaWYgKHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XSkge1xuICAgICAgICB1bml0ID0gdmFsdWVzR3JvdXBlZEJ5U291cmNlW2RldGFpbHMuc291cmNlXVtzZXJpZXNLZXldLnNlcmllc0RldGFpbHMudW5pdDtcbiAgICAgICAgZGF0YSA9IHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XS52YWx1ZXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRldGFpbHMsXG4gICAgICAgIHVuaXQsXG4gICAgICAgIHRpbWVWYWx1ZU1hcDogZGF0YVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGp1c3RzIHRoZSBnaXZlbiBkYXRlIGJ5IGFkZGluZyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaW51dGVzIGFuZCBzZXR0aW5nIHNlY29uZHMgdG8gMC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGUgLSBUaGUgZGF0ZSB0byBiZSBhZGp1c3RlZCBpbiBzdHJpbmcgZm9ybWF0LlxuICAgKiBAcGFyYW0gbWludXRlcyAtIFRoZSBudW1iZXIgb2YgbWludXRlcyB0byBhZGQgdG8gdGhlIGRhdGUuXG4gICAqIEByZXR1cm5zIFRoZSBhZGp1c3RlZCBkYXRlIGluIHRoZSBmb3JtYXQgJ1lZWVktTU0tRERUSEg6bW06c3MrSEg6TU0nLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGp1c3REYXRlKGRhdGU6IHN0cmluZyB8IERhdGUsIG1pbnV0ZXM6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0ZVRpbWUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICBkYXRlVGltZS5zZXRNaW51dGVzKGRhdGVUaW1lLmdldE1pbnV0ZXMoKSArIG1pbnV0ZXMpO1xuICAgIGRhdGVUaW1lLnNldFNlY29uZHMoMCk7XG5cbiAgICBjb25zdCBvZmZzZXQgPSAtZGF0ZVRpbWUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICBjb25zdCBvZmZzZXRTaWduID0gb2Zmc2V0ID49IDAgPyAnKycgOiAnLSc7XG4gICAgY29uc3QgcGFkID0gKG51bTogbnVtYmVyKTogc3RyaW5nID0+IChudW0gPCAxMCA/ICcwJyArIG51bSA6IG51bS50b1N0cmluZygpKTtcbiAgICBjb25zdCBvZmZzZXRIb3VycyA9IHBhZChNYXRoLmZsb29yKE1hdGguYWJzKG9mZnNldCkgLyA2MCkpO1xuICAgIGNvbnN0IG9mZnNldE1pbnV0ZXMgPSBwYWQoTWF0aC5hYnMob2Zmc2V0KSAlIDYwKTtcblxuICAgIGNvbnN0IHllYXIgPSBkYXRlVGltZS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG1vbnRoID0gcGFkKGRhdGVUaW1lLmdldE1vbnRoKCkgKyAxKTtcbiAgICBjb25zdCBkYXkgPSBwYWQoZGF0ZVRpbWUuZ2V0RGF0ZSgpKTtcbiAgICBjb25zdCBob3VycyA9IHBhZChkYXRlVGltZS5nZXRIb3VycygpKTtcbiAgICBjb25zdCBtaW51dGVzU3RyaW5nID0gcGFkKGRhdGVUaW1lLmdldE1pbnV0ZXMoKSk7XG4gICAgY29uc3Qgc2Vjb25kcyA9ICcwMCc7XG5cbiAgICByZXR1cm4gYCR7eWVhcn0tJHttb250aH0tJHtkYXl9VCR7aG91cnN9OiR7bWludXRlc1N0cmluZ306JHtzZWNvbmRzfSR7b2Zmc2V0U2lnbn0ke29mZnNldEhvdXJzfToke29mZnNldE1pbnV0ZXN9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltcyB0aGUgZ2l2ZW4gSFRNTCBtZXNzYWdlIGJ5IHJlbW92aW5nIGxpc3QgaXRlbXMgdGhhdCBjb3JyZXNwb25kIHRvIHplcm8gY291bnRzLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBIVE1MIHN0cmluZyBjb250YWluaW5nIHRoZSBtZXNzYWdlIHdpdGggbGlzdCBpdGVtcy5cbiAgICogQHBhcmFtIGNvdW50cyAtIEFuIGFycmF5IG9mIG51bWJlciB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBlYWNoIGxpc3QgaXRlbS5cbiAgICogQHBhcmFtIGNvdW50VG9UcmltIC0gQSBjb3VudCB0aGF0IHdpbGwgYmUgdHJpbW1lZCB3aXRoIGNvcnJlc3BvbmRpbmcgbGlzdCBpdGVtLlxuICAgKiBAcmV0dXJucyBBIHRyaW1tZWQgSFRNTCBzdHJpbmcgd2l0aCBsaXN0IGl0ZW1zIHJlbW92ZWQgd2hlcmUgdGhlIGNvcnJlc3BvbmRpbmcgY291bnQgaXMgemVyby5cbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtZXNzYWdlID0gJzx1bD48bGk+SXRlbSAxPC9saT48bGk+SXRlbSAyPC9saT48bGk+SXRlbSAzPC9saT48L3VsPic7XG4gICAqIGNvbnN0IGNvdW50cyA9IFsxLCAwLCAyXTtcbiAgICogY29uc3QgdHJpbW1lZE1lc3NhZ2UgPSB0aGlzLnJlbW92ZVplcm9Db3VudExpc3RJdGVtcyhtZXNzYWdlLCBjb3VudHMpO1xuICAgKiAvLyBSZXN1bHQ6ICc8dWw+PGxpPkl0ZW0gMTwvbGk+PGxpPkl0ZW0gMzwvbGk+PC91bD4nXG4gICAqIGBgYFxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVaZXJvQ291bnRMaXN0SXRlbXMobWVzc2FnZTogc3RyaW5nLCBjb3VudHM6IG51bWJlcltdLCBjb3VudFRvVHJpbSA9IDApOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICBjb25zdCBkb2MgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UsICd0ZXh0L2h0bWwnKTtcbiAgICBjb25zdCBsaXN0SXRlbXMgPSBkb2MucXVlcnlTZWxlY3RvckFsbCgndWwgbGknKTtcblxuICAgIGxpc3RJdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGNvdW50c1tpbmRleF0gPT09IGNvdW50VG9UcmltKSB7XG4gICAgICAgIGl0ZW0ucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZG9jLmJvZHkuaW5uZXJIVE1MO1xuICB9XG59XG4iXX0=
|
|
408
|
+
}], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.MeasurementService }, { type: i3.TranslateService }, { type: i4.UtilsService }] });
|
|
409
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mZXRjaGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3IvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItbW9kYWwvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItZmlsZS1leHBvcnRlci9kYXRhLWZldGNoaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBU0wsa0JBQWtCLEVBQ25CLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQVFMLGdDQUFnQyxFQUVqQyxNQUFNLHdDQUF3QyxDQUFDO0FBQ2hELE9BQU8sRUFBYyxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7O0FBSzNELE1BQU0sT0FBTyxtQkFBbUI7SUFDOUIsWUFDVSxZQUEwQixFQUMxQixrQkFBc0MsRUFDdEMsZ0JBQWtDLEVBQ2xDLFlBQTBCO1FBSDFCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztJQUNqQyxDQUFDO0lBRUo7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsMkJBQTJCLENBQy9CLFlBQTBCO1FBRTFCLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDO1FBRXRDLE1BQU0sUUFBUSxHQUF3QyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUNyRixLQUFLLEVBQUMsT0FBTyxFQUFDLEVBQUU7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VSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgYWdncmVnYXRpb25UeXBlLFxuICBJRmV0Y2hSZXNwb25zZSxcbiAgSU1lYXN1cmVtZW50LFxuICBJTWVhc3VyZW1lbnRGaWx0ZXIsXG4gIElSZXN1bHQsXG4gIElSZXN1bHRMaXN0LFxuICBJU2VyaWVzLFxuICBJU2VyaWVzRmlsdGVyLFxuICBNZWFzdXJlbWVudFNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQUdHUkVHQVRJT05fVkFMVUVTLCBBbGVydFNlcnZpY2UsIGdldHRleHQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7XG4gIERhdGFwb2ludERldGFpbHMsXG4gIERhdGFwb2ludHNFeGNlZWRpbmdMaW1pdCxcbiAgRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gIERhdGFUb0V4cG9ydCxcbiAgRGF0YVRvRXhwb3J0V2l0aEJhY2tlbmRDcmVhdGVkRmlsZSxcbiAgRXhwb3J0Q29uZmlnLFxuICBNZWFzdXJlbWVudEZpbGVDb25maWcsXG4gIE1FQVNVUkVNRU5UU19QUkVWSUVXX0lURU1TX0xJTUlULFxuICBUaW1lU2VyaWVzRGF0YVxufSBmcm9tICcuLi8uLi9kYXRhcG9pbnRzLWV4cG9ydC1zZWxlY3Rvci5tb2RlbCc7XG5pbXBvcnQgeyBTb3VyY2VJdGVtLCBVdGlsc1NlcnZpY2UgfSBmcm9tICcuL3V0aWxzLnNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBEYXRhRmV0Y2hpbmdTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIG1lYXN1cmVtZW50U2VydmljZTogTWVhc3VyZW1lbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHV0aWxzU2VydmljZTogVXRpbHNTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGFueSBvZiBtZWFzdXJlbWVudHMgcmVxdWVzdHMgbWF5IGV4Y2VlZGVkIHRoZSBsaW1pdCxcbiAgICogYWZ0ZXIgd2hpY2ggdGhlIGV4cG9ydCBkYXRhIGlzIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgdGhlIGdlbmVyYXRlZCBDU1YvRXhjZWwgZmlsZSBpcyBzZW50IGJ5IGVtYWlsLlxuICAgKlxuICAgKiBUaGUgdGhyZXNob2xkIGlzIHNldCB0byA1MF8wMDAgcmVjb3JkcyBpbiBhcHBsaWNhdGlvbidzIGNvcmUgcHJvcGVydGllcyAoZXhwb3J0LmRhdGEuc3luY2hyb25vdXMubGltaXQpLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwb3J0Q29uZmlnIC0gVGhlIGV4cG9ydCBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXR1cm5zIGFuIGFycmF5IG9mIG9iamVjdHMgcmVwcmVzZW50aW5nIGRhdGFwb2ludHMgZmlsZXMgdGhhdCB3aWxsIGJlIHNlbnQgYnkgZW1haWwuXG4gICAqL1xuICBhc3luYyBnZXREYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQoXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRbXT4ge1xuICAgIGNvbnN0IGJhY2tlbmRQcm9jZXNzaW5nTGltaXQgPSA1MF8wMDA7XG5cbiAgICBjb25zdCBwcm9taXNlczogUHJvbWlzZTxEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQ+W10gPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoXG4gICAgICBhc3luYyBkZXRhaWxzID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHtcbiAgICAgICAgICAgIGRhdGVGcm9tOiBleHBvcnRDb25maWcuZGF0ZUZyb20sXG4gICAgICAgICAgICBkYXRlVG86IGV4cG9ydENvbmZpZy5kYXRlVG8sXG4gICAgICAgICAgICBwYWdlU2l6ZTogMSxcbiAgICAgICAgICAgIHNvdXJjZTogZGV0YWlscy5zb3VyY2UsXG4gICAgICAgICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICAgICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZSxcbiAgICAgICAgICAgIHdpdGhUb3RhbEVsZW1lbnRzOiB0cnVlXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdChmaWx0ZXIpO1xuXG4gICAgICAgICAgaWYgKHJlc3BvbnNlPy5wYWdpbmc/LnRvdGFsRWxlbWVudHMgPiBiYWNrZW5kUHJvY2Vzc2luZ0xpbWl0KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkYXRhcG9pbnREZXRhaWw6IHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgICAgICAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgICAgICAgICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0b3RhbEVsZW1lbnRzOiByZXNwb25zZS5wYWdpbmcudG90YWxFbGVtZW50c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHM6IERhdGFwb2ludHNFeGNlZWRpbmdMaW1pdFtdID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gICAgY29uc3QgZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0ID0gcmVzdWx0cy5maWx0ZXIocmVzdWx0ID0+IHJlc3VsdCAhPT0gbnVsbCk7XG5cbiAgICByZXR1cm4gZGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgd2hlbiB0aGUgbGltaXQgb2YgZGF0YXBvaW50cyBpcyBleGNlZWRlZCBkdXJpbmcgZmlsZSBleHBvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBoYXNOb0V4cG9ydGFibGVEYXRhIC0gSW5kaWNhdGVzIGlmIHRoZXJlIGlzIG5vIGV4cG9ydGFibGUgZGF0YSBiZWNhdXNlIHRoZSBkYXRlIHJhbmdlIG9mIGFsbCBzZWxlY3RlZCBkYXRhcG9pbnRzIGV4Y2VlZHMgMSwwMDAsMDAwIHJlY29yZHMuXG4gICAqIEBwYXJhbSBlbWFpbERlbGl2ZXJhYmxlQ291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHRoYXQgZXhjZWVkIHRoZSBsaW1pdCwgd2lsbCBiZSBwcm9jZWVkZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHNlbnQgYnkgZW1haWwuXG4gICAqIEBwYXJhbSBicm93c2VyRG93bmxvYWRhYmxlQ291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHRoYXQgY2FuIGJlIGRvd25sb2FkZWQgZGlyZWN0bHkuXG4gICAqIEBwYXJhbSBza2lwcGVkRGF0YXBvaW50Q291bnQgLSBUaGUgbnVtYmVyIG9mIGRhdGFwb2ludCBleHBvcnRzIHNraXBwZWQgZHVlIHRvIGV4Y2VlZGluZyB0aGUgbWVhc3VyZW1lbnRzIEFQSSBsaW1pdCBvZiAxLDAwMCwwMDAgcmVjb3Jkcy5cbiAgICogQHBhcmFtIHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQgLSBUb3RhbCBudW1iZXIgb2YgZGF0YXBvaW50IHNlbGVjdGVkIGZvciBleHBvcnRzLlxuICAgKiBAcmV0dXJucyBUaGUgbWVzc2FnZSB0aGF0IGNhbiBiZSBpbmplY3RlZC5cbiAgICovXG4gIGdldExpbWl0RXhjZWVkZWRNZXNzYWdlKFxuICAgIGhhc05vRXhwb3J0YWJsZURhdGE6IGJvb2xlYW4sXG4gICAgZW1haWxEZWxpdmVyYWJsZUNvdW50PzogbnVtYmVyLFxuICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudD86IG51bWJlcixcbiAgICBub25SZXRyaWV2YWJsZUNvdW50PzogbnVtYmVyLFxuICAgIHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ/OiBudW1iZXJcbiAgKTogc3RyaW5nIHtcbiAgICBpZiAoaGFzTm9FeHBvcnRhYmxlRGF0YSkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICBnZXR0ZXh0KFxuICAgICAgICAgIGBUaGUgZGF0YSBmb3Igc2VsZWN0ZWQgZGF0YXBvaW50KHMpIGV4Y2VlZCAxLDAwMCwwMDAgcmVjb3Jkcywgd2hpY2ggaXMgdGhlIGxpbWl0IGZvciBiYWNrZW5kIHByb2Nlc3NpbmcuIFRvIGV4cG9ydCB0aGlzIGRhdGEsIHBsZWFzZSByZWR1Y2UgdGhlIGRhdGUgcmFuZ2UuYFxuICAgICAgICApXG4gICAgICApO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgZ2V0dGV4dChcbiAgICAgICAgYEFmdGVyIGNsaWNraW5nIFwiRG93bmxvYWRcIjo8YnI+XG4gICAgICAgIDx1bD5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRicm93c2VyRG93bmxvYWRhYmxlQ291bnR9fTwvc3Ryb25nPiBkYXRhcG9pbnQocykgZXhwb3J0cyB3aWxsIGJlIGRvd25sb2FkZWQgZGlyZWN0bHkgd2l0aGluIG9uZSBmaWxlOiA8ZW0+ZXhwb3J0ZWRfW2Nzdi9leGNlbF0uemlwPC9lbT48L2xpPlxuICAgICAgICAgIDxsaT48c3Ryb25nPnt7JGVtYWlsRGVsaXZlcmFibGVDb3VudH19PC9zdHJvbmc+IGRhdGFwb2ludChzKSBleHBvcnRzIHJlcXVpcmUgZnVydGhlciBwcm9jZXNzaW5nLiBUaGUgZmlsZXMgd2lsbCBiZSBzZW50IHRvIHlvdSB2aWEgc2VwYXJhdGUgZW1haWxzIG9uY2UgY29tcGxldGVkLCB3aGljaCBtYXkgdGFrZSBzb21lIHRpbWUuPC9saT5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRub25SZXRyaWV2YWJsZUNvdW50fX08L3N0cm9uZz4gZGF0YXBvaW50KHMpIGV4cG9ydHMgZXhjZWVkZWQgMSwwMDAsMDAwIHJlY29yZHMsIHdoaWNoIGlzIHRoZSBsaW1pdCBmb3IgYmFja2VuZCBwcm9jZXNzaW5nLiBUbyBleHBvcnQgdGhlc2UgZGF0YSwgcGxlYXNlIHJlZHVjZSB0aGUgZGF0ZSByYW5nZS4gT3RoZXJ3aXNlLCB0aGUgZGF0YSB3aWxsIG5laXRoZXIgYmUgZG93bmxvYWRlZCBub3Igc2VudCB2aWEgZW1haWwuPC9saT5cbiAgICAgICAgPC91bD5cbiAgICAgICAgPHA+VGhlIHRvdGFsIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IGNhbiBiZSBleHBvcnRlZCBpczogPHN0cm9uZz57eyR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnR9fSBvdXQgb2Yge3skdG90YWxEYXRhcG9pbnRzU2VsZWN0ZWRGb3JFeHBvcnRDb3VudH19PC9zdHJvbmc+LjwvcD5cbiAgICAgICAgPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmlsZSBuYW1lIGNvbnZlbnRpb24gb2YgZmlsZXMgd2l0aGluIHppcCBmaWxlIGlzOiA8Y29kZT5bc291cmNlXV9bZnJhZ21lbnRfc2VyaWVzXS5bY3N2L3hsc108L2NvZGU+PC9wPmBcbiAgICAgICksXG4gICAgICB7XG4gICAgICAgICRicm93c2VyRG93bmxvYWRhYmxlQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgICAgJGVtYWlsRGVsaXZlcmFibGVDb3VudDogZW1haWxEZWxpdmVyYWJsZUNvdW50LFxuICAgICAgICAkbm9uUmV0cmlldmFibGVDb3VudDogbm9uUmV0cmlldmFibGVDb3VudCxcbiAgICAgICAgJHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ6IHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQsXG4gICAgICAgICR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCArIGVtYWlsRGVsaXZlcmFibGVDb3VudFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCB0cmltbWVkTWVzc2FnZSA9IHRoaXMucmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2UsIFtcbiAgICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudCxcbiAgICAgIG5vblJldHJpZXZhYmxlQ291bnRcbiAgICBdKTtcblxuICAgIHJldHVybiB0cmltbWVkTWVzc2FnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltcyB0aGUgZ2l2ZW4gSFRNTCBtZXNzYWdlIGJ5IHJlbW92aW5nIGxpc3QgaXRlbXMgdGhhdCBjb3JyZXNwb25kIHRvIHplcm8gY291bnRzLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBIVE1MIHN0cmluZyBjb250YWluaW5nIHRoZSBtZXNzYWdlIHdpdGggbGlzdCBpdGVtcy5cbiAgICogQHBhcmFtIGNvdW50cyAtIEFuIGFycmF5IG9mIG51bWJlciB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBlYWNoIGxpc3QgaXRlbS5cbiAgICogQHBhcmFtIGNvdW50VG9UcmltIC0gQSBjb3VudCB0aGF0IHdpbGwgYmUgdHJpbW1lZCB3aXRoIGNvcnJlc3BvbmRpbmcgbGlzdCBpdGVtLlxuICAgKiBAcmV0dXJucyBBIHRyaW1tZWQgSFRNTCBzdHJpbmcgd2l0aCBsaXN0IGl0ZW1zIHJlbW92ZWQgd2hlcmUgdGhlIGNvcnJlc3BvbmRpbmcgY291bnQgaXMgemVyby5cbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtZXNzYWdlID0gJzx1bD48bGk+SXRlbSAxPC9saT48bGk+SXRlbSAyPC9saT48bGk+SXRlbSAzPC9saT48L3VsPic7XG4gICAqIGNvbnN0IGNvdW50cyA9IFsxLCAwLCAyXTtcbiAgICogY29uc3QgdHJpbW1lZE1lc3NhZ2UgPSB0aGlzLnJlbW92ZVplcm9Db3VudExpc3RJdGVtcyhtZXNzYWdlLCBjb3VudHMpO1xuICAgKiAvLyBSZXN1bHQ6ICc8dWw+PGxpPkl0ZW0gMTwvbGk+PGxpPkl0ZW0gMzwvbGk+PC91bD4nXG4gICAqIGBgYFxuICAgKi9cbiAgcmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2U6IHN0cmluZywgY291bnRzOiBudW1iZXJbXSwgY291bnRUb1RyaW0gPSAwKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgY29uc3QgZG9jID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhtZXNzYWdlLCAndGV4dC9odG1sJyk7XG4gICAgY29uc3QgbGlzdEl0ZW1zID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoJ3VsIGxpJyk7XG5cbiAgICBsaXN0SXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChjb3VudHNbaW5kZXhdID09PSBjb3VudFRvVHJpbSkge1xuICAgICAgICBpdGVtLnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRvYy5ib2R5LmlubmVySFRNTDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBhbiBpbmZvcm1hdGlvbiBhbGVydCBhYm91dCBzZW5kaW5nIGRhdGEgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBPbmx5IG1lYXN1cmVtZW50cyBBUEkgY2FuIHNlbmQgZmlsZXMgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZVR5cGUgLSBUaGUgdHlwZSBvZiBmaWxlIHRvIGJlIHNlbnQuXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQgLSBUaGUgYXJyYXkgb2YgZGF0YXBvaW50cyBleGNlZWRpbmcgdGhlIGxpbWl0LlxuICAgKi9cbiAgc2hvd1NlbmRWaWFFbWFpbEluZm9BbGVydChcbiAgICBmaWxlVHlwZTogc3RyaW5nLFxuICAgIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDogRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZVRlbXBsYXRlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KGBZb3Ugd2lsbCBnZXQge3skZmlsZVR5cGVUZXh0fX0gZmlsZShzKSBmb3Ige3skY291bnR9fSBzZXJpZXMgdmlhIGVtYWlsLmApLFxuICAgICAgeyAkY291bnQ6IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdC5sZW5ndGgsICRmaWxlVHlwZVRleHQ6IGZpbGVUeXBlIH1cbiAgICApO1xuICAgIGNvbnN0IGZvcm1hdHRlZExpc3QgPSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRcbiAgICAgIC5tYXAoXG4gICAgICAgIGRhdGFwb2ludCA9PlxuICAgICAgICAgIGDigKIgJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnNvdXJjZX1fJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnZhbHVlRnJhZ21lbnRUeXBlfV8ke2RhdGFwb2ludC5kYXRhcG9pbnREZXRhaWwudmFsdWVGcmFnbWVudFNlcmllc31gXG4gICAgICApXG4gICAgICAuam9pbignXFxuJyk7XG5cbiAgICB0aGlzLmFsZXJ0U2VydmljZS5pbmZvKG1lc3NhZ2VUZW1wbGF0ZSwgZm9ybWF0dGVkTGlzdCk7XG4gIH1cblxuICBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZpbGVzQW5kUGFpcldpdGhTb3VyY2VEZXRhaWxzKFxuICAgIGFjY2VwdEZpbGVUeXBlOiBzdHJpbmcsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlW10+IHtcbiAgICBjb25zdCBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyA9IHtcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIGFjY2VwdEZpbGVUeXBlXG4gICAgfTtcbiAgICBjb25zdCBmaWxlUHJvbWlzZXMgPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoZGV0YWlscyA9PlxuICAgICAgdGhpcy5mZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlQ29uZmlnKVxuICAgICk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGZpbGVQcm9taXNlcyk7XG4gIH1cblxuICBhc3luYyBmZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyxcbiAgICByb3VuZFNlY29uZHMgPSBmYWxzZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGUgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBtZWFzdXJlbWVudEZpbGVDb25maWcuZXhwb3J0Q29uZmlnLFxuICAgICAgcm91bmRTZWNvbmRzXG4gICAgKTtcbiAgICBjb25zdCBoZWFkZXIgPSB7IGFjY2VwdDogbWVhc3VyZW1lbnRGaWxlQ29uZmlnLmFjY2VwdEZpbGVUeXBlIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2U6IElGZXRjaFJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UuZ2V0TWVhc3VyZW1lbnRzRmlsZShmaWx0ZXIsIGhlYWRlcik7XG5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAwLCB0aGVuIHRoZSBmaWxlIGlzIGluIHRoZSByZXNwb25zZS5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAyLCB0aGVuIHRoZSBmaWxlIGlzIGJlaW5nIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgICAgaWYgKG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lcmdlTWVhc3VyZW1lbnRzV2l0aEl0c1NvdXJjZURldGFpbHMoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBtZXJnZU1lYXN1cmVtZW50c1dpdGhJdHNTb3VyY2VEZXRhaWxzKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgbWVhc3VyZW1lbnRGaWxlOiBJRmV0Y2hSZXNwb25zZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgIHZhbHVlRnJhZ21lbnRUeXBlOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlLFxuICAgICAgZmV0Y2hlZE1lYXN1cmVtZW50c0Jsb2JGaWxlOiBhd2FpdCBtZWFzdXJlbWVudEZpbGUuYmxvYigpXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoQW5kUHJlcGFyZURhdGFUb0V4cG9ydChcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICBpc01lYXN1cmVtZW50OiBib29sZWFuXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHtcbiAgICByZXR1cm4gaXNNZWFzdXJlbWVudFxuICAgICAgPyBhd2FpdCB0aGlzLmZldGNoQW5kUHJlcGFyZU1lYXN1cmVtZW50RGF0YVRvRXhwb3J0Rm9yUHJldmlldyhleHBvcnRDb25maWcpXG4gICAgICA6IGF3YWl0IHRoaXMuZmV0Y2hBbmRQcmVwYXJlU2VyaWVzRGF0YVRvRXhwb3J0KGV4cG9ydENvbmZpZyk7XG4gIH1cblxuICBwcmVwYXJlTWVhc3VyZW1lbnRzRmlsdGVyKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcsXG4gICAgcm91bmRTZWNvbmRzOiBib29sZWFuLFxuICAgIHBhZ2VTaXplPzogbnVtYmVyXG4gICk6IElNZWFzdXJlbWVudEZpbHRlciB7XG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICBkYXRlRnJvbTogdGhpcy5hZGp1c3REYXRlKGV4cG9ydENvbmZpZy5kYXRlRnJvbSwgMCwgcm91bmRTZWNvbmRzKSxcbiAgICAgIGRhdGVUbzogdGhpcy5hZGp1c3REYXRlKGV4cG9ydENvbmZpZy5kYXRlVG8sIDAsIHJvdW5kU2Vjb25kcyksXG4gICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICB9O1xuXG4gICAgaWYgKHBhZ2VTaXplKSB7XG4gICAgICBmaWx0ZXIucGFnZVNpemUgPSBwYWdlU2l6ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyO1xuICB9XG5cbiAgcHJvY2Vzc01lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoZGV0YWlsczogRGF0YXBvaW50RGV0YWlscywgZGF0YTogSU1lYXN1cmVtZW50W10pOiBEYXRhVG9FeHBvcnQge1xuICAgIGNvbnN0IHVuaXQgPSBkYXRhWzBdW2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGVdW2RldGFpbHMudmFsdWVGcmFnbWVudFNlcmllc10/LnVuaXQgfHwgJyc7XG5cbiAgICBjb25zdCB2YWx1ZXM6IHsgW3RpbWVzdGFtcDogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcbiAgICBkYXRhLmZvckVhY2gobWVhc3VyZW1lbnQgPT4ge1xuICAgICAgdmFsdWVzW21lYXN1cmVtZW50LnRpbWVdID1cbiAgICAgICAgbWVhc3VyZW1lbnRbZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZV1bZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzXS52YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IC4uLmRldGFpbHMsIHVuaXQsIHRpbWVWYWx1ZU1hcDogdmFsdWVzIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIG1hcCBvZiBhY3RpdmUgZGF0YSBwb2ludHMgZGV2aWNlIElEcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgc2VyaWVzLlxuICAgKlxuICAgKiBFeGFtcGxlIG91dHB1dDpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBuZXcgTWFwKFtcbiAgICogICBbJzg0NDY1NzIwMicsIFsnYzh5X1RlbXBlcmF0dXJlLlQnXV0sXG4gICAqICAgWyczMjY2NjQyNycsIFsnYzh5X0JhdHRlcnkuQmF0dGVyeSddXVxuICAgKiBdKTtcbiAgICogYGBgXG4gICAqIEBwYXJhbSBkYXRhcG9pbnREZXRhaWxzIC0gQW4gYXJyYXkgb2YgZGF0YSBwb2ludHMgZGV0YWlscy5cbiAgICogQHJldHVybnMgQSBtYXAgd2hlcmUgdGhlIGtleSBpcyB0aGUgZGF0YSBwb2ludCBJRCBhbmQgdGhlIHZhbHVlIGlzIGFuIGFycmF5IG9mIGRhdGEgcG9pbnQgc2VyaWVzLlxuICAgKi9cbiAgZ3JvdXBTZXJpZXNCeURldmljZUlkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwIHtcbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIG1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gICAgICAgIHsgdmFsdWVGcmFnbWVudFR5cGUsIHZhbHVlRnJhZ21lbnRTZXJpZXMsIHNvdXJjZSB9OiBEYXRhcG9pbnREZXRhaWxzXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBgJHt2YWx1ZUZyYWdtZW50VHlwZX0uJHt2YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSBtYXAuZ2V0KHNvdXJjZSkgPz8gW107XG4gICAgICAgIG1hcC5zZXQoc291cmNlLCBbLi4uZXhpc3RpbmdWYWx1ZSwgdmFsdWVdKTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgIH0sXG4gICAgICBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3NlcyB0aGUgZmV0Y2hlZCBzZXJpZXMgZGF0YSBhbmQgcHJlcGFyZXMgaXQgZm9yIGV4cG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGFwb2ludERldGFpbHMgLSBBbiBhcnJheSBvZiBkYXRhIHBvaW50IGRldGFpbHMuXG4gICAqIEBwYXJhbSBmZXRjaGVkRGF0YU1hcCAtIEEgbWFwIG9mIGZldGNoZWQgc2VyaWVzIGRhdGEgZ3JvdXBlZCBieSBzb3VyY2UuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIERhdGFUb0V4cG9ydCBvYmplY3RzLlxuICAgKi9cbiAgcHJvY2Vzc1Nlcmllc0RhdGEoXG4gICAgZGF0YXBvaW50RGV0YWlsczogRGF0YXBvaW50RGV0YWlsc1tdLFxuICAgIGZldGNoZWREYXRhTWFwOiBTb3VyY2VJdGVtW11cbiAgKTogRGF0YVRvRXhwb3J0W10ge1xuICAgIGNvbnN0IHZhbHVlc0dyb3VwZWRCeVNvdXJjZSA9IHRoaXMudXRpbHNTZXJ2aWNlLnRyYW5zZm9ybURhdGFTdHJ1Y3R1cmUoZmV0Y2hlZERhdGFNYXApO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludERldGFpbHMubWFwKChkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzKSA9PiB7XG4gICAgICBsZXQgdW5pdDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGRhdGE6IFRpbWVTZXJpZXNEYXRhO1xuXG4gICAgICAvKipcbiAgICAgICAqIFVuaXF1ZSBrZXkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBkaWZmZXJlbnQgc2VyaWVzIGZyb20gc2FtZSBzb3VyY2UsXG4gICAgICAgKiBlLmcuOiBjOHlfQWNjZWxlcmF0aW9uLmFjY2VsZXJhdGlvblgsIGM4eV9BY2NlbGVyYXRpb24uYWNjZWxlcmF0aW9uWSwgYzh5X0FjY2VsZXJhdGlvbi5hY2NlbGVyYXRpb25aXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHNlcmllc0tleSA9IGAke2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGV9LiR7ZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG5cbiAgICAgIGlmICh2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0pIHtcbiAgICAgICAgdW5pdCA9IHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XS5zZXJpZXNEZXRhaWxzLnVuaXQ7XG4gICAgICAgIGRhdGEgPSB2YWx1ZXNHcm91cGVkQnlTb3VyY2VbZGV0YWlscy5zb3VyY2VdW3Nlcmllc0tleV0udmFsdWVzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kZXRhaWxzLFxuICAgICAgICB1bml0LFxuICAgICAgICB0aW1lVmFsdWVNYXA6IGRhdGFcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBnZXRTb3VyY2VzV2l0aFBlcm1pc3Npb25zVG9SZWFkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBkYXRlRnJvbSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgZGF0ZVRvID0gbmV3IERhdGUoZGF0ZUZyb20pO1xuXG4gICAgY29uc3QgZmV0Y2hlZERhdGFQcm9taXNlcyA9IGRhdGFwb2ludERldGFpbHMubWFwKGFzeW5jIGRhdGFwb2ludCA9PiB7XG4gICAgICBjb25zdCByYXdGaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICAgIGRhdGVGcm9tLFxuICAgICAgICBkYXRlVG8sXG4gICAgICAgIHNvdXJjZTogZGF0YXBvaW50LnNvdXJjZVxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyByZXMgfTogSVJlc3VsdDxJU2VyaWVzPiA9IGF3YWl0IHRoaXMuZmV0Y2hTZXJpZXNEYXRhKHJhd0ZpbHRlcik7XG4gICAgICAgIGlmIChyZXM/LnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFwb2ludC5zb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGZldGNoLCByZXR1cm4gbnVsbCB0byBwcmV2ZW50IHByb21pc2UgcmVqZWN0aW9uXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZmV0Y2hlZFNvdXJjZXMgPSBhd2FpdCBQcm9taXNlLmFsbChmZXRjaGVkRGF0YVByb21pc2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZFNvdXJjZXMuZmlsdGVyKChzb3VyY2UpOiBzb3VyY2UgaXMgc3RyaW5nID0+IHNvdXJjZSAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogQWRqdXN0cyB0aGUgZ2l2ZW4gZGF0ZSBieSBhZGRpbmcgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbWludXRlcyBhbmQgc2V0dGluZyBzZWNvbmRzIHRvIDAuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gYmUgYWRqdXN0ZWQgaW4gc3RyaW5nIGZvcm1hdC5cbiAgICogQHBhcmFtIG1pbnV0ZXMgLSBUaGUgbnVtYmVyIG9mIG1pbnV0ZXMgdG8gYWRkIHRvIHRoZSBkYXRlLlxuICAgKiBAcGFyYW0gcm91bmRTZWNvbmRzIC0gV2hldGhlciB0byByb3VuZCB0aGUgc2Vjb25kcyBvciBub3QuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBJZiB0cnVlLCB0aGUgc2Vjb25kcyB3aWxsIGJlIHJvdW5kZWQgdG8gMC5cbiAgICogICAgICAgICAgICAgICAgICAgICAgIElmIGZhbHNlLCB0aGUgc2Vjb25kcyB3aWxsIGJlIGRpc3BsYXllZCBhcyB0aGV5IGFyZS5cbiAgICogQHJldHVybnMgVGhlIGFkanVzdGVkIGRhdGUgaW4gSVNPIHN0cmluZyBmb3JtYXQuXG4gICAqL1xuICBhZGp1c3REYXRlKGRhdGU6IHN0cmluZyB8IERhdGUsIG1pbnV0ZXM6IG51bWJlciwgcm91bmRTZWNvbmRzID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0ZVRpbWUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICBpZiAoaXNOYU4oZGF0ZVRpbWUuZ2V0VGltZSgpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGUnKTtcbiAgICB9XG5cbiAgICBkYXRlVGltZS5zZXRVVENNaW51dGVzKGRhdGVUaW1lLmdldFVUQ01pbnV0ZXMoKSArIG1pbnV0ZXMpO1xuICAgIGlmIChyb3VuZFNlY29uZHMpIHtcbiAgICAgIGRhdGVUaW1lLnNldFVUQ1NlY29uZHMoMCwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGVUaW1lLnRvSVNPU3RyaW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogQXN5bmNocm9ub3VzbHkgbG9hZHMgc2VyaWVzIGRhdGEgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNvbnN0cnVjdHMgYSBmaWx0ZXIgZm9yIHJldHJpZXZpbmcgc2VyaWVzIGRhdGEgd2l0aGluIGEgc3BlY2lmaWVkIGRhdGUgcmFuZ2UsXG4gICAqIGZyb20gYSBzcGVjaWZpYyBzb3VyY2UsIGFuZCBvcHRpb25hbGx5IGFwcGx5aW5nIGFuIGFnZ3JlZ2F0aW9uIHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSByYXdGaWx0ZXIgLSBUaGUgcGFyYW1ldGVycyBmb3IgbG9hZGluZyBzZXJpZXMgZGF0YSwgaW5jbHVkaW5nIGRhdGUgcmFuZ2UsIHNvdXJjZSwgc2VyaWVzIG5hbWVzLCBhbmQgYWdncmVnYXRpb24gdHlwZS5cbiAgICogQHBhcmFtIHJvdW5kU2Vjb25kcyAtIEluZGljYXRlcyB3aGV0aGVyIHRvIHJvdW5kIHRoZSBzZWNvbmRzIGluIHRoZSBkYXRlIHJhbmdlIHRvIHRoZSBuZWFyZXN0IHdob2xlIG51bWJlci5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gc2VyaWVzIGRhdGEgd3JhcHBlZCBpbiByZXN1bHQgb2JqZWN0LlxuICAgKi9cbiAgYXN5bmMgZmV0Y2hTZXJpZXNEYXRhKFxuICAgIHJhd0ZpbHRlcjogSVNlcmllc0ZpbHRlcixcbiAgICByb3VuZFNlY29uZHMgPSBmYWxzZVxuICApOiBQcm9taXNlPElSZXN1bHQ8SVNlcmllcz4+IHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgc2VyaWVzRGF0YTogSVJlc3VsdDxJU2VyaWVzPiB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHRoaXMucHJlcGFyZVNlcmllc0ZpbHRlcihcbiAgICAgIHtcbiAgICAgICAgZGF0ZUZyb206IHJhd0ZpbHRlci5kYXRlRnJvbSxcbiAgICAgICAgZGF0ZVRvOiByYXdGaWx0ZXIuZGF0ZVRvLFxuICAgICAgICBzb3VyY2U6IHJhd0ZpbHRlci5zb3VyY2UsXG4gICAgICAgIHNlcmllczogcmF3RmlsdGVyLnNlcmllcyxcbiAgICAgICAgYWdncmVnYXRpb25UeXBlOiByYXdGaWx0ZXIuYWdncmVnYXRpb25UeXBlXG4gICAgICB9LFxuICAgICAgcm91bmRTZWNvbmRzXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBUT0RPOiBjb25zaWRlciBhZGRpbmcgYSBjYWNoZSBtZWNoYW5pc20gLT4gTVRNLTYwMjg5LCBNVE0tNTkyMzNcbiAgICAgIC8vIFdoZW4gdXNlciBzd2l0Y2hlcyBiZXR3ZWVuIHJlcG9ydCB0eXBlcywgYW5kIHJlc3Qgb2YgdGhlIHNldHRpbmdzIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZGF0YSBzaG91bGQgbm90IGJlIGZldGNoZWQgYWdhaW4/XG4gICAgICBzZXJpZXNEYXRhID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdFNlcmllcyhmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWVzRGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIGFuZCBwcmVwYXJlcyBtZWFzdXJlbWVudCBkYXRhIGZvciBwcmV2aWV3LlxuICAgKlxuICAgKiBFbXB0eSBEYXRhVG9FeHBvcnQgb2JqZWN0IGNhbiBiZSByZXR1cm5lZCwgYmVjYXVzZSB1bmxpa2Ugc2VyaWVzIGRhdGEsXG4gICAqIG1lYXN1cmVtZW50IGRhdGEgaXMgbm90IGZ1cnRoZXIgcHJvY2Vzc2VkIGJlc2lkZXMgc2hvd2luZyBvbmx5IGluIHRoZSBwcmV2aWV3LlxuICAgKiBDU1YvRXhjZWwgZmlsZXMgYXJlIGdlbmVyYXRlZCBieSB0aGUgYmFja2VuZCBmb3IgbWVhc3VyZW1lbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwb3J0Q29uZmlnIC0gVGhlIGV4cG9ydCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gcm91bmRTZWNvbmRzIC0gSW5kaWNhdGVzIHdoZXRoZXIgdG8gcm91bmQgdGhlIHNlY29uZHMgaW4gdGhlIGRhdGUgcmFuZ2UgdG8gdGhlIG5lYXJlc3Qgd2hvbGUgbnVtYmVyLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBEYXRhVG9FeHBvcnQgb2JqZWN0cyBvciBudWxsIHdoZW4gbm8gZGF0YSBpcyBmZXRjaGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVNZWFzdXJlbWVudERhdGFUb0V4cG9ydEZvclByZXZpZXcoXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcsXG4gICAgcm91bmRTZWNvbmRzID0gZmFsc2VcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRbXT4gfCBudWxsIHtcbiAgICBjb25zdCBkYXRhVG9FeHBvcnRQcm9taXNlczogUHJvbWlzZTxEYXRhVG9FeHBvcnQ+W10gPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoXG4gICAgICBhc3luYyBkZXRhaWxzID0+IHtcbiAgICAgICAgY29uc3QgZmV0Y2hlZE1lYXN1cmVtZW50RGF0YTogSVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50PiA9XG4gICAgICAgICAgYXdhaXQgdGhpcy5mZXRjaE1lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoZGV0YWlscywgZXhwb3J0Q29uZmlnLCByb3VuZFNlY29uZHMpO1xuXG4gICAgICAgIGlmIChmZXRjaGVkTWVhc3VyZW1lbnREYXRhPy5kYXRhPy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhkZXRhaWxzLCBmZXRjaGVkTWVhc3VyZW1lbnREYXRhLmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICk7XG5cbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoZGF0YVRvRXhwb3J0UHJvbWlzZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZvclByZXZpZXcoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICByb3VuZFNlY29uZHM6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxJTWVhc3VyZW1lbnQ+PiB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IG1lYXN1cmVtZW50czogSVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50PiB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZpbHRlcjogSU1lYXN1cmVtZW50RmlsdGVyID0gdGhpcy5wcmVwYXJlTWVhc3VyZW1lbnRzRmlsdGVyKFxuICAgICAgZGV0YWlscyxcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIHJvdW5kU2Vjb25kcyxcbiAgICAgIE1FQVNVUkVNRU5UU19QUkVWSUVXX0lURU1TX0xJTUlUXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBUT0RPOiBjb25zaWRlciBhZGRpbmcgYSBjYWNoZSBtZWNoYW5pc20gLT4gTVRNLTYwMjg5XG4gICAgICAvLyBXaGVuIHVzZXIgc3dpdGNoZXMgYmV0d2VlbiByZXBvcnQgdHlwZXMsIGFuZCByZXN0IG9mIHRoZSBzZXR0aW5ncyBhcmUgdGhlIHNhbWUsIHRoZW4gdGhlIGRhdGEgc2hvdWxkIG5vdCBiZSBmZXRjaGVkIGFnYWluP1xuICAgICAgbWVhc3VyZW1lbnRzID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdChmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWVhc3VyZW1lbnRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVTZXJpZXNEYXRhVG9FeHBvcnQoZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcpIHtcbiAgICBjb25zdCBkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAgPSB0aGlzLmdyb3VwU2VyaWVzQnlEZXZpY2VJZChcbiAgICAgIGV4cG9ydENvbmZpZy5kYXRhcG9pbnREZXRhaWxzXG4gICAgKTtcblxuICAgIGNvbnN0IGZldGNoZWREYXRhUHJvbWlzZXMgPSBBcnJheS5mcm9tKGRhdGFwb2ludHNWYWx1ZXNEYXRhTWFwKS5tYXAoXG4gICAgICBhc3luYyAoW3NvdXJjZSwgc2VyaWVzXSkgPT4ge1xuICAgICAgICBjb25zdCB7IGRhdGVGcm9tLCBkYXRlVG8sIGFnZ3JlZ2F0aW9uIH0gPSBleHBvcnRDb25maWc7XG5cbiAgICAgICAgY29uc3QgcmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyID0ge1xuICAgICAgICAgIGRhdGVGcm9tLFxuICAgICAgICAgIGRhdGVUbyxcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgc2VyaWVzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogYWdncmVnYXRpb24gYXMgYWdncmVnYXRpb25UeXBlXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgeyBkYXRhIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmZldGNoU2VyaWVzRGF0YShyYXdGaWx0ZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHNvdXJjZSwgZGF0YSB9O1xuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCBmZXRjaGVkRGF0YUdyb3VwZWRCeVNvdXJjZTogU291cmNlSXRlbVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoZmV0Y2hlZERhdGFQcm9taXNlcyk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzU2VyaWVzRGF0YShleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscywgZmV0Y2hlZERhdGFHcm91cGVkQnlTb3VyY2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlU2VyaWVzRmlsdGVyKGZpbHRlcnM6IElTZXJpZXNGaWx0ZXIsIHJvdW5kU2Vjb25kczogYm9vbGVhbik6IElTZXJpZXNGaWx0ZXIge1xuICAgIGNvbnN0IHsgZGF0ZUZyb20sIGRhdGVUbywgc291cmNlLCBzZXJpZXMsIGFnZ3JlZ2F0aW9uVHlwZSB9ID0gZmlsdGVycztcbiAgICBjb25zdCBmcm9tID0gdGhpcy5hZGp1c3REYXRlKGRhdGVGcm9tLCAwLCByb3VuZFNlY29uZHMpO1xuICAgIGNvbnN0IHRvID0gdGhpcy5hZGp1c3REYXRlKGRhdGVUbywgMCwgcm91bmRTZWNvbmRzKTtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHtcbiAgICAgIGRhdGVGcm9tOiBmcm9tLFxuICAgICAgZGF0ZVRvOiB0byxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgcmV2ZXJ0OiB0cnVlXG4gICAgfTtcblxuICAgIC8vIFRoZSAnTk9ORScgYWdncmVnYXRpb24gdHlwZSBpcyBub3QgaGFuZGxlZCBieSBhIGJhY2tlbmQsIHNvIGV2ZW4gd2hlbiBpcyBzZWxlY3RlZCwgaXQgaXMgbm90IHBhc3NlZCBhcyBhIGZpbHRlciBwYXJhbWV0ZXIuXG4gICAgaWYgKGFnZ3JlZ2F0aW9uVHlwZSAmJiBhZ2dyZWdhdGlvblR5cGUgIT09IChBR0dSRUdBVElPTl9WQUxVRVMubm9uZSBhcyBhZ2dyZWdhdGlvblR5cGUpKSB7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRpb25UeXBlID0gYWdncmVnYXRpb25UeXBlO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGl0IGlzIGEgdGVtcG9yYWwgd29ya2Fyb3VuZCBmb3IgYSBidWcgaW4gdGhlIGJhY2tlbmQsXG4gICAgLy8gd2hlcmUgdGhlIHNlcmllcyB3aXRoIG1vcmUgdGhhbiBvbmUgZG90IGFyZSBpbXBvc3NpYmxlIHRvIHJldHJpZXZlOlxuICAgIC8vIGh0dHBzOi8vY3VtdWxvY2l0eS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9NVE0tNTkyNzdcbiAgICBpZiAoc2VyaWVzKSB7XG4gICAgICBjb25zdCBoYXNNb3JlVGhhbk9uZURvdCA9IChzZXJpZXMgYXMgc3RyaW5nW10pLnNvbWUocyA9PiBzLnNwbGl0KCcuJykubGVuZ3RoID4gMik7XG4gICAgICBpZiAoIWhhc01vcmVUaGFuT25lRG90KSB7XG4gICAgICAgIGZpbHRlci5zZXJpZXMgPSBzZXJpZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcjtcbiAgfVxufVxuIl19
|