ngx-easy-table-plus 15.7.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.
- package/LICENSE +20 -0
- package/README.md +37 -0
- package/esm2022/lib/components/base/base.component.mjs +541 -0
- package/esm2022/lib/components/base/base.module.mjs +46 -0
- package/esm2022/lib/components/header/header.component.mjs +24 -0
- package/esm2022/lib/components/pagination/pagination.component.mjs +68 -0
- package/esm2022/lib/components/thead/thead.component.mjs +147 -0
- package/esm2022/lib/index.mjs +7 -0
- package/esm2022/lib/model/api.mjs +24 -0
- package/esm2022/lib/model/columns.mjs +2 -0
- package/esm2022/lib/model/config.mjs +12 -0
- package/esm2022/lib/model/event.enum.mjs +24 -0
- package/esm2022/lib/model/pagination.mjs +2 -0
- package/esm2022/lib/pipes/global-search-pipe.mjs +30 -0
- package/esm2022/lib/pipes/render-pipe.mjs +18 -0
- package/esm2022/lib/pipes/search-pipe.mjs +51 -0
- package/esm2022/lib/pipes/sort.pipe.mjs +64 -0
- package/esm2022/lib/services/config-service.mjs +51 -0
- package/esm2022/lib/services/filters.service.mjs +16 -0
- package/esm2022/lib/services/group-rows.service.mjs +19 -0
- package/esm2022/lib/services/style.service.mjs +46 -0
- package/esm2022/lib/table.module.mjs +19 -0
- package/esm2022/ngx-easy-table-plus.mjs +5 -0
- package/esm2022/public_api.mjs +9 -0
- package/fesm2022/ngx-easy-table-plus.mjs +1142 -0
- package/fesm2022/ngx-easy-table-plus.mjs.map +1 -0
- package/index.d.ts +6 -0
- package/lib/components/base/base.component.d.ts +112 -0
- package/lib/components/base/base.component.d.ts.map +1 -0
- package/lib/components/base/base.module.d.ts +19 -0
- package/lib/components/base/base.module.d.ts.map +1 -0
- package/lib/components/header/header.component.d.ts +15 -0
- package/lib/components/header/header.component.d.ts.map +1 -0
- package/lib/components/pagination/pagination.component.d.ts +32 -0
- package/lib/components/pagination/pagination.component.d.ts.map +1 -0
- package/lib/components/thead/thead.component.d.ts +52 -0
- package/lib/components/thead/thead.component.d.ts.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/model/api.d.ts +117 -0
- package/lib/model/api.d.ts.map +1 -0
- package/lib/model/columns.d.ts +19 -0
- package/lib/model/columns.d.ts.map +1 -0
- package/lib/model/config.d.ts +53 -0
- package/lib/model/config.d.ts.map +1 -0
- package/lib/model/event.enum.d.ts +21 -0
- package/lib/model/event.enum.d.ts.map +1 -0
- package/lib/model/pagination.d.ts +6 -0
- package/lib/model/pagination.d.ts.map +1 -0
- package/lib/pipes/global-search-pipe.d.ts +9 -0
- package/lib/pipes/global-search-pipe.d.ts.map +1 -0
- package/lib/pipes/render-pipe.d.ts +8 -0
- package/lib/pipes/render-pipe.d.ts.map +1 -0
- package/lib/pipes/search-pipe.d.ts +15 -0
- package/lib/pipes/search-pipe.d.ts.map +1 -0
- package/lib/pipes/sort.pipe.d.ts +17 -0
- package/lib/pipes/sort.pipe.d.ts.map +1 -0
- package/lib/services/config-service.d.ts +9 -0
- package/lib/services/config-service.d.ts.map +1 -0
- package/lib/services/filters.service.d.ts +7 -0
- package/lib/services/filters.service.d.ts.map +1 -0
- package/lib/services/group-rows.service.d.ts +7 -0
- package/lib/services/group-rows.service.d.ts.map +1 -0
- package/lib/services/style.service.d.ts +12 -0
- package/lib/services/style.service.d.ts.map +1 -0
- package/lib/table.module.d.ts +10 -0
- package/lib/table.module.d.ts.map +1 -0
- package/ngx-easy-table-plus.d.ts.map +1 -0
- package/package.json +44 -0
- package/public_api.d.ts +9 -0
- package/public_api.d.ts.map +1 -0
- package/style.css +514 -0
- package/style.css.map +1 -0
- package/style.scss +616 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild, } from '@angular/core';
|
|
3
|
+
import { API, Event } from '../..';
|
|
4
|
+
import { DefaultConfigService } from '../../services/config-service';
|
|
5
|
+
import { GroupRowsService } from '../../services/group-rows.service';
|
|
6
|
+
import { StyleService } from '../../services/style.service';
|
|
7
|
+
import { Subject } from 'rxjs';
|
|
8
|
+
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|
9
|
+
import { filter, takeUntil, throttleTime } from 'rxjs/operators';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@angular/cdk/scrolling";
|
|
12
|
+
import * as i2 from "../../services/style.service";
|
|
13
|
+
import * as i3 from "@angular/common";
|
|
14
|
+
import * as i4 from "@angular/cdk/drag-drop";
|
|
15
|
+
import * as i5 from "../pagination/pagination.component";
|
|
16
|
+
import * as i6 from "../thead/thead.component";
|
|
17
|
+
import * as i7 from "ngx-pagination";
|
|
18
|
+
import * as i8 from "../../pipes/search-pipe";
|
|
19
|
+
import * as i9 from "../../pipes/render-pipe";
|
|
20
|
+
import * as i10 from "../../pipes/global-search-pipe";
|
|
21
|
+
import * as i11 from "../../pipes/sort.pipe";
|
|
22
|
+
export class BaseComponent {
|
|
23
|
+
onContextMenuClick(targetElement) {
|
|
24
|
+
if (this.contextMenu && !this.contextMenu.nativeElement.contains(targetElement)) {
|
|
25
|
+
this.rowContextMenuPosition = {
|
|
26
|
+
top: null,
|
|
27
|
+
left: null,
|
|
28
|
+
value: null,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
constructor(cdr, scrollDispatcher, styleService) {
|
|
33
|
+
this.cdr = cdr;
|
|
34
|
+
this.scrollDispatcher = scrollDispatcher;
|
|
35
|
+
this.styleService = styleService;
|
|
36
|
+
this.unsubscribe = new Subject();
|
|
37
|
+
this.filterCount = -1;
|
|
38
|
+
this.filteredCountSubject = new Subject();
|
|
39
|
+
this.tableClass = null;
|
|
40
|
+
this.grouped = [];
|
|
41
|
+
this.isSelected = false;
|
|
42
|
+
this.page = 1;
|
|
43
|
+
this.count = 0;
|
|
44
|
+
this.sortState = new Map();
|
|
45
|
+
this.sortKey = null;
|
|
46
|
+
this.rowContextMenuPosition = {
|
|
47
|
+
top: null,
|
|
48
|
+
left: null,
|
|
49
|
+
value: null,
|
|
50
|
+
};
|
|
51
|
+
this.sortBy = {
|
|
52
|
+
key: '',
|
|
53
|
+
order: 'asc',
|
|
54
|
+
};
|
|
55
|
+
this.selectedDetailsTemplateRowId = new Set();
|
|
56
|
+
this.selectedCheckboxes = new Set();
|
|
57
|
+
this.id = 'table';
|
|
58
|
+
this.event = new EventEmitter();
|
|
59
|
+
this.filteredCountSubject.pipe(takeUntil(this.unsubscribe)).subscribe((count) => {
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
this.filterCount = count;
|
|
62
|
+
this.cdr.detectChanges();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
ngOnInit() {
|
|
67
|
+
if (!this.columns) {
|
|
68
|
+
console.error('[columns] property required!');
|
|
69
|
+
}
|
|
70
|
+
if (this.configuration) {
|
|
71
|
+
this.config = this.configuration;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.config = DefaultConfigService.config;
|
|
75
|
+
}
|
|
76
|
+
this.limit = this.config.rows;
|
|
77
|
+
if (this.groupRowsBy) {
|
|
78
|
+
this.grouped = GroupRowsService.doGroupRows(this.data, this.groupRowsBy);
|
|
79
|
+
}
|
|
80
|
+
this.doDecodePersistedState();
|
|
81
|
+
}
|
|
82
|
+
ngOnDestroy() {
|
|
83
|
+
this.unsubscribe.next();
|
|
84
|
+
this.unsubscribe.complete();
|
|
85
|
+
}
|
|
86
|
+
ngAfterViewInit() {
|
|
87
|
+
const throttleValue = this.config.infiniteScrollThrottleTime
|
|
88
|
+
? this.config.infiniteScrollThrottleTime
|
|
89
|
+
: 200;
|
|
90
|
+
this.scrollDispatcher
|
|
91
|
+
.scrolled()
|
|
92
|
+
.pipe(throttleTime(throttleValue), filter((event) => {
|
|
93
|
+
return (!!event &&
|
|
94
|
+
this.viewPort &&
|
|
95
|
+
this.viewPort.getRenderedRange().end === this.viewPort.getDataLength());
|
|
96
|
+
}), takeUntil(this.unsubscribe))
|
|
97
|
+
.subscribe(() => {
|
|
98
|
+
this.emitEvent(Event.onInfiniteScrollEnd, null);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
ngOnChanges(changes) {
|
|
102
|
+
const { configuration, data, pagination, groupRowsBy } = changes;
|
|
103
|
+
this.toggleRowIndex = changes.toggleRowIndex;
|
|
104
|
+
if (configuration && configuration.currentValue) {
|
|
105
|
+
this.config = configuration.currentValue;
|
|
106
|
+
}
|
|
107
|
+
if (data && data.currentValue) {
|
|
108
|
+
this.doApplyData(data);
|
|
109
|
+
}
|
|
110
|
+
if (pagination && pagination.currentValue) {
|
|
111
|
+
const { count, limit, offset } = pagination.currentValue;
|
|
112
|
+
this.count = count;
|
|
113
|
+
this.limit = limit;
|
|
114
|
+
this.page = offset;
|
|
115
|
+
}
|
|
116
|
+
if (groupRowsBy && groupRowsBy.currentValue) {
|
|
117
|
+
this.grouped = GroupRowsService.doGroupRows(this.data, this.groupRowsBy);
|
|
118
|
+
}
|
|
119
|
+
if (this.toggleRowIndex && this.toggleRowIndex.currentValue) {
|
|
120
|
+
const row = this.toggleRowIndex.currentValue;
|
|
121
|
+
this.collapseRow(row.index);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
orderBy(column) {
|
|
125
|
+
if (typeof column.orderEnabled !== 'undefined' && !column.orderEnabled) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
this.sortKey = column.key;
|
|
129
|
+
if (!this.config.orderEnabled || this.sortKey === '') {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.setColumnOrder(column);
|
|
133
|
+
if (!this.config.orderEventOnly && !column.orderEventOnly) {
|
|
134
|
+
this.sortBy.key = this.sortKey;
|
|
135
|
+
this.sortBy.order = this.sortState.get(this.sortKey);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
this.sortBy.key = '';
|
|
139
|
+
this.sortBy.order = '';
|
|
140
|
+
}
|
|
141
|
+
if (!this.config.serverPagination) {
|
|
142
|
+
this.data = [...this.data];
|
|
143
|
+
this.sortBy = { ...this.sortBy };
|
|
144
|
+
}
|
|
145
|
+
const value = {
|
|
146
|
+
key: this.sortKey,
|
|
147
|
+
order: this.sortState.get(this.sortKey),
|
|
148
|
+
};
|
|
149
|
+
this.emitEvent(Event.onOrder, value);
|
|
150
|
+
}
|
|
151
|
+
onClick($event, row, key, colIndex, rowIndex) {
|
|
152
|
+
if (this.config.selectRow) {
|
|
153
|
+
this.selectedRow = rowIndex;
|
|
154
|
+
}
|
|
155
|
+
if (this.config.selectCol && `${colIndex}`) {
|
|
156
|
+
this.selectedCol = colIndex;
|
|
157
|
+
}
|
|
158
|
+
if (this.config.selectCell && `${colIndex}`) {
|
|
159
|
+
this.selectedRow = rowIndex;
|
|
160
|
+
this.selectedCol = colIndex;
|
|
161
|
+
}
|
|
162
|
+
if (this.config.clickEvent) {
|
|
163
|
+
const value = {
|
|
164
|
+
event: $event,
|
|
165
|
+
row,
|
|
166
|
+
key,
|
|
167
|
+
rowId: rowIndex,
|
|
168
|
+
colId: colIndex,
|
|
169
|
+
};
|
|
170
|
+
this.emitEvent(Event.onClick, value);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
onDoubleClick($event, row, key, colIndex, rowIndex) {
|
|
174
|
+
const value = {
|
|
175
|
+
event: $event,
|
|
176
|
+
row,
|
|
177
|
+
key,
|
|
178
|
+
rowId: rowIndex,
|
|
179
|
+
colId: colIndex,
|
|
180
|
+
};
|
|
181
|
+
this.emitEvent(Event.onDoubleClick, value);
|
|
182
|
+
}
|
|
183
|
+
onCheckboxSelect($event, row, rowIndex) {
|
|
184
|
+
const value = {
|
|
185
|
+
event: $event,
|
|
186
|
+
row,
|
|
187
|
+
rowId: rowIndex,
|
|
188
|
+
};
|
|
189
|
+
this.emitEvent(Event.onCheckboxSelect, value);
|
|
190
|
+
}
|
|
191
|
+
onRadioSelect($event, row, rowIndex) {
|
|
192
|
+
const value = {
|
|
193
|
+
event: $event,
|
|
194
|
+
row,
|
|
195
|
+
rowId: rowIndex,
|
|
196
|
+
};
|
|
197
|
+
this.emitEvent(Event.onRadioSelect, value);
|
|
198
|
+
}
|
|
199
|
+
onSelectAll() {
|
|
200
|
+
this.isSelected = !this.isSelected;
|
|
201
|
+
this.emitEvent(Event.onSelectAll, this.isSelected);
|
|
202
|
+
}
|
|
203
|
+
onSearch($event) {
|
|
204
|
+
if (!this.config.serverPagination) {
|
|
205
|
+
this.term = $event;
|
|
206
|
+
}
|
|
207
|
+
this.emitEvent(Event.onSearch, $event);
|
|
208
|
+
}
|
|
209
|
+
onGlobalSearch(value) {
|
|
210
|
+
if (!this.config.serverPagination) {
|
|
211
|
+
this.globalSearchTerm = value;
|
|
212
|
+
}
|
|
213
|
+
this.emitEvent(Event.onGlobalSearch, value);
|
|
214
|
+
}
|
|
215
|
+
onPagination(pagination) {
|
|
216
|
+
this.page = pagination.page;
|
|
217
|
+
this.limit = pagination.limit;
|
|
218
|
+
this.config.rows = pagination.limit;
|
|
219
|
+
this.emitEvent(Event.onPagination, pagination);
|
|
220
|
+
}
|
|
221
|
+
toggleCheckbox(rowIndex) {
|
|
222
|
+
this.selectedCheckboxes.has(rowIndex)
|
|
223
|
+
? this.selectedCheckboxes.delete(rowIndex)
|
|
224
|
+
: this.selectedCheckboxes.add(rowIndex);
|
|
225
|
+
}
|
|
226
|
+
collapseRow(rowIndex) {
|
|
227
|
+
if (this.selectedDetailsTemplateRowId.has(rowIndex)) {
|
|
228
|
+
this.selectedDetailsTemplateRowId.delete(rowIndex);
|
|
229
|
+
this.emitEvent(Event.onRowCollapsedHide, rowIndex);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this.selectedDetailsTemplateRowId.add(rowIndex);
|
|
233
|
+
this.emitEvent(Event.onRowCollapsedShow, rowIndex);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
doDecodePersistedState() {
|
|
237
|
+
if (!this.config.persistState) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const pagination = localStorage.getItem(Event.onPagination);
|
|
241
|
+
const sort = localStorage.getItem(Event.onOrder);
|
|
242
|
+
const search = localStorage.getItem(Event.onSearch);
|
|
243
|
+
if (pagination) {
|
|
244
|
+
this.onPagination(JSON.parse(pagination));
|
|
245
|
+
}
|
|
246
|
+
if (sort) {
|
|
247
|
+
const { key, order } = JSON.parse(sort);
|
|
248
|
+
this.bindApi({
|
|
249
|
+
type: API.sortBy,
|
|
250
|
+
value: { column: key, order },
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (search) {
|
|
254
|
+
this.bindApi({
|
|
255
|
+
type: API.setInputValue,
|
|
256
|
+
value: JSON.parse(search),
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
isRowCollapsed(rowIndex) {
|
|
261
|
+
if (this.config.collapseAllRows) {
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
return this.selectedDetailsTemplateRowId.has(rowIndex);
|
|
265
|
+
}
|
|
266
|
+
get loadingHeight() {
|
|
267
|
+
const table = document.getElementById(this.id);
|
|
268
|
+
if (table && table.rows && table.rows.length > 3) {
|
|
269
|
+
const searchEnabled = this.config.searchEnabled ? 1 : 0;
|
|
270
|
+
const headerEnabled = this.config.headerEnabled ? 1 : 0;
|
|
271
|
+
const borderTrHeight = 1;
|
|
272
|
+
const borderDivHeight = 2;
|
|
273
|
+
return ((table.rows.length - searchEnabled - headerEnabled) *
|
|
274
|
+
(table.rows[3].offsetHeight - borderTrHeight) -
|
|
275
|
+
borderDivHeight);
|
|
276
|
+
}
|
|
277
|
+
return 30;
|
|
278
|
+
}
|
|
279
|
+
get arrowDefinition() {
|
|
280
|
+
return this.config.showDetailsArrow || typeof this.config.showDetailsArrow === 'undefined';
|
|
281
|
+
}
|
|
282
|
+
onRowContextMenu($event, row, key, colIndex, rowIndex) {
|
|
283
|
+
if (!this.config.showContextMenu) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
$event.preventDefault();
|
|
287
|
+
const value = {
|
|
288
|
+
event: $event,
|
|
289
|
+
row,
|
|
290
|
+
key,
|
|
291
|
+
rowId: rowIndex,
|
|
292
|
+
colId: colIndex,
|
|
293
|
+
};
|
|
294
|
+
this.rowContextMenuPosition = {
|
|
295
|
+
top: `${$event.pageY - 10}px`,
|
|
296
|
+
left: `${$event.pageX - 10}px`,
|
|
297
|
+
value,
|
|
298
|
+
};
|
|
299
|
+
this.emitEvent(Event.onRowContextMenu, value);
|
|
300
|
+
}
|
|
301
|
+
doApplyData(data) {
|
|
302
|
+
const order = this.columns.find((c) => !!c.orderBy);
|
|
303
|
+
if (order) {
|
|
304
|
+
this.sortState.set(this.sortKey, order.orderBy === 'asc' ? 'desc' : 'asc');
|
|
305
|
+
this.orderBy(order);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
this.data = [...data.currentValue];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
onDragStart(event) {
|
|
312
|
+
this.emitEvent(Event.onReorderStart, event);
|
|
313
|
+
}
|
|
314
|
+
onDrop(event) {
|
|
315
|
+
this.emitEvent(Event.onRowDrop, event);
|
|
316
|
+
moveItemInArray(this.data, event.previousIndex, event.currentIndex);
|
|
317
|
+
}
|
|
318
|
+
// DO NOT REMOVE. It is called from parent component. See src/app/demo/api-doc/api-doc.component.ts
|
|
319
|
+
apiEvent(event) {
|
|
320
|
+
return this.bindApi(event);
|
|
321
|
+
}
|
|
322
|
+
/* eslint-disable */
|
|
323
|
+
bindApi(event) {
|
|
324
|
+
switch (event.type) {
|
|
325
|
+
case API.rowContextMenuClicked:
|
|
326
|
+
this.rowContextMenuPosition = {
|
|
327
|
+
top: null,
|
|
328
|
+
left: null,
|
|
329
|
+
value: null,
|
|
330
|
+
};
|
|
331
|
+
break;
|
|
332
|
+
case API.toggleRowIndex:
|
|
333
|
+
this.collapseRow(event.value);
|
|
334
|
+
break;
|
|
335
|
+
case API.toggleCheckbox:
|
|
336
|
+
this.toggleCheckbox(event.value);
|
|
337
|
+
break;
|
|
338
|
+
case API.setInputValue:
|
|
339
|
+
if (this.config.searchEnabled) {
|
|
340
|
+
event.value.forEach((input) => {
|
|
341
|
+
const element = document.getElementById(`search_${input.key}`);
|
|
342
|
+
if (!element) {
|
|
343
|
+
console.error(`Column '${input.key}' not available in the DOM. Have you misspelled a name?`);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
element.value = input.value;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
this.onSearch(event.value);
|
|
351
|
+
this.cdr.markForCheck();
|
|
352
|
+
break;
|
|
353
|
+
case API.onGlobalSearch:
|
|
354
|
+
this.onGlobalSearch(event.value);
|
|
355
|
+
this.cdr.markForCheck();
|
|
356
|
+
break;
|
|
357
|
+
case API.setRowClass:
|
|
358
|
+
if (Array.isArray(event.value)) {
|
|
359
|
+
event.value.forEach((val) => this.styleService.setRowClass(val));
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
this.styleService.setRowClass(event.value);
|
|
363
|
+
this.cdr.markForCheck();
|
|
364
|
+
break;
|
|
365
|
+
case API.setCellClass:
|
|
366
|
+
if (Array.isArray(event.value)) {
|
|
367
|
+
event.value.forEach((val) => this.styleService.setCellClass(val));
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
this.styleService.setCellClass(event.value);
|
|
371
|
+
break;
|
|
372
|
+
case API.setRowStyle:
|
|
373
|
+
if (Array.isArray(event.value)) {
|
|
374
|
+
event.value.forEach((val) => this.styleService.setRowStyle(val));
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
this.styleService.setRowStyle(event.value);
|
|
378
|
+
break;
|
|
379
|
+
case API.setCellStyle:
|
|
380
|
+
if (Array.isArray(event.value)) {
|
|
381
|
+
event.value.forEach((val) => this.styleService.setCellStyle(val));
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
this.styleService.setCellStyle(event.value);
|
|
385
|
+
break;
|
|
386
|
+
case API.setTableClass:
|
|
387
|
+
this.tableClass = event.value;
|
|
388
|
+
this.cdr.markForCheck();
|
|
389
|
+
break;
|
|
390
|
+
case API.getPaginationTotalItems:
|
|
391
|
+
return this.paginationComponent.paginationDirective.getTotalItems();
|
|
392
|
+
case API.getPaginationCurrentPage:
|
|
393
|
+
return this.paginationComponent.paginationDirective.getCurrent();
|
|
394
|
+
case API.getPaginationLastPage:
|
|
395
|
+
return this.paginationComponent.paginationDirective.getLastPage();
|
|
396
|
+
case API.getNumberOfRowsPerPage:
|
|
397
|
+
return this.paginationComponent.paginationDirective.isLastPage()
|
|
398
|
+
? this.paginationComponent.paginationDirective.getTotalItems() % this.limit
|
|
399
|
+
: this.limit;
|
|
400
|
+
case API.setPaginationCurrentPage:
|
|
401
|
+
this.paginationComponent.paginationDirective.setCurrent(event.value);
|
|
402
|
+
break;
|
|
403
|
+
case API.setPaginationRange:
|
|
404
|
+
this.paginationComponent.ranges = event.value;
|
|
405
|
+
break;
|
|
406
|
+
case API.setPaginationPreviousLabel:
|
|
407
|
+
this.paginationComponent.previousLabel = event.value;
|
|
408
|
+
break;
|
|
409
|
+
case API.setPaginationNextLabel:
|
|
410
|
+
this.paginationComponent.nextLabel = event.value;
|
|
411
|
+
break;
|
|
412
|
+
case API.setPaginationDisplayLimit:
|
|
413
|
+
this.paginationComponent.changeLimit(event.value, true);
|
|
414
|
+
break;
|
|
415
|
+
case API.sortBy:
|
|
416
|
+
const column = { title: '', key: event.value.column, orderBy: event.value.order };
|
|
417
|
+
this.orderBy(column);
|
|
418
|
+
this.cdr.detectChanges();
|
|
419
|
+
break;
|
|
420
|
+
default:
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
setColumnOrder(column) {
|
|
425
|
+
const key = column.key;
|
|
426
|
+
switch (this.sortState.get(key)) {
|
|
427
|
+
case '':
|
|
428
|
+
case undefined:
|
|
429
|
+
this.sortState.set(key, column.orderBy || 'desc');
|
|
430
|
+
break;
|
|
431
|
+
case 'asc':
|
|
432
|
+
this.config.threeWaySort ? this.sortState.set(key, '') : this.sortState.set(key, 'desc');
|
|
433
|
+
break;
|
|
434
|
+
case 'desc':
|
|
435
|
+
this.sortState.set(key, 'asc');
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
if (this.sortState.size > 1) {
|
|
439
|
+
const temp = this.sortState.get(key);
|
|
440
|
+
this.sortState.clear();
|
|
441
|
+
this.sortState.set(key, temp);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
emitEvent(event, value) {
|
|
445
|
+
this.event.emit({ event, value });
|
|
446
|
+
if (this.config.persistState) {
|
|
447
|
+
localStorage.setItem(event, JSON.stringify(value));
|
|
448
|
+
}
|
|
449
|
+
if (this.config.logger) {
|
|
450
|
+
// eslint-disable-next-line no-console
|
|
451
|
+
console.log({ event, value });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
dragEnter($event) {
|
|
455
|
+
$event.preventDefault();
|
|
456
|
+
$event.stopPropagation();
|
|
457
|
+
}
|
|
458
|
+
dragOver($event) {
|
|
459
|
+
$event.preventDefault();
|
|
460
|
+
$event.stopPropagation();
|
|
461
|
+
}
|
|
462
|
+
dragLeave($event) {
|
|
463
|
+
$event.preventDefault();
|
|
464
|
+
$event.stopPropagation();
|
|
465
|
+
}
|
|
466
|
+
drop($event) {
|
|
467
|
+
$event.preventDefault();
|
|
468
|
+
$event.stopPropagation();
|
|
469
|
+
const file = $event.dataTransfer?.files?.[0];
|
|
470
|
+
if (file?.type !== 'application/json') {
|
|
471
|
+
// eslint-disable-next-line no-console
|
|
472
|
+
console.log('File not allowed');
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const fileReader = new FileReader();
|
|
476
|
+
fileReader.onload = (event) => {
|
|
477
|
+
this.data = JSON.parse(event?.target?.result);
|
|
478
|
+
this.cdr.markForCheck();
|
|
479
|
+
};
|
|
480
|
+
fileReader.readAsText(file);
|
|
481
|
+
}
|
|
482
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: BaseComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.ScrollDispatcher }, { token: i2.StyleService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
483
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.0", type: BaseComponent, selector: "ngx-table", inputs: { configuration: "configuration", data: "data", pagination: "pagination", groupRowsBy: "groupRowsBy", id: "id", toggleRowIndex: "toggleRowIndex", detailsTemplate: "detailsTemplate", summaryTemplate: "summaryTemplate", groupRowsHeaderTemplate: "groupRowsHeaderTemplate", filtersTemplate: "filtersTemplate", selectAllTemplate: "selectAllTemplate", noResultsTemplate: "noResultsTemplate", loadingTemplate: "loadingTemplate", additionalActionsTemplate: "additionalActionsTemplate", rowContextMenu: "rowContextMenu", columns: "columns" }, outputs: { event: "event" }, host: { listeners: { "document:click": "onContextMenuClick($event.target)" } }, providers: [DefaultConfigService, GroupRowsService, StyleService], queries: [{ propertyName: "rowTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "paginationComponent", first: true, predicate: ["paginationComponent"], descendants: true }, { propertyName: "contextMenu", first: true, predicate: ["contextMenu"], descendants: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "viewPort", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\r\n class=\"ngx-container\"\r\n [class.ngx-container--dark]=\"config.tableLayout.theme === 'dark'\"\r\n (dragenter)=\"dragEnter($event)\"\r\n (dragover)=\"dragOver($event)\"\r\n (dragleave)=\"dragLeave($event)\"\r\n (drop)=\"drop($event)\"\r\n>\r\n <table\r\n [id]=\"id\"\r\n #table\r\n [ngClass]=\"tableClass === null || tableClass === '' ? 'ngx-table' : tableClass\"\r\n [class.ngx-table__table--tiny]=\"config.tableLayout.style === 'tiny'\"\r\n [class.ngx-table__table--normal]=\"config.tableLayout.style === 'normal'\"\r\n [class.ngx-table__table--big]=\"config.tableLayout.style === 'big'\"\r\n [class.ngx-table__table--borderless]=\"config.tableLayout.borderless\"\r\n [class.ngx-table__table--dark]=\"config.tableLayout.theme === 'dark'\"\r\n [class.ngx-table__table--hoverable]=\"config.tableLayout.hover\"\r\n [class.ngx-table__table--striped]=\"config.tableLayout.striped\"\r\n [class.ngx-table__horizontal-scroll]=\"config.horizontalScroll && !config.isLoading\"\r\n >\r\n <thead\r\n [class.ngx-infinite-scroll-viewport-thead]=\"config.infiniteScroll\"\r\n table-thead\r\n [config]=\"config\"\r\n [sortKey]=\"sortKey\"\r\n [sortState]=\"sortState\"\r\n [selectAllTemplate]=\"selectAllTemplate\"\r\n [filtersTemplate]=\"filtersTemplate\"\r\n [additionalActionsTemplate]=\"additionalActionsTemplate\"\r\n [columns]=\"columns\"\r\n (selectAll)=\"onSelectAll()\"\r\n (filter)=\"onSearch($event)\"\r\n (order)=\"orderBy($event)\"\r\n (event)=\"emitEvent($event.event, $event.value)\"\r\n ></thead>\r\n <tbody *ngIf=\"data && !config.isLoading && !config.rowReorder\">\r\n <ng-container *ngIf=\"rowTemplate\">\r\n <ul\r\n class=\"ngx-table__table-row-context-menu\"\r\n [ngStyle]=\"{\r\n position: 'absolute',\r\n top: rowContextMenuPosition.top,\r\n left: rowContextMenuPosition.left\r\n }\"\r\n *ngIf=\"rowContextMenuPosition.top\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowContextMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value }\"\r\n >\r\n </ng-container>\r\n </ul>\r\n <ng-container *ngIf=\"!config.infiniteScroll\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n (click)=\"onClick($event, row, '', null, data.indexOf(row))\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, '', null, data.indexOf(row))\"\r\n (dblclick)=\"onDoubleClick($event, row, '', null, data.indexOf(row))\"\r\n [class.ngx-table__table-row--selected]=\"\r\n data.indexOf(row) === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n <td *ngIf=\"config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(data.indexOf(row))\r\n ? 'ngx-icon-arrow-down'\r\n : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(data.indexOf(row))\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(data.indexOf(row))) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"50\"\r\n *ngIf=\"config.infiniteScroll\"\r\n class=\"ngx-infinite-scroll-viewport\"\r\n >\r\n <ng-container\r\n *cdkVirtualFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject;\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr\r\n (click)=\"onClick($event, row, '', null, rowIndex)\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, '', null, rowIndex)\"\r\n (dblclick)=\"onDoubleClick($event, row, '', null, rowIndex)\"\r\n [class.ngx-table__table-row--selected]=\"\r\n rowIndex === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n <td *ngIf=\"config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\r\n <ul\r\n class=\"ngx-table__table-row-context-menu\"\r\n [ngStyle]=\"{\r\n position: 'absolute',\r\n top: rowContextMenuPosition.top,\r\n left: rowContextMenuPosition.left\r\n }\"\r\n *ngIf=\"rowContextMenuPosition.top\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowContextMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value }\"\r\n >\r\n </ng-container>\r\n </ul>\r\n <ng-container *ngIf=\"!config.infiniteScroll\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n [class.ngx-table__table-row--selected]=\"\r\n data.indexOf(row) === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-{{ data.indexOf(row) }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(data.indexOf(row))\"\r\n (change)=\"onCheckboxSelect($event, row, data.indexOf(row))\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-{{ data.indexOf(row) }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, data.indexOf(row))\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n #contextMenu\r\n (contextmenu)=\"\r\n onRowContextMenu($event, row, column.key, colIndex, data.indexOf(row))\r\n \"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n [class.pinned-left]=\"column.pinned\"\r\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\r\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n data.indexOf(row) === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: data.indexOf(row),\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(data.indexOf(row))\r\n ? 'ngx-icon-arrow-down'\r\n : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(data.indexOf(row))\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(data.indexOf(row))) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n <!-- infinite scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"50\"\r\n *ngIf=\"config.infiniteScroll\"\r\n class=\"ngx-infinite-scroll-viewport\"\r\n >\r\n <ng-container\r\n *cdkVirtualFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject;\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr\r\n [class.ngx-table__table-row--selected]=\"\r\n rowIndex === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes\" width=\"3%\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-infinite-scroll-{{ rowIndex }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(rowIndex)\"\r\n (change)=\"onCheckboxSelect($event, row, rowIndex)\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\" width=\"3%\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-infinite-scroll-{{ rowIndex }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, rowIndex)\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, rowIndex)\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, column.key, colIndex, rowIndex)\"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, rowIndex)\"\r\n [class.pinned-left]=\"column.pinned\"\r\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\r\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n rowIndex === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: rowIndex,\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowTemplate && config.groupRows\">\r\n <ng-container\r\n *ngFor=\"\r\n let group of grouped\r\n | sort: sortBy:config\r\n | search: term:filteredCountSubject:config\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr>\r\n <ng-container *ngIf=\"!groupRowsHeaderTemplate\">\r\n <td [attr.colspan]=\"columns.length\">\r\n <div>{{ group[0][groupRowsBy] }} ({{ group.length }})</div>\r\n </td>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"groupRowsHeaderTemplate\"\r\n [ngTemplateOutlet]=\"groupRowsHeaderTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n total: group.length,\r\n key: groupRowsBy,\r\n value: group[0] ? group[0][groupRowsBy] : '',\r\n group: group,\r\n index: rowIndex\r\n }\"\r\n >\r\n </ng-container>\r\n <td>\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <ng-container *ngIf=\"selectedDetailsTemplateRowId.has(rowIndex)\">\r\n <tr *ngFor=\"let row of group\">\r\n <td *ngFor=\"let column of columns\">\r\n {{ row | render: column.key }}\r\n <!-- TODO allow users to add groupRowsTemplateRef -->\r\n </td>\r\n <td></td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n <tbody\r\n *ngIf=\"data && !config.isLoading && config.rowReorder\"\r\n class=\"ngx-draggable-row-area\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n >\r\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n class=\"ngx-draggable-row\"\r\n cdkDrag\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n [cdkDragStartDelay]=\"config.reorderDelay || 0\"\r\n cdkDragLockAxis=\"y\"\r\n >\r\n <td *ngIf=\"config.checkboxes\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-draggable-{{ data.indexOf(row) }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(data.indexOf(row))\"\r\n (change)=\"onCheckboxSelect($event, row, data.indexOf(row))\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-draggable-{{ data.indexOf(row) }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, data.indexOf(row))\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n data.indexOf(row) === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: data.indexOf(row),\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n <tbody *ngIf=\"filterCount === 0\">\r\n <tr class=\"ngx-table__body-empty\">\r\n <ng-container *ngIf=\"noResultsTemplate\" [ngTemplateOutlet]=\"noResultsTemplate\">\r\n </ng-container>\r\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!noResultsTemplate\">\r\n <div class=\"ngx-table__table-no-results\">No results</div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tbody *ngIf=\"config.isLoading\">\r\n <tr class=\"ngx-table__body-loading\">\r\n <ng-container *ngIf=\"loadingTemplate\" [ngTemplateOutlet]=\"loadingTemplate\"> </ng-container>\r\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!loadingTemplate\">\r\n <div [style.height.px]=\"loadingHeight\" class=\"ngx-table__table-loader-wrapper\">\r\n <div class=\"ngx-table__table-loader\"></div>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot *ngIf=\"summaryTemplate\">\r\n <tr>\r\n <ng-container\r\n [ngTemplateOutlet]=\"summaryTemplate\"\r\n [ngTemplateOutletContext]=\"{ total: data.length, limit: limit, page: page }\"\r\n >\r\n </ng-container>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n <pagination\r\n [attr.id]=\"'pagination' + id\"\r\n [id]=\"id\"\r\n #paginationComponent\r\n [config]=\"config\"\r\n [pagination]=\"pagination\"\r\n (updateRange)=\"onPagination($event)\"\r\n >\r\n </pagination>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: i5.PaginationComponent, selector: "pagination", inputs: ["pagination", "config", "id"], outputs: ["updateRange"] }, { kind: "component", type: i6.TableTHeadComponent, selector: "[table-thead]", inputs: ["config", "columns", "sortKey", "sortState", "selectAllTemplate", "filtersTemplate", "additionalActionsTemplate"], outputs: ["filter", "order", "selectAll", "event"] }, { kind: "pipe", type: i7.PaginatePipe, name: "paginate" }, { kind: "pipe", type: i8.SearchPipe, name: "search" }, { kind: "pipe", type: i9.RenderPipe, name: "render" }, { kind: "pipe", type: i10.GlobalSearchPipe, name: "global" }, { kind: "pipe", type: i11.SortPipe, name: "sort" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
484
|
+
}
|
|
485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: BaseComponent, decorators: [{
|
|
486
|
+
type: Component,
|
|
487
|
+
args: [{ selector: 'ngx-table', providers: [DefaultConfigService, GroupRowsService, StyleService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"ngx-container\"\r\n [class.ngx-container--dark]=\"config.tableLayout.theme === 'dark'\"\r\n (dragenter)=\"dragEnter($event)\"\r\n (dragover)=\"dragOver($event)\"\r\n (dragleave)=\"dragLeave($event)\"\r\n (drop)=\"drop($event)\"\r\n>\r\n <table\r\n [id]=\"id\"\r\n #table\r\n [ngClass]=\"tableClass === null || tableClass === '' ? 'ngx-table' : tableClass\"\r\n [class.ngx-table__table--tiny]=\"config.tableLayout.style === 'tiny'\"\r\n [class.ngx-table__table--normal]=\"config.tableLayout.style === 'normal'\"\r\n [class.ngx-table__table--big]=\"config.tableLayout.style === 'big'\"\r\n [class.ngx-table__table--borderless]=\"config.tableLayout.borderless\"\r\n [class.ngx-table__table--dark]=\"config.tableLayout.theme === 'dark'\"\r\n [class.ngx-table__table--hoverable]=\"config.tableLayout.hover\"\r\n [class.ngx-table__table--striped]=\"config.tableLayout.striped\"\r\n [class.ngx-table__horizontal-scroll]=\"config.horizontalScroll && !config.isLoading\"\r\n >\r\n <thead\r\n [class.ngx-infinite-scroll-viewport-thead]=\"config.infiniteScroll\"\r\n table-thead\r\n [config]=\"config\"\r\n [sortKey]=\"sortKey\"\r\n [sortState]=\"sortState\"\r\n [selectAllTemplate]=\"selectAllTemplate\"\r\n [filtersTemplate]=\"filtersTemplate\"\r\n [additionalActionsTemplate]=\"additionalActionsTemplate\"\r\n [columns]=\"columns\"\r\n (selectAll)=\"onSelectAll()\"\r\n (filter)=\"onSearch($event)\"\r\n (order)=\"orderBy($event)\"\r\n (event)=\"emitEvent($event.event, $event.value)\"\r\n ></thead>\r\n <tbody *ngIf=\"data && !config.isLoading && !config.rowReorder\">\r\n <ng-container *ngIf=\"rowTemplate\">\r\n <ul\r\n class=\"ngx-table__table-row-context-menu\"\r\n [ngStyle]=\"{\r\n position: 'absolute',\r\n top: rowContextMenuPosition.top,\r\n left: rowContextMenuPosition.left\r\n }\"\r\n *ngIf=\"rowContextMenuPosition.top\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowContextMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value }\"\r\n >\r\n </ng-container>\r\n </ul>\r\n <ng-container *ngIf=\"!config.infiniteScroll\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n (click)=\"onClick($event, row, '', null, data.indexOf(row))\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, '', null, data.indexOf(row))\"\r\n (dblclick)=\"onDoubleClick($event, row, '', null, data.indexOf(row))\"\r\n [class.ngx-table__table-row--selected]=\"\r\n data.indexOf(row) === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n <td *ngIf=\"config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(data.indexOf(row))\r\n ? 'ngx-icon-arrow-down'\r\n : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(data.indexOf(row))\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(data.indexOf(row))) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"50\"\r\n *ngIf=\"config.infiniteScroll\"\r\n class=\"ngx-infinite-scroll-viewport\"\r\n >\r\n <ng-container\r\n *cdkVirtualFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject;\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr\r\n (click)=\"onClick($event, row, '', null, rowIndex)\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, '', null, rowIndex)\"\r\n (dblclick)=\"onDoubleClick($event, row, '', null, rowIndex)\"\r\n [class.ngx-table__table-row--selected]=\"\r\n rowIndex === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n <td *ngIf=\"config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\r\n <ul\r\n class=\"ngx-table__table-row-context-menu\"\r\n [ngStyle]=\"{\r\n position: 'absolute',\r\n top: rowContextMenuPosition.top,\r\n left: rowContextMenuPosition.left\r\n }\"\r\n *ngIf=\"rowContextMenuPosition.top\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowContextMenu\"\r\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value }\"\r\n >\r\n </ng-container>\r\n </ul>\r\n <ng-container *ngIf=\"!config.infiniteScroll\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n [class.ngx-table__table-row--selected]=\"\r\n data.indexOf(row) === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-{{ data.indexOf(row) }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(data.indexOf(row))\"\r\n (change)=\"onCheckboxSelect($event, row, data.indexOf(row))\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-{{ data.indexOf(row) }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, data.indexOf(row))\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n #contextMenu\r\n (contextmenu)=\"\r\n onRowContextMenu($event, row, column.key, colIndex, data.indexOf(row))\r\n \"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n [class.pinned-left]=\"column.pinned\"\r\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\r\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n data.indexOf(row) === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: data.indexOf(row),\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(data.indexOf(row))\r\n ? 'ngx-icon-arrow-down'\r\n : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(data.indexOf(row))\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(data.indexOf(row))) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: data.indexOf(row) }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n <!-- infinite scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"50\"\r\n *ngIf=\"config.infiniteScroll\"\r\n class=\"ngx-infinite-scroll-viewport\"\r\n >\r\n <ng-container\r\n *cdkVirtualFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject;\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr\r\n [class.ngx-table__table-row--selected]=\"\r\n rowIndex === selectedRow && !config.selectCell\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes\" width=\"3%\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-infinite-scroll-{{ rowIndex }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(rowIndex)\"\r\n (change)=\"onCheckboxSelect($event, row, rowIndex)\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\" width=\"3%\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-infinite-scroll-{{ rowIndex }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, rowIndex)\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, rowIndex)\"\r\n #contextMenu\r\n (contextmenu)=\"onRowContextMenu($event, row, column.key, colIndex, rowIndex)\"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, rowIndex)\"\r\n [class.pinned-left]=\"column.pinned\"\r\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\r\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n rowIndex === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: rowIndex,\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <tr\r\n *ngIf=\"\r\n (config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) ||\r\n config.collapseAllRows\r\n \"\r\n >\r\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\r\n <td [attr.colspan]=\"columns.length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"detailsTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowTemplate && config.groupRows\">\r\n <ng-container\r\n *ngFor=\"\r\n let group of grouped\r\n | sort: sortBy:config\r\n | search: term:filteredCountSubject:config\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\r\n let rowIndex = index\r\n \"\r\n >\r\n <tr>\r\n <ng-container *ngIf=\"!groupRowsHeaderTemplate\">\r\n <td [attr.colspan]=\"columns.length\">\r\n <div>{{ group[0][groupRowsBy] }} ({{ group.length }})</div>\r\n </td>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"groupRowsHeaderTemplate\"\r\n [ngTemplateOutlet]=\"groupRowsHeaderTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n total: group.length,\r\n key: groupRowsBy,\r\n value: group[0] ? group[0][groupRowsBy] : '',\r\n group: group,\r\n index: rowIndex\r\n }\"\r\n >\r\n </ng-container>\r\n <td>\r\n <span\r\n class=\"ngx-icon\"\r\n *ngIf=\"arrowDefinition\"\r\n [ngClass]=\"\r\n isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\r\n \"\r\n (click)=\"collapseRow(rowIndex)\"\r\n >\r\n </span>\r\n </td>\r\n </tr>\r\n <ng-container *ngIf=\"selectedDetailsTemplateRowId.has(rowIndex)\">\r\n <tr *ngFor=\"let row of group\">\r\n <td *ngFor=\"let column of columns\">\r\n {{ row | render: column.key }}\r\n <!-- TODO allow users to add groupRowsTemplateRef -->\r\n </td>\r\n <td></td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n <tbody\r\n *ngIf=\"data && !config.isLoading && config.rowReorder\"\r\n class=\"ngx-draggable-row-area\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n >\r\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of data\r\n | sort: sortBy\r\n | search: term:filteredCountSubject\r\n | global: globalSearchTerm:filteredCountSubject\r\n | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id }\r\n \"\r\n >\r\n <tr\r\n class=\"ngx-draggable-row\"\r\n cdkDrag\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n [cdkDragStartDelay]=\"config.reorderDelay || 0\"\r\n cdkDragLockAxis=\"y\"\r\n >\r\n <td *ngIf=\"config.checkboxes\">\r\n <label class=\"ngx-form-checkbox\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"checkbox-draggable-{{ data.indexOf(row) }}\"\r\n [checked]=\"isSelected || selectedCheckboxes.has(data.indexOf(row))\"\r\n (change)=\"onCheckboxSelect($event, row, data.indexOf(row))\"\r\n />\r\n <em class=\"ngx-form-icon\"></em>\r\n </label>\r\n </td>\r\n <td *ngIf=\"config.radio\">\r\n <label>\r\n <input\r\n type=\"radio\"\r\n id=\"radio-draggable-{{ data.indexOf(row) }}\"\r\n name=\"radio\"\r\n (change)=\"onRadioSelect($event, row, data.indexOf(row))\"\r\n />\r\n </label>\r\n </td>\r\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\r\n <td\r\n (click)=\"onClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, data.indexOf(row))\"\r\n [class.ngx-table__table-col--selected]=\"\r\n colIndex === selectedCol && !config.selectCell\r\n \"\r\n [class.ngx-table__table-cell--selected]=\"\r\n colIndex === selectedCol &&\r\n data.indexOf(row) === selectedRow &&\r\n !config.selectCol &&\r\n !config.selectRow\r\n \"\r\n >\r\n <div *ngIf=\"!column.cellTemplate\">{{ row | render: column.key }}</div>\r\n <ng-container\r\n *ngIf=\"column.cellTemplate\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n rowIndex: data.indexOf(row),\r\n column: column\r\n }\"\r\n >\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n <tbody *ngIf=\"filterCount === 0\">\r\n <tr class=\"ngx-table__body-empty\">\r\n <ng-container *ngIf=\"noResultsTemplate\" [ngTemplateOutlet]=\"noResultsTemplate\">\r\n </ng-container>\r\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!noResultsTemplate\">\r\n <div class=\"ngx-table__table-no-results\">No results</div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tbody *ngIf=\"config.isLoading\">\r\n <tr class=\"ngx-table__body-loading\">\r\n <ng-container *ngIf=\"loadingTemplate\" [ngTemplateOutlet]=\"loadingTemplate\"> </ng-container>\r\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!loadingTemplate\">\r\n <div [style.height.px]=\"loadingHeight\" class=\"ngx-table__table-loader-wrapper\">\r\n <div class=\"ngx-table__table-loader\"></div>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot *ngIf=\"summaryTemplate\">\r\n <tr>\r\n <ng-container\r\n [ngTemplateOutlet]=\"summaryTemplate\"\r\n [ngTemplateOutletContext]=\"{ total: data.length, limit: limit, page: page }\"\r\n >\r\n </ng-container>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n <pagination\r\n [attr.id]=\"'pagination' + id\"\r\n [id]=\"id\"\r\n #paginationComponent\r\n [config]=\"config\"\r\n [pagination]=\"pagination\"\r\n (updateRange)=\"onPagination($event)\"\r\n >\r\n </pagination>\r\n</div>\r\n" }]
|
|
488
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.ScrollDispatcher }, { type: i2.StyleService }], propDecorators: { configuration: [{
|
|
489
|
+
type: Input
|
|
490
|
+
}], data: [{
|
|
491
|
+
type: Input
|
|
492
|
+
}], pagination: [{
|
|
493
|
+
type: Input
|
|
494
|
+
}], groupRowsBy: [{
|
|
495
|
+
type: Input
|
|
496
|
+
}], id: [{
|
|
497
|
+
type: Input
|
|
498
|
+
}], toggleRowIndex: [{
|
|
499
|
+
type: Input
|
|
500
|
+
}], detailsTemplate: [{
|
|
501
|
+
type: Input
|
|
502
|
+
}], summaryTemplate: [{
|
|
503
|
+
type: Input
|
|
504
|
+
}], groupRowsHeaderTemplate: [{
|
|
505
|
+
type: Input
|
|
506
|
+
}], filtersTemplate: [{
|
|
507
|
+
type: Input
|
|
508
|
+
}], selectAllTemplate: [{
|
|
509
|
+
type: Input
|
|
510
|
+
}], noResultsTemplate: [{
|
|
511
|
+
type: Input
|
|
512
|
+
}], loadingTemplate: [{
|
|
513
|
+
type: Input
|
|
514
|
+
}], additionalActionsTemplate: [{
|
|
515
|
+
type: Input
|
|
516
|
+
}], rowContextMenu: [{
|
|
517
|
+
type: Input
|
|
518
|
+
}], columns: [{
|
|
519
|
+
type: Input
|
|
520
|
+
}], event: [{
|
|
521
|
+
type: Output
|
|
522
|
+
}], rowTemplate: [{
|
|
523
|
+
type: ContentChild,
|
|
524
|
+
args: [TemplateRef]
|
|
525
|
+
}], paginationComponent: [{
|
|
526
|
+
type: ViewChild,
|
|
527
|
+
args: ['paginationComponent']
|
|
528
|
+
}], contextMenu: [{
|
|
529
|
+
type: ViewChild,
|
|
530
|
+
args: ['contextMenu']
|
|
531
|
+
}], table: [{
|
|
532
|
+
type: ViewChild,
|
|
533
|
+
args: ['table']
|
|
534
|
+
}], viewPort: [{
|
|
535
|
+
type: ViewChild,
|
|
536
|
+
args: [CdkVirtualScrollViewport]
|
|
537
|
+
}], onContextMenuClick: [{
|
|
538
|
+
type: HostListener,
|
|
539
|
+
args: ['document:click', ['$event.target']]
|
|
540
|
+
}] } });
|
|
541
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWFzeS10YWJsZS9zcmMvbGliL2NvbXBvbmVudHMvYmFzZS9iYXNlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1lYXN5LXRhYmxlL3NyYy9saWIvY29tcG9uZW50cy9iYXNlL2Jhc2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUE2QixlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRixPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUdOLFdBQVcsRUFDWCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLEdBQUcsRUFBNEIsS0FBSyxFQUFjLE1BQU0sT0FBTyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRXJFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSx3QkFBd0IsRUFBb0IsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRixPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7OztBQWdCakUsTUFBTSxPQUFPLGFBQWE7SUFxRGpCLGtCQUFrQixDQUFDLGFBQWtCO1FBQzFDLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FB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Uzt1QkFBQyxhQUFhO2dCQUNKLEtBQUs7c0JBQXhCLFNBQVM7dUJBQUMsT0FBTztnQkFDbUIsUUFBUTtzQkFBNUMsU0FBUzt1QkFBQyx3QkFBd0I7Z0JBRzVCLGtCQUFrQjtzQkFEeEIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka0RyYWdEcm9wLCBDZGtEcmFnU3RhcnQsIG1vdmVJdGVtSW5BcnJheSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9kcmFnLWRyb3AnO1xyXG5pbXBvcnQge1xyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIENvbnRlbnRDaGlsZCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSG9zdExpc3RlbmVyLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBTaW1wbGVDaGFuZ2UsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBUZW1wbGF0ZVJlZixcclxuICBWaWV3Q2hpbGQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBBUEksIEFwaVR5cGUsIENvbHVtbnMsIENvbmZpZywgRXZlbnQsIFBhZ2luYXRpb24gfSBmcm9tICcuLi8uLic7XHJcbmltcG9ydCB7IERlZmF1bHRDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29uZmlnLXNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQYWdpbmF0aW9uQ29tcG9uZW50LCBQYWdpbmF0aW9uUmFuZ2UgfSBmcm9tICcuLi9wYWdpbmF0aW9uL3BhZ2luYXRpb24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgR3JvdXBSb3dzU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2dyb3VwLXJvd3Muc2VydmljZSc7XHJcbmltcG9ydCB7IFN0eWxlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3N0eWxlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCwgU2Nyb2xsRGlzcGF0Y2hlciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIHRha2VVbnRpbCwgdGhyb3R0bGVUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxudHlwZSBDb2x1bW5LZXlUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbjtcclxuXHJcbmludGVyZmFjZSBSb3dDb250ZXh0TWVudVBvc2l0aW9uIHtcclxuICB0b3A6IHN0cmluZyB8IG51bGw7XHJcbiAgbGVmdDogc3RyaW5nIHwgbnVsbDtcclxuICB2YWx1ZTogYW55IHwgbnVsbDtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduZ3gtdGFibGUnLFxyXG4gIHByb3ZpZGVyczogW0RlZmF1bHRDb25maWdTZXJ2aWNlLCBHcm91cFJvd3NTZXJ2aWNlLCBTdHlsZVNlcnZpY2VdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9iYXNlLmNvbXBvbmVudC5odG1sJyxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxufSlcclxuZXhwb3J0IGNsYXNzIEJhc2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICBwcml2YXRlIHVuc3Vic2NyaWJlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuICBwdWJsaWMgc2VsZWN0ZWRSb3c6IG51bWJlcjtcclxuICBwdWJsaWMgc2VsZWN0ZWRDb2w6IG51bWJlcjtcclxuICBwdWJsaWMgdGVybTogYW55O1xyXG4gIHB1YmxpYyBmaWx0ZXJDb3VudCA9IC0xO1xyXG4gIHB1YmxpYyBmaWx0ZXJlZENvdW50U3ViamVjdCA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcclxuICBwdWJsaWMgdGFibGVDbGFzczogc3RyaW5nIHwgbnVsbCA9IG51bGw7XHJcbiAgcHVibGljIGdsb2JhbFNlYXJjaFRlcm06IHN0cmluZztcclxuICBwdWJsaWMgZ3JvdXBlZDogYW55ID0gW107XHJcbiAgcHVibGljIGlzU2VsZWN0ZWQgPSBmYWxzZTtcclxuICBwdWJsaWMgcGFnZSA9IDE7XHJcbiAgcHVibGljIGNvdW50ID0gMDtcclxuICBwdWJsaWMgc29ydFN0YXRlID0gbmV3IE1hcCgpO1xyXG4gIHB1YmxpYyBzb3J0S2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcclxuICBwdWJsaWMgcm93Q29udGV4dE1lbnVQb3NpdGlvbjogUm93Q29udGV4dE1lbnVQb3NpdGlvbiA9IHtcclxuICAgIHRvcDogbnVsbCxcclxuICAgIGxlZnQ6IG51bGwsXHJcbiAgICB2YWx1ZTogbnVsbCxcclxuICB9O1xyXG4gIHB1YmxpYyBsaW1pdDtcclxuICBwdWJsaWMgc29ydEJ5OiB7IGtleTogc3RyaW5nIH0gJiB7IG9yZGVyOiBzdHJpbmcgfSA9IHtcclxuICAgIGtleTogJycsXHJcbiAgICBvcmRlcjogJ2FzYycsXHJcbiAgfTtcclxuICBwdWJsaWMgc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZCA9IG5ldyBTZXQ8bnVtYmVyPigpO1xyXG4gIHB1YmxpYyBzZWxlY3RlZENoZWNrYm94ZXMgPSBuZXcgU2V0PG51bWJlcj4oKTtcclxuICBwdWJsaWMgY29uZmlnOiBDb25maWc7XHJcblxyXG4gIEBJbnB1dCgpIGNvbmZpZ3VyYXRpb246IENvbmZpZztcclxuICBASW5wdXQoKSBkYXRhOiBhbnlbXTtcclxuICBASW5wdXQoKSBwYWdpbmF0aW9uOiBQYWdpbmF0aW9uO1xyXG4gIEBJbnB1dCgpIGdyb3VwUm93c0J5OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgaWQgPSAndGFibGUnO1xyXG4gIEBJbnB1dCgpIHRvZ2dsZVJvd0luZGV4O1xyXG4gIEBJbnB1dCgpIGRldGFpbHNUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBASW5wdXQoKSBzdW1tYXJ5VGVtcGxhdGU6IFRlbXBsYXRlUmVmPHsgdG90YWw6IG51bWJlcjsgbGltaXQ6IG51bWJlcjsgcGFnZTogbnVtYmVyIH0+O1xyXG4gIEBJbnB1dCgpIGdyb3VwUm93c0hlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBJbnB1dCgpIGZpbHRlcnNUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBASW5wdXQoKSBzZWxlY3RBbGxUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBASW5wdXQoKSBub1Jlc3VsdHNUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dm9pZD47XHJcbiAgQElucHV0KCkgbG9hZGluZ1RlbXBsYXRlOiBUZW1wbGF0ZVJlZjx2b2lkPjtcclxuICBASW5wdXQoKSBhZGRpdGlvbmFsQWN0aW9uc1RlbXBsYXRlOiBUZW1wbGF0ZVJlZjx2b2lkPjtcclxuICBASW5wdXQoKSByb3dDb250ZXh0TWVudTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBASW5wdXQoKSBjb2x1bW5zOiBDb2x1bW5zW107XHJcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGV2ZW50OiBzdHJpbmc7IHZhbHVlOiBhbnkgfT4oKTtcclxuICBAQ29udGVudENoaWxkKFRlbXBsYXRlUmVmKSBwdWJsaWMgcm93VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQFZpZXdDaGlsZCgncGFnaW5hdGlvbkNvbXBvbmVudCcpIHByaXZhdGUgcGFnaW5hdGlvbkNvbXBvbmVudDogUGFnaW5hdGlvbkNvbXBvbmVudDtcclxuICBAVmlld0NoaWxkKCdjb250ZXh0TWVudScpIGNvbnRleHRNZW51O1xyXG4gIEBWaWV3Q2hpbGQoJ3RhYmxlJykgdGFibGU7XHJcbiAgQFZpZXdDaGlsZChDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQpIHZpZXdQb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ7XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQudGFyZ2V0J10pXHJcbiAgcHVibGljIG9uQ29udGV4dE1lbnVDbGljayh0YXJnZXRFbGVtZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmNvbnRleHRNZW51ICYmICF0aGlzLmNvbnRleHRNZW51Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0RWxlbWVudCkpIHtcclxuICAgICAgdGhpcy5yb3dDb250ZXh0TWVudVBvc2l0aW9uID0ge1xyXG4gICAgICAgIHRvcDogbnVsbCxcclxuICAgICAgICBsZWZ0OiBudWxsLFxyXG4gICAgICAgIHZhbHVlOiBudWxsLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjcm9sbERpc3BhdGNoZXI6IFNjcm9sbERpc3BhdGNoZXIsXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3R5bGVTZXJ2aWNlOiBTdHlsZVNlcnZpY2VcclxuICApIHtcclxuICAgIHRoaXMuZmlsdGVyZWRDb3VudFN1YmplY3QucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5maWx0ZXJDb3VudCA9IGNvdW50O1xyXG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmNvbHVtbnMpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW2NvbHVtbnNdIHByb3BlcnR5IHJlcXVpcmVkIScpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuY29uZmlndXJhdGlvbikge1xyXG4gICAgICB0aGlzLmNvbmZpZyA9IHRoaXMuY29uZmlndXJhdGlvbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY29uZmlnID0gRGVmYXVsdENvbmZpZ1NlcnZpY2UuY29uZmlnO1xyXG4gICAgfVxyXG4gICAgdGhpcy5saW1pdCA9IHRoaXMuY29uZmlnLnJvd3M7XHJcbiAgICBpZiAodGhpcy5ncm91cFJvd3NCeSkge1xyXG4gICAgICB0aGlzLmdyb3VwZWQgPSBHcm91cFJvd3NTZXJ2aWNlLmRvR3JvdXBSb3dzKHRoaXMuZGF0YSwgdGhpcy5ncm91cFJvd3NCeSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmRvRGVjb2RlUGVyc2lzdGVkU3RhdGUoKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZS5uZXh0KCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICBjb25zdCB0aHJvdHRsZVZhbHVlID0gdGhpcy5jb25maWcuaW5maW5pdGVTY3JvbGxUaHJvdHRsZVRpbWVcclxuICAgICAgPyB0aGlzLmNvbmZpZy5pbmZpbml0ZVNjcm9sbFRocm90dGxlVGltZVxyXG4gICAgICA6IDIwMDtcclxuICAgIHRoaXMuc2Nyb2xsRGlzcGF0Y2hlclxyXG4gICAgICAuc2Nyb2xsZWQoKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0aHJvdHRsZVRpbWUodGhyb3R0bGVWYWx1ZSksXHJcbiAgICAgICAgZmlsdGVyKChldmVudCkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgISFldmVudCAmJlxyXG4gICAgICAgICAgICB0aGlzLnZpZXdQb3J0ICYmXHJcbiAgICAgICAgICAgIHRoaXMudmlld1BvcnQuZ2V0UmVuZGVyZWRSYW5nZSgpLmVuZCA9PT0gdGhpcy52aWV3UG9ydC5nZXREYXRhTGVuZ3RoKClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUpXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25JbmZpbml0ZVNjcm9sbEVuZCwgbnVsbCk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgY29uc3QgeyBjb25maWd1cmF0aW9uLCBkYXRhLCBwYWdpbmF0aW9uLCBncm91cFJvd3NCeSB9ID0gY2hhbmdlcztcclxuICAgIHRoaXMudG9nZ2xlUm93SW5kZXggPSBjaGFuZ2VzLnRvZ2dsZVJvd0luZGV4O1xyXG4gICAgaWYgKGNvbmZpZ3VyYXRpb24gJiYgY29uZmlndXJhdGlvbi5jdXJyZW50VmFsdWUpIHtcclxuICAgICAgdGhpcy5jb25maWcgPSBjb25maWd1cmF0aW9uLmN1cnJlbnRWYWx1ZTtcclxuICAgIH1cclxuICAgIGlmIChkYXRhICYmIGRhdGEuY3VycmVudFZhbHVlKSB7XHJcbiAgICAgIHRoaXMuZG9BcHBseURhdGEoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBpZiAocGFnaW5hdGlvbiAmJiBwYWdpbmF0aW9uLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICBjb25zdCB7IGNvdW50LCBsaW1pdCwgb2Zmc2V0IH0gPSBwYWdpbmF0aW9uLmN1cnJlbnRWYWx1ZSBhcyBQYWdpbmF0aW9uO1xyXG4gICAgICB0aGlzLmNvdW50ID0gY291bnQ7XHJcbiAgICAgIHRoaXMubGltaXQgPSBsaW1pdDtcclxuICAgICAgdGhpcy5wYWdlID0gb2Zmc2V0O1xyXG4gICAgfVxyXG4gICAgaWYgKGdyb3VwUm93c0J5ICYmIGdyb3VwUm93c0J5LmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICB0aGlzLmdyb3VwZWQgPSBHcm91cFJvd3NTZXJ2aWNlLmRvR3JvdXBSb3dzKHRoaXMuZGF0YSwgdGhpcy5ncm91cFJvd3NCeSk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy50b2dnbGVSb3dJbmRleCAmJiB0aGlzLnRvZ2dsZVJvd0luZGV4LmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICBjb25zdCByb3cgPSB0aGlzLnRvZ2dsZVJvd0luZGV4LmN1cnJlbnRWYWx1ZTtcclxuICAgICAgdGhpcy5jb2xsYXBzZVJvdyhyb3cuaW5kZXgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb3JkZXJCeShjb2x1bW46IENvbHVtbnMpOiB2b2lkIHtcclxuICAgIGlmICh0eXBlb2YgY29sdW1uLm9yZGVyRW5hYmxlZCAhPT0gJ3VuZGVmaW5lZCcgJiYgIWNvbHVtbi5vcmRlckVuYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zb3J0S2V5ID0gY29sdW1uLmtleTtcclxuICAgIGlmICghdGhpcy5jb25maWcub3JkZXJFbmFibGVkIHx8IHRoaXMuc29ydEtleSA9PT0gJycpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc2V0Q29sdW1uT3JkZXIoY29sdW1uKTtcclxuICAgIGlmICghdGhpcy5jb25maWcub3JkZXJFdmVudE9ubHkgJiYgIWNvbHVtbi5vcmRlckV2ZW50T25seSkge1xyXG4gICAgICB0aGlzLnNvcnRCeS5rZXkgPSB0aGlzLnNvcnRLZXk7XHJcbiAgICAgIHRoaXMuc29ydEJ5Lm9yZGVyID0gdGhpcy5zb3J0U3RhdGUuZ2V0KHRoaXMuc29ydEtleSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNvcnRCeS5rZXkgPSAnJztcclxuICAgICAgdGhpcy5zb3J0Qnkub3JkZXIgPSAnJztcclxuICAgIH1cclxuICAgIGlmICghdGhpcy5jb25maWcuc2VydmVyUGFnaW5hdGlvbikge1xyXG4gICAgICB0aGlzLmRhdGEgPSBbLi4udGhpcy5kYXRhXTtcclxuICAgICAgdGhpcy5zb3J0QnkgPSB7IC4uLnRoaXMuc29ydEJ5IH07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdmFsdWUgPSB7XHJcbiAgICAgIGtleTogdGhpcy5zb3J0S2V5LFxyXG4gICAgICBvcmRlcjogdGhpcy5zb3J0U3RhdGUuZ2V0KHRoaXMuc29ydEtleSksXHJcbiAgICB9O1xyXG4gICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25PcmRlciwgdmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgb25DbGljaygkZXZlbnQ6IE1vdXNlRXZlbnQsIHJvdzogYW55LCBrZXk6IENvbHVtbktleVR5cGUsIGNvbEluZGV4OiBhbnksIHJvd0luZGV4OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmNvbmZpZy5zZWxlY3RSb3cpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZFJvdyA9IHJvd0luZGV4O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuY29uZmlnLnNlbGVjdENvbCAmJiBgJHtjb2xJbmRleH1gKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb2wgPSBjb2xJbmRleDtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbmZpZy5zZWxlY3RDZWxsICYmIGAke2NvbEluZGV4fWApIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZFJvdyA9IHJvd0luZGV4O1xyXG4gICAgICB0aGlzLnNlbGVjdGVkQ29sID0gY29sSW5kZXg7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29uZmlnLmNsaWNrRXZlbnQpIHtcclxuICAgICAgY29uc3QgdmFsdWUgPSB7XHJcbiAgICAgICAgZXZlbnQ6ICRldmVudCxcclxuICAgICAgICByb3csXHJcbiAgICAgICAga2V5LFxyXG4gICAgICAgIHJvd0lkOiByb3dJbmRleCxcclxuICAgICAgICBjb2xJZDogY29sSW5kZXgsXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uQ2xpY2ssIHZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uRG91YmxlQ2xpY2soXHJcbiAgICAkZXZlbnQ6IE1vdXNlRXZlbnQsXHJcbiAgICByb3c6IGFueSxcclxuICAgIGtleTogQ29sdW1uS2V5VHlwZSxcclxuICAgIGNvbEluZGV4OiBhbnksXHJcbiAgICByb3dJbmRleDogbnVtYmVyXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IHtcclxuICAgICAgZXZlbnQ6ICRldmVudCxcclxuICAgICAgcm93LFxyXG4gICAgICBrZXksXHJcbiAgICAgIHJvd0lkOiByb3dJbmRleCxcclxuICAgICAgY29sSWQ6IGNvbEluZGV4LFxyXG4gICAgfTtcclxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uRG91YmxlQ2xpY2ssIHZhbHVlKTtcclxuICB9XHJcblxyXG4gIG9uQ2hlY2tib3hTZWxlY3QoJGV2ZW50OiBhbnksIHJvdzogYW55LCByb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IHtcclxuICAgICAgZXZlbnQ6ICRldmVudCxcclxuICAgICAgcm93LFxyXG4gICAgICByb3dJZDogcm93SW5kZXgsXHJcbiAgICB9O1xyXG4gICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25DaGVja2JveFNlbGVjdCwgdmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgb25SYWRpb1NlbGVjdCgkZXZlbnQ6IGFueSwgcm93OiBhbnksIHJvd0luZGV4OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGNvbnN0IHZhbHVlID0ge1xyXG4gICAgICBldmVudDogJGV2ZW50LFxyXG4gICAgICByb3csXHJcbiAgICAgIHJvd0lkOiByb3dJbmRleCxcclxuICAgIH07XHJcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJhZGlvU2VsZWN0LCB2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBvblNlbGVjdEFsbCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNTZWxlY3RlZCA9ICF0aGlzLmlzU2VsZWN0ZWQ7XHJcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblNlbGVjdEFsbCwgdGhpcy5pc1NlbGVjdGVkKTtcclxuICB9XHJcblxyXG4gIG9uU2VhcmNoKCRldmVudDogQXJyYXk8eyBrZXk6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9Pik6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zZXJ2ZXJQYWdpbmF0aW9uKSB7XHJcbiAgICAgIHRoaXMudGVybSA9ICRldmVudDtcclxuICAgIH1cclxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uU2VhcmNoLCAkZXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgb25HbG9iYWxTZWFyY2godmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zZXJ2ZXJQYWdpbmF0aW9uKSB7XHJcbiAgICAgIHRoaXMuZ2xvYmFsU2VhcmNoVGVybSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25HbG9iYWxTZWFyY2gsIHZhbHVlKTtcclxuICB9XHJcblxyXG4gIG9uUGFnaW5hdGlvbihwYWdpbmF0aW9uOiBQYWdpbmF0aW9uUmFuZ2UpOiB2b2lkIHtcclxuICAgIHRoaXMucGFnZSA9IHBhZ2luYXRpb24ucGFnZTtcclxuICAgIHRoaXMubGltaXQgPSBwYWdpbmF0aW9uLmxpbWl0O1xyXG4gICAgdGhpcy5jb25maWcucm93cyA9IHBhZ2luYXRpb24ubGltaXQ7XHJcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblBhZ2luYXRpb24sIHBhZ2luYXRpb24pO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlQ2hlY2tib3gocm93SW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RlZENoZWNrYm94ZXMuaGFzKHJvd0luZGV4KVxyXG4gICAgICA/IHRoaXMuc2VsZWN0ZWRDaGVja2JveGVzLmRlbGV0ZShyb3dJbmRleClcclxuICAgICAgOiB0aGlzLnNlbGVjdGVkQ2hlY2tib3hlcy5hZGQocm93SW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgY29sbGFwc2VSb3cocm93SW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5oYXMocm93SW5kZXgpKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5kZWxldGUocm93SW5kZXgpO1xyXG4gICAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJvd0NvbGxhcHNlZEhpZGUsIHJvd0luZGV4KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5hZGQocm93SW5kZXgpO1xyXG4gICAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJvd0NvbGxhcHNlZFNob3csIHJvd0luZGV4KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZG9EZWNvZGVQZXJzaXN0ZWRTdGF0ZSgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jb25maWcucGVyc2lzdFN0YXRlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IHBhZ2luYXRpb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShFdmVudC5vblBhZ2luYXRpb24pO1xyXG4gICAgY29uc3Qgc29ydCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKEV2ZW50Lm9uT3JkZXIpO1xyXG4gICAgY29uc3Qgc2VhcmNoID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oRXZlbnQub25TZWFyY2gpO1xyXG4gICAgaWYgKHBhZ2luYXRpb24pIHtcclxuICAgICAgdGhpcy5vblBhZ2luYXRpb24oSlNPTi5wYXJzZShwYWdpbmF0aW9uKSk7XHJcbiAgICB9XHJcbiAgICBpZiAoc29ydCkge1xyXG4gICAgICBjb25zdCB7IGtleSwgb3JkZXIgfSA9IEpTT04ucGFyc2Uoc29ydCk7XHJcbiAgICAgIHRoaXMuYmluZEFwaSh7XHJcbiAgICAgICAgdHlwZTogQVBJLnNvcnRCeSxcclxuICAgICAgICB2YWx1ZTogeyBjb2x1bW46IGtleSwgb3JkZXIgfSxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAoc2VhcmNoKSB7XHJcbiAgICAgIHRoaXMuYmluZEFwaSh7XHJcbiAgICAgICAgdHlwZTogQVBJLnNldElucHV0VmFsdWUsXHJcbiAgICAgICAgdmFsdWU6IEpTT04ucGFyc2Uoc2VhcmNoKSxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpc1Jvd0NvbGxhcHNlZChyb3dJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5jb25maWcuY29sbGFwc2VBbGxSb3dzKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5oYXMocm93SW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGxvYWRpbmdIZWlnaHQoKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pZCkgYXMgSFRNTFRhYmxlRWxlbWVudDtcclxuICAgIGlmICh0YWJsZSAmJiB0YWJsZS5yb3dzICYmIHRhYmxlLnJvd3MubGVuZ3RoID4gMykge1xyXG4gICAgICBjb25zdCBzZWFyY2hFbmFibGVkID0gdGhpcy5jb25maWcuc2VhcmNoRW5hYmxlZCA/IDEgOiAwO1xyXG4gICAgICBjb25zdCBoZWFkZXJFbmFibGVkID0gdGhpcy5jb25maWcuaGVhZGVyRW5hYmxlZCA/IDEgOiAwO1xyXG4gICAgICBjb25zdCBib3JkZXJUckhlaWdodCA9IDE7XHJcbiAgICAgIGNvbnN0IGJvcmRlckRpdkhlaWdodCA9IDI7XHJcbiAgICAgIHJldHVybiAoXHJcbiAgICAgICAgKHRhYmxlLnJvd3MubGVuZ3RoIC0gc2VhcmNoRW5hYmxlZCAtIGhlYWRlckVuYWJsZWQpICpcclxuICAgICAgICAgICh0YWJsZS5yb3dzWzNdLm9mZnNldEhlaWdodCAtIGJvcmRlclRySGVpZ2h0KSAtXHJcbiAgICAgICAgYm9yZGVyRGl2SGVpZ2h0XHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIDMwO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGFycm93RGVmaW5pdGlvbigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zaG93RGV0YWlsc0Fycm93IHx8IHR5cGVvZiB0aGlzLmNvbmZpZy5zaG93RGV0YWlsc0Fycm93ID09PSAndW5kZWZpbmVkJztcclxuICB9XHJcblxyXG4gIG9uUm93Q29udGV4dE1lbnUoXHJcbiAgICAkZXZlbnQ6IE1vdXNlRXZlbnQsXHJcbiAgICByb3c6IGFueSxcclxuICAgIGtleTogQ29sdW1uS2V5VHlwZSxcclxuICAgIGNvbEluZGV4OiBhbnksXHJcbiAgICByb3dJbmRleDogbnVtYmVyXHJcbiAgKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY29uZmlnLnNob3dDb250ZXh0TWVudSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIGNvbnN0IHZhbHVlID0ge1xyXG4gICAgICBldmVudDogJGV2ZW50LFxyXG4gICAgICByb3csXHJcbiAgICAgIGtleSxcclxuICAgICAgcm93SWQ6IHJvd0luZGV4LFxyXG4gICAgICBjb2xJZDogY29sSW5kZXgsXHJcbiAgICB9O1xyXG4gICAgdGhpcy5yb3dDb250ZXh0TWVudVBvc2l0aW9uID0ge1xyXG4gICAgICB0b3A6IGAkeyRldmVudC5wYWdlWSAtIDEwfXB4YCxcclxuICAgICAgbGVmdDogYCR7JGV2ZW50LnBhZ2VYIC0gMTB9cHhgLFxyXG4gICAgICB2YWx1ZSxcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25Sb3dDb250ZXh0TWVudSwgdmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkb0FwcGx5RGF0YShkYXRhOiBTaW1wbGVDaGFuZ2UpOiB2b2lkIHtcclxuICAgIGNvbnN0IG9yZGVyID0gdGhpcy5jb2x1bW5zLmZpbmQoKGMpID0+ICEhYy5vcmRlckJ5KTtcclxuICAgIGlmIChvcmRlcikge1xyXG4gICAgICB0aGlzLnNvcnRTdGF0ZS5zZXQodGhpcy5zb3J0S2V5LCBvcmRlci5vcmRlckJ5ID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnKTtcclxuICAgICAgdGhpcy5vcmRlckJ5KG9yZGVyKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGF0YSA9IFsuLi5kYXRhLmN1cnJlbnRWYWx1ZV07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkRyYWdTdGFydChldmVudDogQ2RrRHJhZ1N0YXJ0KTogdm9pZCB7XHJcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJlb3JkZXJTdGFydCwgZXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgb25Ecm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxzdHJpbmdbXT4pOiB2b2lkIHtcclxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uUm93RHJvcCwgZXZlbnQpO1xyXG4gICAgbW92ZUl0ZW1JbkFycmF5KHRoaXMuZGF0YSwgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuICB9XHJcblxyXG4gIC8vIERPIE5PVCBSRU1PVkUuIEl0IGlzIGNhbGxlZCBmcm9tIHBhcmVudCBjb21wb25lbnQuIFNlZSBzcmMvYXBwL2RlbW8vYXBpLWRvYy9hcGktZG9jLmNvbXBvbmVudC50c1xyXG4gIGFwaUV2ZW50KGV2ZW50OiBBcGlUeXBlKTogdm9pZCB8IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5iaW5kQXBpKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8qIGVzbGludC1kaXNhYmxlICovXHJcbiAgcHJpdmF0ZSBiaW5kQXBpKGV2ZW50OiBBcGlUeXBlKTogdm9pZCB8IG51bWJlciB7XHJcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcclxuICAgICAgY2FzZSBBUEkucm93Q29udGV4dE1lbnVDbGlja2VkOlxyXG4gICAgICAgIHRoaXMucm93Q29udGV4dE1lbnVQb3NpdGlvbiA9IHtcclxuICAgICAgICAgIHRvcDogbnVsbCxcclxuICAgICAgICAgIGxlZnQ6IG51bGwsXHJcbiAgICAgICAgICB2YWx1ZTogbnVsbCxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS50b2dnbGVSb3dJbmRleDpcclxuICAgICAgICB0aGlzLmNvbGxhcHNlUm93KGV2ZW50LnZhbHVlKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSBBUEkudG9nZ2xlQ2hlY2tib3g6XHJcbiAgICAgICAgdGhpcy50b2dnbGVDaGVja2JveChldmVudC52YWx1ZSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLnNldElucHV0VmFsdWU6XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnNlYXJjaEVuYWJsZWQpIHtcclxuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKGlucHV0KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc2VhcmNoXyR7aW5wdXQua2V5fWApIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGlmICghZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICAgICAgICAgICBgQ29sdW1uICcke2lucHV0LmtleX0nIG5vdCBhdmFpbGFibGUgaW4gdGhlIERPTS4gSGF2ZSB5b3UgbWlzc3BlbGxlZCBhIG5hbWU/YFxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IGlucHV0LnZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vblNlYXJjaChldmVudC52YWx1ZSk7XHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLm9uR2xvYmFsU2VhcmNoOlxyXG4gICAgICAgIHRoaXMub25HbG9iYWxTZWFyY2goZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRSb3dDbGFzczpcclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudC52YWx1ZSkpIHtcclxuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKHZhbCkgPT4gdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93Q2xhc3ModmFsKSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93Q2xhc3MoZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRDZWxsQ2xhc3M6XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQudmFsdWUpKSB7XHJcbiAgICAgICAgICBldmVudC52YWx1ZS5mb3JFYWNoKCh2YWwpID0+IHRoaXMuc3R5bGVTZXJ2aWNlLnNldENlbGxDbGFzcyh2YWwpKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnN0eWxlU2VydmljZS5zZXRDZWxsQ2xhc3MoZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRSb3dTdHlsZTpcclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudC52YWx1ZSkpIHtcclxuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKHZhbCkgPT4gdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93U3R5bGUodmFsKSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93U3R5bGUoZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRDZWxsU3R5bGU6XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQudmFsdWUpKSB7XHJcbiAgICAgICAgICBldmVudC52YWx1ZS5mb3JFYWNoKCh2YWwpID0+IHRoaXMuc3R5bGVTZXJ2aWNlLnNldENlbGxTdHlsZSh2YWwpKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnN0eWxlU2VydmljZS5zZXRDZWxsU3R5bGUoZXZlbnQudmFsdWUpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRUYWJsZUNsYXNzOlxyXG4gICAgICAgIHRoaXMudGFibGVDbGFzcyA9IGV2ZW50LnZhbHVlO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5nZXRQYWdpbmF0aW9uVG90YWxJdGVtczpcclxuICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuZ2V0VG90YWxJdGVtcygpO1xyXG4gICAgICBjYXNlIEFQSS5nZXRQYWdpbmF0aW9uQ3VycmVudFBhZ2U6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGFnaW5hdGlvbkNvbXBvbmVudC5wYWdpbmF0aW9uRGlyZWN0aXZlLmdldEN1cnJlbnQoKTtcclxuICAgICAgY2FzZSBBUEkuZ2V0UGFnaW5hdGlvbkxhc3RQYWdlOlxyXG4gICAgICAgIHJldHVybiB0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucGFnaW5hdGlvbkRpcmVjdGl2ZS5nZXRMYXN0UGFnZSgpO1xyXG4gICAgICBjYXNlIEFQSS5nZXROdW1iZXJPZlJvd3NQZXJQYWdlOlxyXG4gICAgICAgIHJldHVybiB0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucGFnaW5hdGlvbkRpcmVjdGl2ZS5pc0xhc3RQYWdlKClcclxuICAgICAgICAgID8gdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuZ2V0VG90YWxJdGVtcygpICUgdGhpcy5saW1pdFxyXG4gICAgICAgICAgOiB0aGlzLmxpbWl0O1xyXG4gICAgICBjYXNlIEFQSS5zZXRQYWdpbmF0aW9uQ3VycmVudFBhZ2U6XHJcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuc2V0Q3VycmVudChldmVudC52YWx1ZSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLnNldFBhZ2luYXRpb25SYW5nZTpcclxuICAgICAgICB0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucmFuZ2VzID0gZXZlbnQudmFsdWU7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLnNldFBhZ2luYXRpb25QcmV2aW91c0xhYmVsOlxyXG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkNvbXBvbmVudC5wcmV2aW91c0xhYmVsID0gZXZlbnQudmFsdWU7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLnNldFBhZ2luYXRpb25OZXh0TGFiZWw6XHJcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50Lm5leHRMYWJlbCA9IGV2ZW50LnZhbHVlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEFQSS5zZXRQYWdpbmF0aW9uRGlzcGxheUxpbWl0OlxyXG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkNvbXBvbmVudC5jaGFuZ2VMaW1pdChldmVudC52YWx1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQVBJLnNvcnRCeTpcclxuICAgICAgICBjb25zdCBjb2x1bW46IENvbHVtbnMgPSB7IHRpdGxlOiAnJywga2V5OiBldmVudC52YWx1ZS5jb2x1bW4sIG9yZGVyQnk6IGV2ZW50LnZhbHVlLm9yZGVyIH07XHJcbiAgICAgICAgdGhpcy5vcmRlckJ5KGNvbHVtbik7XHJcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRDb2x1bW5PcmRlcihjb2x1bW46IENvbHVtbnMpOiB2b2lkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gY29sdW1uLmtleTtcclxuXHJcbiAgICBzd2l0Y2ggKHRoaXMuc29ydFN0YXRlLmdldChrZXkpKSB7XHJcbiAgICAgIGNhc2UgJyc6XHJcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxyXG4gICAgICAgIHRoaXMuc29ydFN0YXRlLnNldChrZXksIGNvbHVtbi5vcmRlckJ5IHx8ICdkZXNjJyk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2FzYyc6XHJcbiAgICAgICAgdGhpcy5jb25maWcudGhyZWVXYXlTb3J0ID8gdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJycpIDogdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJ2Rlc2MnKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnZGVzYyc6XHJcbiAgICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJ2FzYycpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuc29ydFN0YXRlLnNpemUgPiAxKSB7XHJcbiAgICAgIGNvbnN0IHRlbXAgPSB0aGlzLnNvcnRTdGF0ZS5nZXQoa2V5KTtcclxuICAgICAgdGhpcy5zb3J0U3RhdGUuY2xlYXIoKTtcclxuICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgdGVtcCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZW1pdEV2ZW50KGV2ZW50OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuZXZlbnQuZW1pdCh7IGV2ZW50LCB2YWx1ZSB9KTtcclxuICAgIGlmICh0aGlzLmNvbmZpZy5wZXJzaXN0U3RhdGUpIHtcclxuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oZXZlbnQsIEpTT04uc3RyaW5naWZ5KHZhbHVlKSk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5jb25maWcubG9nZ2VyKSB7XHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXHJcbiAgICAgIGNvbnNvbGUubG9nKHsgZXZlbnQsIHZhbHVlIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZHJhZ0VudGVyKCRldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XHJcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICB9XHJcblxyXG4gIGRyYWdPdmVyKCRldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XHJcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICB9XHJcblxyXG4gIGRyYWdMZWF2ZSgkZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xyXG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgfVxyXG5cclxuICBkcm9wKCRldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XHJcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGNvbnN0IGZpbGUgPSAkZXZlbnQuZGF0YVRyYW5zZmVyPy5maWxlcz8uWzBdO1xyXG4gICAgaWYgKGZpbGU/LnR5cGUgIT09ICdhcHBsaWNhdGlvbi9qc29uJykge1xyXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxyXG4gICAgICBjb25zb2xlLmxvZygnRmlsZSBub3QgYWxsb3dlZCcpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgIGZpbGVSZWFkZXIub25sb2FkID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMuZGF0YSA9IEpTT04ucGFyc2UoZXZlbnQ/LnRhcmdldD8ucmVzdWx0IGFzIHN0cmluZyk7XHJcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgfTtcclxuICAgIGZpbGVSZWFkZXIucmVhZEFzVGV4dChmaWxlKTtcclxuICB9XHJcbn1cclxuIiwiPGRpdlxyXG4gIGNsYXNzPVwibmd4LWNvbnRhaW5lclwiXHJcbiAgW2NsYXNzLm5neC1jb250YWluZXItLWRhcmtdPVwiY29uZmlnLnRhYmxlTGF5b3V0LnRoZW1lID09PSAnZGFyaydcIlxyXG4gIChkcmFnZW50ZXIpPVwiZHJhZ0VudGVyKCRldmVudClcIlxyXG4gIChkcmFnb3Zlcik9XCJkcmFnT3ZlcigkZXZlbnQpXCJcclxuICAoZHJhZ2xlYXZlKT1cImRyYWdMZWF2ZSgkZXZlbnQpXCJcclxuICAoZHJvcCk9XCJkcm9wKCRldmVudClcIlxyXG4+XHJcbiAgPHRhYmxlXHJcbiAgICBbaWRdPVwiaWRcIlxyXG4gICAgI3RhYmxlXHJcbiAgICBbbmdDbGFzc109XCJ0YWJsZUNsYXNzID09PSBudWxsIHx8IHRhYmxlQ2xhc3MgPT09ICcnID8gJ25neC10YWJsZScgOiB0YWJsZUNsYXNzXCJcclxuICAgIFtjbGFzcy5uZ3gtdGFibGVfX3RhYmxlLS10aW55XT1cImNvbmZpZy50YWJsZUxheW91dC5zdHlsZSA9PT0gJ3RpbnknXCJcclxuICAgIFtjbGFzcy5uZ3gtdGFibGVfX3RhYmxlLS1ub3JtYWxdPVwiY29uZmlnLnRhYmxlTGF5b3V0LnN0eWxlID09PSAnbm9ybWFsJ1wiXHJcbiAgICBbY2xhc3Mubmd4LXRhYmxlX190YWJsZS0tYmlnXT1cImNvbmZpZy50YWJsZUxheW91dC5zdHlsZSA9PT0gJ2JpZydcIlxyXG4gICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtLWJvcmRlcmxlc3NdPVwiY29uZmlnLnRhYmxlTGF5b3V0LmJvcmRlcmxlc3NcIlxyXG4gICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtLWRhcmtdPVwiY29uZmlnLnRhYmxlTGF5b3V0LnRoZW1lID09PSAnZGFyaydcIlxyXG4gICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtLWhvdmVyYWJsZV09XCJjb25maWcudGFibGVMYXlvdXQuaG92ZXJcIlxyXG4gICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtLXN0cmlwZWRdPVwiY29uZmlnLnRhYmxlTGF5b3V0LnN0cmlwZWRcIlxyXG4gICAgW2NsYXNzLm5neC10YWJsZV9faG9yaXpvbnRhbC1zY3JvbGxdPVwiY29uZmlnLmhvcml6b250YWxTY3JvbGwgJiYgIWNvbmZpZy5pc0xvYWRpbmdcIlxyXG4gID5cclxuICAgIDx0aGVhZFxyXG4gICAgICBbY2xhc3Mubmd4LWluZmluaXRlLXNjcm9sbC12aWV3cG9ydC10aGVhZF09XCJjb25maWcuaW5maW5pdGVTY3JvbGxcIlxyXG4gICAgICB0YWJsZS10aGVhZFxyXG4gICAgICBbY29uZmlnXT1cImNvbmZpZ1wiXHJcbiAgICAgIFtzb3J0S2V5XT1cInNvcnRLZXlcIlxyXG4gICAgICBbc29ydFN0YXRlXT1cInNvcnRTdGF0ZVwiXHJcbiAgICAgIFtzZWxlY3RBbGxUZW1wbGF0ZV09XCJzZWxlY3RBbGxUZW1wbGF0ZVwiXHJcbiAgICAgIFtmaWx0ZXJzVGVtcGxhdGVdPVwiZmlsdGVyc1RlbXBsYXRlXCJcclxuICAgICAgW2FkZGl0aW9uYWxBY3Rpb25zVGVtcGxhdGVdPVwiYWRkaXRpb25hbEFjdGlvbnNUZW1wbGF0ZVwiXHJcbiAgICAgIFtjb2x1bW5zXT1cImNvbHVtbnNcIlxyXG4gICAgICAoc2VsZWN0QWxsKT1cIm9uU2VsZWN0QWxsKClcIlxyXG4gICAgICAoZmlsdGVyKT1cIm9uU2VhcmNoKCRldmVudClcIlxyXG4gICAgICAob3JkZXIpPVwib3JkZXJCeSgkZXZlbnQpXCJcclxuICAgICAgKGV2ZW50KT1cImVtaXRFdmVudCgkZXZlbnQuZXZlbnQsICRldmVudC52YWx1ZSlcIlxyXG4gICAgPjwvdGhlYWQ+XHJcbiAgICA8dGJvZHkgKm5nSWY9XCJkYXRhICYmICFjb25maWcuaXNMb2FkaW5nICYmICFjb25maWcucm93UmVvcmRlclwiPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicm93VGVtcGxhdGVcIj5cclxuICAgICAgICA8dWxcclxuICAgICAgICAgIGNsYXNzPVwibmd4LXRhYmxlX190YWJsZS1yb3ctY29udGV4dC1tZW51XCJcclxuICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXHJcbiAgICAgICAgICAgIHRvcDogcm93Q29udGV4dE1lbnVQb3NpdGlvbi50b3AsXHJcbiAgICAgICAgICAgIGxlZnQ6IHJvd0NvbnRleHRNZW51UG9zaXRpb24ubGVmdFxyXG4gICAgICAgICAgfVwiXHJcbiAgICAgICAgICAqbmdJZj1cInJvd0NvbnRleHRNZW51UG9zaXRpb24udG9wXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInJvd0NvbnRleHRNZW51XCJcclxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3dDb250ZXh0TWVudVBvc2l0aW9uLnZhbHVlIH1cIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC91bD5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNvbmZpZy5pbmZpbml0ZVNjcm9sbFwiPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAqbmdGb3I9XCJcclxuICAgICAgICAgICAgICBsZXQgcm93IG9mIGRhdGFcclxuICAgICAgICAgICAgICAgIHwgc29ydDogc29ydEJ5XHJcbiAgICAgICAgICAgICAgICB8IHNlYXJjaDogdGVybTpmaWx0ZXJlZENvdW50U3ViamVjdFxyXG4gICAgICAgICAgICAgICAgfCBnbG9iYWw6IGdsb2JhbFNlYXJjaFRlcm06ZmlsdGVyZWRDb3VudFN1YmplY3RcclxuICAgICAgICAgICAgICAgIHwgcGFnaW5hdGU6IHsgaXRlbXNQZXJQYWdlOiBsaW1pdCwgY3VycmVudFBhZ2U6IHBhZ2UsIHRvdGFsSXRlbXM6IGNvdW50LCBpZDogaWQgfVxyXG4gICAgICAgICAgICBcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8dHJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwib25DbGljaygkZXZlbnQsIHJvdywgJycsIG51bGwsIGRhdGEuaW5kZXhPZihyb3cpKVwiXHJcbiAgICAgICAgICAgICAgI2NvbnRleHRNZW51XHJcbiAgICAgICAgICAgICAgKGNvbnRleHRtZW51KT1cIm9uUm93Q29udGV4dE1lbnUoJGV2ZW50LCByb3csICcnLCBudWxsLCBkYXRhLmluZGV4T2Yocm93KSlcIlxyXG4gICAgICAgICAgICAgIChkYmxjbGljayk9XCJvbkRvdWJsZUNsaWNrKCRldmVudCwgcm93LCAnJywgbnVsbCwgZGF0YS5pbmRleE9mKHJvdykpXCJcclxuICAgICAgICAgICAgICBbY2xhc3Mubmd4LXRhYmxlX190YWJsZS1yb3ctLXNlbGVjdGVkXT1cIlxyXG4gICAgICAgICAgICAgICAgZGF0YS5pbmRleE9mKHJvdykgPT09IHNlbGVjdGVkUm93ICYmICFjb25maWcuc2VsZWN0Q2VsbFxyXG4gICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJyb3dUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IHJvdywgaW5kZXg6IGRhdGEuaW5kZXhPZihyb3cpIH1cIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJjb25maWcuZGV0YWlsc1RlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhblxyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cIm5neC1pY29uXCJcclxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJhcnJvd0RlZmluaXRpb25cIlxyXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJcclxuICAgICAgICAgICAgICAgICAgICBpc1Jvd0NvbGxhcHNlZChkYXRhLmluZGV4T2Yocm93KSlcclxuICAgICAgICAgICAgICAgICAgICAgID8gJ25neC1pY29uLWFycm93LWRvd24nXHJcbiAgICAgICAgICAgICAgICAgICAgICA6ICduZ3gtaWNvbi1hcnJvdy1yaWdodCdcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbGxhcHNlUm93KGRhdGEuaW5kZXhPZihyb3cpKVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPHRyXHJcbiAgICAgICAgICAgICAgKm5nSWY9XCJcclxuICAgICAgICAgICAgICAgIChjb25maWcuZGV0YWlsc1RlbXBsYXRlICYmIHNlbGVjdGVkRGV0YWlsc1RlbXBsYXRlUm93SWQuaGFzKGRhdGEuaW5kZXhPZihyb3cpKSkgfHxcclxuICAgICAgICAgICAgICAgIGNvbmZpZy5jb2xsYXBzZUFsbFJvd3NcclxuICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29sdW1ucy5sZW5ndGggKyAxXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRldGFpbHNUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogcm93LCBpbmRleDogZGF0YS5pbmRleE9mKHJvdykgfVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFxyXG4gICAgICAgICAgaXRlbVNpemU9XCI1MFwiXHJcbiAgICAgICAgICAqbmdJZj1cImNvbmZpZy5pbmZpbml0ZVNjcm9sbFwiXHJcbiAgICAgICAgICBjbGFzcz1cIm5neC1pbmZpbml0ZS1zY3JvbGwtdmlld3BvcnRcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgKmNka1ZpcnR1YWxGb3I9XCJcclxuICAgICAgICAgICAgICBsZXQgcm93IG9mIGRhdGFcclxuICAgICAgICAgICAgICAgIHwgc29ydDogc29ydEJ5XHJcbiAgICAgICAgICAgICAgICB8IHNlYXJjaDogdGVybTpmaWx0ZXJlZENvdW50U3ViamVjdFxyXG4gICAgICAgICAgICAgICAgfCBnbG9iYWw6IGdsb2JhbFNlYXJjaFRlcm06ZmlsdGVyZWRDb3VudFN1YmplY3Q7XHJcbiAgICAgICAgICAgICAgbGV0IHJvd0luZGV4ID0gaW5kZXhcclxuICAgICAgICAgICAgXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPHRyXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2soJGV2ZW50LCByb3csICcnLCBudWxsLCByb3dJbmRleClcIlxyXG4gICAgICAgICAgICAgICNjb250ZXh0TWVudVxyXG4gICAgICAgICAgICAgIChjb250ZXh0bWVudSk9XCJvblJvd0NvbnRleHRNZW51KCRldmVudCwgcm93LCAnJywgbnVsbCwgcm93SW5kZXgpXCJcclxuICAgICAgICAgICAgICAoZGJsY2xpY2spPVwib25Eb3VibGVDbGljaygkZXZlbnQsIHJvdywgJycsIG51bGwsIHJvd0luZGV4KVwiXHJcbiAgICAgICAgICAgICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtcm93LS1zZWxlY3RlZF09XCJcclxuICAgICAgICAgICAgICAgIHJvd0luZGV4ID09PSBzZWxlY3RlZFJvdyAmJiAhY29uZmlnLnNlbGVjdENlbGxcclxuICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwicm93VGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3csIGluZGV4OiByb3dJbmRleCB9XCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiY29uZmlnLmRldGFpbHNUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW5cclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJuZ3gtaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYXJyb3dEZWZpbml0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgaXNSb3dDb2xsYXBzZWQocm93SW5kZXgpID8gJ25neC1pY29uLWFycm93LWRvd24nIDogJ25neC1pY29uLWFycm93LXJpZ2h0J1xyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29sbGFwc2VSb3cocm93SW5kZXgpXCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICA8dHJcclxuICAgICAgICAgICAgICAqbmdJZj1cIlxyXG4gICAgICAgICAgICAgICAgKGNvbmZpZy5kZXRhaWxzVGVtcGxhdGUgJiYgc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5oYXMocm93SW5kZXgpKSB8fFxyXG4gICAgICAgICAgICAgICAgY29uZmlnLmNvbGxhcHNlQWxsUm93c1xyXG4gICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJjb2x1bW5zLmxlbmd0aCArIDFcIj5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiZGV0YWlsc1RlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3csIGluZGV4OiByb3dJbmRleCB9XCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydD5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcm93VGVtcGxhdGUgJiYgIWNvbmZpZy5ncm91cFJvd3NcIj5cclxuICAgICAgICA8dWxcclxuICAgICAgICAgIGNsYXNzPVwibmd4LXRhYmxlX190YWJsZS1yb3ctY29udGV4dC1tZW51XCJcclxuICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXHJcbiAgICAgICAgICAgIHRvcDogcm93Q29udGV4dE1lbnVQb3NpdGlvbi50b3AsXHJcbiAgICAgICAgICAgIGxlZnQ6IHJvd0NvbnRleHRNZW51UG9zaXRpb24ubGVmdFxyXG4gICAgICAgICAgfVwiXHJcbiAgICAgICAgICAqbmdJZj1cInJvd0NvbnRleHRNZW51UG9zaXRpb24udG9wXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInJvd0NvbnRleHRNZW51XCJcclxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3dDb250ZXh0TWVudVBvc2l0aW9uLnZhbHVlIH1cIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC91bD5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNvbmZpZy5pbmZpbml0ZVNjcm9sbFwiPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAqbmdGb3I9XCJcclxuICAgICAgICAgICAgICBsZXQgcm93IG9mIGRhdGFcclxuICAgICAgICAgICAgICAgIHwgc29ydDogc29ydEJ5XHJcbiAgICAgICAgICAgICAgICB8IHNlYXJjaDogdGVybTpmaWx0ZXJlZENvdW50U3ViamVjdFxyXG4gICAgICAgICAgICAgICAgfCBnbG9iYWw6IGdsb2JhbFNlYXJjaFRlcm06ZmlsdGVyZWRDb3VudFN1YmplY3RcclxuICAgICAgICAgICAgICAgIHwgcGFnaW5hdGU6IHsgaXRlbXNQZXJQYWdlOiBsaW1pdCwgY3VycmVudFBhZ2U6IHBhZ2UsIHRvdGFsSXRlbXM6IGNvdW50LCBpZDogaWQgfVxyXG4gICAgICAgICAgICBcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8dHJcclxuICAgICAgICAgICAgICBbY2xhc3Mubmd4LXRhYmxlX190YWJsZS1yb3ctLXNlbGVjdGVkXT1cIlxyXG4gICAgICAgICAgICAgICAgZGF0YS5pbmRleE9mKHJvdykgPT09IHNlbGVjdGVkUm93ICYmICFjb25maWcuc2VsZWN0Q2VsbFxyXG4gICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJjb25maWcuY2hlY2tib3hlc1wiPlxyXG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZvcm0tY2hlY2tib3hcIj5cclxuICAgICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcclxuICAgICAgICAgICAgICAgICAgICBpZD1cImNoZWNrYm94LXt7IGRhdGEuaW5kZXhPZihyb3cpIH19XCJcclxuICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJpc1NlbGVjdGVkIHx8IHNlbGVjdGVkQ2hlY2tib3hlcy5oYXMoZGF0YS5pbmRleE9mKHJvdykpXCJcclxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hlY2tib3hTZWxlY3QoJGV2ZW50LCByb3csIGRhdGEuaW5kZXhPZihyb3cpKVwiXHJcbiAgICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICAgIDxlbSBjbGFzcz1cIm5neC1mb3JtLWljb25cIj48L2VtPlxyXG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgIDx0ZCAqbmdJZj1cImNvbmZpZy5yYWRpb1wiPlxyXG4gICAgICAgICAgICAgICAgPGxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgIGlkPVwicmFkaW8te3sgZGF0YS5pbmRleE9mKHJvdykgfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJyYWRpb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvblJhZGlvU2VsZWN0KCRldmVudCwgcm93LCBkYXRhLmluZGV4T2Yocm93KSlcIlxyXG4gICAgICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zOyBsZXQgY29sSW5kZXggPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgPHRkXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkNsaWNrKCRldmVudCwgcm93LCBjb2x1bW4ua2V5LCBjb2xJbmRleCwgZGF0YS5pbmRleE9mKHJvdykpXCJcclxuICAgICAgICAgICAgICAgICAgI2NvbnRleHRNZW51XHJcbiAgICAgICAgICAgICAgICAgIChjb250ZXh0bWVudSk9XCJcclxuICAgICAgICAgICAgICAgICAgICBvblJvd0NvbnRleHRNZW51KCRldmVudCwgcm93LCBjb2x1bW4ua2V5LCBjb2xJbmRleCwgZGF0YS5pbmRleE9mKHJvdykpXHJcbiAgICAgICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJvbkRvdWJsZUNsaWNrKCRldmVudCwgcm93LCBjb2x1bW4ua2V5LCBjb2xJbmRleCwgZGF0YS5pbmRleE9mKHJvdykpXCJcclxuICAgICAgICAgICAgICAgICAgW2NsYXNzLnBpbm5lZC1sZWZ0XT1cImNvbHVtbi5waW5uZWRcIlxyXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjb2x1bW4uY3NzQ2xhc3MgPyBjb2x1bW4uY3NzQ2xhc3MubmFtZSA6ICcnXCJcclxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmxlZnRdPVwic3R5bGVTZXJ2aWNlLnBpbm5lZFdpZHRoKGNvbHVtbi5waW5uZWQsIGNvbEluZGV4KVwiXHJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5uZ3gtdGFibGVfX3RhYmxlLWNvbC0tc2VsZWN0ZWRdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgY29sSW5kZXggPT09IHNlbGVjdGVkQ29sICYmICFjb25maWcuc2VsZWN0Q2VsbFxyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICBbY2xhc3Mubmd4LXRhYmxlX190YWJsZS1jZWxsLS1zZWxlY3RlZF09XCJcclxuICAgICAgICAgICAgICAgICAgICBjb2xJbmRleCA9PT0gc2VsZWN0ZWRDb2wgJiZcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLmluZGV4T2Yocm93KSA9PT0gc2VsZWN0ZWRSb3cgJiZcclxuICAgICAgICAgICAgICAgICAgICAhY29uZmlnLnNlbGVjdENvbCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICFjb25maWcuc2VsZWN0Um93XHJcbiAgICAgICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhY29sdW1uLmNlbGxUZW1wbGF0ZVwiPnt7IHJvdyB8IHJlbmRlcjogY29sdW1uLmtleSB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW4uY2VsbFRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4uY2VsbFRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICByb3dJbmRleDogZGF0YS5pbmRleE9mKHJvdyksXHJcbiAgICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJjb25maWcuYWRkaXRpb25hbEFjdGlvbnMgfHwgY29uZmlnLmRldGFpbHNUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW5cclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJuZ3gtaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYXJyb3dEZWZpbml0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgaXNSb3dDb2xsYXBzZWQoZGF0YS5pbmRleE9mKHJvdykpXHJcbiAgICAgICAgICAgICAgICAgICAgICA/ICduZ3gtaWNvbi1hcnJvdy1kb3duJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgOiAnbmd4LWljb24tYXJyb3ctcmlnaHQnXHJcbiAgICAgICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb2xsYXBzZVJvdyhkYXRhLmluZGV4T2Yocm93KSlcIlxyXG4gICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDx0clxyXG4gICAgICAgICAgICAgICpuZ0lmPVwiXHJcbiAgICAgICAgICAgICAgICAoY29uZmlnLmRldGFpbHNUZW1wbGF0ZSAmJiBzZWxlY3RlZERldGFpbHNUZW1wbGF0ZVJvd0lkLmhhcyhkYXRhLmluZGV4T2Yocm93KSkpIHx8XHJcbiAgICAgICAgICAgICAgICBjb25maWcuY29sbGFwc2VBbGxSb3dzXHJcbiAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgIDx0ZCAqbmdJZj1cImNvbmZpZy5jaGVja2JveGVzIHx8IGNvbmZpZy5yYWRpb1wiPjwvdGQ+XHJcbiAgICAgICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29sdW1ucy5sZW5ndGggKyAxXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRldGFpbHNUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogcm93LCBpbmRleDogZGF0YS5pbmRleE9mKHJvdykgfVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPCEtLSBpbmZpbml0ZSBzY3JvbGwgLS0+XHJcbiAgICAgICAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFxyXG4gICAgICAgICAgaXRlbVNpemU9XCI1MFwiXHJcbiAgICAgICAgICAqbmdJZj1cImNvbmZpZy5pbmZpbml0ZVNjcm9sbFwiXHJcbiAgICAgICAgICBjbGFzcz1cIm5neC1pbmZpbml0ZS1zY3JvbGwtdmlld3BvcnRcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgKmNka1ZpcnR1YWxGb3I9XCJcclxuICAgICAgICAgICAgICBsZXQgcm93IG9mIGRhdGFcclxuICAgICAgICAgICAgICAgIHwgc29ydDogc29ydEJ5XHJcbiAgICAgICAgICAgICAgICB8IHNlYXJjaDogdGVybTpmaWx0ZXJlZENvdW50U3ViamVjdFxyXG4gICAgICAgICAgICAgICAgfCBnbG9iYWw6IGdsb2JhbFNlYXJjaFRlcm06ZmlsdGVyZWRDb3VudFN1YmplY3Q7XHJcbiAgICAgICAgICAgICAgbGV0IHJvd0luZGV4ID0gaW5kZXhcclxuICAgICAgICAgICAgXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPHRyXHJcbiAgICAgICAgICAgICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtcm93LS1zZWxlY3RlZF09XCJcclxuICAgICAgICAgICAgICAgIHJvd0luZGV4ID09PSBzZWxlY3RlZFJvdyAmJiAhY29uZmlnLnNlbGVjdENlbGxcclxuICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiY29uZmlnLmNoZWNrYm94ZXNcIiB3aWR0aD1cIjMlXCI+XHJcbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZm9ybS1jaGVja2JveFwiPlxyXG4gICAgICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgICAgICAgIGlkPVwiY2hlY2tib3gtaW5maW5pdGUtc2Nyb2xsLXt7IHJvd0luZGV4IH19XCJcclxuICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJpc1NlbGVjdGVkIHx8IHNlbGVjdGVkQ2hlY2tib3hlcy5oYXMocm93SW5kZXgpXCJcclxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hlY2tib3hTZWxlY3QoJGV2ZW50LCByb3csIHJvd0luZGV4KVwiXHJcbiAgICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICAgIDxlbSBjbGFzcz1cIm5neC1mb3JtLWljb25cIj48L2VtPlxyXG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgIDx0ZCAqbmdJZj1cImNvbmZpZy5yYWRpb1wiIHdpZHRoPVwiMyVcIj5cclxuICAgICAgICAgICAgICAgIDxsYWJlbD5cclxuICAgICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcclxuICAgICAgICAgICAgICAgICAgICBpZD1cInJhZGlvLWluZmluaXRlLXNjcm9sbC17eyByb3dJbmRleCB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInJhZGlvXCJcclxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUmFkaW9TZWxlY3QoJGV2ZW50LCByb3csIHJvd0luZGV4KVwiXHJcbiAgICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnM7IGxldCBjb2xJbmRleCA9IGluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICA8dGRcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2soJGV2ZW50LCByb3csIGNvbHVtbi5rZXksIGNvbEluZGV4LCByb3dJbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICAjY29udGV4dE1lbnVcclxuICAgICAgICAgICAgICAgICAgKGNvbnRleHRtZW51KT1cIm9uUm93Q29udGV4dE1lbnUoJGV2ZW50LCByb3csIGNvbHVtbi5rZXksIGNvbEluZGV4LCByb3dJbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICAoZGJsY2xpY2spPVwib25Eb3VibGVDbGljaygkZXZlbnQsIHJvdywgY29sdW1uLmtleSwgY29sSW5kZXgsIHJvd0luZGV4KVwiXHJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5waW5uZWQtbGVmdF09XCJjb2x1bW4ucGlubmVkXCJcclxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29sdW1uLmNzc0NsYXNzID8gY29sdW1uLmNzc0NsYXNzLm5hbWUgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5sZWZ0XT1cInN0eWxlU2VydmljZS5waW5uZWRXaWR0aChjb2x1bW4ucGlubmVkLCBjb2xJbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICBbY2xhc3Mubmd4LXRhYmxlX190YWJsZS1jb2wtLXNlbGVjdGVkXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbEluZGV4ID09PSBzZWxlY3RlZENvbCAmJiAhY29uZmlnLnNlbGVjdENlbGxcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtY2VsbC0tc2VsZWN0ZWRdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgY29sSW5kZXggPT09IHNlbGVjdGVkQ29sICYmXHJcbiAgICAgICAgICAgICAgICAgICAgcm93SW5kZXggPT09IHNlbGVjdGVkUm93ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgIWNvbmZpZy5zZWxlY3RDb2wgJiZcclxuICAgICAgICAgICAgICAgICAgICAhY29uZmlnLnNlbGVjdFJvd1xyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNvbHVtbi5jZWxsVGVtcGxhdGVcIj57eyByb3cgfCByZW5kZXI6IGNvbHVtbi5rZXkgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sdW1uLmNlbGxUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sdW1uLmNlbGxUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICRpbXBsaWNpdDogcm93LFxyXG4gICAgICAgICAgICAgICAgICAgICAgcm93SW5kZXg6IHJvd0luZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgICAgY29sdW1uOiBjb2x1bW5cclxuICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiY29uZmlnLmFkZGl0aW9uYWxBY3Rpb25zIHx8IGNvbmZpZy5kZXRhaWxzVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICAgIDxzcGFuXHJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwibmd4LWljb25cIlxyXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImFycm93RGVmaW5pdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgIGlzUm93Q29sbGFwc2VkKHJvd0luZGV4KSA/ICduZ3gtaWNvbi1hcnJvdy1kb3duJyA6ICduZ3gtaWNvbi1hcnJvdy1yaWdodCdcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbGxhcHNlUm93KHJvd0luZGV4KVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPHRyXHJcbiAgICAgICAgICAgICAgKm5nSWY9XCJcclxuICAgICAgICAgICAgICAgIChjb25maWcuZGV0YWlsc1RlbXBsYXRlICYmIHNlbGVjdGVkRGV0YWlsc1RlbXBsYXRlUm93SWQuaGFzKHJvd0luZGV4KSkgfHxcclxuICAgICAgICAgICAgICAgIGNvbmZpZy5jb2xsYXBzZUFsbFJvd3NcclxuICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiY29uZmlnLmNoZWNrYm94ZXMgfHwgY29uZmlnLnJhZGlvXCI+PC90ZD5cclxuICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJjb2x1bW5zLmxlbmd0aCArIDFcIj5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiZGV0YWlsc1RlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3csIGluZGV4OiByb3dJbmRleCB9XCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydD5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcm93VGVtcGxhdGUgJiYgY29uZmlnLmdyb3VwUm93c1wiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICpuZ0Zvcj1cIlxyXG4gICAgICAgICAgICBsZXQgZ3JvdXAgb2YgZ3JvdXBlZFxyXG4gICAgICAgICAgICAgIHwgc29ydDogc29ydEJ5OmNvbmZpZ1xyXG4gICAgICAgICAgICAgIHwgc2VhcmNoOiB0ZXJtOmZpbHRlcmVkQ291bnRTdWJqZWN0OmNvbmZpZ1xyXG4gICAgICAgICAgICAgIHwgZ2xvYmFsOiBnbG9iYWxTZWFyY2hUZXJtOmZpbHRlcmVkQ291bnRTdWJqZWN0XHJcbiAgICAgICAgICAgICAgfCBwYWdpbmF0ZTogeyBpdGVtc1BlclBhZ2U6IGxpbWl0LCBjdXJyZW50UGFnZTogcGFnZSwgdG90YWxJdGVtczogY291bnQsIGlkOiBpZCB9O1xyXG4gICAgICAgICAgICBsZXQgcm93SW5kZXggPSBpbmRleFxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhZ3JvdXBSb3dzSGVhZGVyVGVtcGxhdGVcIj5cclxuICAgICAgICAgICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJjb2x1bW5zLmxlbmd0aFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdj57eyBncm91cFswXVtncm91cFJvd3NCeV0gfX0gKHt7IGdyb3VwLmxlbmd0aCB9fSk8L2Rpdj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICpuZ0lmPVwiZ3JvdXBSb3dzSGVhZGVyVGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdyb3VwUm93c0hlYWRlclRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xyXG4gICAgICAgICAgICAgICAgdG90YWw6IGdyb3VwLmxlbmd0aCxcclxuICAgICAgICAgICAgICAgIGtleTogZ3JvdXBSb3dzQnksXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogZ3JvdXBbMF0gPyBncm91cFswXVtncm91cFJvd3NCeV0gOiAnJyxcclxuICAgICAgICAgICAgICAgIGdyb3VwOiBncm91cCxcclxuICAgICAgICAgICAgICAgIGluZGV4OiByb3dJbmRleFxyXG4gICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgPHNwYW5cclxuICAgICAgICAgICAgICAgIGNsYXNzPVwibmd4LWljb25cIlxyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJhcnJvd0RlZmluaXRpb25cIlxyXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiXHJcbiAgICAgICAgICAgICAgICAgIGlzUm93Q29sbGFwc2VkKHJvd0luZGV4KSA/ICduZ3gtaWNvbi1hcnJvdy1kb3duJyA6ICduZ3gtaWNvbi1hcnJvdy1yaWdodCdcclxuICAgICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29sbGFwc2VSb3cocm93SW5kZXgpXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgPC90cj5cclxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZERldGFpbHNUZW1wbGF0ZVJvd0lkLmhhcyhyb3dJbmRleClcIj5cclxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgZ3JvdXBcIj5cclxuICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zXCI+XHJcbiAgICAgICAgICAgICAgICB7eyByb3cgfCByZW5kZXI6IGNvbHVtbi5rZXkgfX1cclxuICAgICAgICAgICAgICAgIDwhLS0gVE9ETyBhbGxvdyB1c2VycyB0byBhZGQgZ3JvdXBSb3dzVGVtcGxhdGVSZWYgLS0+XHJcbiAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICA8dGQ+PC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvdGJvZHk+XHJcbiAgICA8dGJvZHlcclxuICAgICAgKm5nSWY9XCJkYXRhICYmICFjb25maWcuaXNMb2FkaW5nICYmIGNvbmZpZy5yb3dSZW9yZGVyXCJcclxuICAgICAgY2xhc3M9XCJuZ3gtZHJhZ2dhYmxlLXJvdy1hcmVhXCJcclxuICAgICAgY2RrRHJvcExpc3RcclxuICAgICAgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJvbkRyb3AoJGV2ZW50KVwiXHJcbiAgICA+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcm93VGVtcGxhdGUgJiYgIWNvbmZpZy5ncm91cFJvd3NcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAqbmdGb3I9XCJcclxuICAgICAgICAgICAgbGV0IHJvdyBvZiBkYXRhXHJcbiAgICAgICAgICAgICAgfCBzb3J0OiBzb3J0QnlcclxuICAgICAgICAgICAgICB8IHNlYXJjaDogdGVybTpmaWx0ZXJlZENvdW50U3ViamVjdFxyXG4gICAgICAgICAgICAgIHwgZ2xvYmFsOiBnbG9iYWxTZWFyY2hUZXJtOmZpbHRlcmVkQ291bnRTdWJqZWN0XHJcbiAgICAgICAgICAgICAgfCBwYWdpbmF0ZTogeyBpdGVtc1BlclBhZ2U6IGxpbWl0LCBjdXJyZW50UGFnZTogcGFnZSwgdG90YWxJdGVtczogY291bnQsIGlkOiBpZCB9XHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDx0clxyXG4gICAgICAgICAgICBjbGFzcz1cIm5neC1kcmFnZ2FibGUtcm93XCJcclxuICAgICAgICAgICAgY2RrRHJhZ1xyXG4gICAgICAgICAgICAoY2RrRHJhZ1N0YXJ0ZWQpPVwib25EcmFnU3RhcnQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIFtjZGtEcmFnU3RhcnREZWxheV09XCJjb25maWcucmVvcmRlckRlbGF5IHx8IDBcIlxyXG4gICAgICAgICAgICBjZGtEcmFnTG9ja0F4aXM9XCJ5XCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiY29uZmlnLmNoZWNrYm94ZXNcIj5cclxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZm9ybS1jaGVja2JveFwiPlxyXG4gICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXHJcbiAgICAgICAgICAgICAgICAgIGlkPVwiY2hlY2tib3gtZHJhZ2dhYmxlLXt7IGRhdGEuaW5kZXhPZihyb3cpIH19XCJcclxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiaXNTZWxlY3RlZCB8fCBzZWxlY3RlZENoZWNrYm94ZXMuaGFzKGRhdGEuaW5kZXhPZihyb3cpKVwiXHJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25DaGVja2JveFNlbGVjdCgkZXZlbnQsIHJvdywgZGF0YS5pbmRleE9mKHJvdykpXCJcclxuICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICA8ZW0gY2xhc3M9XCJuZ3gtZm9ybS1pY29uXCI+PC9lbT5cclxuICAgICAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJjb25maWcucmFkaW9cIj5cclxuICAgICAgICAgICAgICA8bGFiZWw+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcclxuICAgICAgICAgICAgICAgICAgaWQ9XCJyYWRpby1kcmFnZ2FibGUte3sgZGF0YS5pbmRleE9mKHJvdykgfX1cIlxyXG4gICAgICAgICAgICAgICAgICBuYW1lPVwicmFkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUmFkaW9TZWxlY3QoJGV2ZW50LCByb3csIGRhdGEuaW5kZXhPZihyb3cpKVwiXHJcbiAgICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zOyBsZXQgY29sSW5kZXggPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgIDx0ZFxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2soJGV2ZW50LCByb3csIGNvbHVtbi5rZXksIGNvbEluZGV4LCBkYXRhLmluZGV4T2Yocm93KSlcIlxyXG4gICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cIm9uRG91YmxlQ2xpY2soJGV2ZW50LCByb3csIGNvbHVtbi5rZXksIGNvbEluZGV4LCBkYXRhLmluZGV4T2Yocm93KSlcIlxyXG4gICAgICAgICAgICAgICAgW2NsYXNzLm5neC10YWJsZV9fdGFibGUtY29sLS1zZWxlY3RlZF09XCJcclxuICAgICAgICAgICAgICAgICAgY29sSW5kZXggPT09IHNlbGVjdGVkQ29sICYmICFjb25maWcuc2VsZWN0Q2VsbFxyXG4gICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgIFtjbGFzcy5uZ3gtdGFibGVfX3RhYmxlLWNlbGwtLXNlbGVjdGVkXT1cIlxyXG4gICAgICAgICAgICAgICAgICBjb2xJbmRleCA9PT0gc2VsZWN0ZWRDb2wgJiZcclxuICAgICAgICAgICAgICAgICAgZGF0YS5pbmRleE9mKHJvdykgPT09IHNlbGVjdGVkUm93ICYmXHJcbiAgICAgICAgICAgICAgICAgICFjb25maWcuc2VsZWN0Q29sICYmXHJcbiAgICAgICAgICAgICAgICAgICFjb25maWcuc2VsZWN0Um93XHJcbiAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhY29sdW1uLmNlbGxUZW1wbGF0ZVwiPnt7IHJvdyB8IHJlbmRlcjogY29sdW1uLmtleSB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbi5jZWxsVGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4uY2VsbFRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcclxuICAgICAgICAgICAgICAgICAgICAkaW1wbGljaXQ6IHJvdyxcclxuICAgICAgICAgICAgICAgICAgICByb3dJbmRleDogZGF0YS5pbmRleE9mKHJvdyksXHJcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uOiBjb2x1bW5cclxuICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC90Ym9keT5cclxuICAgIDx0Ym9keSAqbmdJZj1cImZpbHRlckNvdW50ID09PSAwXCI+XHJcbiAgICAgIDx0ciBjbGFzcz1cIm5neC10YWJsZV9fYm9keS1lbXB0eVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJub1Jlc3VsdHNUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5vUmVzdWx0c1RlbXBsYXRlXCI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29sdW1ucyAmJiBjb2x1bW5zLmxlbmd0aCArIDFcIiAqbmdJZj1cIiFub1Jlc3VsdHNUZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm5neC10YWJsZV9fdGFibGUtbm8tcmVzdWx0c1wiPk5vIHJlc3VsdHM8L2Rpdj5cclxuICAgICAgICA8L3RkPlxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90Ym9keT5cclxuICAgIDx0Ym9keSAqbmdJZj1cImNvbmZpZy5pc0xvYWRpbmdcIj5cclxuICAgICAgPHRyIGNsYXNzPVwibmd4LXRhYmxlX19ib2R5LWxvYWRpbmdcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZ1RlbXBsYXRlXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibG9hZGluZ1RlbXBsYXRlXCI+IDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnMgJiYgY29sdW1ucy5sZW5ndGggKyAxXCIgKm5nSWY9XCIhbG9hZGluZ1RlbXBsYXRlXCI+XHJcbiAgICAgICAgICA8ZGl2IFtzdHlsZS5oZWlnaHQucHhdPVwibG9hZGluZ0hlaWdodFwiIGNsYXNzPVwibmd4LXRhYmxlX190YWJsZS1sb2FkZXItd3JhcHBlclwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmd4LXRhYmxlX190YWJsZS1sb2FkZXJcIj48L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvdGQ+XHJcbiAgICAgIDwvdHI+XHJcbiAgICA8L3Rib2R5PlxyXG4gICAgPHRmb290ICpuZ0lmPVwic3VtbWFyeVRlbXBsYXRlXCI+XHJcbiAgICAgIDx0cj5cclxuICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJzdW1tYXJ5VGVtcGxhdGVcIlxyXG4gICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgdG90YWw6IGRhdGEubGVuZ3RoLCBsaW1pdDogbGltaXQsIHBhZ2U6IHBhZ2UgfVwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90Zm9vdD5cclxuICA8L3RhYmxlPlxyXG4gIDxwYWdpbmF0aW9uXHJcbiAgICBbYXR0ci5pZF09XCIncGFnaW5hdGlvbicgKyBpZFwiXHJcbiAgICBbaWRdPVwiaWRcIlxyXG4gICAgI3BhZ2luYXRpb25Db21wb25lbnRcclxuICAgIFtjb25maWddPVwiY29uZmlnXCJcclxuICAgIFtwYWdpbmF0aW9uXT1cInBhZ2luYXRpb25cIlxyXG4gICAgKHVwZGF0ZVJhbmdlKT1cIm9uUGFnaW5hdGlvbigkZXZlbnQpXCJcclxuICA+XHJcbiAgPC9wYWdpbmF0aW9uPlxyXG48L2Rpdj5cclxuIl19
|