ngx-hana-nameserver-history-viewer 1.2.1 → 21.1.0

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.
Files changed (147) hide show
  1. package/README.md +2 -1
  2. package/{fesm2020 → fesm2022}/ngx-hana-nameserver-history-viewer.mjs +2898 -3983
  3. package/fesm2022/ngx-hana-nameserver-history-viewer.mjs.map +1 -0
  4. package/ngx-hana-nameserver-history-viewer-21.1.0.tgz +0 -0
  5. package/package.json +20 -27
  6. package/types/ngx-hana-nameserver-history-viewer.d.ts +545 -0
  7. package/esm2020/ngx-hana-nameserver-history-viewer.mjs +0 -5
  8. package/esm2020/public-api.mjs +0 -2
  9. package/esm2020/src/nameserver-history-viewer/components/alert/alert.component.mjs +0 -68
  10. package/esm2020/src/nameserver-history-viewer/components/alert/alert.module.mjs +0 -22
  11. package/esm2020/src/nameserver-history-viewer/components/alert/index.mjs +0 -3
  12. package/esm2020/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.mjs +0 -112
  13. package/esm2020/src/nameserver-history-viewer/components/file-drop-input/index.mjs +0 -2
  14. package/esm2020/src/nameserver-history-viewer/components/index.mjs +0 -9
  15. package/esm2020/src/nameserver-history-viewer/components/instruction/index.mjs +0 -2
  16. package/esm2020/src/nameserver-history-viewer/components/instruction/instruction.component.mjs +0 -42
  17. package/esm2020/src/nameserver-history-viewer/components/nameserver-history.component.mjs +0 -557
  18. package/esm2020/src/nameserver-history-viewer/components/port-selector/index.mjs +0 -2
  19. package/esm2020/src/nameserver-history-viewer/components/port-selector/port-selector.component.mjs +0 -69
  20. package/esm2020/src/nameserver-history-viewer/components/port-selector/port-selector.service.mjs +0 -41
  21. package/esm2020/src/nameserver-history-viewer/components/progress-bar/index.mjs +0 -2
  22. package/esm2020/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.mjs +0 -40
  23. package/esm2020/src/nameserver-history-viewer/components/time-range-selector/index.mjs +0 -2
  24. package/esm2020/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.mjs +0 -70
  25. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/index.mjs +0 -2
  26. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.mjs +0 -88
  27. package/esm2020/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.mjs +0 -47
  28. package/esm2020/src/nameserver-history-viewer/index.mjs +0 -3
  29. package/esm2020/src/nameserver-history-viewer/nameserver-history.module.mjs +0 -63
  30. package/esm2020/src/nameserver-history-viewer/services/chart.service.mjs +0 -328
  31. package/esm2020/src/nameserver-history-viewer/services/file.service.mjs +0 -390
  32. package/esm2020/src/nameserver-history-viewer/services/index.mjs +0 -4
  33. package/esm2020/src/nameserver-history-viewer/services/ui.service.mjs +0 -557
  34. package/esm2020/src/nameserver-history-viewer/types/abort.types.mjs +0 -6
  35. package/esm2020/src/nameserver-history-viewer/types/alert.types.mjs +0 -8
  36. package/esm2020/src/nameserver-history-viewer/types/chart-content-data-item.types.mjs +0 -2
  37. package/esm2020/src/nameserver-history-viewer/types/chart-content-data.types.mjs +0 -2
  38. package/esm2020/src/nameserver-history-viewer/types/chart-content-header.types.mjs +0 -2
  39. package/esm2020/src/nameserver-history-viewer/types/chart-content-time.types.mjs +0 -2
  40. package/esm2020/src/nameserver-history-viewer/types/chart-content.types.mjs +0 -2
  41. package/esm2020/src/nameserver-history-viewer/types/color-rgba.types.mjs +0 -2
  42. package/esm2020/src/nameserver-history-viewer/types/html-element.type.mjs +0 -9
  43. package/esm2020/src/nameserver-history-viewer/types/index.mjs +0 -28
  44. package/esm2020/src/nameserver-history-viewer/types/item.types.mjs +0 -14
  45. package/esm2020/src/nameserver-history-viewer/types/legend-color.types.mjs +0 -2
  46. package/esm2020/src/nameserver-history-viewer/types/load-history-info-backup.types.mjs +0 -2
  47. package/esm2020/src/nameserver-history-viewer/types/load-history-info-columnstore.types.mjs +0 -2
  48. package/esm2020/src/nameserver-history-viewer/types/load-history-info-host.types.mjs +0 -2
  49. package/esm2020/src/nameserver-history-viewer/types/load-history-info-item.types.mjs +0 -2
  50. package/esm2020/src/nameserver-history-viewer/types/load-history-info-persistence.types.mjs +0 -2
  51. package/esm2020/src/nameserver-history-viewer/types/load-history-info-rowstore.types.mjs +0 -2
  52. package/esm2020/src/nameserver-history-viewer/types/load-history-info-server.types.mjs +0 -2
  53. package/esm2020/src/nameserver-history-viewer/types/load-history-info-session-admission-control.types.mjs +0 -2
  54. package/esm2020/src/nameserver-history-viewer/types/load-history-info-sql.types.mjs +0 -2
  55. package/esm2020/src/nameserver-history-viewer/types/load-history-info-sync-primitives.types.mjs +0 -2
  56. package/esm2020/src/nameserver-history-viewer/types/load-history-info-threads.types.mjs +0 -2
  57. package/esm2020/src/nameserver-history-viewer/types/load-history-info.types.mjs +0 -2
  58. package/esm2020/src/nameserver-history-viewer/types/port.types.mjs +0 -2
  59. package/esm2020/src/nameserver-history-viewer/types/scale-group.types.mjs +0 -17
  60. package/esm2020/src/nameserver-history-viewer/types/unit-category.types.mjs +0 -10
  61. package/esm2020/src/nameserver-history-viewer/types/unit.types.mjs +0 -14
  62. package/esm2020/src/nameserver-history-viewer/utils/chart-util.mjs +0 -25
  63. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/chartjs_ext.mjs +0 -2
  64. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/data_culling.mjs +0 -56
  65. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/data_mipmap.mjs +0 -139
  66. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/index.mjs +0 -41
  67. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.mjs +0 -106
  68. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/responsive_downsample_plugin.mjs +0 -167
  69. package/esm2020/src/nameserver-history-viewer/utils/chartjs-downsample/utils.mjs +0 -114
  70. package/esm2020/src/nameserver-history-viewer/utils/chartjs-zoom/chart.zoom.mjs +0 -527
  71. package/esm2020/src/nameserver-history-viewer/utils/chartjs-zoom/index.mjs +0 -2
  72. package/esm2020/src/nameserver-history-viewer/utils/file-util.mjs +0 -161
  73. package/esm2020/src/nameserver-history-viewer/utils/index.mjs +0 -5
  74. package/esm2020/src/nameserver-history-viewer/utils/time-util.mjs +0 -99
  75. package/esm2020/src/nameserver-history-viewer/utils/ui-util.mjs +0 -162
  76. package/fesm2015/ngx-hana-nameserver-history-viewer.mjs +0 -4098
  77. package/fesm2015/ngx-hana-nameserver-history-viewer.mjs.map +0 -1
  78. package/fesm2020/ngx-hana-nameserver-history-viewer.mjs.map +0 -1
  79. package/ngx-hana-nameserver-history-viewer.d.ts +0 -5
  80. package/public-api.d.ts +0 -1
  81. package/src/nameserver-history-viewer/components/alert/alert.component.d.ts +0 -21
  82. package/src/nameserver-history-viewer/components/alert/alert.module.d.ts +0 -8
  83. package/src/nameserver-history-viewer/components/alert/index.d.ts +0 -2
  84. package/src/nameserver-history-viewer/components/file-drop-input/file-drop-input.component.d.ts +0 -16
  85. package/src/nameserver-history-viewer/components/file-drop-input/index.d.ts +0 -1
  86. package/src/nameserver-history-viewer/components/index.d.ts +0 -8
  87. package/src/nameserver-history-viewer/components/instruction/index.d.ts +0 -1
  88. package/src/nameserver-history-viewer/components/instruction/instruction.component.d.ts +0 -17
  89. package/src/nameserver-history-viewer/components/nameserver-history.component.d.ts +0 -262
  90. package/src/nameserver-history-viewer/components/port-selector/index.d.ts +0 -1
  91. package/src/nameserver-history-viewer/components/port-selector/port-selector.component.d.ts +0 -31
  92. package/src/nameserver-history-viewer/components/port-selector/port-selector.service.d.ts +0 -14
  93. package/src/nameserver-history-viewer/components/progress-bar/index.d.ts +0 -1
  94. package/src/nameserver-history-viewer/components/progress-bar/progress-bar.component.d.ts +0 -6
  95. package/src/nameserver-history-viewer/components/time-range-selector/index.d.ts +0 -1
  96. package/src/nameserver-history-viewer/components/time-range-selector/time-range-selector.component.d.ts +0 -19
  97. package/src/nameserver-history-viewer/components/timezone-selector/index.d.ts +0 -1
  98. package/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.component.d.ts +0 -26
  99. package/src/nameserver-history-viewer/components/timezone-selector/timezone-selector.service.d.ts +0 -21
  100. package/src/nameserver-history-viewer/index.d.ts +0 -2
  101. package/src/nameserver-history-viewer/nameserver-history.module.d.ts +0 -19
  102. package/src/nameserver-history-viewer/services/chart.service.d.ts +0 -59
  103. package/src/nameserver-history-viewer/services/file.service.d.ts +0 -63
  104. package/src/nameserver-history-viewer/services/index.d.ts +0 -3
  105. package/src/nameserver-history-viewer/services/ui.service.d.ts +0 -88
  106. package/src/nameserver-history-viewer/types/abort.types.d.ts +0 -4
  107. package/src/nameserver-history-viewer/types/alert.types.d.ts +0 -6
  108. package/src/nameserver-history-viewer/types/chart-content-data-item.types.d.ts +0 -4
  109. package/src/nameserver-history-viewer/types/chart-content-data.types.d.ts +0 -4
  110. package/src/nameserver-history-viewer/types/chart-content-header.types.d.ts +0 -4
  111. package/src/nameserver-history-viewer/types/chart-content-time.types.d.ts +0 -3
  112. package/src/nameserver-history-viewer/types/chart-content.types.d.ts +0 -10
  113. package/src/nameserver-history-viewer/types/color-rgba.types.d.ts +0 -6
  114. package/src/nameserver-history-viewer/types/html-element.type.d.ts +0 -7
  115. package/src/nameserver-history-viewer/types/index.d.ts +0 -27
  116. package/src/nameserver-history-viewer/types/item.types.d.ts +0 -12
  117. package/src/nameserver-history-viewer/types/legend-color.types.d.ts +0 -4
  118. package/src/nameserver-history-viewer/types/load-history-info-backup.types.d.ts +0 -7
  119. package/src/nameserver-history-viewer/types/load-history-info-columnstore.types.d.ts +0 -7
  120. package/src/nameserver-history-viewer/types/load-history-info-host.types.d.ts +0 -15
  121. package/src/nameserver-history-viewer/types/load-history-info-item.types.d.ts +0 -13
  122. package/src/nameserver-history-viewer/types/load-history-info-persistence.types.d.ts +0 -11
  123. package/src/nameserver-history-viewer/types/load-history-info-rowstore.types.d.ts +0 -5
  124. package/src/nameserver-history-viewer/types/load-history-info-server.types.d.ts +0 -10
  125. package/src/nameserver-history-viewer/types/load-history-info-session-admission-control.types.d.ts +0 -10
  126. package/src/nameserver-history-viewer/types/load-history-info-sql.types.d.ts +0 -16
  127. package/src/nameserver-history-viewer/types/load-history-info-sync-primitives.types.d.ts +0 -5
  128. package/src/nameserver-history-viewer/types/load-history-info-threads.types.d.ts +0 -9
  129. package/src/nameserver-history-viewer/types/load-history-info.types.d.ts +0 -22
  130. package/src/nameserver-history-viewer/types/port.types.d.ts +0 -5
  131. package/src/nameserver-history-viewer/types/scale-group.types.d.ts +0 -15
  132. package/src/nameserver-history-viewer/types/unit-category.types.d.ts +0 -8
  133. package/src/nameserver-history-viewer/types/unit.types.d.ts +0 -12
  134. package/src/nameserver-history-viewer/utils/chart-util.d.ts +0 -14
  135. package/src/nameserver-history-viewer/utils/chartjs-downsample/chartjs_ext.d.ts +0 -89
  136. package/src/nameserver-history-viewer/utils/chartjs-downsample/data_culling.d.ts +0 -32
  137. package/src/nameserver-history-viewer/utils/chartjs-downsample/data_mipmap.d.ts +0 -78
  138. package/src/nameserver-history-viewer/utils/chartjs-downsample/index.d.ts +0 -1
  139. package/src/nameserver-history-viewer/utils/chartjs-downsample/lttb_data_mipmap.d.ts +0 -57
  140. package/src/nameserver-history-viewer/utils/chartjs-downsample/responsive_downsample_plugin.d.ts +0 -55
  141. package/src/nameserver-history-viewer/utils/chartjs-downsample/utils.d.ts +0 -64
  142. package/src/nameserver-history-viewer/utils/chartjs-zoom/chart.zoom.d.ts +0 -30
  143. package/src/nameserver-history-viewer/utils/chartjs-zoom/index.d.ts +0 -1
  144. package/src/nameserver-history-viewer/utils/file-util.d.ts +0 -68
  145. package/src/nameserver-history-viewer/utils/index.d.ts +0 -4
  146. package/src/nameserver-history-viewer/utils/time-util.d.ts +0 -23
  147. package/src/nameserver-history-viewer/utils/ui-util.d.ts +0 -41
