cilog-lib 1.10.21 → 1.10.23
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/esm2022/cilog-lib.mjs +5 -0
- package/esm2022/lib/cilog-lib.component.mjs +22 -0
- package/esm2022/lib/cilog-lib.module.mjs +96 -0
- package/esm2022/lib/cilog-lib.service.mjs +14 -0
- package/esm2022/lib/helpers/enums/grille.enum.mjs +51 -0
- package/esm2022/lib/helpers/interfaces/edition.interface.mjs +2 -0
- package/esm2022/lib/helpers/interfaces/editor.interface.mjs +2 -0
- package/esm2022/lib/helpers/interfaces/grille.interface.mjs +2 -0
- package/esm2022/lib/helpers/interfaces/message.interface.mjs +2 -0
- package/esm2022/lib/helpers/pipes/value.pipe.mjs +27 -0
- package/esm2022/lib/modules/primeng.module.mjs +86 -0
- package/esm2022/lib/services/excel.service.mjs +184 -0
- package/esm2022/lib/services/message.service.mjs +30 -0
- package/esm2022/lib/services/table.service.mjs +14 -0
- package/esm2022/lib/views/cilog-input-number/cilog-input-number.component.mjs +251 -0
- package/esm2022/lib/views/documentation/documentation-contextuelle.component.mjs +156 -0
- package/esm2022/lib/views/editor/editor.component.mjs +38 -0
- package/esm2022/lib/views/message/message.component.mjs +77 -0
- package/esm2022/lib/views/table/table.component.mjs +675 -0
- package/esm2022/public-api.mjs +24 -0
- package/fesm2022/cilog-lib.mjs +103 -92
- package/fesm2022/cilog-lib.mjs.map +1 -1
- package/index.d.ts +5 -0
- package/lib/cilog-lib.component.d.ts +8 -0
- package/lib/cilog-lib.module.d.ts +21 -0
- package/lib/cilog-lib.service.d.ts +6 -0
- package/lib/helpers/enums/grille.enum.d.ts +44 -0
- package/lib/helpers/interfaces/edition.interface.d.ts +34 -0
- package/lib/helpers/interfaces/editor.interface.d.ts +4 -0
- package/lib/helpers/interfaces/grille.interface.d.ts +167 -0
- package/lib/helpers/interfaces/message.interface.d.ts +6 -0
- package/lib/helpers/pipes/value.pipe.d.ts +7 -0
- package/lib/modules/primeng.module.d.ts +24 -0
- package/lib/services/excel.service.d.ts +15 -0
- package/lib/services/message.service.d.ts +12 -0
- package/lib/services/table.service.d.ts +6 -0
- package/lib/views/cilog-input-number/cilog-input-number.component.d.ts +40 -0
- package/lib/views/documentation/documentation-contextuelle.component.d.ts +49 -0
- package/lib/views/editor/editor.component.d.ts +17 -0
- package/lib/views/message/message.component.d.ts +17 -0
- package/lib/views/table/table.component.d.ts +83 -0
- package/package.json +5 -3
- package/public-api.d.ts +15 -0
- package/types/cilog-lib.d.ts +0 -538
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
2
|
+
import { ColType, ModeSelection } from '../../helpers/enums/grille.enum';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "primeng/api";
|
|
5
|
+
import * as i2 from "../../services/excel.service";
|
|
6
|
+
import * as i3 from "@angular/common";
|
|
7
|
+
import * as i4 from "primeng/button";
|
|
8
|
+
import * as i5 from "primeng/table";
|
|
9
|
+
import * as i6 from "primeng/inputtext";
|
|
10
|
+
import * as i7 from "primeng/selectbutton";
|
|
11
|
+
import * as i8 from "primeng/dropdown";
|
|
12
|
+
import * as i9 from "primeng/inputnumber";
|
|
13
|
+
import * as i10 from "primeng/multiselect";
|
|
14
|
+
import * as i11 from "primeng/calendar";
|
|
15
|
+
import * as i12 from "primeng/contextmenu";
|
|
16
|
+
import * as i13 from "primeng/tooltip";
|
|
17
|
+
import * as i14 from "primeng/tag";
|
|
18
|
+
import * as i15 from "primeng/inputswitch";
|
|
19
|
+
import * as i16 from "@angular/forms";
|
|
20
|
+
import * as i17 from "../cilog-input-number/cilog-input-number.component";
|
|
21
|
+
import * as i18 from "../../helpers/pipes/value.pipe";
|
|
22
|
+
export class CilogTableComponent {
|
|
23
|
+
constructor(confirmationService, filterService, cdRef, exportService) {
|
|
24
|
+
this.confirmationService = confirmationService;
|
|
25
|
+
this.filterService = filterService;
|
|
26
|
+
this.cdRef = cdRef;
|
|
27
|
+
this.exportService = exportService;
|
|
28
|
+
this.initFilter = true;
|
|
29
|
+
this.columnsChange = new EventEmitter();
|
|
30
|
+
this.valuesChange = new EventEmitter();
|
|
31
|
+
this.onEdit = new EventEmitter();
|
|
32
|
+
this.onEditInit = new EventEmitter();
|
|
33
|
+
this.onDelete = new EventEmitter();
|
|
34
|
+
this.onSelect = new EventEmitter();
|
|
35
|
+
this.onUnselect = new EventEmitter();
|
|
36
|
+
this.onFilter = new EventEmitter();
|
|
37
|
+
this.onFilterInit = new EventEmitter();
|
|
38
|
+
this.onSort = new EventEmitter();
|
|
39
|
+
this.onPage = new EventEmitter();
|
|
40
|
+
this.onRowDoubleClick = new EventEmitter();
|
|
41
|
+
}
|
|
42
|
+
ngOnInit() {
|
|
43
|
+
this.optionsSwitch = [
|
|
44
|
+
{ label: 'Oui', value: true },
|
|
45
|
+
{ label: 'Non', value: false },
|
|
46
|
+
];
|
|
47
|
+
// Date
|
|
48
|
+
this.filterService.register('dateRangeFilter', (cell, filter) => {
|
|
49
|
+
if (filter == null) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
let start = filter[0].getTime();
|
|
53
|
+
let end;
|
|
54
|
+
let endDate;
|
|
55
|
+
if (filter[1]) {
|
|
56
|
+
endDate = new Date(filter[1].getFullYear(), filter[1].getMonth(), filter[1].getDate(), 23, 59, 59);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
endDate = new Date(filter[0].getFullYear(), filter[0].getMonth(), filter[0].getDate(), 23, 59, 59);
|
|
60
|
+
}
|
|
61
|
+
end = endDate.getTime();
|
|
62
|
+
return cell.value == null ? false : cell.value.getTime() >= start && cell.value.getTime() <= end;
|
|
63
|
+
});
|
|
64
|
+
// Objet
|
|
65
|
+
this.filterService.register('objetFilter', (cell, filter) => {
|
|
66
|
+
return filter.find(val => val.ID == cell.value?.ID) != null;
|
|
67
|
+
});
|
|
68
|
+
// Select Button
|
|
69
|
+
this.filterService.register('selectButtonFilter', (cell, filter) => {
|
|
70
|
+
return filter.find(val => val.value == cell.value) != null;
|
|
71
|
+
});
|
|
72
|
+
// Liste
|
|
73
|
+
this.filterService.register('listeFilter', (cell, filter) => {
|
|
74
|
+
let ok = false;
|
|
75
|
+
filter.forEach(val => {
|
|
76
|
+
if (cell.value.indexOf(val) != -1) {
|
|
77
|
+
ok = true;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return ok;
|
|
81
|
+
});
|
|
82
|
+
// Switch
|
|
83
|
+
this.filterService.register('switchFilter', (cell, filter) => {
|
|
84
|
+
return (filter.indexOf(cell.value) != -1);
|
|
85
|
+
});
|
|
86
|
+
// Button
|
|
87
|
+
this.filterService.register('buttonFilter', (cell, filter) => {
|
|
88
|
+
let filterObjField = cell.options['filterObjField'];
|
|
89
|
+
let filterObjSubField = cell.options['filterObjSubField'];
|
|
90
|
+
if (cell.obj == null || filter == null || filter.trim() == '' || filterObjField == null) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
if (filterObjSubField == null) {
|
|
94
|
+
return cell.obj[filterObjField].toLowerCase().includes(filter.toLowerCase());
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return cell.obj[filterObjField].find(val => val[filterObjSubField].toLowerCase().includes(filter.toLowerCase())) != null;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// Text
|
|
101
|
+
this.filterService.register('textFilter', (cell, filter) => {
|
|
102
|
+
if (filter == null || filter.trim() == '') {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
if (cell.value == null) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
let value;
|
|
109
|
+
if (typeof cell.value == 'string') {
|
|
110
|
+
value = cell.value;
|
|
111
|
+
}
|
|
112
|
+
else if (typeof cell.value == 'number') {
|
|
113
|
+
value = cell.value.toString().replace('.', ',');
|
|
114
|
+
}
|
|
115
|
+
else if (Array.isArray(cell.value)) {
|
|
116
|
+
if (cell.options == null || cell.options['optionLabelFilterText'] == null) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
value = this.getMultiSelectConcat(cell.value, cell.options['optionLabelFilterText']);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
if (cell.options == null || cell.options['optionLabelFilterText'] == null) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
value = cell.value[cell.options['optionLabelFilterText']];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (value == null) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
return value.toLowerCase().includes(filter.toLowerCase());
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
this.columns.forEach(col => {
|
|
139
|
+
if (col.options == null) {
|
|
140
|
+
col.options = { defaultFilters: null };
|
|
141
|
+
}
|
|
142
|
+
if (col.options['onlyListValues'] && col.options['optionGroupLabel'] == null) {
|
|
143
|
+
col.options['options'] = [];
|
|
144
|
+
this.values.forEach(val => {
|
|
145
|
+
if (col.type == ColType.MultiSelect) {
|
|
146
|
+
val[col.id].value.forEach(val2 => {
|
|
147
|
+
if (col.options['options'].find(opt => opt.ID == val2.ID) == null) {
|
|
148
|
+
col.options['options'].push(val2);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
else if (col.type == ColType.Dropdown) {
|
|
153
|
+
if (val[col.id].value != null && col.options['options'].find(opt => opt.ID == val[col.id].value.ID) == null) {
|
|
154
|
+
col.options['options'].push(val[col.id].value);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
col.options['options'] = [...col.options['options'].sort((a, b) => a[col.options['optionLabel']].localeCompare(a[col.options['optionLabel']]))];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
this.columnsChange.emit(this.columns);
|
|
162
|
+
if (this.columns.filter(col => col.options.defaultFilters != null).length == 0) {
|
|
163
|
+
this.initFilter = false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
ngAfterViewInit() {
|
|
167
|
+
this.columns.forEach(col => {
|
|
168
|
+
if (!col.invisible) {
|
|
169
|
+
if (col.options.defaultFilters != null) {
|
|
170
|
+
this.filter(col, col.options.defaultFilters, this.getFilterByCol(col));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
if (this.table.scroller && this.options.modeAppendOnly) {
|
|
175
|
+
this.table.scroller.appendOnly = true;
|
|
176
|
+
}
|
|
177
|
+
this.cdRef.detectChanges();
|
|
178
|
+
}
|
|
179
|
+
onFilterTable(event) {
|
|
180
|
+
if (this.initFilter == true) {
|
|
181
|
+
this.onFilterInit.emit(event.filteredValue);
|
|
182
|
+
this.initFilter = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
onInputNumber(event) {
|
|
186
|
+
}
|
|
187
|
+
loadLazy(event) {
|
|
188
|
+
//this.values = event.rows.slice(event.first, (event.first + event.rows));
|
|
189
|
+
}
|
|
190
|
+
// Sort
|
|
191
|
+
sortGrille(event) {
|
|
192
|
+
let col = this.columns.find(col => col.id == event.field);
|
|
193
|
+
this.onSort.emit({ column: col, order: event.order });
|
|
194
|
+
let typeCol = col.type;
|
|
195
|
+
event.data.sort((data1, data2) => {
|
|
196
|
+
let value1 = data1[event.field].value;
|
|
197
|
+
let value2 = data2[event.field].value;
|
|
198
|
+
if (col.options.customSort && col.options.sortFunction != null) {
|
|
199
|
+
return col.options.sortFunction({ column: col, order: event.order, value1: value1, value2: value2 });
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
let result = null;
|
|
203
|
+
if (value1 == null && value2 != null)
|
|
204
|
+
result = -1;
|
|
205
|
+
else if (value1 != null && value2 == null)
|
|
206
|
+
result = 1;
|
|
207
|
+
else if (value1 == null && value2 == null)
|
|
208
|
+
result = 0;
|
|
209
|
+
else if (typeCol == ColType.Text || typeCol == ColType.File)
|
|
210
|
+
result = value1.localeCompare(value2);
|
|
211
|
+
else if (typeCol == ColType.MultiSelect) {
|
|
212
|
+
if (value1[this.getOption(col, data1, 'optionLabel')] == null) {
|
|
213
|
+
result = -1;
|
|
214
|
+
}
|
|
215
|
+
else if (value2[this.getOption(col, data2, 'optionLabel')] == null) {
|
|
216
|
+
result = 1;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
result = this.getMultiSelectConcat(value1, this.getOption(col, data1, 'optionLabel')).localeCompare(this.getMultiSelectConcat(value2, this.getOption(col, data2, 'optionLabel')));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else if (typeCol == ColType.Dropdown || typeCol == ColType.SelectButton || typeCol == ColType.State) {
|
|
223
|
+
if (value1[this.getOption(col, data1, 'optionLabel')] == null) {
|
|
224
|
+
result = -1;
|
|
225
|
+
}
|
|
226
|
+
else if (value2[this.getOption(col, data2, 'optionLabel')] == null) {
|
|
227
|
+
result = 1;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
result = value1[this.getOption(col, data1, 'optionLabel')].localeCompare(value2[this.getOption(col, data2, 'optionLabel')]);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (typeCol == ColType.Number || typeCol == ColType.CilogNumber || typeCol == ColType.Date) {
|
|
234
|
+
result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
|
|
235
|
+
}
|
|
236
|
+
else if (typeCol == ColType.Switch)
|
|
237
|
+
result = (value1 === value2) ? 0 : value1 ? -1 : 1;
|
|
238
|
+
else
|
|
239
|
+
result == 0;
|
|
240
|
+
return (event.order * result);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
checkType(typeCol, col) {
|
|
245
|
+
return col['type'] == typeCol;
|
|
246
|
+
}
|
|
247
|
+
clickById(id) {
|
|
248
|
+
document.getElementById(id).click();
|
|
249
|
+
}
|
|
250
|
+
onEditCell(row, column, value) {
|
|
251
|
+
event.stopPropagation();
|
|
252
|
+
if (this.getOption(column, row, 'action') != null) {
|
|
253
|
+
this.getOption(column, row, 'action')();
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.onEdit.emit({ row: row, column: column, value: value });
|
|
257
|
+
}
|
|
258
|
+
// Destroy Focus
|
|
259
|
+
this.values.forEach(val => {
|
|
260
|
+
val[column.id].focus = false;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
onKeyDown(event, row, column, value) {
|
|
264
|
+
if (event.key == 'Enter') {
|
|
265
|
+
this.onEditCell(row, column, value);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
editMultiselect(row, column, event) {
|
|
269
|
+
this.onEditCell(row, column, { listSelected: event.value, itemSelected: event.itemValue, selected: event.value.indexOf(event.itemValue) != -1 });
|
|
270
|
+
}
|
|
271
|
+
onSelectAll(event) {
|
|
272
|
+
this.onSelect.emit({ row: null, selectedRows: this.selectedRows, checked: event.checked });
|
|
273
|
+
}
|
|
274
|
+
onSelectRow(row) {
|
|
275
|
+
this.onSelect.emit({ row: row, selectedRows: this.selectedRows, checked: true });
|
|
276
|
+
}
|
|
277
|
+
onSelectCell(cell) {
|
|
278
|
+
console.log(cell);
|
|
279
|
+
this.onSelect.emit({ cell: cell });
|
|
280
|
+
}
|
|
281
|
+
onUnselectRow(row) {
|
|
282
|
+
this.onUnselect.emit({ row: row, selectedRows: this.selectedRows, checked: false });
|
|
283
|
+
}
|
|
284
|
+
refreshData() {
|
|
285
|
+
if (this.options.sortable && this.options.virtualScroll) {
|
|
286
|
+
this.values = [...this.values];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
onPageTable(event) {
|
|
290
|
+
this.onPage.emit(event);
|
|
291
|
+
}
|
|
292
|
+
onDeleteLine(row) {
|
|
293
|
+
if (this.options.manuallyDeletable) {
|
|
294
|
+
this.onDelete.emit({ row: row });
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
this.confirmationService.confirm({
|
|
298
|
+
key: 'confirm',
|
|
299
|
+
message: 'Êtes-vous sûr de vouloir supprimer cette ligne ?',
|
|
300
|
+
accept: () => {
|
|
301
|
+
this.values.splice(this.values.indexOf(row), 1);
|
|
302
|
+
this.values = [...this.values];
|
|
303
|
+
this.valuesChange.emit(this.values);
|
|
304
|
+
this.onDelete.emit({ row: row });
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
onEditInitCell(event, row, column, value) {
|
|
310
|
+
event.target.select();
|
|
311
|
+
this.onEditInit.emit({ row: row, column: column, value: value });
|
|
312
|
+
}
|
|
313
|
+
onRowDoubleClickEvent(row) {
|
|
314
|
+
this.onRowDoubleClick.emit({ row: row });
|
|
315
|
+
}
|
|
316
|
+
getOption(col, row, option) {
|
|
317
|
+
if (row != null && row[col.id].options != null) {
|
|
318
|
+
if (row[col.id].options[option] != null) {
|
|
319
|
+
return row[col.id].options[option];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (col != null && col.options != null) {
|
|
323
|
+
if (col.options[option] != null) {
|
|
324
|
+
return col.options[option];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
getMultiSelectConcat(value, label) {
|
|
330
|
+
if (value != null) {
|
|
331
|
+
return value.map(val => { return val[label]; }).join(', ');
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
return '';
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
getSelectLibelleByValue(row, col) {
|
|
338
|
+
let label = '';
|
|
339
|
+
if (row[col.id].value == null) {
|
|
340
|
+
return label;
|
|
341
|
+
}
|
|
342
|
+
if (row[col.id].options != null) {
|
|
343
|
+
label = row[col.id].options['options'].find(opt => opt.value == row[col.id].value)[row[col.id].options.optionLabel];
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
if (col.options != null) {
|
|
347
|
+
label = col.options['options'].find(opt => opt.value == row[col.id].value)[col.options.optionLabel];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return label;
|
|
351
|
+
}
|
|
352
|
+
getFilterByCol(col) {
|
|
353
|
+
// Dates (range)
|
|
354
|
+
if (col.type == ColType.Date) {
|
|
355
|
+
return 'dateRangeFilter';
|
|
356
|
+
}
|
|
357
|
+
// Objet
|
|
358
|
+
if ((col.type == ColType.Dropdown && !col.options.filterText) || col.type == ColType.State) {
|
|
359
|
+
return 'objetFilter';
|
|
360
|
+
}
|
|
361
|
+
// Liste
|
|
362
|
+
if (col.type == ColType.MultiSelect && !col.options.filterText) {
|
|
363
|
+
return 'listeFilter';
|
|
364
|
+
}
|
|
365
|
+
// Texte
|
|
366
|
+
if (col.type == ColType.File
|
|
367
|
+
|| col.type == ColType.Text
|
|
368
|
+
|| col.type == ColType.Number
|
|
369
|
+
|| col.type == ColType.CilogNumber
|
|
370
|
+
|| (col.type == ColType.MultiSelect && col.options.filterText)
|
|
371
|
+
|| (col.type == ColType.Dropdown && col.options.filterText)) {
|
|
372
|
+
return 'textFilter';
|
|
373
|
+
}
|
|
374
|
+
// Switch
|
|
375
|
+
if (col.type == ColType.Switch) {
|
|
376
|
+
return 'switchFilter';
|
|
377
|
+
}
|
|
378
|
+
// Switch
|
|
379
|
+
if (col.type == ColType.SelectButton) {
|
|
380
|
+
return 'selectButtonFilter';
|
|
381
|
+
}
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
onFilterCol(event, col) {
|
|
385
|
+
let value;
|
|
386
|
+
// Dates (range)
|
|
387
|
+
if (col.type == ColType.Date) {
|
|
388
|
+
value = col.options.defaultFilters;
|
|
389
|
+
}
|
|
390
|
+
// Objet
|
|
391
|
+
if ((col.type == ColType.Dropdown && !col.options.filterText) || col.type == ColType.State) {
|
|
392
|
+
value = event == null ? null : event.value;
|
|
393
|
+
}
|
|
394
|
+
// Liste
|
|
395
|
+
if (col.type == ColType.MultiSelect && !col.options.filterText) {
|
|
396
|
+
value = event == null ? null : event.value;
|
|
397
|
+
}
|
|
398
|
+
// Texte
|
|
399
|
+
if (col.type == ColType.File
|
|
400
|
+
|| col.type == ColType.Text
|
|
401
|
+
|| col.type == ColType.Number
|
|
402
|
+
|| col.type == ColType.CilogNumber
|
|
403
|
+
|| (col.type == ColType.MultiSelect && col.options.filterText)
|
|
404
|
+
|| (col.type == ColType.Dropdown && col.options.filterText)) {
|
|
405
|
+
value = event.target.value;
|
|
406
|
+
}
|
|
407
|
+
// Switch
|
|
408
|
+
if (col.type == ColType.Switch) {
|
|
409
|
+
value = event.value;
|
|
410
|
+
}
|
|
411
|
+
// SelectButton
|
|
412
|
+
if (col.type == ColType.SelectButton) {
|
|
413
|
+
value = event == null ? null : event.value;
|
|
414
|
+
}
|
|
415
|
+
// Button
|
|
416
|
+
if (col.type == ColType.Button) {
|
|
417
|
+
value = event.target.value;
|
|
418
|
+
}
|
|
419
|
+
this.filter(col, value, this.getFilterByCol(col));
|
|
420
|
+
if (this.table.scroller != null) {
|
|
421
|
+
this.table.scroller.setInitialState();
|
|
422
|
+
this.table.scroller.init();
|
|
423
|
+
}
|
|
424
|
+
this.onFilter.emit({ column: col, value: value, filteredValue: this.table.filteredValue });
|
|
425
|
+
}
|
|
426
|
+
filter(col, val, filter) {
|
|
427
|
+
// Copier - Coller de la méthode filter() de table.ts de PrimeNG sans la désynchronisation causée par filterDelay (setTimeout)
|
|
428
|
+
if (this.table.filterTimeout) {
|
|
429
|
+
clearTimeout(this.table.filterTimeout);
|
|
430
|
+
}
|
|
431
|
+
if (!this.table.isFilterBlank(val)) {
|
|
432
|
+
this.table.filters[col.id] = { value: val, matchMode: filter };
|
|
433
|
+
}
|
|
434
|
+
else if (this.table.filters[col.id]) {
|
|
435
|
+
delete this.table.filters[col.id];
|
|
436
|
+
}
|
|
437
|
+
this.table._filter();
|
|
438
|
+
this.table.filterTimeout = null;
|
|
439
|
+
this.table.anchorRowIndex = null;
|
|
440
|
+
if (this.table.scroller) {
|
|
441
|
+
this.table.scroller.viewInit();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
getTotal(col) {
|
|
445
|
+
if (col.displayTotal && (col.type == ColType.Number || col.type == ColType.CilogNumber)) {
|
|
446
|
+
let values = this.values;
|
|
447
|
+
if (this.options.totalByFilter == true && this.table.filteredValue != null) {
|
|
448
|
+
values = this.table.filteredValue;
|
|
449
|
+
}
|
|
450
|
+
let total = 0;
|
|
451
|
+
values.forEach(val => {
|
|
452
|
+
if (!val.exclusionTotal && !val[col.id].exclusionTotal) {
|
|
453
|
+
if (this.options.modeSelection != null) {
|
|
454
|
+
if (this.options.modeSelection == ModeSelection.Checkbox && this.options.totalBySelection == true) {
|
|
455
|
+
if (this.selectedRows != null && this.selectedRows.find(row => row.id == val.id) != null) {
|
|
456
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
return total;
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
return 0;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
getTotalStr(col) {
|
|
475
|
+
if (col.displayTotal && (col.type == ColType.Number || col.type == ColType.CilogNumber)) {
|
|
476
|
+
if (col.methodTotal != null) {
|
|
477
|
+
return this.getFormattedNumber(col, null, col.methodTotal(), true);
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
let values = this.values;
|
|
481
|
+
if (this.options.totalByFilter == true && this.table.filteredValue != null) {
|
|
482
|
+
values = this.table.filteredValue;
|
|
483
|
+
}
|
|
484
|
+
let total = 0;
|
|
485
|
+
values.forEach(val => {
|
|
486
|
+
if (!val.exclusionTotal && !val[col.id].exclusionTotal) {
|
|
487
|
+
if (this.options.modeSelection != null) {
|
|
488
|
+
if (this.options.modeSelection == ModeSelection.Checkbox && this.options.totalBySelection == true) {
|
|
489
|
+
if (this.selectedRows != null && this.selectedRows.find(row => row.id == val.id) != null) {
|
|
490
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
total += (val[col.id].value != null ? val[col.id].value : 0);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
return this.getFormattedNumber(col, null, total, true);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
getFormattedText(col, rowData) {
|
|
510
|
+
let value = rowData[col.id].value;
|
|
511
|
+
if (value != null) {
|
|
512
|
+
let indentation = this.getOption(col, rowData, 'indentation');
|
|
513
|
+
if (indentation != null) {
|
|
514
|
+
return ' '.repeat(indentation) + value;
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
return value;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
return '';
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
getFormattedNumber(col, rowData, value, total = false) {
|
|
525
|
+
if (value == null) {
|
|
526
|
+
return '';
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
let finalValue = [];
|
|
530
|
+
// Préfixe
|
|
531
|
+
if (this.getOption(col, rowData, 'prefix') != null) {
|
|
532
|
+
finalValue.push(this.getOption(col, rowData, 'prefix'));
|
|
533
|
+
}
|
|
534
|
+
// Valeur
|
|
535
|
+
if (total) {
|
|
536
|
+
let minDecimalesTotal = 2;
|
|
537
|
+
let maxDecimalesTotal = 2;
|
|
538
|
+
if (col.options.minDecimalesTotal != null) {
|
|
539
|
+
minDecimalesTotal = col.options.minDecimalesTotal;
|
|
540
|
+
}
|
|
541
|
+
if (col.options.maxDecimalesTotal != null) {
|
|
542
|
+
maxDecimalesTotal = col.options.maxDecimalesTotal;
|
|
543
|
+
}
|
|
544
|
+
if (maxDecimalesTotal < minDecimalesTotal) {
|
|
545
|
+
maxDecimalesTotal = minDecimalesTotal;
|
|
546
|
+
}
|
|
547
|
+
finalValue.push(value.toLocaleString('fr-FR', { maximumFractionDigits: maxDecimalesTotal, minimumFractionDigits: minDecimalesTotal }));
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
let minDecimales;
|
|
551
|
+
let maxDecimales;
|
|
552
|
+
if (this.getOption(col, rowData, 'maxDecimales') != null) {
|
|
553
|
+
maxDecimales = this.getOption(col, rowData, 'maxDecimales');
|
|
554
|
+
}
|
|
555
|
+
if (this.getOption(col, rowData, 'minDecimales') != null) {
|
|
556
|
+
minDecimales = this.getOption(col, rowData, 'minDecimales');
|
|
557
|
+
}
|
|
558
|
+
//finalValue.push(value.toLocaleString('fr-FR'))
|
|
559
|
+
finalValue.push(value.toLocaleString('fr-FR', { maximumFractionDigits: maxDecimales, minimumFractionDigits: minDecimales }));
|
|
560
|
+
}
|
|
561
|
+
// Suffixe
|
|
562
|
+
if (this.getOption(col, rowData, 'suffix') != null) {
|
|
563
|
+
finalValue.push(this.getOption(col, rowData, 'suffix'));
|
|
564
|
+
}
|
|
565
|
+
return finalValue.join(' ');
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
downloadFile(cell) {
|
|
569
|
+
let path = cell.options.downloadPath;
|
|
570
|
+
let fileName = cell.value;
|
|
571
|
+
const a = document.createElement('a');
|
|
572
|
+
a.href = path;
|
|
573
|
+
a.download = fileName;
|
|
574
|
+
document.body.appendChild(a);
|
|
575
|
+
a.click();
|
|
576
|
+
document.body.removeChild(a);
|
|
577
|
+
URL.revokeObjectURL(path);
|
|
578
|
+
}
|
|
579
|
+
hasFrozenColumns() {
|
|
580
|
+
return this.columns.filter(col => col.frozen == true).length > 0;
|
|
581
|
+
}
|
|
582
|
+
trackByFunction(index, item) {
|
|
583
|
+
return item?.id;
|
|
584
|
+
}
|
|
585
|
+
isValueButtonByType(value, type) {
|
|
586
|
+
return value != null && typeof value == type;
|
|
587
|
+
}
|
|
588
|
+
isModeEdition() {
|
|
589
|
+
return this.options.editable;
|
|
590
|
+
}
|
|
591
|
+
getModeSelection() {
|
|
592
|
+
if (this.options.selectable != true) {
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
switch (this.options.modeSelection) {
|
|
596
|
+
case ModeSelection.Checkbox:
|
|
597
|
+
case ModeSelection.Metakey:
|
|
598
|
+
return 'multiple';
|
|
599
|
+
case ModeSelection.Cell:
|
|
600
|
+
return null;
|
|
601
|
+
case ModeSelection.Row:
|
|
602
|
+
default:
|
|
603
|
+
return 'single';
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
isModeCheckboxSelection() {
|
|
607
|
+
return this.options.selectable == true && this.options.modeSelection != null && this.options.modeSelection == ModeSelection.Checkbox;
|
|
608
|
+
}
|
|
609
|
+
isModeCellSelection() {
|
|
610
|
+
return this.options.selectable == true && this.options.modeSelection != null && this.options.modeSelection == ModeSelection.Cell;
|
|
611
|
+
}
|
|
612
|
+
isModeMetakeySelection() {
|
|
613
|
+
return this.options.selectable == true && this.options.modeSelection != null && this.options.modeSelection == ModeSelection.Metakey;
|
|
614
|
+
}
|
|
615
|
+
exportExcel(byFiltre = false, withColors = true) {
|
|
616
|
+
this.exportService.exportExcel(this.table.filteredValue != null ? this.table.filteredValue : this.values, this.columns, byFiltre, withColors);
|
|
617
|
+
}
|
|
618
|
+
onClickCellNumber(row, col) {
|
|
619
|
+
this.values.forEach(val => {
|
|
620
|
+
val[col.id].focus = false;
|
|
621
|
+
});
|
|
622
|
+
row[col.id].focus = true;
|
|
623
|
+
setTimeout(() => {
|
|
624
|
+
this.inputNumber.input.nativeElement.focus();
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CilogTableComponent, deps: [{ token: i1.ConfirmationService }, { token: i1.FilterService }, { token: i0.ChangeDetectorRef }, { token: i2.ExportService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
628
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CilogTableComponent, selector: "cilog-table", inputs: { columns: "columns", values: "values", options: "options", loading: "loading" }, outputs: { columnsChange: "columnsChange", valuesChange: "valuesChange", onEdit: "onEdit", onEditInit: "onEditInit", onDelete: "onDelete", onSelect: "onSelect", onUnselect: "onUnselect", onFilter: "onFilter", onFilterInit: "onFilterInit", onSort: "onSort", onPage: "onPage", onRowDoubleClick: "onRowDoubleClick" }, viewQueries: [{ propertyName: "table", first: true, predicate: ["table"], descendants: true, static: true }, { propertyName: "cm", first: true, predicate: ["cm"], descendants: true }, { propertyName: "inputNumber", first: true, predicate: ["inputNumber"], descendants: true }], ngImport: i0, template: "<div [ngStyle]=\"{ 'height': options.scrollHeight != null ? options.scrollHeight : '100%' }\">\r\n\r\n <button pButton\r\n *ngIf=\"options.exportExcel\"\r\n icon=\"pi pi-file-excel\"\r\n class=\"p-button-success absolute z-5 w-2rem h-2rem border-round-right border-noround-top\"\r\n pTooltip=\"Exporter le contenu de la grille au format Excel\"\r\n (click)=\"exportExcel(options.exportExcelByFiltre, !options.exportExcelNoColors)\">\r\n </button>\r\n\r\n <p-contextMenu #cm [model]=\"options.contextMenuItems\" />\r\n\r\n <p-table #table\r\n [columns]=\"columns\"\r\n [value]=\"values\"\r\n dataKey=\"id\"\r\n [selectionMode]=\"getModeSelection()\"\r\n [metaKeySelection]=\"isModeMetakeySelection()\"\r\n [(selection)]=\"selectedRows\"\r\n (onRowSelect)=\"onSelectRow($event)\"\r\n (onRowUnselect)=\"onUnselectRow($event)\"\r\n (onHeaderCheckboxToggle)=\"onSelectAll($event)\"\r\n (sortFunction)=\"sortGrille($event)\"\r\n [customSort]=\"options.grouping == null ? true : false\"\r\n [scrollable]=\"true\"\r\n [loading]=\"loading\"\r\n [scrollHeight]=\"'flex'\"\r\n [rowGroupMode]=\"options.grouping != null ? 'subheader' : null\"\r\n [groupRowsBy]=\"options.grouping != null ? options.grouping.obj + '.' + options.grouping.id : null\"\r\n [groupRowsByOrder]=\"0\"\r\n [virtualScroll]=\"options.virtualScroll == true && options.scrollHeight != null ? true : false\"\r\n [virtualScrollItemSize]=\"options.virtualScrollItemSize != null ? options.virtualScrollItemSize : 35\"\r\n [paginator]=\"options.paginator == null ? false : true\"\r\n [rows]=\"options.paginatorRows\"\r\n (onPage)=\"onPageTable($event)\"\r\n [tableStyleClass]=\"!options.themeGrille ? 'grid_grey' : options.themeGrille\"\r\n [lazy]=\"options.lazy == true ? true : false\"\r\n (onFilter)=\"onFilterTable($event)\"\r\n [rowTrackBy]=\"trackByFunction\"\r\n [(contextMenuSelection)]=\"contextMenuSelectedItem\"\r\n [contextMenu]=\"cm\">\r\n\r\n <!-- HEADER -->\r\n <ng-template pTemplate=\"header\" let-columns>\r\n\r\n <!-- HEADERS -->\r\n <tr class=\"rowHeader\">\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n <p-tableHeaderCheckbox *ngIf=\"!options.filterable && options.toggleAll\"></p-tableHeaderCheckbox>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns\">\r\n <th *ngIf=\"!col.invisible\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': col.backgroundColor ? col.backgroundColor : null }\"\r\n [ngClass]=\"{ 'text-center' : options.centerHeaders, 'headerAffichageSimple': !options.headersAffichageEntier, 'headerAffichageEntier': options.headersAffichageEntier }\"\r\n [pSortableColumn]=\"col.id\"\r\n [pSortableColumnDisabled]=\"!options.sortable || options.grouping != null || col.libelle == null || col.libelle == ''\"\r\n id=\"{{ col.id }}\"\r\n (click)=\"refreshData()\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n [pTooltip]=\"col.libelle\"\r\n [tooltipDisabled]=\"!col.tooltipHeader\"\r\n tooltipPosition=\"bottom\">\r\n <div [ngStyle]=\"{ 'color': col.textColor ? col.textColor : null }\">\r\n {{ col.libelle }}\r\n </div>\r\n <p-sortIcon *ngIf=\"options.sortable && options.grouping == null && col.libelle != null && col.libelle != ''\"\r\n [field]=\"col.id\">\r\n </p-sortIcon>\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n\r\n <!-- FILTRES -->\r\n <tr *ngIf=\"options.filterable\" class=\"rowFilter\">\r\n\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n <p-tableHeaderCheckbox *ngIf=\"options.toggleAll\"></p-tableHeaderCheckbox>\r\n </th>\r\n\r\n <ng-container *ngFor=\"let col of columns\">\r\n <!-- Text -->\r\n <th *ngIf=\"!col.invisible && ((checkType('Dropdown', col) && col.options.filterText)\r\n || (checkType('MultiSelect', col) && col.options.filterText)\r\n || checkType('Text', col)\r\n || checkType('File', col)\r\n || (checkType('Button', col) && col.options.filterCol))\r\n || checkType('Number', col)\r\n || checkType('CilogNumber', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <input *ngIf=\"!col.disableFilter\"\r\n pInputText\r\n type=\"text\"\r\n (input)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </th>\r\n\r\n <!-- Date -->\r\n <th *ngIf=\"!col.invisible && checkType('Date', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-calendar *ngIf=\"!col.disableFilter\"\r\n [view]=\"getOption(col, rowData, 'mode') == null ? 'date' : getOption(col, rowData, 'mode')\"\r\n [dateFormat]=\"getOption(col, rowData, 'mode') == 'year' ? 'yy' : getOption(col, rowData, 'mode') == 'month' ? 'mm/yy' : 'dd/mm/yy'\"\r\n [inputId]=\"col.id + '_filter'\"\r\n firstDayOfWeek=\"1\"\r\n [readonlyInput]=\"true\"\r\n appendTo=\"body\"\r\n selectionMode=\"range\"\r\n (onSelect)=\"onFilterCol($event, col)\"\r\n showButtonBar=\"true\"\r\n (onClearClick)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </p-calendar>\r\n </th>\r\n\r\n <!-- Liste -->\r\n <th *ngIf=\"!col.invisible && ((checkType('Dropdown', col) && !col.options.filterText) || (checkType('MultiSelect', col) && !col.options.filterText) || checkType('SelectButton', col) || checkType('State', col))\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-multiSelect *ngIf=\"!col.disableFilter\"\r\n [options]=\"col.options?.options\"\r\n [filter]=\"true\"\r\n dataKey=\"ID\"\r\n [optionLabel]=\"col.options?.optionLabel\"\r\n appendTo=\"body\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [virtualScroll]=\"true\"\r\n [virtualScrollItemSize]=\"35\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\"\r\n [group]=\"col.options.optionGroupChildren != null ? true : false\"\r\n [optionGroupLabel]=\"col.options.optionGroupLabel\"\r\n [optionGroupChildren]=\"col.options.optionGroupChildren\"\r\n [showToggleAll]=\"false\"\r\n [showClear]=\"true\"\r\n (onClear)=\"onFilterCol(null, col)\">\r\n <ng-template let-group pTemplate=\"group\">\r\n <div>{{group[col.options.optionGroupLabel]}}</div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </th>\r\n\r\n <!-- Switch -->\r\n <th *ngIf=\"!col.invisible && checkType('Switch', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-multiSelect *ngIf=\"!col.disableFilter\"\r\n [options]=\"optionsSwitch\"\r\n [showHeader]=\"false\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n appendTo=\"body\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [virtualScrollItemSize]=\"30\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </p-multiSelect>\r\n </th>\r\n\r\n <!-- Non filtrable -->\r\n <th *ngIf=\"!col.invisible && (checkType('Image', col) || (checkType('Button', col) && !col.options.filterCol))\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n\r\n <!-- TOTAL -->\r\n <tr *ngIf=\"options.rowTotal\"\r\n class=\"rowTotal\">\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns\">\r\n <th *ngIf=\"!col.invisible\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n [ngClass]=\"{ 'text-center' : true }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div>{{ getTotalStr(col) }}</div>\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n </ng-template>\r\n\r\n <!--Groupheader-->\r\n <ng-template pTemplate=\"groupheader\" let-rowData>\r\n <tr pRowGroupHeader class=\"rowGrouping\">\r\n <td [attr.colspan]=\"columns.length\">\r\n <div class=\"text_bold\">{{ rowData[options.grouping.obj][options.grouping.libelle] }}</div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- Body -->\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\">\r\n <tr id=\"{{ rowData.id }}\"\r\n [ngStyle]=\"{ 'background-color': rowData.color ? rowData.color : null }\"\r\n [pSelectableRow]=\"rowData\"\r\n [pSelectableRowDisabled]=\"!options.selectable || isModeCheckboxSelection() || isModeCellSelection()\"\r\n (dblclick)=\"onRowDoubleClickEvent(rowData)\"\r\n [pContextMenuRow]=\"rowData\"\r\n [pContextMenuRowDisabled]=\"options.contextMenuItems == null\">\r\n\r\n <td *ngIf=\"isModeCheckboxSelection()\"\r\n class=\"cellDelete\"\r\n pFrozenColumn>\r\n <p-tableCheckbox [value]=\"rowData\" [disabled]=\"rowData.readonly\"></p-tableCheckbox>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let col of columns\">\r\n\r\n <!-- Text -->\r\n <td *ngIf=\"!col.invisible && checkType('Text', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [frozen]=\"col.frozen\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <input pInputText\r\n type=\"text\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n (blur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (keydown.enter)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (keydown.tab)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (click)=\"onEditInitCell(rowData, col, rowData[col.id].value)\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\" />\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedText(col, rowData) }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Text', col) && (!isModeEdition() || rowData.readonly || rowData[col.id]?.readonly)\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color' : rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">\r\n {{ col.libelle }} :\r\n </div>\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedText(col, rowData) }}\r\n </div>\r\n </td>\r\n\r\n <!-- Dropdown -->\r\n <td *ngIf=\"!col.invisible && checkType('Dropdown', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"paddingCell\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <p-dropdown *ngIf=\"rowData[col.id] != null\"\r\n dataKey=\"ID\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [autoDisplayFirst]=\"false\"\r\n appendTo=\"body\"\r\n [showClear]=\"getOption(col, rowData, 'deletable')\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [virtualScrollItemSize]=\"30\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-data pTemplate=\"selectedItem\">\r\n <span *ngIf=\"data != null\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ data[getOption(col, rowData, 'optionLabel')] }}\r\n </span>\r\n <span *ngIf=\"data == null\"></span>\r\n </ng-template>\r\n </p-dropdown>\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : '' }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n <!--<p-dropdown *ngIf=\"rowData[col.id] != null\"\r\n dataKey=\"ID\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [autoDisplayFirst]=\"false\"\r\n appendTo=\"body\"\r\n [showClear]=\"getOption(col, rowData, 'deletable')\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [virtualScrollItemSize]=\"30\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-data pTemplate=\"selectedItem\">\r\n <span *ngIf=\"data != null\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ data[getOption(col, rowData, 'optionLabel')] }}\r\n </span>\r\n <span *ngIf=\"data == null\"></span>\r\n </ng-template>\r\n </p-dropdown>-->\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Dropdown', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : '' }}</div>\r\n </td>\r\n\r\n <!-- Cilog Number -->\r\n <td *ngIf=\"!col.invisible && checkType('CilogNumber', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <cilog-input-number *ngIf=\"rowData[col.id] && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n (onInput)=\"onInputNumber($event)\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [textColor]=\"rowData[col.id].textColor\"\r\n [bold]=\"rowData.bold == true || rowData[col.id].bold == true\"\r\n [italic]=\"rowData.italic == true || rowData[col.id].italic == true\"\r\n [suffixe]=\"getOption(col, rowData, 'suffix')\"\r\n [prefixe]=\"getOption(col, rowData, 'prefix') != null ? getOption(col, rowData, 'prefix') + ' ' : null\"\r\n [min]=\"getOption(col, rowData, 'min')\"\r\n [max]=\"getOption(col, rowData, 'max')\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [maxDecimals]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'maxDecimales') != null ? getOption(col, rowData, 'maxDecimales') : 2 \"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onFocus)=\"onEditInitCell(rowData, col, rowData[col.id].value)\">\r\n </cilog-input-number>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('CilogNumber', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getFormattedNumber(col, rowData, rowData[col.id].value) }}</div>\r\n </td>\r\n\r\n <!-- Number -->\r\n <td *ngIf=\"!col.invisible && checkType('Number', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left',\r\n 'text-right': col.position == 'right' || col.position == null,\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <p-inputNumber #inputNumber\r\n *ngIf=\"rowData[col.id] && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n locale=\"fr-FR\"\r\n (onInput)=\"onInputNumber($event)\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [showButtons]=\"getOption(col, rowData, 'showButtons')\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [inputStyle]=\"{ 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null, 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null }\"\r\n [suffix]=\"getOption(col, rowData, 'suffix')\"\r\n [prefix]=\"getOption(col, rowData, 'prefix') != null ? getOption(col, rowData, 'prefix') + ' ' : null\"\r\n [min]=\"getOption(col, rowData, 'min')\"\r\n [max]=\"getOption(col, rowData, 'max')\"\r\n [minFractionDigits]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'minDecimales') != null ? getOption(col, rowData, 'minDecimales') : 0\"\r\n [maxFractionDigits]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'maxDecimales') != null ? getOption(col, rowData, 'maxDecimales') : 2 \"\r\n (onBlur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onKeyDown)=\"onKeyDown($event, rowData, col, rowData[col.id].value)\"\r\n (onFocus)=\"onEditInitCell($event, rowData, col, rowData[col.id].value)\"\r\n [step]=\"0\">\r\n </p-inputNumber>\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedNumber(col, rowData, rowData[col.id].value) }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Number', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left',\r\n 'text-right': col.position == 'right' || col.position == null,\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getFormattedNumber(col, rowData, rowData[col.id].value) }}</div>\r\n </td>\r\n\r\n <!-- Date -->\r\n <td *ngIf=\"!col.invisible && checkType('Date', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getOption(col, rowData, 'mode') == 'year' ? (rowData[col.id].value | date: 'yyyy') : getOption(col, rowData, 'mode') == 'month' ? (rowData[col.id].value | date: 'MM/yy') : getOption(col, rowData, 'mode') == 'hour' ? (rowData[col.id].value | date: 'HH:mm') : getOption(col, rowData, 'mode') == 'datehour' ? (rowData[col.id].value | date: 'dd/MM/yy HH:mm') : (rowData[col.id].value | date: 'dd/MM/yyyy')\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-calendar [(ngModel)]=\"rowData[col.id].value\"\r\n [view]=\"getOption(col, rowData, 'mode') == null || getOption(col, rowData, 'mode') == 'date' || getOption(col, rowData, 'mode') == 'hour' ? 'date' : getOption(col, rowData, 'mode') == 'datehour' ? 'date' : getOption(col, rowData, 'mode')\"\r\n [dateFormat]=\"getOption(col, rowData, 'mode') == 'year' ? 'yy' : getOption(col, rowData, 'mode') == 'month' ? 'mm/yy' : getOption(col, rowData, 'mode') == 'hour' || getOption(col, rowData, 'mode') == 'datehour' ? 'dd/mm/yy' : 'dd/mm/yy'\"\r\n [showTime]=\"getOption(col, rowData, 'mode') == 'datehour'\"\r\n [timeOnly]=\"getOption(col, rowData, 'mode') == 'hour'\"\r\n [hourFormat]=\"24\"\r\n firstDayOfWeek=\"1\"\r\n (onSelect)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onBlur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [inputStyle]=\"{ 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null, 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null }\"\r\n [showClear]=\"getOption(col, rowData, 'clear')\"\r\n [minDate]=\"getOption(col, rowData, 'minDate')\"\r\n [maxDate]=\"getOption(col, rowData, 'maxDate')\"\r\n [defaultDate]=\"getOption(col, rowData, 'defaultDate')\"\r\n appendTo=\"body\">\r\n </p-calendar>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Date', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'min-width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | date: 'dd/MM/yyyy'\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value | date: (getOption(col, rowData, 'mode') == 'year' ? 'yyyy' : getOption(col, rowData, 'mode') == 'month' ? 'MM/yyyy' : 'dd/MM/yyyy') }}</div>\r\n </td>\r\n\r\n <!-- MultiSelect -->\r\n <td *ngIf=\"!col.invisible && checkType('MultiSelect', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel'))\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"paddingCell\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-multiSelect *ngIf=\"rowData[col.id] != null\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n appendTo=\"body\"\r\n dataKey=\"ID\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\"\r\n [virtualScrollItemSize]=\"30\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"editMultiselect(rowData, col, $event)\"\r\n [showToggleAll]=\"false\"\r\n [showHeader]=\"getOption(col, rowData, 'filter')\"\r\n [group]=\"getOption(col, rowData, 'optionGroupChildren') != null ? true : false\"\r\n [optionGroupLabel]=\"getOption(col, rowData, 'optionGroupLabel')\"\r\n [optionGroupChildren]=\"getOption(col, rowData, 'optionGroupChildren')\"\r\n ngDefaultControl>\r\n <ng-template let-data pTemplate=\"selectedItems\">\r\n <span *ngFor=\"let option of data, let i = index\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ option[getOption(col, rowData, 'optionLabel')] + (i != data.length - 1 ? ',' : '') }}\r\n </span>\r\n </ng-template>\r\n <ng-template let-group pTemplate=\"group\">\r\n <div>{{group[col.options.optionGroupLabel]}}</div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('MultiSelect', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel'))\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel')) }}</div>\r\n </td>\r\n\r\n <!-- Image -->\r\n <td *ngIf=\"!col.invisible && checkType('Image', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n class=\"text-center\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <img *ngIf=\"rowData[col.id]\" style=\"vertical-align: middle; width: 40px;\" src=\"{{ rowData[col.id].value }}\" />\r\n </td>\r\n\r\n <!-- Button -->\r\n <td *ngIf=\"!col.invisible && checkType('Button', col)\"\r\n class=\"paddingCell text-center\"\r\n [ngClass]=\"{\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <button pButton\r\n *ngIf=\"rowData[col.id].value != null && isValueButtonByType(rowData[col.id].value, 'function')\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [label]=\"getOption(col, rowData, 'label')\"\r\n [icon]=\"getOption(col, rowData, 'icon')\"\r\n (click)=\"rowData[col.id].value()\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getOption(col, rowData, 'label')\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n [class]=\"'p-button-' + getOption(col, rowData, 'severity')\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n </button>\r\n <div *ngIf=\"isValueButtonByType(rowData[col.id].value, 'string')\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\">\r\n {{ rowData[col.id].value }}\r\n </div>\r\n </td>\r\n\r\n <!-- SelectButton -->\r\n <td *ngIf=\"!col.invisible && checkType('SelectButton', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-selectButton *ngIf=\"rowData[col.id] != null\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [optionValue]=\"getOption(col, rowData, 'optionValue') != null ? getOption(col, rowData, 'optionValue') : 'value'\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <span class=\"text-center w-full\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ item.label }}\r\n </span>\r\n </ng-template>\r\n </p-selectButton>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('SelectButton', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"text-center\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getSelectLibelleByValue(rowData, col) }}</div>\r\n </td>\r\n\r\n <!-- Switch -->\r\n <td *ngIf=\"!col.invisible && checkType('Switch', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n class=\"text-center\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-inputSwitch *ngIf=\"rowData[col.id] != null\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || (getOption(col, rowData, 'action') == null && !isModeEdition())\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n ngDefaultControl>\r\n </p-inputSwitch>\r\n </td>\r\n\r\n <!-- File -->\r\n <td *ngIf=\"!col.invisible && checkType('File', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div class=\"p-inputgroup\" *ngIf=\"rowData[col.id] != null\">\r\n <button type=\"button\"\r\n pButton\r\n pRipple\r\n icon=\"pi pi-upload\"\r\n (click)=\"clickById('input_' + rowData[col.id].id)\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\">\r\n </button>\r\n <input id=\"{{'output_' + rowData[col.id].id}}\"\r\n pInputText\r\n type=\"text\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\"\r\n value=\"{{ rowData[col.id].value != null ? rowData[col.id].value : '' }}\"\r\n readonly\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value ? rowData[col.id].value : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\">\r\n <button *ngIf=\"getOption(col, rowData, 'downloadPath') && rowData[col.id].value != null\"\r\n type=\"button\"\r\n pButton\r\n pRipple\r\n icon=\"pi pi-download\"\r\n (click)=\"downloadFile(rowData[col.id])\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\">\r\n </button>\r\n </div>\r\n <input *ngIf=\"rowData[col.id]\" id=\"{{'input_' + rowData[col.id].id}}\" #inputFile pInputText type=\"file\" hidden (change)=\"rowData[col.id].value = inputFile.files[0].name; onEditCell(rowData, col, inputFile.files[0])\">\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('File', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value ? rowData[col.id].value : ''\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value ? rowData[col.id].value : '' }}</div>\r\n </td>\r\n\r\n <!-- State -->\r\n <td *ngIf=\"!col.invisible && checkType('State', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n class=\"text-center\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-tag *ngIf=\"rowData[col.id].value != null\"\r\n [value]=\"rowData[col.id].value[getOption(col, rowData, 'optionLabel')]\"\r\n [severity]=\"rowData[col.id].value.severity\"\r\n [icon]=\"rowData[col.id].value.icon\"\r\n [style]=\"{\r\n 'background-color': rowData[col.id].value.backgroundColor,\r\n 'color': rowData[col.id].value.textColor,\r\n 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null,\r\n 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null\r\n }\">\r\n </p-tag>\r\n </td>\r\n\r\n </ng-container>\r\n\r\n <!-- Deletion -->\r\n <td *ngIf=\"options.rowsDeletable\"\r\n class=\"cellDelete\"\r\n [ngClass]=\"rowData.deletable ? 'paddingCell' : null\">\r\n <button *ngIf=\"rowData.deletable\"\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-times\"\r\n class=\"p-button-danger buttonDelete p-button-text\"\r\n [disabled]=\"rowData.readonly\"\r\n (click)=\"onDeleteLine(rowData)\">\r\n </button>\r\n </td>\r\n\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n</div>\r\n", styles: ["::ng-deep .p-tooltip .p-tooltip-text{overflow-wrap:break-word!important}:host ::ng-deep .grid_brown .rowHeader>th{background-color:#795548}:host ::ng-deep .grid_brown .rowHeader>th div{color:#fff}:host ::ng-deep .grid_brown .rowHeader>th i{color:#fff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column:hover{background-color:#a47767}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column:hover i{color:#fff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column.p-highlight div{color:#76c7ff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column.p-highlight .p-sortable-column-icon{color:#76c7ff}:host ::ng-deep .grid_brown .rowFilter th{background-color:#795548}:host ::ng-deep .grid_grey .rowHeader>th{background-color:#dedddd}:host ::ng-deep .grid_grey .rowHeader>th div{color:#495057}:host ::ng-deep .grid_grey .rowHeader>th i{color:#495057}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column:hover{background-color:#e7e7e7}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column:hover i{color:#495057}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column.p-highlight div{color:#008bff}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column.p-highlight .p-sortable-column-icon{color:#008bff}:host ::ng-deep .grid_grey .rowFilter th{background-color:#dedddd}:host ::ng-deep .selectable_cell:hover{background:#dcdcdc!important;cursor:pointer!important}:host ::ng-deep .p-frozen-column{z-index:2!important}:host ::ng-deep .p-datatable-thead{z-index:3!important}:host ::ng-deep .p-checkbox{border-radius:inherit!important}:host ::ng-deep p-inputnumber{width:100%}:host ::ng-deep .p-calendar,:host ::ng-deep .p-inputtext,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber-input,:host ::ng-deep .p-dropdown,:host ::ng-deep .p-multiselect{width:100%}:host ::ng-deep .suffixe,:host ::ng-deep .prefixe{height:25px;padding-top:1px!important}:host ::ng-deep .p-multiselect-label-container,:host ::ng-deep .p-dropdown-label{width:1px!important}:host ::ng-deep .p-scroller-content{min-height:50%}:host ::ng-deep .rowTotal>th{background-color:#edcbaa!important}:host ::ng-deep .rowGrouping{background:#faeada!important}:host ::ng-deep .p-inputswitch.p-inputswitch-checked .p-inputswitch-slider{background:#30e130}:host ::ng-deep .p-inputswitch.p-inputswitch-checked:not(.p-disabled):hover .p-inputswitch-slider{background:#2bd12b}:host ::ng-deep .p-datatable-table{table-layout:fixed}:host ::ng-deep .p-datatable-thead>tr>th{border:1px solid rgba(0,0,0,.12)!important;padding:8px;font-weight:600;height:40px}:host ::ng-deep .headerAffichageSimple div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .headerAffichageEntier{word-wrap:break-word}:host ::ng-deep .p-datatable-tbody>tr>td{border:1px solid rgba(0,0,0,.12)!important;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-datatable-tbody>tr>td div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-tag{max-width:100%}:host ::ng-deep .p-tag .p-tag-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-button{padding:5px;max-width:100%}:host ::ng-deep .p-button .p-button-label{overflow:hidden!important;white-space:nowrap!important;text-overflow:ellipsis!important}:host ::ng-deep .text_bold{font-weight:700!important}:host ::ng-deep .cellDelete{flex:0 0 50px!important;width:50px;text-align:center!important;padding:0!important}:host ::ng-deep .p-tooltip .p-tooltip-text{background-color:red!important}:host ::ng-deep .p-skeleton{background-color:#dee2e6;border-radius:6px;padding:0}:host ::ng-deep .p-datatable-tbody>tr{height:35px}:host ::ng-deep .p-inputtext{height:25px!important;padding:4px 5px!important}:host ::ng-deep .p-inputnumber{height:25px;padding:0!important}:host ::ng-deep .p-inputnumber-input{padding:0 5px!important}:host ::ng-deep .p-inputgroup .p-inputtext{height:25px;padding:4px 5px!important}:host ::ng-deep .p-dropdown,:host ::ng-deep .p-multiselect{vertical-align:middle}:host ::ng-deep .p-dropdown-label{padding-top:2px;padding-bottom:2px}:host ::ng-deep .p-multiselect-label{padding-top:2px;padding-bottom:2px}:host ::ng-deep .p-editable-column{padding:3px 10px!important}:host ::ng-deep .paddingCell{padding:3px 10px!important}:host ::ng-deep .p-selectbutton>.p-button{width:50%;height:25px}:host ::ng-deep .p-inputgroup>.p-button{height:25px}:host ::ng-deep .buttonDelete{width:100%;height:20px}:host ::ng-deep .p-column-title{display:none}:host ::ng-deep .p-datatable-loading-icon{color:#fff}\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.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i5.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i5.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i5.RowGroupHeader, selector: "[pRowGroupHeader]" }, { kind: "directive", type: i5.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "directive", type: i5.ContextMenuRow, selector: "[pContextMenuRow]", inputs: ["pContextMenuRow", "pContextMenuRowIndex", "pContextMenuRowDisabled"] }, { kind: "directive", type: i5.EditableColumn, selector: "[pEditableColumn]", inputs: ["pEditableColumn", "pEditableColumnField", "pEditableColumnRowIndex", "pEditableColumnDisabled", "pFocusCellSelector"] }, { kind: "component", type: i5.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i5.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i5.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i5.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "component", type: i7.SelectButton, selector: "p-selectButton", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "style", "styleClass", "ariaLabelledBy", "disabled", "dataKey", "autofocus"], outputs: ["onOptionClick", "onChange"] }, { kind: "component", type: i8.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i9.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i10.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i11.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i12.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i13.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i14.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i15.InputSwitch, selector: "p-inputSwitch", inputs: ["style", "styleClass", "tabindex", "inputId", "name", "disabled", "readonly", "trueValue", "falseValue", "ariaLabel", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "directive", type: i16.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i16.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i16.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i17.CilogInputNumberComponent, selector: "cilog-input-number", inputs: ["min", "max", "maxDecimals", "prefixe", "suffixe", "inputStyleClass", "disabled", "readonly", "textColor", "bold", "italic", "floatLabel"], outputs: ["onInput", "onChange", "onFocus", "onBlur"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: i18.ValuePipe, name: "value" }] }); }
|
|
629
|
+
}
|
|
630
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CilogTableComponent, decorators: [{
|
|
631
|
+
type: Component,
|
|
632
|
+
args: [{ selector: 'cilog-table', template: "<div [ngStyle]=\"{ 'height': options.scrollHeight != null ? options.scrollHeight : '100%' }\">\r\n\r\n <button pButton\r\n *ngIf=\"options.exportExcel\"\r\n icon=\"pi pi-file-excel\"\r\n class=\"p-button-success absolute z-5 w-2rem h-2rem border-round-right border-noround-top\"\r\n pTooltip=\"Exporter le contenu de la grille au format Excel\"\r\n (click)=\"exportExcel(options.exportExcelByFiltre, !options.exportExcelNoColors)\">\r\n </button>\r\n\r\n <p-contextMenu #cm [model]=\"options.contextMenuItems\" />\r\n\r\n <p-table #table\r\n [columns]=\"columns\"\r\n [value]=\"values\"\r\n dataKey=\"id\"\r\n [selectionMode]=\"getModeSelection()\"\r\n [metaKeySelection]=\"isModeMetakeySelection()\"\r\n [(selection)]=\"selectedRows\"\r\n (onRowSelect)=\"onSelectRow($event)\"\r\n (onRowUnselect)=\"onUnselectRow($event)\"\r\n (onHeaderCheckboxToggle)=\"onSelectAll($event)\"\r\n (sortFunction)=\"sortGrille($event)\"\r\n [customSort]=\"options.grouping == null ? true : false\"\r\n [scrollable]=\"true\"\r\n [loading]=\"loading\"\r\n [scrollHeight]=\"'flex'\"\r\n [rowGroupMode]=\"options.grouping != null ? 'subheader' : null\"\r\n [groupRowsBy]=\"options.grouping != null ? options.grouping.obj + '.' + options.grouping.id : null\"\r\n [groupRowsByOrder]=\"0\"\r\n [virtualScroll]=\"options.virtualScroll == true && options.scrollHeight != null ? true : false\"\r\n [virtualScrollItemSize]=\"options.virtualScrollItemSize != null ? options.virtualScrollItemSize : 35\"\r\n [paginator]=\"options.paginator == null ? false : true\"\r\n [rows]=\"options.paginatorRows\"\r\n (onPage)=\"onPageTable($event)\"\r\n [tableStyleClass]=\"!options.themeGrille ? 'grid_grey' : options.themeGrille\"\r\n [lazy]=\"options.lazy == true ? true : false\"\r\n (onFilter)=\"onFilterTable($event)\"\r\n [rowTrackBy]=\"trackByFunction\"\r\n [(contextMenuSelection)]=\"contextMenuSelectedItem\"\r\n [contextMenu]=\"cm\">\r\n\r\n <!-- HEADER -->\r\n <ng-template pTemplate=\"header\" let-columns>\r\n\r\n <!-- HEADERS -->\r\n <tr class=\"rowHeader\">\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n <p-tableHeaderCheckbox *ngIf=\"!options.filterable && options.toggleAll\"></p-tableHeaderCheckbox>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns\">\r\n <th *ngIf=\"!col.invisible\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': col.backgroundColor ? col.backgroundColor : null }\"\r\n [ngClass]=\"{ 'text-center' : options.centerHeaders, 'headerAffichageSimple': !options.headersAffichageEntier, 'headerAffichageEntier': options.headersAffichageEntier }\"\r\n [pSortableColumn]=\"col.id\"\r\n [pSortableColumnDisabled]=\"!options.sortable || options.grouping != null || col.libelle == null || col.libelle == ''\"\r\n id=\"{{ col.id }}\"\r\n (click)=\"refreshData()\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n [pTooltip]=\"col.libelle\"\r\n [tooltipDisabled]=\"!col.tooltipHeader\"\r\n tooltipPosition=\"bottom\">\r\n <div [ngStyle]=\"{ 'color': col.textColor ? col.textColor : null }\">\r\n {{ col.libelle }}\r\n </div>\r\n <p-sortIcon *ngIf=\"options.sortable && options.grouping == null && col.libelle != null && col.libelle != ''\"\r\n [field]=\"col.id\">\r\n </p-sortIcon>\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n\r\n <!-- FILTRES -->\r\n <tr *ngIf=\"options.filterable\" class=\"rowFilter\">\r\n\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n <p-tableHeaderCheckbox *ngIf=\"options.toggleAll\"></p-tableHeaderCheckbox>\r\n </th>\r\n\r\n <ng-container *ngFor=\"let col of columns\">\r\n <!-- Text -->\r\n <th *ngIf=\"!col.invisible && ((checkType('Dropdown', col) && col.options.filterText)\r\n || (checkType('MultiSelect', col) && col.options.filterText)\r\n || checkType('Text', col)\r\n || checkType('File', col)\r\n || (checkType('Button', col) && col.options.filterCol))\r\n || checkType('Number', col)\r\n || checkType('CilogNumber', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <input *ngIf=\"!col.disableFilter\"\r\n pInputText\r\n type=\"text\"\r\n (input)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </th>\r\n\r\n <!-- Date -->\r\n <th *ngIf=\"!col.invisible && checkType('Date', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-calendar *ngIf=\"!col.disableFilter\"\r\n [view]=\"getOption(col, rowData, 'mode') == null ? 'date' : getOption(col, rowData, 'mode')\"\r\n [dateFormat]=\"getOption(col, rowData, 'mode') == 'year' ? 'yy' : getOption(col, rowData, 'mode') == 'month' ? 'mm/yy' : 'dd/mm/yy'\"\r\n [inputId]=\"col.id + '_filter'\"\r\n firstDayOfWeek=\"1\"\r\n [readonlyInput]=\"true\"\r\n appendTo=\"body\"\r\n selectionMode=\"range\"\r\n (onSelect)=\"onFilterCol($event, col)\"\r\n showButtonBar=\"true\"\r\n (onClearClick)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </p-calendar>\r\n </th>\r\n\r\n <!-- Liste -->\r\n <th *ngIf=\"!col.invisible && ((checkType('Dropdown', col) && !col.options.filterText) || (checkType('MultiSelect', col) && !col.options.filterText) || checkType('SelectButton', col) || checkType('State', col))\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-multiSelect *ngIf=\"!col.disableFilter\"\r\n [options]=\"col.options?.options\"\r\n [filter]=\"true\"\r\n dataKey=\"ID\"\r\n [optionLabel]=\"col.options?.optionLabel\"\r\n appendTo=\"body\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [virtualScroll]=\"true\"\r\n [virtualScrollItemSize]=\"35\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\"\r\n [group]=\"col.options.optionGroupChildren != null ? true : false\"\r\n [optionGroupLabel]=\"col.options.optionGroupLabel\"\r\n [optionGroupChildren]=\"col.options.optionGroupChildren\"\r\n [showToggleAll]=\"false\"\r\n [showClear]=\"true\"\r\n (onClear)=\"onFilterCol(null, col)\">\r\n <ng-template let-group pTemplate=\"group\">\r\n <div>{{group[col.options.optionGroupLabel]}}</div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </th>\r\n\r\n <!-- Switch -->\r\n <th *ngIf=\"!col.invisible && checkType('Switch', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <p-multiSelect *ngIf=\"!col.disableFilter\"\r\n [options]=\"optionsSwitch\"\r\n [showHeader]=\"false\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n appendTo=\"body\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [virtualScrollItemSize]=\"30\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"onFilterCol($event, col)\"\r\n [(ngModel)]=\"col.options.defaultFilters\">\r\n </p-multiSelect>\r\n </th>\r\n\r\n <!-- Non filtrable -->\r\n <th *ngIf=\"!col.invisible && (checkType('Image', col) || (checkType('Button', col) && !col.options.filterCol))\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n\r\n <!-- TOTAL -->\r\n <tr *ngIf=\"options.rowTotal\"\r\n class=\"rowTotal\">\r\n <th class=\"cellDelete\"\r\n *ngIf=\"isModeCheckboxSelection()\"\r\n pFrozenColumn>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns\">\r\n <th *ngIf=\"!col.invisible\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null }\"\r\n [ngClass]=\"{ 'text-center' : true }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div>{{ getTotalStr(col) }}</div>\r\n </th>\r\n </ng-container>\r\n <th class=\"cellDelete\" *ngIf=\"options.rowsDeletable\"></th>\r\n </tr>\r\n </ng-template>\r\n\r\n <!--Groupheader-->\r\n <ng-template pTemplate=\"groupheader\" let-rowData>\r\n <tr pRowGroupHeader class=\"rowGrouping\">\r\n <td [attr.colspan]=\"columns.length\">\r\n <div class=\"text_bold\">{{ rowData[options.grouping.obj][options.grouping.libelle] }}</div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- Body -->\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\">\r\n <tr id=\"{{ rowData.id }}\"\r\n [ngStyle]=\"{ 'background-color': rowData.color ? rowData.color : null }\"\r\n [pSelectableRow]=\"rowData\"\r\n [pSelectableRowDisabled]=\"!options.selectable || isModeCheckboxSelection() || isModeCellSelection()\"\r\n (dblclick)=\"onRowDoubleClickEvent(rowData)\"\r\n [pContextMenuRow]=\"rowData\"\r\n [pContextMenuRowDisabled]=\"options.contextMenuItems == null\">\r\n\r\n <td *ngIf=\"isModeCheckboxSelection()\"\r\n class=\"cellDelete\"\r\n pFrozenColumn>\r\n <p-tableCheckbox [value]=\"rowData\" [disabled]=\"rowData.readonly\"></p-tableCheckbox>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let col of columns\">\r\n\r\n <!-- Text -->\r\n <td *ngIf=\"!col.invisible && checkType('Text', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [frozen]=\"col.frozen\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <input pInputText\r\n type=\"text\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n (blur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (keydown.enter)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (keydown.tab)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (click)=\"onEditInitCell(rowData, col, rowData[col.id].value)\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\" />\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedText(col, rowData) }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Text', col) && (!isModeEdition() || rowData.readonly || rowData[col.id]?.readonly)\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color' : rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">\r\n {{ col.libelle }} :\r\n </div>\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedText(col, rowData) }}\r\n </div>\r\n </td>\r\n\r\n <!-- Dropdown -->\r\n <td *ngIf=\"!col.invisible && checkType('Dropdown', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"paddingCell\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <p-dropdown *ngIf=\"rowData[col.id] != null\"\r\n dataKey=\"ID\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [autoDisplayFirst]=\"false\"\r\n appendTo=\"body\"\r\n [showClear]=\"getOption(col, rowData, 'deletable')\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [virtualScrollItemSize]=\"30\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-data pTemplate=\"selectedItem\">\r\n <span *ngIf=\"data != null\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ data[getOption(col, rowData, 'optionLabel')] }}\r\n </span>\r\n <span *ngIf=\"data == null\"></span>\r\n </ng-template>\r\n </p-dropdown>\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : '' }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n <!--<p-dropdown *ngIf=\"rowData[col.id] != null\"\r\n dataKey=\"ID\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [autoDisplayFirst]=\"false\"\r\n appendTo=\"body\"\r\n [showClear]=\"getOption(col, rowData, 'deletable')\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [virtualScrollItemSize]=\"30\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-data pTemplate=\"selectedItem\">\r\n <span *ngIf=\"data != null\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ data[getOption(col, rowData, 'optionLabel')] }}\r\n </span>\r\n <span *ngIf=\"data == null\"></span>\r\n </ng-template>\r\n </p-dropdown>-->\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Dropdown', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value != null ? rowData[col.id].value[getOption(col, rowData, 'optionLabel')] : '' }}</div>\r\n </td>\r\n\r\n <!-- Cilog Number -->\r\n <td *ngIf=\"!col.invisible && checkType('CilogNumber', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <cilog-input-number *ngIf=\"rowData[col.id] && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n (onInput)=\"onInputNumber($event)\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [textColor]=\"rowData[col.id].textColor\"\r\n [bold]=\"rowData.bold == true || rowData[col.id].bold == true\"\r\n [italic]=\"rowData.italic == true || rowData[col.id].italic == true\"\r\n [suffixe]=\"getOption(col, rowData, 'suffix')\"\r\n [prefixe]=\"getOption(col, rowData, 'prefix') != null ? getOption(col, rowData, 'prefix') + ' ' : null\"\r\n [min]=\"getOption(col, rowData, 'min')\"\r\n [max]=\"getOption(col, rowData, 'max')\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [maxDecimals]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'maxDecimales') != null ? getOption(col, rowData, 'maxDecimales') : 2 \"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onFocus)=\"onEditInitCell(rowData, col, rowData[col.id].value)\">\r\n </cilog-input-number>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('CilogNumber', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getFormattedNumber(col, rowData, rowData[col.id].value) }}</div>\r\n </td>\r\n\r\n <!-- Number -->\r\n <td *ngIf=\"!col.invisible && checkType('Number', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n [pEditableColumn]=\"rowData\"\r\n [pEditableColumnField]=\"col.id\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left',\r\n 'text-right': col.position == 'right' || col.position == null,\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-cellEditor>\r\n <ng-template pTemplate=\"input\">\r\n <p-inputNumber #inputNumber\r\n *ngIf=\"rowData[col.id] && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n locale=\"fr-FR\"\r\n (onInput)=\"onInputNumber($event)\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [showButtons]=\"getOption(col, rowData, 'showButtons')\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [inputStyle]=\"{ 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null, 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null }\"\r\n [suffix]=\"getOption(col, rowData, 'suffix')\"\r\n [prefix]=\"getOption(col, rowData, 'prefix') != null ? getOption(col, rowData, 'prefix') + ' ' : null\"\r\n [min]=\"getOption(col, rowData, 'min')\"\r\n [max]=\"getOption(col, rowData, 'max')\"\r\n [minFractionDigits]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'minDecimales') != null ? getOption(col, rowData, 'minDecimales') : 0\"\r\n [maxFractionDigits]=\"getOption(col, rowData, 'modeInteger') != null && getOption(col, rowData, 'modeInteger') == true ? 0 : getOption(col, rowData, 'maxDecimales') != null ? getOption(col, rowData, 'maxDecimales') : 2 \"\r\n (onBlur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onKeyDown)=\"onKeyDown($event, rowData, col, rowData[col.id].value)\"\r\n (onFocus)=\"onEditInitCell($event, rowData, col, rowData[col.id].value)\"\r\n [step]=\"0\">\r\n </p-inputNumber>\r\n </ng-template>\r\n <ng-template pTemplate=\"output\">\r\n <div *ngIf=\"rowData[col.id]\"\r\n style=\"white-space: pre;\">\r\n {{ getFormattedNumber(col, rowData, rowData[col.id].value) }}\r\n </div>\r\n </ng-template>\r\n </p-cellEditor>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Number', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | value\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left',\r\n 'text-right': col.position == 'right' || col.position == null,\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getFormattedNumber(col, rowData, rowData[col.id].value) }}</div>\r\n </td>\r\n\r\n <!-- Date -->\r\n <td *ngIf=\"!col.invisible && checkType('Date', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getOption(col, rowData, 'mode') == 'year' ? (rowData[col.id].value | date: 'yyyy') : getOption(col, rowData, 'mode') == 'month' ? (rowData[col.id].value | date: 'MM/yy') : getOption(col, rowData, 'mode') == 'hour' ? (rowData[col.id].value | date: 'HH:mm') : getOption(col, rowData, 'mode') == 'datehour' ? (rowData[col.id].value | date: 'dd/MM/yy HH:mm') : (rowData[col.id].value | date: 'dd/MM/yyyy')\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-calendar [(ngModel)]=\"rowData[col.id].value\"\r\n [view]=\"getOption(col, rowData, 'mode') == null || getOption(col, rowData, 'mode') == 'date' || getOption(col, rowData, 'mode') == 'hour' ? 'date' : getOption(col, rowData, 'mode') == 'datehour' ? 'date' : getOption(col, rowData, 'mode')\"\r\n [dateFormat]=\"getOption(col, rowData, 'mode') == 'year' ? 'yy' : getOption(col, rowData, 'mode') == 'month' ? 'mm/yy' : getOption(col, rowData, 'mode') == 'hour' || getOption(col, rowData, 'mode') == 'datehour' ? 'dd/mm/yy' : 'dd/mm/yy'\"\r\n [showTime]=\"getOption(col, rowData, 'mode') == 'datehour'\"\r\n [timeOnly]=\"getOption(col, rowData, 'mode') == 'hour'\"\r\n [hourFormat]=\"24\"\r\n firstDayOfWeek=\"1\"\r\n (onSelect)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onBlur)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n (onClear)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n [inputStyleClass]=\"col.position == null || col.position == 'right' ? 'text-right' : col.position == 'left' ? 'text-left' : 'text-center'\"\r\n [inputStyle]=\"{ 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null, 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null }\"\r\n [showClear]=\"getOption(col, rowData, 'clear')\"\r\n [minDate]=\"getOption(col, rowData, 'minDate')\"\r\n [maxDate]=\"getOption(col, rowData, 'maxDate')\"\r\n [defaultDate]=\"getOption(col, rowData, 'defaultDate')\"\r\n appendTo=\"body\">\r\n </p-calendar>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('Date', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'min-width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value | date: 'dd/MM/yyyy'\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value | date: (getOption(col, rowData, 'mode') == 'year' ? 'yyyy' : getOption(col, rowData, 'mode') == 'month' ? 'MM/yyyy' : 'dd/MM/yyyy') }}</div>\r\n </td>\r\n\r\n <!-- MultiSelect -->\r\n <td *ngIf=\"!col.invisible && checkType('MultiSelect', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel'))\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"paddingCell\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-multiSelect *ngIf=\"rowData[col.id] != null\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [filter]=\"getOption(col, rowData, 'filter')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n appendTo=\"body\"\r\n dataKey=\"ID\"\r\n emptyFilterMessage=\"Aucun r\u00E9sultat\"\r\n emptyMessage=\"Aucun r\u00E9sultat\"\r\n [baseZIndex]=\"getOption(col, rowData, 'baseZIndex')\"\r\n [virtualScroll]=\"getOption(col, rowData, 'virtualScroll')\"\r\n [readonly]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\"\r\n [virtualScrollItemSize]=\"30\"\r\n selectedItemsLabel=\"{0} selectionn\u00E9s\"\r\n (onChange)=\"editMultiselect(rowData, col, $event)\"\r\n [showToggleAll]=\"false\"\r\n [showHeader]=\"getOption(col, rowData, 'filter')\"\r\n [group]=\"getOption(col, rowData, 'optionGroupChildren') != null ? true : false\"\r\n [optionGroupLabel]=\"getOption(col, rowData, 'optionGroupLabel')\"\r\n [optionGroupChildren]=\"getOption(col, rowData, 'optionGroupChildren')\"\r\n ngDefaultControl>\r\n <ng-template let-data pTemplate=\"selectedItems\">\r\n <span *ngFor=\"let option of data, let i = index\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ option[getOption(col, rowData, 'optionLabel')] + (i != data.length - 1 ? ',' : '') }}\r\n </span>\r\n </ng-template>\r\n <ng-template let-group pTemplate=\"group\">\r\n <div>{{group[col.options.optionGroupLabel]}}</div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('MultiSelect', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel'))\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getMultiSelectConcat(rowData[col.id].value, getOption(col, rowData, 'optionLabel')) }}</div>\r\n </td>\r\n\r\n <!-- Image -->\r\n <td *ngIf=\"!col.invisible && checkType('Image', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n class=\"text-center\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <img *ngIf=\"rowData[col.id]\" style=\"vertical-align: middle; width: 40px;\" src=\"{{ rowData[col.id].value }}\" />\r\n </td>\r\n\r\n <!-- Button -->\r\n <td *ngIf=\"!col.invisible && checkType('Button', col)\"\r\n class=\"paddingCell text-center\"\r\n [ngClass]=\"{\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <button pButton\r\n *ngIf=\"rowData[col.id].value != null && isValueButtonByType(rowData[col.id].value, 'function')\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly\"\r\n [label]=\"getOption(col, rowData, 'label')\"\r\n [icon]=\"getOption(col, rowData, 'icon')\"\r\n (click)=\"rowData[col.id].value()\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : getOption(col, rowData, 'label')\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n [class]=\"'p-button-' + getOption(col, rowData, 'severity')\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n </button>\r\n <div *ngIf=\"isValueButtonByType(rowData[col.id].value, 'string')\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value\"\r\n [tooltipDisabled]=\"!col.tooltip\">\r\n {{ rowData[col.id].value }}\r\n </div>\r\n </td>\r\n\r\n <!-- SelectButton -->\r\n <td *ngIf=\"!col.invisible && checkType('SelectButton', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-selectButton *ngIf=\"rowData[col.id] != null\"\r\n [options]=\"getOption(col, rowData, 'options')\"\r\n [optionLabel]=\"getOption(col, rowData, 'optionLabel')\"\r\n [optionValue]=\"getOption(col, rowData, 'optionValue') != null ? getOption(col, rowData, 'optionValue') : 'value'\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <span class=\"text-center w-full\"\r\n [ngClass]=\"{\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\">\r\n {{ item.label }}\r\n </span>\r\n </ng-template>\r\n </p-selectButton>\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('SelectButton', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\"\r\n class=\"text-center\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ getSelectLibelleByValue(rowData, col) }}</div>\r\n </td>\r\n\r\n <!-- Switch -->\r\n <td *ngIf=\"!col.invisible && checkType('Switch', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n class=\"text-center\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-inputSwitch *ngIf=\"rowData[col.id] != null\"\r\n [(ngModel)]=\"rowData[col.id].value\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || (getOption(col, rowData, 'action') == null && !isModeEdition())\"\r\n (onChange)=\"onEditCell(rowData, col, rowData[col.id].value)\"\r\n ngDefaultControl>\r\n </p-inputSwitch>\r\n </td>\r\n\r\n <!-- File -->\r\n <td *ngIf=\"!col.invisible && checkType('File', col) && isModeEdition() && !rowData.readonly && !rowData[col.id]?.readonly\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div class=\"p-inputgroup\" *ngIf=\"rowData[col.id] != null\">\r\n <button type=\"button\"\r\n pButton\r\n pRipple\r\n icon=\"pi pi-upload\"\r\n (click)=\"clickById('input_' + rowData[col.id].id)\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\">\r\n </button>\r\n <input id=\"{{'output_' + rowData[col.id].id}}\"\r\n pInputText\r\n type=\"text\"\r\n [ngClass]=\"{\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true\r\n }\"\r\n value=\"{{ rowData[col.id].value != null ? rowData[col.id].value : '' }}\"\r\n readonly\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value ? rowData[col.id].value : ''\"\r\n [tooltipDisabled]=\"!col.tooltip\">\r\n <button *ngIf=\"getOption(col, rowData, 'downloadPath') && rowData[col.id].value != null\"\r\n type=\"button\"\r\n pButton\r\n pRipple\r\n icon=\"pi pi-download\"\r\n (click)=\"downloadFile(rowData[col.id])\"\r\n [disabled]=\"rowData.readonly || rowData[col.id]?.readonly || !isModeEdition()\">\r\n </button>\r\n </div>\r\n <input *ngIf=\"rowData[col.id]\" id=\"{{'input_' + rowData[col.id].id}}\" #inputFile pInputText type=\"file\" hidden (change)=\"rowData[col.id].value = inputFile.files[0].name; onEditCell(rowData, col, inputFile.files[0])\">\r\n </td>\r\n <td *ngIf=\"!col.invisible && checkType('File', col) && (rowData.readonly || rowData[col.id]?.readonly || !isModeEdition())\"\r\n [ngStyle]=\"{\r\n 'width' : col.width ? col.width : null,\r\n 'background-color': rowData[col.id].color ? rowData[col.id].color : null,\r\n 'color' : rowData[col.id].textColor ? rowData[col.id].textColor : null\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [pTooltip]=\"rowData[col.id].tooltip != null ? rowData[col.id].tooltip : rowData[col.id].value ? rowData[col.id].value : ''\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'text-left': col.position == 'left' || col.position == null,\r\n 'text-right': col.position == 'right',\r\n 'text-center': col.position == 'center',\r\n 'font-bold': rowData.bold == true || rowData[col.id].bold == true,\r\n 'font-italic': rowData.italic == true || rowData[col.id].italic == true,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n [tooltipDisabled]=\"!col.tooltip\"\r\n tooltipPosition=\"bottom\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <div *ngIf=\"rowData[col.id]\">{{ rowData[col.id].value ? rowData[col.id].value : '' }}</div>\r\n </td>\r\n\r\n <!-- State -->\r\n <td *ngIf=\"!col.invisible && checkType('State', col)\"\r\n [ngStyle]=\"{ 'width' : col.width ? col.width : null, 'background-color': rowData[col.id].color ? rowData[col.id].color : null }\"\r\n id=\"{{ rowData[col.id] != null ? rowData[col.id].id : '' }}\"\r\n [ngClass]=\"{\r\n 'paddingCell': rowData[col.id] != null,\r\n 'selectable_cell' : options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection\r\n }\"\r\n (click)=\"options.selectable && isModeCellSelection() && !rowData[col.id].disableSelection && onSelectCell(rowData[col.id])\"\r\n class=\"text-center\"\r\n pFrozenColumn\r\n [frozen]=\"col.frozen\">\r\n <div class=\"p-column-title\">{{ col.libelle }} : </div>\r\n <p-tag *ngIf=\"rowData[col.id].value != null\"\r\n [value]=\"rowData[col.id].value[getOption(col, rowData, 'optionLabel')]\"\r\n [severity]=\"rowData[col.id].value.severity\"\r\n [icon]=\"rowData[col.id].value.icon\"\r\n [style]=\"{\r\n 'background-color': rowData[col.id].value.backgroundColor,\r\n 'color': rowData[col.id].value.textColor,\r\n 'font-weight': rowData.bold == true || rowData[col.id].bold == true ? 'bold' : null,\r\n 'font-style': rowData.italic == true || rowData[col.id].italic == true ? 'italic' : null\r\n }\">\r\n </p-tag>\r\n </td>\r\n\r\n </ng-container>\r\n\r\n <!-- Deletion -->\r\n <td *ngIf=\"options.rowsDeletable\"\r\n class=\"cellDelete\"\r\n [ngClass]=\"rowData.deletable ? 'paddingCell' : null\">\r\n <button *ngIf=\"rowData.deletable\"\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-times\"\r\n class=\"p-button-danger buttonDelete p-button-text\"\r\n [disabled]=\"rowData.readonly\"\r\n (click)=\"onDeleteLine(rowData)\">\r\n </button>\r\n </td>\r\n\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n</div>\r\n", styles: ["::ng-deep .p-tooltip .p-tooltip-text{overflow-wrap:break-word!important}:host ::ng-deep .grid_brown .rowHeader>th{background-color:#795548}:host ::ng-deep .grid_brown .rowHeader>th div{color:#fff}:host ::ng-deep .grid_brown .rowHeader>th i{color:#fff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column:hover{background-color:#a47767}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column:hover i{color:#fff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column.p-highlight div{color:#76c7ff}:host ::ng-deep .grid_brown .rowHeader .p-sortable-column.p-highlight .p-sortable-column-icon{color:#76c7ff}:host ::ng-deep .grid_brown .rowFilter th{background-color:#795548}:host ::ng-deep .grid_grey .rowHeader>th{background-color:#dedddd}:host ::ng-deep .grid_grey .rowHeader>th div{color:#495057}:host ::ng-deep .grid_grey .rowHeader>th i{color:#495057}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column:hover{background-color:#e7e7e7}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column:hover i{color:#495057}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column.p-highlight div{color:#008bff}:host ::ng-deep .grid_grey .rowHeader .p-sortable-column.p-highlight .p-sortable-column-icon{color:#008bff}:host ::ng-deep .grid_grey .rowFilter th{background-color:#dedddd}:host ::ng-deep .selectable_cell:hover{background:#dcdcdc!important;cursor:pointer!important}:host ::ng-deep .p-frozen-column{z-index:2!important}:host ::ng-deep .p-datatable-thead{z-index:3!important}:host ::ng-deep .p-checkbox{border-radius:inherit!important}:host ::ng-deep p-inputnumber{width:100%}:host ::ng-deep .p-calendar,:host ::ng-deep .p-inputtext,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber-input,:host ::ng-deep .p-dropdown,:host ::ng-deep .p-multiselect{width:100%}:host ::ng-deep .suffixe,:host ::ng-deep .prefixe{height:25px;padding-top:1px!important}:host ::ng-deep .p-multiselect-label-container,:host ::ng-deep .p-dropdown-label{width:1px!important}:host ::ng-deep .p-scroller-content{min-height:50%}:host ::ng-deep .rowTotal>th{background-color:#edcbaa!important}:host ::ng-deep .rowGrouping{background:#faeada!important}:host ::ng-deep .p-inputswitch.p-inputswitch-checked .p-inputswitch-slider{background:#30e130}:host ::ng-deep .p-inputswitch.p-inputswitch-checked:not(.p-disabled):hover .p-inputswitch-slider{background:#2bd12b}:host ::ng-deep .p-datatable-table{table-layout:fixed}:host ::ng-deep .p-datatable-thead>tr>th{border:1px solid rgba(0,0,0,.12)!important;padding:8px;font-weight:600;height:40px}:host ::ng-deep .headerAffichageSimple div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .headerAffichageEntier{word-wrap:break-word}:host ::ng-deep .p-datatable-tbody>tr>td{border:1px solid rgba(0,0,0,.12)!important;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-datatable-tbody>tr>td div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-tag{max-width:100%}:host ::ng-deep .p-tag .p-tag-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host ::ng-deep .p-button{padding:5px;max-width:100%}:host ::ng-deep .p-button .p-button-label{overflow:hidden!important;white-space:nowrap!important;text-overflow:ellipsis!important}:host ::ng-deep .text_bold{font-weight:700!important}:host ::ng-deep .cellDelete{flex:0 0 50px!important;width:50px;text-align:center!important;padding:0!important}:host ::ng-deep .p-tooltip .p-tooltip-text{background-color:red!important}:host ::ng-deep .p-skeleton{background-color:#dee2e6;border-radius:6px;padding:0}:host ::ng-deep .p-datatable-tbody>tr{height:35px}:host ::ng-deep .p-inputtext{height:25px!important;padding:4px 5px!important}:host ::ng-deep .p-inputnumber{height:25px;padding:0!important}:host ::ng-deep .p-inputnumber-input{padding:0 5px!important}:host ::ng-deep .p-inputgroup .p-inputtext{height:25px;padding:4px 5px!important}:host ::ng-deep .p-dropdown,:host ::ng-deep .p-multiselect{vertical-align:middle}:host ::ng-deep .p-dropdown-label{padding-top:2px;padding-bottom:2px}:host ::ng-deep .p-multiselect-label{padding-top:2px;padding-bottom:2px}:host ::ng-deep .p-editable-column{padding:3px 10px!important}:host ::ng-deep .paddingCell{padding:3px 10px!important}:host ::ng-deep .p-selectbutton>.p-button{width:50%;height:25px}:host ::ng-deep .p-inputgroup>.p-button{height:25px}:host ::ng-deep .buttonDelete{width:100%;height:20px}:host ::ng-deep .p-column-title{display:none}:host ::ng-deep .p-datatable-loading-icon{color:#fff}\n"] }]
|
|
633
|
+
}], ctorParameters: () => [{ type: i1.ConfirmationService }, { type: i1.FilterService }, { type: i0.ChangeDetectorRef }, { type: i2.ExportService }], propDecorators: { columns: [{
|
|
634
|
+
type: Input
|
|
635
|
+
}], columnsChange: [{
|
|
636
|
+
type: Output
|
|
637
|
+
}], values: [{
|
|
638
|
+
type: Input
|
|
639
|
+
}], valuesChange: [{
|
|
640
|
+
type: Output
|
|
641
|
+
}], options: [{
|
|
642
|
+
type: Input
|
|
643
|
+
}], loading: [{
|
|
644
|
+
type: Input
|
|
645
|
+
}], onEdit: [{
|
|
646
|
+
type: Output
|
|
647
|
+
}], onEditInit: [{
|
|
648
|
+
type: Output
|
|
649
|
+
}], onDelete: [{
|
|
650
|
+
type: Output
|
|
651
|
+
}], onSelect: [{
|
|
652
|
+
type: Output
|
|
653
|
+
}], onUnselect: [{
|
|
654
|
+
type: Output
|
|
655
|
+
}], onFilter: [{
|
|
656
|
+
type: Output
|
|
657
|
+
}], onFilterInit: [{
|
|
658
|
+
type: Output
|
|
659
|
+
}], onSort: [{
|
|
660
|
+
type: Output
|
|
661
|
+
}], onPage: [{
|
|
662
|
+
type: Output
|
|
663
|
+
}], onRowDoubleClick: [{
|
|
664
|
+
type: Output
|
|
665
|
+
}], table: [{
|
|
666
|
+
type: ViewChild,
|
|
667
|
+
args: ['table', { static: true }]
|
|
668
|
+
}], cm: [{
|
|
669
|
+
type: ViewChild,
|
|
670
|
+
args: ['cm']
|
|
671
|
+
}], inputNumber: [{
|
|
672
|
+
type: ViewChild,
|
|
673
|
+
args: ['inputNumber']
|
|
674
|
+
}] } });
|
|
675
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2lsb2ctbGliL3NyYy9saWIvdmlld3MvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2lsb2ctbGliL3NyYy9saWIvdmlld3MvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBSzdHLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBVXpFLE1BQU0sT0FBTyxtQkFBbUI7SUFxQzVCLFlBQ1ksbUJBQXdDLEVBQ3hDLGFBQTRCLEVBQzVCLEtBQXdCLEVBQ3hCLGFBQTRCO1FBSDVCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDeEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUF2Q3hDLGVBQVUsR0FBWSxJQUFJLENBQUM7UUFHakIsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBYSxDQUFDO1FBRzlDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQU0xQyxXQUFNLEdBQTJCLElBQUksWUFBWSxFQUFZLENBQUM7UUFDOUQsZUFBVSxHQUEyQixJQUFJLFlBQVksRUFBWSxDQUFDO1FBQ2xFLGFBQVEsR0FBK0IsSUFBSSxZQUFZLEVBQWdCLENBQUM7UUFDeEUsYUFBUSxHQUE2QixJQUFJLFlBQVksRUFBYyxDQUFDO1FBQ3BFLGVBQVUsR0FBNkIsSUFBSSxZQUFZLEVBQWMsQ0FBQztRQUN0RSxhQUFRLEdBQTBCLElB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QkNmaEMscWtyRUEwNkJBOzs0RkQzNUJhLG1CQUFtQjtrQkFML0IsU0FBUzsrQkFDSSxhQUFhO2dMQVFkLE9BQU87c0JBQWYsS0FBSztnQkFDSSxhQUFhO3NCQUF0QixNQUFNO2dCQUVFLE1BQU07c0JBQWQsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUVFLE9BQU87c0JBQWYsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUksTUFBTTtzQkFBZixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxRQUFRO3NCQUFqQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQVUrQixLQUFLO3NCQUExQyxTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ25CLEVBQUU7c0JBQWxCLFNBQVM7dUJBQUMsSUFBSTtnQkFDVyxXQUFXO3NCQUFwQyxTQUFTO3VCQUFDLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQsIENoYW5nZURldGVjdG9yUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbmZpcm1hdGlvblNlcnZpY2UsIEZpbHRlclNlcnZpY2UsIExhenlMb2FkRXZlbnQsIFNvcnRFdmVudCB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgSUVkaXRpb24sIElTdXBwcmVzc2lvbiwgSVNlbGVjdGlvbiwgSUZpbHRlciwgSVNvcnQsIElQYWdlLCBJU29ydEN1c3RvbSB9IGZyb20gJy4uLy4uL2hlbHBlcnMvaW50ZXJmYWNlcy9lZGl0aW9uLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IElDb2x1bW4sIElSb3csIElPcHRpb25zR3JpbGxlLCBJQ2VsbCwgSU9wdGlvbnNGaWxlLCBJT3B0aW9uc011bHRpU2VsZWN0LCBJT3B0aW9uc0Ryb3Bkb3duLCBJT3B0aW9uc051bWJlciB9IGZyb20gJy4uLy4uL2hlbHBlcnMvaW50ZXJmYWNlcy9ncmlsbGUuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgVGFibGUgfSBmcm9tICdwcmltZW5nL3RhYmxlJztcclxuaW1wb3J0IHsgQ29sVHlwZSwgTW9kZVNlbGVjdGlvbiB9IGZyb20gJy4uLy4uL2hlbHBlcnMvZW51bXMvZ3JpbGxlLmVudW0nO1xyXG5pbXBvcnQgeyBFeHBvcnRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZXhjZWwuc2VydmljZSc7XHJcbmltcG9ydCB7IENvbnRleHRNZW51IH0gZnJvbSAncHJpbWVuZy9jb250ZXh0bWVudSc7XHJcbmltcG9ydCB7IElucHV0TnVtYmVyIH0gZnJvbSAncHJpbWVuZy9pbnB1dG51bWJlcic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnY2lsb2ctdGFibGUnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL3RhYmxlLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIENpbG9nVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICAgIGluaXRGaWx0ZXI6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAgIEBJbnB1dCgpIGNvbHVtbnM6IElDb2x1bW5bXTtcclxuICAgIEBPdXRwdXQoKSBjb2x1bW5zQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxJQ29sdW1uW10+KCk7XHJcblxyXG4gICAgQElucHV0KCkgdmFsdWVzOiBJUm93W107XHJcbiAgICBAT3V0cHV0KCkgdmFsdWVzQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxJUm93W10+KCk7XHJcblxyXG4gICAgQElucHV0KCkgb3B0aW9uczogSU9wdGlvbnNHcmlsbGU7XHJcblxyXG4gICAgQElucHV0KCkgbG9hZGluZzogYm9vbGVhbjtcclxuXHJcbiAgICBAT3V0cHV0KCkgb25FZGl0OiBFdmVudEVtaXR0ZXI8SUVkaXRpb24+ID0gbmV3IEV2ZW50RW1pdHRlcjxJRWRpdGlvbj4oKTtcclxuICAgIEBPdXRwdXQoKSBvbkVkaXRJbml0OiBFdmVudEVtaXR0ZXI8SUVkaXRpb24+ID0gbmV3IEV2ZW50RW1pdHRlcjxJRWRpdGlvbj4oKTtcclxuICAgIEBPdXRwdXQoKSBvbkRlbGV0ZTogRXZlbnRFbWl0dGVyPElTdXBwcmVzc2lvbj4gPSBuZXcgRXZlbnRFbWl0dGVyPElTdXBwcmVzc2lvbj4oKTtcclxuICAgIEBPdXRwdXQoKSBvblNlbGVjdDogRXZlbnRFbWl0dGVyPElTZWxlY3Rpb24+ID0gbmV3IEV2ZW50RW1pdHRlcjxJU2VsZWN0aW9uPigpO1xyXG4gICAgQE91dHB1dCgpIG9uVW5zZWxlY3Q6IEV2ZW50RW1pdHRlcjxJU2VsZWN0aW9uPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVNlbGVjdGlvbj4oKTtcclxuICAgIEBPdXRwdXQoKSBvbkZpbHRlcjogRXZlbnRFbWl0dGVyPElGaWx0ZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxJRmlsdGVyPigpO1xyXG4gICAgQE91dHB1dCgpIG9uRmlsdGVySW5pdDogRXZlbnRFbWl0dGVyPElSb3dbXT4gPSBuZXcgRXZlbnRFbWl0dGVyPElSb3dbXT4oKTtcclxuICAgIEBPdXRwdXQoKSBvblNvcnQ6IEV2ZW50RW1pdHRlcjxJU29ydD4gPSBuZXcgRXZlbnRFbWl0dGVyPElTb3J0PigpO1xyXG4gICAgQE91dHB1dCgpIG9uUGFnZTogRXZlbnRFbWl0dGVyPElQYWdlPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBhZ2U+KCk7XHJcbiAgICBAT3V0cHV0KCkgb25Sb3dEb3VibGVDbGljazogRXZlbnRFbWl0dGVyPElTZWxlY3Rpb24+ID0gbmV3IEV2ZW50RW1pdHRlcjxJU2VsZWN0aW9uPigpO1xyXG5cclxuICAgIHNlbGVjdGVkUm93czogSVJvd1tdIHwgSVJvdztcclxuXHJcbiAgICBmaWx0ZXJEYXRlc1JhbmdlOiBEYXRlW107XHJcblxyXG4gICAgb3B0aW9uc1N3aXRjaDogYW55W107XHJcblxyXG4gICAgY29udGV4dE1lbnVTZWxlY3RlZEl0ZW06IElSb3c7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgndGFibGUnLCB7IHN0YXRpYzogdHJ1ZSB9KSB0YWJsZTogVGFibGU7XHJcbiAgICBAVmlld0NoaWxkKCdjbScpIGNtOiBDb250ZXh0TWVudTtcclxuICAgIEBWaWV3Q2hpbGQoJ2lucHV0TnVtYmVyJykgaW5wdXROdW1iZXI6IElucHV0TnVtYmVyO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgY29uZmlybWF0aW9uU2VydmljZTogQ29uZmlybWF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIGZpbHRlclNlcnZpY2U6IEZpbHRlclNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBleHBvcnRTZXJ2aWNlOiBFeHBvcnRTZXJ2aWNlXHJcbiAgICApIHsgfVxyXG5cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMub3B0aW9uc1N3aXRjaCA9IFtcclxuICAgICAgICAgICAgeyBsYWJlbDogJ091aScsIHZhbHVlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgbGFiZWw6ICdOb24nLCB2YWx1ZTogZmFsc2UgfSxcclxuICAgICAgICBdXHJcblxyXG4gICAgICAgIC8vIERhdGVcclxuICAgICAgICB0aGlzLmZpbHRlclNlcnZpY2UucmVnaXN0ZXIoJ2RhdGVSYW5nZUZpbHRlcicsIChjZWxsLCBmaWx0ZXIpID0+IHtcclxuICAgICAgICAgICAgaWYgKGZpbHRlciA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgc3RhcnQ6IG51bWJlciA9IGZpbHRlclswXS5nZXRUaW1lKCk7XHJcbiAgICAgICAgICAgIGxldCBlbmQ6IG51bWJlcjtcclxuICAgICAgICAgICAgbGV0IGVuZERhdGU6IERhdGU7XHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJbMV0pIHtcclxuICAgICAgICAgICAgICAgIGVuZERhdGUgPSBuZXcgRGF0ZShmaWx0ZXJbMV0uZ2V0RnVsbFllYXIoKSwgZmlsdGVyWzFdLmdldE1vbnRoKCksIGZpbHRlclsxXS5nZXREYXRlKCksIDIzLCA1OSwgNTkpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZW5kRGF0ZSA9IG5ldyBEYXRlKGZpbHRlclswXS5nZXRGdWxsWWVhcigpLCBmaWx0ZXJbMF0uZ2V0TW9udGgoKSwgZmlsdGVyWzBdLmdldERhdGUoKSwgMjMsIDU5LCA1OSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZW5kID0gZW5kRGF0ZS5nZXRUaW1lKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBjZWxsLnZhbHVlID09IG51bGwgPyBmYWxzZSA6IGNlbGwudmFsdWUuZ2V0VGltZSgpID49IHN0YXJ0ICYmIGNlbGwudmFsdWUuZ2V0VGltZSgpIDw9IGVuZDtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBPYmpldFxyXG4gICAgICAgIHRoaXMuZmlsdGVyU2VydmljZS5yZWdpc3Rlcignb2JqZXRGaWx0ZXInLCAoY2VsbCwgZmlsdGVyKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBmaWx0ZXIuZmluZCh2YWwgPT4gdmFsLklEID09IGNlbGwudmFsdWU/LklEKSAhPSBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFNlbGVjdCBCdXR0b25cclxuICAgICAgICB0aGlzLmZpbHRlclNlcnZpY2UucmVnaXN0ZXIoJ3NlbGVjdEJ1dHRvbkZpbHRlcicsIChjZWxsLCBmaWx0ZXIpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIGZpbHRlci5maW5kKHZhbCA9PiB2YWwudmFsdWUgPT0gY2VsbC52YWx1ZSkgIT0gbnVsbDtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBMaXN0ZVxyXG4gICAgICAgIHRoaXMuZmlsdGVyU2VydmljZS5yZWdpc3RlcignbGlzdGVGaWx0ZXInLCAoY2VsbCwgZmlsdGVyKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBvazogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBmaWx0ZXIuZm9yRWFjaCh2YWwgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNlbGwudmFsdWUuaW5kZXhPZih2YWwpICE9IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2sgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIG9rO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFN3aXRjaFxyXG4gICAgICAgIHRoaXMuZmlsdGVyU2VydmljZS5yZWdpc3Rlcignc3dpdGNoRmlsdGVyJywgKGNlbGwsIGZpbHRlcikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gKGZpbHRlci5pbmRleE9mKGNlbGwudmFsdWUpICE9IC0xKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBCdXR0b25cclxuICAgICAgICB0aGlzLmZpbHRlclNlcnZpY2UucmVnaXN0ZXIoJ2J1dHRvbkZpbHRlcicsIChjZWxsLCBmaWx0ZXIpID0+IHtcclxuXHJcbiAgICAgICAgICAgIGxldCBmaWx0ZXJPYmpGaWVsZDogc3RyaW5nID0gY2VsbC5vcHRpb25zWydmaWx0ZXJPYmpGaWVsZCddO1xyXG4gICAgICAgICAgICBsZXQgZmlsdGVyT2JqU3ViRmllbGQ6IHN0cmluZyA9IGNlbGwub3B0aW9uc1snZmlsdGVyT2JqU3ViRmllbGQnXTtcclxuXHJcbiAgICAgICAgICAgIGlmIChjZWxsLm9iaiA9PSBudWxsIHx8IGZpbHRlciA9PSBudWxsIHx8IGZpbHRlci50cmltKCkgPT0gJycgfHwgZmlsdGVyT2JqRmllbGQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJPYmpTdWJGaWVsZCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2VsbC5vYmpbZmlsdGVyT2JqRmllbGRdLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyLnRvTG93ZXJDYXNlKCkpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNlbGwub2JqW2ZpbHRlck9iakZpZWxkXS5maW5kKHZhbCA9PiB2YWxbZmlsdGVyT2JqU3ViRmllbGRdLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyLnRvTG93ZXJDYXNlKCkpKSAhPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gVGV4dFxyXG4gICAgICAgIHRoaXMuZmlsdGVyU2VydmljZS5yZWdpc3RlcigndGV4dEZpbHRlcicsIChjZWxsLCBmaWx0ZXIpID0+IHtcclxuXHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXIgPT0gbnVsbCB8fCBmaWx0ZXIudHJpbSgpID09ICcnKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoY2VsbC52YWx1ZSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCB2YWx1ZTogc3RyaW5nO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNlbGwudmFsdWUgPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gY2VsbC52YWx1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY2VsbC52YWx1ZSA9PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBjZWxsLnZhbHVlLnRvU3RyaW5nKCkucmVwbGFjZSgnLicsICcsJyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjZWxsLnZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNlbGwub3B0aW9ucyA9PSBudWxsIHx8IGNlbGwub3B0aW9uc1snb3B0aW9uTGFiZWxGaWx0ZXJUZXh0J10gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmdldE11bHRpU2VsZWN0Q29uY2F0KGNlbGwudmFsdWUsIGNlbGwub3B0aW9uc1snb3B0aW9uTGFiZWxGaWx0ZXJUZXh0J10pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNlbGwub3B0aW9ucyA9PSBudWxsIHx8IGNlbGwub3B0aW9uc1snb3B0aW9uTGFiZWxGaWx0ZXJUZXh0J10gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBjZWxsLnZhbHVlW2NlbGwub3B0aW9uc1snb3B0aW9uTGFiZWxGaWx0ZXJUZXh0J11dO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyLnRvTG93ZXJDYXNlKCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuY29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XHJcbiAgICAgICAgICAgIGlmIChjb2wub3B0aW9ucyA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjb2wub3B0aW9ucyA9IHsgZGVmYXVsdEZpbHRlcnM6IG51bGwgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoY29sLm9wdGlvbnNbJ29ubHlMaXN0VmFsdWVzJ10gJiYgY29sLm9wdGlvbnNbJ29wdGlvbkdyb3VwTGFiZWwnXSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjb2wub3B0aW9uc1snb3B0aW9ucyddID0gW107XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcy5mb3JFYWNoKHZhbCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbC50eXBlID09IENvbFR5cGUuTXVsdGlTZWxlY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsW2NvbC5pZF0udmFsdWUuZm9yRWFjaCh2YWwyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2wub3B0aW9uc1snb3B0aW9ucyddLmZpbmQob3B0ID0+IG9wdC5JRCA9PSB2YWwyLklEKSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLm9wdGlvbnNbJ29wdGlvbnMnXS5wdXNoKHZhbDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbC50eXBlID09IENvbFR5cGUuRHJvcGRvd24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgJiYgY29sLm9wdGlvbnNbJ29wdGlvbnMnXS5maW5kKG9wdCA9PiBvcHQuSUQgPT0gdmFsW2NvbC5pZF0udmFsdWUuSUQpID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5vcHRpb25zWydvcHRpb25zJ10ucHVzaCh2YWxbY29sLmlkXS52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGNvbC5vcHRpb25zWydvcHRpb25zJ10gPSBbLi4uY29sLm9wdGlvbnNbJ29wdGlvbnMnXS5zb3J0KChhLCBiKSA9PiBhW2NvbC5vcHRpb25zWydvcHRpb25MYWJlbCddXS5sb2NhbGVDb21wYXJlKGFbY29sLm9wdGlvbnNbJ29wdGlvbkxhYmVsJ11dKSldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb2x1bW5zQ2hhbmdlLmVtaXQodGhpcy5jb2x1bW5zKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29sdW1ucy5maWx0ZXIoY29sID0+IGNvbC5vcHRpb25zLmRlZmF1bHRGaWx0ZXJzICE9IG51bGwpLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5pdEZpbHRlciA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAgICAgdGhpcy5jb2x1bW5zLmZvckVhY2goY29sID0+IHtcclxuICAgICAgICAgICAgaWYgKCFjb2wuaW52aXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sLm9wdGlvbnMuZGVmYXVsdEZpbHRlcnMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyKGNvbCwgY29sLm9wdGlvbnMuZGVmYXVsdEZpbHRlcnMsIHRoaXMuZ2V0RmlsdGVyQnlDb2woY29sKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMudGFibGUuc2Nyb2xsZXIgJiYgdGhpcy5vcHRpb25zLm1vZGVBcHBlbmRPbmx5KSB7XHJcbiAgICAgICAgICAgIHRoaXMudGFibGUuc2Nyb2xsZXIuYXBwZW5kT25seSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNkUmVmLmRldGVjdENoYW5nZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkZpbHRlclRhYmxlKGV2ZW50KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaW5pdEZpbHRlciA9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25GaWx0ZXJJbml0LmVtaXQoZXZlbnQuZmlsdGVyZWRWYWx1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuaW5pdEZpbHRlciA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBvbklucHV0TnVtYmVyKGV2ZW50KSB7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGxvYWRMYXp5KGV2ZW50OiBMYXp5TG9hZEV2ZW50KSB7XHJcbiAgICAgICAgLy90aGlzLnZhbHVlcyA9IGV2ZW50LnJvd3Muc2xpY2UoZXZlbnQuZmlyc3QsIChldmVudC5maXJzdCArIGV2ZW50LnJvd3MpKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTb3J0XHJcbiAgICBzb3J0R3JpbGxlKGV2ZW50OiBTb3J0RXZlbnQpIHtcclxuXHJcbiAgICAgICAgbGV0IGNvbDogSUNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKGNvbCA9PiBjb2wuaWQgPT0gZXZlbnQuZmllbGQpO1xyXG4gICAgICAgIHRoaXMub25Tb3J0LmVtaXQoeyBjb2x1bW46IGNvbCwgb3JkZXI6IGV2ZW50Lm9yZGVyIH0pXHJcbiAgICAgICAgbGV0IHR5cGVDb2w6IENvbFR5cGUgPSBjb2wudHlwZTtcclxuXHJcbiAgICAgICAgZXZlbnQuZGF0YS5zb3J0KChkYXRhMSwgZGF0YTIpID0+IHtcclxuICAgICAgICAgICAgbGV0IHZhbHVlMSA9IGRhdGExW2V2ZW50LmZpZWxkXS52YWx1ZTtcclxuICAgICAgICAgICAgbGV0IHZhbHVlMiA9IGRhdGEyW2V2ZW50LmZpZWxkXS52YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChjb2wub3B0aW9ucy5jdXN0b21Tb3J0ICYmIGNvbC5vcHRpb25zLnNvcnRGdW5jdGlvbiAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sLm9wdGlvbnMuc29ydEZ1bmN0aW9uKHsgY29sdW1uOiBjb2wsIG9yZGVyOiBldmVudC5vcmRlciwgdmFsdWUxOiB2YWx1ZTEsIHZhbHVlMjogdmFsdWUyIH0gYXMgSVNvcnRDdXN0b20pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUxID09IG51bGwgJiYgdmFsdWUyICE9IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gLTE7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZTEgIT0gbnVsbCAmJiB2YWx1ZTIgPT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAxO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUxID09IG51bGwgJiYgdmFsdWUyID09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gMDtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVDb2wgPT0gQ29sVHlwZS5UZXh0IHx8IHR5cGVDb2wgPT0gQ29sVHlwZS5GaWxlKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlMS5sb2NhbGVDb21wYXJlKHZhbHVlMik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlQ29sID09IENvbFR5cGUuTXVsdGlTZWxlY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUxW3RoaXMuZ2V0T3B0aW9uKGNvbCwgZGF0YTEsICdvcHRpb25MYWJlbCcpXSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUyW3RoaXMuZ2V0T3B0aW9uKGNvbCwgZGF0YTIsICdvcHRpb25MYWJlbCcpXSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5nZXRNdWx0aVNlbGVjdENvbmNhdCh2YWx1ZTEsIHRoaXMuZ2V0T3B0aW9uKGNvbCwgZGF0YTEsICdvcHRpb25MYWJlbCcpKS5sb2NhbGVDb21wYXJlKHRoaXMuZ2V0TXVsdGlTZWxlY3RDb25jYXQodmFsdWUyLCB0aGlzLmdldE9wdGlvbihjb2wsIGRhdGEyLCAnb3B0aW9uTGFiZWwnKSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZUNvbCA9PSBDb2xUeXBlLkRyb3Bkb3duIHx8IHR5cGVDb2wgPT0gQ29sVHlwZS5TZWxlY3RCdXR0b24gfHwgdHlwZUNvbCA9PSBDb2xUeXBlLlN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlMVt0aGlzLmdldE9wdGlvbihjb2wsIGRhdGExLCAnb3B0aW9uTGFiZWwnKV0gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAtMTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlMlt0aGlzLmdldE9wdGlvbihjb2wsIGRhdGEyLCAnb3B0aW9uTGFiZWwnKV0gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlMVt0aGlzLmdldE9wdGlvbihjb2wsIGRhdGExLCAnb3B0aW9uTGFiZWwnKV0ubG9jYWxlQ29tcGFyZSh2YWx1ZTJbdGhpcy5nZXRPcHRpb24oY29sLCBkYXRhMiwgJ29wdGlvbkxhYmVsJyldKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVDb2wgPT0gQ29sVHlwZS5OdW1iZXIgfHwgdHlwZUNvbCA9PSBDb2xUeXBlLkNpbG9nTnVtYmVyIHx8IHR5cGVDb2wgPT0gQ29sVHlwZS5EYXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHZhbHVlMSA8IHZhbHVlMikgPyAtMSA6ICh2YWx1ZTEgPiB2YWx1ZTIpID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVDb2wgPT0gQ29sVHlwZS5Td2l0Y2gpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHZhbHVlMSA9PT0gdmFsdWUyKSA/IDAgOiB2YWx1ZTEgPyAtMSA6IDE7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID09IDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGV2ZW50Lm9yZGVyICogcmVzdWx0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrVHlwZSh0eXBlQ29sOiBzdHJpbmcsIGNvbDogSUNvbHVtbikge1xyXG4gICAgICAgIHJldHVybiBjb2xbJ3R5cGUnXSA9PSB0eXBlQ29sO1xyXG4gICAgfVxyXG5cclxuICAgIGNsaWNrQnlJZChpZDogc3RyaW5nKSB7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsaWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25FZGl0Q2VsbChyb3c6IElSb3csIGNvbHVtbjogSUNvbHVtbiwgdmFsdWU6IGFueSkge1xyXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oY29sdW1uLCByb3csICdhY3Rpb24nKSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGNvbHVtbiwgcm93LCAnYWN0aW9uJykoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm9uRWRpdC5lbWl0KHsgcm93OiByb3csIGNvbHVtbjogY29sdW1uLCB2YWx1ZTogdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEZXN0cm95IEZvY3VzXHJcbiAgICAgICAgdGhpcy52YWx1ZXMuZm9yRWFjaCh2YWwgPT4ge1xyXG4gICAgICAgICAgICB2YWxbY29sdW1uLmlkXS5mb2N1cyA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCwgcm93OiBJUm93LCBjb2x1bW46IElDb2x1bW4sIHZhbHVlOiBhbnkpIHtcclxuICAgICAgICBpZiAoZXZlbnQua2V5ID09ICdFbnRlcicpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkVkaXRDZWxsKHJvdywgY29sdW1uLCB2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGVkaXRNdWx0aXNlbGVjdChyb3c6IElSb3csIGNvbHVtbjogSUNvbHVtbiwgZXZlbnQpIHtcclxuICAgICAgICB0aGlzLm9uRWRpdENlbGwocm93LCBjb2x1bW4sIHsgbGlzdFNlbGVjdGVkOiBldmVudC52YWx1ZSwgaXRlbVNlbGVjdGVkOiBldmVudC5pdGVtVmFsdWUsIHNlbGVjdGVkOiBldmVudC52YWx1ZS5pbmRleE9mKGV2ZW50Lml0ZW1WYWx1ZSkgIT0gLTEgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TZWxlY3RBbGwoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLm9uU2VsZWN0LmVtaXQoeyByb3c6IG51bGwsIHNlbGVjdGVkUm93czogdGhpcy5zZWxlY3RlZFJvd3MsIGNoZWNrZWQ6IGV2ZW50LmNoZWNrZWQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TZWxlY3RSb3cocm93OiBJUm93KSB7XHJcbiAgICAgICAgdGhpcy5vblNlbGVjdC5lbWl0KHsgcm93OiByb3csIHNlbGVjdGVkUm93czogdGhpcy5zZWxlY3RlZFJvd3MsIGNoZWNrZWQ6IHRydWUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TZWxlY3RDZWxsKGNlbGw6IElDZWxsKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coY2VsbClcclxuICAgICAgICB0aGlzLm9uU2VsZWN0LmVtaXQoeyBjZWxsOiBjZWxsIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uVW5zZWxlY3RSb3cocm93OiBJUm93KSB7XHJcbiAgICAgICAgdGhpcy5vblVuc2VsZWN0LmVtaXQoeyByb3c6IHJvdywgc2VsZWN0ZWRSb3dzOiB0aGlzLnNlbGVjdGVkUm93cywgY2hlY2tlZDogZmFsc2UgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVmcmVzaERhdGEoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zb3J0YWJsZSAmJiB0aGlzLm9wdGlvbnMudmlydHVhbFNjcm9sbCkge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlcyA9IFsuLi50aGlzLnZhbHVlc107XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uUGFnZVRhYmxlKGV2ZW50OiBJUGFnZSkge1xyXG4gICAgICAgIHRoaXMub25QYWdlLmVtaXQoZXZlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uRGVsZXRlTGluZShyb3c6IElSb3cpIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLm1hbnVhbGx5RGVsZXRhYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25EZWxldGUuZW1pdCh7IHJvdzogcm93IH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlybWF0aW9uU2VydmljZS5jb25maXJtKHtcclxuICAgICAgICAgICAgICAgIGtleTogJ2NvbmZpcm0nLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ8OKdGVzLXZvdXMgc8O7ciBkZSB2b3Vsb2lyIHN1cHByaW1lciBjZXR0ZSBsaWduZSA/JyxcclxuICAgICAgICAgICAgICAgIGFjY2VwdDogKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzLnNwbGljZSh0aGlzLnZhbHVlcy5pbmRleE9mKHJvdyksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzID0gWy4uLnRoaXMudmFsdWVzXTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlc0NoYW5nZS5lbWl0KHRoaXMudmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlLmVtaXQoeyByb3c6IHJvdyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uRWRpdEluaXRDZWxsKGV2ZW50LCByb3c6IElSb3csIGNvbHVtbjogSUNvbHVtbiwgdmFsdWU6IGFueSkge1xyXG4gICAgICAgIGV2ZW50LnRhcmdldC5zZWxlY3QoKTtcclxuICAgICAgICB0aGlzLm9uRWRpdEluaXQuZW1pdCh7IHJvdzogcm93LCBjb2x1bW46IGNvbHVtbiwgdmFsdWU6IHZhbHVlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uUm93RG91YmxlQ2xpY2tFdmVudChyb3c6IElSb3cpIHtcclxuICAgICAgICB0aGlzLm9uUm93RG91YmxlQ2xpY2suZW1pdCh7IHJvdzogcm93IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE9wdGlvbihjb2wsIHJvdywgb3B0aW9uOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAocm93ICE9IG51bGwgJiYgcm93W2NvbC5pZF0ub3B0aW9ucyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGlmIChyb3dbY29sLmlkXS5vcHRpb25zW29wdGlvbl0gIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJvd1tjb2wuaWRdLm9wdGlvbnNbb3B0aW9uXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29sICE9IG51bGwgJiYgY29sLm9wdGlvbnMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBpZiAoY29sLm9wdGlvbnNbb3B0aW9uXSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sLm9wdGlvbnNbb3B0aW9uXVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE11bHRpU2VsZWN0Q29uY2F0KHZhbHVlLCBsYWJlbDogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLm1hcCh2YWwgPT4geyByZXR1cm4gdmFsW2xhYmVsXTsgfSkuam9pbignLCAnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFNlbGVjdExpYmVsbGVCeVZhbHVlKHJvdywgY29sKSB7XHJcbiAgICAgICAgbGV0IGxhYmVsOiBzdHJpbmcgPSAnJztcclxuICAgICAgICBpZiAocm93W2NvbC5pZF0udmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbGFiZWw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyb3dbY29sLmlkXS5vcHRpb25zICE9IG51bGwpIHtcclxuICAgICAgICAgICAgbGFiZWwgPSByb3dbY29sLmlkXS5vcHRpb25zWydvcHRpb25zJ10uZmluZChvcHQgPT4gb3B0LnZhbHVlID09IHJvd1tjb2wuaWRdLnZhbHVlKVtyb3dbY29sLmlkXS5vcHRpb25zLm9wdGlvbkxhYmVsXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoY29sLm9wdGlvbnMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgbGFiZWwgPSBjb2wub3B0aW9uc1snb3B0aW9ucyddLmZpbmQob3B0ID0+IG9wdC52YWx1ZSA9PSByb3dbY29sLmlkXS52YWx1ZSlbY29sLm9wdGlvbnMub3B0aW9uTGFiZWxdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBsYWJlbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXRGaWx0ZXJCeUNvbChjb2w6IElDb2x1bW4pIHtcclxuICAgICAgICAvLyBEYXRlcyAocmFuZ2UpXHJcbiAgICAgICAgaWYgKGNvbC50eXBlID09IENvbFR5cGUuRGF0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ2RhdGVSYW5nZUZpbHRlcic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE9iamV0XHJcbiAgICAgICAgaWYgKChjb2wudHlwZSA9PSBDb2xUeXBlLkRyb3Bkb3duICYmICEoPElPcHRpb25zRHJvcGRvd24+Y29sLm9wdGlvbnMpLmZpbHRlclRleHQpIHx8IGNvbC50eXBlID09IENvbFR5cGUuU3RhdGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdvYmpldEZpbHRlcic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIExpc3RlXHJcbiAgICAgICAgaWYgKGNvbC50eXBlID09IENvbFR5cGUuTXVsdGlTZWxlY3QgJiYgISg8SU9wdGlvbnNNdWx0aVNlbGVjdD5jb2wub3B0aW9ucykuZmlsdGVyVGV4dCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ2xpc3RlRmlsdGVyJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVGV4dGVcclxuICAgICAgICBpZiAoY29sLnR5cGUgPT0gQ29sVHlwZS5GaWxlXHJcbiAgICAgICAgICAgIHx8IGNvbC50eXBlID09IENvbFR5cGUuVGV4dFxyXG4gICAgICAgICAgICB8fCBjb2wudHlwZSA9PSBDb2xUeXBlLk51bWJlclxyXG4gICAgICAgICAgICB8fCBjb2wudHlwZSA9PSBDb2xUeXBlLkNpbG9nTnVtYmVyXHJcbiAgICAgICAgICAgIHx8IChjb2wudHlwZSA9PSBDb2xUeXBlLk11bHRpU2VsZWN0ICYmICg8SU9wdGlvbnNNdWx0aVNlbGVjdD5jb2wub3B0aW9ucykuZmlsdGVyVGV4dClcclxuICAgICAgICAgICAgfHwgKGNvbC50eXBlID09IENvbFR5cGUuRHJvcGRvd24gJiYgKDxJT3B0aW9uc0Ryb3Bkb3duPmNvbC5vcHRpb25zKS5maWx0ZXJUZXh0KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ3RleHRGaWx0ZXInO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTd2l0Y2hcclxuICAgICAgICBpZiAoY29sLnR5cGUgPT0gQ29sVHlwZS5Td2l0Y2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdzd2l0Y2hGaWx0ZXInO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTd2l0Y2hcclxuICAgICAgICBpZiAoY29sLnR5cGUgPT0gQ29sVHlwZS5TZWxlY3RCdXR0b24pIHtcclxuICAgICAgICAgICAgcmV0dXJuICdzZWxlY3RCdXR0b25GaWx0ZXInO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBvbkZpbHRlckNvbChldmVudCwgY29sOiBJQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IHZhbHVlOiBhbnk7XHJcblxyXG4gICAgICAgIC8vIERhdGVzIChyYW5nZSlcclxuICAgICAgICBpZiAoY29sLnR5cGUgPT0gQ29sVHlwZS5EYXRlKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gY29sLm9wdGlvbnMuZGVmYXVsdEZpbHRlcnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE9iamV0XHJcbiAgICAgICAgaWYgKChjb2wudHlwZSA9PSBDb2xUeXBlLkRyb3Bkb3duICYmICEoPElPcHRpb25zRHJvcGRvd24+Y29sLm9wdGlvbnMpLmZpbHRlclRleHQpIHx8IGNvbC50eXBlID09IENvbFR5cGUuU3RhdGUpIHtcclxuICAgICAgICAgICAgdmFsdWUgPSBldmVudCA9PSBudWxsID8gbnVsbCA6IGV2ZW50LnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBMaXN0ZVxyXG4gICAgICAgIGlmIChjb2wudHlwZSA9PSBDb2xUeXBlLk11bHRpU2VsZWN0ICYmICEoPElPcHRpb25zTXVsdGlTZWxlY3Q+Y29sLm9wdGlvbnMpLmZpbHRlclRleHQpIHtcclxuICAgICAgICAgICAgdmFsdWUgPSBldmVudCA9PSBudWxsID8gbnVsbCA6IGV2ZW50LnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBUZXh0ZVxyXG4gICAgICAgIGlmIChjb2wudHlwZSA9PSBDb2xUeXBlLkZpbGVcclxuICAgICAgICAgICAgfHwgY29sLnR5cGUgPT0gQ29sVHlwZS5UZXh0XHJcbiAgICAgICAgICAgIHx8IGNvbC50eXBlID09IENvbFR5cGUuTnVtYmVyXHJcbiAgICAgICAgICAgIHx8IGNvbC50eXBlID09IENvbFR5cGUuQ2lsb2dOdW1iZXJcclxuICAgICAgICAgICAgfHwgKGNvbC50eXBlID09IENvbFR5cGUuTXVsdGlTZWxlY3QgJiYgKDxJT3B0aW9uc011bHRpU2VsZWN0PmNvbC5vcHRpb25zKS5maWx0ZXJUZXh0KVxyXG4gICAgICAgICAgICB8fCAoY29sLnR5cGUgPT0gQ29sVHlwZS5Ecm9wZG93biAmJiAoPElPcHRpb25zRHJvcGRvd24+Y29sLm9wdGlvbnMpLmZpbHRlclRleHQpKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTd2l0Y2hcclxuICAgICAgICBpZiAoY29sLnR5cGUgPT0gQ29sVHlwZS5Td2l0Y2gpIHtcclxuICAgICAgICAgICAgdmFsdWUgPSBldmVudC52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gU2VsZWN0QnV0dG9uXHJcbiAgICAgICAgaWYgKGNvbC50eXBlID09IENvbFR5cGUuU2VsZWN0QnV0dG9uKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gZXZlbnQgPT0gbnVsbCA/IG51bGwgOiBldmVudC52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQnV0dG9uXHJcbiAgICAgICAgaWYgKGNvbC50eXBlID09IENvbFR5cGUuQnV0dG9uKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5maWx0ZXIoY29sLCB2YWx1ZSwgdGhpcy5nZXRGaWx0ZXJCeUNvbChjb2wpKTtcclxuICAgICAgICBpZiAodGhpcy50YWJsZS5zY3JvbGxlciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGFibGUuc2Nyb2xsZXIuc2V0SW5pdGlhbFN0YXRlKCk7XHJcbiAgICAgICAgICAgIHRoaXMudGFibGUuc2Nyb2xsZXIuaW5pdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5vbkZpbHRlci5lbWl0KHsgY29sdW1uOiBjb2wsIHZhbHVlOiB2YWx1ZSwgZmlsdGVyZWRWYWx1ZTogdGhpcy50YWJsZS5maWx0ZXJlZFZhbHVlIH0pXHJcbiAgICB9XHJcblxyXG4gICAgZmlsdGVyKGNvbDogSUNvbHVtbiwgdmFsOiBhbnksIGZpbHRlcjogc3RyaW5nKSB7XHJcblxyXG4gICAgICAgIC8vIENvcGllciAtIENvbGxlciBkZSBsYSBtw6l0aG9kZSBmaWx0ZXIoKSBkZSB0YWJsZS50cyBkZSBQcmltZU5HIHNhbnMgbGEgZMOpc3luY2hyb25pc2F0aW9uIGNhdXPDqWUgcGFyIGZpbHRlckRlbGF5IChzZXRUaW1lb3V0KVxyXG4gICAgICAgIGlmICh0aGlzLnRhYmxlLmZpbHRlclRpbWVvdXQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGFibGUuZmlsdGVyVGltZW91dCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy50YWJsZS5pc0ZpbHRlckJsYW5rKHZhbCkpIHtcclxuICAgICAgICAgICAgdGhpcy50YWJsZS5maWx0ZXJzW2NvbC5pZF0gPSB7IHZhbHVlOiB2YWwsIG1hdGNoTW9kZTogZmlsdGVyIH07XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhYmxlLmZpbHRlcnNbY29sLmlkXSkge1xyXG4gICAgICAgICAgICBkZWxldGUgdGhpcy50YWJsZS5maWx0ZXJzW2NvbC5pZF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnRhYmxlLl9maWx0ZXIoKTtcclxuICAgICAgICB0aGlzLnRhYmxlLmZpbHRlclRpbWVvdXQgPSBudWxsO1xyXG4gICAgICAgIHRoaXMudGFibGUuYW5jaG9yUm93SW5kZXggPSBudWxsO1xyXG5cclxuICAgICAgICBpZiAodGhpcy50YWJsZS5zY3JvbGxlcikge1xyXG4gICAgICAgICAgICB0aGlzLnRhYmxlLnNjcm9sbGVyLnZpZXdJbml0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFRvdGFsKGNvbDogSUNvbHVtbikge1xyXG4gICAgICAgIGlmIChjb2wuZGlzcGxheVRvdGFsICYmIChjb2wudHlwZSA9PSBDb2xUeXBlLk51bWJlciB8fCBjb2wudHlwZSA9PSBDb2xUeXBlLkNpbG9nTnVtYmVyKSkge1xyXG4gICAgICAgICAgICBsZXQgdmFsdWVzOiBJUm93W10gPSB0aGlzLnZhbHVlcztcclxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50b3RhbEJ5RmlsdGVyID09IHRydWUgJiYgdGhpcy50YWJsZS5maWx0ZXJlZFZhbHVlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHRoaXMudGFibGUuZmlsdGVyZWRWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgdG90YWw6IG51bWJlciA9IDA7XHJcbiAgICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKHZhbCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXZhbC5leGNsdXNpb25Ub3RhbCAmJiAhdmFsW2NvbC5pZF0uZXhjbHVzaW9uVG90YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLm1vZGVTZWxlY3Rpb24gIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLm1vZGVTZWxlY3Rpb24gPT0gTW9kZVNlbGVjdGlvbi5DaGVja2JveCAmJiB0aGlzLm9wdGlvbnMudG90YWxCeVNlbGVjdGlvbiA9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZFJvd3MgIT0gbnVsbCAmJiB0aGlzLnNlbGVjdGVkUm93cy5maW5kKHJvdyA9PiByb3cuaWQgPT0gdmFsLmlkKSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0b3RhbDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VG90YWxTdHIoY29sOiBJQ29sdW1uKSB7XHJcbiAgICAgICAgaWYgKGNvbC5kaXNwbGF5VG90YWwgJiYgKGNvbC50eXBlID09IENvbFR5cGUuTnVtYmVyIHx8IGNvbC50eXBlID09IENvbFR5cGUuQ2lsb2dOdW1iZXIpKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoY29sLm1ldGhvZFRvdGFsICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEZvcm1hdHRlZE51bWJlcihjb2wsIG51bGwsIGNvbC5tZXRob2RUb3RhbCgpLCB0cnVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZXM6IElSb3dbXSA9IHRoaXMudmFsdWVzO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50b3RhbEJ5RmlsdGVyID09IHRydWUgJiYgdGhpcy50YWJsZS5maWx0ZXJlZFZhbHVlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB0aGlzLnRhYmxlLmZpbHRlcmVkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsZXQgdG90YWw6IG51bWJlciA9IDA7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZXMuZm9yRWFjaCh2YWwgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdmFsLmV4Y2x1c2lvblRvdGFsICYmICF2YWxbY29sLmlkXS5leGNsdXNpb25Ub3RhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLm1vZGVTZWxlY3Rpb24gIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5tb2RlU2VsZWN0aW9uID09IE1vZGVTZWxlY3Rpb24uQ2hlY2tib3ggJiYgdGhpcy5vcHRpb25zLnRvdGFsQnlTZWxlY3Rpb24gPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkUm93cyAhPSBudWxsICYmIHRoaXMuc2VsZWN0ZWRSb3dzLmZpbmQocm93ID0+IHJvdy5pZCA9PSB2YWwuaWQpICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gKHZhbFtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyB2YWxbY29sLmlkXS52YWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRGb3JtYXR0ZWROdW1iZXIoY29sLCBudWxsLCB0b3RhbCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Rm9ybWF0dGVkVGV4dChjb2w6IElDb2x1bW4sIHJvd0RhdGE6IElSb3cpIHtcclxuICAgICAgICBsZXQgdmFsdWU6IHN0cmluZyA9IHJvd0RhdGFbY29sLmlkXS52YWx1ZTtcclxuICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsZXQgaW5kZW50YXRpb246IG51bWJlciA9IHRoaXMuZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ2luZGVudGF0aW9uJyk7XHJcbiAgICAgICAgICAgIGlmIChpbmRlbnRhdGlvbiAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJyAgICAgICAnLnJlcGVhdChpbmRlbnRhdGlvbikgKyB2YWx1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Rm9ybWF0dGVkTnVtYmVyKGNvbDogSUNvbHVtbiwgcm93RGF0YTogSVJvdywgdmFsdWU6IG51bWJlciwgdG90YWw6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG5cclxuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IGZpbmFsVmFsdWU6IHN0cmluZ1tdID0gW107XHJcblxyXG4gICAgICAgICAgICAvLyBQcsOpZml4ZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oY29sLCByb3dEYXRhLCAncHJlZml4JykgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgZmluYWxWYWx1ZS5wdXNoKHRoaXMuZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ3ByZWZpeCcpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gVmFsZXVyXHJcbiAgICAgICAgICAgIGlmICh0b3RhbCkge1xyXG4gICAgICAgICAgICAgICAgbGV0IG1pbkRlY2ltYWxlc1RvdGFsOiBudW1iZXIgPSAyO1xyXG4gICAgICAgICAgICAgICAgbGV0IG1heERlY2ltYWxlc1RvdGFsOiBudW1iZXIgPSAyO1xyXG4gICAgICAgICAgICAgICAgaWYgKCg8SU9wdGlvbnNOdW1iZXI+Y29sLm9wdGlvbnMpLm1pbkRlY2ltYWxlc1RvdGFsICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBtaW5EZWNpbWFsZXNUb3RhbCA9ICg8SU9wdGlvbnNOdW1iZXI+Y29sLm9wdGlvbnMpLm1pbkRlY2ltYWxlc1RvdGFsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCg8SU9wdGlvbnNOdW1iZXI+Y29sLm9wdGlvbnMpLm1heERlY2ltYWxlc1RvdGFsICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXhEZWNpbWFsZXNUb3RhbCA9ICg8SU9wdGlvbnNOdW1iZXI+Y29sLm9wdGlvbnMpLm1heERlY2ltYWxlc1RvdGFsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKG1heERlY2ltYWxlc1RvdGFsIDwgbWluRGVjaW1hbGVzVG90YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXhEZWNpbWFsZXNUb3RhbCA9IG1pbkRlY2ltYWxlc1RvdGFsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZmluYWxWYWx1ZS5wdXNoKHZhbHVlLnRvTG9jYWxlU3RyaW5nKCdmci1GUicsIHsgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiBtYXhEZWNpbWFsZXNUb3RhbCwgbWluaW11bUZyYWN0aW9uRGlnaXRzOiBtaW5EZWNpbWFsZXNUb3RhbCB9KSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbWluRGVjaW1hbGVzOiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBsZXQgbWF4RGVjaW1hbGVzOiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWF4RGVjaW1hbGVzJykgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG1heERlY2ltYWxlcyA9IHRoaXMuZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21heERlY2ltYWxlcycpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21pbkRlY2ltYWxlcycpICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBtaW5EZWNpbWFsZXMgPSB0aGlzLmdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtaW5EZWNpbWFsZXMnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vZmluYWxWYWx1ZS5wdXNoKHZhbHVlLnRvTG9jYWxlU3RyaW5nKCdmci1GUicpKVxyXG4gICAgICAgICAgICAgICAgZmluYWxWYWx1ZS5wdXNoKHZhbHVlLnRvTG9jYWxlU3RyaW5nKCdmci1GUicsIHsgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiBtYXhEZWNpbWFsZXMsIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogbWluRGVjaW1hbGVzIH0pKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gU3VmZml4ZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oY29sLCByb3dEYXRhLCAnc3VmZml4JykgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgZmluYWxWYWx1ZS5wdXNoKHRoaXMuZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ3N1ZmZpeCcpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGZpbmFsVmFsdWUuam9pbignICcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBkb3dubG9hZEZpbGUoY2VsbDogSUNlbGwpIHtcclxuICAgICAgICBsZXQgcGF0aDogc3RyaW5nID0gKDxJT3B0aW9uc0ZpbGU+Y2VsbC5vcHRpb25zKS5kb3dubG9hZFBhdGg7XHJcbiAgICAgICAgbGV0IGZpbGVOYW1lID0gY2VsbC52YWx1ZTtcclxuICAgICAgICBjb25zdCBhOiBIVE1MQW5jaG9yRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKSBhcyBIVE1MQW5jaG9yRWxlbWVudDtcclxuICAgICAgICBhLmhyZWYgPSBwYXRoO1xyXG4gICAgICAgIGEuZG93bmxvYWQgPSBmaWxlTmFtZTtcclxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xyXG4gICAgICAgIGEuY2xpY2soKTtcclxuICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xyXG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwocGF0aCk7XHJcbiAgICB9XHJcblxyXG4gICAgaGFzRnJvemVuQ29sdW1ucygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5zLmZpbHRlcihjb2wgPT4gY29sLmZyb3plbiA9PSB0cnVlKS5sZW5ndGggPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIHRyYWNrQnlGdW5jdGlvbihpbmRleCwgaXRlbSkge1xyXG4gICAgICAgIHJldHVybiBpdGVtPy5pZDtcclxuICAgIH1cclxuXHJcbiAgICBpc1ZhbHVlQnV0dG9uQnlUeXBlKHZhbHVlOiBhbnksIHR5cGU6IHN0cmluZykge1xyXG4gICAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSB0eXBlO1xyXG4gICAgfVxyXG5cclxuICAgIGlzTW9kZUVkaXRpb24oKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5lZGl0YWJsZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRNb2RlU2VsZWN0aW9uKCk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zZWxlY3RhYmxlICE9IHRydWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHN3aXRjaCAodGhpcy5vcHRpb25zLm1vZGVTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgY2FzZSBNb2RlU2VsZWN0aW9uLkNoZWNrYm94OlxyXG4gICAgICAgICAgICBjYXNlIE1vZGVTZWxlY3Rpb24uTWV0YWtleTpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnbXVsdGlwbGUnO1xyXG4gICAgICAgICAgICBjYXNlIE1vZGVTZWxlY3Rpb24uQ2VsbDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBjYXNlIE1vZGVTZWxlY3Rpb24uUm93OlxyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdzaW5nbGUnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpc01vZGVDaGVja2JveFNlbGVjdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnNlbGVjdGFibGUgPT0gdHJ1ZSAmJiB0aGlzLm9wdGlvbnMubW9kZVNlbGVjdGlvbiAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5tb2RlU2VsZWN0aW9uID09IE1vZGVTZWxlY3Rpb24uQ2hlY2tib3g7XHJcbiAgICB9XHJcblxyXG4gICAgaXNNb2RlQ2VsbFNlbGVjdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnNlbGVjdGFibGUgPT0gdHJ1ZSAmJiB0aGlzLm9wdGlvbnMubW9kZVNlbGVjdGlvbiAhPSBudWxsICYmIHRoaXMub3B0aW9ucy5tb2RlU2VsZWN0aW9uID09IE1vZGVTZWxlY3Rpb24uQ2VsbDtcclxuICAgIH1cclxuXHJcbiAgICBpc01vZGVNZXRha2V5U2VsZWN0aW9uKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuc2VsZWN0YWJsZSA9PSB0cnVlICYmIHRoaXMub3B0aW9ucy5tb2RlU2VsZWN0aW9uICE9IG51bGwgJiYgdGhpcy5vcHRpb25zLm1vZGVTZWxlY3Rpb24gPT0gTW9kZVNlbGVjdGlvbi5NZXRha2V5O1xyXG4gICAgfVxyXG5cclxuICAgIGV4cG9ydEV4Y2VsKGJ5RmlsdHJlOiBib29sZWFuID0gZmFsc2UsIHdpdGhDb2xvcnM6IGJvb2xlYW4gPSB0cnVlKSB7XHJcbiAgICAgICAgdGhpcy5leHBvcnRTZXJ2aWNlLmV4cG9ydEV4Y2VsKHRoaXMudGFibGUuZmlsdGVyZWRWYWx1ZSAhPSBudWxsID8gdGhpcy50YWJsZS5maWx0ZXJlZFZhbHVlIDogdGhpcy52YWx1ZXMsIHRoaXMuY29sdW1ucywgYnlGaWx0cmUsIHdpdGhDb2xvcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQ2xpY2tDZWxsTnVtYmVyKHJvdzogSVJvdywgY29sOiBJQ29sdW1uKSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZXMuZm9yRWFjaCh2YWwgPT4ge1xyXG4gICAgICAgICAgICB2YWxbY29sLmlkXS5mb2N1cyA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJvd1tjb2wuaWRdLmZvY3VzID0gdHJ1ZTtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5pbnB1dE51bWJlci5pbnB1dC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiBbbmdTdHlsZV09XCJ7ICdoZWlnaHQnOiBvcHRpb25zLnNjcm9sbEhlaWdodCAhPSBudWxsID8gb3B0aW9ucy5zY3JvbGxIZWlnaHQgOiAnMTAwJScgfVwiPlxyXG5cclxuICAgIDxidXR0b24gcEJ1dHRvblxyXG4gICAgICAgICAgICAqbmdJZj1cIm9wdGlvbnMuZXhwb3J0RXhjZWxcIlxyXG4gICAgICAgICAgICBpY29uPVwicGkgcGktZmlsZS1leGNlbFwiXHJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tc3VjY2VzcyBhYnNvbHV0ZSB6LTUgdy0ycmVtIGgtMnJlbSBib3JkZXItcm91bmQtcmlnaHQgYm9yZGVyLW5vcm91bmQtdG9wXCJcclxuICAgICAgICAgICAgcFRvb2x0aXA9XCJFeHBvcnRlciBsZSBjb250ZW51IGRlIGxhIGdyaWxsZSBhdSBmb3JtYXQgRXhjZWxcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0RXhjZWwob3B0aW9ucy5leHBvcnRFeGNlbEJ5RmlsdHJlLCAhb3B0aW9ucy5leHBvcnRFeGNlbE5vQ29sb3JzKVwiPlxyXG4gICAgPC9idXR0b24+XHJcblxyXG4gICAgPHAtY29udGV4dE1lbnUgI2NtIFttb2RlbF09XCJvcHRpb25zLmNvbnRleHRNZW51SXRlbXNcIiAvPlxyXG5cclxuICAgIDxwLXRhYmxlICN0YWJsZVxyXG4gICAgICAgICAgICAgW2NvbHVtbnNdPVwiY29sdW1uc1wiXHJcbiAgICAgICAgICAgICBbdmFsdWVdPVwidmFsdWVzXCJcclxuICAgICAgICAgICAgIGRhdGFLZXk9XCJpZFwiXHJcbiAgICAgICAgICAgICBbc2VsZWN0aW9uTW9kZV09XCJnZXRNb2RlU2VsZWN0aW9uKClcIlxyXG4gICAgICAgICAgICAgW21ldGFLZXlTZWxlY3Rpb25dPVwiaXNNb2RlTWV0YWtleVNlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgIFsoc2VsZWN0aW9uKV09XCJzZWxlY3RlZFJvd3NcIlxyXG4gICAgICAgICAgICAgKG9uUm93U2VsZWN0KT1cIm9uU2VsZWN0Um93KCRldmVudClcIlxyXG4gICAgICAgICAgICAgKG9uUm93VW5zZWxlY3QpPVwib25VbnNlbGVjdFJvdygkZXZlbnQpXCJcclxuICAgICAgICAgICAgIChvbkhlYWRlckNoZWNrYm94VG9nZ2xlKT1cIm9uU2VsZWN0QWxsKCRldmVudClcIlxyXG4gICAgICAgICAgICAgKHNvcnRGdW5jdGlvbik9XCJzb3J0R3JpbGxlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgW2N1c3RvbVNvcnRdPVwib3B0aW9ucy5ncm91cGluZyA9PSBudWxsID8gdHJ1ZSA6IGZhbHNlXCJcclxuICAgICAgICAgICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgW2xvYWRpbmddPVwibG9hZGluZ1wiXHJcbiAgICAgICAgICAgICBbc2Nyb2xsSGVpZ2h0XT1cIidmbGV4J1wiXHJcbiAgICAgICAgICAgICBbcm93R3JvdXBNb2RlXT1cIm9wdGlvbnMuZ3JvdXBpbmcgIT0gbnVsbCA/ICdzdWJoZWFkZXInIDogbnVsbFwiXHJcbiAgICAgICAgICAgICBbZ3JvdXBSb3dzQnldPVwib3B0aW9ucy5ncm91cGluZyAhPSBudWxsID8gb3B0aW9ucy5ncm91cGluZy5vYmogKyAnLicgKyBvcHRpb25zLmdyb3VwaW5nLmlkIDogbnVsbFwiXHJcbiAgICAgICAgICAgICBbZ3JvdXBSb3dzQnlPcmRlcl09XCIwXCJcclxuICAgICAgICAgICAgIFt2aXJ0dWFsU2Nyb2xsXT1cIm9wdGlvbnMudmlydHVhbFNjcm9sbCA9PSB0cnVlICYmIG9wdGlvbnMuc2Nyb2xsSGVpZ2h0ICE9IG51bGwgPyB0cnVlIDogZmFsc2VcIlxyXG4gICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxJdGVtU2l6ZV09XCJvcHRpb25zLnZpcnR1YWxTY3JvbGxJdGVtU2l6ZSAhPSBudWxsID8gb3B0aW9ucy52aXJ0dWFsU2Nyb2xsSXRlbVNpemUgOiAzNVwiXHJcbiAgICAgICAgICAgICBbcGFnaW5hdG9yXT1cIm9wdGlvbnMucGFnaW5hdG9yID09IG51bGwgPyBmYWxzZSA6IHRydWVcIlxyXG4gICAgICAgICAgICAgW3Jvd3NdPVwib3B0aW9ucy5wYWdpbmF0b3JSb3dzXCJcclxuICAgICAgICAgICAgIChvblBhZ2UpPVwib25QYWdlVGFibGUoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICBbdGFibGVTdHlsZUNsYXNzXT1cIiFvcHRpb25zLnRoZW1lR3JpbGxlID8gJ2dyaWRfZ3JleScgOiBvcHRpb25zLnRoZW1lR3JpbGxlXCJcclxuICAgICAgICAgICAgIFtsYXp5XT1cIm9wdGlvbnMubGF6eSA9PSB0cnVlID8gdHJ1ZSA6IGZhbHNlXCJcclxuICAgICAgICAgICAgIChvbkZpbHRlcik9XCJvbkZpbHRlclRhYmxlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgW3Jvd1RyYWNrQnldPVwidHJhY2tCeUZ1bmN0aW9uXCJcclxuICAgICAgICAgICAgIFsoY29udGV4dE1lbnVTZWxlY3Rpb24pXT1cImNvbnRleHRNZW51U2VsZWN0ZWRJdGVtXCJcclxuICAgICAgICAgICAgIFtjb250ZXh0TWVudV09XCJjbVwiPlxyXG5cclxuICAgICAgICA8IS0tIEhFQURFUiAtLT5cclxuICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCIgbGV0LWNvbHVtbnM+XHJcblxyXG4gICAgICAgICAgICA8IS0tIEhFQURFUlMgLS0+XHJcbiAgICAgICAgICAgIDx0ciBjbGFzcz1cInJvd0hlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiY2VsbERlbGV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZGVDaGVja2JveFNlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlSGVhZGVyQ2hlY2tib3ggKm5nSWY9XCIhb3B0aW9ucy5maWx0ZXJhYmxlICYmIG9wdGlvbnMudG9nZ2xlQWxsXCI+PC9wLXRhYmxlSGVhZGVyQ2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCIhY29sLmludmlzaWJsZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsICdiYWNrZ3JvdW5kLWNvbG9yJzogY29sLmJhY2tncm91bmRDb2xvciA/IGNvbC5iYWNrZ3JvdW5kQ29sb3IgOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICd0ZXh0LWNlbnRlcicgOiBvcHRpb25zLmNlbnRlckhlYWRlcnMsICdoZWFkZXJBZmZpY2hhZ2VTaW1wbGUnOiAhb3B0aW9ucy5oZWFkZXJzQWZmaWNoYWdlRW50aWVyLCAnaGVhZGVyQWZmaWNoYWdlRW50aWVyJzogb3B0aW9ucy5oZWFkZXJzQWZmaWNoYWdlRW50aWVyIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uXT1cImNvbC5pZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwU29ydGFibGVDb2x1bW5EaXNhYmxlZF09XCIhb3B0aW9ucy5zb3J0YWJsZSB8fCBvcHRpb25zLmdyb3VwaW5nICE9IG51bGwgfHwgY29sLmxpYmVsbGUgPT0gbnVsbCB8fCBjb2wubGliZWxsZSA9PSAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgY29sLmlkIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlZnJlc2hEYXRhKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJjb2wubGliZWxsZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwRGlzYWJsZWRdPVwiIWNvbC50b29sdGlwSGVhZGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nU3R5bGVdPVwieyAnY29sb3InOiBjb2wudGV4dENvbG9yID8gY29sLnRleHRDb2xvciA6IG51bGwgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sLmxpYmVsbGUgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLXNvcnRJY29uICpuZ0lmPVwib3B0aW9ucy5zb3J0YWJsZSAmJiBvcHRpb25zLmdyb3VwaW5nID09IG51bGwgJiYgY29sLmxpYmVsbGUgIT0gbnVsbCAmJiBjb2wubGliZWxsZSAhPSAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLXNvcnRJY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImNlbGxEZWxldGVcIiAqbmdJZj1cIm9wdGlvbnMucm93c0RlbGV0YWJsZVwiPjwvdGg+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcblxyXG4gICAgICAgICAgICA8IS0tIEZJTFRSRVMgLS0+XHJcbiAgICAgICAgICAgIDx0ciAqbmdJZj1cIm9wdGlvbnMuZmlsdGVyYWJsZVwiIGNsYXNzPVwicm93RmlsdGVyXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiY2VsbERlbGV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZGVDaGVja2JveFNlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlSGVhZGVyQ2hlY2tib3ggKm5nSWY9XCJvcHRpb25zLnRvZ2dsZUFsbFwiPjwvcC10YWJsZUhlYWRlckNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuXHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gVGV4dCAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiAoKGNoZWNrVHlwZSgnRHJvcGRvd24nLCBjb2wpICYmIGNvbC5vcHRpb25zLmZpbHRlclRleHQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8IChjaGVja1R5cGUoJ011bHRpU2VsZWN0JywgY29sKSAmJiBjb2wub3B0aW9ucy5maWx0ZXJUZXh0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCBjaGVja1R5cGUoJ1RleHQnLCBjb2wpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoZWNrVHlwZSgnRmlsZScsIGNvbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGNoZWNrVHlwZSgnQnV0dG9uJywgY29sKSAmJiBjb2wub3B0aW9ucy5maWx0ZXJDb2wpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCBjaGVja1R5cGUoJ051bWJlcicsIGNvbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2hlY2tUeXBlKCdDaWxvZ051bWJlcicsIGNvbClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCIhY29sLmRpc2FibGVGaWx0ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uRmlsdGVyQ29sKCRldmVudCwgY29sKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNvbC5vcHRpb25zLmRlZmF1bHRGaWx0ZXJzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90aD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEYXRlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0aCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnRGF0ZScsIGNvbClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1jYWxlbmRhciAqbmdJZj1cIiFjb2wuZGlzYWJsZUZpbHRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2aWV3XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gbnVsbCA/ICdkYXRlJyA6IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICd5ZWFyJyA/ICd5eScgOiBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICdtb250aCcgPyAnbW0veXknIDogJ2RkL21tL3l5J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dElkXT1cImNvbC5pZCArICdfZmlsdGVyJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0RGF5T2ZXZWVrPVwiMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seUlucHV0XT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25Nb2RlPVwicmFuZ2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25TZWxlY3QpPVwib25GaWx0ZXJDb2woJGV2ZW50LCBjb2wpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0J1dHRvbkJhcj1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGVhckNsaWNrKT1cIm9uRmlsdGVyQ29sKCRldmVudCwgY29sKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29sLm9wdGlvbnMuZGVmYXVsdEZpbHRlcnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWNhbGVuZGFyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTGlzdGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgKChjaGVja1R5cGUoJ0Ryb3Bkb3duJywgY29sKSAmJiAhY29sLm9wdGlvbnMuZmlsdGVyVGV4dCkgfHwgKGNoZWNrVHlwZSgnTXVsdGlTZWxlY3QnLCBjb2wpICYmICFjb2wub3B0aW9ucy5maWx0ZXJUZXh0KSB8fCBjaGVja1R5cGUoJ1NlbGVjdEJ1dHRvbicsIGNvbCkgfHwgY2hlY2tUeXBlKCdTdGF0ZScsIGNvbCkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnd2lkdGgnIDogY29sLndpZHRoID8gY29sLndpZHRoIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3QgKm5nSWY9XCIhY29sLmRpc2FibGVGaWx0ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2wub3B0aW9ucz8ub3B0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWx0ZXJdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJJRFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25MYWJlbF09XCJjb2wub3B0aW9ucz8ub3B0aW9uTGFiZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUZpbHRlck1lc3NhZ2U9XCJBdWN1biByw6lzdWx0YXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eU1lc3NhZ2U9XCJBdWN1biByw6lzdWx0YXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmlydHVhbFNjcm9sbF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxJdGVtU2l6ZV09XCIzNVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbXNMYWJlbD1cInswfSBzZWxlY3Rpb25uw6lzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uRmlsdGVyQ29sKCRldmVudCwgY29sKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29sLm9wdGlvbnMuZGVmYXVsdEZpbHRlcnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3JvdXBdPVwiY29sLm9wdGlvbnMub3B0aW9uR3JvdXBDaGlsZHJlbiAhPSBudWxsID8gdHJ1ZSA6IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbkdyb3VwTGFiZWxdPVwiY29sLm9wdGlvbnMub3B0aW9uR3JvdXBMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25Hcm91cENoaWxkcmVuXT1cImNvbC5vcHRpb25zLm9wdGlvbkdyb3VwQ2hpbGRyZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1RvZ2dsZUFsbF09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNsZWFyKT1cIm9uRmlsdGVyQ29sKG51bGwsIGNvbClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtZ3JvdXAgcFRlbXBsYXRlPVwiZ3JvdXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pnt7Z3JvdXBbY29sLm9wdGlvbnMub3B0aW9uR3JvdXBMYWJlbF19fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLW11bHRpU2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gU3dpdGNoIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0aCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnU3dpdGNoJywgY29sKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0ICpuZ0lmPVwiIWNvbC5kaXNhYmxlRmlsdGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwib3B0aW9uc1N3aXRjaFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93SGVhZGVyXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uTGFiZWw9XCJsYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvblZhbHVlPVwidmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUZpbHRlck1lc3NhZ2U9XCJBdWN1biByw6lzdWx0YXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eU1lc3NhZ2U9XCJBdWN1biByw6lzdWx0YXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmlydHVhbFNjcm9sbEl0ZW1TaXplXT1cIjMwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtc0xhYmVsPVwiezB9IHNlbGVjdGlvbm7DqXNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25GaWx0ZXJDb2woJGV2ZW50LCBjb2wpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJjb2wub3B0aW9ucy5kZWZhdWx0RmlsdGVyc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90aD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBOb24gZmlsdHJhYmxlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0aCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIChjaGVja1R5cGUoJ0ltYWdlJywgY29sKSB8fCAoY2hlY2tUeXBlKCdCdXR0b24nLCBjb2wpICYmICFjb2wub3B0aW9ucy5maWx0ZXJDb2wpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiY2VsbERlbGV0ZVwiICpuZ0lmPVwib3B0aW9ucy5yb3dzRGVsZXRhYmxlXCI+PC90aD5cclxuICAgICAgICAgICAgPC90cj5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gVE9UQUwgLS0+XHJcbiAgICAgICAgICAgIDx0ciAqbmdJZj1cIm9wdGlvbnMucm93VG90YWxcIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJyb3dUb3RhbFwiPlxyXG4gICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiY2VsbERlbGV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZGVDaGVja2JveFNlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uPlxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRoICpuZ0lmPVwiIWNvbC5pbnZpc2libGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICd0ZXh0LWNlbnRlcicgOiB0cnVlIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pnt7IGdldFRvdGFsU3RyKGNvbCkgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJjZWxsRGVsZXRlXCIgKm5nSWY9XCJvcHRpb25zLnJvd3NEZWxldGFibGVcIj48L3RoPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgIDwhLS1Hcm91cGhlYWRlci0tPlxyXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJncm91cGhlYWRlclwiIGxldC1yb3dEYXRhPlxyXG4gICAgICAgICAgICA8dHIgcFJvd0dyb3VwSGVhZGVyIGNsYXNzPVwicm93R3JvdXBpbmdcIj5cclxuICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnMubGVuZ3RoXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHRfYm9sZFwiPnt7IHJvd0RhdGFbb3B0aW9ucy5ncm91cGluZy5vYmpdW29wdGlvbnMuZ3JvdXBpbmcubGliZWxsZV0gfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgICAgICAgPCEtLSBCb2R5IC0tPlxyXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJib2R5XCIgbGV0LXJvd0RhdGEgbGV0LWNvbHVtbnM9XCJjb2x1bW5zXCI+XHJcbiAgICAgICAgICAgIDx0ciBpZD1cInt7IHJvd0RhdGEuaWQgfX1cIlxyXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGEuY29sb3IgPyByb3dEYXRhLmNvbG9yIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgIFtwU2VsZWN0YWJsZVJvd109XCJyb3dEYXRhXCJcclxuICAgICAgICAgICAgICAgIFtwU2VsZWN0YWJsZVJvd0Rpc2FibGVkXT1cIiFvcHRpb25zLnNlbGVjdGFibGUgfHwgaXNNb2RlQ2hlY2tib3hTZWxlY3Rpb24oKSB8fCBpc01vZGVDZWxsU2VsZWN0aW9uKClcIlxyXG4gICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cIm9uUm93RG91YmxlQ2xpY2tFdmVudChyb3dEYXRhKVwiXHJcbiAgICAgICAgICAgICAgICBbcENvbnRleHRNZW51Um93XT1cInJvd0RhdGFcIlxyXG4gICAgICAgICAgICAgICAgW3BDb250ZXh0TWVudVJvd0Rpc2FibGVkXT1cIm9wdGlvbnMuY29udGV4dE1lbnVJdGVtcyA9PSBudWxsXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNNb2RlQ2hlY2tib3hTZWxlY3Rpb24oKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjZWxsRGVsZXRlXCJcclxuICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlQ2hlY2tib3ggW3ZhbHVlXT1cInJvd0RhdGFcIiBbZGlzYWJsZWRdPVwicm93RGF0YS5yZWFkb25seVwiPjwvcC10YWJsZUNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIFRleHQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdUZXh0JywgY29sKSAmJiBpc01vZGVFZGl0aW9uKCkgJiYgIXJvd0RhdGEucmVhZG9ubHkgJiYgIXJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLCAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwRWRpdGFibGVDb2x1bW5dPVwicm93RGF0YVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwRWRpdGFibGVDb2x1bW5GaWVsZF09XCJjb2wuaWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogcm93RGF0YVtjb2wuaWRdLnZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvbiAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVjdGFibGVfY2VsbCcgOiBvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNlbGxFZGl0b3I+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgcElucHV0VGV4dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93RGF0YVtjb2wuaWRdLnZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJsdXIpPVwib25FZGl0Q2VsbChyb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duLnRhYik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkVkaXRJbml0Q2VsbChyb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogcHJlO1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBnZXRGb3JtYXR0ZWRUZXh0KGNvbCwgcm93RGF0YSkgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdUZXh0JywgY29sKSAmJiAoIWlzTW9kZUVkaXRpb24oKSB8fCByb3dEYXRhLnJlYWRvbmx5IHx8IHJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcicgOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbG9yJyA6IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgPyByb3dEYXRhW2NvbC5pZF0udGV4dENvbG9yIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvbiAmJiBvblNlbGVjdENlbGwocm93RGF0YVtjb2wuaWRdKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiByb3dEYXRhW2NvbC5pZF0udmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yaWdodCc6IGNvbC5wb3NpdGlvbiA9PSAncmlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtY2VudGVyJzogY29sLnBvc2l0aW9uID09ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sLmxpYmVsbGUgfX0gOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvd0RhdGFbY29sLmlkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogcHJlO1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZ2V0Rm9ybWF0dGVkVGV4dChjb2wsIHJvd0RhdGEpIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRHJvcGRvd24gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdEcm9wZG93bicsIGNvbCkgJiYgaXNNb2RlRWRpdGlvbigpICYmICFyb3dEYXRhLnJlYWRvbmx5ICYmICFyb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnd2lkdGgnIDogY29sLndpZHRoID8gY29sLndpZHRoIDogbnVsbCwgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1sZWZ0JzogY29sLnBvc2l0aW9uID09ICdsZWZ0JyB8fCBjb2wucG9zaXRpb24gPT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LXJpZ2h0JzogY29sLnBvc2l0aW9uID09ICdyaWdodCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcEVkaXRhYmxlQ29sdW1uXT1cInJvd0RhdGFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcEVkaXRhYmxlQ29sdW1uRmllbGRdPVwiY29sLmlkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmIG9uU2VsZWN0Q2VsbChyb3dEYXRhW2NvbC5pZF0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cInJvd0RhdGFbY29sLmlkXS50b29sdGlwICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udG9vbHRpcCA6IHJvd0RhdGFbY29sLmlkXS52YWx1ZSAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnZhbHVlW2dldE9wdGlvbihjb2wsIHJvd0RhdGEsICdvcHRpb25MYWJlbCcpXSA6ICcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicGFkZGluZ0NlbGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY29sdW1uLXRpdGxlXCI+e3sgY29sLmxpYmVsbGUgfX0gOiA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWRyb3Bkb3duICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdICE9IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJJRFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbnMnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlcl09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnZmlsdGVyJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25MYWJlbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhW2NvbC5pZF0udmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdXRvRGlzcGxheUZpcnN0XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ2RlbGV0YWJsZScpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUZpbHRlck1lc3NhZ2U9XCJBdWN1biByw6lzdWx0YXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5TWVzc2FnZT1cIkF1Y3VuIHLDqXN1bHRhdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Jhc2VaSW5kZXhdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ2Jhc2VaSW5kZXgnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ3ZpcnR1YWxTY3JvbGwnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxJdGVtU2l6ZV09XCIzMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uRWRpdENlbGwocm93RGF0YSwgY29sLCByb3dEYXRhW2NvbC5pZF0udmFsdWUpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGVhcik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbGV0LWRhdGEgcFRlbXBsYXRlPVwic2VsZWN0ZWRJdGVtXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImRhdGEgIT0gbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1ib2xkJzogcm93RGF0YS5ib2xkID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLmJvbGQgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWl0YWxpYyc6IHJvd0RhdGEuaXRhbGljID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLml0YWxpYyA9PSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2dldE9wdGlvbihjb2wsIHJvd0RhdGEsICdvcHRpb25MYWJlbCcpXSB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJkYXRhID09IG51bGxcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWRyb3Bkb3duPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwid2hpdGUtc3BhY2U6IHByZTtcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcm93RGF0YVtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udmFsdWVbZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJyldIDogJycgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tPHAtZHJvcGRvd24gKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF0gIT0gbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJJRFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdvcHRpb25zJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVyXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdmaWx0ZXInKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25MYWJlbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93RGF0YVtjb2wuaWRdLnZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9EaXNwbGF5Rmlyc3RdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0NsZWFyXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdkZWxldGFibGUnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5RmlsdGVyTWVzc2FnZT1cIkF1Y3VuIHLDqXN1bHRhdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5TWVzc2FnZT1cIkF1Y3VuIHLDqXN1bHRhdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYXNlWkluZGV4XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdiYXNlWkluZGV4JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmlydHVhbFNjcm9sbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAndmlydHVhbFNjcm9sbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2aXJ0dWFsU2Nyb2xsSXRlbVNpemVdPVwiMzBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25FZGl0Q2VsbChyb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGVhcik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1kYXRhIHBUZW1wbGF0ZT1cInNlbGVjdGVkSXRlbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZGF0YSAhPSBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1ib2xkJzogcm93RGF0YS5ib2xkID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLmJvbGQgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWl0YWxpYyc6IHJvd0RhdGEuaXRhbGljID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLml0YWxpYyA9PSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZGF0YVtnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKV0gfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJkYXRhID09IG51bGxcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3AtZHJvcGRvd24+LS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ0Ryb3Bkb3duJywgY29sKSAmJiAocm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8ICFpc01vZGVFZGl0aW9uKCkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29sb3InIDogcm93RGF0YVtjb2wuaWRdLnRleHRDb2xvciA/IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgOiBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInt7IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLmlkIDogJycgfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogcm93RGF0YVtjb2wuaWRdLnZhbHVlICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udmFsdWVbZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJyldIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yaWdodCc6IGNvbC5wb3NpdGlvbiA9PSAncmlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtY2VudGVyJzogY29sLnBvc2l0aW9uID09ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIj57eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS52YWx1ZVtnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKV0gOiAnJyB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQ2lsb2cgTnVtYmVyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnQ2lsb2dOdW1iZXInLCBjb2wpICYmIGlzTW9kZUVkaXRpb24oKSAmJiAhcm93RGF0YS5yZWFkb25seSAmJiAhcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsICdiYWNrZ3JvdW5kLWNvbG9yJzogcm93RGF0YVtjb2wuaWRdLmNvbG9yID8gcm93RGF0YVtjb2wuaWRdLmNvbG9yIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogcm93RGF0YVtjb2wuaWRdLnZhbHVlIHwgdmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjaWxvZy1pbnB1dC1udW1iZXIgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF0gJiYgIXJvd0RhdGEucmVhZG9ubHkgJiYgIXJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbklucHV0KT1cIm9uSW5wdXROdW1iZXIoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhW2NvbC5pZF0udmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dFN0eWxlQ2xhc3NdPVwiY29sLnBvc2l0aW9uID09IG51bGwgfHwgY29sLnBvc2l0aW9uID09ICdyaWdodCcgPyAndGV4dC1yaWdodCcgOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnID8gJ3RleHQtbGVmdCcgOiAndGV4dC1jZW50ZXInXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dENvbG9yXT1cInJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3JcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtib2xkXT1cInJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGFsaWNdPVwicm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdWZmaXhlXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdzdWZmaXgnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ByZWZpeGVdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ3ByZWZpeCcpICE9IG51bGwgPyBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAncHJlZml4JykgKyAnICcgOiBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtaW4nKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWF4JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyb3dEYXRhLnJlYWRvbmx5IHx8IHJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEZWNpbWFsc109XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZUludGVnZXInKSAhPSBudWxsICYmIGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlSW50ZWdlcicpID09IHRydWUgPyAwIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21heERlY2ltYWxlcycpICE9IG51bGwgPyBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWF4RGVjaW1hbGVzJykgOiAyIFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uRWRpdENlbGwocm93RGF0YSwgY29sLCByb3dEYXRhW2NvbC5pZF0udmFsdWUpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25Gb2N1cyk9XCJvbkVkaXRJbml0Q2VsbChyb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9jaWxvZy1pbnB1dC1udW1iZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ0NpbG9nTnVtYmVyJywgY29sKSAmJiAocm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8ICFpc01vZGVFZGl0aW9uKCkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29sb3InIDogcm93RGF0YVtjb2wuaWRdLnRleHRDb2xvciA/IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgOiBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInt7IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLmlkIDogJycgfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogcm93RGF0YVtjb2wuaWRdLnZhbHVlIHwgdmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yaWdodCc6IGNvbC5wb3NpdGlvbiA9PSAncmlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtY2VudGVyJzogY29sLnBvc2l0aW9uID09ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIj57eyBnZXRGb3JtYXR0ZWROdW1iZXIoY29sLCByb3dEYXRhLCByb3dEYXRhW2NvbC5pZF0udmFsdWUpIH19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBOdW1iZXIgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdOdW1iZXInLCBjb2wpICYmIGlzTW9kZUVkaXRpb24oKSAmJiAhcm93RGF0YS5yZWFkb25seSAmJiAhcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsICdiYWNrZ3JvdW5kLWNvbG9yJzogcm93RGF0YVtjb2wuaWRdLmNvbG9yID8gcm93RGF0YVtjb2wuaWRdLmNvbG9yIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cInJvd0RhdGFbY29sLmlkXS50b29sdGlwICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udG9vbHRpcCA6IHJvd0RhdGFbY29sLmlkXS52YWx1ZSB8IHZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcEVkaXRhYmxlQ29sdW1uXT1cInJvd0RhdGFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcEVkaXRhYmxlQ29sdW1uRmllbGRdPVwiY29sLmlkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1sZWZ0JzogY29sLnBvc2l0aW9uID09ICdsZWZ0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LXJpZ2h0JzogY29sLnBvc2l0aW9uID09ICdyaWdodCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1ib2xkJzogcm93RGF0YS5ib2xkID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLmJvbGQgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWl0YWxpYyc6IHJvd0RhdGEuaXRhbGljID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLml0YWxpYyA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVjdGFibGVfY2VsbCcgOiBvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY29sdW1uLXRpdGxlXCI+e3sgY29sLmxpYmVsbGUgfX0gOiA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWlucHV0TnVtYmVyICNpbnB1dE51bWJlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdICYmICFyb3dEYXRhLnJlYWRvbmx5ICYmICFyb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGU9XCJmci1GUlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uSW5wdXQpPVwib25JbnB1dE51bWJlcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd0RhdGFbY29sLmlkXS52YWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCdXR0b25zXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdzaG93QnV0dG9ucycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5wdXRTdHlsZUNsYXNzXT1cImNvbC5wb3NpdGlvbiA9PSBudWxsIHx8IGNvbC5wb3NpdGlvbiA9PSAncmlnaHQnID8gJ3RleHQtcmlnaHQnIDogY29sLnBvc2l0aW9uID09ICdsZWZ0JyA/ICd0ZXh0LWxlZnQnIDogJ3RleHQtY2VudGVyJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lucHV0U3R5bGVdPVwieyAnZm9udC13ZWlnaHQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlID8gJ2JvbGQnIDogbnVsbCwgJ2ZvbnQtc3R5bGUnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSA/ICdpdGFsaWMnIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3VmZml4XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdzdWZmaXgnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ByZWZpeF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAncHJlZml4JykgIT0gbnVsbCA/IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdwcmVmaXgnKSArICcgJyA6IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21pbicpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtYXgnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbkZyYWN0aW9uRGlnaXRzXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlSW50ZWdlcicpICE9IG51bGwgJiYgZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGVJbnRlZ2VyJykgPT0gdHJ1ZSA/IDAgOiBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWluRGVjaW1hbGVzJykgIT0gbnVsbCA/IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtaW5EZWNpbWFsZXMnKSA6IDBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhGcmFjdGlvbkRpZ2l0c109XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZUludGVnZXInKSAhPSBudWxsICYmIGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlSW50ZWdlcicpID09IHRydWUgPyAwIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21heERlY2ltYWxlcycpICE9IG51bGwgPyBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWF4RGVjaW1hbGVzJykgOiAyIFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQmx1cik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uS2V5RG93bik9XCJvbktleURvd24oJGV2ZW50LCByb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkZvY3VzKT1cIm9uRWRpdEluaXRDZWxsKCRldmVudCwgcm93RGF0YSwgY29sLCByb3dEYXRhW2NvbC5pZF0udmFsdWUpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RlcF09XCIwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWlucHV0TnVtYmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwid2hpdGUtc3BhY2U6IHByZTtcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZ2V0Rm9ybWF0dGVkTnVtYmVyKGNvbCwgcm93RGF0YSwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKSB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWNlbGxFZGl0b3I+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ051bWJlcicsIGNvbCkgJiYgKHJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seSB8fCAhaXNNb2RlRWRpdGlvbigpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbG9yJyA6IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgPyByb3dEYXRhW2NvbC5pZF0udGV4dENvbG9yIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cInJvd0RhdGFbY29sLmlkXS50b29sdGlwICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udG9vbHRpcCA6IHJvd0RhdGFbY29sLmlkXS52YWx1ZSB8IHZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFkZGluZ0NlbGwnOiByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWxlZnQnOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyB8fCBjb2wucG9zaXRpb24gPT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWNlbnRlcic6IGNvbC5wb3NpdGlvbiA9PSAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWJvbGQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdXCI+e3sgZ2V0Rm9ybWF0dGVkTnVtYmVyKGNvbCwgcm93RGF0YSwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKSB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRGF0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ0RhdGUnLCBjb2wpICYmIGlzTW9kZUVkaXRpb24oKSAmJiAhcm93RGF0YS5yZWFkb25seSAmJiAhcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsICdiYWNrZ3JvdW5kLWNvbG9yJzogcm93RGF0YVtjb2wuaWRdLmNvbG9yID8gcm93RGF0YVtjb2wuaWRdLmNvbG9yIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSAneWVhcicgPyAocm93RGF0YVtjb2wuaWRdLnZhbHVlIHwgZGF0ZTogJ3l5eXknKSA6IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ21vbnRoJyA/IChyb3dEYXRhW2NvbC5pZF0udmFsdWUgfCBkYXRlOiAnTU0veXknKSA6IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ2hvdXInID8gKHJvd0RhdGFbY29sLmlkXS52YWx1ZSB8IGRhdGU6ICdISDptbScpIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSAnZGF0ZWhvdXInID8gKHJvd0RhdGFbY29sLmlkXS52YWx1ZSB8IGRhdGU6ICdkZC9NTS95eSBISDptbScpIDogKHJvd0RhdGFbY29sLmlkXS52YWx1ZSB8IGRhdGU6ICdkZC9NTS95eXl5JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyIFsobmdNb2RlbCldPVwicm93RGF0YVtjb2wuaWRdLnZhbHVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZpZXddPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSBudWxsIHx8IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ2RhdGUnIHx8IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ2hvdXInID8gJ2RhdGUnIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSAnZGF0ZWhvdXInID8gJ2RhdGUnIDogZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ3llYXInID8gJ3l5JyA6IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtb2RlJykgPT0gJ21vbnRoJyA/ICdtbS95eScgOiBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICdob3VyJyB8fCBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICdkYXRlaG91cicgPyAnZGQvbW0veXknIDogJ2RkL21tL3l5J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICdkYXRlaG91cidcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGltZU9ubHldPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSAnaG91cidcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaG91ckZvcm1hdF09XCIyNFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0RGF5T2ZXZWVrPVwiMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvblNlbGVjdCk9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkJsdXIpPVwib25FZGl0Q2VsbChyb3dEYXRhLCBjb2wsIHJvd0RhdGFbY29sLmlkXS52YWx1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGVhcik9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dFN0eWxlQ2xhc3NdPVwiY29sLnBvc2l0aW9uID09IG51bGwgfHwgY29sLnBvc2l0aW9uID09ICdyaWdodCcgPyAndGV4dC1yaWdodCcgOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnID8gJ3RleHQtbGVmdCcgOiAndGV4dC1jZW50ZXInXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lucHV0U3R5bGVdPVwieyAnZm9udC13ZWlnaHQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlID8gJ2JvbGQnIDogbnVsbCwgJ2ZvbnQtc3R5bGUnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSA/ICdpdGFsaWMnIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dDbGVhcl09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnY2xlYXInKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5EYXRlXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdtaW5EYXRlJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4RGF0ZV09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbWF4RGF0ZScpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RlZmF1bHREYXRlXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdkZWZhdWx0RGF0ZScpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1jYWxlbmRhcj5cclxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnRGF0ZScsIGNvbCkgJiYgKHJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seSB8fCAhaXNNb2RlRWRpdGlvbigpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtaW4td2lkdGgnIDogY29sLndpZHRoID8gY29sLndpZHRoIDogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWNvbG9yJzogcm93RGF0YVtjb2wuaWRdLmNvbG9yID8gcm93RGF0YVtjb2wuaWRdLmNvbG9yIDogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb2xvcicgOiByb3dEYXRhW2NvbC5pZF0udGV4dENvbG9yID8gcm93RGF0YVtjb2wuaWRdLnRleHRDb2xvciA6IG51bGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvbiAmJiBvblNlbGVjdENlbGwocm93RGF0YVtjb2wuaWRdKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiByb3dEYXRhW2NvbC5pZF0udmFsdWUgfCBkYXRlOiAnZGQvTU0veXl5eSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yaWdodCc6IGNvbC5wb3NpdGlvbiA9PSAncmlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtY2VudGVyJzogY29sLnBvc2l0aW9uID09ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIj57eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgfCBkYXRlOiAoZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ21vZGUnKSA9PSAneWVhcicgPyAneXl5eScgOiBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbW9kZScpID09ICdtb250aCcgPyAnTU0veXl5eScgOiAnZGQvTU0veXl5eScpIH19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNdWx0aVNlbGVjdCAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ011bHRpU2VsZWN0JywgY29sKSAmJiBpc01vZGVFZGl0aW9uKCkgJiYgIXJvd0RhdGEucmVhZG9ubHkgJiYgIXJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLCAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWxlZnQnOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnIHx8IGNvbC5wb3NpdGlvbiA9PSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWNlbnRlcic6IGNvbC5wb3NpdGlvbiA9PSAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvbiAmJiBvblNlbGVjdENlbGwocm93RGF0YVtjb2wuaWRdKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiBnZXRNdWx0aVNlbGVjdENvbmNhdChyb3dEYXRhW2NvbC5pZF0udmFsdWUsIGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdvcHRpb25MYWJlbCcpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwRGlzYWJsZWRdPVwiIWNvbC50b29sdGlwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInBhZGRpbmdDZWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLW11bHRpU2VsZWN0ICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdICE9IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9ucycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlcl09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnZmlsdGVyJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uTGFiZWxdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd0RhdGFbY29sLmlkXS52YWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvPVwiYm9keVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJJRFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5RmlsdGVyTWVzc2FnZT1cIkF1Y3VuIHLDqXN1bHRhdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5TWVzc2FnZT1cIkF1Y3VuIHLDqXN1bHRhdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYXNlWkluZGV4XT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdiYXNlWkluZGV4JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmlydHVhbFNjcm9sbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAndmlydHVhbFNjcm9sbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seSB8fCAhaXNNb2RlRWRpdGlvbigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxJdGVtU2l6ZV09XCIzMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbXNMYWJlbD1cInswfSBzZWxlY3Rpb25uw6lzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cImVkaXRNdWx0aXNlbGVjdChyb3dEYXRhLCBjb2wsICRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1RvZ2dsZUFsbF09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93SGVhZGVyXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdmaWx0ZXInKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtncm91cF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uR3JvdXBDaGlsZHJlbicpICE9IG51bGwgPyB0cnVlIDogZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uR3JvdXBMYWJlbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uR3JvdXBMYWJlbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbkdyb3VwQ2hpbGRyZW5dPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkdyb3VwQ2hpbGRyZW4nKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5nRGVmYXVsdENvbnRyb2w+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbGV0LWRhdGEgcFRlbXBsYXRlPVwic2VsZWN0ZWRJdGVtc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgZGF0YSwgbGV0IGkgPSBpbmRleFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb25bZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJyldICsgKGkgIT0gZGF0YS5sZW5ndGggLSAxID8gJywnIDogJycpIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtZ3JvdXAgcFRlbXBsYXRlPVwiZ3JvdXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pnt7Z3JvdXBbY29sLm9wdGlvbnMub3B0aW9uR3JvdXBMYWJlbF19fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wLW11bHRpU2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdNdWx0aVNlbGVjdCcsIGNvbCkgJiYgKHJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seSB8fCAhaXNNb2RlRWRpdGlvbigpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbG9yJyA6IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgPyByb3dEYXRhW2NvbC5pZF0udGV4dENvbG9yIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmIG9uU2VsZWN0Q2VsbChyb3dEYXRhW2NvbC5pZF0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cInJvd0RhdGFbY29sLmlkXS50b29sdGlwICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0udG9vbHRpcCA6IGdldE11bHRpU2VsZWN0Q29uY2F0KHJvd0RhdGFbY29sLmlkXS52YWx1ZSwgZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJykpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFkZGluZ0NlbGwnOiByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWxlZnQnOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnIHx8IGNvbC5wb3NpdGlvbiA9PSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWNlbnRlcic6IGNvbC5wb3NpdGlvbiA9PSAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWJvbGQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdXCI+e3sgZ2V0TXVsdGlTZWxlY3RDb25jYXQocm93RGF0YVtjb2wuaWRdLnZhbHVlLCBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKSkgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIEltYWdlIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnSW1hZ2UnLCBjb2wpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnd2lkdGgnIDogY29sLndpZHRoID8gY29sLndpZHRoIDogbnVsbCwgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInt7IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLmlkIDogJycgfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFkZGluZ0NlbGwnOiByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RhYmxlX2NlbGwnIDogb3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvbiAmJiBvblNlbGVjdENlbGwocm93RGF0YVtjb2wuaWRdKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1jZW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdXCIgc3R5bGU9XCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlOyB3aWR0aDogNDBweDtcIiBzcmM9XCJ7eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgfX1cIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQnV0dG9uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZCAqbmdJZj1cIiFjb2wuaW52aXNpYmxlICYmIGNoZWNrVHlwZSgnQnV0dG9uJywgY29sKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicGFkZGluZ0NlbGwgdGV4dC1jZW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLCAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInJvd0RhdGFbY29sLmlkXS52YWx1ZSAhPSBudWxsICYmIGlzVmFsdWVCdXR0b25CeVR5cGUocm93RGF0YVtjb2wuaWRdLnZhbHVlLCAnZnVuY3Rpb24nKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cImdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdsYWJlbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWNvbl09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnaWNvbicpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicm93RGF0YVtjb2wuaWRdLnZhbHVlKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiBnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnbGFiZWwnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCIncC1idXR0b24tJyArIGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdzZXZlcml0eScpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWJvbGQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc1ZhbHVlQnV0dG9uQnlUeXBlKHJvd0RhdGFbY29sLmlkXS52YWx1ZSwgJ3N0cmluZycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtbGVmdCc6IGNvbC5wb3NpdGlvbiA9PSAnbGVmdCcgfHwgY29sLnBvc2l0aW9uID09IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtYm9sZCc6IHJvd0RhdGEuYm9sZCA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5ib2xkID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiByb3dEYXRhW2NvbC5pZF0udmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwRGlzYWJsZWRdPVwiIWNvbC50b29sdGlwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBTZWxlY3RCdXR0b24gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdTZWxlY3RCdXR0b24nLCBjb2wpICYmIGlzTW9kZUVkaXRpb24oKSAmJiAhcm93RGF0YS5yZWFkb25seSAmJiAhcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsICdiYWNrZ3JvdW5kLWNvbG9yJzogcm93RGF0YVtjb2wuaWRdLmNvbG9yID8gcm93RGF0YVtjb2wuaWRdLmNvbG9yIDogbnVsbCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1zZWxlY3RCdXR0b24gKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF0gIT0gbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9ucycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25MYWJlbF09XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnb3B0aW9uTGFiZWwnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uVmFsdWVdPVwiZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvblZhbHVlJykgIT0gbnVsbCA/IGdldE9wdGlvbihjb2wsIHJvd0RhdGEsICdvcHRpb25WYWx1ZScpIDogJ3ZhbHVlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd0RhdGFbY29sLmlkXS52YWx1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwicm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8ICFpc01vZGVFZGl0aW9uKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uRWRpdENlbGwocm93RGF0YSwgY29sLCByb3dEYXRhW2NvbC5pZF0udmFsdWUpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbGV0LWl0ZW0gcFRlbXBsYXRlPVwiaXRlbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1jZW50ZXIgdy1mdWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWJvbGQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1pdGFsaWMnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5sYWJlbCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1zZWxlY3RCdXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmludmlzaWJsZSAmJiBjaGVja1R5cGUoJ1NlbGVjdEJ1dHRvbicsIGNvbCkgJiYgKHJvd0RhdGEucmVhZG9ubHkgfHwgcm93RGF0YVtjb2wuaWRdPy5yZWFkb25seSB8fCAhaXNNb2RlRWRpdGlvbigpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbG9yJyA6IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgPyByb3dEYXRhW2NvbC5pZF0udGV4dENvbG9yIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmIG9uU2VsZWN0Q2VsbChyb3dEYXRhW2NvbC5pZF0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtY2VudGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1ib2xkJzogcm93RGF0YS5ib2xkID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLmJvbGQgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWl0YWxpYyc6IHJvd0RhdGEuaXRhbGljID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLml0YWxpYyA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVjdGFibGVfY2VsbCcgOiBvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIj57eyBnZXRTZWxlY3RMaWJlbGxlQnlWYWx1ZShyb3dEYXRhLCBjb2wpIH19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBTd2l0Y2ggLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdTd2l0Y2gnLCBjb2wpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyAnd2lkdGgnIDogY29sLndpZHRoID8gY29sLndpZHRoIDogbnVsbCwgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0uY29sb3IgPyByb3dEYXRhW2NvbC5pZF0uY29sb3IgOiBudWxsIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtY2VudGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7eyByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS5pZCA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmdDZWxsJzogcm93RGF0YVtjb2wuaWRdICE9IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmcm96ZW5dPVwiY29sLmZyb3plblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wubGliZWxsZSB9fSA6IDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1pbnB1dFN3aXRjaCAqbmdJZj1cInJvd0RhdGFbY29sLmlkXSAhPSBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhW2NvbC5pZF0udmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwicm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8IChnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnYWN0aW9uJykgPT0gbnVsbCAmJiAhaXNNb2RlRWRpdGlvbigpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgcm93RGF0YVtjb2wuaWRdLnZhbHVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5nRGVmYXVsdENvbnRyb2w+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1pbnB1dFN3aXRjaD5cclxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIEZpbGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdGaWxlJywgY29sKSAmJiBpc01vZGVFZGl0aW9uKCkgJiYgIXJvd0RhdGEucmVhZG9ubHkgJiYgIXJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLCAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVjdGFibGVfY2VsbCcgOiBvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmIG9uU2VsZWN0Q2VsbChyb3dEYXRhW2NvbC5pZF0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgcEZyb3plbkNvbHVtblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImNvbC5mcm96ZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY29sdW1uLXRpdGxlXCI+e3sgY29sLmxpYmVsbGUgfX0gOiA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtaW5wdXRncm91cFwiICpuZ0lmPVwicm93RGF0YVtjb2wuaWRdICE9IG51bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJpcHBsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdXBsb2FkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsaWNrQnlJZCgnaW5wdXRfJyArIHJvd0RhdGFbY29sLmlkXS5pZClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwicm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8ICFpc01vZGVFZGl0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVwie3snb3V0cHV0XycgKyByb3dEYXRhW2NvbC5pZF0uaWR9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1sZWZ0JzogY29sLnBvc2l0aW9uID09ICdsZWZ0JyB8fCBjb2wucG9zaXRpb24gPT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LXJpZ2h0JzogY29sLnBvc2l0aW9uID09ICdyaWdodCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1jZW50ZXInOiBjb2wucG9zaXRpb24gPT0gJ2NlbnRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1ib2xkJzogcm93RGF0YS5ib2xkID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLmJvbGQgPT0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWl0YWxpYyc6IHJvd0RhdGEuaXRhbGljID09IHRydWUgfHwgcm93RGF0YVtjb2wuaWRdLml0YWxpYyA9PSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9XCJ7eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS52YWx1ZSA6ICcnIH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkb25seVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCJyb3dEYXRhW2NvbC5pZF0udG9vbHRpcCAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgOiByb3dEYXRhW2NvbC5pZF0udmFsdWUgPyByb3dEYXRhW2NvbC5pZF0udmFsdWUgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCIhY29sLnRvb2x0aXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJnZXRPcHRpb24oY29sLCByb3dEYXRhLCAnZG93bmxvYWRQYXRoJykgJiYgcm93RGF0YVtjb2wuaWRdLnZhbHVlICE9IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS1kb3dubG9hZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkb3dubG9hZEZpbGUocm93RGF0YVtjb2wuaWRdKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyb3dEYXRhLnJlYWRvbmx5IHx8IHJvd0RhdGFbY29sLmlkXT8ucmVhZG9ubHkgfHwgIWlzTW9kZUVkaXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIiBpZD1cInt7J2lucHV0XycgKyByb3dEYXRhW2NvbC5pZF0uaWR9fVwiICNpbnB1dEZpbGUgcElucHV0VGV4dCB0eXBlPVwiZmlsZVwiIGhpZGRlbiAoY2hhbmdlKT1cInJvd0RhdGFbY29sLmlkXS52YWx1ZSA9IGlucHV0RmlsZS5maWxlc1swXS5uYW1lOyBvbkVkaXRDZWxsKHJvd0RhdGEsIGNvbCwgaW5wdXRGaWxlLmZpbGVzWzBdKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdGaWxlJywgY29sKSAmJiAocm93RGF0YS5yZWFkb25seSB8fCByb3dEYXRhW2NvbC5pZF0/LnJlYWRvbmx5IHx8ICFpc01vZGVFZGl0aW9uKCkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyA6IGNvbC53aWR0aCA/IGNvbC53aWR0aCA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29sb3InIDogcm93RGF0YVtjb2wuaWRdLnRleHRDb2xvciA/IHJvd0RhdGFbY29sLmlkXS50ZXh0Q29sb3IgOiBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib3B0aW9ucy5zZWxlY3RhYmxlICYmIGlzTW9kZUNlbGxTZWxlY3Rpb24oKSAmJiAhcm93RGF0YVtjb2wuaWRdLmRpc2FibGVTZWxlY3Rpb24gJiYgb25TZWxlY3RDZWxsKHJvd0RhdGFbY29sLmlkXSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInt7IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsID8gcm93RGF0YVtjb2wuaWRdLmlkIDogJycgfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwicm93RGF0YVtjb2wuaWRdLnRvb2x0aXAgIT0gbnVsbCA/IHJvd0RhdGFbY29sLmlkXS50b29sdGlwIDogcm93RGF0YVtjb2wuaWRdLnZhbHVlID8gcm93RGF0YVtjb2wuaWRdLnZhbHVlIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFkZGluZ0NlbGwnOiByb3dEYXRhW2NvbC5pZF0gIT0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWxlZnQnOiBjb2wucG9zaXRpb24gPT0gJ2xlZnQnIHx8IGNvbC5wb3NpdGlvbiA9PSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmlnaHQnOiBjb2wucG9zaXRpb24gPT0gJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWNlbnRlcic6IGNvbC5wb3NpdGlvbiA9PSAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb250LWJvbGQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtaXRhbGljJzogcm93RGF0YS5pdGFsaWMgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uaXRhbGljID09IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0YWJsZV9jZWxsJyA6IG9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcERpc2FibGVkXT1cIiFjb2wudG9vbHRpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3dEYXRhW2NvbC5pZF1cIj57eyByb3dEYXRhW2NvbC5pZF0udmFsdWUgPyByb3dEYXRhW2NvbC5pZF0udmFsdWUgOiAnJyB9fTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gU3RhdGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkICpuZ0lmPVwiIWNvbC5pbnZpc2libGUgJiYgY2hlY2tUeXBlKCdTdGF0ZScsIGNvbClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICd3aWR0aCcgOiBjb2wud2lkdGggPyBjb2wud2lkdGggOiBudWxsLCAnYmFja2dyb3VuZC1jb2xvcic6IHJvd0RhdGFbY29sLmlkXS5jb2xvciA/IHJvd0RhdGFbY29sLmlkXS5jb2xvciA6IG51bGwgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwie3sgcm93RGF0YVtjb2wuaWRdICE9IG51bGwgPyByb3dEYXRhW2NvbC5pZF0uaWQgOiAnJyB9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYWRkaW5nQ2VsbCc6IHJvd0RhdGFbY29sLmlkXSAhPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVjdGFibGVfY2VsbCcgOiBvcHRpb25zLnNlbGVjdGFibGUgJiYgaXNNb2RlQ2VsbFNlbGVjdGlvbigpICYmICFyb3dEYXRhW2NvbC5pZF0uZGlzYWJsZVNlbGVjdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbnMuc2VsZWN0YWJsZSAmJiBpc01vZGVDZWxsU2VsZWN0aW9uKCkgJiYgIXJvd0RhdGFbY29sLmlkXS5kaXNhYmxlU2VsZWN0aW9uICYmIG9uU2VsZWN0Q2VsbChyb3dEYXRhW2NvbC5pZF0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJjb2wuZnJvemVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5saWJlbGxlIH19IDogPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLXRhZyAqbmdJZj1cInJvd0RhdGFbY29sLmlkXS52YWx1ZSAhPSBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJyb3dEYXRhW2NvbC5pZF0udmFsdWVbZ2V0T3B0aW9uKGNvbCwgcm93RGF0YSwgJ29wdGlvbkxhYmVsJyldXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZXZlcml0eV09XCJyb3dEYXRhW2NvbC5pZF0udmFsdWUuc2V2ZXJpdHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ljb25dPVwicm93RGF0YVtjb2wuaWRdLnZhbHVlLmljb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlXT1cIntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiByb3dEYXRhW2NvbC5pZF0udmFsdWUuYmFja2dyb3VuZENvbG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29sb3InOiByb3dEYXRhW2NvbC5pZF0udmFsdWUudGV4dENvbG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9udC13ZWlnaHQnOiByb3dEYXRhLmJvbGQgPT0gdHJ1ZSB8fCByb3dEYXRhW2NvbC5pZF0uYm9sZCA9PSB0cnVlID8gJ2JvbGQnIDogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbnQtc3R5bGUnOiByb3dEYXRhLml0YWxpYyA9PSB0cnVlIHx8IHJvd0RhdGFbY29sLmlkXS5pdGFsaWMgPT0gdHJ1ZSA/ICdpdGFsaWMnIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3AtdGFnPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBEZWxldGlvbiAtLT5cclxuICAgICAgICAgICAgICAgIDx0ZCAqbmdJZj1cIm9wdGlvbnMucm93c0RlbGV0YWJsZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjZWxsRGVsZXRlXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJyb3dEYXRhLmRlbGV0YWJsZSA/ICdwYWRkaW5nQ2VsbCcgOiBudWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInJvd0RhdGEuZGVsZXRhYmxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBCdXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXRpbWVzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tZGFuZ2VyIGJ1dHRvbkRlbGV0ZSBwLWJ1dHRvbi10ZXh0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyb3dEYXRhLnJlYWRvbmx5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZUxpbmUocm93RGF0YSlcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICA8L3AtdGFibGU+XHJcbjwvZGl2PlxyXG4iXX0=
|