@@ -1,557 +0,0 @@
1
- import { Component, ElementRef, Input, ViewChild } from '@angular/core';
2
- import { SelectionModel } from '@angular/cdk/collections';
3
- import { setChartHeight, sleep, isEmptyData, getDisplayPort, getFileFromInput, isSameFile, getAbbreviatedFileName, getFileFromDrop, getRealPorts, getTimeString, printProcessedTime, getTimeRangeString, generatePorts, getDefaultTimezone, blobToFile, isFile, } from '../utils';
4
- import { Abort, Alert, HtmlElement, Item } from '../types';
5
- import { FileService, ChartService, UIService } from '../services';
6
- import 'hammerjs';
7
- import '../utils/chartjs-downsample';
8
- import '../utils/chartjs-zoom';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "../services";
11
- import * as i2 from "./file-drop-input/file-drop-input.component";
12
- import * as i3 from "./progress-bar/progress-bar.component";
13
- import * as i4 from "./time-range-selector/time-range-selector.component";
14
- import * as i5 from "./timezone-selector/timezone-selector.component";
15
- import * as i6 from "./port-selector/port-selector.component";
16
- import * as i7 from "./instruction/instruction.component";
17
- import * as i8 from "ngx-selection-table";
18
- import * as i9 from "./alert/alert.component";
19
- import * as i10 from "@angular/common";
20
- var SearchType;
21
- (function (SearchType) {
22
- SearchType["searchWithSubHeader"] = "searchWithSubHeader";
23
- SearchType["searchAll"] = "searchAll";
24
- SearchType["searchInChildren"] = "searchInChildren";
25
- })(SearchType || (SearchType = {}));
26
- export class NameServerHistoryComponent {
27
- constructor(fileService, chartService, uiService) {
28
- this.fileService = fileService;
29
- this.chartService = chartService;
30
- this.uiService = uiService;
31
- /**
32
- * Input (optional) bind to [showInstruction]
33
- */
34
- this.showInstruction = true;
35
- /**
36
- * time info of the name server history file
37
- */
38
- this.time = {};
39
- /**
40
- * data of the name server history file
41
- */
42
- this.data = {};
43
- /**
44
- * header of the name server history file
45
- */
46
- this.header = [];
47
- /**
48
- * host of the name server history file
49
- */
50
- this.host = 'nameserver history file';
51
- /**
52
- * the progress for reading file
53
- */
54
- this.readProgress = 0;
55
- /**
56
- * selected/dropped file name (abbreviation), full file name will be shown via the tooltips
57
- */
58
- this.abbreviatedFileName = 'or Drop File Here';
59
- /**
60
- * for the instruction step 4
61
- */
62
- this.stepShowChart = false;
63
- this.searchType = SearchType.searchAll;
64
- }
65
- async ngOnChanges(changes) {
66
- const fbc = changes.fileBuffer;
67
- // !isFile(fbc.currentValue) --> only show chart when it's not a file -> it's a file, means the object has already been processed
68
- if (fbc && fbc.currentValue && fbc.currentValue !== fbc.previousValue && !isFile(fbc.currentValue)) {
69
- // simulate selecting file
70
- const simulatedEvent = { target: { files: [blobToFile(fbc.currentValue, this.streamModeFileName)] } };
71
- await this.fileSelected(simulatedEvent);
72
- this.port = undefined; // clear the port selection
73
- if (this.autoDisplay) {
74
- this.onResize(); // ngAfterViewInit/resize won't work in electron
75
- this.showChart();
76
- }
77
- }
78
- }
79
- ngAfterViewInit() {
80
- // init items' status
81
- // reset chart button will be disable by default later, only be enabled after zoomed
82
- this._toggleItems([
83
- { id: HtmlElement.chartArea, status: false },
84
- { id: HtmlElement.readFileProgress, status: false },
85
- { id: HtmlElement.showChartButton, status: false },
86
- { id: HtmlElement.loadPortsButton, status: true },
87
- { id: HtmlElement.resetChartButton, status: false }
88
- ]);
89
- this.onResize(); // update the size, otherwise there may have a scrollbar (because of the toast) if auto display is set to true
90
- }
91
- /**
92
- * Reset Chart to initial status
93
- * If legend is already selected/unselected from the list, it wouldn't be restored.
94
- */
95
- resetChart() {
96
- this._toggleItems([{ id: HtmlElement.resetChartButton, status: false }]);
97
- if (this.tableSource && this._selection) {
98
- this.chartService.resetChart(this.tableSource, this._selection)
99
- .catch(e => this._showMessage(Alert.error, e));
100
- }
101
- }
102
- /**
103
- * read the file and display the chart
104
- */
105
- showChart() {
106
- // after click, this button and reset button needs to be disabled
107
- this._toggleItems([
108
- { id: HtmlElement.resetChartButton, status: false },
109
- { id: HtmlElement.showChartButton, status: false }
110
- ]);
111
- this.stepShowChart = true;
112
- this._initChartEnv().then(() => {
113
- const selectedTime = this._selectedTimeRange;
114
- if (selectedTime.startTime > selectedTime.endTime) {
115
- this._showMessage(Alert.error, 'Time range is not correct.');
116
- return;
117
- }
118
- if (this.file) {
119
- // it's time for displaying the reading progress bar
120
- this._toggleItems([{ id: HtmlElement.readFileProgress, status: true }]);
121
- return this._buildChartFromDataFile(this.file, selectedTime.startTime, selectedTime.endTime, this.port);
122
- }
123
- }).catch(e => {
124
- this._showMessage(Alert.error, e);
125
- this._toggleItems([{ id: HtmlElement.readFileProgress, status: false }]);
126
- });
127
- }
128
- /**
129
- * load all ports from file
130
- */
131
- loadPorts() {
132
- // do confirmation actions
133
- if (this.file) {
134
- // before start loading ports from file, display progress bar and disable the show chart button
135
- this._toggleItems([
136
- { id: HtmlElement.readFileProgress, status: true },
137
- { id: HtmlElement.showChartButton, status: false }
138
- ]);
139
- this._readPortsFromFile(this.file);
140
- }
141
- }
142
- /**
143
- * select name server history file, currently only supports 1 file.
144
- */
145
- async fileSelected(event) {
146
- const selectedFile = getFileFromInput(event.target);
147
- if (selectedFile) {
148
- if (!isSameFile(this.file, selectedFile)) {
149
- // init port selector
150
- await this._initPortSelector().catch(e => this._showMessage(Alert.error, e));
151
- this.file = selectedFile;
152
- this.abbreviatedFileName = getAbbreviatedFileName(this.file.name);
153
- // after file has been selected, the show chart button needs to be enabled
154
- this._toggleItems([{ id: HtmlElement.showChartButton, status: true }]);
155
- }
156
- }
157
- }
158
- /**
159
- * drop name server history file, currently only supports 1 file.
160
- */
161
- fileDropped(event) {
162
- getFileFromDrop(event)
163
- .then(file => {
164
- if (!isSameFile(this.file, file)) {
165
- // init port selector
166
- this.file = file;
167
- if (this.file) {
168
- this.abbreviatedFileName = getAbbreviatedFileName(this.file.name);
169
- // after file has been dropped, the show chart button needs to be enabled
170
- this._toggleItems([{ id: HtmlElement.showChartButton, status: true }]);
171
- }
172
- }
173
- })
174
- .then(() => {
175
- return this._initPortSelector();
176
- })
177
- .catch(e => this._showMessage(Alert.error, e));
178
- }
179
- /**
180
- * Select one item from selection table, relative dataset will be shown or hidden
181
- */
182
- selectItem(event) {
183
- if (event && event.tableRow) {
184
- const row = event.tableRow;
185
- this._selection.toggle(row);
186
- this.chartService.toggleDataInChart(row.KPI, !this._selection.isSelected(row))
187
- .catch(e => this._showMessage(Alert.error, e));
188
- }
189
- }
190
- /**
191
- * recalculating chart height when resizing
192
- */
193
- onResize() {
194
- const nameserverHistoryAllElement = this.nameserverHistoryAllRef ? this.nameserverHistoryAllRef.nativeElement : null;
195
- const nameserverHistoryContentElement = this.nameserverHistoryContentRef ? this.nameserverHistoryContentRef.nativeElement : null;
196
- setChartHeight(nameserverHistoryAllElement, nameserverHistoryContentElement);
197
- }
198
- /**
199
- * Switch port and reinitialize chart, triggered by changing the port
200
- * @param port the selected port
201
- */
202
- switchPortForChart(port) {
203
- if (port === this._currentChartPort) {
204
- // not to switch port, because the relative port is displaying, no need to render twice.
205
- return;
206
- }
207
- if (!this.file || !port || port.length === 0 || port.slice(1, 3) === '**') {
208
- return;
209
- }
210
- else if (Object.keys(this.time).length > 1 && !getRealPorts(Object.keys(this.time).filter(key => this.time[key])).includes(port)) {
211
- this._showMessage(Alert.info, `Data of port:${port} is not loaded, please load the data first by clicking the "Show" button.`);
212
- return;
213
- }
214
- // only do switch ports when available ports number > 1
215
- if (Object.keys(this.time).filter(key => this.time[key]).length > 1) {
216
- // disable the "show chart" and "reset chart" button first
217
- this._toggleItems([
218
- { id: HtmlElement.showChartButton, status: false },
219
- { id: HtmlElement.resetChartButton, status: false }
220
- ]);
221
- // init the environment with switch flag
222
- this._initChartEnv(true).then(() => {
223
- return this._buildChart(port, null, true);
224
- }).catch(e => this._showMessage(Alert.error, e));
225
- }
226
- }
227
- /**
228
- * get the columns which need to be hidden from the selection table
229
- */
230
- get hiddenColumns() {
231
- return this.uiService.getHiddenColumns(this.hideMeasureColumns);
232
- }
233
- /**
234
- * get default timezone
235
- */
236
- get defaultTimezone() {
237
- return getDefaultTimezone();
238
- }
239
- /**
240
- * get the key column (KPI)
241
- */
242
- get kpiColumn() {
243
- return Item.kpi;
244
- }
245
- /**
246
- * get the key column (KPI)
247
- */
248
- get descColumn() {
249
- return Item.description;
250
- }
251
- /**
252
- * get the selected time range, set second and millisecond part to 0
253
- */
254
- get _selectedTimeRange() {
255
- let startTime = 0;
256
- let endTime = 4102358400000; // 2099/12/31
257
- if (this.dateTimeRange != null) {
258
- if (this.dateTimeRange.length >= 1) {
259
- // get start time
260
- if (this.dateTimeRange[0]) {
261
- startTime = this.dateTimeRange[0].setSeconds(0, 0);
262
- }
263
- if (this.dateTimeRange[1]) {
264
- endTime = this.dateTimeRange[1].setSeconds(0, 0);
265
- }
266
- }
267
- }
268
- return { startTime: startTime, endTime: endTime };
269
- }
270
- /**
271
- * get the time range string, eg: 2018-10-25 10:25 ~ 2018-10-26 10:26
272
- */
273
- get _selectedTimeRangeString() {
274
- const selectedTimeRangeString = this._selectedTimeRange;
275
- return `${getTimeString(selectedTimeRangeString.startTime)} ~ ${getTimeString(selectedTimeRangeString.endTime)}`;
276
- }
277
- /**
278
- * get array of header key
279
- */
280
- get _headerKey() {
281
- if (this.header) {
282
- return this.header.map(headerItem => headerItem.key);
283
- }
284
- }
285
- /**
286
- * get array of header text
287
- */
288
- get _headerText() {
289
- return this.header.map(headerItem => headerItem.text);
290
- }
291
- /**
292
- * read ports from the selected nameserver history file
293
- * @param file nameserver history file
294
- */
295
- _readPortsFromFile(file) {
296
- this.fileService.getPortsFromFile(file, (progress) => {
297
- this.readProgress = progress;
298
- }).then(ports => {
299
- return sleep(100).then(() => {
300
- return this._initPortSelector(ports);
301
- });
302
- }).catch(e => this._showMessage(Alert.error, e));
303
- }
304
- /**
305
- * build chart from the selected nameserver history file
306
- * @param file the nameserver history file
307
- * @param startTime start time
308
- * @param endTime end time
309
- * @param selectedPort selected port for nameserver history file (MDC system)
310
- */
311
- _buildChartFromDataFile(file, startTime, endTime, selectedPort) {
312
- return this.fileService.getChartContentFromFile(file, startTime, endTime, selectedPort, this.timezone, this.maxRowsLimitation, progress => this.readProgress = progress)
313
- .then(result => {
314
- // parsing done
315
- const beginTime = new Date();
316
- const promises = [];
317
- const ports = getRealPorts(Object.keys(result.time), true);
318
- ports.forEach(port => {
319
- // convert the unit and generate controlling data for all ports
320
- promises.push(this.uiService.convertUnitAndGenerateControlData(result.data[port], result.header, port));
321
- });
322
- return Promise.all(promises)
323
- .then(() => {
324
- // get all ports from the analyzed data(time)
325
- // get the port that will be shown in the page
326
- const port = getDisplayPort(ports, selectedPort);
327
- printProcessedTime(beginTime, 'converting step');
328
- ports.forEach(portItem => this.uiService.generateYScale(portItem));
329
- printProcessedTime(beginTime, 'generating YScale step');
330
- this.data = result.data;
331
- this.time = result.time;
332
- this.header = this.uiService.getHeader(result.header, port);
333
- this.host = result.host;
334
- if (result.aborted === Abort.maxLineNumReached) {
335
- this._showMessage(Alert.warning, `Maximum number of lines reached. Processed time range is: ${getTimeRangeString(this.time)}.`);
336
- }
337
- else {
338
- if (isEmptyData(this.data)) {
339
- this._showMessage(Alert.info, `Cannot find any data for the selected time period: ${this._selectedTimeRangeString}`);
340
- }
341
- else {
342
- this._showMessage(Alert.success, `Processed time range is: ${getTimeRangeString(this.time)}.`);
343
- }
344
- }
345
- return sleep(100).then(() => {
346
- return this._buildChart(port, ports);
347
- });
348
- });
349
- });
350
- }
351
- /**
352
- * reinitialize the port selector with the ports
353
- */
354
- _initPortSelector(ports = null, selectedPort = null) {
355
- return new Promise(resolve => {
356
- // initialization for ngx-select
357
- if (ports != null && ports.length > 1) {
358
- // MDC, remove default '0000' port
359
- this.ports = generatePorts(getRealPorts(ports), selectedPort);
360
- }
361
- else {
362
- this.ports = generatePorts(ports);
363
- }
364
- if (ports != null && selectedPort === null) {
365
- // reset status when doing:
366
- // 1. loading ports
367
- // 2. the file doesn't contain the selected Port
368
- this.readProgress = 0;
369
- // hide the progress bar and enable the "show chart" button
370
- this._toggleItems([
371
- { id: HtmlElement.readFileProgress, status: false },
372
- { id: HtmlElement.showChartButton, status: true }
373
- ]);
374
- }
375
- resolve();
376
- });
377
- }
378
- /**
379
- * build and display the chart on page
380
- * @param port the selected port
381
- * @param ports all available ports
382
- * @param switchFlag indicates whether this function is triggered from switching ports (no init port selector needed)
383
- */
384
- _buildChart(port, ports, switchFlag = false) {
385
- const beginTime = new Date();
386
- if (port) {
387
- return Promise.resolve(this._loadSettingsForSelectionsTable(port))
388
- .then(() => {
389
- // get the config
390
- return this.chartService.buildChart(this.time[port], this.data[port], this.uiService.getYScale(this._headerKey, port), this._headerText, this._headerKey, this._selection, this.tableSource, this._getHostTitle(port), this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems), this._onZoom.bind(this))
391
- .then(() => {
392
- this.readProgress = 0;
393
- // after chart has been created, show the chart area, hide progress bar and enable the "show chart" button
394
- this._toggleItems([
395
- { id: HtmlElement.chartArea, status: true },
396
- { id: HtmlElement.readFileProgress, status: false },
397
- { id: HtmlElement.showChartButton, status: true }
398
- ]);
399
- // set port to current displaying port
400
- this._currentChartPort = port;
401
- printProcessedTime(beginTime, 'step_build_chart');
402
- if (ports && ports.length > 0) {
403
- if (!switchFlag) {
404
- // initialize port selector. Do not need to do it when switching port.
405
- return this._initPortSelector(ports, port);
406
- }
407
- }
408
- });
409
- });
410
- }
411
- else {
412
- if (ports.length > 0) {
413
- this._showMessage(Alert.warning, 'The selected port does not exist in the name server history file. Please choose a correct port and have a try again.');
414
- if (!switchFlag) {
415
- // initialize port selector. Do not need to do it when switching port.
416
- return this._initPortSelector(ports, port);
417
- }
418
- }
419
- }
420
- }
421
- /**
422
- * get the string that will be displayed on the title area of the chart
423
- * eg: host1 - 30040 (2018-09-05 15:32:32 ~ 2018-09-07 15:32:15)
424
- * @param port selected port
425
- */
426
- _getHostTitle(port) {
427
- if (this.host) {
428
- return `${this.host} - ${port} ( ${getTimeRangeString(this.time[port])} )`;
429
- }
430
- }
431
- /**
432
- * after zoom, enable the reset button.
433
- */
434
- _onZoom() {
435
- this._toggleItems([{ id: HtmlElement.resetChartButton, status: true }]);
436
- }
437
- /**
438
- * initialize chart, including: destroy current chart, initialize config, initialize all relative data
439
- */
440
- _initChartEnv(switchFlag = false) {
441
- return this.chartService.destroyChart().then(() => {
442
- {
443
- // cleanup other data
444
- this._toggleItems([{ id: HtmlElement.chartArea, status: false }]);
445
- if (!switchFlag) {
446
- Object.keys(this.time).forEach(key => {
447
- if (this.time[key]) {
448
- this.time[key].length = 0;
449
- }
450
- });
451
- this.time = {};
452
- Object.keys(this.data).forEach(key => {
453
- if (this.data[key]) {
454
- this.data[key].length = 0;
455
- }
456
- });
457
- this.data = {};
458
- this.header.length = 0;
459
- this.host = 'nameserver history file';
460
- this.tableSource = void 0;
461
- this.readProgress = 0;
462
- this.uiService.clearLoadHistoryInfos();
463
- }
464
- }
465
- });
466
- }
467
- /**
468
- * Load settings for the selection table (the right part of the chart)
469
- * @param port the selected port
470
- */
471
- _loadSettingsForSelectionsTable(port) {
472
- this.tableSource = this.uiService.getSelectionTableRows(this._headerKey, port, this.defaultSelectedItems);
473
- this._selection = new SelectionModel(true, []);
474
- this.tableSource.forEach(row => {
475
- if (this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems).includes(row.KPI)) {
476
- this._selection.select(row);
477
- }
478
- });
479
- }
480
- /**
481
- * Show messages
482
- * @param type type of the message
483
- * @param message message text
484
- */
485
- _showMessage(type, message) {
486
- if (type) {
487
- switch (type) {
488
- case Alert.success:
489
- case Alert.info:
490
- break;
491
- case Alert.warning:
492
- console.warn(message);
493
- break;
494
- case Alert.error:
495
- console.error(message);
496
- }
497
- }
498
- if (this.alertMessage === message) {
499
- // try trigger the change event of the alert.
500
- this.alertMessage = void 0;
501
- setTimeout(() => this.alertMessage = message, 100);
502
- }
503
- else {
504
- this.alertMessage = message;
505
- }
506
- this.alertType = type;
507
- }
508
- /**
509
- * toggle items with the provided status (show or hide the relative element on the page)
510
- * @param items items with the relative id and status.
511
- */
512
- _toggleItems(items) {
513
- const getVariableNameByTypeId = (id) => {
514
- switch (id) {
515
- case HtmlElement.chartArea: return 'showChartFlag';
516
- case HtmlElement.readFileProgress: return 'showReadFileProgress';
517
- case HtmlElement.showChartButton: return 'enableShowChartButton';
518
- case HtmlElement.loadPortsButton: return 'enableLoadPortsButton';
519
- case HtmlElement.resetChartButton: return 'enableResetChartButton';
520
- }
521
- };
522
- if (items) {
523
- items.forEach(item => {
524
- this[getVariableNameByTypeId(item.id)] = item.status;
525
- });
526
- }
527
- }
528
- }
529
- NameServerHistoryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NameServerHistoryComponent, deps: [{ token: i1.FileService }, { token: i1.ChartService }, { token: i1.UIService }], target: i0.ɵɵFactoryTarget.Component });
530
- NameServerHistoryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NameServerHistoryComponent, selector: "ngx-hana-nameserver-history-viewer", inputs: { defaultSelectedItems: "defaultSelectedItems", hideMeasureColumns: "hideMeasureColumns", maxRowsLimitation: "maxRowsLimitation", showInstruction: "showInstruction", timezone: "timezone", fileBuffer: "fileBuffer", streamModeFileName: "streamModeFileName", autoDisplay: "autoDisplay" }, providers: [FileService, ChartService, UIService], viewQueries: [{ propertyName: "nameserverHistoryAllRef", first: true, predicate: ["nameserverHistoryAll"], descendants: true, read: ElementRef }, { propertyName: "nameserverHistoryContentRef", first: true, predicate: ["nameserverHistoryContent"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"], components: [{ type: i2.FileDropInputComponent, selector: "file-drop-input", inputs: ["dropAreaText", "inputAreaText"], outputs: ["fileDrop", "fileInput"] }, { type: i3.ProgressBarComponent, selector: "progress-bar", inputs: ["progress"] }, { type: i4.TimeRangeSelectorComponent, selector: "time-range-selector", inputs: ["disabled", "dateTimeRange"], outputs: ["dateTimeRangeChange"] }, { type: i5.TimezoneSelectorComponent, selector: "timezone-selector", inputs: ["disabled", "timezone"], outputs: ["timezoneChange"] }, { type: i6.PortSelectorComponent, selector: "port-selector", inputs: ["disabled", "port", "ports"], outputs: ["portChange"] }, { type: i7.InstructionComponent, selector: "instruction", inputs: ["step1Finished", "step2Finished", "step3Finished", "step4Finished", "step5Finished", "show"], outputs: ["showChange"] }, { type: i8.SelectionTableComponent, selector: "ngx-selection-table", inputs: ["filter", "keyColumn", "tableSource", "checkbox", "multiSelection", "clickToSelect", "hiddenColumns", "tooltipColumn", "searchStyle", "searchColumn"], outputs: ["change"] }, { type: i9.AlertComponent, selector: "alert", inputs: ["alertMessage", "alertType", "alertTimeout"], outputs: ["alertMessageChange"] }], directives: [{ type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
531
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NameServerHistoryComponent, decorators: [{
532
- type: Component,
533
- args: [{ selector: 'ngx-hana-nameserver-history-viewer', providers: [FileService, ChartService, UIService], template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"] }]
534
- }], ctorParameters: function () { return [{ type: i1.FileService }, { type: i1.ChartService }, { type: i1.UIService }]; }, propDecorators: { nameserverHistoryAllRef: [{
535
- type: ViewChild,
536
- args: ['nameserverHistoryAll', { read: ElementRef }]
537
- }], nameserverHistoryContentRef: [{
538
- type: ViewChild,
539
- args: ['nameserverHistoryContent', { read: ElementRef }]
540
- }], defaultSelectedItems: [{
541
- type: Input
542
- }], hideMeasureColumns: [{
543
- type: Input
544
- }], maxRowsLimitation: [{
545
- type: Input
546
- }], showInstruction: [{
547
- type: Input
548
- }], timezone: [{
549
- type: Input
550
- }], fileBuffer: [{
551
- type: Input
552
- }], streamModeFileName: [{
553
- type: Input
554
- }], autoDisplay: [{
555
- type: Input
556
- }] } });
557
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9uYW1lc2VydmVyLWhpc3Rvcnktdmlld2VyL2NvbXBvbmVudHMvbmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9uYW1lc2VydmVyLWhpc3Rvcnktdmlld2VyL2NvbXBvbmVudHMvbmFtZXNlcnZlci1oaXN0b3J5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQTRCLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUNMLGNBQWMsRUFDZCxLQUFLLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsVUFBVSxFQUNWLHNCQUFzQixFQUN0QixlQUFlLEVBQ2YsWUFBWSxFQUNaLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIsVUFBVSxFQUNWLE1BQU0sR0FDUCxNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFnRSxNQUFNLFVBQVUsQ0FBQztBQUN6SCxPQUFPLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbkUsT0FBTyxVQUFVLENBQUM7QUFDbEIsT0FBTyw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLHVCQUF1QixDQUFDOzs7Ozs7Ozs7Ozs7QUFFL0IsSUFBSyxVQUlKO0FBSkQsV0FBSyxVQUFVO0lBQ2IseURBQTJDLENBQUE7SUFDM0MscUNBQXVCLENBQUE7SUFDdkIsbURBQXFDLENB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MkI7c0JBQXZGLFNBQVM7dUJBQUMsMEJBQTBCLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUtsRCxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBS0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUtHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFLRyxlQUFlO3NCQUF2QixLQUFLO2dCQUtHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBS0csVUFBVTtzQkFBbEIsS0FBSztnQkFLRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBS0csV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XHJcbmltcG9ydCB7XHJcbiAgc2V0Q2hhcnRIZWlnaHQsXHJcbiAgc2xlZXAsXHJcbiAgaXNFbXB0eURhdGEsXHJcbiAgZ2V0RGlzcGxheVBvcnQsXHJcbiAgZ2V0RmlsZUZyb21JbnB1dCxcclxuICBpc1NhbWVGaWxlLFxyXG4gIGdldEFiYnJldmlhdGVkRmlsZU5hbWUsXHJcbiAgZ2V0RmlsZUZyb21Ecm9wLFxyXG4gIGdldFJlYWxQb3J0cyxcclxuICBnZXRUaW1lU3RyaW5nLFxyXG4gIHByaW50UHJvY2Vzc2VkVGltZSxcclxuICBnZXRUaW1lUmFuZ2VTdHJpbmcsXHJcbiAgZ2VuZXJhdGVQb3J0cyxcclxuICBnZXREZWZhdWx0VGltZXpvbmUsXHJcbiAgYmxvYlRvRmlsZSxcclxuICBpc0ZpbGUsXHJcbn0gZnJvbSAnLi4vdXRpbHMnO1xyXG5pbXBvcnQgeyBBYm9ydCwgQWxlcnQsIEh0bWxFbGVtZW50LCBJdGVtLCBDaGFydENvbnRlbnREYXRhLCBDaGFydENvbnRlbnRIZWFkZXIsIENoYXJ0Q29udGVudFRpbWUsIFBvcnQgfSBmcm9tICcuLi90eXBlcyc7XHJcbmltcG9ydCB7IEZpbGVTZXJ2aWNlLCBDaGFydFNlcnZpY2UsIFVJU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzJztcclxuXHJcbmltcG9ydCAnaGFtbWVyanMnO1xyXG5pbXBvcnQgJy4uL3V0aWxzL2NoYXJ0anMtZG93bnNhbXBsZSc7XHJcbmltcG9ydCAnLi4vdXRpbHMvY2hhcnRqcy16b29tJztcclxuXHJcbmVudW0gU2VhcmNoVHlwZSB7XHJcbiAgc2VhcmNoV2l0aFN1YkhlYWRlciA9ICdzZWFyY2hXaXRoU3ViSGVhZGVyJyxcclxuICBzZWFyY2hBbGwgPSAnc2VhcmNoQWxsJyxcclxuICBzZWFyY2hJbkNoaWxkcmVuID0gJ3NlYXJjaEluQ2hpbGRyZW4nXHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmd4LWhhbmEtbmFtZXNlcnZlci1oaXN0b3J5LXZpZXdlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL25hbWVzZXJ2ZXItaGlzdG9yeS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbICcuL25hbWVzZXJ2ZXItaGlzdG9yeS5jb21wb25lbnQuc2NzcycgXSxcclxuICBwcm92aWRlcnM6IFsgRmlsZVNlcnZpY2UsIENoYXJ0U2VydmljZSwgVUlTZXJ2aWNlIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIE5hbWVTZXJ2ZXJIaXN0b3J5Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcclxuICBAVmlld0NoaWxkKCduYW1lc2VydmVySGlzdG9yeUFsbCcsIHsgcmVhZDogRWxlbWVudFJlZiB9KSBuYW1lc2VydmVySGlzdG9yeUFsbFJlZjogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCduYW1lc2VydmVySGlzdG9yeUNvbnRlbnQnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgbmFtZXNlcnZlckhpc3RvcnlDb250ZW50UmVmOiBFbGVtZW50UmVmO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCAob3B0aW9uYWwpIGJpbmQgdG8gW2RlZmF1bHRTZWxlY3RlZEl0ZW1zXVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRlZmF1bHRTZWxlY3RlZEl0ZW1zOiBzdHJpbmdbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5wdXQgKG9wdGlvbmFsKSBiaW5kIHRvIFtoaWRlTWVhc3VyZUNvbHVtbnNdXHJcbiAgICovXHJcbiAgQElucHV0KCkgaGlkZU1lYXN1cmVDb2x1bW5zOiBzdHJpbmdbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5wdXQgKG9wdGlvbmFsKSBiaW5kIHRvIFttYXhSb3dzTGltaXRhdGlvbl1cclxuICAgKi9cclxuICBASW5wdXQoKSBtYXhSb3dzTGltaXRhdGlvbjogbnVtYmVyO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCAob3B0aW9uYWwpIGJpbmQgdG8gW3Nob3dJbnN0cnVjdGlvbl1cclxuICAgKi9cclxuICBASW5wdXQoKSBzaG93SW5zdHJ1Y3Rpb24gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBJbnB1dCAob3B0aW9uYWwpIGJpbmQgdG8gW3RpbWV6b25lXVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHRpbWV6b25lOiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIGZpbGUgYnVmZmVyLCB1c2UgdGhpcyBmb3Igc3RyZWFtIG1vZGVcclxuICAgKi9cclxuICBASW5wdXQoKSBmaWxlQnVmZmVyOiBCbG9iO1xyXG5cclxuICAvKipcclxuICAgKiBmaWxlIG5hbWUgZm9yIHN0cmVhbSBtb2RlXHJcbiAgICovXHJcbiAgQElucHV0KCkgc3RyZWFtTW9kZUZpbGVOYW1lOiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIGF1dG8gZGlzcGxheSB0aGUgY2hhcnQgaW4gc3RyZWFtIG1vZGVcclxuICAgKi9cclxuICBASW5wdXQoKSBhdXRvRGlzcGxheTogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogc2VsZWN0ZWQgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICovXHJcbiAgZmlsZTogRmlsZTtcclxuXHJcbiAgLyoqXHJcbiAgICogdGltZSBpbmZvIG9mIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICB0aW1lOiBDaGFydENvbnRlbnRUaW1lID0ge307XHJcblxyXG4gIC8qKlxyXG4gICAqIGRhdGEgb2YgdGhlIG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqL1xyXG4gIGRhdGE6IENoYXJ0Q29udGVudERhdGEgPSB7fTtcclxuXHJcbiAgLyoqXHJcbiAgICogaGVhZGVyIG9mIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGVcclxuICAgKi9cclxuICBoZWFkZXI6IENoYXJ0Q29udGVudEhlYWRlcltdID0gW107XHJcblxyXG4gIC8qKlxyXG4gICAqIGhvc3Qgb2YgdGhlIG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqL1xyXG4gIGhvc3QgPSAnbmFtZXNlcnZlciBoaXN0b3J5IGZpbGUnO1xyXG5cclxuICAvKipcclxuICAgKiBhbGVydCBtZXNzYWdlIGNvbnRlbnRcclxuICAgKi9cclxuICBhbGVydE1lc3NhZ2U6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogYWxlcnQgbWVzc2FnZSB0eXBlXHJcbiAgICovXHJcbiAgYWxlcnRUeXBlOiBBbGVydDtcclxuXHJcbiAgLyoqXHJcbiAgICogc2VsZWN0ZWQgcG9ydFxyXG4gICAqL1xyXG4gIHBvcnQ6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogYWxsIHRoZSBwb3J0cyBmcm9tIHRoZSBuYW1lc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqL1xyXG4gIHBvcnRzOiBQb3J0W107XHJcblxyXG4gIC8qKlxyXG4gICAqIHNlbGVjdGVkIHRpbWUgcmFuZ2VcclxuICAgKi9cclxuICBkYXRlVGltZVJhbmdlOiBEYXRlW107XHJcblxyXG4gIC8qKlxyXG4gICAqIGRhdGEgc291cmNlIGZvciB0aGUgc2VsZWN0aW9uIHRhYmxlIChyaWdodCBwYXJ0IG9mIHRoZSBjaGFydClcclxuICAgKi9cclxuICB0YWJsZVNvdXJjZTogYW55W107XHJcblxyXG4gIC8qKlxyXG4gICAqIHRoZSBwcm9ncmVzcyBmb3IgcmVhZGluZyBmaWxlXHJcbiAgICovXHJcbiAgcmVhZFByb2dyZXNzID0gMDtcclxuXHJcbiAgLyoqXHJcbiAgICogc2VsZWN0ZWQvZHJvcHBlZCBmaWxlIG5hbWUgKGFiYnJldmlhdGlvbiksIGZ1bGwgZmlsZSBuYW1lIHdpbGwgYmUgc2hvd24gdmlhIHRoZSB0b29sdGlwc1xyXG4gICAqL1xyXG4gIGFiYnJldmlhdGVkRmlsZU5hbWUgPSAnb3IgRHJvcCBGaWxlIEhlcmUnO1xyXG5cclxuICAvKipcclxuICAgKiBmb3IgdGhlIGluc3RydWN0aW9uIHN0ZXAgNFxyXG4gICAqL1xyXG4gIHN0ZXBTaG93Q2hhcnQgPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogY29udHJvbCBmbGFnIGZvciBzaG93aW5nIHRoZSBuYW1lIHNlcnZlciBoaXN0b3J5IGNoYXJ0XHJcbiAgICovXHJcbiAgc2hvd0NoYXJ0RmxhZzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogY29udHJvbCBmbGFnIGZvciBzaG93aW5nIHRoZSBmaWxlIHJlYWRpbmcgcHJvZ3Jlc3NcclxuICAgKi9cclxuICBzaG93UmVhZEZpbGVQcm9ncmVzczogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogY29udHJvbCBmbGFnIGZvciBcIkxvYWRcIiBwb3J0cyBidXR0b25cclxuICAgKi9cclxuICBlbmFibGVMb2FkUG9ydHNCdXR0b246IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIGNvbnRyb2wgZmxhZyBmb3IgZW5hYmxpbmcgXCJTaG93XCIgY2hhcnQgYnV0dG9uXHJcbiAgICovXHJcbiAgZW5hYmxlU2hvd0NoYXJ0QnV0dG9uOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBjb250cm9sIGZsYWcgZm9yIFwiUmVzZXRcIiBjaGFydCBidXR0b25cclxuICAgKi9cclxuICBlbmFibGVSZXNldENoYXJ0QnV0dG9uOiBib29sZWFuO1xyXG5cclxuICBzZWFyY2hUeXBlID0gU2VhcmNoVHlwZS5zZWFyY2hBbGw7XHJcblxyXG4gIC8qKlxyXG4gICAqIHNlbGVjdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhlIHNlbGVjdGlvbiB0YWJsZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3NlbGVjdGlvbjogU2VsZWN0aW9uTW9kZWw8YW55PjtcclxuXHJcbiAgLyoqXHJcbiAgICogY3VycmVudCBkaXNwbGF5aW5nIHBvcnRcclxuICAgKi9cclxuICBwcml2YXRlIF9jdXJyZW50Q2hhcnRQb3J0OiBzdHJpbmc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmlsZVNlcnZpY2U6IEZpbGVTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgY2hhcnRTZXJ2aWNlOiBDaGFydFNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSB1aVNlcnZpY2U6IFVJU2VydmljZSkge31cclxuXHJcbiAgYXN5bmMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgY29uc3QgZmJjID0gY2hhbmdlcy5maWxlQnVmZmVyO1xyXG4gICAgLy8gIWlzRmlsZShmYmMuY3VycmVudFZhbHVlKSAtLT4gb25seSBzaG93IGNoYXJ0IHdoZW4gaXQncyBub3QgYSBmaWxlIC0+IGl0J3MgYSBmaWxlLCBtZWFucyB0aGUgb2JqZWN0IGhhcyBhbHJlYWR5IGJlZW4gcHJvY2Vzc2VkXHJcbiAgICBpZiAoZmJjICYmIGZiYy5jdXJyZW50VmFsdWUgJiYgZmJjLmN1cnJlbnRWYWx1ZSAhPT0gZmJjLnByZXZpb3VzVmFsdWUgJiYgIWlzRmlsZShmYmMuY3VycmVudFZhbHVlKSkge1xyXG4gICAgICAvLyBzaW11bGF0ZSBzZWxlY3RpbmcgZmlsZVxyXG4gICAgICBjb25zdCBzaW11bGF0ZWRFdmVudCA9IHt0YXJnZXQ6IHtmaWxlczogW2Jsb2JUb0ZpbGUoZmJjLmN1cnJlbnRWYWx1ZSwgdGhpcy5zdHJlYW1Nb2RlRmlsZU5hbWUpXX19O1xyXG4gICAgICBhd2FpdCB0aGlzLmZpbGVTZWxlY3RlZChzaW11bGF0ZWRFdmVudCk7XHJcbiAgICAgIHRoaXMucG9ydCA9IHVuZGVmaW5lZDsgLy8gY2xlYXIgdGhlIHBvcnQgc2VsZWN0aW9uXHJcbiAgICAgIGlmICh0aGlzLmF1dG9EaXNwbGF5KSB7XHJcbiAgICAgICAgdGhpcy5vblJlc2l6ZSgpOyAvLyBuZ0FmdGVyVmlld0luaXQvcmVzaXplIHdvbid0IHdvcmsgaW4gZWxlY3Ryb25cclxuICAgICAgICB0aGlzLnNob3dDaGFydCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAvLyBpbml0IGl0ZW1zJyBzdGF0dXNcclxuICAgIC8vIHJlc2V0IGNoYXJ0IGJ1dHRvbiB3aWxsIGJlIGRpc2FibGUgYnkgZGVmYXVsdCBsYXRlciwgb25seSBiZSBlbmFibGVkIGFmdGVyIHpvb21lZFxyXG4gICAgdGhpcy5fdG9nZ2xlSXRlbXMoW1xyXG4gICAgICB7aWQ6IEh0bWxFbGVtZW50LmNoYXJ0QXJlYSwgc3RhdHVzOiBmYWxzZX0sXHJcbiAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiBmYWxzZX0sXHJcbiAgICAgIHtpZDogSHRtbEVsZW1lbnQuc2hvd0NoYXJ0QnV0dG9uLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5sb2FkUG9ydHNCdXR0b24sIHN0YXR1czogdHJ1ZX0sXHJcbiAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVzZXRDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX1dKTtcclxuICAgIHRoaXMub25SZXNpemUoKTsgLy8gdXBkYXRlIHRoZSBzaXplLCBvdGhlcndpc2UgdGhlcmUgbWF5IGhhdmUgYSBzY3JvbGxiYXIgKGJlY2F1c2Ugb2YgdGhlIHRvYXN0KSBpZiBhdXRvIGRpc3BsYXkgaXMgc2V0IHRvIHRydWVcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc2V0IENoYXJ0IHRvIGluaXRpYWwgc3RhdHVzXHJcbiAgICogSWYgbGVnZW5kIGlzIGFscmVhZHkgc2VsZWN0ZWQvdW5zZWxlY3RlZCBmcm9tIHRoZSBsaXN0LCBpdCB3b3VsZG4ndCBiZSByZXN0b3JlZC5cclxuICAgKi9cclxuICByZXNldENoYXJ0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5fdG9nZ2xlSXRlbXMoW3tpZDogSHRtbEVsZW1lbnQucmVzZXRDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX1dKTtcclxuXHJcbiAgICBpZiAodGhpcy50YWJsZVNvdXJjZSAmJiB0aGlzLl9zZWxlY3Rpb24pIHtcclxuICAgICAgdGhpcy5jaGFydFNlcnZpY2UucmVzZXRDaGFydCh0aGlzLnRhYmxlU291cmNlLCB0aGlzLl9zZWxlY3Rpb24pXHJcbiAgICAgICAgLmNhdGNoKGUgPT4gdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuZXJyb3IsIGUpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHJlYWQgdGhlIGZpbGUgYW5kIGRpc3BsYXkgdGhlIGNoYXJ0XHJcbiAgICovXHJcbiAgc2hvd0NoYXJ0KCk6IHZvaWQge1xyXG4gICAgLy8gYWZ0ZXIgY2xpY2ssIHRoaXMgYnV0dG9uIGFuZCByZXNldCBidXR0b24gbmVlZHMgdG8gYmUgZGlzYWJsZWRcclxuICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFtcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uLCBzdGF0dXM6IGZhbHNlfSxcclxuICAgICAge2lkOiBIdG1sRWxlbWVudC5zaG93Q2hhcnRCdXR0b24sIHN0YXR1czogZmFsc2V9XSk7XHJcblxyXG4gICAgdGhpcy5zdGVwU2hvd0NoYXJ0ID0gdHJ1ZTtcclxuXHJcbiAgICB0aGlzLl9pbml0Q2hhcnRFbnYoKS50aGVuKCgpID0+IHtcclxuICAgICAgY29uc3Qgc2VsZWN0ZWRUaW1lID0gdGhpcy5fc2VsZWN0ZWRUaW1lUmFuZ2U7XHJcbiAgICAgIGlmIChzZWxlY3RlZFRpbWUuc3RhcnRUaW1lID4gc2VsZWN0ZWRUaW1lLmVuZFRpbWUpIHtcclxuICAgICAgICB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgJ1RpbWUgcmFuZ2UgaXMgbm90IGNvcnJlY3QuJyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmZpbGUpIHtcclxuICAgICAgICAvLyBpdCdzIHRpbWUgZm9yIGRpc3BsYXlpbmcgdGhlIHJlYWRpbmcgcHJvZ3Jlc3MgYmFyXHJcbiAgICAgICAgdGhpcy5fdG9nZ2xlSXRlbXMoW3tpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiB0cnVlfV0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9idWlsZENoYXJ0RnJvbURhdGFGaWxlKHRoaXMuZmlsZSwgc2VsZWN0ZWRUaW1lLnN0YXJ0VGltZSwgc2VsZWN0ZWRUaW1lLmVuZFRpbWUsIHRoaXMucG9ydCk7XHJcbiAgICAgIH1cclxuICAgIH0pLmNhdGNoKGUgPT4ge1xyXG4gICAgICB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgZSk7XHJcbiAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFt7aWQ6IEh0bWxFbGVtZW50LnJlYWRGaWxlUHJvZ3Jlc3MsIHN0YXR1czogZmFsc2V9XSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGxvYWQgYWxsIHBvcnRzIGZyb20gZmlsZVxyXG4gICAqL1xyXG4gIGxvYWRQb3J0cygpOiB2b2lkIHtcclxuICAgIC8vIGRvIGNvbmZpcm1hdGlvbiBhY3Rpb25zXHJcbiAgICBpZiAodGhpcy5maWxlKSB7XHJcbiAgICAgIC8vIGJlZm9yZSBzdGFydCBsb2FkaW5nIHBvcnRzIGZyb20gZmlsZSwgZGlzcGxheSBwcm9ncmVzcyBiYXIgYW5kIGRpc2FibGUgdGhlIHNob3cgY2hhcnQgYnV0dG9uXHJcbiAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFtcclxuICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LnJlYWRGaWxlUHJvZ3Jlc3MsIHN0YXR1czogdHJ1ZX0sXHJcbiAgICAgICAge2lkOiBIdG1sRWxlbWVudC5zaG93Q2hhcnRCdXR0b24sIHN0YXR1czogZmFsc2V9XHJcbiAgICAgIF0pO1xyXG4gICAgICB0aGlzLl9yZWFkUG9ydHNGcm9tRmlsZSh0aGlzLmZpbGUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogc2VsZWN0IG5hbWUgc2VydmVyIGhpc3RvcnkgZmlsZSwgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMgMSBmaWxlLlxyXG4gICAqL1xyXG4gIGFzeW5jIGZpbGVTZWxlY3RlZChldmVudDogYW55KSB7XHJcbiAgICBjb25zdCBzZWxlY3RlZEZpbGUgPSBnZXRGaWxlRnJvbUlucHV0KGV2ZW50LnRhcmdldCk7XHJcbiAgICBpZiAoc2VsZWN0ZWRGaWxlKSB7XHJcbiAgICAgIGlmICghaXNTYW1lRmlsZSh0aGlzLmZpbGUsIHNlbGVjdGVkRmlsZSkpIHtcclxuICAgICAgICAvLyBpbml0IHBvcnQgc2VsZWN0b3JcclxuICAgICAgICBhd2FpdCB0aGlzLl9pbml0UG9ydFNlbGVjdG9yKCkuY2F0Y2goZSA9PiB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgZSkpO1xyXG5cclxuICAgICAgICB0aGlzLmZpbGUgPSBzZWxlY3RlZEZpbGU7XHJcbiAgICAgICAgdGhpcy5hYmJyZXZpYXRlZEZpbGVOYW1lID0gZ2V0QWJicmV2aWF0ZWRGaWxlTmFtZSh0aGlzLmZpbGUubmFtZSk7XHJcbiAgICAgICAgLy8gYWZ0ZXIgZmlsZSBoYXMgYmVlbiBzZWxlY3RlZCwgdGhlIHNob3cgY2hhcnQgYnV0dG9uIG5lZWRzIHRvIGJlIGVuYWJsZWRcclxuICAgICAgICB0aGlzLl90b2dnbGVJdGVtcyhbe2lkOiBIdG1sRWxlbWVudC5zaG93Q2hhcnRCdXR0b24sIHN0YXR1czogdHJ1ZX1dKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZHJvcCBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGUsIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIDEgZmlsZS5cclxuICAgKi9cclxuICBmaWxlRHJvcHBlZChldmVudDogYW55KSB7XHJcbiAgICBnZXRGaWxlRnJvbURyb3AoZXZlbnQpXHJcbiAgICAgIC50aGVuKGZpbGUgPT4ge1xyXG4gICAgICAgIGlmICghaXNTYW1lRmlsZSh0aGlzLmZpbGUsIGZpbGUpKSB7XHJcbiAgICAgICAgICAvLyBpbml0IHBvcnQgc2VsZWN0b3JcclxuICAgICAgICAgIHRoaXMuZmlsZSA9IGZpbGU7XHJcbiAgICAgICAgICBpZiAodGhpcy5maWxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWJicmV2aWF0ZWRGaWxlTmFtZSA9IGdldEFiYnJldmlhdGVkRmlsZU5hbWUodGhpcy5maWxlLm5hbWUpO1xyXG4gICAgICAgICAgICAvLyBhZnRlciBmaWxlIGhhcyBiZWVuIGRyb3BwZWQsIHRoZSBzaG93IGNoYXJ0IGJ1dHRvbiBuZWVkcyB0byBiZSBlbmFibGVkXHJcbiAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFt7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiB0cnVlfV0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH19KVxyXG4gICAgICAudGhlbigoKSA9PiAge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pbml0UG9ydFNlbGVjdG9yKCk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlID0+IHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCBlKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZWxlY3Qgb25lIGl0ZW0gZnJvbSBzZWxlY3Rpb24gdGFibGUsIHJlbGF0aXZlIGRhdGFzZXQgd2lsbCBiZSBzaG93biBvciBoaWRkZW5cclxuICAgKi9cclxuICBzZWxlY3RJdGVtKGV2ZW50OiBhbnkpIHtcclxuICAgIGlmIChldmVudCAmJiBldmVudC50YWJsZVJvdykge1xyXG4gICAgICBjb25zdCByb3cgPSBldmVudC50YWJsZVJvdztcclxuICAgICAgdGhpcy5fc2VsZWN0aW9uLnRvZ2dsZShyb3cpO1xyXG4gICAgICB0aGlzLmNoYXJ0U2VydmljZS50b2dnbGVEYXRhSW5DaGFydChyb3cuS1BJLCAhdGhpcy5fc2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KSlcclxuICAgICAgICAuY2F0Y2goZSA9PiB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5lcnJvciwgZSkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmVjYWxjdWxhdGluZyBjaGFydCBoZWlnaHQgd2hlbiByZXNpemluZ1xyXG4gICAqL1xyXG4gIG9uUmVzaXplKCkge1xyXG4gICAgY29uc3QgbmFtZXNlcnZlckhpc3RvcnlBbGxFbGVtZW50ID0gdGhpcy5uYW1lc2VydmVySGlzdG9yeUFsbFJlZiA/IHRoaXMubmFtZXNlcnZlckhpc3RvcnlBbGxSZWYubmF0aXZlRWxlbWVudCA6IG51bGw7XHJcbiAgICBjb25zdCBuYW1lc2VydmVySGlzdG9yeUNvbnRlbnRFbGVtZW50ID0gdGhpcy5uYW1lc2VydmVySGlzdG9yeUNvbnRlbnRSZWYgPyB0aGlzLm5hbWVzZXJ2ZXJIaXN0b3J5Q29udGVudFJlZi5uYXRpdmVFbGVtZW50IDogbnVsbDtcclxuICAgIHNldENoYXJ0SGVpZ2h0KG5hbWVzZXJ2ZXJIaXN0b3J5QWxsRWxlbWVudCwgbmFtZXNlcnZlckhpc3RvcnlDb250ZW50RWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTd2l0Y2ggcG9ydCBhbmQgcmVpbml0aWFsaXplIGNoYXJ0LCB0cmlnZ2VyZWQgYnkgY2hhbmdpbmcgdGhlIHBvcnRcclxuICAgKiBAcGFyYW0gcG9ydCB0aGUgc2VsZWN0ZWQgcG9ydFxyXG4gICAqL1xyXG4gIHN3aXRjaFBvcnRGb3JDaGFydChwb3J0OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmIChwb3J0ID09PSB0aGlzLl9jdXJyZW50Q2hhcnRQb3J0KSB7XHJcbiAgICAgIC8vIG5vdCB0byBzd2l0Y2ggcG9ydCwgYmVjYXVzZSB0aGUgcmVsYXRpdmUgcG9ydCBpcyBkaXNwbGF5aW5nLCBubyBuZWVkIHRvIHJlbmRlciB0d2ljZS5cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKCF0aGlzLmZpbGUgfHwgIXBvcnQgfHwgcG9ydC5sZW5ndGggPT09IDAgfHwgcG9ydC5zbGljZSgxLCAzKSA9PT0gJyoqJykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKHRoaXMudGltZSkubGVuZ3RoID4gMSAmJiAhZ2V0UmVhbFBvcnRzKE9iamVjdC5rZXlzKHRoaXMudGltZSkuZmlsdGVyKGtleSA9PiB0aGlzLnRpbWVba2V5XSkpLmluY2x1ZGVzKHBvcnQpKSB7XHJcbiAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmluZm8sIGBEYXRhIG9mIHBvcnQ6JHtwb3J0fSBpcyBub3QgbG9hZGVkLCBwbGVhc2UgbG9hZCB0aGUgZGF0YSBmaXJzdCBieSBjbGlja2luZyB0aGUgXCJTaG93XCIgYnV0dG9uLmApO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gb25seSBkbyBzd2l0Y2ggcG9ydHMgd2hlbiBhdmFpbGFibGUgcG9ydHMgbnVtYmVyID4gMVxyXG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMudGltZSkuZmlsdGVyKGtleSA9PiB0aGlzLnRpbWVba2V5XSkubGVuZ3RoID4gMSkge1xyXG4gICAgICAvLyBkaXNhYmxlIHRoZSBcInNob3cgY2hhcnRcIiBhbmQgXCJyZXNldCBjaGFydFwiIGJ1dHRvbiBmaXJzdFxyXG4gICAgICB0aGlzLl90b2dnbGVJdGVtcyhbXHJcbiAgICAgICAge2lkOiBIdG1sRWxlbWVudC5zaG93Q2hhcnRCdXR0b24sIHN0YXR1czogZmFsc2V9LFxyXG4gICAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVzZXRDaGFydEJ1dHRvbiwgc3RhdHVzOiBmYWxzZX1dKTtcclxuICAgICAgLy8gaW5pdCB0aGUgZW52aXJvbm1lbnQgd2l0aCBzd2l0Y2ggZmxhZ1xyXG4gICAgICB0aGlzLl9pbml0Q2hhcnRFbnYodHJ1ZSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1aWxkQ2hhcnQocG9ydCwgbnVsbCwgdHJ1ZSk7XHJcbiAgICAgIH0pLmNhdGNoKGUgPT4gdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuZXJyb3IsIGUpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCB0aGUgY29sdW1ucyB3aGljaCBuZWVkIHRvIGJlIGhpZGRlbiBmcm9tIHRoZSBzZWxlY3Rpb24gdGFibGVcclxuICAgKi9cclxuICBnZXQgaGlkZGVuQ29sdW1ucygpOiBzdHJpbmdbXSB7XHJcbiAgICByZXR1cm4gdGhpcy51aVNlcnZpY2UuZ2V0SGlkZGVuQ29sdW1ucyh0aGlzLmhpZGVNZWFzdXJlQ29sdW1ucyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgZGVmYXVsdCB0aW1lem9uZVxyXG4gICAqL1xyXG4gIGdldCBkZWZhdWx0VGltZXpvbmUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBnZXREZWZhdWx0VGltZXpvbmUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCB0aGUga2V5IGNvbHVtbiAoS1BJKVxyXG4gICAqL1xyXG4gIGdldCBrcGlDb2x1bW4oKTogSXRlbSB7XHJcbiAgICByZXR1cm4gSXRlbS5rcGk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgdGhlIGtleSBjb2x1bW4gKEtQSSlcclxuICAgKi9cclxuICBnZXQgZGVzY0NvbHVtbigpOiBJdGVtIHtcclxuICAgIHJldHVybiBJdGVtLmRlc2NyaXB0aW9uO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IHRoZSBzZWxlY3RlZCB0aW1lIHJhbmdlLCBzZXQgc2Vjb25kIGFuZCBtaWxsaXNlY29uZCBwYXJ0IHRvIDBcclxuICAgKi9cclxuICBwcml2YXRlIGdldCBfc2VsZWN0ZWRUaW1lUmFuZ2UoKToge3N0YXJ0VGltZTogbnVtYmVyLCBlbmRUaW1lOiBudW1iZXJ9IHtcclxuICAgIGxldCBzdGFydFRpbWUgPSAwO1xyXG4gICAgbGV0IGVuZFRpbWUgPSA0MTAyMzU4NDAwMDAwOyAvLyAyMDk5LzEyLzMxXHJcbiAgICBpZiAodGhpcy5kYXRlVGltZVJhbmdlICE9IG51bGwpIHtcclxuICAgICAgaWYgKHRoaXMuZGF0ZVRpbWVSYW5nZS5sZW5ndGggPj0gMSkge1xyXG4gICAgICAgIC8vIGdldCBzdGFydCB0aW1lXHJcbiAgICAgICAgaWYgKHRoaXMuZGF0ZVRpbWVSYW5nZVswXSkge1xyXG4gICAgICAgICAgc3RhcnRUaW1lID0gdGhpcy5kYXRlVGltZVJhbmdlWzBdLnNldFNlY29uZHMoMCwgMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmRhdGVUaW1lUmFuZ2VbMV0pIHtcclxuICAgICAgICAgIGVuZFRpbWUgPSB0aGlzLmRhdGVUaW1lUmFuZ2VbMV0uc2V0U2Vjb25kcygwLCAwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB7c3RhcnRUaW1lOiBzdGFydFRpbWUsIGVuZFRpbWU6IGVuZFRpbWV9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IHRoZSB0aW1lIHJhbmdlIHN0cmluZywgZWc6IDIwMTgtMTAtMjUgMTA6MjUgfiAyMDE4LTEwLTI2IDEwOjI2XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXQgX3NlbGVjdGVkVGltZVJhbmdlU3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBzZWxlY3RlZFRpbWVSYW5nZVN0cmluZyA9IHRoaXMuX3NlbGVjdGVkVGltZVJhbmdlO1xyXG4gICAgcmV0dXJuIGAke2dldFRpbWVTdHJpbmcoc2VsZWN0ZWRUaW1lUmFuZ2VTdHJpbmcuc3RhcnRUaW1lKX0gfiAke2dldFRpbWVTdHJpbmcoc2VsZWN0ZWRUaW1lUmFuZ2VTdHJpbmcuZW5kVGltZSl9YDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCBhcnJheSBvZiBoZWFkZXIga2V5XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXQgX2hlYWRlcktleSgpOiBzdHJpbmdbXSB7XHJcbiAgICBpZiAodGhpcy5oZWFkZXIpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaGVhZGVyLm1hcChoZWFkZXJJdGVtID0+IGhlYWRlckl0ZW0ua2V5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCBhcnJheSBvZiBoZWFkZXIgdGV4dFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0IF9oZWFkZXJUZXh0KCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiB0aGlzLmhlYWRlci5tYXAoaGVhZGVySXRlbSA9PiBoZWFkZXJJdGVtLnRleHQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmVhZCBwb3J0cyBmcm9tIHRoZSBzZWxlY3RlZCBuYW1lc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqIEBwYXJhbSBmaWxlIG5hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfcmVhZFBvcnRzRnJvbUZpbGUoZmlsZTogRmlsZSk6IHZvaWQge1xyXG4gICAgdGhpcy5maWxlU2VydmljZS5nZXRQb3J0c0Zyb21GaWxlKGZpbGUsIChwcm9ncmVzcykgPT4ge1xyXG4gICAgICB0aGlzLnJlYWRQcm9ncmVzcyA9IHByb2dyZXNzO1xyXG4gICAgfSkudGhlbihwb3J0cyA9PiB7XHJcbiAgICAgIHJldHVybiBzbGVlcCgxMDApLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pbml0UG9ydFNlbGVjdG9yKHBvcnRzKTtcclxuICAgICAgfSk7XHJcbiAgICB9KS5jYXRjaChlID0+IHRoaXMuX3Nob3dNZXNzYWdlKEFsZXJ0LmVycm9yLCBlKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBidWlsZCBjaGFydCBmcm9tIHRoZSBzZWxlY3RlZCBuYW1lc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqIEBwYXJhbSBmaWxlIHRoZSBuYW1lc2VydmVyIGhpc3RvcnkgZmlsZVxyXG4gICAqIEBwYXJhbSBzdGFydFRpbWUgc3RhcnQgdGltZVxyXG4gICAqIEBwYXJhbSBlbmRUaW1lIGVuZCB0aW1lXHJcbiAgICogQHBhcmFtIHNlbGVjdGVkUG9ydCBzZWxlY3RlZCBwb3J0IGZvciBuYW1lc2VydmVyIGhpc3RvcnkgZmlsZSAoTURDIHN5c3RlbSlcclxuICAgKi9cclxuICBwcml2YXRlIF9idWlsZENoYXJ0RnJvbURhdGFGaWxlKGZpbGU6IEZpbGUsIHN0YXJ0VGltZTogbnVtYmVyLCBlbmRUaW1lOiBudW1iZXIsIHNlbGVjdGVkUG9ydDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVTZXJ2aWNlLmdldENoYXJ0Q29udGVudEZyb21GaWxlKFxyXG4gICAgICBmaWxlLFxyXG4gICAgICBzdGFydFRpbWUsXHJcbiAgICAgIGVuZFRpbWUsXHJcbiAgICAgIHNlbGVjdGVkUG9ydCxcclxuICAgICAgdGhpcy50aW1lem9uZSxcclxuICAgICAgdGhpcy5tYXhSb3dzTGltaXRhdGlvbiwgcHJvZ3Jlc3MgPT4gdGhpcy5yZWFkUHJvZ3Jlc3MgPSBwcm9ncmVzcylcclxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICAvLyBwYXJzaW5nIGRvbmVcclxuICAgICAgICBjb25zdCBiZWdpblRpbWUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XHJcbiAgICAgICAgY29uc3QgcG9ydHMgPSBnZXRSZWFsUG9ydHMoT2JqZWN0LmtleXMocmVzdWx0LnRpbWUpLCB0cnVlKTtcclxuICAgICAgICBwb3J0cy5mb3JFYWNoKHBvcnQgPT4ge1xyXG4gICAgICAgICAgLy8gY29udmVydCB0aGUgdW5pdCBhbmQgZ2VuZXJhdGUgY29udHJvbGxpbmcgZGF0YSBmb3IgYWxsIHBvcnRzXHJcbiAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMudWlTZXJ2aWNlLmNvbnZlcnRVbml0QW5kR2VuZXJhdGVDb250cm9sRGF0YShyZXN1bHQuZGF0YVtwb3J0XSwgcmVzdWx0LmhlYWRlciwgcG9ydCkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpXHJcbiAgICAgICAgICAudGhlbigoKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAvLyBnZXQgYWxsIHBvcnRzIGZyb20gdGhlIGFuYWx5emVkIGRhdGEodGltZSlcclxuICAgICAgICAgICAgLy8gZ2V0IHRoZSBwb3J0IHRoYXQgd2lsbCBiZSBzaG93biBpbiB0aGUgcGFnZVxyXG4gICAgICAgICAgICBjb25zdCBwb3J0ID0gZ2V0RGlzcGxheVBvcnQocG9ydHMsIHNlbGVjdGVkUG9ydCk7XHJcblxyXG4gICAgICAgICAgICBwcmludFByb2Nlc3NlZFRpbWUoYmVnaW5UaW1lLCAnY29udmVydGluZyBzdGVwJyk7XHJcbiAgICAgICAgICAgIHBvcnRzLmZvckVhY2goIHBvcnRJdGVtID0+IHRoaXMudWlTZXJ2aWNlLmdlbmVyYXRlWVNjYWxlKHBvcnRJdGVtKSk7XHJcbiAgICAgICAgICAgIHByaW50UHJvY2Vzc2VkVGltZShiZWdpblRpbWUsICdnZW5lcmF0aW5nIFlTY2FsZSBzdGVwJyk7XHJcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IHJlc3VsdC5kYXRhO1xyXG4gICAgICAgICAgICB0aGlzLnRpbWUgPSByZXN1bHQudGltZTtcclxuICAgICAgICAgICAgdGhpcy5oZWFkZXIgPSB0aGlzLnVpU2VydmljZS5nZXRIZWFkZXIocmVzdWx0LmhlYWRlciwgcG9ydCk7XHJcbiAgICAgICAgICAgIHRoaXMuaG9zdCA9IHJlc3VsdC5ob3N0O1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0LmFib3J0ZWQgPT09IEFib3J0Lm1heExpbmVOdW1SZWFjaGVkKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoXHJcbiAgICAgICAgICAgICAgICBBbGVydC53YXJuaW5nLCBgTWF4aW11bSBudW1iZXIgb2YgbGluZXMgcmVhY2hlZC4gUHJvY2Vzc2VkIHRpbWUgcmFuZ2UgaXM6ICR7Z2V0VGltZVJhbmdlU3RyaW5nKHRoaXMudGltZSl9LmApO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGlmIChpc0VtcHR5RGF0YSh0aGlzLmRhdGEpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaG93TWVzc2FnZShBbGVydC5pbmZvLCBgQ2Fubm90IGZpbmQgYW55IGRhdGEgZm9yIHRoZSBzZWxlY3RlZCB0aW1lIHBlcmlvZDogJHt0aGlzLl9zZWxlY3RlZFRpbWVSYW5nZVN0cmluZ31gKTtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoQWxlcnQuc3VjY2VzcywgYFByb2Nlc3NlZCB0aW1lIHJhbmdlIGlzOiAke2dldFRpbWVSYW5nZVN0cmluZyh0aGlzLnRpbWUpfS5gKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHNsZWVwKDEwMCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1aWxkQ2hhcnQocG9ydCwgcG9ydHMpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHJlaW5pdGlhbGl6ZSB0aGUgcG9ydCBzZWxlY3RvciB3aXRoIHRoZSBwb3J0c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgX2luaXRQb3J0U2VsZWN0b3IocG9ydHM6IHN0cmluZ1tdID0gbnVsbCwgc2VsZWN0ZWRQb3J0OiBzdHJpbmcgPSBudWxsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcbiAgICAgIC8vIGluaXRpYWxpemF0aW9uIGZvciBuZ3gtc2VsZWN0XHJcbiAgICAgIGlmIChwb3J0cyAhPSBudWxsICYmIHBvcnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAvLyBNREMsIHJlbW92ZSBkZWZhdWx0ICcwMDAwJyBwb3J0XHJcbiAgICAgICAgdGhpcy5wb3J0cyA9IGdlbmVyYXRlUG9ydHMoZ2V0UmVhbFBvcnRzKHBvcnRzKSwgc2VsZWN0ZWRQb3J0KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnBvcnRzID0gZ2VuZXJhdGVQb3J0cyhwb3J0cyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChwb3J0cyAhPSBudWxsICYmIHNlbGVjdGVkUG9ydCA9PT0gbnVsbCkge1xyXG4gICAgICAgIC8vIHJlc2V0IHN0YXR1cyB3aGVuIGRvaW5nOlxyXG4gICAgICAgIC8vIDEuIGxvYWRpbmcgcG9ydHNcclxuICAgICAgICAvLyAyLiB0aGUgZmlsZSBkb2Vzbid0IGNvbnRhaW4gdGhlIHNlbGVjdGVkIFBvcnRcclxuICAgICAgICB0aGlzLnJlYWRQcm9ncmVzcyA9IDA7XHJcbiAgICAgICAgLy8gaGlkZSB0aGUgcHJvZ3Jlc3MgYmFyIGFuZCBlbmFibGUgdGhlIFwic2hvdyBjaGFydFwiIGJ1dHRvblxyXG4gICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFtcclxuICAgICAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiBmYWxzZX0sXHJcbiAgICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiB0cnVlfVxyXG4gICAgICAgIF0pO1xyXG4gICAgICB9XHJcbiAgICAgIHJlc29sdmUoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogYnVpbGQgYW5kIGRpc3BsYXkgdGhlIGNoYXJ0IG9uIHBhZ2VcclxuICAgKiBAcGFyYW0gcG9ydCB0aGUgc2VsZWN0ZWQgcG9ydFxyXG4gICAqIEBwYXJhbSBwb3J0cyBhbGwgYXZhaWxhYmxlIHBvcnRzXHJcbiAgICogQHBhcmFtIHN3aXRjaEZsYWcgaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBmdW5jdGlvbiBpcyB0cmlnZ2VyZWQgZnJvbSBzd2l0Y2hpbmcgcG9ydHMgKG5vIGluaXQgcG9ydCBzZWxlY3RvciBuZWVkZWQpXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfYnVpbGRDaGFydChwb3J0OiBzdHJpbmcsIHBvcnRzOiBzdHJpbmdbXSwgc3dpdGNoRmxhZyA9IGZhbHNlKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IGJlZ2luVGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBpZiAocG9ydCkge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2xvYWRTZXR0aW5nc0ZvclNlbGVjdGlvbnNUYWJsZShwb3J0KSlcclxuICAgICAgICAudGhlbiggKCkgPT4ge1xyXG4gICAgICAgICAgLy8gZ2V0IHRoZSBjb25maWdcclxuICAgICAgICAgIHJldHVybiB0aGlzLmNoYXJ0U2VydmljZS5idWlsZENoYXJ0KFxyXG4gICAgICAgICAgICB0aGlzLnRpbWVbcG9ydF0sXHJcbiAgICAgICAgICAgIHRoaXMuZGF0YVtwb3J0XSxcclxuICAgICAgICAgICAgdGhpcy51aVNlcnZpY2UuZ2V0WVNjYWxlKHRoaXMuX2hlYWRlcktleSwgcG9ydCksXHJcbiAgICAgICAgICAgIHRoaXMuX2hlYWRlclRleHQsXHJcbiAgICAgICAgICAgIHRoaXMuX2hlYWRlcktleSxcclxuICAgICAgICAgICAgdGhpcy5fc2VsZWN0aW9uLFxyXG4gICAgICAgICAgICB0aGlzLnRhYmxlU291cmNlLFxyXG4gICAgICAgICAgICB0aGlzLl9nZXRIb3N0VGl0bGUocG9ydCksXHJcbiAgICAgICAgICAgIHRoaXMudWlTZXJ2aWNlLmdldERpc3BsYXlJdGVtcyh0aGlzLl9oZWFkZXJLZXksIHBvcnQsIHRoaXMuZGVmYXVsdFNlbGVjdGVkSXRlbXMpLFxyXG4gICAgICAgICAgICB0aGlzLl9vblpvb20uYmluZCh0aGlzKSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMucmVhZFByb2dyZXNzID0gMDtcclxuICAgICAgICAgICAgICAvLyBhZnRlciBjaGFydCBoYXMgYmVlbiBjcmVhdGVkLCBzaG93IHRoZSBjaGFydCBhcmVhLCBoaWRlIHByb2dyZXNzIGJhciBhbmQgZW5hYmxlIHRoZSBcInNob3cgY2hhcnRcIiBidXR0b25cclxuICAgICAgICAgICAgICB0aGlzLl90b2dnbGVJdGVtcyhbXHJcbiAgICAgICAgICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LmNoYXJ0QXJlYSwgc3RhdHVzOiB0cnVlfSxcclxuICAgICAgICAgICAgICAgIHtpZDogSHRtbEVsZW1lbnQucmVhZEZpbGVQcm9ncmVzcywgc3RhdHVzOiBmYWxzZX0sXHJcbiAgICAgICAgICAgICAgICB7aWQ6IEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbiwgc3RhdHVzOiB0cnVlfVxyXG4gICAgICAgICAgICAgIF0pO1xyXG4gICAgICAgICAgICAgIC8vIHNldCBwb3J0IHRvIGN1cnJlbnQgZGlzcGxheWluZyBwb3J0XHJcbiAgICAgICAgICAgICAgdGhpcy5fY3VycmVudENoYXJ0UG9ydCA9IHBvcnQ7XHJcbiAgICAgICAgICAgICAgcHJpbnRQcm9jZXNzZWRUaW1lKGJlZ2luVGltZSwgJ3N0ZXBfYnVpbGRfY2hhcnQnKTtcclxuICAgICAgICAgICAgICBpZiAocG9ydHMgJiYgcG9ydHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzd2l0Y2hGbGFnKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vIGluaXRpYWxpemUgcG9ydCBzZWxlY3Rvci4gRG8gbm90IG5lZWQgdG8gZG8gaXQgd2hlbiBzd2l0Y2hpbmcgcG9ydC5cclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRQb3J0U2VsZWN0b3IocG9ydHMsIHBvcnQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAocG9ydHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKFxyXG4gICAgICAgICAgQWxlcnQud2FybmluZyxcclxuICAgICAgICAgICdUaGUgc2VsZWN0ZWQgcG9ydCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgbmFtZSBzZXJ2ZXIgaGlzdG9yeSBmaWxlLiBQbGVhc2UgY2hvb3NlIGEgY29ycmVjdCBwb3J0IGFuZCBoYXZlIGEgdHJ5IGFnYWluLicpO1xyXG4gICAgICAgIGlmICghc3dpdGNoRmxhZykge1xyXG4gICAgICAgICAgLy8gaW5pdGlhbGl6ZSBwb3J0IHNlbGVjdG9yLiBEbyBub3QgbmVlZCB0byBkbyBpdCB3aGVuIHN3aXRjaGluZyBwb3J0LlxyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRQb3J0U2VsZWN0b3IocG9ydHMsIHBvcnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZ2V0IHRoZSBzdHJpbmcgdGhhdCB3aWxsIGJlIGRpc3BsYXllZCBvbiB0aGUgdGl0bGUgYXJlYSBvZiB0aGUgY2hhcnRcclxuICAgKiBlZzogaG9zdDEgLSAzMDA0MCAoMjAxOC0wOS0wNSAxNTozMjozMiB+IDIwMTgtMDktMDcgMTU6MzI6MTUpXHJcbiAgICogQHBhcmFtIHBvcnQgc2VsZWN0ZWQgcG9ydFxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2dldEhvc3RUaXRsZShwb3J0OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuaG9zdCkge1xyXG4gICAgICByZXR1cm4gIGAke3RoaXMuaG9zdH0gLSAke3BvcnR9ICggJHtnZXRUaW1lUmFuZ2VTdHJpbmcodGhpcy50aW1lW3BvcnRdKX0gKWA7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBhZnRlciB6b29tLCBlbmFibGUgdGhlIHJlc2V0IGJ1dHRvbi5cclxuICAgKi9cclxuICBwcml2YXRlIF9vblpvb20oKTogdm9pZCB7XHJcbiAgICB0aGlzLl90b2dnbGVJdGVtcyhbe2lkOiBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uLCBzdGF0dXM6IHRydWV9XSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBpbml0aWFsaXplIGNoYXJ0LCBpbmNsdWRpbmc6IGRlc3Ryb3kgY3VycmVudCBjaGFydCwgaW5pdGlhbGl6ZSBjb25maWcsIGluaXRpYWxpemUgYWxsIHJlbGF0aXZlIGRhdGFcclxuICAgKi9cclxuICBwcml2YXRlIF9pbml0Q2hhcnRFbnYoc3dpdGNoRmxhZzogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmNoYXJ0U2VydmljZS5kZXN0cm95Q2hhcnQoKS50aGVuKCgpID0+IHtcclxuICAgICAge1xyXG4gICAgICAgIC8vIGNsZWFudXAgb3RoZXIgZGF0YVxyXG4gICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW1zKFt7aWQ6IEh0bWxFbGVtZW50LmNoYXJ0QXJlYSwgc3RhdHVzOiBmYWxzZX1dKTtcclxuXHJcbiAgICAgICAgaWYgKCFzd2l0Y2hGbGFnKSB7XHJcbiAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnRpbWUpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMudGltZVtrZXldKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy50aW1lW2tleV0ubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgfX0pO1xyXG4gICAgICAgICAgdGhpcy50aW1lID0ge307XHJcbiAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YVtrZXldKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5kYXRhW2tleV0ubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgfX0pO1xyXG4gICAgICAgICAgdGhpcy5kYXRhID0ge307XHJcbiAgICAgICAgICB0aGlzLmhlYWRlci5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgdGhpcy5ob3N0ID0gJ25hbWVzZXJ2ZXIgaGlzdG9yeSBmaWxlJztcclxuICAgICAgICAgIHRoaXMudGFibGVTb3VyY2UgPSB2b2lkIDA7XHJcbiAgICAgICAgICB0aGlzLnJlYWRQcm9ncmVzcyA9IDA7XHJcbiAgICAgICAgICB0aGlzLnVpU2VydmljZS5jbGVhckxvYWRIaXN0b3J5SW5mb3MoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBzZXR0aW5ncyBmb3IgdGhlIHNlbGVjdGlvbiB0YWJsZSAodGhlIHJpZ2h0IHBhcnQgb2YgdGhlIGNoYXJ0KVxyXG4gICAqIEBwYXJhbSBwb3J0IHRoZSBzZWxlY3RlZCBwb3J0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfbG9hZFNldHRpbmdzRm9yU2VsZWN0aW9uc1RhYmxlKHBvcnQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50YWJsZVNvdXJjZSA9IHRoaXMudWlTZXJ2aWNlLmdldFNlbGVjdGlvblRhYmxlUm93cyh0aGlzLl9oZWFkZXJLZXksIHBvcnQsIHRoaXMuZGVmYXVsdFNlbGVjdGVkSXRlbXMpO1xyXG4gICAgdGhpcy5fc2VsZWN0aW9uID0gbmV3IFNlbGVjdGlvbk1vZGVsKHRydWUsIFtdKTtcclxuICAgIHRoaXMudGFibGVTb3VyY2UuZm9yRWFjaChyb3cgPT4ge1xyXG4gICAgICBpZiAodGhpcy51aVNlcnZpY2UuZ2V0RGlzcGxheUl0ZW1zKHRoaXMuX2hlYWRlcktleSwgcG9ydCwgdGhpcy5kZWZhdWx0U2VsZWN0ZWRJdGVtcykuaW5jbHVkZXMocm93LktQSSkpIHtcclxuICAgICAgICB0aGlzLl9zZWxlY3Rpb24uc2VsZWN0KHJvdyk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2hvdyBtZXNzYWdlc1xyXG4gICAqIEBwYXJhbSB0eXBlIHR5cGUgb2YgdGhlIG1lc3NhZ2VcclxuICAgKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIHRleHRcclxuICAgKi9cclxuICBwcml2YXRlIF9zaG93TWVzc2FnZSh0eXBlOiBBbGVydCwgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAodHlwZSkge1xyXG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgICAgICBjYXNlIEFsZXJ0LnN1Y2Nlc3M6XHJcbiAgICAgICAgY2FzZSBBbGVydC5pbmZvOlxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBBbGVydC53YXJuaW5nOlxyXG4gICAgICAgICAgY29uc29sZS53YXJuKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBBbGVydC5lcnJvcjpcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0aGlzLmFsZXJ0TWVzc2FnZSA9PT0gbWVzc2FnZSkge1xyXG4gICAgICAvLyB0cnkgdHJpZ2dlciB0aGUgY2hhbmdlIGV2ZW50IG9mIHRoZSBhbGVydC5cclxuICAgICAgdGhpcy5hbGVydE1lc3NhZ2UgPSB2b2lkIDA7XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5hbGVydE1lc3NhZ2UgPSBtZXNzYWdlLCAxMDApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5hbGVydE1lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hbGVydFR5cGUgPSB0eXBlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogdG9nZ2xlIGl0ZW1zIHdpdGggdGhlIHByb3ZpZGVkIHN0YXR1cyAoc2hvdyBvciBoaWRlIHRoZSByZWxhdGl2ZSBlbGVtZW50IG9uIHRoZSBwYWdlKVxyXG4gICAqIEBwYXJhbSBpdGVtcyBpdGVtcyB3aXRoIHRoZSByZWxhdGl2ZSBpZCBhbmQgc3RhdHVzLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3RvZ2dsZUl0ZW1zKGl0ZW1zOiB7aWQ6IEh0bWxFbGVtZW50LCBzdGF0dXM6IGJvb2xlYW59W10pIHtcclxuICAgIGNvbnN0IGdldFZhcmlhYmxlTmFtZUJ5VHlwZUlkID0gKGlkOiBIdG1sRWxlbWVudCkgPT4ge1xyXG4gICAgICBzd2l0Y2ggKGlkKSB7XHJcbiAgICAgICAgY2FzZSBIdG1sRWxlbWVudC5jaGFydEFyZWE6IHJldHVybiAnc2hvd0NoYXJ0RmxhZyc7XHJcbiAgICAgICAgY2FzZSBIdG1sRWxlbWVudC5yZWFkRmlsZVByb2dyZXNzOiByZXR1cm4gJ3Nob3dSZWFkRmlsZVByb2dyZXNzJztcclxuICAgICAgICBjYXNlIEh0bWxFbGVtZW50LnNob3dDaGFydEJ1dHRvbjogcmV0dXJuICdlbmFibGVTaG93Q2hhcnRCdXR0b24nO1xyXG4gICAgICAgIGNhc2UgSHRtbEVsZW1lbnQubG9hZFBvcnRzQnV0dG9uOiByZXR1cm4gJ2VuYWJsZUxvYWRQb3J0c0J1dHRvbic7XHJcbiAgICAgICAgY2FzZSBIdG1sRWxlbWVudC5yZXNldENoYXJ0QnV0dG9uOiByZXR1cm4gJ2VuYWJsZVJlc2V0Q2hhcnRCdXR0b24nO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgaWYgKGl0ZW1zKSB7XHJcbiAgICAgIGl0ZW1zLmZvckVhY2goaXRlbSA9PiB7XHJcbiAgICAgICAgdGhpc1tnZXRWYXJpYWJsZU5hbWVCeVR5cGVJZChpdGVtLmlkKV0gPSBpdGVtLnN0YXR1cztcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgI25hbWVzZXJ2ZXJIaXN0b3J5QWxsIGNsYXNzPVwibmFtZXNlcnZlci1oaXN0b3J5LWFsbFwiICh3aW5kb3c6cmVzaXplKT1cIm9uUmVzaXplKClcIj5cclxuICA8ZGl2IGNsYXNzPVwidG9vbGJhci1jaGFydFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cInVwbG9hZC1ib3gtY29udGVudFwiPlxyXG4gICAgICA8ZGl2ICpuZ0lmPVwiIXNob3dSZWFkRmlsZVByb2dyZXNzXCI+XHJcbiAgICAgICAgPGZpbGUtZHJvcC1pbnB1dCAoZmlsZURyb3ApPVwiZmlsZURyb3BwZWQoJGV2ZW50KVwiIChmaWxlSW5wdXQpPVwiZmlsZVNlbGVjdGVkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2Ryb3BBcmVhVGV4dF09IFwiYWJicmV2aWF0ZWRGaWxlTmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbaW5wdXRBcmVhVGV4dF09XCInQnJvd3NlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiZmlsZT8ubmFtZT8gZmlsZS5uYW1lOidTZWxlY3QgYSBuYW1lIHNlcnZlciBoaXN0b3J5IGZpbGUgZnJvbSB5b3VyIGxvY2FsIGRpc2suJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmaWxlQnVmZmVyXCI+XHJcbiAgICAgICAgPC9maWxlLWRyb3AtaW5wdXQ+XHJcbiAgICAgICAgPHAgKm5nSWY9XCJmaWxlQnVmZmVyXCIgY2xhc3M9XCJib3gtc3RyZWFtLW1vZGUtdGV4dFwiPnt7c3RyZWFtTW9kZUZpbGVOYW1lIHx8ICduYW1lc2VydmVyX2hpc3RvcnkudHJjIChzdHJlYW0gbW9kZSknfX08L3A+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2ICpuZ0lmPVwic2hvd1JlYWRGaWxlUHJvZ3Jlc3NcIj5cclxuICAgICAgICA8cHJvZ3Jlc3MtYmFyIFtwcm9ncmVzc109XCJyZWFkUHJvZ3Jlc3NcIj48L3Byb2dyZXNzLWJhcj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJpbnB1dC10aW1lXCI+XHJcbiAgICAgPGRpdiBjbGFzcz1cImlucHV0LXRpbWUtcmFuZ2VcIj5cclxuICAgICAgIDx0aW1lLXJhbmdlLXNlbGVjdG9yIFtkaXNhYmxlZF09XCJzaG93UmVhZEZpbGVQcm9ncmVzc1wiIFsoZGF0ZVRpbWVSYW5nZSldPVwiZGF0ZVRpbWVSYW5nZVwiPjwvdGltZS1yYW5nZS1zZWxlY3Rvcj5cclxuICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cInRpbWV6b25lLXNlbGVjdG9yXCI+XHJcbiAgICAgICAgPHRpbWV6b25lLXNlbGVjdG9yIFsodGltZXpvbmUpXT1cInRpbWV6b25lXCIgW2Rpc2FibGVkXT1cInNob3dSZWFkRmlsZVByb2dyZXNzXCI+PC90aW1lem9uZS1zZWxlY3Rvcj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwicG9ydC1zZWxlY3Rpb25cIj5cclxuICAgICAgPGRpdiBjbGFzcz1cInBvcnQtc2VsZWN0b3JcIj5cclxuICAgICAgICA8cG9ydC1zZWxlY3RvciAocG9ydENoYW5nZSk9XCJzd2l0Y2hQb3J0Rm9yQ2hhcnQoJGV2ZW50KVwiIFsocG9ydCldPVwicG9ydFwiIFtwb3J0c109XCJwb3J0c1wiIFtkaXNhYmxlZF09XCJzaG93UmVhZEZpbGVQcm9ncmVzc1wiPjwvcG9ydC1zZWxlY3Rvcj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJwb3J0LWxvYWQtYnV0dG9uXCI+XHJcbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwibG9hZFBvcnRzKClcIiB0aXRsZT1cIkxvYWQgYWxsIHBvcnRzIGZyb20gbmFtZSBzZXJ2ZXIgaGlzdG9yeSB0cmFjZSBmaWxlLlwiIFtkaXNhYmxlZF09XCIhZW5hYmxlU2hvd0NoYXJ0QnV0dG9uIHx8IHBvcnQgfHwgIWVuYWJsZUxvYWRQb3J0c0J1dHRvblwiPnt7c2hvd1JlYWRGaWxlUHJvZ3Jlc3M/IFwiTG9hZGluZy4uLlwiIDogXCJMb2FkXCJ9fTwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJjaGFydC1vcGVyYXRpb25cIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cclxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJzaG93Q2hhcnQoKVwiIHRpdGxlPVwiTG9hZCBhbmQgZGlzcGxheSBhbGwgZGF0YSBmcm9tIG5hbWUgc2VydmVyIGhpc3RvcnkgdHJhY2UgZmlsZS5cIiBbZGlzYWJsZWRdPVwiIWVuYWJsZVNob3dDaGFydEJ1dHRvblwiPnt7c2hvd1JlYWRGaWxlUHJvZ3Jlc3M/IFwiTG9hZGluZy4uLlwiIDogXCJTaG93XCJ9fTwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+XHJcbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwicmVzZXRDaGFydCgpXCIgdGl0bGU9XCJSZXNldCB6b29tIG9mIGNoYXJ0LlwiIFtkaXNhYmxlZF09XCJzaG93UmVhZEZpbGVQcm9ncmVzcyB8fCAhZW5hYmxlUmVzZXRDaGFydEJ1dHRvblwiPlJlc2V0IENoYXJ0PC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgPGRpdiAjbmFtZXNlcnZlckhpc3RvcnlDb250ZW50IGNsYXNzPVwibmFtZXNlcnZlci1oaXN0b3J5LWNvbnRlbnRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJuYW1lc2VydmVyLWhpc3RvcnktY29udGVudC1jaGFydFwiPlxyXG4gICAgICA8aW5zdHJ1Y3Rpb24gWyhzaG93KV09XCJzaG93SW5zdHJ1Y3Rpb25cIiAqbmdJZj1cIiFzaG93Q2hhcnRGbGFnICYmIHNob3dJbnN0cnVjdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICBbc3RlcDFGaW5pc2hlZF09XCIhIWZpbGVcIlxyXG4gICAgICAgICAgICAgICAgICAgW3N0ZXAyRmluaXNoZWRdPVwiZGF0ZVRpbWVSYW5nZSAmJiAoISFkYXRlVGltZVJhbmdlWzBdIHx8ICEhZGF0ZVRpbWVSYW5nZVsxXSkgfHwgdGltZXpvbmUgIT0gZGVmYXVsdFRpbWV6b25lXCJcclxuICAgICAgICAgICAgICAgICAgIFtzdGVwM0ZpbmlzaGVkXT1cIiEhcG9ydFwiXHJcbiAgICAgICAgICAgICAgICAgICBbc3RlcDRGaW5pc2hlZF09XCJzdGVwU2hvd0NoYXJ0ICYmICFlbmFibGVTaG93Q2hhcnRCdXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgW3N0ZXA1RmluaXNoZWRdPVwiZmFsc2VcIj5cclxuICAgICAgPC9pbnN0cnVjdGlvbj5cclxuICAgICAgPGNhbnZhcyBpZD1cImNoYXJ0TmFtZVNlcnZlckhpc3RvcnlcIiA+PC9jYW52YXM+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJuYW1lc2VydmVyLWhpc3RvcnktY29udGVudC1jb250cm9sbGVyXCIgPlxyXG4gICAgICA8bmd4LXNlbGVjdGlvbi10YWJsZSAoY2hhbmdlKT1cInNlbGVjdEl0ZW0oJGV2ZW50KVwiICpuZ0lmPVwic2hvd0NoYXJ0RmxhZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWx0ZXJdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2JveF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RhYmxlU291cmNlXT1cInRhYmxlU291cmNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW2tleUNvbHVtbl09XCJrcGlDb2x1bW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZGVuQ29sdW1uc109XCJoaWRkZW5Db2x1bW5zXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBDb2x1bW5dPVwiZGVzY0NvbHVtblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWFyY2hTdHlsZV09XCJzZWFyY2hUeXBlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlYXJjaENvbHVtbl09XCJrcGlDb2x1bW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlTZWxlY3Rpb25dPVwidHJ1ZVwiPlxyXG4gICAgICA8L25neC1zZWxlY3Rpb24tdGFibGU+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcbjxkaXYgY2xhc3M9XCJtZXNzYWdlLWNvbnRhaW5lclwiICpuZ0lmPVwiYWxlcnRNZXNzYWdlXCI+XHJcbiAgPGFsZXJ0IFsoYWxlcnRNZXNzYWdlKV09XCJhbGVydE1lc3NhZ2VcIiBbYWxlcnRUeXBlXT1cImFsZXJ0VHlwZVwiIFthbGVydFRpbWVvdXRdPVwiMzAwMDBcIj48L2FsZXJ0PlxyXG48L2Rpdj5cclxuIl19