@oneteme/jquery-table 0.0.1 → 0.0.2
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/README.md +439 -122
- package/esm2022/lib/component/export.manager.mjs +45 -0
- package/esm2022/lib/component/group-by.manager.mjs +99 -0
- package/esm2022/lib/component/lazy-column-manager.mjs +99 -0
- package/esm2022/lib/component/slice-panel/slice-panel.component.mjs +43 -37
- package/esm2022/lib/component/slice-panel/slice-panel.model.mjs +1 -1
- package/esm2022/lib/component/table-preferences.manager.mjs +38 -0
- package/esm2022/lib/component/table.component.mjs +681 -370
- package/esm2022/lib/component/table.constants.mjs +31 -0
- package/esm2022/lib/component/table.utils.mjs +2 -2
- package/esm2022/lib/component/view/view.facade.mjs +298 -0
- package/esm2022/lib/jqt-i18n.token.mjs +41 -0
- package/esm2022/lib/jquery-table.model.mjs +14 -2
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/oneteme-jquery-table.mjs +1377 -408
- package/fesm2022/oneteme-jquery-table.mjs.map +1 -1
- package/lib/component/export.manager.d.ts +16 -0
- package/lib/component/group-by.manager.d.ts +44 -0
- package/lib/component/lazy-column-manager.d.ts +26 -0
- package/lib/component/slice-panel/slice-panel.component.d.ts +11 -3
- package/lib/component/slice-panel/slice-panel.model.d.ts +11 -1
- package/lib/component/table-preferences.manager.d.ts +17 -0
- package/lib/component/table.component.d.ts +162 -27
- package/lib/component/table.constants.d.ts +30 -0
- package/lib/component/view/view.facade.d.ts +93 -0
- package/lib/jqt-i18n.token.d.ts +87 -0
- package/lib/jquery-table.model.d.ts +79 -0
- package/package.json +2 -2
- package/public-api.d.ts +1 -0
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
import { CommonModule } from '@angular/common';
|
|
2
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, inject, Input, Output, QueryList, ViewChild } from '@angular/core';
|
|
2
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, inject, Input, NgZone, Output, QueryList, ViewChild } from '@angular/core';
|
|
3
3
|
import { FormsModule } from '@angular/forms';
|
|
4
4
|
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatDividerModule } from '@angular/material/divider';
|
|
5
6
|
import { MatIconModule } from '@angular/material/icon';
|
|
6
7
|
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
|
7
8
|
import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
|
|
8
9
|
import { MatSelectModule } from '@angular/material/select';
|
|
9
10
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
10
11
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
11
|
-
import { Subject,
|
|
12
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
13
|
+
import { JQT_I18N, JQT_I18N_DEFAULTS } from '../jqt-i18n.token';
|
|
12
14
|
import { JqtCellDefDirective } from '../directive/jqt-cell-def.directive';
|
|
13
15
|
import { SlicePanelComponent } from './slice-panel/slice-panel.component';
|
|
14
16
|
import { getFrenchPaginatorIntl, humanizeKey, normalizeCellValue } from './table.utils';
|
|
17
|
+
import { ViewFacade } from './view/view.facade';
|
|
18
|
+
import { LazyColumnManager } from './lazy-column-manager';
|
|
19
|
+
import { TablePreferencesManager } from './table-preferences.manager';
|
|
20
|
+
import { GroupByManager } from './group-by.manager';
|
|
21
|
+
import { ExportManager } from './export.manager';
|
|
22
|
+
import { GROUP_ROW_COLUMN, GROUP_HEADER_MARKER, GROUP_KEY_LAZY_LOADING, GROUP_KEY_TOO_MANY, ROW_RAW_KEY, ROW_INDEX_KEY, ROW_GROUP_KEY, ROW_GROUP_COUNT, ROW_GROUP_PAGE, ROW_GROUP_PAGE_COUNT, LAZY_LOADING_VALUE, LAZY_ERROR_VALUE, } from './table.constants';
|
|
15
23
|
import * as i0 from "@angular/core";
|
|
16
24
|
import * as i1 from "@angular/common";
|
|
17
25
|
import * as i2 from "@angular/forms";
|
|
18
26
|
import * as i3 from "@angular/material/table";
|
|
19
|
-
import * as i4 from "@angular/material/
|
|
20
|
-
import * as i5 from "@angular/material/
|
|
21
|
-
import * as i6 from "@angular/material/
|
|
22
|
-
import * as i7 from "@angular/material/
|
|
23
|
-
import * as i8 from "@angular/material/
|
|
24
|
-
import * as i9 from "@angular/material/
|
|
25
|
-
import * as i10 from "@angular/material/
|
|
27
|
+
import * as i4 from "@angular/material/divider";
|
|
28
|
+
import * as i5 from "@angular/material/paginator";
|
|
29
|
+
import * as i6 from "@angular/material/sort";
|
|
30
|
+
import * as i7 from "@angular/material/menu";
|
|
31
|
+
import * as i8 from "@angular/material/icon";
|
|
32
|
+
import * as i9 from "@angular/material/form-field";
|
|
33
|
+
import * as i10 from "@angular/material/select";
|
|
34
|
+
import * as i11 from "@angular/material/core";
|
|
26
35
|
export class TableComponent {
|
|
27
36
|
constructor() {
|
|
28
37
|
this.isLoading = false;
|
|
@@ -31,8 +40,35 @@ export class TableComponent {
|
|
|
31
40
|
this.columnRemoved = new EventEmitter();
|
|
32
41
|
this.categorySelected = new EventEmitter();
|
|
33
42
|
this.rowSelected = new EventEmitter();
|
|
43
|
+
/** Émis à chaque changement de tri (y compris le tri initial). */
|
|
44
|
+
this.sortChange = new EventEmitter();
|
|
45
|
+
/** Émis à chaque changement de page ou de taille de page. */
|
|
46
|
+
this.pageChange = new EventEmitter();
|
|
47
|
+
/** Émis à chaque changement de la recherche texte. */
|
|
48
|
+
this.searchChange = new EventEmitter();
|
|
49
|
+
/** Émis quand le Group by change (clé de colonne, ou `null` si désactivé). */
|
|
50
|
+
this.groupByChange = new EventEmitter();
|
|
51
|
+
/** Émis quand la liste des colonnes visibles change (clés dans l’ordre d’affichage). */
|
|
52
|
+
this.columnsChange = new EventEmitter();
|
|
53
|
+
/** Map clé→TemplateRef pré-calculée depuis _cellDefs. Mise à jour dans ngAfterContentInit et sur _cellDefs.changes. */
|
|
54
|
+
this._cellDefMap = new Map();
|
|
34
55
|
this.renderedColumns = [];
|
|
35
56
|
this.tableDataSource = new MatTableDataSource([]);
|
|
57
|
+
/** Constante exposée au template pour le matColumnDef de la ligne de groupe. */
|
|
58
|
+
this._GROUP_ROW_COLUMN = GROUP_ROW_COLUMN;
|
|
59
|
+
/** Clés d'accès aux propriétés des lignes projetées — exposées pour le template. */
|
|
60
|
+
this._ROW_RAW_KEY = ROW_RAW_KEY;
|
|
61
|
+
this._ROW_INDEX_KEY = ROW_INDEX_KEY;
|
|
62
|
+
this._ROW_GROUP_KEY = ROW_GROUP_KEY;
|
|
63
|
+
this._ROW_GROUP_COUNT = ROW_GROUP_COUNT;
|
|
64
|
+
this._ROW_GROUP_PAGE = ROW_GROUP_PAGE;
|
|
65
|
+
this._ROW_GROUP_PAGE_COUNT = ROW_GROUP_PAGE_COUNT;
|
|
66
|
+
/** Facade View : état et actions centralisés (Champs / Group by / Slice by) */
|
|
67
|
+
this._view = new ViewFacade();
|
|
68
|
+
/**
|
|
69
|
+
* Snapshot stable synchronisé depuis _view.fields.activeColumns dans refreshViewModel().
|
|
70
|
+
* Propriété (non getter) pour qu'Angular puisse la suivre sans NG0100.
|
|
71
|
+
*/
|
|
36
72
|
this.activeColumns = [];
|
|
37
73
|
this.activeSliceFilter = () => true;
|
|
38
74
|
// Propriétés stables pour les bindings du template (contre erreur NG0100)
|
|
@@ -40,55 +76,69 @@ export class TableComponent {
|
|
|
40
76
|
this._sliceColumns = [];
|
|
41
77
|
this._sliceData = [];
|
|
42
78
|
this._sliceShowToggle = true;
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
79
|
+
/** Snapshot stable de la visibilité du panneau slice — jamais calculé depuis @ViewChild */
|
|
80
|
+
this._showSlicePanel = false;
|
|
81
|
+
/** Snapshot stable de l'état collapsed du panneau slice, mis à jour via (collapsedChange) */
|
|
82
|
+
this._slicePanelCollapsed = false;
|
|
83
|
+
this._sliceByMenuItems = [];
|
|
48
84
|
this.searchQuery = '';
|
|
49
|
-
this.activeGroupByKey = null;
|
|
50
85
|
this._matSortActive = '';
|
|
51
86
|
this._matSortDirection = '';
|
|
52
|
-
this._collapsedGroups = new Set();
|
|
53
87
|
this._activeSort = { active: '', direction: '' };
|
|
54
88
|
this._sortSubscribed = null;
|
|
55
89
|
this._destroy$ = new Subject();
|
|
56
|
-
this._defaultGroupCollapsed = false;
|
|
57
|
-
this._groupPages = new Map();
|
|
58
90
|
this._totalFilteredCount = 0;
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
|
|
91
|
+
/** Gestionnaire du mode Group By (état collapsed, pagination, tri des groupes). */
|
|
92
|
+
this._groupBy = new GroupByManager(() => { this._projectCurrentPage(); this._cdr.markForCheck(); }, () => this.refreshViewModel());
|
|
93
|
+
/** Gestionnaire du cycle de vie des colonnes lazy (fetch, annulation, statuts, données). */
|
|
94
|
+
this._lazy = new LazyColumnManager();
|
|
62
95
|
this._cdr = inject(ChangeDetectorRef);
|
|
63
96
|
this._el = inject((ElementRef));
|
|
64
|
-
this.
|
|
65
|
-
|
|
97
|
+
this._ngZone = inject(NgZone);
|
|
98
|
+
this._i18nRaw = inject(JQT_I18N, { optional: true });
|
|
99
|
+
/** Labels de l’interface. Fusionnés depuis JQT_I18N_DEFAULTS et le token JQT_I18N injecté. */
|
|
100
|
+
this.i18n = { ...JQT_I18N_DEFAULTS, ...(this._i18nRaw ?? {}) };
|
|
101
|
+
this.isGroupHeader = (_, row) => row[GROUP_HEADER_MARKER] === true;
|
|
102
|
+
/** Gestionnaire export CSV. */
|
|
103
|
+
this._export = new ExportManager(() => this._allFilteredRows, () => this.activeColumns, () => this.resolvedConfig.export, (col, row, idx) => this.resolveCellValue(col, row, idx));
|
|
104
|
+
// ── Lifecycle
|
|
66
105
|
this.pageSize = 5;
|
|
67
106
|
this.pageSizeOptions = [5, 10, 20];
|
|
68
107
|
this.pageSizeOptionsGroupBy = [5, 10, 20];
|
|
69
|
-
this.groupPageSize = 5;
|
|
70
|
-
this.groupSortOrder = 'asc';
|
|
71
108
|
this.draggedColumnKey = null;
|
|
72
109
|
this.dragOverColumnKey = null;
|
|
73
|
-
|
|
110
|
+
// ── Mode édition (Préférences)
|
|
111
|
+
/** Vrai quand le mode édition est actif (resize + drag colonnes, interactions désactivées). */
|
|
112
|
+
this._editMode = false;
|
|
113
|
+
/** Largeurs de colonnes personnalisées par l'utilisateur (clé → px). */
|
|
114
|
+
this._columnWidths = {};
|
|
115
|
+
/** Message de feedback après save/clear. `null` = pas de message. */
|
|
116
|
+
this._preferencesMessage = null;
|
|
117
|
+
/** Vrai si une configuration est sauvegardée pour ce tableau. */
|
|
118
|
+
this._hasSavedConfig = false;
|
|
119
|
+
this._preferencesManager = null;
|
|
120
|
+
this._resizeState = null;
|
|
121
|
+
/** Dynamic slice keys à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
|
|
122
|
+
this._pendingDynamicSliceKeys = null;
|
|
123
|
+
/** Filtres de slice à restaurer après ngAfterViewInit (slicePanelRef pas encore dispo). */
|
|
124
|
+
this._pendingSliceFilters = null;
|
|
74
125
|
this.resolvedConfig = { columns: [] };
|
|
75
126
|
this._columnMap = new Map();
|
|
76
127
|
this._resolvedData = [];
|
|
77
128
|
this._preservePageIndex = null;
|
|
78
129
|
this._initialSearchApplied = false;
|
|
79
|
-
// ── Optimisation performance
|
|
130
|
+
// ── Optimisation performance
|
|
80
131
|
this._allFilteredRows = [];
|
|
81
132
|
this._paginatorSubscribed = null;
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
this._groupCacheKey = null;
|
|
85
|
-
this._groupCacheSortOrder = 'asc';
|
|
86
|
-
this._groupCacheSortActive = '';
|
|
87
|
-
this._groupCacheSortDir = '';
|
|
88
|
-
this._groupCacheOrder = [];
|
|
89
|
-
this._groupCacheMap = new Map();
|
|
133
|
+
/** Cache groupBy — invalidé dès que rows/key/tri changent. */
|
|
134
|
+
this._groupCache = null;
|
|
90
135
|
this._pendingRender = null;
|
|
91
|
-
this.
|
|
136
|
+
this._staticSliceHiddenKeys = new Set();
|
|
137
|
+
this._configHiddenKeys = new Set();
|
|
138
|
+
/** Clés des colonnes visibles du dernier émission columnsChange (pour éviter les émissions dupliquement). */
|
|
139
|
+
this._prevColumnKeys = [];
|
|
140
|
+
this.trackRowFn = (_index, row) => row[GROUP_HEADER_MARKER] ? `__group_${row[ROW_GROUP_KEY]}` : row[ROW_INDEX_KEY] ?? _index;
|
|
141
|
+
this._preferencesMessageTimer = null;
|
|
92
142
|
}
|
|
93
143
|
set paginator(value) {
|
|
94
144
|
this._paginator = value;
|
|
@@ -98,15 +148,40 @@ export class TableComponent {
|
|
|
98
148
|
}
|
|
99
149
|
}
|
|
100
150
|
get paginator() { return this._paginator; }
|
|
151
|
+
// Délégués vers _view (conservés pour compatibilité template sans refactoring HTML)
|
|
152
|
+
get _staticSlicesForMenu() { return this._view.staticSlicesForMenu; }
|
|
153
|
+
get _activeDynamicSliceColumns() { return this._view.sliceBy.activeDynamicColumns; }
|
|
154
|
+
get _availableColumnsForDynamicSlice() { return this._view.sliceBy.availableForDynamic; }
|
|
155
|
+
get _allDynamicSliceColumns() { return this._view.sliceBy.allDynamicColumns; }
|
|
156
|
+
get _activeSliceByLabel() { return this._view.sliceBy.activeLabel; }
|
|
157
|
+
get activeGroupByKey() { return this._view.groupBy.activeKey; }
|
|
158
|
+
/** Délégués vers GroupByManager pour la compatibilité des templates. */
|
|
159
|
+
get groupPageSize() { return this._groupBy.groupPageSize; }
|
|
160
|
+
set groupPageSize(v) { this._groupBy.groupPageSize = v; }
|
|
161
|
+
get groupSortOrder() { return this._groupBy.groupSortOrder; }
|
|
162
|
+
set groupSortOrder(v) { this._groupBy.groupSortOrder = v; }
|
|
163
|
+
/** Compatibilité template : retourne la map de statuts lazy. */
|
|
164
|
+
get _lazyColumnStatus() { return this._lazy.status; }
|
|
165
|
+
/** Compatibilité template : retourne la map de données lazy. */
|
|
166
|
+
get _lazyColumnData() { return this._lazy.data; }
|
|
167
|
+
/** Retourne true si la ligne de groupe est une ligne normale (ni lazy, ni too-many). */
|
|
168
|
+
isNormalGroupRow(row) {
|
|
169
|
+
return row[ROW_GROUP_KEY] !== GROUP_KEY_LAZY_LOADING && row[ROW_GROUP_KEY] !== GROUP_KEY_TOO_MANY;
|
|
170
|
+
}
|
|
171
|
+
isGroupRowLoading(row) { return row[ROW_GROUP_KEY] === GROUP_KEY_LAZY_LOADING; }
|
|
172
|
+
isGroupRowTooMany(row) { return row[ROW_GROUP_KEY] === GROUP_KEY_TOO_MANY; }
|
|
173
|
+
/** Gère le clic sur une ligne d'en-tête de groupe (no-op pour les états spéciaux). */
|
|
174
|
+
onGroupHeaderClick(row) {
|
|
175
|
+
if (!this.isNormalGroupRow(row))
|
|
176
|
+
return;
|
|
177
|
+
this.toggleGroupCollapse(row[ROW_GROUP_KEY]);
|
|
178
|
+
}
|
|
101
179
|
// Seuil au-delà duquel le rendu groupé est bloqué pour protéger le navigateur
|
|
102
180
|
static { this.MAX_GROUP_COUNT = 500; }
|
|
103
181
|
ngOnChanges(changes) {
|
|
104
182
|
const dataChanged = !!(changes['config'] || changes['data'] || changes['dataSource']);
|
|
105
183
|
if (dataChanged) {
|
|
106
|
-
this.
|
|
107
|
-
this._lazyFetchCancels.clear();
|
|
108
|
-
this._lazyColumnStatus = new Map();
|
|
109
|
-
this._lazyColumnData = new Map();
|
|
184
|
+
this._lazy.cancelAll();
|
|
110
185
|
}
|
|
111
186
|
if (changes['config'] && !this._initialSearchApplied) {
|
|
112
187
|
const initial = this.config?.search?.initialQuery;
|
|
@@ -120,28 +195,81 @@ export class TableComponent {
|
|
|
120
195
|
this.activeColumns.filter(c => c.lazy).forEach(c => this.triggerLazyFetch(c));
|
|
121
196
|
}
|
|
122
197
|
}
|
|
198
|
+
ngAfterContentInit() {
|
|
199
|
+
this._rebuildCellDefMap();
|
|
200
|
+
this._cellDefs.changes.pipe(takeUntil(this._destroy$)).subscribe(() => {
|
|
201
|
+
this._rebuildCellDefMap();
|
|
202
|
+
this._cdr.markForCheck();
|
|
203
|
+
});
|
|
204
|
+
}
|
|
123
205
|
ngAfterViewInit() {
|
|
124
206
|
this.attachPaginator();
|
|
125
207
|
this.attachSort();
|
|
126
208
|
this._measureHeaderHeight();
|
|
209
|
+
this._applyPendingDynamicSliceKeys();
|
|
210
|
+
}
|
|
211
|
+
_applyPendingDynamicSliceKeys() {
|
|
212
|
+
const hasPendingDynamic = !!this._pendingDynamicSliceKeys;
|
|
213
|
+
const hasPendingFilters = !!this._pendingSliceFilters;
|
|
214
|
+
if (!hasPendingDynamic && !hasPendingFilters)
|
|
215
|
+
return;
|
|
216
|
+
const allCols = this.resolvedConfig.columns ?? [];
|
|
217
|
+
const keys = hasPendingDynamic ? [...this._pendingDynamicSliceKeys] : [];
|
|
218
|
+
const filters = this._pendingSliceFilters ? { ...this._pendingSliceFilters } : null;
|
|
219
|
+
this._pendingDynamicSliceKeys = null;
|
|
220
|
+
this._pendingSliceFilters = null;
|
|
221
|
+
// Tout est différé dans le même setTimeout pour :
|
|
222
|
+
// 1. Éviter NG0100 (modifications après vérification dans ngAfterViewInit)
|
|
223
|
+
// 2. Garantir que les dynamic slices sont ajoutées AVANT la restauration des filtres
|
|
224
|
+
// (les indices dans sliceFilters dépendent de l'ordre final de _cachedSlices)
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
keys.forEach(key => {
|
|
227
|
+
const col = allCols.find(c => c.key === key);
|
|
228
|
+
if (col)
|
|
229
|
+
this.addDynamicSlice(col);
|
|
230
|
+
});
|
|
231
|
+
if (filters) {
|
|
232
|
+
if (this.slicePanelRef) {
|
|
233
|
+
this.slicePanelRef.restoreFilters(filters);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// slicePanelRef toujours null (données pas encore arrivées) :
|
|
237
|
+
// remettre en attente pour que _recomputeShowSlicePanel les applique
|
|
238
|
+
this._pendingSliceFilters = filters;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
this._cdr.markForCheck();
|
|
242
|
+
});
|
|
127
243
|
}
|
|
128
244
|
ngOnDestroy() {
|
|
129
245
|
if (this._pendingRender !== null) {
|
|
130
246
|
clearTimeout(this._pendingRender);
|
|
131
247
|
}
|
|
248
|
+
if (this._preferencesMessageTimer !== null) {
|
|
249
|
+
clearTimeout(this._preferencesMessageTimer);
|
|
250
|
+
}
|
|
251
|
+
// Nettoie un éventuel resize en cours (listeners window non retirés)
|
|
252
|
+
this._resizeState = null;
|
|
132
253
|
this._destroy$.next();
|
|
133
254
|
this._destroy$.complete();
|
|
255
|
+
this._view.destroy();
|
|
134
256
|
}
|
|
135
257
|
_measureHeaderHeight() {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
258
|
+
const measure = () => {
|
|
259
|
+
const headerRow = this._el.nativeElement.querySelector('tr.mat-mdc-header-row');
|
|
260
|
+
if (headerRow) {
|
|
261
|
+
const h = headerRow.getBoundingClientRect().height;
|
|
262
|
+
if (h > 0) {
|
|
263
|
+
this._el.nativeElement.style.setProperty('--actual-header-height', h + 'px');
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
141
266
|
}
|
|
142
|
-
|
|
267
|
+
// Header pas encore rendu (ex: lazy Angular Material), on réessaie après le prochain frame
|
|
268
|
+
this._ngZone.runOutsideAngular(() => requestAnimationFrame(() => measure()));
|
|
269
|
+
};
|
|
270
|
+
this._ngZone.runOutsideAngular(() => requestAnimationFrame(() => measure()));
|
|
143
271
|
}
|
|
144
|
-
// ── Getters d'affichage
|
|
272
|
+
// ── Getters d'affichage
|
|
145
273
|
get title() {
|
|
146
274
|
return this.resolvedConfig.title ?? '';
|
|
147
275
|
}
|
|
@@ -152,60 +280,48 @@ export class TableComponent {
|
|
|
152
280
|
return this.activeColumns;
|
|
153
281
|
}
|
|
154
282
|
get showSearchBar() { return this.resolvedConfig.search?.enabled === true; }
|
|
155
|
-
get showViewButton() { return this.
|
|
156
|
-
get
|
|
157
|
-
get
|
|
158
|
-
|
|
159
|
-
get filteredRowCount() {
|
|
160
|
-
return this.activeGroupByKey ? this._totalFilteredCount : this._allFilteredRows.length;
|
|
161
|
-
}
|
|
162
|
-
get activeGroupByLabel() {
|
|
163
|
-
if (!this.activeGroupByKey)
|
|
164
|
-
return 'Aucun';
|
|
165
|
-
const col = this.groupByColumns.find((c) => c.key === this.activeGroupByKey);
|
|
166
|
-
return col?.header || this.activeGroupByKey;
|
|
283
|
+
get showViewButton() { return this._view.enabled || this.showExportButton || this.showPreferencesMenu; }
|
|
284
|
+
get showSliceExpandBtn() { return this._showSlicePanel && this._slicePanelCollapsed && this._sliceShowToggle; }
|
|
285
|
+
get showExportButton() {
|
|
286
|
+
return this.resolvedConfig.export?.enabled === true;
|
|
167
287
|
}
|
|
168
|
-
get
|
|
169
|
-
return
|
|
288
|
+
get showPreferencesMenu() {
|
|
289
|
+
return this.resolvedConfig.preferences?.enabled === true;
|
|
170
290
|
}
|
|
171
|
-
get
|
|
172
|
-
|
|
291
|
+
get hasSavedPreferences() { return this._hasSavedConfig; }
|
|
292
|
+
get showToolbar() { return this.showSearchBar || this.showViewButton || this.showSliceExpandBtn; }
|
|
293
|
+
expandSlicePanel() {
|
|
294
|
+
this.slicePanelRef?.togglePanel();
|
|
173
295
|
}
|
|
174
|
-
get
|
|
175
|
-
|
|
296
|
+
get showFields() { return this._view.showFields; }
|
|
297
|
+
get showGroupBySection() { return this._view.showGroupBySection; }
|
|
298
|
+
get filteredRowCount() {
|
|
299
|
+
return this.activeGroupByKey ? this._totalFilteredCount : this._allFilteredRows.length;
|
|
176
300
|
}
|
|
301
|
+
get activeGroupByLabel() { return this._view.activeGroupByLabel; }
|
|
302
|
+
get totalColumnCount() { return this._view.totalColumnCount; }
|
|
303
|
+
get activeSliceByLabel() { return this._view.sliceBy.activeLabel; }
|
|
304
|
+
get activeDynamicSliceColumns() { return this._view.sliceBy.activeDynamicColumns; }
|
|
177
305
|
removeDynamicSliceByKey(key) {
|
|
178
306
|
this.slicePanelRef?.removeDynamicSliceByKey(key);
|
|
179
307
|
}
|
|
180
|
-
get groupByColumns() {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return all.filter((c) => {
|
|
184
|
-
if (c.groupable === false || seen.has(c.key))
|
|
185
|
-
return false;
|
|
186
|
-
if (!c.header && c.groupable !== true)
|
|
187
|
-
return false;
|
|
188
|
-
seen.add(c.key);
|
|
189
|
-
return true;
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
colLabel(col) {
|
|
193
|
-
return col.header || humanizeKey(col.key);
|
|
194
|
-
}
|
|
195
|
-
// ── Actions utilisateur ────────────────────────────────────────────────────
|
|
308
|
+
get groupByColumns() { return this._view.groupByColumns; }
|
|
309
|
+
colLabel(col) { return this._view.colLabel(col); }
|
|
310
|
+
// ── Actions utilisateur
|
|
196
311
|
onSearchChange() {
|
|
197
312
|
this._preservePageIndex = 0;
|
|
198
313
|
this.refreshViewModel();
|
|
199
314
|
this.paginator?.firstPage();
|
|
315
|
+
this.searchChange.emit(this.searchQuery);
|
|
200
316
|
}
|
|
201
317
|
onGroupByChange(key) {
|
|
202
|
-
this.
|
|
203
|
-
this.
|
|
204
|
-
this.
|
|
205
|
-
this.
|
|
206
|
-
this.groupPageSize = this.resolveDefaultGroupPageSize();
|
|
318
|
+
this._view.setGroupBy(key);
|
|
319
|
+
this._groupBy.setDefaultCollapsed(key !== null);
|
|
320
|
+
this._groupBy.reset();
|
|
321
|
+
this._groupBy.groupPageSize = this.resolveDefaultGroupPageSize();
|
|
207
322
|
this.refreshViewModel();
|
|
208
323
|
this.paginator?.firstPage();
|
|
324
|
+
this.groupByChange.emit(key);
|
|
209
325
|
if (key) {
|
|
210
326
|
this.viewMenuTrigger?.closeMenu();
|
|
211
327
|
const colDef = (this.resolvedConfig.columns || []).find(c => c.key === key);
|
|
@@ -214,113 +330,43 @@ export class TableComponent {
|
|
|
214
330
|
}
|
|
215
331
|
}
|
|
216
332
|
else {
|
|
217
|
-
setTimeout(() => {
|
|
333
|
+
this._ngZone.runOutsideAngular(() => setTimeout(() => {
|
|
218
334
|
this.tableBodyScrollRef?.nativeElement.scrollTo({ top: 0, behavior: 'smooth' });
|
|
219
|
-
}, 0);
|
|
335
|
+
}, 0));
|
|
220
336
|
}
|
|
221
337
|
}
|
|
222
338
|
onGroupPageSizeChange(size) {
|
|
223
|
-
this.
|
|
224
|
-
this._groupPages.clear();
|
|
225
|
-
this.refreshViewModel();
|
|
339
|
+
this._groupBy.onGroupPageSizeChange(Number(size));
|
|
226
340
|
}
|
|
227
341
|
onGroupSortToggle(dir) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this._groupPages.clear();
|
|
232
|
-
this.refreshViewModel();
|
|
233
|
-
const openGroup = this._defaultGroupCollapsed
|
|
234
|
-
? (this._collapsedGroups.size === 1 ? [...this._collapsedGroups][0] : null)
|
|
235
|
-
: null;
|
|
236
|
-
if (openGroup) {
|
|
237
|
-
setTimeout(() => this.scrollToGroupHeader(openGroup), 0);
|
|
238
|
-
}
|
|
342
|
+
this._groupBy.onGroupSortToggle(dir, (key) => {
|
|
343
|
+
this._ngZone.runOutsideAngular(() => setTimeout(() => this.scrollToGroupHeader(key), 0));
|
|
344
|
+
});
|
|
239
345
|
}
|
|
240
|
-
// ── Lazy loading
|
|
346
|
+
// ── Lazy loading
|
|
241
347
|
getLazyColumnStatus(key) {
|
|
242
|
-
return this.
|
|
348
|
+
return this._lazy.getStatus(key);
|
|
243
349
|
}
|
|
244
350
|
getLazyRenderType(rowValue) {
|
|
245
|
-
|
|
246
|
-
return 'loading';
|
|
247
|
-
if (rowValue === '__lazy_error__')
|
|
248
|
-
return 'error';
|
|
249
|
-
return 'value';
|
|
351
|
+
return this._lazy.getRenderType(rowValue);
|
|
250
352
|
}
|
|
251
353
|
retryLazyColumn(column) {
|
|
252
|
-
|
|
253
|
-
const prev = this._lazyFetchCancels.get(k);
|
|
254
|
-
if (prev) {
|
|
255
|
-
prev.next();
|
|
256
|
-
prev.complete();
|
|
257
|
-
}
|
|
258
|
-
this._lazyFetchCancels.delete(k);
|
|
259
|
-
const newStatus = new Map(this._lazyColumnStatus);
|
|
260
|
-
newStatus.delete(k);
|
|
261
|
-
this._lazyColumnStatus = newStatus;
|
|
262
|
-
const newData = new Map(this._lazyColumnData);
|
|
263
|
-
newData.delete(k);
|
|
264
|
-
this._lazyColumnData = newData;
|
|
265
|
-
this.triggerLazyFetch(column);
|
|
354
|
+
this._lazy.retry(column, this._resolvedData, this._lazyCallbacks());
|
|
266
355
|
}
|
|
267
356
|
triggerLazyFetch(column) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
prev.next();
|
|
276
|
-
prev.complete();
|
|
277
|
-
}
|
|
278
|
-
const cancel$ = new Subject();
|
|
279
|
-
this._lazyFetchCancels.set(k, cancel$);
|
|
280
|
-
const newStatus1 = new Map(this._lazyColumnStatus);
|
|
281
|
-
newStatus1.set(k, 'loading');
|
|
282
|
-
this._lazyColumnStatus = newStatus1;
|
|
283
|
-
this.refreshViewModel();
|
|
284
|
-
column.lazy.fetchFn().pipe(take(1), takeUntil(cancel$)).subscribe({
|
|
285
|
-
next: (values) => {
|
|
286
|
-
const rowMap = new Map();
|
|
287
|
-
const data = this._resolvedData;
|
|
288
|
-
values.forEach((value, i) => {
|
|
289
|
-
if (i < data.length)
|
|
290
|
-
rowMap.set(data[i], value);
|
|
291
|
-
});
|
|
292
|
-
const newData = new Map(this._lazyColumnData);
|
|
293
|
-
newData.set(k, rowMap);
|
|
294
|
-
this._lazyColumnData = newData;
|
|
295
|
-
const newStatus2 = new Map(this._lazyColumnStatus);
|
|
296
|
-
newStatus2.set(k, 'loaded');
|
|
297
|
-
this._lazyColumnStatus = newStatus2;
|
|
298
|
-
this.refreshViewModel();
|
|
299
|
-
this._cdr.markForCheck();
|
|
300
|
-
},
|
|
301
|
-
error: () => {
|
|
302
|
-
const newStatusErr = new Map(this._lazyColumnStatus);
|
|
303
|
-
newStatusErr.set(k, 'error');
|
|
304
|
-
this._lazyColumnStatus = newStatusErr;
|
|
305
|
-
this.refreshViewModel();
|
|
306
|
-
this._cdr.markForCheck();
|
|
307
|
-
},
|
|
308
|
-
});
|
|
357
|
+
this._lazy.fetch(column, this._resolvedData, this._lazyCallbacks());
|
|
358
|
+
}
|
|
359
|
+
_lazyCallbacks() {
|
|
360
|
+
return {
|
|
361
|
+
onRefresh: () => this.refreshViewModel(),
|
|
362
|
+
onMarkForCheck: () => this._cdr.markForCheck(),
|
|
363
|
+
};
|
|
309
364
|
}
|
|
310
|
-
// ── Groupement
|
|
365
|
+
// ── Groupement
|
|
311
366
|
toggleGroupCollapse(groupKey) {
|
|
312
|
-
|
|
313
|
-
this.
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
this._collapsedGroups.clear();
|
|
317
|
-
this._collapsedGroups.add(groupKey);
|
|
318
|
-
setTimeout(() => this.scrollToGroupHeader(groupKey), 0);
|
|
319
|
-
}
|
|
320
|
-
// Court-circuit de refreshViewModel : la data et les colonnes n'ont pas changé,
|
|
321
|
-
// seul l'état collapsed change — reprojection directe sans rebuild complet
|
|
322
|
-
this._projectCurrentPage();
|
|
323
|
-
this._cdr.markForCheck();
|
|
367
|
+
this._groupBy.toggleGroupCollapse(groupKey, (key) => {
|
|
368
|
+
this._ngZone.runOutsideAngular(() => setTimeout(() => this.scrollToGroupHeader(key), 0));
|
|
369
|
+
});
|
|
324
370
|
}
|
|
325
371
|
scrollToGroupHeader(groupKey) {
|
|
326
372
|
const container = this.tableBodyScrollRef?.nativeElement;
|
|
@@ -337,63 +383,86 @@ export class TableComponent {
|
|
|
337
383
|
container.scrollTo({ top: targetScrollTop, behavior: 'smooth' });
|
|
338
384
|
}
|
|
339
385
|
isGroupCollapsed(groupKey) {
|
|
340
|
-
return this.
|
|
386
|
+
return this._groupBy.isGroupCollapsed(groupKey);
|
|
341
387
|
}
|
|
342
388
|
groupPageBack(groupKey) {
|
|
343
|
-
|
|
344
|
-
if (current > 0) {
|
|
345
|
-
this._groupPages.set(groupKey, current - 1);
|
|
346
|
-
this._projectCurrentPage();
|
|
347
|
-
this._cdr.markForCheck();
|
|
348
|
-
}
|
|
389
|
+
this._groupBy.groupPageBack(groupKey);
|
|
349
390
|
}
|
|
350
391
|
groupPageForward(groupKey, totalCount) {
|
|
351
|
-
|
|
352
|
-
const current = this._groupPages.get(groupKey) ?? 0;
|
|
353
|
-
if (current < maxPage) {
|
|
354
|
-
this._groupPages.set(groupKey, current + 1);
|
|
355
|
-
this._projectCurrentPage();
|
|
356
|
-
this._cdr.markForCheck();
|
|
357
|
-
}
|
|
392
|
+
this._groupBy.groupPageForward(groupKey, totalCount);
|
|
358
393
|
}
|
|
359
|
-
// ── Colonnes
|
|
394
|
+
// ── Colonnes
|
|
360
395
|
get hasAddableColumns() {
|
|
361
|
-
return this.menuBaseColumns.length > 0 || this.menuOptionalColumns.length > 0;
|
|
396
|
+
return this._view.menuBaseColumns.length > 0 || this._view.menuOptionalColumns.length > 0;
|
|
362
397
|
}
|
|
363
398
|
get menuBaseColumns() {
|
|
364
|
-
return this.
|
|
399
|
+
return this._view.menuBaseColumns;
|
|
365
400
|
}
|
|
366
401
|
get menuOptionalColumns() {
|
|
367
|
-
return this.
|
|
402
|
+
return this._view.menuOptionalColumns;
|
|
368
403
|
}
|
|
369
404
|
get availableColumnsToAdd() {
|
|
370
405
|
const activeKeys = new Set(this.activeColumns.map((column) => column.key));
|
|
371
406
|
return (this.resolvedConfig.columns || []).filter((c) => c.optional && !activeKeys.has(c.key));
|
|
372
407
|
}
|
|
373
408
|
get allowColumnRemoval() {
|
|
374
|
-
return this.
|
|
409
|
+
return this._view.allowColumnRemoval;
|
|
375
410
|
}
|
|
376
|
-
// ── Slices
|
|
411
|
+
// ── Slices
|
|
377
412
|
get hasSliceConfig() {
|
|
378
413
|
return (this.resolvedConfig.slices?.length ?? 0) > 0;
|
|
379
414
|
}
|
|
380
415
|
get showSlicePanel() {
|
|
381
|
-
return this.
|
|
416
|
+
return this._showSlicePanel;
|
|
417
|
+
}
|
|
418
|
+
onSlicePanelCollapsedChange(collapsed) {
|
|
419
|
+
this._slicePanelCollapsed = collapsed;
|
|
420
|
+
this._cdr.markForCheck();
|
|
421
|
+
}
|
|
422
|
+
_recomputeShowSlicePanel() {
|
|
423
|
+
const hasCfg = this._sliceConfigs.length > 0 || this._view.sliceBy.activeDynamicColumns.length > 0;
|
|
424
|
+
const wasVisible = this._showSlicePanel;
|
|
425
|
+
this._showSlicePanel = hasCfg && this._resolvedData.length > 0;
|
|
426
|
+
// Le SlicePanelComponent vient d'être rendu pour la 1ère fois
|
|
427
|
+
// (données arrivées) → appliquer les filtres en attente
|
|
428
|
+
if (!wasVisible && this._showSlicePanel && this._pendingSliceFilters) {
|
|
429
|
+
const filters = this._pendingSliceFilters;
|
|
430
|
+
this._pendingSliceFilters = null;
|
|
431
|
+
setTimeout(() => {
|
|
432
|
+
this.slicePanelRef?.restoreFilters(filters);
|
|
433
|
+
this._cdr.markForCheck();
|
|
434
|
+
});
|
|
435
|
+
}
|
|
382
436
|
}
|
|
383
437
|
get showAddSliceButton() {
|
|
384
|
-
return this.
|
|
438
|
+
return this._view.showSliceBySection;
|
|
385
439
|
}
|
|
386
440
|
get staticSlicesForMenu() {
|
|
387
|
-
return this.
|
|
441
|
+
return this._view.staticSlicesForMenu;
|
|
388
442
|
}
|
|
389
443
|
get availableColumnsForDynamicSlice() {
|
|
390
|
-
return this.
|
|
444
|
+
return this._view.sliceBy.availableForDynamic;
|
|
391
445
|
}
|
|
392
446
|
isStaticSliceVisible(columnKey) {
|
|
393
|
-
return this.
|
|
447
|
+
return !this._staticSliceHiddenKeys.has(columnKey);
|
|
394
448
|
}
|
|
395
449
|
toggleStaticSlice(columnKey) {
|
|
396
|
-
this.
|
|
450
|
+
const next = new Set(this._staticSliceHiddenKeys);
|
|
451
|
+
if (next.has(columnKey))
|
|
452
|
+
next.delete(columnKey);
|
|
453
|
+
else
|
|
454
|
+
next.add(columnKey);
|
|
455
|
+
this._staticSliceHiddenKeys = next;
|
|
456
|
+
this._view.updateHiddenStaticKeys(this._staticSliceHiddenKeys);
|
|
457
|
+
this._sliceConfigs = this._computeSliceConfigs();
|
|
458
|
+
// Si une slice vient d'être cachée, réinitialise le filtre actif pour éviter
|
|
459
|
+
// un filtre orphelin (la slice n'est plus visible mais son filtre resterait actif)
|
|
460
|
+
if (next.has(columnKey)) {
|
|
461
|
+
this.activeSliceFilter = () => true;
|
|
462
|
+
}
|
|
463
|
+
this._recomputeShowSlicePanel();
|
|
464
|
+
this._scheduleRender();
|
|
465
|
+
this._cdr.markForCheck();
|
|
397
466
|
}
|
|
398
467
|
addDynamicSlice(column) {
|
|
399
468
|
this.slicePanelRef?.addDynamicSlice(column);
|
|
@@ -405,7 +474,7 @@ export class TableComponent {
|
|
|
405
474
|
return this._allDynamicSliceColumns;
|
|
406
475
|
}
|
|
407
476
|
isDynamicSliceActive(key) {
|
|
408
|
-
return this.
|
|
477
|
+
return this._view.isDynamicSliceActive(key);
|
|
409
478
|
}
|
|
410
479
|
toggleDynamicSlice(col) {
|
|
411
480
|
if (this.isDynamicSliceActive(col.key)) {
|
|
@@ -422,34 +491,22 @@ export class TableComponent {
|
|
|
422
491
|
this.paginator?.firstPage();
|
|
423
492
|
}
|
|
424
493
|
onDynamicSliceKeysChange(keys) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const dynamicKeySet = new Set(keys);
|
|
428
|
-
const existingKeys = new Set([...staticKeys, ...dynamicKeySet]);
|
|
429
|
-
this._activeDynamicSliceColumns = keys
|
|
430
|
-
.map(k => allCols.find(c => c.key === k))
|
|
431
|
-
.filter((c) => !!c);
|
|
432
|
-
const seen = new Set();
|
|
433
|
-
this._availableColumnsForDynamicSlice = allCols.filter(c => {
|
|
434
|
-
if (c.sliceable === false || existingKeys.has(c.key) || seen.has(c.key))
|
|
435
|
-
return false;
|
|
436
|
-
seen.add(c.key);
|
|
437
|
-
return true;
|
|
438
|
-
});
|
|
439
|
-
this._computeSliceLabel();
|
|
494
|
+
this._view.onDynamicSliceKeysChange(keys);
|
|
495
|
+
this._recomputeShowSlicePanel();
|
|
440
496
|
this._cdr.markForCheck();
|
|
441
497
|
}
|
|
442
498
|
get emptyStateLabel() {
|
|
443
|
-
return this.resolvedConfig.labels?.empty ||
|
|
499
|
+
return this.resolvedConfig.labels?.empty || this.i18n.emptyState;
|
|
444
500
|
}
|
|
445
501
|
get loadingStateLabel() {
|
|
446
|
-
return this.resolvedConfig.labels?.loading ||
|
|
502
|
+
return this.resolvedConfig.labels?.loading || this.i18n.loadingState;
|
|
447
503
|
}
|
|
448
504
|
get effectiveIsLoading() {
|
|
449
|
-
return this.isLoading
|
|
505
|
+
return this.isLoading;
|
|
450
506
|
}
|
|
451
507
|
get isEmpty() {
|
|
452
|
-
|
|
508
|
+
// _pendingRender : le rendu interne n'est pas encore terminé → pas de message vide prématuré
|
|
509
|
+
return !this.isLoading && this._pendingRender === null && this._allFilteredRows.length === 0;
|
|
453
510
|
}
|
|
454
511
|
get showPagination() {
|
|
455
512
|
if (this.activeGroupByKey !== null)
|
|
@@ -457,35 +514,16 @@ export class TableComponent {
|
|
|
457
514
|
return this.resolvedConfig.pagination?.enabled !== false;
|
|
458
515
|
}
|
|
459
516
|
get isColumnDragDropEnabled() {
|
|
460
|
-
return this.
|
|
517
|
+
return this._view.isColumnDragDropEnabled;
|
|
461
518
|
}
|
|
462
519
|
get totalRows() {
|
|
463
520
|
return this.activeGroupByKey
|
|
464
|
-
? this.tableDataSource.data.filter((r) => !r
|
|
521
|
+
? this.tableDataSource.data.filter((r) => !r[GROUP_HEADER_MARKER]).length
|
|
465
522
|
: this._allFilteredRows.length;
|
|
466
523
|
}
|
|
467
|
-
// ── Gestion des colonnes
|
|
524
|
+
// ── Gestion des colonnes
|
|
468
525
|
onAddColumn(column) {
|
|
469
|
-
this.
|
|
470
|
-
const configCols = this.resolvedConfig.columns ?? [];
|
|
471
|
-
const configIndex = configCols.findIndex(c => c.key === column.key);
|
|
472
|
-
if (configIndex === -1) {
|
|
473
|
-
this.activeColumns = [...this.activeColumns, column];
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
const insertBefore = this.activeColumns.findIndex(c => {
|
|
477
|
-
const ci = configCols.findIndex(cc => cc.key === c.key);
|
|
478
|
-
return ci !== -1 && ci > configIndex;
|
|
479
|
-
});
|
|
480
|
-
if (insertBefore === -1) {
|
|
481
|
-
this.activeColumns = [...this.activeColumns, column];
|
|
482
|
-
}
|
|
483
|
-
else {
|
|
484
|
-
const copy = [...this.activeColumns];
|
|
485
|
-
copy.splice(insertBefore, 0, column);
|
|
486
|
-
this.activeColumns = copy;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
526
|
+
this._view.addColumn(column);
|
|
489
527
|
this._preservePageIndex = this.paginator?.pageIndex ?? null;
|
|
490
528
|
this.refreshViewModel();
|
|
491
529
|
if (column.lazy) {
|
|
@@ -495,70 +533,87 @@ export class TableComponent {
|
|
|
495
533
|
this.columnAdded.emit(column);
|
|
496
534
|
}
|
|
497
535
|
onColumnVisibilityChange(column, checked) {
|
|
498
|
-
const isVisible = this.isColumnVisible(column.key);
|
|
536
|
+
const isVisible = this._view.isColumnVisible(column.key);
|
|
499
537
|
if (checked && !isVisible) {
|
|
500
538
|
this.onAddColumn(column);
|
|
501
539
|
return;
|
|
502
540
|
}
|
|
503
541
|
if (!checked && isVisible) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
if (this.activeColumns.length <= 1) {
|
|
542
|
+
const removed = this._view.removeColumn(column.key);
|
|
543
|
+
if (!removed)
|
|
508
544
|
return;
|
|
509
|
-
}
|
|
510
|
-
this.userCustomizedColumns = true;
|
|
511
|
-
this.activeColumns = this.activeColumns.filter((item) => item.key !== column.key);
|
|
512
545
|
this._preservePageIndex = this.paginator?.pageIndex ?? null;
|
|
513
546
|
this.refreshViewModel();
|
|
514
547
|
this.columnRemoved.emit(column);
|
|
515
548
|
}
|
|
516
549
|
}
|
|
517
550
|
isColumnVisible(columnKey) {
|
|
518
|
-
return this.activeColumns.some(
|
|
551
|
+
return this.activeColumns.some(c => c.key === columnKey);
|
|
519
552
|
}
|
|
520
553
|
onRemoveColumn(columnKey, event) {
|
|
521
554
|
event?.stopPropagation();
|
|
522
|
-
|
|
555
|
+
const column = this.activeColumns.find(item => item.key === columnKey);
|
|
556
|
+
if (!column)
|
|
523
557
|
return;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if (!column || !this.canRemoveColumn(column)) {
|
|
558
|
+
const removed = this._view.removeColumn(columnKey);
|
|
559
|
+
if (!removed)
|
|
527
560
|
return;
|
|
528
|
-
}
|
|
529
|
-
this.userCustomizedColumns = true;
|
|
530
|
-
this.activeColumns = this.activeColumns.filter((item) => item.key !== columnKey);
|
|
531
561
|
this.refreshViewModel();
|
|
532
562
|
this.columnRemoved.emit(column);
|
|
533
563
|
}
|
|
534
|
-
// ── Lignes
|
|
564
|
+
// ── Lignes
|
|
565
|
+
_rebuildCellDefMap() {
|
|
566
|
+
this._cellDefMap = new Map((this._cellDefs ?? []).map(d => [d.columnKey, d.template]));
|
|
567
|
+
}
|
|
535
568
|
getCellTemplate(key) {
|
|
536
|
-
return this.
|
|
569
|
+
return this._cellDefMap.get(key) ?? null;
|
|
537
570
|
}
|
|
538
571
|
get hasCustomCellDefs() {
|
|
539
|
-
return
|
|
572
|
+
return this._cellDefMap.size > 0;
|
|
540
573
|
}
|
|
541
574
|
get hasRowClickHandler() {
|
|
542
|
-
return this.rowSelected.observed || !!this.
|
|
575
|
+
return this.rowSelected.observed || !!this.resolvedConfig.onRowSelected;
|
|
576
|
+
}
|
|
577
|
+
/** Largeur minimale du tableau en px, calculée depuis les largeurs explicites des colonnes actives.
|
|
578
|
+
* Retourne null si aucune colonne n'a de largeur définie (le tableau remplit alors 100% du conteneur).
|
|
579
|
+
* Seules les valeurs explicitement en `px` sont sommables ; les pourcentages ou autres unités sont ignorés. */
|
|
580
|
+
get tableMinWidth() {
|
|
581
|
+
const hasSomeExplicitWidth = this.activeColumns.some(c => c.width);
|
|
582
|
+
if (!hasSomeExplicitWidth)
|
|
583
|
+
return null;
|
|
584
|
+
let sum = 0;
|
|
585
|
+
for (const col of this.activeColumns) {
|
|
586
|
+
if (col.width) {
|
|
587
|
+
const isPx = col.width.trim().toLowerCase().endsWith('px');
|
|
588
|
+
const px = Number.parseFloat(col.width);
|
|
589
|
+
if (isPx && !Number.isNaN(px)) {
|
|
590
|
+
sum += px;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
sum += 120; // largeur minimale estimée pour une colonne sans largeur explicite
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return sum + 'px';
|
|
543
598
|
}
|
|
544
599
|
getRowClass(row) {
|
|
545
600
|
const fn = this.resolvedConfig.rowClass;
|
|
546
|
-
if (!fn || row?.
|
|
601
|
+
if (!fn || row?.[GROUP_HEADER_MARKER])
|
|
547
602
|
return {};
|
|
548
|
-
return fn(row
|
|
603
|
+
return fn(row[ROW_RAW_KEY] ?? row, row[ROW_INDEX_KEY] ?? 0);
|
|
549
604
|
}
|
|
550
605
|
onRowClick(row, event) {
|
|
551
|
-
if (row?.
|
|
606
|
+
if (row?.[GROUP_HEADER_MARKER])
|
|
552
607
|
return;
|
|
553
608
|
if (!this.hasRowClickHandler)
|
|
554
609
|
return;
|
|
555
|
-
const resolved = (row?.
|
|
610
|
+
const resolved = (row?.[ROW_RAW_KEY] ?? row);
|
|
611
|
+
this.resolvedConfig.onRowSelected?.(resolved, event);
|
|
556
612
|
this.rowSelected.emit(resolved);
|
|
557
|
-
this.config?.onRowSelected?.(resolved, event);
|
|
558
613
|
}
|
|
559
|
-
// ── Drag & drop
|
|
614
|
+
// ── Drag & drop
|
|
560
615
|
onHeaderDragStart(columnKey, event) {
|
|
561
|
-
if (!this.isColumnDragDropEnabled) {
|
|
616
|
+
if (!this.isColumnDragDropEnabled && !this._editMode) {
|
|
562
617
|
return;
|
|
563
618
|
}
|
|
564
619
|
this.draggedColumnKey = columnKey;
|
|
@@ -569,28 +624,22 @@ export class TableComponent {
|
|
|
569
624
|
}
|
|
570
625
|
}
|
|
571
626
|
onHeaderDragOver(columnKey, event) {
|
|
572
|
-
if (!this.isColumnDragDropEnabled || !this.draggedColumnKey) {
|
|
627
|
+
if ((!this.isColumnDragDropEnabled && !this._editMode) || !this.draggedColumnKey) {
|
|
573
628
|
return;
|
|
574
629
|
}
|
|
575
630
|
event.preventDefault();
|
|
576
631
|
this.dragOverColumnKey = columnKey;
|
|
577
632
|
}
|
|
578
633
|
onHeaderDrop(targetColumnKey, event) {
|
|
579
|
-
if (!this.isColumnDragDropEnabled || !this.draggedColumnKey) {
|
|
634
|
+
if ((!this.isColumnDragDropEnabled && !this._editMode) || !this.draggedColumnKey) {
|
|
580
635
|
return;
|
|
581
636
|
}
|
|
582
637
|
event.preventDefault();
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
if (previousIndex === -1 || currentIndex === -1 || previousIndex === currentIndex) {
|
|
638
|
+
const moved = this._view.reorderColumns(this.draggedColumnKey, targetColumnKey);
|
|
639
|
+
if (!moved) {
|
|
586
640
|
this.onHeaderDragEnd();
|
|
587
641
|
return;
|
|
588
642
|
}
|
|
589
|
-
this.userCustomizedColumns = true;
|
|
590
|
-
const reordered = [...this.activeColumns];
|
|
591
|
-
const [moved] = reordered.splice(previousIndex, 1);
|
|
592
|
-
reordered.splice(currentIndex, 0, moved);
|
|
593
|
-
this.activeColumns = reordered;
|
|
594
643
|
this.refreshViewModel();
|
|
595
644
|
this.onHeaderDragEnd();
|
|
596
645
|
}
|
|
@@ -601,8 +650,177 @@ export class TableComponent {
|
|
|
601
650
|
isHeaderDropTarget(columnKey) {
|
|
602
651
|
return !!this.draggedColumnKey && this.dragOverColumnKey === columnKey && this.draggedColumnKey !== columnKey;
|
|
603
652
|
}
|
|
653
|
+
// ── Préférences : mode édition
|
|
654
|
+
enterEditMode() {
|
|
655
|
+
this._editMode = true;
|
|
656
|
+
this._preferencesMessage = null;
|
|
657
|
+
this._cdr.markForCheck();
|
|
658
|
+
}
|
|
659
|
+
confirmEditMode() {
|
|
660
|
+
this._editMode = false;
|
|
661
|
+
this._cdr.markForCheck();
|
|
662
|
+
}
|
|
663
|
+
/** Démarre le resize d'une colonne (mousedown sur la poignée droite). */
|
|
664
|
+
onResizeStart(columnKey, event) {
|
|
665
|
+
if (!this._editMode)
|
|
666
|
+
return;
|
|
667
|
+
event.preventDefault();
|
|
668
|
+
event.stopPropagation();
|
|
669
|
+
const th = event.target.closest('th');
|
|
670
|
+
if (!th)
|
|
671
|
+
return;
|
|
672
|
+
this._resizeState = { key: columnKey, startX: event.clientX, startWidth: th.offsetWidth };
|
|
673
|
+
const onMove = (e) => {
|
|
674
|
+
if (!this._resizeState) {
|
|
675
|
+
window.removeEventListener('mousemove', onMove);
|
|
676
|
+
window.removeEventListener('mouseup', onUp);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
const delta = e.clientX - this._resizeState.startX;
|
|
680
|
+
const newWidth = Math.max(60, this._resizeState.startWidth + delta);
|
|
681
|
+
this._columnWidths = { ...this._columnWidths, [this._resizeState.key]: newWidth };
|
|
682
|
+
// detectChanges() pour forcer la mise à jour immédiate en mode OnPush
|
|
683
|
+
// (les listeners window tournent hors zone Angular avec runOutsideAngular)
|
|
684
|
+
this._cdr.detectChanges();
|
|
685
|
+
};
|
|
686
|
+
const onUp = () => {
|
|
687
|
+
this._resizeState = null;
|
|
688
|
+
window.removeEventListener('mousemove', onMove);
|
|
689
|
+
window.removeEventListener('mouseup', onUp);
|
|
690
|
+
};
|
|
691
|
+
// Listeners hors zone Angular pour éviter des cycles CD à chaque mousemove
|
|
692
|
+
this._ngZone.runOutsideAngular(() => {
|
|
693
|
+
window.addEventListener('mousemove', onMove);
|
|
694
|
+
window.addEventListener('mouseup', onUp);
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
/** Retourne la largeur CSS d'une colonne (px si personnalisée, sinon la valeur de config ou auto). */
|
|
698
|
+
getColumnWidth(key) {
|
|
699
|
+
if (this._columnWidths[key] != null)
|
|
700
|
+
return this._columnWidths[key] + 'px';
|
|
701
|
+
const col = this._columnMap.get(key);
|
|
702
|
+
return col?.width ?? 'auto';
|
|
703
|
+
}
|
|
704
|
+
// ── Préférences : save / clear
|
|
705
|
+
savePreferences() {
|
|
706
|
+
if (!this._preferencesManager)
|
|
707
|
+
return;
|
|
708
|
+
const dynamicSliceKeys = this._view.sliceBy.activeDynamicColumns.map(c => c.key);
|
|
709
|
+
const config = {
|
|
710
|
+
search: this.searchQuery || undefined,
|
|
711
|
+
groupBy: this.activeGroupByKey,
|
|
712
|
+
columnOrder: this.activeColumns.map(c => c.key),
|
|
713
|
+
visibleColumns: this.activeColumns.map(c => c.key),
|
|
714
|
+
columnWidths: Object.keys(this._columnWidths).length ? { ...this._columnWidths } : undefined,
|
|
715
|
+
slicePanelCollapsed: this._slicePanelCollapsed,
|
|
716
|
+
hiddenSliceKeys: [...this._staticSliceHiddenKeys],
|
|
717
|
+
dynamicSliceKeys: dynamicSliceKeys.length ? dynamicSliceKeys : undefined,
|
|
718
|
+
sliceFilters: this.slicePanelRef ? this.slicePanelRef.getActiveFilters() : undefined,
|
|
719
|
+
};
|
|
720
|
+
this._preferencesManager.save(config);
|
|
721
|
+
this._hasSavedConfig = true;
|
|
722
|
+
this._showPreferencesMessage(this.i18n.preferencesSavedMessage);
|
|
723
|
+
}
|
|
724
|
+
clearPreferences() {
|
|
725
|
+
if (!this._preferencesManager)
|
|
726
|
+
return;
|
|
727
|
+
this._preferencesManager.clear();
|
|
728
|
+
this._hasSavedConfig = false;
|
|
729
|
+
// Capturer les dynamic slices actives AVANT le reset (resetToDefaults() les vide)
|
|
730
|
+
const dynamicSlicesToRemove = this._view.sliceBy.activeDynamicColumns.slice();
|
|
731
|
+
// Reset complet de l'état vers les valeurs par défaut de la config
|
|
732
|
+
this.searchQuery = '';
|
|
733
|
+
this._columnWidths = {};
|
|
734
|
+
this._slicePanelCollapsed = false;
|
|
735
|
+
this._groupBy.reset();
|
|
736
|
+
this._groupBy.setDefaultCollapsed(false);
|
|
737
|
+
// Slices statiques : revenir aux seules celles cachées par la config (pas par l'utilisateur)
|
|
738
|
+
this._staticSliceHiddenKeys = new Set(this._configHiddenKeys);
|
|
739
|
+
this._view.updateHiddenStaticKeys(this._staticSliceHiddenKeys);
|
|
740
|
+
// Colonnes et groupBy : reset via la facade (retire les optionnelles, remet l'ordre config)
|
|
741
|
+
this._view.resetToDefaults();
|
|
742
|
+
// Dynamic slices : les retirer du slice panel avec la liste capturée avant le reset
|
|
743
|
+
dynamicSlicesToRemove.forEach(col => {
|
|
744
|
+
this.slicePanelRef?.removeDynamicSliceByKey(col.key);
|
|
745
|
+
});
|
|
746
|
+
// Filtre de slice actif
|
|
747
|
+
this.activeSliceFilter = () => true;
|
|
748
|
+
if (this.slicePanelRef)
|
|
749
|
+
this.slicePanelRef.restoreFilters({});
|
|
750
|
+
// Rafraîchit toute la vue
|
|
751
|
+
this.activeColumns = this._view.fields.activeColumns;
|
|
752
|
+
this.renderedColumns = this.activeColumns.map(c => c.key);
|
|
753
|
+
this._pendingDynamicSliceKeys = null;
|
|
754
|
+
this._pendingSliceFilters = null;
|
|
755
|
+
this.refreshViewModel();
|
|
756
|
+
this._showPreferencesMessage(this.i18n.preferencesClearedMessage);
|
|
757
|
+
}
|
|
758
|
+
_showPreferencesMessage(msg) {
|
|
759
|
+
if (this._preferencesMessageTimer !== null)
|
|
760
|
+
clearTimeout(this._preferencesMessageTimer);
|
|
761
|
+
this._preferencesMessage = msg;
|
|
762
|
+
this._cdr.markForCheck();
|
|
763
|
+
this._preferencesMessageTimer = setTimeout(() => {
|
|
764
|
+
this._preferencesMessageTimer = null;
|
|
765
|
+
this._preferencesMessage = null;
|
|
766
|
+
this._cdr.markForCheck();
|
|
767
|
+
}, 4000);
|
|
768
|
+
}
|
|
769
|
+
_applyPreferences(saved) {
|
|
770
|
+
if (!saved)
|
|
771
|
+
return;
|
|
772
|
+
// Recherche
|
|
773
|
+
if (saved.search)
|
|
774
|
+
this.searchQuery = saved.search;
|
|
775
|
+
// Largeurs colonnes
|
|
776
|
+
if (saved.columnWidths)
|
|
777
|
+
this._columnWidths = { ...saved.columnWidths };
|
|
778
|
+
// Group by
|
|
779
|
+
if (saved.groupBy !== undefined) {
|
|
780
|
+
this._view.setGroupBy(saved.groupBy);
|
|
781
|
+
if (saved.groupBy) {
|
|
782
|
+
this._groupBy.setDefaultCollapsed(true);
|
|
783
|
+
this._groupBy.reset();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
// État panneau slice
|
|
787
|
+
if (saved.slicePanelCollapsed !== undefined)
|
|
788
|
+
this._slicePanelCollapsed = saved.slicePanelCollapsed;
|
|
789
|
+
// Slices statiques cachées — on utilise la valeur exacte sauvegardée (pas les defaults de config)
|
|
790
|
+
if (saved.hiddenSliceKeys !== undefined) {
|
|
791
|
+
this._staticSliceHiddenKeys = new Set(saved.hiddenSliceKeys);
|
|
792
|
+
this._view.updateHiddenStaticKeys(this._staticSliceHiddenKeys);
|
|
793
|
+
}
|
|
794
|
+
// Colonnes visibles + ordre — reconstruit activeColumns en une seule passe.
|
|
795
|
+
// On part de saved.columnOrder (ordre sauvegardé) si disponible, sinon saved.visibleColumns.
|
|
796
|
+
// Cela gère à la fois : colonnes optionnelles ajoutées, colonnes retirées, et réordonnancement.
|
|
797
|
+
const targetKeys = saved.columnOrder ?? saved.visibleColumns;
|
|
798
|
+
if (targetKeys?.length) {
|
|
799
|
+
const allByKey = new Map((this.resolvedConfig.columns ?? []).map(c => [c.key, c]));
|
|
800
|
+
// Colonnes dans l'ordre sauvegardé (on ne garde que celles connues de la config)
|
|
801
|
+
const ordered = targetKeys
|
|
802
|
+
.map(key => allByKey.get(key))
|
|
803
|
+
.filter((c) => c !== undefined);
|
|
804
|
+
// Colonnes actives actuelllement non présentes dans targetKeys (non-optional passées sous silence)
|
|
805
|
+
// → on les exclut : l'utilisateur avait explicitement choisi ce sous-ensemble
|
|
806
|
+
if (ordered.length > 0) {
|
|
807
|
+
this._view.setActiveColumns(ordered);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
// Dynamic slices — différé : slicePanelRef pas encore disponible au moment de ngOnChanges
|
|
811
|
+
if (saved.dynamicSliceKeys?.length) {
|
|
812
|
+
this._pendingDynamicSliceKeys = saved.dynamicSliceKeys;
|
|
813
|
+
}
|
|
814
|
+
// Filtres actifs du slice panel
|
|
815
|
+
// Filtres actifs du slice panel — toujours stockés en pending :
|
|
816
|
+
// appliqués par _applyPendingDynamicSliceKeys (si dynamic slices) ou
|
|
817
|
+
// par _recomputeShowSlicePanel (quand les données arrivent et rendent le panel visible)
|
|
818
|
+
if (saved.sliceFilters && Object.keys(saved.sliceFilters).length) {
|
|
819
|
+
this._pendingSliceFilters = saved.sliceFilters;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
604
822
|
canRemoveColumn(column) {
|
|
605
|
-
return (this.allowColumnRemoval &&
|
|
823
|
+
return (this._view.allowColumnRemoval &&
|
|
606
824
|
column.removable !== false &&
|
|
607
825
|
this.activeColumns.length > 1);
|
|
608
826
|
}
|
|
@@ -615,20 +833,40 @@ export class TableComponent {
|
|
|
615
833
|
}
|
|
616
834
|
return String(value);
|
|
617
835
|
}
|
|
618
|
-
// ──
|
|
836
|
+
// ── Export CSV
|
|
837
|
+
onExport() {
|
|
838
|
+
this._export.export();
|
|
839
|
+
}
|
|
840
|
+
// ── Pipeline de données (privé)
|
|
619
841
|
refreshViewModel() {
|
|
620
842
|
this._resolvedData = this.resolveData();
|
|
621
843
|
this.resolvedConfig = this.buildEffectiveConfig();
|
|
622
844
|
this._columnMap = new Map((this.resolvedConfig.columns || []).map(c => [c.key, c]));
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
this.
|
|
845
|
+
// ── Initialiser le gestionnaire de préférences si l'option est activée
|
|
846
|
+
const prefsId = this.resolvedConfig.preferences?.enabled
|
|
847
|
+
? this.resolvedConfig.preferences.tableId
|
|
848
|
+
: null;
|
|
849
|
+
const currentId = prefsId ?? null;
|
|
850
|
+
// Préférences à appliquer après _view.update() (quand activeColumns est déjà peuplé)
|
|
851
|
+
let pendingPrefs = null;
|
|
852
|
+
if (currentId && this._preferencesManager?.key !== ('jqt_prefs_' + currentId)) {
|
|
853
|
+
this._preferencesManager = new TablePreferencesManager(currentId);
|
|
854
|
+
this._hasSavedConfig = this._preferencesManager.hasSaved();
|
|
855
|
+
pendingPrefs = this._preferencesManager.load();
|
|
626
856
|
}
|
|
627
|
-
else {
|
|
628
|
-
|
|
629
|
-
this.
|
|
857
|
+
else if (!currentId) {
|
|
858
|
+
this._preferencesManager = null;
|
|
859
|
+
this._hasSavedConfig = false;
|
|
630
860
|
}
|
|
631
|
-
|
|
861
|
+
// Délègue à la facade : mise à jour de l'état View (colonnes, groupBy meta, sliceBy meta)
|
|
862
|
+
this._view.update({
|
|
863
|
+
config: this.resolvedConfig.view,
|
|
864
|
+
columns: this.resolvedConfig.columns ?? [],
|
|
865
|
+
sliceConfigs: this.resolvedConfig.slices ?? [],
|
|
866
|
+
});
|
|
867
|
+
// Synchronise la propriété stable (évite NG0100 — la facade est source de vérité)
|
|
868
|
+
this.activeColumns = this._view.fields.activeColumns;
|
|
869
|
+
this.renderedColumns = this.activeColumns.map(c => c.key);
|
|
632
870
|
this.pageSize = this.paginator?.pageSize || this.resolvePageSize();
|
|
633
871
|
this.pageSizeOptions = this.resolvePageSizeOptions();
|
|
634
872
|
this.pageSizeOptionsGroupBy = this.resolvePageSizeOptionsGroupBy();
|
|
@@ -637,72 +875,100 @@ export class TableComponent {
|
|
|
637
875
|
}
|
|
638
876
|
this.attachPaginator();
|
|
639
877
|
this.attachSort();
|
|
640
|
-
//
|
|
641
|
-
|
|
878
|
+
// Réinitialise _staticSliceHiddenKeys seulement si les clés hidden de la config ont vraiment changé
|
|
879
|
+
// ET qu'il n'y a pas de préférences sauvegardées (qui géreront hiddenSliceKeys elles-mêmes).
|
|
880
|
+
const newConfigHidden = new Set((this.resolvedConfig.slices ?? []).filter(s => s.hidden && s.columnKey).map(s => s.columnKey));
|
|
881
|
+
if (!TableComponent._setsEqual(newConfigHidden, this._configHiddenKeys)) {
|
|
882
|
+
this._configHiddenKeys = newConfigHidden;
|
|
883
|
+
// N'écraser _staticSliceHiddenKeys que si on n'est PAS en train d'appliquer des prefs
|
|
884
|
+
// (pendingPrefs les gèrera lui-même via _applyPreferences → hiddenSliceKeys)
|
|
885
|
+
if (!pendingPrefs) {
|
|
886
|
+
this._staticSliceHiddenKeys = new Set(newConfigHidden);
|
|
887
|
+
this._view.updateHiddenStaticKeys(this._staticSliceHiddenKeys);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
// Applique les préférences ICI, APRÈS _view.update() ET après _configHiddenKeys mis à jour,
|
|
891
|
+
// mais avant _computeSliceConfigs() pour que hiddenSliceKeys soit déjà restauré.
|
|
892
|
+
if (pendingPrefs) {
|
|
893
|
+
this._applyPreferences(pendingPrefs);
|
|
894
|
+
}
|
|
895
|
+
// Propriétés stables pour les bindings du template
|
|
896
|
+
// On recalcule _sliceConfigs en reflétant l'état courant des slices cachées,
|
|
897
|
+
// pour que SlicePanelComponent.ngOnInit reçoive la bonne valeur de `hidden`
|
|
898
|
+
// même quand le composant est créé pour la 1ère fois après un toggle.
|
|
899
|
+
this._sliceConfigs = this._computeSliceConfigs();
|
|
642
900
|
this._sliceColumns = this.resolvedConfig.columns ?? [];
|
|
643
901
|
this._sliceData = this._resolvedData;
|
|
644
902
|
this._sliceShowToggle = this.resolvedConfig.enableSliceToggle !== false;
|
|
645
|
-
this.
|
|
646
|
-
.filter(s => !!s.columnKey)
|
|
647
|
-
.map(s => {
|
|
648
|
-
const colIcon = (this.resolvedConfig.columns ?? []).find(c => c.key === s.columnKey)?.icon;
|
|
649
|
-
return { key: s.columnKey, title: s.title || humanizeKey(s.columnKey), icon: s.icon ?? colIcon };
|
|
650
|
-
});
|
|
903
|
+
this._recomputeShowSlicePanel();
|
|
651
904
|
if (!this._activeSort.active && this.resolvedConfig.defaultSort) {
|
|
652
905
|
this._matSortActive = this.resolvedConfig.defaultSort.active;
|
|
653
906
|
this._matSortDirection = this.resolvedConfig.defaultSort.direction;
|
|
654
907
|
}
|
|
655
|
-
|
|
656
|
-
const activeDynKeys = new Set(this._activeDynamicSliceColumns.map(c => c.key));
|
|
657
|
-
const seen = new Set();
|
|
658
|
-
this._availableColumnsForDynamicSlice = (this.resolvedConfig.columns ?? []).filter(c => {
|
|
659
|
-
if (c.sliceable === false || staticKeys.has(c.key) || activeDynKeys.has(c.key) || seen.has(c.key))
|
|
660
|
-
return false;
|
|
661
|
-
if (!c.header && c.sliceable !== true)
|
|
662
|
-
return false;
|
|
663
|
-
seen.add(c.key);
|
|
664
|
-
return true;
|
|
665
|
-
});
|
|
666
|
-
const seen2 = new Set();
|
|
667
|
-
this._allDynamicSliceColumns = (this.resolvedConfig.columns ?? []).filter(c => {
|
|
668
|
-
if (c.sliceable === false || staticKeys.has(c.key) || seen2.has(c.key))
|
|
669
|
-
return false;
|
|
670
|
-
if (!c.header && c.sliceable !== true)
|
|
671
|
-
return false;
|
|
672
|
-
seen2.add(c.key);
|
|
673
|
-
return true;
|
|
674
|
-
});
|
|
675
|
-
this._computeSliceLabel();
|
|
908
|
+
this._buildSliceByMenuItems();
|
|
676
909
|
this._scheduleRender();
|
|
677
910
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
911
|
+
/** Retourne uniquement les slices visibles (non cachées par _staticSliceHiddenKeys).
|
|
912
|
+
* Le SlicePanelComponent affiche tout ce qu'il reçoit — c'est ici que se fait le filtrage. */
|
|
913
|
+
_computeSliceConfigs() {
|
|
914
|
+
return (this.resolvedConfig.slices ?? []).filter(s => !s.columnKey || !this._staticSliceHiddenKeys.has(s.columnKey));
|
|
915
|
+
}
|
|
916
|
+
static _setsEqual(a, b) {
|
|
917
|
+
if (a.size !== b.size)
|
|
918
|
+
return false;
|
|
919
|
+
for (const v of a)
|
|
920
|
+
if (!b.has(v))
|
|
921
|
+
return false;
|
|
922
|
+
return true;
|
|
923
|
+
}
|
|
924
|
+
_buildSliceByMenuItems() {
|
|
925
|
+
const staticSliceMap = new Map(this._staticSlicesForMenu.map(s => [s.key, s]));
|
|
926
|
+
const dynamicSliceSet = new Set(this._allDynamicSliceColumns.map(c => c.key));
|
|
927
|
+
const seen = new Set();
|
|
928
|
+
const items = [];
|
|
929
|
+
for (const col of this.resolvedConfig.columns ?? []) {
|
|
930
|
+
if (seen.has(col.key))
|
|
931
|
+
continue;
|
|
932
|
+
if (staticSliceMap.has(col.key)) {
|
|
933
|
+
const s = staticSliceMap.get(col.key);
|
|
934
|
+
items.push({ isStatic: true, key: s.key, title: s.title, icon: s.icon });
|
|
935
|
+
seen.add(col.key);
|
|
936
|
+
}
|
|
937
|
+
else if (dynamicSliceSet.has(col.key)) {
|
|
938
|
+
items.push({ isStatic: false, key: col.key, title: this.colLabel(col), icon: col.icon, col });
|
|
939
|
+
seen.add(col.key);
|
|
940
|
+
}
|
|
685
941
|
}
|
|
686
|
-
|
|
687
|
-
if (
|
|
688
|
-
|
|
689
|
-
this._activeSliceByLabel = first?.title || first?.columnKey || '1';
|
|
690
|
-
return;
|
|
942
|
+
for (const s of this._staticSlicesForMenu) {
|
|
943
|
+
if (!seen.has(s.key)) {
|
|
944
|
+
items.push({ isStatic: true, key: s.key, title: s.title, icon: s.icon });
|
|
691
945
|
}
|
|
692
|
-
this._activeSliceByLabel = this._activeDynamicSliceColumns[0]?.header || '1';
|
|
693
|
-
return;
|
|
694
946
|
}
|
|
695
|
-
this.
|
|
947
|
+
this._sliceByMenuItems = items;
|
|
948
|
+
}
|
|
949
|
+
get sliceByMenuItems() { return this._sliceByMenuItems; }
|
|
950
|
+
onSliceMenuItemClick(item) {
|
|
951
|
+
if (item.isStatic) {
|
|
952
|
+
this.toggleStaticSlice(item.key);
|
|
953
|
+
}
|
|
954
|
+
else if (item.col) {
|
|
955
|
+
this.toggleDynamicSlice(item.col);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
isSliceMenuItemActive(item) {
|
|
959
|
+
return item.isStatic ? this.isStaticSliceVisible(item.key) : this.isDynamicSliceActive(item.key);
|
|
696
960
|
}
|
|
697
961
|
_scheduleRender() {
|
|
698
962
|
if (this._pendingRender !== null) {
|
|
699
963
|
clearTimeout(this._pendingRender);
|
|
700
964
|
this._pendingRender = null;
|
|
701
965
|
}
|
|
702
|
-
this.
|
|
703
|
-
this._pendingRender =
|
|
704
|
-
|
|
705
|
-
|
|
966
|
+
this._ngZone.runOutsideAngular(() => {
|
|
967
|
+
this._pendingRender = setTimeout(() => {
|
|
968
|
+
this._pendingRender = null;
|
|
969
|
+
this._ngZone.run(() => this._executeRender());
|
|
970
|
+
}, 0);
|
|
971
|
+
});
|
|
706
972
|
}
|
|
707
973
|
_executeRender() {
|
|
708
974
|
const categoryRows = this.getCategoryFilteredData();
|
|
@@ -723,7 +989,9 @@ export class TableComponent {
|
|
|
723
989
|
this._preservePageIndex = null;
|
|
724
990
|
}
|
|
725
991
|
this._projectCurrentPage();
|
|
726
|
-
|
|
992
|
+
// detectChanges() au lieu de markForCheck() : met à jour uniquement CE composant
|
|
993
|
+
// sans déclencher un cycle CD global qui provoquerait NG0100 dans les parents.
|
|
994
|
+
this._cdr.detectChanges();
|
|
727
995
|
}
|
|
728
996
|
_projectCurrentPage() {
|
|
729
997
|
if (this.activeGroupByKey) {
|
|
@@ -736,7 +1004,7 @@ export class TableComponent {
|
|
|
736
1004
|
const projected = [];
|
|
737
1005
|
pageRows.forEach((row, i) => {
|
|
738
1006
|
const idx = start + i;
|
|
739
|
-
const p = {
|
|
1007
|
+
const p = { [ROW_RAW_KEY]: row, [ROW_INDEX_KEY]: idx };
|
|
740
1008
|
this.activeColumns.forEach((col) => {
|
|
741
1009
|
p[col.key] = this.resolveCellValue(col, row, idx);
|
|
742
1010
|
});
|
|
@@ -750,9 +1018,12 @@ export class TableComponent {
|
|
|
750
1018
|
const columns = config.columns ||
|
|
751
1019
|
this.columnsConfig ||
|
|
752
1020
|
this.resolveColumnsFromCompat(rows);
|
|
1021
|
+
// Mode HTML : [view] prend le dessus sur config.view si fourni (Phase 3).
|
|
1022
|
+
const view = this.view ?? config.view;
|
|
753
1023
|
return {
|
|
754
1024
|
...config,
|
|
755
1025
|
columns,
|
|
1026
|
+
view,
|
|
756
1027
|
slices: config.slices || [],
|
|
757
1028
|
enableSliceToggle: config.enableSliceToggle ?? true,
|
|
758
1029
|
};
|
|
@@ -790,8 +1061,12 @@ export class TableComponent {
|
|
|
790
1061
|
let filtered = data.filter(this.activeSliceFilter);
|
|
791
1062
|
const query = this.searchQuery?.trim().toLowerCase();
|
|
792
1063
|
if (query) {
|
|
793
|
-
|
|
794
|
-
|
|
1064
|
+
const restrictedKeys = this.resolvedConfig.search?.searchColumns;
|
|
1065
|
+
const searchCols = restrictedKeys?.length
|
|
1066
|
+
? [...this._columnMap.values()].filter(col => restrictedKeys.includes(col.key))
|
|
1067
|
+
: [...this._columnMap.values()];
|
|
1068
|
+
filtered = filtered.filter((row) => searchCols.some((col) => {
|
|
1069
|
+
const val = this.getDisplayValueForSearch(col, row);
|
|
795
1070
|
return val != null && String(val).toLowerCase().includes(query);
|
|
796
1071
|
}));
|
|
797
1072
|
}
|
|
@@ -802,7 +1077,7 @@ export class TableComponent {
|
|
|
802
1077
|
if (!groupKey) {
|
|
803
1078
|
const result = [];
|
|
804
1079
|
rows.forEach((row, index) => {
|
|
805
|
-
const projected = {
|
|
1080
|
+
const projected = { [ROW_RAW_KEY]: row, [ROW_INDEX_KEY]: index };
|
|
806
1081
|
this.activeColumns.forEach((col) => {
|
|
807
1082
|
projected[col.key] = this.resolveCellValue(col, row, index);
|
|
808
1083
|
});
|
|
@@ -814,22 +1089,23 @@ export class TableComponent {
|
|
|
814
1089
|
const groupLazyStatus = groupColDef?.lazy ? (this._lazyColumnStatus.get(groupKey) ?? 'idle') : 'loaded';
|
|
815
1090
|
if (groupLazyStatus !== 'loaded') {
|
|
816
1091
|
this._totalFilteredCount = rows.length;
|
|
817
|
-
return [{
|
|
1092
|
+
return [{ [GROUP_HEADER_MARKER]: true, [ROW_GROUP_KEY]: GROUP_KEY_LAZY_LOADING, [ROW_GROUP_COUNT]: rows.length, [ROW_GROUP_PAGE]: 0, [ROW_GROUP_PAGE_COUNT]: 1 }];
|
|
818
1093
|
}
|
|
819
1094
|
const effectiveSort = this._activeSort.active && this._activeSort.direction
|
|
820
1095
|
? this._activeSort
|
|
821
1096
|
: this.resolvedConfig.defaultSort ?? { active: '', direction: '' };
|
|
822
1097
|
// Vérifie si le cache est encore valide (même référence de rows + même paramètres de tri/groupe)
|
|
823
|
-
const cacheValid = this.
|
|
824
|
-
this.
|
|
825
|
-
this.
|
|
826
|
-
this.
|
|
827
|
-
this.
|
|
1098
|
+
const cacheValid = this._groupCache !== null &&
|
|
1099
|
+
this._groupCache.rows === rows &&
|
|
1100
|
+
this._groupCache.key === groupKey &&
|
|
1101
|
+
this._groupCache.sortOrder === this._groupBy.groupSortOrder &&
|
|
1102
|
+
this._groupCache.sortActive === (effectiveSort.active ?? '') &&
|
|
1103
|
+
this._groupCache.sortDir === (effectiveSort.direction ?? '');
|
|
828
1104
|
let groupOrder;
|
|
829
1105
|
let groupMap;
|
|
830
1106
|
if (cacheValid) {
|
|
831
|
-
groupOrder = this.
|
|
832
|
-
groupMap = this.
|
|
1107
|
+
groupOrder = this._groupCache.order;
|
|
1108
|
+
groupMap = this._groupCache.map;
|
|
833
1109
|
}
|
|
834
1110
|
else {
|
|
835
1111
|
// Pré-calcul des valeurs de groupe en un seul passage (évite O(n) find() par comparaison)
|
|
@@ -860,7 +1136,7 @@ export class TableComponent {
|
|
|
860
1136
|
const va = groupValueCache.get(a);
|
|
861
1137
|
const vb = groupValueCache.get(b);
|
|
862
1138
|
const cmp = va.localeCompare(vb);
|
|
863
|
-
return this.groupSortOrder === 'desc' ? -cmp : cmp;
|
|
1139
|
+
return this._groupBy.groupSortOrder === 'desc' ? -cmp : cmp;
|
|
864
1140
|
});
|
|
865
1141
|
groupOrder = [];
|
|
866
1142
|
groupMap = new Map();
|
|
@@ -880,34 +1156,36 @@ export class TableComponent {
|
|
|
880
1156
|
});
|
|
881
1157
|
}
|
|
882
1158
|
// Mise en cache
|
|
883
|
-
this.
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
1159
|
+
this._groupCache = {
|
|
1160
|
+
rows,
|
|
1161
|
+
key: groupKey,
|
|
1162
|
+
sortOrder: this._groupBy.groupSortOrder,
|
|
1163
|
+
sortActive: effectiveSort.active ?? '',
|
|
1164
|
+
sortDir: effectiveSort.direction ?? '',
|
|
1165
|
+
order: groupOrder,
|
|
1166
|
+
map: groupMap,
|
|
1167
|
+
};
|
|
890
1168
|
}
|
|
891
1169
|
this._totalFilteredCount = rows.length;
|
|
892
1170
|
// Protection contre les jeux de données à trop haute cardinalité
|
|
893
1171
|
if (groupOrder.length > TableComponent.MAX_GROUP_COUNT) {
|
|
894
|
-
return [{
|
|
1172
|
+
return [{ [GROUP_HEADER_MARKER]: true, [ROW_GROUP_KEY]: GROUP_KEY_TOO_MANY, [ROW_GROUP_COUNT]: groupOrder.length, [ROW_GROUP_PAGE]: 0, [ROW_GROUP_PAGE_COUNT]: 1 }];
|
|
895
1173
|
}
|
|
896
1174
|
const pageSize = this.groupPageSize;
|
|
897
1175
|
const result = [];
|
|
898
1176
|
groupOrder.forEach((groupValue) => {
|
|
899
1177
|
const groupRows = groupMap.get(groupValue);
|
|
900
1178
|
const totalCount = groupRows.length;
|
|
901
|
-
const currentPage = pageSize === 0 ? 0 :
|
|
1179
|
+
const currentPage = pageSize === 0 ? 0 : this._groupBy.getPage(groupValue);
|
|
902
1180
|
const pageCount = pageSize === 0 ? 1 : Math.max(1, Math.ceil(totalCount / pageSize));
|
|
903
1181
|
const collapsed = this.isGroupCollapsed(groupValue);
|
|
904
|
-
result.push({
|
|
1182
|
+
result.push({ [GROUP_HEADER_MARKER]: true, [ROW_GROUP_KEY]: groupValue, [ROW_GROUP_COUNT]: totalCount, [ROW_GROUP_PAGE]: currentPage, [ROW_GROUP_PAGE_COUNT]: pageCount });
|
|
905
1183
|
if (!collapsed) {
|
|
906
1184
|
const start = pageSize === 0 ? 0 : currentPage * pageSize;
|
|
907
1185
|
const end = pageSize === 0 ? totalCount : Math.min(start + pageSize, totalCount);
|
|
908
1186
|
groupRows.slice(start, end).forEach((row, i) => {
|
|
909
1187
|
const idx = start + i;
|
|
910
|
-
const projected = {
|
|
1188
|
+
const projected = { [ROW_RAW_KEY]: row, [ROW_INDEX_KEY]: idx };
|
|
911
1189
|
this.activeColumns.forEach((col) => {
|
|
912
1190
|
projected[col.key] = this.resolveCellValue(col, row, idx);
|
|
913
1191
|
});
|
|
@@ -939,6 +1217,25 @@ export class TableComponent {
|
|
|
939
1217
|
return direction === 'asc' ? cmp : -cmp;
|
|
940
1218
|
};
|
|
941
1219
|
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Retourne la valeur telle qu'elle est affichée dans la cellule, en suivant exactement
|
|
1222
|
+
* le même chemin que resolveCellValue — utilisée pour la recherche plein-texte.
|
|
1223
|
+
* Ne passe pas par sortValue (valeur brute de tri) contrairement à getLazyAwareValue.
|
|
1224
|
+
*/
|
|
1225
|
+
getDisplayValueForSearch(col, row) {
|
|
1226
|
+
if (col.lazy) {
|
|
1227
|
+
const status = this._lazyColumnStatus.get(col.key) ?? 'idle';
|
|
1228
|
+
if (status !== 'loaded')
|
|
1229
|
+
return null;
|
|
1230
|
+
const rowMap = this._lazyColumnData.get(col.key);
|
|
1231
|
+
return normalizeCellValue(rowMap?.get(row) ?? '');
|
|
1232
|
+
}
|
|
1233
|
+
if (col.searchValue) {
|
|
1234
|
+
return col.searchValue(row, 0);
|
|
1235
|
+
}
|
|
1236
|
+
const rawValue = col.value ? col.value(row, 0) : row?.[col.key];
|
|
1237
|
+
return normalizeCellValue(rawValue);
|
|
1238
|
+
}
|
|
942
1239
|
getLazyAwareValue(columnKey, row) {
|
|
943
1240
|
const colDef = this._columnMap.get(columnKey);
|
|
944
1241
|
if (colDef?.lazy) {
|
|
@@ -956,9 +1253,9 @@ export class TableComponent {
|
|
|
956
1253
|
if (col.lazy) {
|
|
957
1254
|
const status = this._lazyColumnStatus.get(col.key) ?? 'idle';
|
|
958
1255
|
if (status === 'loading')
|
|
959
|
-
return
|
|
1256
|
+
return LAZY_LOADING_VALUE;
|
|
960
1257
|
if (status === 'error')
|
|
961
|
-
return
|
|
1258
|
+
return LAZY_ERROR_VALUE;
|
|
962
1259
|
if (status === 'loaded') {
|
|
963
1260
|
const rowMap = this._lazyColumnData.get(col.key);
|
|
964
1261
|
return normalizeCellValue(rowMap?.get(row) ?? '');
|
|
@@ -1018,6 +1315,7 @@ export class TableComponent {
|
|
|
1018
1315
|
this._paginatorSubscribed = this.paginator;
|
|
1019
1316
|
this.paginator.page.pipe(takeUntil(this._destroy$)).subscribe(() => {
|
|
1020
1317
|
this.pageSize = this.paginator.pageSize;
|
|
1318
|
+
this.pageChange.emit({ pageIndex: this.paginator.pageIndex, pageSize: this.paginator.pageSize });
|
|
1021
1319
|
if (this._pendingRender !== null)
|
|
1022
1320
|
return;
|
|
1023
1321
|
this._projectCurrentPage();
|
|
@@ -1036,16 +1334,17 @@ export class TableComponent {
|
|
|
1036
1334
|
active: this.sort.active,
|
|
1037
1335
|
direction: this.sort.direction,
|
|
1038
1336
|
};
|
|
1337
|
+
this.sortChange.emit({ active: this.sort.active, direction: this.sort.direction });
|
|
1039
1338
|
this._scheduleRender();
|
|
1040
1339
|
});
|
|
1041
1340
|
}
|
|
1042
1341
|
}
|
|
1043
1342
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1044
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableComponent, isStandalone: true, selector: "jquery-table", inputs: { config: "config", dataSource: "dataSource", data: "data", displayedColumns: "displayedColumns", columnsConfig: "columnsConfig", columnLabels: "columnLabels", isLoading: "isLoading" }, outputs: { addRequested: "addRequested", columnAdded: "columnAdded", columnRemoved: "columnRemoved", categorySelected: "categorySelected", rowSelected: "rowSelected" }, providers: [{ provide: MatPaginatorIntl, useFactory: getFrenchPaginatorIntl }], queries: [{ propertyName: "_cellDefs", predicate: JqtCellDefDirective }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "tableBodyScrollRef", first: true, predicate: ["tableBodyScroll"], descendants: true }, { propertyName: "slicePanelRef", first: true, predicate: SlicePanelComponent, descendants: true }, { propertyName: "viewMenuTrigger", first: true, predicate: ["viewMenuTrigger"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section class=\"jquery-table-wrapper\">\n <header class=\"table-header\" *ngIf=\"showTitle\">\n <h3>{{ title }}</h3>\n </header>\n\n <div\n class=\"table-layout\"\n [class.slice-collapsed]=\"showSlicePanel && (slicePanelRef?.isCollapsed ?? false)\"\n [class.no-slice]=\"!showSlicePanel\"\n >\n <slice-panel\n [style.display]=\"showSlicePanel ? null : 'none'\"\n [sliceConfigs]=\"_sliceConfigs\"\n [columns]=\"_sliceColumns\"\n [data]=\"_sliceData\"\n [lazyData]=\"_lazyColumnData\"\n [lazyStatus]=\"_lazyColumnStatus\"\n [showToggle]=\"_sliceShowToggle\"\n (filterChange)=\"onSliceFilterChange($event)\"\n (dynamicSliceKeysChange)=\"onDynamicSliceKeysChange($event)\"\n ></slice-panel>\n\n <div class=\"table-shell\">\n <div class=\"table-toolbar\" *ngIf=\"showToolbar\">\n <div class=\"table-toolbar-left\">\n <div *ngIf=\"showSearchBar\" class=\"search-input-wrapper\">\n <svg class=\"search-icon\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/>\n <path d=\"M13 13L17 17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n <input\n class=\"search-input\"\n type=\"text\"\n [(ngModel)]=\"searchQuery\"\n (ngModelChange)=\"onSearchChange()\"\n placeholder=\"Rechercher...\"\n autocomplete=\"off\"\n />\n <button *ngIf=\"searchQuery\" type=\"button\" class=\"search-clear-btn\" (click)=\"searchQuery = ''; onSearchChange()\">\u00D7</button>\n <span class=\"search-count\">{{ filteredRowCount }}</span>\n </div>\n </div>\n <div *ngIf=\"showViewButton\" class=\"table-toolbar-right\">\n <button type=\"button\" class=\"view-btn\" [matMenuTriggerFor]=\"viewMenu\" #viewMenuTrigger=\"matMenuTrigger\">\n <mat-icon class=\"view-btn-icon\">settings</mat-icon>\n View\n </button>\n\n <mat-menu #viewMenu=\"matMenu\" [panelClass]=\"'view-menu-panel'\">\n <button *ngIf=\"showFields\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Champs</span>\n <span class=\"view-menu-sub-value\">{{ visibleColumns.length }}/{{ totalColumnCount }}</span>\n </button>\n <button *ngIf=\"showGroupBySection\" mat-menu-item [matMenuTriggerFor]=\"groupBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Group by</span>\n <span class=\"view-menu-sub-value\">{{ activeGroupByLabel }}</span>\n </button>\n <button *ngIf=\"showAddSliceButton\" mat-menu-item [matMenuTriggerFor]=\"sliceBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Slice by</span>\n <span class=\"view-menu-sub-value\">{{ activeSliceByLabel }}</span>\n </button>\n </mat-menu>\n\n <mat-menu #fieldsSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuBaseColumns\"\n [disabled]=\"!column.optional && !allowColumnRemoval\"\n (click)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n </button>\n <ng-container *ngIf=\"menuOptionalColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuOptionalColumns\"\n [disabled]=\"(isColumnVisible(column.key) && visibleColumns.length === 1) || getLazyColumnStatus(column.key) === 'loading'\"\n (click)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'loading'\" class=\"lazy-menu-spinner\">\u21BB</span>\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'error'\" class=\"lazy-menu-error\" title=\"Erreur de chargement\">\u26A0</span>\n </button>\n </ng-container>\n </div>\n </mat-menu>\n\n <mat-menu #groupBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of groupByColumns\"\n [class.active]=\"activeGroupByKey === col.key\"\n (click)=\"onGroupByChange(activeGroupByKey === col.key ? null : col.key)\">\n <span class=\"view-menu-check\">{{ activeGroupByKey === col.key ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #sliceBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let s of staticSlicesForMenu\"\n (click)=\"toggleStaticSlice(s.key)\">\n <span class=\"view-menu-check\">{{ isStaticSliceVisible(s.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"s.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ s.icon }}</mat-icon>\n {{ s.title }}\n </button>\n <ng-container *ngIf=\"allDynamicSliceColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of allDynamicSliceColumns\"\n [class.active]=\"isDynamicSliceActive(col.key)\"\n (click)=\"toggleDynamicSlice(col)\">\n <span class=\"view-menu-check\">{{ isDynamicSliceActive(col.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </ng-container>\n </div>\n </mat-menu>\n </div>\n </div>\n\n <div class=\"table-body-wrapper\">\n <div class=\"table-body-scroll\" #tableBodyScroll>\n <table mat-table matSort [dataSource]=\"tableDataSource\" class=\"jquery-table\"\n [trackBy]=\"trackRowFn\"\n [matSortActive]=\"_matSortActive\" [matSortDirection]=\"_matSortDirection\">\n <ng-container *ngFor=\"let column of visibleColumns\" [matColumnDef]=\"column.key\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [mat-sort-header]=\"column.sortable !== false ? column.key : ''\"\n [disabled]=\"column.sortable === false\"\n [style.width]=\"column.width || null\"\n [style.min-width]=\"column.width || null\"\n [class.drag-enabled]=\"isColumnDragDropEnabled\"\n [class.drop-target]=\"isHeaderDropTarget(column.key)\"\n (dragover)=\"onHeaderDragOver(column.key, $event)\"\n (drop)=\"onHeaderDrop(column.key, $event)\"\n >\n <div class=\"head-cell\">\n <mat-icon *ngIf=\"column.icon\" class=\"head-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n <span class=\"head-text\" [title]=\"column.header\">{{ column.header }}</span>\n <span\n *ngIf=\"isColumnDragDropEnabled\"\n class=\"drag-handle\"\n draggable=\"true\"\n (dragstart)=\"onHeaderDragStart(column.key, $event)\"\n (dragend)=\"onHeaderDragEnd()\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </span>\n </div>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n [style.width]=\"column.width || null\"\n [style.min-width]=\"column.width || null\">\n <ng-container *ngIf=\"getCellTemplate(column.key) as customTpl; else defaultCellTpl\">\n <ng-container *ngTemplateOutlet=\"customTpl; context: { $implicit: row.__raw, index: row.__index }\"></ng-container>\n </ng-container>\n <ng-template #defaultCellTpl>\n <ng-container [ngSwitch]=\"column.lazy ? getLazyRenderType(row[column.key]) : 'value'\">\n <span *ngSwitchCase=\"'loading'\" class=\"lazy-skeleton\"></span>\n <button *ngSwitchCase=\"'error'\" type=\"button\" class=\"lazy-error-btn\" (click)=\"retryLazyColumn(column)\" title=\"Erreur de chargement \u2014 cliquer pour r\u00E9essayer\">\n <span class=\"lazy-error-icon\">\u26A0</span>\n <span class=\"lazy-error-label\">R\u00E9essayer</span>\n </button>\n <span *ngSwitchDefault class=\"cell-text\" [class.cell-empty]=\"isCellEmpty(row[column.key])\" [title]=\"asTitle(row[column.key])\">{{ isCellEmpty(row[column.key]) ? 'N/A' : row[column.key] }}</span>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"renderedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: renderedColumns; when: !isGroupHeader\"\n [attr.tabindex]=\"hasRowClickHandler ? 0 : null\"\n [ngClass]=\"getRowClass(row)\"\n [class.no-pointer]=\"!hasRowClickHandler\"\n (click)=\"onRowClick(row, $event)\"\n (keydown.enter)=\"onRowClick(row, null)\"\n (keydown.space)=\"onRowClick(row, null)\"\n ></tr>\n <ng-container matColumnDef=\"__group_row\">\n <td mat-cell *matCellDef=\"let row\" [attr.colspan]=\"renderedColumns.length\" class=\"group-header-cell\">\n <div class=\"group-header-label\">\n <span class=\"group-chevron\" [class.collapsed]=\"isGroupCollapsed(row.__groupKey)\" *ngIf=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__'\">\u203A</span>\n <span *ngIf=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__'\" class=\"group-key-label\">{{ row.__groupKey }}</span>\n <span *ngIf=\"row.__groupKey === '__lazy_loading__'\" class=\"lazy-skeleton group-lazy-key-skeleton\"></span>\n <span *ngIf=\"row.__groupKey === '__too_many_groups__'\" class=\"group-too-many-label\">\u26A0 Trop de groupes ({{ row.__groupCount }}) \u2014 affinez les donn\u00E9es ou choisissez une autre colonne</span>\n <span class=\"group-count-badge\">{{ row.__groupCount }}</span>\n <div class=\"group-pagination\" *ngIf=\"!isGroupCollapsed(row.__groupKey) && row.__groupPageCount > 1\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row.__groupPage === 0\" (click)=\"groupPageBack(row.__groupKey)\">\u2039</button>\n <span class=\"group-page-info\">{{ row.__groupPage + 1 }}\u00A0/\u00A0{{ row.__groupPageCount }}</span>\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row.__groupPage >= row.__groupPageCount - 1\" (click)=\"groupPageForward(row.__groupKey, row.__groupCount)\">\u203A</button>\n </div>\n </div>\n </td>\n </ng-container>\n <tr mat-row *matRowDef=\"let row; columns: ['__group_row']; when: isGroupHeader\"\n class=\"group-header-row\"\n [class.group-header-loading]=\"row.__groupKey === '__lazy_loading__'\"\n [class.group-header-too-many]=\"row.__groupKey === '__too_many_groups__'\"\n [attr.data-group-key]=\"row.__groupKey\"\n (click)=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__' && toggleGroupCollapse(row.__groupKey)\"></tr>\n <tr class=\"mat-mdc-row no-data-row\" *matNoDataRow>\n <td class=\"mat-mdc-cell no-data-cell\" [attr.colspan]=\"renderedColumns.length\"></td>\n </tr>\n </table>\n </div><!-- /table-body-scroll -->\n <div class=\"table-body-overlay\" *ngIf=\"effectiveIsLoading || isEmpty\">\n <span class=\"table-body-overlay-text\">{{ effectiveIsLoading ? loadingStateLabel : emptyStateLabel }}</span>\n </div>\n </div><!-- /table-body-wrapper -->\n\n <div class=\"bottom-bar\" *ngIf=\"showPagination\">\n <mat-paginator\n [length]=\"totalRows\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <div class=\"group-bottom-bar\" *ngIf=\"activeGroupByKey\">\n <div class=\"group-bottom-bar-container\">\n <div class=\"group-bottom-bar-left\">\n <button type=\"button\" class=\"group-reset-btn\" (click)=\"onGroupByChange(null)\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"group-reset-icon\">\n <path d=\"M3 8a5 5 0 1 0 5-5 5 5 0 0 0-3.54 1.46L3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3 3v2.5H5.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n Retirer le groupe\n </button>\n <div class=\"group-bar-separator\"></div>\n <div class=\"group-sort-controls\">\n <span class=\"group-sort-label\">Trier :</span>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'asc'\" (click)=\"onGroupSortToggle('asc')\" title=\"A \u2192 Z\">\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'desc'\" (click)=\"onGroupSortToggle('desc')\" title=\"Z \u2192 A\">\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"mat-mdc-paginator-page-size\">\n <div class=\"mat-mdc-paginator-page-size-label\">Lignes par groupe :</div>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"mat-mdc-paginator-page-size-select\">\n <mat-select\n [(ngModel)]=\"groupPageSize\"\n (ngModelChange)=\"onGroupPageSizeChange($event)\"\n panelClass=\"mat-mdc-paginator-select-page-size group-page-size-panel\"\n [panelWidth]=\"'auto'\"\n >\n <mat-select-trigger>{{ groupPageSize === 0 ? 'Toutes' : groupPageSize }}</mat-select-trigger>\n <mat-option *ngFor=\"let opt of pageSizeOptionsGroupBy\" [value]=\"opt\">{{ opt }}</mat-option>\n <mat-option [value]=\"0\">Toutes</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;max-height:100%;min-height:inherit;--jqt-title-color: #1f2937;--jqt-text-color: #111827;--jqt-text-secondary: #6b7280;--jqt-text-muted: #9ca3af;--jqt-surface-color: #ffffff;--jqt-surface-alt-color: #f9fafb;--jqt-row-hover-bg: #f3f4f6;--jqt-border-color: #e5e7eb;--jqt-group-bg: #eef2f7;--jqt-group-bg-hover: #e4ecf4;--jqt-group-accent: #94a3b8;--jqt-group-border: #d1d9e4;--jqt-primary-color: #1d4ed8;--jqt-danger-color: #dc2626;--jqt-danger-hover-bg: #fef2f2;--jqt-danger-border: #fca5a5;--jqt-header-bg: #f5f5f5;--jqt-header-text-color: #374151;--jqt-cell-bg: #ffffff;--jqt-footer-bg: #f5f5f5;--jqt-footer-text-color: #374151;--jqt-footer-icon-color: #374151}.jquery-table-wrapper{display:flex;flex-direction:column;width:100%;height:100%;min-height:inherit;padding:2px 2px 0;box-sizing:border-box}.table-header{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-bottom:12px}.table-header h3{margin:0;font-size:20px;font-weight:600;color:var(--jqt-title-color)}.table-layout{display:grid;grid-template-columns:minmax(155px,190px) minmax(0,1fr);gap:12px;align-items:stretch;min-height:inherit;height:100%}.table-layout.no-slice{grid-template-columns:minmax(0,1fr)}.table-layout.slice-collapsed{grid-template-columns:40px minmax(0,1fr)}.table-shell{display:flex;flex-direction:column;flex:1 1 0;min-height:0;min-width:0;width:100%;max-width:100%}.table-body-wrapper{position:relative;flex:1 1 0;min-height:0;display:flex;flex-direction:column}.table-body-scroll{flex:1 1 0;overflow-y:auto;min-height:0;border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:8px 8px 0 0;scrollbar-width:thin;scrollbar-color:var(--jqt-border-color) transparent}.table-body-scroll::-webkit-scrollbar{width:6px}.table-body-scroll::-webkit-scrollbar-thumb{background:var(--jqt-border-color);border-radius:4px}.table-body-overlay{position:absolute;top:var(--actual-header-height, 56px);left:0;right:0;bottom:0;z-index:3;display:flex;align-items:center;justify-content:center;background:var(--jqt-surface-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);pointer-events:none}.table-body-overlay-text{font-size:14px;color:var(--jqt-text-secondary)}.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 0 8px}.table-toolbar-left{flex:1 1 auto;min-width:0}.table-toolbar-right{flex:0 0 auto}.search-input-wrapper{position:relative;display:inline-flex;align-items:center;width:100%;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 8px;box-sizing:border-box;gap:6px}.search-input-wrapper:focus-within{border-color:var(--jqt-text-muted)}.search-input-wrapper .search-icon{flex-shrink:0;width:14px;height:14px;color:var(--jqt-text-muted)}.search-input{flex:1;border:none;outline:none;font-size:13px;color:var(--jqt-text-color);background:transparent;padding:7px 0;min-width:0}.search-input::placeholder{color:var(--jqt-text-muted)}.search-count{flex-shrink:0;font-size:12px;font-weight:600;color:var(--jqt-text-secondary);background:var(--jqt-row-hover-bg);border-radius:10px;padding:1px 7px;min-width:20px;text-align:center;line-height:18px}.search-clear-btn{background:none;border:none;cursor:pointer;color:var(--jqt-text-muted);font-size:16px;padding:0;line-height:1;flex-shrink:0}.search-clear-btn:hover{color:var(--jqt-text-color)}.view-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.view-btn:hover{border-color:var(--jqt-text-muted)}.view-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.group-header-row{cursor:pointer}:host ::ng-deep .jquery-table{border-spacing:0}:host ::ng-deep .group-header-row td{padding:0!important;background:var(--jqt-group-bg);border-bottom:1px solid var(--jqt-group-border);border-top:1px solid var(--jqt-group-border);border-left:3px solid var(--jqt-group-accent);position:sticky;top:var(--actual-header-height, 56px);z-index:2;box-shadow:-4px 0 0 0 var(--jqt-group-bg)}:host ::ng-deep .group-header-row:hover td{background:var(--jqt-group-bg-hover);box-shadow:-4px 0 0 0 var(--jqt-group-bg-hover)}:host ::ng-deep .group-header-loading td,:host ::ng-deep .group-header-loading:hover td,:host ::ng-deep .group-header-too-many td,:host ::ng-deep .group-header-too-many:hover td{cursor:default;background:var(--jqt-surface-alt-color)}.group-too-many-label{font-size:12px;font-weight:500;color:var(--jqt-warn-color, #b45309);font-style:italic}.group-header-cell{padding:0!important}.group-header-label{display:flex;align-items:center;gap:6px;padding:6px 16px;font-size:12px;font-weight:700;color:var(--jqt-text-color);text-transform:uppercase;letter-spacing:.04em}.group-key-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-count-badge{flex-shrink:0;font-size:11px;line-height:1;font-weight:600;color:#fff;background:var(--jqt-text-secondary, #6b7280);border-radius:10px;padding:3px 7px;min-width:20px;text-align:center;text-transform:none;letter-spacing:0}.group-pagination{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.group-page-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--jqt-border-color);border-radius:5px;background:var(--jqt-surface-color);cursor:pointer;font-size:14px;color:var(--jqt-text-color);line-height:1;padding:0 0 3px;text-transform:none;letter-spacing:0}.group-page-btn:hover:not(:disabled){border-color:var(--jqt-text-muted);background:var(--jqt-surface-alt-color)}.group-page-btn:disabled{opacity:.35;cursor:default}.group-page-info{font-size:11px;color:var(--jqt-text-secondary);min-width:36px;text-align:center;font-weight:500;text-transform:none;letter-spacing:0}.group-chevron{flex-shrink:0;font-size:14px;font-weight:700;padding-bottom:3px;transition:transform .15s ease;transform:rotate(90deg)}.group-chevron.collapsed{transform:rotate(0)}.no-data-row{cursor:default!important}.no-data-cell{padding:0!important;height:0!important;border:none!important}.jquery-table{width:100%;table-layout:fixed}:host ::ng-deep .mat-mdc-table{width:100%;background:transparent}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .mat-mdc-header-row{background:var(--jqt-header-bg)}:host ::ng-deep .mat-mdc-header-cell{background:var(--jqt-header-bg);color:var(--jqt-header-text-color)}:host ::ng-deep .mat-mdc-row,:host ::ng-deep .mat-mdc-cell{background:var(--jqt-cell-bg)}:host ::ng-deep .mat-mdc-row{cursor:pointer;border-bottom-color:var(--jqt-border-color)}:host ::ng-deep .mat-mdc-row.no-pointer{cursor:auto}:host ::ng-deep .mat-mdc-row.no-data-row{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drag-enabled{-webkit-user-select:none;user-select:none}:host ::ng-deep .mat-mdc-header-cell.drag-enabled:active{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drop-target{background:var(--jqt-row-hover-bg)}.head-cell{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}.drag-handle{display:inline-flex;align-items:center;cursor:grab;color:var(--jqt-border-color);flex-shrink:0;padding:0 2px;border-radius:4px;line-height:1}.drag-handle:active{cursor:grabbing}.drag-handle:hover{color:var(--jqt-text-muted)}.drag-handle mat-icon{font-size:16px;width:16px;height:16px;line-height:1}.head-icon{font-size:14px;width:14px;height:14px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.head-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;font-size:11px;font-weight:600;letter-spacing:.05em}.head-actions{display:inline-flex;align-items:center;gap:6px}.cell-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cell-empty{color:var(--jqt-empty-cell-color, #9ca3af);font-style:italic}.bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}:host ::ng-deep .bottom-bar mat-paginator{flex:1 1 auto;background:transparent;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-paginator-outer-container{display:flex}:host ::ng-deep .bottom-bar .mat-mdc-paginator-container{display:flex;align-items:center;flex-wrap:nowrap;min-height:0;height:var(--actual-header-height, 56px);padding:0 8px;box-sizing:border-box}:host ::ng-deep .bottom-bar .mat-mdc-paginator-range-label,:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button{color:var(--jqt-footer-icon-color);width:28px;height:28px;padding:0;line-height:1;display:inline-flex;align-items:center;justify-content:center;--mdc-icon-button-state-layer-size: 28px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-mdc-button-persistent-ripple,:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mdc-icon-button__state-layer{width:28px;height:28px;top:50%;left:50%;transform:translate(-50%,-50%)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button:disabled{opacity:.35}:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}.group-bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}.group-bottom-bar-container{display:flex;align-items:center;justify-content:space-between;flex-wrap:nowrap;height:var(--actual-header-height, 56px);padding:0 16px;gap:16px;width:100%;box-sizing:border-box}.group-bar-separator{width:1px;height:20px;background:#9ca3af;flex-shrink:0;margin:0 4px}.group-bottom-bar-left{display:flex;align-items:center;gap:8px;flex-shrink:0}.group-sort-controls{display:flex;align-items:center;gap:2px}.group-sort-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap;margin-right:2px}.group-sort-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--jqt-footer-icon-color);cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.group-sort-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.group-sort-btn:hover{background:#0000000a}.group-sort-btn.active{color:var(--jqt-primary-color, #1976d2);border-color:var(--jqt-primary-color, #1976d2);background:#1976d214}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size{display:flex;align-items:center;gap:8px}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .group-bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .group-bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .group-bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .group-bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .group-bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}:host ::ng-deep .group-bottom-bar .mat-mdc-select-arrow{color:var(--jqt-footer-text-color)}.group-reset-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);color:var(--jqt-text-secondary);font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;white-space:nowrap;flex-shrink:0}.group-reset-btn:hover{background:var(--jqt-danger-hover-bg);color:var(--jqt-danger-color);border-color:var(--jqt-danger-border)}.group-reset-icon{width:14px;height:14px;flex-shrink:0}::ng-deep .mat-mdc-paginator-select-page-size .mat-pseudo-checkbox{display:none!important}::ng-deep .group-page-size-panel{min-width:90px!important}::ng-deep .group-page-size-panel .mat-mdc-option{justify-content:center;min-height:40px}::ng-deep .group-page-size-panel .mdc-list-item__primary-text{text-align:center;width:100%}@media (max-width: 960px){.table-layout{grid-template-columns:1fr}}::ng-deep .view-menu-panel .mat-mdc-menu-panel{min-width:220px!important;overflow:visible!important}::ng-deep .view-menu-panel .mat-mdc-menu-content{padding:4px 0!important}::ng-deep .view-submenu-panel .mat-mdc-menu-panel{min-width:200px!important}::ng-deep .view-submenu-panel .mat-mdc-menu-content{padding:0!important}::ng-deep .view-menu-panel .view-menu-sub-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}::ng-deep .view-menu-panel .view-menu-sub-trigger .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;gap:0;overflow:hidden}::ng-deep .view-menu-sub-label{font-size:13px;font-weight:500;color:var(--jqt-text-color);flex:0 0 auto;white-space:nowrap;padding-right:8px}::ng-deep .view-menu-sub-value{font-size:12px;color:var(--jqt-text-secondary);flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}::ng-deep .view-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}::ng-deep .view-submenu .view-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:var(--jqt-text-color);cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}::ng-deep .view-submenu .view-menu-item:hover{background:var(--jqt-row-hover-bg)}::ng-deep .view-submenu .view-menu-item.active{font-weight:600}::ng-deep .view-submenu .view-menu-item:disabled{opacity:.4;cursor:default}::ng-deep .view-menu-col-icon{flex-shrink:0;font-size:14px!important;width:14px!important;height:14px!important;color:var(--jqt-text-muted)}::ng-deep .view-menu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:var(--jqt-text-color)}::ng-deep .view-menu-separator{border:none;border-top:1px solid var(--jqt-border-color);margin:4px 0}.lazy-skeleton{display:block;height:12px;width:70%;border-radius:4px;background:linear-gradient(90deg,var(--jqt-border-color) 25%,var(--jqt-surface-alt-color) 50%,var(--jqt-border-color) 75%);background-size:200% 100%;animation:lazy-shimmer 1.4s ease-in-out infinite}.group-lazy-key-skeleton{flex:1 1 auto;min-width:80px;height:13px;border-radius:4px}@keyframes lazy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.lazy-error-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:1px solid #fca5a5;border-radius:4px;padding:2px 6px;cursor:pointer;color:#ef4444;font-size:12px;opacity:.85;transition:opacity .15s}.lazy-error-btn:hover{opacity:1;background:#fef2f2}.lazy-error-icon{font-size:12px}.lazy-error-label{font-size:11px;font-weight:500}::ng-deep .lazy-menu-spinner{display:inline-block;margin-left:auto;font-size:13px;color:var(--jqt-text-secondary);animation:lazy-spin 1s linear infinite}::ng-deep .lazy-menu-error{display:inline-block;margin-left:auto;font-size:13px;color:#ef4444}@keyframes lazy-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i3.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i3.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i4.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i5.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i5.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i9.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i10.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: SlicePanelComponent, selector: "slice-panel", inputs: ["sliceConfigs", "columns", "data", "lazyData", "lazyStatus", "showToggle", "showCounts", "collapsedByDefault", "alwaysShow"], outputs: ["filterChange", "activeKeysChange", "dynamicSliceKeysChange", "collapsedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1343
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableComponent, isStandalone: true, selector: "jquery-table", inputs: { config: "config", dataSource: "dataSource", data: "data", displayedColumns: "displayedColumns", columnsConfig: "columnsConfig", view: "view", columnLabels: "columnLabels", isLoading: "isLoading" }, outputs: { addRequested: "addRequested", columnAdded: "columnAdded", columnRemoved: "columnRemoved", categorySelected: "categorySelected", rowSelected: "rowSelected", sortChange: "sortChange", pageChange: "pageChange", searchChange: "searchChange", groupByChange: "groupByChange", columnsChange: "columnsChange" }, providers: [{ provide: MatPaginatorIntl, useFactory: getFrenchPaginatorIntl }], queries: [{ propertyName: "_cellDefs", predicate: JqtCellDefDirective }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "tableBodyScrollRef", first: true, predicate: ["tableBodyScroll"], descendants: true }, { propertyName: "slicePanelRef", first: true, predicate: SlicePanelComponent, descendants: true }, { propertyName: "viewMenuTrigger", first: true, predicate: ["viewMenuTrigger"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section class=\"jquery-table-wrapper\">\n <header class=\"table-header\" *ngIf=\"showTitle\">\n <h3>{{ title }}</h3>\n </header>\n\n <div\n class=\"table-layout\"\n [class.no-slice]=\"!_showSlicePanel || _slicePanelCollapsed\"\n >\n <slice-panel\n [style.display]=\"!_showSlicePanel || _slicePanelCollapsed ? 'none' : null\"\n [sliceConfigs]=\"_sliceConfigs\"\n [columns]=\"_sliceColumns\"\n [data]=\"_sliceData\"\n [lazyData]=\"_lazyColumnData\"\n [lazyStatus]=\"_lazyColumnStatus\"\n [showToggle]=\"_sliceShowToggle\"\n [collapsedByDefault]=\"_slicePanelCollapsed\"\n (filterChange)=\"onSliceFilterChange($event)\"\n (dynamicSliceKeysChange)=\"onDynamicSliceKeysChange($event)\"\n (collapsedChange)=\"onSlicePanelCollapsedChange($event)\"\n ></slice-panel>\n\n <div class=\"table-shell\">\n <div class=\"table-toolbar\" *ngIf=\"showToolbar\">\n <div class=\"table-toolbar-left\">\n <button\n *ngIf=\"showSliceExpandBtn\"\n type=\"button\"\n class=\"slice-expand-btn\"\n [title]=\"i18n.expandFilterTitle\"\n (click)=\"expandSlicePanel()\"\n ><mat-icon class=\"slice-expand-mat-icon\">menu</mat-icon></button>\n <div *ngIf=\"showSearchBar\" class=\"search-input-wrapper\">\n <svg class=\"search-icon\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/>\n <path d=\"M13 13L17 17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n <input\n class=\"search-input\"\n type=\"text\"\n [(ngModel)]=\"searchQuery\"\n (ngModelChange)=\"onSearchChange()\"\n [placeholder]=\"i18n.searchPlaceholder\"\n autocomplete=\"off\"\n />\n <button *ngIf=\"searchQuery\" type=\"button\" class=\"search-clear-btn\" (click)=\"searchQuery = ''; onSearchChange()\">\u00D7</button>\n <span class=\"search-count\">{{ filteredRowCount }}</span>\n </div>\n </div>\n <div *ngIf=\"showViewButton\" class=\"table-toolbar-right\">\n <button *ngIf=\"showViewButton\" type=\"button\" class=\"view-btn\" [matMenuTriggerFor]=\"viewMenu\" #viewMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"'View'\">\n <mat-icon class=\"view-btn-icon\">settings</mat-icon>\n </button>\n\n <mat-menu #viewMenu=\"matMenu\" [panelClass]=\"'view-menu-panel'\">\n <button *ngIf=\"showFields\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuFields }}</span>\n <span class=\"view-menu-sub-value\">{{ visibleColumns.length }}/{{ totalColumnCount }}</span>\n </button>\n <button *ngIf=\"showGroupBySection\" mat-menu-item [matMenuTriggerFor]=\"groupBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuGroupBy }}</span>\n <span class=\"view-menu-sub-value\">{{ activeGroupByLabel }}</span>\n </button>\n <button *ngIf=\"showAddSliceButton\" mat-menu-item [matMenuTriggerFor]=\"sliceBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuSliceBy }}</span>\n <span class=\"view-menu-sub-value\">{{ activeSliceByLabel }}</span>\n </button>\n <mat-divider *ngIf=\"showExportButton\" class=\"view-menu-export-divider\"></mat-divider>\n <button *ngIf=\"showExportButton\" mat-menu-item type=\"button\" class=\"view-menu-export-item\"\n (click)=\"onExport(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-export-icon\">download</mat-icon>\n <span class=\"view-menu-sub-label\">{{ i18n.exportButtonLabel }}</span>\n </button>\n <mat-divider *ngIf=\"showPreferencesMenu\" class=\"view-menu-export-divider\"></mat-divider>\n <button *ngIf=\"showPreferencesMenu\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.preferencesMenuLabel }}</span>\n </button>\n </mat-menu>\n\n <mat-menu #preferencesSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" (mousedown)=\"enterEditMode(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">edit</mat-icon>\n {{ i18n.preferencesEdit }}\n </button>\n <button type=\"button\" class=\"view-menu-item\" (mousedown)=\"savePreferences(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">save</mat-icon>\n {{ i18n.preferencesSave }}\n </button>\n <button type=\"button\" class=\"view-menu-item\" [disabled]=\"!hasSavedPreferences\" (mousedown)=\"clearPreferences(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">delete_outline</mat-icon>\n {{ i18n.preferencesClear }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #fieldsSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuBaseColumns\"\n [disabled]=\"!column.optional && !allowColumnRemoval\"\n (mousedown)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n </button>\n <ng-container *ngIf=\"menuOptionalColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuOptionalColumns\"\n [disabled]=\"(isColumnVisible(column.key) && visibleColumns.length === 1) || getLazyColumnStatus(column.key) === 'loading'\"\n (mousedown)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'loading'\" class=\"lazy-menu-spinner\">\u21BB</span>\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'error'\" class=\"lazy-menu-error\" [title]=\"i18n.lazyErrorMenuTitle\">\u26A0</span>\n </button>\n </ng-container>\n </div>\n </mat-menu>\n\n <mat-menu #groupBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of groupByColumns\"\n [class.active]=\"activeGroupByKey === col.key\"\n (mousedown)=\"onGroupByChange(activeGroupByKey === col.key ? null : col.key)\">\n <span class=\"view-menu-check\">{{ activeGroupByKey === col.key ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #sliceBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let item of sliceByMenuItems\"\n [class.active]=\"isSliceMenuItemActive(item)\"\n (mousedown)=\"onSliceMenuItemClick(item)\">\n <span class=\"view-menu-check\">{{ isSliceMenuItemActive(item) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"item.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\n {{ item.title }}\n </button>\n </div>\n </mat-menu>\n </div>\n </div>\n\n <div class=\"table-body-wrapper\">\n\n <!-- Banni\u00E8re message pr\u00E9f\u00E9rences -->\n <div *ngIf=\"_preferencesMessage\" class=\"preferences-message\">\n <mat-icon class=\"preferences-message-icon\">check_circle</mat-icon>\n <span>{{ _preferencesMessage }}</span>\n </div>\n\n <!-- Bouton de confirmation du mode \u00E9dition -->\n <button\n *ngIf=\"_editMode\"\n type=\"button\"\n class=\"edit-confirm-btn\"\n [title]=\"i18n.preferencesConfirmEdit\"\n (click)=\"confirmEditMode()\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n <div class=\"table-body-scroll\" #tableBodyScroll>\n <table mat-table matSort [dataSource]=\"tableDataSource\" class=\"jquery-table\"\n [style.min-width]=\"tableMinWidth\"\n [trackBy]=\"trackRowFn\"\n [matSortActive]=\"_matSortActive\" [matSortDirection]=\"_matSortDirection\">\n <ng-container *ngFor=\"let column of visibleColumns\" [matColumnDef]=\"column.key\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [mat-sort-header]=\"(!_editMode && column.sortable !== false) ? column.key : ''\"\n [disabled]=\"_editMode || column.sortable === false\"\n [style.width]=\"getColumnWidth(column.key)\"\n [class.drag-enabled]=\"isColumnDragDropEnabled || _editMode\"\n [class.drop-target]=\"isHeaderDropTarget(column.key)\"\n [class.edit-mode-header]=\"_editMode\"\n (dragover)=\"onHeaderDragOver(column.key, $event)\"\n (drop)=\"onHeaderDrop(column.key, $event)\"\n >\n <div class=\"head-cell\">\n <mat-icon *ngIf=\"column.icon\" class=\"head-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n <span class=\"head-text\" [title]=\"column.header\">{{ column.header }}</span>\n <span\n *ngIf=\"isColumnDragDropEnabled || _editMode\"\n class=\"drag-handle\"\n draggable=\"true\"\n (dragstart)=\"onHeaderDragStart(column.key, $event)\"\n (dragend)=\"onHeaderDragEnd()\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </span>\n </div>\n <!-- Poign\u00E9e de resize (visible uniquement en mode \u00E9dition) -->\n <span\n *ngIf=\"_editMode\"\n class=\"col-resize-handle\"\n draggable=\"false\"\n (mousedown)=\"onResizeStart(column.key, $event)\"\n ></span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n [style.width]=\"getColumnWidth(column.key)\"\n [class.edit-mode-cell]=\"_editMode\">\n <ng-container *ngIf=\"!_editMode; else editModeCellTpl\">\n <ng-container *ngIf=\"getCellTemplate(column.key) as customTpl; else defaultCellTpl\">\n <ng-container *ngTemplateOutlet=\"customTpl; context: { $implicit: row[_ROW_RAW_KEY], index: row[_ROW_INDEX_KEY] }\"></ng-container>\n </ng-container>\n <ng-template #defaultCellTpl>\n <ng-container [ngSwitch]=\"column.lazy ? getLazyRenderType(row[column.key]) : 'value'\">\n <span *ngSwitchCase=\"'loading'\" class=\"lazy-skeleton\"></span>\n <button *ngSwitchCase=\"'error'\" type=\"button\" class=\"lazy-error-btn\" (click)=\"retryLazyColumn(column)\" [title]=\"i18n.lazyErrorTitle\">\n <span class=\"lazy-error-icon\">\u26A0</span>\n <span class=\"lazy-error-label\">{{ i18n.lazyRetry }}</span>\n </button>\n <span *ngSwitchDefault class=\"cell-text\" [class.cell-empty]=\"isCellEmpty(row[column.key])\" [title]=\"asTitle(row[column.key])\">{{ isCellEmpty(row[column.key]) ? i18n.cellEmpty : row[column.key] }}</span>\n </ng-container>\n </ng-template>\n </ng-container>\n <ng-template #editModeCellTpl>\n <span class=\"cell-text cell-edit-mode\" [title]=\"asTitle(row[column.key])\">{{ row[column.key] }}</span>\n </ng-template>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"renderedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: renderedColumns; when: !isGroupHeader\"\n [attr.tabindex]=\"hasRowClickHandler && !_editMode ? 0 : null\"\n [ngClass]=\"getRowClass(row)\"\n [class.no-pointer]=\"!hasRowClickHandler || _editMode\"\n [class.edit-mode-row]=\"_editMode\"\n (click)=\"!_editMode && onRowClick(row, $event)\"\n (keydown.enter)=\"!_editMode && onRowClick(row, null)\"\n (keydown.space)=\"!_editMode && onRowClick(row, null)\"\n ></tr>\n <ng-container [matColumnDef]=\"_GROUP_ROW_COLUMN\">\n <td mat-cell *matCellDef=\"let row\" [attr.colspan]=\"renderedColumns.length\" class=\"group-header-cell\">\n <div class=\"group-header-label\">\n <span class=\"group-chevron\" [class.collapsed]=\"isGroupCollapsed(row[_ROW_GROUP_KEY])\" *ngIf=\"isNormalGroupRow(row)\">\u203A</span>\n <span *ngIf=\"isNormalGroupRow(row)\" class=\"group-key-label\">{{ row[_ROW_GROUP_KEY] }}</span>\n <span *ngIf=\"isGroupRowLoading(row)\" class=\"lazy-skeleton group-lazy-key-skeleton\"></span>\n <span *ngIf=\"isGroupRowTooMany(row)\" class=\"group-too-many-label\">{{ i18n.groupTooMany(row[_ROW_GROUP_COUNT]) }}</span>\n <span class=\"group-count-badge\">{{ row[_ROW_GROUP_COUNT] }}</span>\n <div class=\"group-pagination\" *ngIf=\"!isGroupCollapsed(row[_ROW_GROUP_KEY]) && row[_ROW_GROUP_PAGE_COUNT] > 1\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row[_ROW_GROUP_PAGE] === 0\" (click)=\"groupPageBack(row[_ROW_GROUP_KEY])\">\u2039</button>\n <span class=\"group-page-info\">{{ row[_ROW_GROUP_PAGE] + 1 }} / {{ row[_ROW_GROUP_PAGE_COUNT] }}</span>\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row[_ROW_GROUP_PAGE] >= row[_ROW_GROUP_PAGE_COUNT] - 1\" (click)=\"groupPageForward(row[_ROW_GROUP_KEY], row[_ROW_GROUP_COUNT])\">\u203A</button>\n </div>\n </div>\n </td>\n </ng-container>\n <tr mat-row *matRowDef=\"let row; columns: [_GROUP_ROW_COLUMN]; when: isGroupHeader\"\n class=\"group-header-row\"\n [class.group-header-loading]=\"isGroupRowLoading(row)\"\n [class.group-header-too-many]=\"isGroupRowTooMany(row)\"\n [attr.data-group-key]=\"row[_ROW_GROUP_KEY]\"\n (click)=\"onGroupHeaderClick(row)\"></tr>\n <tr class=\"mat-mdc-row no-data-row\" *matNoDataRow>\n <td class=\"mat-mdc-cell no-data-cell\" [attr.colspan]=\"renderedColumns.length\"></td>\n </tr>\n </table>\n </div><!-- /table-body-scroll -->\n <div class=\"table-body-overlay\" *ngIf=\"effectiveIsLoading || isEmpty\">\n <span class=\"table-body-overlay-text\">{{ effectiveIsLoading ? loadingStateLabel : emptyStateLabel }}</span>\n </div>\n </div><!-- /table-body-wrapper -->\n\n <div class=\"bottom-bar\" *ngIf=\"showPagination\">\n <mat-paginator\n [length]=\"totalRows\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <div class=\"group-bottom-bar\" *ngIf=\"activeGroupByKey\">\n <div class=\"group-bottom-bar-container\">\n <div class=\"group-bottom-bar-left\">\n <button type=\"button\" class=\"group-reset-btn\" (click)=\"onGroupByChange(null)\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"group-reset-icon\">\n <path d=\"M3 8a5 5 0 1 0 5-5 5 5 0 0 0-3.54 1.46L3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3 3v2.5H5.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n {{ i18n.groupRemove }}\n </button>\n <div class=\"group-bar-separator\"></div>\n <div class=\"group-sort-controls\">\n <span class=\"group-sort-label\">{{ i18n.groupSortLabel }}</span>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'asc'\" (click)=\"onGroupSortToggle('asc')\" [title]=\"i18n.groupSortAsc\">\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'desc'\" (click)=\"onGroupSortToggle('desc')\" [title]=\"i18n.groupSortDesc\">\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"mat-mdc-paginator-page-size\">\n <div class=\"mat-mdc-paginator-page-size-label\">{{ i18n.groupRowsPerGroup }}</div>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"mat-mdc-paginator-page-size-select\">\n <mat-select\n [(ngModel)]=\"groupPageSize\"\n (ngModelChange)=\"onGroupPageSizeChange($event)\"\n panelClass=\"mat-mdc-paginator-select-page-size group-page-size-panel\"\n [panelWidth]=\"'auto'\"\n >\n <mat-select-trigger>{{ groupPageSize === 0 ? i18n.groupShowAll : groupPageSize }}</mat-select-trigger>\n <mat-option *ngFor=\"let opt of pageSizeOptionsGroupBy\" [value]=\"opt\">{{ opt }}</mat-option>\n <mat-option [value]=\"0\">{{ i18n.groupShowAll }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;max-height:100%;min-height:inherit;--jqt-title-color: #1f2937;--jqt-text-color: #111827;--jqt-text-secondary: #6b7280;--jqt-text-muted: #9ca3af;--jqt-surface-color: #ffffff;--jqt-surface-alt-color: #f9fafb;--jqt-row-hover-bg: #f3f4f6;--jqt-border-color: #e5e7eb;--jqt-group-bg: #eef2f7;--jqt-group-bg-hover: #e4ecf4;--jqt-group-accent: #94a3b8;--jqt-group-border: #d1d9e4;--jqt-primary-color: #1d4ed8;--jqt-danger-color: #dc2626;--jqt-danger-hover-bg: #fef2f2;--jqt-danger-border: #fca5a5;--jqt-header-bg: #f5f5f5;--jqt-header-text-color: #374151;--jqt-cell-bg: #ffffff;--jqt-footer-bg: #f5f5f5;--jqt-footer-text-color: #374151;--jqt-footer-icon-color: #374151}.jquery-table-wrapper{display:flex;flex-direction:column;width:100%;height:100%;min-height:inherit;padding:2px 2px 0;box-sizing:border-box}.table-header{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-bottom:12px}.table-header h3{margin:0;font-size:20px;font-weight:600;color:var(--jqt-title-color)}.table-layout{display:grid;grid-template-columns:minmax(155px,190px) minmax(0,1fr);gap:12px;align-items:stretch;min-height:inherit;height:100%}.table-layout.no-slice{grid-template-columns:minmax(0,1fr)}.table-layout.slice-collapsed{grid-template-columns:40px minmax(0,1fr)}.table-shell{display:flex;flex-direction:column;flex:1 1 0;min-height:0;min-width:0;width:100%;max-width:100%}.table-body-wrapper{position:relative;flex:1 1 0;min-height:0;display:flex;flex-direction:column}.table-body-scroll{flex:1 1 0;overflow-x:auto;overflow-y:auto;min-height:0;border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:8px 8px 0 0;scrollbar-width:thin;scrollbar-color:var(--jqt-border-color) transparent}.table-body-scroll::-webkit-scrollbar{width:6px}.table-body-scroll::-webkit-scrollbar-thumb{background:var(--jqt-border-color);border-radius:4px}.table-body-overlay{position:absolute;top:var(--actual-header-height, 56px);left:0;right:0;bottom:0;z-index:3;display:flex;align-items:center;justify-content:center;background:var(--jqt-surface-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);pointer-events:none}.table-body-overlay-text{font-size:14px;color:var(--jqt-text-secondary)}.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 0 8px}.table-toolbar-left{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:6px}.table-toolbar-right{flex:0 0 auto;display:flex;align-items:center;gap:6px}.search-input-wrapper{position:relative;display:inline-flex;align-items:center;flex:1 1 auto;min-width:0;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 8px;box-sizing:border-box;gap:6px}.search-input-wrapper:focus-within{border-color:var(--jqt-text-muted)}.search-input-wrapper .search-icon{flex-shrink:0;width:14px;height:14px;color:var(--jqt-text-muted)}.search-input{flex:1;border:none;outline:none;font-size:13px;color:var(--jqt-text-color);background:transparent;padding:7px 0;min-width:0}.search-input::placeholder{color:var(--jqt-text-muted)}.search-count{flex-shrink:0;font-size:12px;font-weight:600;color:var(--jqt-text-secondary);background:var(--jqt-row-hover-bg);border-radius:10px;padding:1px 7px;min-width:20px;text-align:center;line-height:18px}.search-clear-btn{background:none;border:none;cursor:pointer;color:var(--jqt-text-muted);font-size:16px;padding:0;line-height:1;flex-shrink:0}.search-clear-btn:hover{color:var(--jqt-text-color)}.slice-expand-btn{flex-shrink:0;width:34px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--jqt-text-color);padding:0;line-height:1}.slice-expand-btn:hover{border-color:var(--jqt-text-muted)}.slice-expand-mat-icon{font-size:18px;width:18px;height:18px;line-height:1}.view-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.view-btn:hover{border-color:var(--jqt-text-muted)}.view-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.export-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.export-btn:hover{border-color:var(--jqt-text-muted)}.export-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.view-menu-export-divider{margin:4px 0!important}.view-menu-export-item{display:flex;align-items:center;gap:6px;width:100%;padding:0 16px;height:40px;border:none;background:transparent;cursor:pointer;font-size:13px;font-weight:500;color:var(--jqt-text-color);text-align:left;box-sizing:border-box}.view-menu-export-item:hover{background:#0000000a}.view-menu-export-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.edit-confirm-btn{position:absolute;top:10px;right:10px;z-index:200;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:50%;background:#16a34a;cursor:pointer;box-shadow:0 2px 8px #00000040;transition:background .15s}.edit-confirm-btn mat-icon{color:#fff;font-size:22px;width:22px;height:22px}.edit-confirm-btn:hover{background:#15803d}.preferences-message{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 12px;background:#f0fdf4;border:1px solid #bbf7d0;border-radius:6px;font-size:12px;color:#15803d}.preferences-message .preferences-message-icon{font-size:16px;width:16px;height:16px}:host ::ng-deep .edit-mode-header{background:#3b82f60a!important;cursor:grab!important;-webkit-user-select:none;user-select:none;overflow:visible!important}.col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize!important;background:#3b82f640;z-index:20}.col-resize-handle:hover{background:#3b82f6b3}.col-resize-handle:active{background:#3b82f6e6}:host ::ng-deep th.mat-mdc-header-cell{position:relative;overflow:visible!important}:host ::ng-deep .edit-mode-row{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.8}.cell-edit-mode{pointer-events:none;-webkit-user-select:none;user-select:none;color:var(--jqt-text-muted)}.group-header-row{cursor:pointer}:host ::ng-deep .jquery-table{border-spacing:0}:host ::ng-deep .group-header-row td{padding:0!important;background:var(--jqt-group-bg);border-bottom:1px solid var(--jqt-group-border);border-top:1px solid var(--jqt-group-border);border-left:3px solid var(--jqt-group-accent);position:sticky;top:var(--actual-header-height, 56px);z-index:2;box-shadow:-4px 0 0 0 var(--jqt-group-bg)}:host ::ng-deep .group-header-row:hover td{background:var(--jqt-group-bg-hover);box-shadow:-4px 0 0 0 var(--jqt-group-bg-hover)}:host ::ng-deep .group-header-loading td,:host ::ng-deep .group-header-loading:hover td,:host ::ng-deep .group-header-too-many td,:host ::ng-deep .group-header-too-many:hover td{cursor:default;background:var(--jqt-surface-alt-color)}.group-too-many-label{font-size:12px;font-weight:500;color:var(--jqt-warn-color, #b45309);font-style:italic}.group-header-cell{padding:0!important}.group-header-label{display:flex;align-items:center;gap:6px;padding:6px 16px;font-size:12px;font-weight:700;color:var(--jqt-text-color);text-transform:uppercase;letter-spacing:.04em}.group-key-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-count-badge{flex-shrink:0;font-size:11px;line-height:1;font-weight:600;color:#fff;background:var(--jqt-text-secondary, #6b7280);border-radius:10px;padding:3px 7px;min-width:20px;text-align:center;text-transform:none;letter-spacing:0}.group-pagination{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.group-page-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--jqt-border-color);border-radius:5px;background:var(--jqt-surface-color);cursor:pointer;font-size:14px;color:var(--jqt-text-color);line-height:1;padding:0 0 3px;text-transform:none;letter-spacing:0}.group-page-btn:hover:not(:disabled){border-color:var(--jqt-text-muted);background:var(--jqt-surface-alt-color)}.group-page-btn:disabled{opacity:.35;cursor:default}.group-page-info{font-size:11px;color:var(--jqt-text-secondary);min-width:36px;text-align:center;font-weight:500;text-transform:none;letter-spacing:0}.group-chevron{flex-shrink:0;font-size:14px;font-weight:700;padding-bottom:3px;transition:transform .15s ease;transform:rotate(90deg)}.group-chevron.collapsed{transform:rotate(0)}.no-data-row{cursor:default!important}.no-data-cell{padding:0!important;height:0!important;border:none!important}.jquery-table{width:100%;table-layout:fixed}:host ::ng-deep .mat-mdc-table{width:100%;background:transparent}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .mat-mdc-header-row{background:var(--jqt-header-bg)}:host ::ng-deep .mat-mdc-header-cell{background:var(--jqt-header-bg);color:var(--jqt-header-text-color)}:host ::ng-deep .mat-mdc-row,:host ::ng-deep .mat-mdc-cell{background:var(--jqt-cell-bg)}:host ::ng-deep .mat-mdc-row{cursor:pointer;border-bottom-color:var(--jqt-border-color)}:host ::ng-deep .mat-mdc-row.no-pointer{cursor:auto}:host ::ng-deep .mat-mdc-row.no-data-row{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drag-enabled{-webkit-user-select:none;user-select:none}:host ::ng-deep .mat-mdc-header-cell.drag-enabled:active{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drop-target{background:var(--jqt-row-hover-bg)}.head-cell{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}.drag-handle{display:inline-flex;align-items:center;cursor:grab;color:var(--jqt-border-color);flex-shrink:0;padding:0 2px;border-radius:4px;line-height:1}.drag-handle:active{cursor:grabbing}.drag-handle:hover{color:var(--jqt-text-muted)}.drag-handle mat-icon{font-size:16px;width:16px;height:16px;line-height:1}.head-icon{font-size:14px;width:14px;height:14px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.head-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;font-size:11px;font-weight:600;letter-spacing:.05em}.head-actions{display:inline-flex;align-items:center;gap:6px}.cell-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cell-empty{color:var(--jqt-empty-cell-color, #9ca3af);font-style:italic}.bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}:host ::ng-deep .bottom-bar mat-paginator{flex:1 1 auto;background:transparent;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-paginator-outer-container{display:flex}:host ::ng-deep .bottom-bar .mat-mdc-paginator-container{display:flex;align-items:center;flex-wrap:nowrap;min-height:0;height:var(--actual-header-height, 56px);padding:0 8px;box-sizing:border-box}:host ::ng-deep .bottom-bar .mat-mdc-paginator-range-label,:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button{color:var(--jqt-footer-icon-color);width:28px;height:28px;padding:0;line-height:1;display:inline-flex;align-items:center;justify-content:center;--mdc-icon-button-state-layer-size: 28px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-mdc-button-persistent-ripple,:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mdc-icon-button__state-layer{width:28px;height:28px;top:50%;left:50%;transform:translate(-50%,-50%)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button:disabled{opacity:.35}:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}.group-bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}.group-bottom-bar-container{display:flex;align-items:center;justify-content:space-between;flex-wrap:nowrap;height:var(--actual-header-height, 56px);padding:0 16px;gap:16px;width:100%;box-sizing:border-box}.group-bar-separator{width:1px;height:20px;background:#9ca3af;flex-shrink:0;margin:0 4px}.group-bottom-bar-left{display:flex;align-items:center;gap:8px;flex-shrink:0}.group-sort-controls{display:flex;align-items:center;gap:2px}.group-sort-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap;margin-right:2px}.group-sort-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--jqt-footer-icon-color);cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.group-sort-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.group-sort-btn:hover{background:#0000000a}.group-sort-btn.active{color:var(--jqt-primary-color, #1976d2);border-color:var(--jqt-primary-color, #1976d2);background:#1976d214}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size{display:flex;align-items:center;gap:8px}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .group-bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .group-bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .group-bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .group-bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .group-bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}:host ::ng-deep .group-bottom-bar .mat-mdc-select-arrow{color:var(--jqt-footer-text-color)}.group-reset-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);color:var(--jqt-text-secondary);font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;white-space:nowrap;flex-shrink:0}.group-reset-btn:hover{background:var(--jqt-danger-hover-bg);color:var(--jqt-danger-color);border-color:var(--jqt-danger-border)}.group-reset-icon{width:14px;height:14px;flex-shrink:0}::ng-deep .mat-mdc-paginator-select-page-size .mat-pseudo-checkbox{display:none!important}::ng-deep .group-page-size-panel{min-width:90px!important}::ng-deep .group-page-size-panel .mat-mdc-option{justify-content:center;min-height:40px}::ng-deep .group-page-size-panel .mdc-list-item__primary-text{text-align:center;width:100%}@media (max-width: 960px){.table-layout{grid-template-columns:1fr}}::ng-deep .view-menu-panel .mat-mdc-menu-panel{min-width:220px!important;overflow:visible!important}::ng-deep .view-menu-panel .mat-mdc-menu-content{padding:4px 0!important}::ng-deep .view-submenu-panel .mat-mdc-menu-panel{min-width:200px!important}::ng-deep .view-submenu-panel .mat-mdc-menu-content{padding:0!important}::ng-deep .view-menu-panel .view-menu-sub-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}::ng-deep .view-menu-panel .view-menu-sub-trigger .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;gap:0;overflow:hidden}::ng-deep .view-menu-sub-label{font-size:13px;font-weight:500;color:var(--jqt-text-color);flex:0 0 auto;white-space:nowrap;padding-right:8px}::ng-deep .view-menu-sub-value{font-size:12px;color:var(--jqt-text-secondary);flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}::ng-deep .view-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}::ng-deep .view-submenu .view-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:var(--jqt-text-color);cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}::ng-deep .view-submenu .view-menu-item:hover{background:var(--jqt-row-hover-bg)}::ng-deep .view-submenu .view-menu-item.active{font-weight:600}::ng-deep .view-submenu .view-menu-item:disabled{opacity:.4;cursor:default}::ng-deep .view-menu-col-icon{flex-shrink:0;font-size:14px!important;width:14px!important;height:14px!important;color:var(--jqt-text-muted)}::ng-deep .view-menu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:var(--jqt-text-color)}::ng-deep .view-menu-separator{border:none;border-top:1px solid var(--jqt-border-color);margin:4px 0}.lazy-skeleton{display:block;height:12px;width:70%;border-radius:4px;background:linear-gradient(90deg,var(--jqt-border-color) 25%,var(--jqt-surface-alt-color) 50%,var(--jqt-border-color) 75%);background-size:200% 100%;animation:lazy-shimmer 1.4s ease-in-out infinite}.group-lazy-key-skeleton{flex:1 1 auto;min-width:80px;height:13px;border-radius:4px}@keyframes lazy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.lazy-error-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:1px solid #fca5a5;border-radius:4px;padding:2px 6px;cursor:pointer;color:#ef4444;font-size:12px;opacity:.85;transition:opacity .15s}.lazy-error-btn:hover{opacity:1;background:#fef2f2}.lazy-error-icon{font-size:12px}.lazy-error-label{font-size:11px;font-weight:500}::ng-deep .lazy-menu-spinner{display:inline-block;margin-left:auto;font-size:13px;color:var(--jqt-text-secondary);animation:lazy-spin 1s linear infinite}::ng-deep .lazy-menu-error{display:inline-block;margin-left:auto;font-size:13px;color:#ef4444}@keyframes lazy-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i3.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i3.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i4.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i5.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i6.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i6.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i10.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i10.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i11.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: SlicePanelComponent, selector: "slice-panel", inputs: ["sliceConfigs", "columns", "data", "lazyData", "lazyStatus", "showToggle", "showCounts", "collapsedByDefault", "alwaysShow"], outputs: ["filterChange", "activeKeysChange", "dynamicSliceKeysChange", "collapsedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1045
1344
|
}
|
|
1046
1345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableComponent, decorators: [{
|
|
1047
1346
|
type: Component,
|
|
1048
|
-
args: [{ standalone: true, selector: 'jquery-table', imports: [CommonModule, FormsModule, MatTableModule, MatButtonModule, MatPaginatorModule, MatSortModule, MatMenuModule, MatIconModule, MatSelectModule, SlicePanelComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: MatPaginatorIntl, useFactory: getFrenchPaginatorIntl }], template: "<section class=\"jquery-table-wrapper\">\n <header class=\"table-header\" *ngIf=\"showTitle\">\n <h3>{{ title }}</h3>\n </header>\n\n <div\n class=\"table-layout\"\n [class.slice-collapsed]=\"showSlicePanel && (slicePanelRef?.isCollapsed ?? false)\"\n [class.no-slice]=\"!showSlicePanel\"\n >\n <slice-panel\n [style.display]=\"showSlicePanel ? null : 'none'\"\n [sliceConfigs]=\"_sliceConfigs\"\n [columns]=\"_sliceColumns\"\n [data]=\"_sliceData\"\n [lazyData]=\"_lazyColumnData\"\n [lazyStatus]=\"_lazyColumnStatus\"\n [showToggle]=\"_sliceShowToggle\"\n (filterChange)=\"onSliceFilterChange($event)\"\n (dynamicSliceKeysChange)=\"onDynamicSliceKeysChange($event)\"\n ></slice-panel>\n\n <div class=\"table-shell\">\n <div class=\"table-toolbar\" *ngIf=\"showToolbar\">\n <div class=\"table-toolbar-left\">\n <div *ngIf=\"showSearchBar\" class=\"search-input-wrapper\">\n <svg class=\"search-icon\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/>\n <path d=\"M13 13L17 17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n <input\n class=\"search-input\"\n type=\"text\"\n [(ngModel)]=\"searchQuery\"\n (ngModelChange)=\"onSearchChange()\"\n placeholder=\"Rechercher...\"\n autocomplete=\"off\"\n />\n <button *ngIf=\"searchQuery\" type=\"button\" class=\"search-clear-btn\" (click)=\"searchQuery = ''; onSearchChange()\">\u00D7</button>\n <span class=\"search-count\">{{ filteredRowCount }}</span>\n </div>\n </div>\n <div *ngIf=\"showViewButton\" class=\"table-toolbar-right\">\n <button type=\"button\" class=\"view-btn\" [matMenuTriggerFor]=\"viewMenu\" #viewMenuTrigger=\"matMenuTrigger\">\n <mat-icon class=\"view-btn-icon\">settings</mat-icon>\n View\n </button>\n\n <mat-menu #viewMenu=\"matMenu\" [panelClass]=\"'view-menu-panel'\">\n <button *ngIf=\"showFields\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Champs</span>\n <span class=\"view-menu-sub-value\">{{ visibleColumns.length }}/{{ totalColumnCount }}</span>\n </button>\n <button *ngIf=\"showGroupBySection\" mat-menu-item [matMenuTriggerFor]=\"groupBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Group by</span>\n <span class=\"view-menu-sub-value\">{{ activeGroupByLabel }}</span>\n </button>\n <button *ngIf=\"showAddSliceButton\" mat-menu-item [matMenuTriggerFor]=\"sliceBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">Slice by</span>\n <span class=\"view-menu-sub-value\">{{ activeSliceByLabel }}</span>\n </button>\n </mat-menu>\n\n <mat-menu #fieldsSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuBaseColumns\"\n [disabled]=\"!column.optional && !allowColumnRemoval\"\n (click)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n </button>\n <ng-container *ngIf=\"menuOptionalColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuOptionalColumns\"\n [disabled]=\"(isColumnVisible(column.key) && visibleColumns.length === 1) || getLazyColumnStatus(column.key) === 'loading'\"\n (click)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'loading'\" class=\"lazy-menu-spinner\">\u21BB</span>\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'error'\" class=\"lazy-menu-error\" title=\"Erreur de chargement\">\u26A0</span>\n </button>\n </ng-container>\n </div>\n </mat-menu>\n\n <mat-menu #groupBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of groupByColumns\"\n [class.active]=\"activeGroupByKey === col.key\"\n (click)=\"onGroupByChange(activeGroupByKey === col.key ? null : col.key)\">\n <span class=\"view-menu-check\">{{ activeGroupByKey === col.key ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #sliceBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let s of staticSlicesForMenu\"\n (click)=\"toggleStaticSlice(s.key)\">\n <span class=\"view-menu-check\">{{ isStaticSliceVisible(s.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"s.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ s.icon }}</mat-icon>\n {{ s.title }}\n </button>\n <ng-container *ngIf=\"allDynamicSliceColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of allDynamicSliceColumns\"\n [class.active]=\"isDynamicSliceActive(col.key)\"\n (click)=\"toggleDynamicSlice(col)\">\n <span class=\"view-menu-check\">{{ isDynamicSliceActive(col.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </ng-container>\n </div>\n </mat-menu>\n </div>\n </div>\n\n <div class=\"table-body-wrapper\">\n <div class=\"table-body-scroll\" #tableBodyScroll>\n <table mat-table matSort [dataSource]=\"tableDataSource\" class=\"jquery-table\"\n [trackBy]=\"trackRowFn\"\n [matSortActive]=\"_matSortActive\" [matSortDirection]=\"_matSortDirection\">\n <ng-container *ngFor=\"let column of visibleColumns\" [matColumnDef]=\"column.key\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [mat-sort-header]=\"column.sortable !== false ? column.key : ''\"\n [disabled]=\"column.sortable === false\"\n [style.width]=\"column.width || null\"\n [style.min-width]=\"column.width || null\"\n [class.drag-enabled]=\"isColumnDragDropEnabled\"\n [class.drop-target]=\"isHeaderDropTarget(column.key)\"\n (dragover)=\"onHeaderDragOver(column.key, $event)\"\n (drop)=\"onHeaderDrop(column.key, $event)\"\n >\n <div class=\"head-cell\">\n <mat-icon *ngIf=\"column.icon\" class=\"head-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n <span class=\"head-text\" [title]=\"column.header\">{{ column.header }}</span>\n <span\n *ngIf=\"isColumnDragDropEnabled\"\n class=\"drag-handle\"\n draggable=\"true\"\n (dragstart)=\"onHeaderDragStart(column.key, $event)\"\n (dragend)=\"onHeaderDragEnd()\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </span>\n </div>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n [style.width]=\"column.width || null\"\n [style.min-width]=\"column.width || null\">\n <ng-container *ngIf=\"getCellTemplate(column.key) as customTpl; else defaultCellTpl\">\n <ng-container *ngTemplateOutlet=\"customTpl; context: { $implicit: row.__raw, index: row.__index }\"></ng-container>\n </ng-container>\n <ng-template #defaultCellTpl>\n <ng-container [ngSwitch]=\"column.lazy ? getLazyRenderType(row[column.key]) : 'value'\">\n <span *ngSwitchCase=\"'loading'\" class=\"lazy-skeleton\"></span>\n <button *ngSwitchCase=\"'error'\" type=\"button\" class=\"lazy-error-btn\" (click)=\"retryLazyColumn(column)\" title=\"Erreur de chargement \u2014 cliquer pour r\u00E9essayer\">\n <span class=\"lazy-error-icon\">\u26A0</span>\n <span class=\"lazy-error-label\">R\u00E9essayer</span>\n </button>\n <span *ngSwitchDefault class=\"cell-text\" [class.cell-empty]=\"isCellEmpty(row[column.key])\" [title]=\"asTitle(row[column.key])\">{{ isCellEmpty(row[column.key]) ? 'N/A' : row[column.key] }}</span>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"renderedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: renderedColumns; when: !isGroupHeader\"\n [attr.tabindex]=\"hasRowClickHandler ? 0 : null\"\n [ngClass]=\"getRowClass(row)\"\n [class.no-pointer]=\"!hasRowClickHandler\"\n (click)=\"onRowClick(row, $event)\"\n (keydown.enter)=\"onRowClick(row, null)\"\n (keydown.space)=\"onRowClick(row, null)\"\n ></tr>\n <ng-container matColumnDef=\"__group_row\">\n <td mat-cell *matCellDef=\"let row\" [attr.colspan]=\"renderedColumns.length\" class=\"group-header-cell\">\n <div class=\"group-header-label\">\n <span class=\"group-chevron\" [class.collapsed]=\"isGroupCollapsed(row.__groupKey)\" *ngIf=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__'\">\u203A</span>\n <span *ngIf=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__'\" class=\"group-key-label\">{{ row.__groupKey }}</span>\n <span *ngIf=\"row.__groupKey === '__lazy_loading__'\" class=\"lazy-skeleton group-lazy-key-skeleton\"></span>\n <span *ngIf=\"row.__groupKey === '__too_many_groups__'\" class=\"group-too-many-label\">\u26A0 Trop de groupes ({{ row.__groupCount }}) \u2014 affinez les donn\u00E9es ou choisissez une autre colonne</span>\n <span class=\"group-count-badge\">{{ row.__groupCount }}</span>\n <div class=\"group-pagination\" *ngIf=\"!isGroupCollapsed(row.__groupKey) && row.__groupPageCount > 1\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row.__groupPage === 0\" (click)=\"groupPageBack(row.__groupKey)\">\u2039</button>\n <span class=\"group-page-info\">{{ row.__groupPage + 1 }}\u00A0/\u00A0{{ row.__groupPageCount }}</span>\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row.__groupPage >= row.__groupPageCount - 1\" (click)=\"groupPageForward(row.__groupKey, row.__groupCount)\">\u203A</button>\n </div>\n </div>\n </td>\n </ng-container>\n <tr mat-row *matRowDef=\"let row; columns: ['__group_row']; when: isGroupHeader\"\n class=\"group-header-row\"\n [class.group-header-loading]=\"row.__groupKey === '__lazy_loading__'\"\n [class.group-header-too-many]=\"row.__groupKey === '__too_many_groups__'\"\n [attr.data-group-key]=\"row.__groupKey\"\n (click)=\"row.__groupKey !== '__lazy_loading__' && row.__groupKey !== '__too_many_groups__' && toggleGroupCollapse(row.__groupKey)\"></tr>\n <tr class=\"mat-mdc-row no-data-row\" *matNoDataRow>\n <td class=\"mat-mdc-cell no-data-cell\" [attr.colspan]=\"renderedColumns.length\"></td>\n </tr>\n </table>\n </div><!-- /table-body-scroll -->\n <div class=\"table-body-overlay\" *ngIf=\"effectiveIsLoading || isEmpty\">\n <span class=\"table-body-overlay-text\">{{ effectiveIsLoading ? loadingStateLabel : emptyStateLabel }}</span>\n </div>\n </div><!-- /table-body-wrapper -->\n\n <div class=\"bottom-bar\" *ngIf=\"showPagination\">\n <mat-paginator\n [length]=\"totalRows\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <div class=\"group-bottom-bar\" *ngIf=\"activeGroupByKey\">\n <div class=\"group-bottom-bar-container\">\n <div class=\"group-bottom-bar-left\">\n <button type=\"button\" class=\"group-reset-btn\" (click)=\"onGroupByChange(null)\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"group-reset-icon\">\n <path d=\"M3 8a5 5 0 1 0 5-5 5 5 0 0 0-3.54 1.46L3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3 3v2.5H5.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n Retirer le groupe\n </button>\n <div class=\"group-bar-separator\"></div>\n <div class=\"group-sort-controls\">\n <span class=\"group-sort-label\">Trier :</span>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'asc'\" (click)=\"onGroupSortToggle('asc')\" title=\"A \u2192 Z\">\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'desc'\" (click)=\"onGroupSortToggle('desc')\" title=\"Z \u2192 A\">\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"mat-mdc-paginator-page-size\">\n <div class=\"mat-mdc-paginator-page-size-label\">Lignes par groupe :</div>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"mat-mdc-paginator-page-size-select\">\n <mat-select\n [(ngModel)]=\"groupPageSize\"\n (ngModelChange)=\"onGroupPageSizeChange($event)\"\n panelClass=\"mat-mdc-paginator-select-page-size group-page-size-panel\"\n [panelWidth]=\"'auto'\"\n >\n <mat-select-trigger>{{ groupPageSize === 0 ? 'Toutes' : groupPageSize }}</mat-select-trigger>\n <mat-option *ngFor=\"let opt of pageSizeOptionsGroupBy\" [value]=\"opt\">{{ opt }}</mat-option>\n <mat-option [value]=\"0\">Toutes</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;max-height:100%;min-height:inherit;--jqt-title-color: #1f2937;--jqt-text-color: #111827;--jqt-text-secondary: #6b7280;--jqt-text-muted: #9ca3af;--jqt-surface-color: #ffffff;--jqt-surface-alt-color: #f9fafb;--jqt-row-hover-bg: #f3f4f6;--jqt-border-color: #e5e7eb;--jqt-group-bg: #eef2f7;--jqt-group-bg-hover: #e4ecf4;--jqt-group-accent: #94a3b8;--jqt-group-border: #d1d9e4;--jqt-primary-color: #1d4ed8;--jqt-danger-color: #dc2626;--jqt-danger-hover-bg: #fef2f2;--jqt-danger-border: #fca5a5;--jqt-header-bg: #f5f5f5;--jqt-header-text-color: #374151;--jqt-cell-bg: #ffffff;--jqt-footer-bg: #f5f5f5;--jqt-footer-text-color: #374151;--jqt-footer-icon-color: #374151}.jquery-table-wrapper{display:flex;flex-direction:column;width:100%;height:100%;min-height:inherit;padding:2px 2px 0;box-sizing:border-box}.table-header{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-bottom:12px}.table-header h3{margin:0;font-size:20px;font-weight:600;color:var(--jqt-title-color)}.table-layout{display:grid;grid-template-columns:minmax(155px,190px) minmax(0,1fr);gap:12px;align-items:stretch;min-height:inherit;height:100%}.table-layout.no-slice{grid-template-columns:minmax(0,1fr)}.table-layout.slice-collapsed{grid-template-columns:40px minmax(0,1fr)}.table-shell{display:flex;flex-direction:column;flex:1 1 0;min-height:0;min-width:0;width:100%;max-width:100%}.table-body-wrapper{position:relative;flex:1 1 0;min-height:0;display:flex;flex-direction:column}.table-body-scroll{flex:1 1 0;overflow-y:auto;min-height:0;border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:8px 8px 0 0;scrollbar-width:thin;scrollbar-color:var(--jqt-border-color) transparent}.table-body-scroll::-webkit-scrollbar{width:6px}.table-body-scroll::-webkit-scrollbar-thumb{background:var(--jqt-border-color);border-radius:4px}.table-body-overlay{position:absolute;top:var(--actual-header-height, 56px);left:0;right:0;bottom:0;z-index:3;display:flex;align-items:center;justify-content:center;background:var(--jqt-surface-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);pointer-events:none}.table-body-overlay-text{font-size:14px;color:var(--jqt-text-secondary)}.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 0 8px}.table-toolbar-left{flex:1 1 auto;min-width:0}.table-toolbar-right{flex:0 0 auto}.search-input-wrapper{position:relative;display:inline-flex;align-items:center;width:100%;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 8px;box-sizing:border-box;gap:6px}.search-input-wrapper:focus-within{border-color:var(--jqt-text-muted)}.search-input-wrapper .search-icon{flex-shrink:0;width:14px;height:14px;color:var(--jqt-text-muted)}.search-input{flex:1;border:none;outline:none;font-size:13px;color:var(--jqt-text-color);background:transparent;padding:7px 0;min-width:0}.search-input::placeholder{color:var(--jqt-text-muted)}.search-count{flex-shrink:0;font-size:12px;font-weight:600;color:var(--jqt-text-secondary);background:var(--jqt-row-hover-bg);border-radius:10px;padding:1px 7px;min-width:20px;text-align:center;line-height:18px}.search-clear-btn{background:none;border:none;cursor:pointer;color:var(--jqt-text-muted);font-size:16px;padding:0;line-height:1;flex-shrink:0}.search-clear-btn:hover{color:var(--jqt-text-color)}.view-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.view-btn:hover{border-color:var(--jqt-text-muted)}.view-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.group-header-row{cursor:pointer}:host ::ng-deep .jquery-table{border-spacing:0}:host ::ng-deep .group-header-row td{padding:0!important;background:var(--jqt-group-bg);border-bottom:1px solid var(--jqt-group-border);border-top:1px solid var(--jqt-group-border);border-left:3px solid var(--jqt-group-accent);position:sticky;top:var(--actual-header-height, 56px);z-index:2;box-shadow:-4px 0 0 0 var(--jqt-group-bg)}:host ::ng-deep .group-header-row:hover td{background:var(--jqt-group-bg-hover);box-shadow:-4px 0 0 0 var(--jqt-group-bg-hover)}:host ::ng-deep .group-header-loading td,:host ::ng-deep .group-header-loading:hover td,:host ::ng-deep .group-header-too-many td,:host ::ng-deep .group-header-too-many:hover td{cursor:default;background:var(--jqt-surface-alt-color)}.group-too-many-label{font-size:12px;font-weight:500;color:var(--jqt-warn-color, #b45309);font-style:italic}.group-header-cell{padding:0!important}.group-header-label{display:flex;align-items:center;gap:6px;padding:6px 16px;font-size:12px;font-weight:700;color:var(--jqt-text-color);text-transform:uppercase;letter-spacing:.04em}.group-key-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-count-badge{flex-shrink:0;font-size:11px;line-height:1;font-weight:600;color:#fff;background:var(--jqt-text-secondary, #6b7280);border-radius:10px;padding:3px 7px;min-width:20px;text-align:center;text-transform:none;letter-spacing:0}.group-pagination{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.group-page-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--jqt-border-color);border-radius:5px;background:var(--jqt-surface-color);cursor:pointer;font-size:14px;color:var(--jqt-text-color);line-height:1;padding:0 0 3px;text-transform:none;letter-spacing:0}.group-page-btn:hover:not(:disabled){border-color:var(--jqt-text-muted);background:var(--jqt-surface-alt-color)}.group-page-btn:disabled{opacity:.35;cursor:default}.group-page-info{font-size:11px;color:var(--jqt-text-secondary);min-width:36px;text-align:center;font-weight:500;text-transform:none;letter-spacing:0}.group-chevron{flex-shrink:0;font-size:14px;font-weight:700;padding-bottom:3px;transition:transform .15s ease;transform:rotate(90deg)}.group-chevron.collapsed{transform:rotate(0)}.no-data-row{cursor:default!important}.no-data-cell{padding:0!important;height:0!important;border:none!important}.jquery-table{width:100%;table-layout:fixed}:host ::ng-deep .mat-mdc-table{width:100%;background:transparent}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .mat-mdc-header-row{background:var(--jqt-header-bg)}:host ::ng-deep .mat-mdc-header-cell{background:var(--jqt-header-bg);color:var(--jqt-header-text-color)}:host ::ng-deep .mat-mdc-row,:host ::ng-deep .mat-mdc-cell{background:var(--jqt-cell-bg)}:host ::ng-deep .mat-mdc-row{cursor:pointer;border-bottom-color:var(--jqt-border-color)}:host ::ng-deep .mat-mdc-row.no-pointer{cursor:auto}:host ::ng-deep .mat-mdc-row.no-data-row{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drag-enabled{-webkit-user-select:none;user-select:none}:host ::ng-deep .mat-mdc-header-cell.drag-enabled:active{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drop-target{background:var(--jqt-row-hover-bg)}.head-cell{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}.drag-handle{display:inline-flex;align-items:center;cursor:grab;color:var(--jqt-border-color);flex-shrink:0;padding:0 2px;border-radius:4px;line-height:1}.drag-handle:active{cursor:grabbing}.drag-handle:hover{color:var(--jqt-text-muted)}.drag-handle mat-icon{font-size:16px;width:16px;height:16px;line-height:1}.head-icon{font-size:14px;width:14px;height:14px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.head-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;font-size:11px;font-weight:600;letter-spacing:.05em}.head-actions{display:inline-flex;align-items:center;gap:6px}.cell-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cell-empty{color:var(--jqt-empty-cell-color, #9ca3af);font-style:italic}.bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}:host ::ng-deep .bottom-bar mat-paginator{flex:1 1 auto;background:transparent;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-paginator-outer-container{display:flex}:host ::ng-deep .bottom-bar .mat-mdc-paginator-container{display:flex;align-items:center;flex-wrap:nowrap;min-height:0;height:var(--actual-header-height, 56px);padding:0 8px;box-sizing:border-box}:host ::ng-deep .bottom-bar .mat-mdc-paginator-range-label,:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button{color:var(--jqt-footer-icon-color);width:28px;height:28px;padding:0;line-height:1;display:inline-flex;align-items:center;justify-content:center;--mdc-icon-button-state-layer-size: 28px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-mdc-button-persistent-ripple,:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mdc-icon-button__state-layer{width:28px;height:28px;top:50%;left:50%;transform:translate(-50%,-50%)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button:disabled{opacity:.35}:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}.group-bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}.group-bottom-bar-container{display:flex;align-items:center;justify-content:space-between;flex-wrap:nowrap;height:var(--actual-header-height, 56px);padding:0 16px;gap:16px;width:100%;box-sizing:border-box}.group-bar-separator{width:1px;height:20px;background:#9ca3af;flex-shrink:0;margin:0 4px}.group-bottom-bar-left{display:flex;align-items:center;gap:8px;flex-shrink:0}.group-sort-controls{display:flex;align-items:center;gap:2px}.group-sort-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap;margin-right:2px}.group-sort-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--jqt-footer-icon-color);cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.group-sort-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.group-sort-btn:hover{background:#0000000a}.group-sort-btn.active{color:var(--jqt-primary-color, #1976d2);border-color:var(--jqt-primary-color, #1976d2);background:#1976d214}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size{display:flex;align-items:center;gap:8px}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .group-bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .group-bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .group-bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .group-bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .group-bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}:host ::ng-deep .group-bottom-bar .mat-mdc-select-arrow{color:var(--jqt-footer-text-color)}.group-reset-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);color:var(--jqt-text-secondary);font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;white-space:nowrap;flex-shrink:0}.group-reset-btn:hover{background:var(--jqt-danger-hover-bg);color:var(--jqt-danger-color);border-color:var(--jqt-danger-border)}.group-reset-icon{width:14px;height:14px;flex-shrink:0}::ng-deep .mat-mdc-paginator-select-page-size .mat-pseudo-checkbox{display:none!important}::ng-deep .group-page-size-panel{min-width:90px!important}::ng-deep .group-page-size-panel .mat-mdc-option{justify-content:center;min-height:40px}::ng-deep .group-page-size-panel .mdc-list-item__primary-text{text-align:center;width:100%}@media (max-width: 960px){.table-layout{grid-template-columns:1fr}}::ng-deep .view-menu-panel .mat-mdc-menu-panel{min-width:220px!important;overflow:visible!important}::ng-deep .view-menu-panel .mat-mdc-menu-content{padding:4px 0!important}::ng-deep .view-submenu-panel .mat-mdc-menu-panel{min-width:200px!important}::ng-deep .view-submenu-panel .mat-mdc-menu-content{padding:0!important}::ng-deep .view-menu-panel .view-menu-sub-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}::ng-deep .view-menu-panel .view-menu-sub-trigger .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;gap:0;overflow:hidden}::ng-deep .view-menu-sub-label{font-size:13px;font-weight:500;color:var(--jqt-text-color);flex:0 0 auto;white-space:nowrap;padding-right:8px}::ng-deep .view-menu-sub-value{font-size:12px;color:var(--jqt-text-secondary);flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}::ng-deep .view-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}::ng-deep .view-submenu .view-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:var(--jqt-text-color);cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}::ng-deep .view-submenu .view-menu-item:hover{background:var(--jqt-row-hover-bg)}::ng-deep .view-submenu .view-menu-item.active{font-weight:600}::ng-deep .view-submenu .view-menu-item:disabled{opacity:.4;cursor:default}::ng-deep .view-menu-col-icon{flex-shrink:0;font-size:14px!important;width:14px!important;height:14px!important;color:var(--jqt-text-muted)}::ng-deep .view-menu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:var(--jqt-text-color)}::ng-deep .view-menu-separator{border:none;border-top:1px solid var(--jqt-border-color);margin:4px 0}.lazy-skeleton{display:block;height:12px;width:70%;border-radius:4px;background:linear-gradient(90deg,var(--jqt-border-color) 25%,var(--jqt-surface-alt-color) 50%,var(--jqt-border-color) 75%);background-size:200% 100%;animation:lazy-shimmer 1.4s ease-in-out infinite}.group-lazy-key-skeleton{flex:1 1 auto;min-width:80px;height:13px;border-radius:4px}@keyframes lazy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.lazy-error-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:1px solid #fca5a5;border-radius:4px;padding:2px 6px;cursor:pointer;color:#ef4444;font-size:12px;opacity:.85;transition:opacity .15s}.lazy-error-btn:hover{opacity:1;background:#fef2f2}.lazy-error-icon{font-size:12px}.lazy-error-label{font-size:11px;font-weight:500}::ng-deep .lazy-menu-spinner{display:inline-block;margin-left:auto;font-size:13px;color:var(--jqt-text-secondary);animation:lazy-spin 1s linear infinite}::ng-deep .lazy-menu-error{display:inline-block;margin-left:auto;font-size:13px;color:#ef4444}@keyframes lazy-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
1347
|
+
args: [{ standalone: true, selector: 'jquery-table', imports: [CommonModule, FormsModule, MatTableModule, MatButtonModule, MatDividerModule, MatPaginatorModule, MatSortModule, MatMenuModule, MatIconModule, MatSelectModule, SlicePanelComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: MatPaginatorIntl, useFactory: getFrenchPaginatorIntl }], template: "<section class=\"jquery-table-wrapper\">\n <header class=\"table-header\" *ngIf=\"showTitle\">\n <h3>{{ title }}</h3>\n </header>\n\n <div\n class=\"table-layout\"\n [class.no-slice]=\"!_showSlicePanel || _slicePanelCollapsed\"\n >\n <slice-panel\n [style.display]=\"!_showSlicePanel || _slicePanelCollapsed ? 'none' : null\"\n [sliceConfigs]=\"_sliceConfigs\"\n [columns]=\"_sliceColumns\"\n [data]=\"_sliceData\"\n [lazyData]=\"_lazyColumnData\"\n [lazyStatus]=\"_lazyColumnStatus\"\n [showToggle]=\"_sliceShowToggle\"\n [collapsedByDefault]=\"_slicePanelCollapsed\"\n (filterChange)=\"onSliceFilterChange($event)\"\n (dynamicSliceKeysChange)=\"onDynamicSliceKeysChange($event)\"\n (collapsedChange)=\"onSlicePanelCollapsedChange($event)\"\n ></slice-panel>\n\n <div class=\"table-shell\">\n <div class=\"table-toolbar\" *ngIf=\"showToolbar\">\n <div class=\"table-toolbar-left\">\n <button\n *ngIf=\"showSliceExpandBtn\"\n type=\"button\"\n class=\"slice-expand-btn\"\n [title]=\"i18n.expandFilterTitle\"\n (click)=\"expandSlicePanel()\"\n ><mat-icon class=\"slice-expand-mat-icon\">menu</mat-icon></button>\n <div *ngIf=\"showSearchBar\" class=\"search-input-wrapper\">\n <svg class=\"search-icon\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/>\n <path d=\"M13 13L17 17\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n <input\n class=\"search-input\"\n type=\"text\"\n [(ngModel)]=\"searchQuery\"\n (ngModelChange)=\"onSearchChange()\"\n [placeholder]=\"i18n.searchPlaceholder\"\n autocomplete=\"off\"\n />\n <button *ngIf=\"searchQuery\" type=\"button\" class=\"search-clear-btn\" (click)=\"searchQuery = ''; onSearchChange()\">\u00D7</button>\n <span class=\"search-count\">{{ filteredRowCount }}</span>\n </div>\n </div>\n <div *ngIf=\"showViewButton\" class=\"table-toolbar-right\">\n <button *ngIf=\"showViewButton\" type=\"button\" class=\"view-btn\" [matMenuTriggerFor]=\"viewMenu\" #viewMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"'View'\">\n <mat-icon class=\"view-btn-icon\">settings</mat-icon>\n </button>\n\n <mat-menu #viewMenu=\"matMenu\" [panelClass]=\"'view-menu-panel'\">\n <button *ngIf=\"showFields\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuFields }}</span>\n <span class=\"view-menu-sub-value\">{{ visibleColumns.length }}/{{ totalColumnCount }}</span>\n </button>\n <button *ngIf=\"showGroupBySection\" mat-menu-item [matMenuTriggerFor]=\"groupBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuGroupBy }}</span>\n <span class=\"view-menu-sub-value\">{{ activeGroupByLabel }}</span>\n </button>\n <button *ngIf=\"showAddSliceButton\" mat-menu-item [matMenuTriggerFor]=\"sliceBySubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.viewMenuSliceBy }}</span>\n <span class=\"view-menu-sub-value\">{{ activeSliceByLabel }}</span>\n </button>\n <mat-divider *ngIf=\"showExportButton\" class=\"view-menu-export-divider\"></mat-divider>\n <button *ngIf=\"showExportButton\" mat-menu-item type=\"button\" class=\"view-menu-export-item\"\n (click)=\"onExport(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-export-icon\">download</mat-icon>\n <span class=\"view-menu-sub-label\">{{ i18n.exportButtonLabel }}</span>\n </button>\n <mat-divider *ngIf=\"showPreferencesMenu\" class=\"view-menu-export-divider\"></mat-divider>\n <button *ngIf=\"showPreferencesMenu\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"view-menu-sub-trigger\">\n <span class=\"view-menu-sub-label\">{{ i18n.preferencesMenuLabel }}</span>\n </button>\n </mat-menu>\n\n <mat-menu #preferencesSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" (mousedown)=\"enterEditMode(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">edit</mat-icon>\n {{ i18n.preferencesEdit }}\n </button>\n <button type=\"button\" class=\"view-menu-item\" (mousedown)=\"savePreferences(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">save</mat-icon>\n {{ i18n.preferencesSave }}\n </button>\n <button type=\"button\" class=\"view-menu-item\" [disabled]=\"!hasSavedPreferences\" (mousedown)=\"clearPreferences(); viewMenuTrigger.closeMenu()\">\n <mat-icon class=\"view-menu-col-icon\">delete_outline</mat-icon>\n {{ i18n.preferencesClear }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #fieldsSubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuBaseColumns\"\n [disabled]=\"!column.optional && !allowColumnRemoval\"\n (mousedown)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n </button>\n <ng-container *ngIf=\"menuOptionalColumns.length > 0\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let column of menuOptionalColumns\"\n [disabled]=\"(isColumnVisible(column.key) && visibleColumns.length === 1) || getLazyColumnStatus(column.key) === 'loading'\"\n (mousedown)=\"onColumnVisibilityChange(column, !isColumnVisible(column.key))\">\n <span class=\"view-menu-check\">{{ isColumnVisible(column.key) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"column.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n {{ colLabel(column) }}\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'loading'\" class=\"lazy-menu-spinner\">\u21BB</span>\n <span *ngIf=\"column.lazy && getLazyColumnStatus(column.key) === 'error'\" class=\"lazy-menu-error\" [title]=\"i18n.lazyErrorMenuTitle\">\u26A0</span>\n </button>\n </ng-container>\n </div>\n </mat-menu>\n\n <mat-menu #groupBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let col of groupByColumns\"\n [class.active]=\"activeGroupByKey === col.key\"\n (mousedown)=\"onGroupByChange(activeGroupByKey === col.key ? null : col.key)\">\n <span class=\"view-menu-check\">{{ activeGroupByKey === col.key ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"col.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ col.icon }}</mat-icon>\n {{ colLabel(col) }}\n </button>\n </div>\n </mat-menu>\n\n <mat-menu #sliceBySubMenu=\"matMenu\" [panelClass]=\"'view-submenu-panel'\">\n <div class=\"view-submenu\" (mousedown)=\"$event.stopPropagation()\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"view-menu-item\" *ngFor=\"let item of sliceByMenuItems\"\n [class.active]=\"isSliceMenuItemActive(item)\"\n (mousedown)=\"onSliceMenuItemClick(item)\">\n <span class=\"view-menu-check\">{{ isSliceMenuItemActive(item) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"item.icon\" class=\"view-menu-col-icon\" fontSet=\"material-icons-outlined\">{{ item.icon }}</mat-icon>\n {{ item.title }}\n </button>\n </div>\n </mat-menu>\n </div>\n </div>\n\n <div class=\"table-body-wrapper\">\n\n <!-- Banni\u00E8re message pr\u00E9f\u00E9rences -->\n <div *ngIf=\"_preferencesMessage\" class=\"preferences-message\">\n <mat-icon class=\"preferences-message-icon\">check_circle</mat-icon>\n <span>{{ _preferencesMessage }}</span>\n </div>\n\n <!-- Bouton de confirmation du mode \u00E9dition -->\n <button\n *ngIf=\"_editMode\"\n type=\"button\"\n class=\"edit-confirm-btn\"\n [title]=\"i18n.preferencesConfirmEdit\"\n (click)=\"confirmEditMode()\"\n >\n <mat-icon>check_circle</mat-icon>\n </button>\n <div class=\"table-body-scroll\" #tableBodyScroll>\n <table mat-table matSort [dataSource]=\"tableDataSource\" class=\"jquery-table\"\n [style.min-width]=\"tableMinWidth\"\n [trackBy]=\"trackRowFn\"\n [matSortActive]=\"_matSortActive\" [matSortDirection]=\"_matSortDirection\">\n <ng-container *ngFor=\"let column of visibleColumns\" [matColumnDef]=\"column.key\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [mat-sort-header]=\"(!_editMode && column.sortable !== false) ? column.key : ''\"\n [disabled]=\"_editMode || column.sortable === false\"\n [style.width]=\"getColumnWidth(column.key)\"\n [class.drag-enabled]=\"isColumnDragDropEnabled || _editMode\"\n [class.drop-target]=\"isHeaderDropTarget(column.key)\"\n [class.edit-mode-header]=\"_editMode\"\n (dragover)=\"onHeaderDragOver(column.key, $event)\"\n (drop)=\"onHeaderDrop(column.key, $event)\"\n >\n <div class=\"head-cell\">\n <mat-icon *ngIf=\"column.icon\" class=\"head-icon\" fontSet=\"material-icons-outlined\">{{ column.icon }}</mat-icon>\n <span class=\"head-text\" [title]=\"column.header\">{{ column.header }}</span>\n <span\n *ngIf=\"isColumnDragDropEnabled || _editMode\"\n class=\"drag-handle\"\n draggable=\"true\"\n (dragstart)=\"onHeaderDragStart(column.key, $event)\"\n (dragend)=\"onHeaderDragEnd()\"\n (click)=\"$event.stopPropagation()\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </span>\n </div>\n <!-- Poign\u00E9e de resize (visible uniquement en mode \u00E9dition) -->\n <span\n *ngIf=\"_editMode\"\n class=\"col-resize-handle\"\n draggable=\"false\"\n (mousedown)=\"onResizeStart(column.key, $event)\"\n ></span>\n </th>\n <td mat-cell *matCellDef=\"let row\"\n [style.width]=\"getColumnWidth(column.key)\"\n [class.edit-mode-cell]=\"_editMode\">\n <ng-container *ngIf=\"!_editMode; else editModeCellTpl\">\n <ng-container *ngIf=\"getCellTemplate(column.key) as customTpl; else defaultCellTpl\">\n <ng-container *ngTemplateOutlet=\"customTpl; context: { $implicit: row[_ROW_RAW_KEY], index: row[_ROW_INDEX_KEY] }\"></ng-container>\n </ng-container>\n <ng-template #defaultCellTpl>\n <ng-container [ngSwitch]=\"column.lazy ? getLazyRenderType(row[column.key]) : 'value'\">\n <span *ngSwitchCase=\"'loading'\" class=\"lazy-skeleton\"></span>\n <button *ngSwitchCase=\"'error'\" type=\"button\" class=\"lazy-error-btn\" (click)=\"retryLazyColumn(column)\" [title]=\"i18n.lazyErrorTitle\">\n <span class=\"lazy-error-icon\">\u26A0</span>\n <span class=\"lazy-error-label\">{{ i18n.lazyRetry }}</span>\n </button>\n <span *ngSwitchDefault class=\"cell-text\" [class.cell-empty]=\"isCellEmpty(row[column.key])\" [title]=\"asTitle(row[column.key])\">{{ isCellEmpty(row[column.key]) ? i18n.cellEmpty : row[column.key] }}</span>\n </ng-container>\n </ng-template>\n </ng-container>\n <ng-template #editModeCellTpl>\n <span class=\"cell-text cell-edit-mode\" [title]=\"asTitle(row[column.key])\">{{ row[column.key] }}</span>\n </ng-template>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"renderedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: renderedColumns; when: !isGroupHeader\"\n [attr.tabindex]=\"hasRowClickHandler && !_editMode ? 0 : null\"\n [ngClass]=\"getRowClass(row)\"\n [class.no-pointer]=\"!hasRowClickHandler || _editMode\"\n [class.edit-mode-row]=\"_editMode\"\n (click)=\"!_editMode && onRowClick(row, $event)\"\n (keydown.enter)=\"!_editMode && onRowClick(row, null)\"\n (keydown.space)=\"!_editMode && onRowClick(row, null)\"\n ></tr>\n <ng-container [matColumnDef]=\"_GROUP_ROW_COLUMN\">\n <td mat-cell *matCellDef=\"let row\" [attr.colspan]=\"renderedColumns.length\" class=\"group-header-cell\">\n <div class=\"group-header-label\">\n <span class=\"group-chevron\" [class.collapsed]=\"isGroupCollapsed(row[_ROW_GROUP_KEY])\" *ngIf=\"isNormalGroupRow(row)\">\u203A</span>\n <span *ngIf=\"isNormalGroupRow(row)\" class=\"group-key-label\">{{ row[_ROW_GROUP_KEY] }}</span>\n <span *ngIf=\"isGroupRowLoading(row)\" class=\"lazy-skeleton group-lazy-key-skeleton\"></span>\n <span *ngIf=\"isGroupRowTooMany(row)\" class=\"group-too-many-label\">{{ i18n.groupTooMany(row[_ROW_GROUP_COUNT]) }}</span>\n <span class=\"group-count-badge\">{{ row[_ROW_GROUP_COUNT] }}</span>\n <div class=\"group-pagination\" *ngIf=\"!isGroupCollapsed(row[_ROW_GROUP_KEY]) && row[_ROW_GROUP_PAGE_COUNT] > 1\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row[_ROW_GROUP_PAGE] === 0\" (click)=\"groupPageBack(row[_ROW_GROUP_KEY])\">\u2039</button>\n <span class=\"group-page-info\">{{ row[_ROW_GROUP_PAGE] + 1 }} / {{ row[_ROW_GROUP_PAGE_COUNT] }}</span>\n <button type=\"button\" class=\"group-page-btn\" [disabled]=\"row[_ROW_GROUP_PAGE] >= row[_ROW_GROUP_PAGE_COUNT] - 1\" (click)=\"groupPageForward(row[_ROW_GROUP_KEY], row[_ROW_GROUP_COUNT])\">\u203A</button>\n </div>\n </div>\n </td>\n </ng-container>\n <tr mat-row *matRowDef=\"let row; columns: [_GROUP_ROW_COLUMN]; when: isGroupHeader\"\n class=\"group-header-row\"\n [class.group-header-loading]=\"isGroupRowLoading(row)\"\n [class.group-header-too-many]=\"isGroupRowTooMany(row)\"\n [attr.data-group-key]=\"row[_ROW_GROUP_KEY]\"\n (click)=\"onGroupHeaderClick(row)\"></tr>\n <tr class=\"mat-mdc-row no-data-row\" *matNoDataRow>\n <td class=\"mat-mdc-cell no-data-cell\" [attr.colspan]=\"renderedColumns.length\"></td>\n </tr>\n </table>\n </div><!-- /table-body-scroll -->\n <div class=\"table-body-overlay\" *ngIf=\"effectiveIsLoading || isEmpty\">\n <span class=\"table-body-overlay-text\">{{ effectiveIsLoading ? loadingStateLabel : emptyStateLabel }}</span>\n </div>\n </div><!-- /table-body-wrapper -->\n\n <div class=\"bottom-bar\" *ngIf=\"showPagination\">\n <mat-paginator\n [length]=\"totalRows\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <div class=\"group-bottom-bar\" *ngIf=\"activeGroupByKey\">\n <div class=\"group-bottom-bar-container\">\n <div class=\"group-bottom-bar-left\">\n <button type=\"button\" class=\"group-reset-btn\" (click)=\"onGroupByChange(null)\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"group-reset-icon\">\n <path d=\"M3 8a5 5 0 1 0 5-5 5 5 0 0 0-3.54 1.46L3 3\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3 3v2.5H5.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n {{ i18n.groupRemove }}\n </button>\n <div class=\"group-bar-separator\"></div>\n <div class=\"group-sort-controls\">\n <span class=\"group-sort-label\">{{ i18n.groupSortLabel }}</span>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'asc'\" (click)=\"onGroupSortToggle('asc')\" [title]=\"i18n.groupSortAsc\">\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button type=\"button\" class=\"group-sort-btn\" [class.active]=\"groupSortOrder === 'desc'\" (click)=\"onGroupSortToggle('desc')\" [title]=\"i18n.groupSortDesc\">\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"mat-mdc-paginator-page-size\">\n <div class=\"mat-mdc-paginator-page-size-label\">{{ i18n.groupRowsPerGroup }}</div>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"mat-mdc-paginator-page-size-select\">\n <mat-select\n [(ngModel)]=\"groupPageSize\"\n (ngModelChange)=\"onGroupPageSizeChange($event)\"\n panelClass=\"mat-mdc-paginator-select-page-size group-page-size-panel\"\n [panelWidth]=\"'auto'\"\n >\n <mat-select-trigger>{{ groupPageSize === 0 ? i18n.groupShowAll : groupPageSize }}</mat-select-trigger>\n <mat-option *ngFor=\"let opt of pageSizeOptionsGroupBy\" [value]=\"opt\">{{ opt }}</mat-option>\n <mat-option [value]=\"0\">{{ i18n.groupShowAll }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n </div>\n</section>\n", styles: [":host{display:block;max-height:100%;min-height:inherit;--jqt-title-color: #1f2937;--jqt-text-color: #111827;--jqt-text-secondary: #6b7280;--jqt-text-muted: #9ca3af;--jqt-surface-color: #ffffff;--jqt-surface-alt-color: #f9fafb;--jqt-row-hover-bg: #f3f4f6;--jqt-border-color: #e5e7eb;--jqt-group-bg: #eef2f7;--jqt-group-bg-hover: #e4ecf4;--jqt-group-accent: #94a3b8;--jqt-group-border: #d1d9e4;--jqt-primary-color: #1d4ed8;--jqt-danger-color: #dc2626;--jqt-danger-hover-bg: #fef2f2;--jqt-danger-border: #fca5a5;--jqt-header-bg: #f5f5f5;--jqt-header-text-color: #374151;--jqt-cell-bg: #ffffff;--jqt-footer-bg: #f5f5f5;--jqt-footer-text-color: #374151;--jqt-footer-icon-color: #374151}.jquery-table-wrapper{display:flex;flex-direction:column;width:100%;height:100%;min-height:inherit;padding:2px 2px 0;box-sizing:border-box}.table-header{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-bottom:12px}.table-header h3{margin:0;font-size:20px;font-weight:600;color:var(--jqt-title-color)}.table-layout{display:grid;grid-template-columns:minmax(155px,190px) minmax(0,1fr);gap:12px;align-items:stretch;min-height:inherit;height:100%}.table-layout.no-slice{grid-template-columns:minmax(0,1fr)}.table-layout.slice-collapsed{grid-template-columns:40px minmax(0,1fr)}.table-shell{display:flex;flex-direction:column;flex:1 1 0;min-height:0;min-width:0;width:100%;max-width:100%}.table-body-wrapper{position:relative;flex:1 1 0;min-height:0;display:flex;flex-direction:column}.table-body-scroll{flex:1 1 0;overflow-x:auto;overflow-y:auto;min-height:0;border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:8px 8px 0 0;scrollbar-width:thin;scrollbar-color:var(--jqt-border-color) transparent}.table-body-scroll::-webkit-scrollbar{width:6px}.table-body-scroll::-webkit-scrollbar-thumb{background:var(--jqt-border-color);border-radius:4px}.table-body-overlay{position:absolute;top:var(--actual-header-height, 56px);left:0;right:0;bottom:0;z-index:3;display:flex;align-items:center;justify-content:center;background:var(--jqt-surface-color);border-right:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);pointer-events:none}.table-body-overlay-text{font-size:14px;color:var(--jqt-text-secondary)}.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 0 8px}.table-toolbar-left{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:6px}.table-toolbar-right{flex:0 0 auto;display:flex;align-items:center;gap:6px}.search-input-wrapper{position:relative;display:inline-flex;align-items:center;flex:1 1 auto;min-width:0;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 8px;box-sizing:border-box;gap:6px}.search-input-wrapper:focus-within{border-color:var(--jqt-text-muted)}.search-input-wrapper .search-icon{flex-shrink:0;width:14px;height:14px;color:var(--jqt-text-muted)}.search-input{flex:1;border:none;outline:none;font-size:13px;color:var(--jqt-text-color);background:transparent;padding:7px 0;min-width:0}.search-input::placeholder{color:var(--jqt-text-muted)}.search-count{flex-shrink:0;font-size:12px;font-weight:600;color:var(--jqt-text-secondary);background:var(--jqt-row-hover-bg);border-radius:10px;padding:1px 7px;min-width:20px;text-align:center;line-height:18px}.search-clear-btn{background:none;border:none;cursor:pointer;color:var(--jqt-text-muted);font-size:16px;padding:0;line-height:1;flex-shrink:0}.search-clear-btn:hover{color:var(--jqt-text-color)}.slice-expand-btn{flex-shrink:0;width:34px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--jqt-text-color);padding:0;line-height:1}.slice-expand-btn:hover{border-color:var(--jqt-text-muted)}.slice-expand-mat-icon{font-size:18px;width:18px;height:18px;line-height:1}.view-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.view-btn:hover{border-color:var(--jqt-text-muted)}.view-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.export-btn{display:inline-flex;align-items:center;gap:5px;height:34px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);padding:0 12px;font-size:13px;font-weight:500;color:var(--jqt-text-color);cursor:pointer;white-space:nowrap;box-sizing:border-box}.export-btn:hover{border-color:var(--jqt-text-muted)}.export-btn-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0}.view-menu-export-divider{margin:4px 0!important}.view-menu-export-item{display:flex;align-items:center;gap:6px;width:100%;padding:0 16px;height:40px;border:none;background:transparent;cursor:pointer;font-size:13px;font-weight:500;color:var(--jqt-text-color);text-align:left;box-sizing:border-box}.view-menu-export-item:hover{background:#0000000a}.view-menu-export-icon{font-size:16px;width:16px;height:16px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.edit-confirm-btn{position:absolute;top:10px;right:10px;z-index:200;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:50%;background:#16a34a;cursor:pointer;box-shadow:0 2px 8px #00000040;transition:background .15s}.edit-confirm-btn mat-icon{color:#fff;font-size:22px;width:22px;height:22px}.edit-confirm-btn:hover{background:#15803d}.preferences-message{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 12px;background:#f0fdf4;border:1px solid #bbf7d0;border-radius:6px;font-size:12px;color:#15803d}.preferences-message .preferences-message-icon{font-size:16px;width:16px;height:16px}:host ::ng-deep .edit-mode-header{background:#3b82f60a!important;cursor:grab!important;-webkit-user-select:none;user-select:none;overflow:visible!important}.col-resize-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize!important;background:#3b82f640;z-index:20}.col-resize-handle:hover{background:#3b82f6b3}.col-resize-handle:active{background:#3b82f6e6}:host ::ng-deep th.mat-mdc-header-cell{position:relative;overflow:visible!important}:host ::ng-deep .edit-mode-row{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.8}.cell-edit-mode{pointer-events:none;-webkit-user-select:none;user-select:none;color:var(--jqt-text-muted)}.group-header-row{cursor:pointer}:host ::ng-deep .jquery-table{border-spacing:0}:host ::ng-deep .group-header-row td{padding:0!important;background:var(--jqt-group-bg);border-bottom:1px solid var(--jqt-group-border);border-top:1px solid var(--jqt-group-border);border-left:3px solid var(--jqt-group-accent);position:sticky;top:var(--actual-header-height, 56px);z-index:2;box-shadow:-4px 0 0 0 var(--jqt-group-bg)}:host ::ng-deep .group-header-row:hover td{background:var(--jqt-group-bg-hover);box-shadow:-4px 0 0 0 var(--jqt-group-bg-hover)}:host ::ng-deep .group-header-loading td,:host ::ng-deep .group-header-loading:hover td,:host ::ng-deep .group-header-too-many td,:host ::ng-deep .group-header-too-many:hover td{cursor:default;background:var(--jqt-surface-alt-color)}.group-too-many-label{font-size:12px;font-weight:500;color:var(--jqt-warn-color, #b45309);font-style:italic}.group-header-cell{padding:0!important}.group-header-label{display:flex;align-items:center;gap:6px;padding:6px 16px;font-size:12px;font-weight:700;color:var(--jqt-text-color);text-transform:uppercase;letter-spacing:.04em}.group-key-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-count-badge{flex-shrink:0;font-size:11px;line-height:1;font-weight:600;color:#fff;background:var(--jqt-text-secondary, #6b7280);border-radius:10px;padding:3px 7px;min-width:20px;text-align:center;text-transform:none;letter-spacing:0}.group-pagination{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.group-page-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--jqt-border-color);border-radius:5px;background:var(--jqt-surface-color);cursor:pointer;font-size:14px;color:var(--jqt-text-color);line-height:1;padding:0 0 3px;text-transform:none;letter-spacing:0}.group-page-btn:hover:not(:disabled){border-color:var(--jqt-text-muted);background:var(--jqt-surface-alt-color)}.group-page-btn:disabled{opacity:.35;cursor:default}.group-page-info{font-size:11px;color:var(--jqt-text-secondary);min-width:36px;text-align:center;font-weight:500;text-transform:none;letter-spacing:0}.group-chevron{flex-shrink:0;font-size:14px;font-weight:700;padding-bottom:3px;transition:transform .15s ease;transform:rotate(90deg)}.group-chevron.collapsed{transform:rotate(0)}.no-data-row{cursor:default!important}.no-data-cell{padding:0!important;height:0!important;border:none!important}.jquery-table{width:100%;table-layout:fixed}:host ::ng-deep .mat-mdc-table{width:100%;background:transparent}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .mat-mdc-header-row{background:var(--jqt-header-bg)}:host ::ng-deep .mat-mdc-header-cell{background:var(--jqt-header-bg);color:var(--jqt-header-text-color)}:host ::ng-deep .mat-mdc-row,:host ::ng-deep .mat-mdc-cell{background:var(--jqt-cell-bg)}:host ::ng-deep .mat-mdc-row{cursor:pointer;border-bottom-color:var(--jqt-border-color)}:host ::ng-deep .mat-mdc-row.no-pointer{cursor:auto}:host ::ng-deep .mat-mdc-row.no-data-row{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drag-enabled{-webkit-user-select:none;user-select:none}:host ::ng-deep .mat-mdc-header-cell.drag-enabled:active{cursor:default}:host ::ng-deep .mat-mdc-header-cell.drop-target{background:var(--jqt-row-hover-bg)}.head-cell{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}.drag-handle{display:inline-flex;align-items:center;cursor:grab;color:var(--jqt-border-color);flex-shrink:0;padding:0 2px;border-radius:4px;line-height:1}.drag-handle:active{cursor:grabbing}.drag-handle:hover{color:var(--jqt-text-muted)}.drag-handle mat-icon{font-size:16px;width:16px;height:16px;line-height:1}.head-icon{font-size:14px;width:14px;height:14px;line-height:1;flex-shrink:0;color:var(--jqt-text-muted)}.head-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;font-size:11px;font-weight:600;letter-spacing:.05em}.head-actions{display:inline-flex;align-items:center;gap:6px}.cell-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cell-empty{color:var(--jqt-empty-cell-color, #9ca3af);font-style:italic}.bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}:host ::ng-deep .bottom-bar mat-paginator{flex:1 1 auto;background:transparent;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-paginator-outer-container{display:flex}:host ::ng-deep .bottom-bar .mat-mdc-paginator-container{display:flex;align-items:center;flex-wrap:nowrap;min-height:0;height:var(--actual-header-height, 56px);padding:0 8px;box-sizing:border-box}:host ::ng-deep .bottom-bar .mat-mdc-paginator-range-label,:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button{color:var(--jqt-footer-icon-color);width:28px;height:28px;padding:0;line-height:1;display:inline-flex;align-items:center;justify-content:center;--mdc-icon-button-state-layer-size: 28px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-mdc-button-persistent-ripple,:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mdc-icon-button__state-layer{width:28px;height:28px;top:50%;left:50%;transform:translate(-50%,-50%)}:host ::ng-deep .bottom-bar .mat-mdc-icon-button .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .bottom-bar .mat-mdc-icon-button:disabled{opacity:.35}:host ::ng-deep .bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}.group-bottom-bar{display:flex;align-items:center;flex:0 0 auto;background:var(--jqt-footer-bg);border-top:1px solid var(--jqt-border-color);border-right:1px solid var(--jqt-border-color);border-bottom:1px solid var(--jqt-border-color);border-left:1px solid var(--jqt-border-color);border-radius:0 0 8px 8px}.group-bottom-bar-container{display:flex;align-items:center;justify-content:space-between;flex-wrap:nowrap;height:var(--actual-header-height, 56px);padding:0 16px;gap:16px;width:100%;box-sizing:border-box}.group-bar-separator{width:1px;height:20px;background:#9ca3af;flex-shrink:0;margin:0 4px}.group-bottom-bar-left{display:flex;align-items:center;gap:8px;flex-shrink:0}.group-sort-controls{display:flex;align-items:center;gap:2px}.group-sort-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap;margin-right:2px}.group-sort-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--jqt-footer-icon-color);cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.group-sort-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.group-sort-btn:hover{background:#0000000a}.group-sort-btn.active{color:var(--jqt-primary-color, #1976d2);border-color:var(--jqt-primary-color, #1976d2);background:#1976d214}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size{display:flex;align-items:center;gap:8px}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-label{font-size:12px;color:var(--jqt-footer-text-color);white-space:nowrap}:host ::ng-deep .group-bottom-bar .mat-mdc-paginator-page-size-select{width:72px;font-size:12px}:host ::ng-deep .group-bottom-bar .mat-mdc-text-field-wrapper{padding:0 8px}:host ::ng-deep .group-bottom-bar .mdc-text-field--outlined{height:28px}:host ::ng-deep .group-bottom-bar .mat-mdc-form-field-infix{padding-top:0;padding-bottom:0;min-height:0;height:28px;display:flex;align-items:center}:host ::ng-deep .group-bottom-bar .mat-mdc-select-value-text{font-size:12px;color:var(--jqt-text-color)}:host ::ng-deep .group-bottom-bar .mdc-notched-outline__leading,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__notch,:host ::ng-deep .group-bottom-bar .mdc-notched-outline__trailing{border-color:var(--jqt-border-color)}:host ::ng-deep .group-bottom-bar .mat-mdc-select-arrow{color:var(--jqt-footer-text-color)}.group-reset-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border:1px solid var(--jqt-border-color);border-radius:8px;background:var(--jqt-surface-color);color:var(--jqt-text-secondary);font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;white-space:nowrap;flex-shrink:0}.group-reset-btn:hover{background:var(--jqt-danger-hover-bg);color:var(--jqt-danger-color);border-color:var(--jqt-danger-border)}.group-reset-icon{width:14px;height:14px;flex-shrink:0}::ng-deep .mat-mdc-paginator-select-page-size .mat-pseudo-checkbox{display:none!important}::ng-deep .group-page-size-panel{min-width:90px!important}::ng-deep .group-page-size-panel .mat-mdc-option{justify-content:center;min-height:40px}::ng-deep .group-page-size-panel .mdc-list-item__primary-text{text-align:center;width:100%}@media (max-width: 960px){.table-layout{grid-template-columns:1fr}}::ng-deep .view-menu-panel .mat-mdc-menu-panel{min-width:220px!important;overflow:visible!important}::ng-deep .view-menu-panel .mat-mdc-menu-content{padding:4px 0!important}::ng-deep .view-submenu-panel .mat-mdc-menu-panel{min-width:200px!important}::ng-deep .view-submenu-panel .mat-mdc-menu-content{padding:0!important}::ng-deep .view-menu-panel .view-menu-sub-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}::ng-deep .view-menu-panel .view-menu-sub-trigger .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;gap:0;overflow:hidden}::ng-deep .view-menu-sub-label{font-size:13px;font-weight:500;color:var(--jqt-text-color);flex:0 0 auto;white-space:nowrap;padding-right:8px}::ng-deep .view-menu-sub-value{font-size:12px;color:var(--jqt-text-secondary);flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}::ng-deep .view-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}::ng-deep .view-submenu .view-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:var(--jqt-text-color);cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}::ng-deep .view-submenu .view-menu-item:hover{background:var(--jqt-row-hover-bg)}::ng-deep .view-submenu .view-menu-item.active{font-weight:600}::ng-deep .view-submenu .view-menu-item:disabled{opacity:.4;cursor:default}::ng-deep .view-menu-col-icon{flex-shrink:0;font-size:14px!important;width:14px!important;height:14px!important;color:var(--jqt-text-muted)}::ng-deep .view-menu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:var(--jqt-text-color)}::ng-deep .view-menu-separator{border:none;border-top:1px solid var(--jqt-border-color);margin:4px 0}.lazy-skeleton{display:block;height:12px;width:70%;border-radius:4px;background:linear-gradient(90deg,var(--jqt-border-color) 25%,var(--jqt-surface-alt-color) 50%,var(--jqt-border-color) 75%);background-size:200% 100%;animation:lazy-shimmer 1.4s ease-in-out infinite}.group-lazy-key-skeleton{flex:1 1 auto;min-width:80px;height:13px;border-radius:4px}@keyframes lazy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.lazy-error-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:1px solid #fca5a5;border-radius:4px;padding:2px 6px;cursor:pointer;color:#ef4444;font-size:12px;opacity:.85;transition:opacity .15s}.lazy-error-btn:hover{opacity:1;background:#fef2f2}.lazy-error-icon{font-size:12px}.lazy-error-label{font-size:11px;font-weight:500}::ng-deep .lazy-menu-spinner{display:inline-block;margin-left:auto;font-size:13px;color:var(--jqt-text-secondary);animation:lazy-spin 1s linear infinite}::ng-deep .lazy-menu-error{display:inline-block;margin-left:auto;font-size:13px;color:#ef4444}@keyframes lazy-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
1049
1348
|
}], propDecorators: { config: [{
|
|
1050
1349
|
type: Input
|
|
1051
1350
|
}], dataSource: [{
|
|
@@ -1056,6 +1355,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1056
1355
|
type: Input
|
|
1057
1356
|
}], columnsConfig: [{
|
|
1058
1357
|
type: Input
|
|
1358
|
+
}], view: [{
|
|
1359
|
+
type: Input
|
|
1059
1360
|
}], columnLabels: [{
|
|
1060
1361
|
type: Input
|
|
1061
1362
|
}], isLoading: [{
|
|
@@ -1070,6 +1371,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1070
1371
|
type: Output
|
|
1071
1372
|
}], rowSelected: [{
|
|
1072
1373
|
type: Output
|
|
1374
|
+
}], sortChange: [{
|
|
1375
|
+
type: Output
|
|
1376
|
+
}], pageChange: [{
|
|
1377
|
+
type: Output
|
|
1378
|
+
}], searchChange: [{
|
|
1379
|
+
type: Output
|
|
1380
|
+
}], groupByChange: [{
|
|
1381
|
+
type: Output
|
|
1382
|
+
}], columnsChange: [{
|
|
1383
|
+
type: Output
|
|
1073
1384
|
}], paginator: [{
|
|
1074
1385
|
type: ViewChild,
|
|
1075
1386
|
args: [MatPaginator]
|
|
@@ -1089,4 +1400,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1089
1400
|
type: ContentChildren,
|
|
1090
1401
|
args: [JqtCellDefDirective]
|
|
1091
1402
|
}] } });
|
|
1092
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktdGFibGUvc3JjL2xpYi9jb21wb25lbnQvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktdGFibGUvc3JjL2xpYi9jb21wb25lbnQvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQXdCLE1BQU0sRUFBRSxTQUFTLEVBQThCLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvTyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxF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RyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFFRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBR0gsU0FBUztzQkFEWixTQUFTO3VCQUFDLFlBQVk7Z0JBVUgsSUFBSTtzQkFBdkIsU0FBUzt1QkFBQyxPQUFPO2dCQUNZLGtCQUFrQjtzQkFBL0MsU0FBUzt1QkFBQyxpQkFBaUI7Z0JBQ0ksYUFBYTtzQkFBNUMsU0FBUzt1QkFBQyxtQkFBbUI7Z0JBQ0EsZUFBZTtzQkFBNUMsU0FBUzt1QkFBQyxpQkFBaUI7Z0JBQ1UsU0FBUztzQkFBOUMsZUFBZTt1QkFBQyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbnRlbnRDaGlsZHJlbiwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT3V0cHV0LCBRdWVyeUxpc3QsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdE1lbnVNb2R1bGUsIE1hdE1lbnVUcmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbWVudSc7XG5pbXBvcnQgeyBNYXRQYWdpbmF0b3IsIE1hdFBhZ2luYXRvckludGwsIE1hdFBhZ2luYXRvck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3BhZ2luYXRvcic7XG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U29ydCwgTWF0U29ydE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xuaW1wb3J0IHsgTWF0VGFibGVEYXRhU291cmNlLCBNYXRUYWJsZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYmxlJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVGFibGVDb2x1bW5Qcm92aWRlciwgVGFibGVQcm92aWRlciB9IGZyb20gJy4uL2pxdWVyeS10YWJsZS5tb2RlbCc7XG5pbXBvcnQgeyBKcXRDZWxsRGVmRGlyZWN0aXZlIH0gZnJvbSAnLi4vZGlyZWN0aXZlL2pxdC1jZWxsLWRlZi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgU2xpY2VQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc2xpY2UtcGFuZWwvc2xpY2UtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IGdldEZyZW5jaFBhZ2luYXRvckludGwsIGh1bWFuaXplS2V5LCBub3JtYWxpemVDZWxsVmFsdWUgfSBmcm9tICcuL3RhYmxlLnV0aWxzJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnanF1ZXJ5LXRhYmxlJyxcbiAgaW1wb3J0czogWyBDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBNYXRUYWJsZU1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlLCBNYXRQYWdpbmF0b3JNb2R1bGUsIE1hdFNvcnRNb2R1bGUsIE1hdE1lbnVNb2R1bGUsIE1hdEljb25Nb2R1bGUsIE1hdFNlbGVjdE1vZHVsZSwgU2xpY2VQYW5lbENvbXBvbmVudCBdLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90YWJsZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBNYXRQYWdpbmF0b3JJbnRsLCB1c2VGYWN0b3J5OiBnZXRGcmVuY2hQYWdpbmF0b3JJbnRsIH1dLFxufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUNvbXBvbmVudDxUID0gYW55PiBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgY29uZmlnPzogVGFibGVQcm92aWRlcjxUPjtcblxuICBASW5wdXQoKSBkYXRhU291cmNlPzogVFtdIHwgeyBkYXRhOiBUW10gfTtcbiAgQElucHV0KCkgZGF0YT86IFRbXTtcbiAgQElucHV0KCkgZGlzcGxheWVkQ29sdW1ucz86IHN0cmluZ1tdO1xuICBASW5wdXQoKSBjb2x1bW5zQ29uZmlnPzogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdO1xuXG4gIEBJbnB1dCgpIGNvbHVtbkxhYmVscz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIEBJbnB1dCgpIGlzTG9hZGluZyA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBhZGRSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5BZGRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVDb2x1bW5Qcm92aWRlcjxUPj4oKTtcbiAgQE91dHB1dCgpIGNvbHVtblJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4+KCk7XG4gIEBPdXRwdXQoKSBjYXRlZ29yeVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSByb3dTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcblxuICBAVmlld0NoaWxkKE1hdFBhZ2luYXRvcilcbiAgc2V0IHBhZ2luYXRvcih2YWx1ZTogTWF0UGFnaW5hdG9yIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fcGFnaW5hdG9yID0gdmFsdWU7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLmF0dGFjaFBhZ2luYXRvcigpO1xuICAgICAgdGhpcy5fc2NoZWR1bGVSZW5kZXIoKTtcbiAgICB9XG4gIH1cbiAgZ2V0IHBhZ2luYXRvcigpOiBNYXRQYWdpbmF0b3IgfCB1bmRlZmluZWQgeyByZXR1cm4gdGhpcy5fcGFnaW5hdG9yOyB9XG4gIHByaXZhdGUgX3BhZ2luYXRvcj86IE1hdFBhZ2luYXRvcjtcbiAgQFZpZXdDaGlsZChNYXRTb3J0KSBzb3J0PzogTWF0U29ydDtcbiAgQFZpZXdDaGlsZCgndGFibGVCb2R5U2Nyb2xsJykgdGFibGVCb2R5U2Nyb2xsUmVmPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoU2xpY2VQYW5lbENvbXBvbmVudCkgc2xpY2VQYW5lbFJlZj86IFNsaWNlUGFuZWxDb21wb25lbnQ8VD47XG4gIEBWaWV3Q2hpbGQoJ3ZpZXdNZW51VHJpZ2dlcicpIHZpZXdNZW51VHJpZ2dlcj86IE1hdE1lbnVUcmlnZ2VyO1xuICBAQ29udGVudENoaWxkcmVuKEpxdENlbGxEZWZEaXJlY3RpdmUpIF9jZWxsRGVmcyE6IFF1ZXJ5TGlzdDxKcXRDZWxsRGVmRGlyZWN0aXZlPjtcblxuICByZW5kZXJlZENvbHVtbnM6IHN0cmluZ1tdID0gW107XG4gIHRhYmxlRGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2U8YW55PihbXSk7XG4gIGFjdGl2ZUNvbHVtbnM6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSA9IFtdO1xuXG4gIGFjdGl2ZVNsaWNlRmlsdGVyOiAocm93OiBUKSA9PiBib29sZWFuID0gKCkgPT4gdHJ1ZTtcblxuICAvLyBQcm9wcmnDqXTDqXMgc3RhYmxlcyBwb3VyIGxlcyBiaW5kaW5ncyBkdSB0ZW1wbGF0ZSAoY29udHJlIGVycmV1ciBORzAxMDApXG4gIF9zbGljZUNvbmZpZ3M6IGFueVtdID0gW107XG4gIF9zbGljZUNvbHVtbnM6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSA9IFtdO1xuICBfc2xpY2VEYXRhOiBUW10gPSBbXTtcbiAgX3NsaWNlU2hvd1RvZ2dsZSA9IHRydWU7XG4gIF9zdGF0aWNTbGljZXNGb3JNZW51OiBBcnJheTx7IGtleTogc3RyaW5nOyB0aXRsZTogc3RyaW5nOyBpY29uPzogc3RyaW5nIH0+ID0gW107XG4gIF9hY3RpdmVEeW5hbWljU2xpY2VDb2x1bW5zOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10gPSBbXTtcbiAgX2F2YWlsYWJsZUNvbHVtbnNGb3JEeW5hbWljU2xpY2U6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSA9IFtdO1xuICBfYWxsRHluYW1pY1NsaWNlQ29sdW1uczogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdID0gW107XG4gIF9hY3RpdmVTbGljZUJ5TGFiZWwgPSAnQXVjdW4nO1xuXG4gIHNlYXJjaFF1ZXJ5ID0gJyc7XG4gIGFjdGl2ZUdyb3VwQnlLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBfbWF0U29ydEFjdGl2ZSA9ICcnO1xuICBfbWF0U29ydERpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycgfCAnJyA9ICcnO1xuICBwcml2YXRlIF9jb2xsYXBzZWRHcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBfYWN0aXZlU29ydDogeyBhY3RpdmU6IHN0cmluZzsgZGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyB8ICcnIH0gPSB7IGFjdGl2ZTogJycsIGRpcmVjdGlvbjogJycgfTtcbiAgcHJpdmF0ZSBfc29ydFN1YnNjcmliZWQ6IE1hdFNvcnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIF9kZWZhdWx0R3JvdXBDb2xsYXBzZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfZ3JvdXBQYWdlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgX3RvdGFsRmlsdGVyZWRDb3VudCA9IDA7XG5cbiAgX2xhenlDb2x1bW5TdGF0dXMgPSBuZXcgTWFwPHN0cmluZywgJ2lkbGUnIHwgJ2xvYWRpbmcnIHwgJ2xvYWRlZCcgfCAnZXJyb3InPigpO1xuICBfbGF6eUNvbHVtbkRhdGEgPSBuZXcgTWFwPHN0cmluZywgTWFwPGFueSwgYW55Pj4oKTtcbiAgcHJpdmF0ZSBfbGF6eUZldGNoQ2FuY2VscyA9IG5ldyBNYXA8c3RyaW5nLCBTdWJqZWN0PHZvaWQ+PigpO1xuICBwcml2YXRlIF9jZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIF9lbCA9IGluamVjdChFbGVtZW50UmVmPEhUTUxFbGVtZW50Pik7XG5cbiAgaXNHcm91cEhlYWRlciA9IChfOiBudW1iZXIsIHJvdzogYW55KTogYm9vbGVhbiA9PiByb3cuX19ncm91cEhlYWRlciA9PT0gdHJ1ZTtcblxuICAvLyDilIDilIAgTGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHBhZ2VTaXplID0gNTtcbiAgcGFnZVNpemVPcHRpb25zOiBudW1iZXJbXSA9IFs1LCAxMCwgMjBdO1xuICBwYWdlU2l6ZU9wdGlvbnNHcm91cEJ5OiBudW1iZXJbXSA9IFs1LCAxMCwgMjBdO1xuICBncm91cFBhZ2VTaXplID0gNTtcbiAgZ3JvdXBTb3J0T3JkZXI6ICdhc2MnIHwgJ2Rlc2MnID0gJ2FzYyc7XG5cbiAgZHJhZ2dlZENvbHVtbktleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGRyYWdPdmVyQ29sdW1uS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHVzZXJDdXN0b21pemVkQ29sdW1ucyA9IGZhbHNlO1xuICBwcml2YXRlIHJlc29sdmVkQ29uZmlnOiBUYWJsZVByb3ZpZGVyPFQ+ID0geyBjb2x1bW5zOiBbXSB9O1xuICBwcml2YXRlIF9jb2x1bW5NYXA6IE1hcDxzdHJpbmcsIFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIF9yZXNvbHZlZERhdGE6IFRbXSA9IFtdO1xuICBwcml2YXRlIF9wcmVzZXJ2ZVBhZ2VJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2luaXRpYWxTZWFyY2hBcHBsaWVkID0gZmFsc2U7XG5cbiAgLy8gU2V1aWwgYXUtZGVsw6AgZHVxdWVsIGxlIHJlbmR1IGdyb3Vww6kgZXN0IGJsb3F1w6kgcG91ciBwcm90w6lnZXIgbGUgbmF2aWdhdGV1clxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBNQVhfR1JPVVBfQ09VTlQgPSA1MDA7XG5cbiAgLy8g4pSA4pSAIE9wdGltaXNhdGlvbiBwZXJmb3JtYW5jZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBfYWxsRmlsdGVyZWRSb3dzOiBUW10gPSBbXTtcbiAgcHJpdmF0ZSBfcGFnaW5hdG9yU3Vic2NyaWJlZDogTWF0UGFnaW5hdG9yIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gQ2FjaGUgZ3JvdXBCeSA6IGludmFsaWRlIHVuaXF1ZW1lbnQgcXVhbmQgbGVzIGRvbm7DqWVzL3RyaS9ncm91cEtleSBjaGFuZ2VudFxuICBwcml2YXRlIF9ncm91cENhY2hlUm93czogVFtdIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2dyb3VwQ2FjaGVLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9ncm91cENhY2hlU29ydE9yZGVyOiAnYXNjJyB8ICdkZXNjJyA9ICdhc2MnO1xuICBwcml2YXRlIF9ncm91cENhY2hlU29ydEFjdGl2ZTogc3RyaW5nID0gJyc7XG4gIHByaXZhdGUgX2dyb3VwQ2FjaGVTb3J0RGlyOiBzdHJpbmcgPSAnJztcbiAgcHJpdmF0ZSBfZ3JvdXBDYWNoZU9yZGVyOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIF9ncm91cENhY2hlTWFwOiBNYXA8c3RyaW5nLCBUW10+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIF9wZW5kaW5nUmVuZGVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuXG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IGRhdGFDaGFuZ2VkID0gISEoY2hhbmdlc1snY29uZmlnJ10gfHwgY2hhbmdlc1snZGF0YSddIHx8IGNoYW5nZXNbJ2RhdGFTb3VyY2UnXSk7XG4gICAgaWYgKGRhdGFDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9sYXp5RmV0Y2hDYW5jZWxzLmZvckVhY2gocyA9PiB7IHMubmV4dCgpOyBzLmNvbXBsZXRlKCk7IH0pO1xuICAgICAgdGhpcy5fbGF6eUZldGNoQ2FuY2Vscy5jbGVhcigpO1xuICAgICAgdGhpcy5fbGF6eUNvbHVtblN0YXR1cyA9IG5ldyBNYXAoKTtcbiAgICAgIHRoaXMuX2xhenlDb2x1bW5EYXRhID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snY29uZmlnJ10gJiYgIXRoaXMuX2luaXRpYWxTZWFyY2hBcHBsaWVkKSB7XG4gICAgICBjb25zdCBpbml0aWFsID0gdGhpcy5jb25maWc/LnNlYXJjaD8uaW5pdGlhbFF1ZXJ5O1xuICAgICAgaWYgKGluaXRpYWwgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnNlYXJjaFF1ZXJ5ID0gaW5pdGlhbDtcbiAgICAgICAgdGhpcy5faW5pdGlhbFNlYXJjaEFwcGxpZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICBpZiAoZGF0YUNoYW5nZWQpIHtcbiAgICAgIHRoaXMuYWN0aXZlQ29sdW1ucy5maWx0ZXIoYyA9PiBjLmxhenkpLmZvckVhY2goYyA9PiB0aGlzLnRyaWdnZXJMYXp5RmV0Y2goYykpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmF0dGFjaFBhZ2luYXRvcigpO1xuICAgIHRoaXMuYXR0YWNoU29ydCgpO1xuICAgIHRoaXMuX21lYXN1cmVIZWFkZXJIZWlnaHQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nUmVuZGVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5fcGVuZGluZ1JlbmRlcik7XG4gICAgfVxuICAgIHRoaXMuX2Rlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLl9kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfbWVhc3VyZUhlYWRlckhlaWdodCgpOiB2b2lkIHtcbiAgICBjb25zdCBoZWFkZXJSb3cgPSB0aGlzLl9lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3RyLm1hdC1tZGMtaGVhZGVyLXJvdycpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmIChoZWFkZXJSb3cpIHtcbiAgICAgIGNvbnN0IGggPSBoZWFkZXJSb3cuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuICAgICAgaWYgKGggPiAwKSB7XG4gICAgICAgIHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tYWN0dWFsLWhlYWRlci1oZWlnaHQnLCBoICsgJ3B4Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8g4pSA4pSAIEdldHRlcnMgZCdhZmZpY2hhZ2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0IHRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcudGl0bGUgPz8gJyc7XG4gIH1cblxuICBnZXQgc2hvd1RpdGxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMucmVzb2x2ZWRDb25maWcudGl0bGU7XG4gIH1cblxuICBnZXQgdmlzaWJsZUNvbHVtbnMoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVDb2x1bW5zO1xuICB9XG5cbiAgZ2V0IHNob3dTZWFyY2hCYXIoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLnNlYXJjaD8uZW5hYmxlZCA9PT0gdHJ1ZTsgfVxuICBnZXQgc2hvd1ZpZXdCdXR0b24oKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLnZpZXc/LmVuYWJsZWQgPT09IHRydWU7IH1cbiAgZ2V0IHNob3dUb29sYmFyKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5zaG93U2VhcmNoQmFyIHx8IHRoaXMuc2hvd1ZpZXdCdXR0b247IH1cbiAgZ2V0IHNob3dGaWVsZHMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNob3dWaWV3QnV0dG9uOyB9XG4gIGdldCBzaG93R3JvdXBCeVNlY3Rpb24oKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNob3dWaWV3QnV0dG9uICYmIHRoaXMuZ3JvdXBCeUNvbHVtbnMubGVuZ3RoID4gMDsgfVxuXG4gIGdldCBmaWx0ZXJlZFJvd0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlR3JvdXBCeUtleSA/IHRoaXMuX3RvdGFsRmlsdGVyZWRDb3VudCA6IHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGg7XG4gIH1cblxuICBnZXQgYWN0aXZlR3JvdXBCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmFjdGl2ZUdyb3VwQnlLZXkpIHJldHVybiAnQXVjdW4nO1xuICAgIGNvbnN0IGNvbCA9IHRoaXMuZ3JvdXBCeUNvbHVtbnMuZmluZCgoYykgPT4gYy5rZXkgPT09IHRoaXMuYWN0aXZlR3JvdXBCeUtleSk7XG4gICAgcmV0dXJuIGNvbD8uaGVhZGVyIHx8IHRoaXMuYWN0aXZlR3JvdXBCeUtleTtcbiAgfVxuXG4gIGdldCB0b3RhbENvbHVtbkNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIG5ldyBTZXQoKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyB8fCBbXSkubWFwKChjKSA9PiBjLmtleSkpLnNpemU7XG4gIH1cblxuICBnZXQgYWN0aXZlU2xpY2VCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZVNsaWNlQnlMYWJlbDtcbiAgfVxuXG4gIGdldCBhY3RpdmVEeW5hbWljU2xpY2VDb2x1bW5zKCk6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUR5bmFtaWNTbGljZUNvbHVtbnM7XG4gIH1cblxuICByZW1vdmVEeW5hbWljU2xpY2VCeUtleShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2xpY2VQYW5lbFJlZj8ucmVtb3ZlRHluYW1pY1NsaWNlQnlLZXkoa2V5KTtcbiAgfVxuXG4gIGdldCBncm91cEJ5Q29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyB8fCBbXTtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcmV0dXJuIGFsbC5maWx0ZXIoKGMpID0+IHtcbiAgICAgIGlmIChjLmdyb3VwYWJsZSA9PT0gZmFsc2UgfHwgc2Vlbi5oYXMoYy5rZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoIWMuaGVhZGVyICYmIGMuZ3JvdXBhYmxlICE9PSB0cnVlKSByZXR1cm4gZmFsc2U7XG4gICAgICBzZWVuLmFkZChjLmtleSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbExhYmVsKGNvbDogeyBrZXk6IHN0cmluZzsgaGVhZGVyPzogc3RyaW5nIH0pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb2wuaGVhZGVyIHx8IGh1bWFuaXplS2V5KGNvbC5rZXkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIEFjdGlvbnMgdXRpbGlzYXRldXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgb25TZWFyY2hDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSAwO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICAgIHRoaXMucGFnaW5hdG9yPy5maXJzdFBhZ2UoKTtcbiAgfVxuXG4gIG9uR3JvdXBCeUNoYW5nZShrZXk6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUdyb3VwQnlLZXkgPSBrZXk7XG4gICAgdGhpcy5fZGVmYXVsdEdyb3VwQ29sbGFwc2VkID0ga2V5ICE9PSBudWxsO1xuICAgIHRoaXMuX2NvbGxhcHNlZEdyb3Vwcy5jbGVhcigpO1xuICAgIHRoaXMuX2dyb3VwUGFnZXMuY2xlYXIoKTtcbiAgICB0aGlzLmdyb3VwUGFnZVNpemUgPSB0aGlzLnJlc29sdmVEZWZhdWx0R3JvdXBQYWdlU2l6ZSgpO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICAgIHRoaXMucGFnaW5hdG9yPy5maXJzdFBhZ2UoKTtcbiAgICBpZiAoa2V5KSB7XG4gICAgICB0aGlzLnZpZXdNZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gICAgICBjb25zdCBjb2xEZWYgPSAodGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zIHx8IFtdKS5maW5kKGMgPT4gYy5rZXkgPT09IGtleSk7XG4gICAgICBpZiAoY29sRGVmPy5sYXp5ICYmIHRoaXMuX2xhenlDb2x1bW5TdGF0dXMuZ2V0KGtleSkgIT09ICdsb2FkZWQnKSB7XG4gICAgICAgIHRoaXMudHJpZ2dlckxhenlGZXRjaChjb2xEZWYpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy50YWJsZUJvZHlTY3JvbGxSZWY/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuXG4gIG9uR3JvdXBQYWdlU2l6ZUNoYW5nZShzaXplOiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmdyb3VwUGFnZVNpemUgPSBOdW1iZXIoc2l6ZSk7XG4gICAgdGhpcy5fZ3JvdXBQYWdlcy5jbGVhcigpO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICB9XG5cbiAgb25Hcm91cFNvcnRUb2dnbGUoZGlyOiAnYXNjJyB8ICdkZXNjJyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmdyb3VwU29ydE9yZGVyID09PSBkaXIpIHJldHVybjtcbiAgICB0aGlzLmdyb3VwU29ydE9yZGVyID0gZGlyO1xuICAgIHRoaXMuX2dyb3VwUGFnZXMuY2xlYXIoKTtcbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICBjb25zdCBvcGVuR3JvdXAgPSB0aGlzLl9kZWZhdWx0R3JvdXBDb2xsYXBzZWRcbiAgICAgID8gKHRoaXMuX2NvbGxhcHNlZEdyb3Vwcy5zaXplID09PSAxID8gWy4uLnRoaXMuX2NvbGxhcHNlZEdyb3Vwc11bMF0gOiBudWxsKVxuICAgICAgOiBudWxsO1xuICAgIGlmIChvcGVuR3JvdXApIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxUb0dyb3VwSGVhZGVyKG9wZW5Hcm91cCksIDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBMYXp5IGxvYWRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0TGF6eUNvbHVtblN0YXR1cyhrZXk6IHN0cmluZyk6ICdpZGxlJyB8ICdsb2FkaW5nJyB8ICdsb2FkZWQnIHwgJ2Vycm9yJyB7XG4gICAgcmV0dXJuIHRoaXMuX2xhenlDb2x1bW5TdGF0dXMuZ2V0KGtleSkgPz8gJ2lkbGUnO1xuICB9XG5cbiAgZ2V0TGF6eVJlbmRlclR5cGUocm93VmFsdWU6IGFueSk6ICdsb2FkaW5nJyB8ICdlcnJvcicgfCAndmFsdWUnIHtcbiAgICBpZiAocm93VmFsdWUgPT09ICdfX2xhenlfbG9hZGluZ19fJykgcmV0dXJuICdsb2FkaW5nJztcbiAgICBpZiAocm93VmFsdWUgPT09ICdfX2xhenlfZXJyb3JfXycpIHJldHVybiAnZXJyb3InO1xuICAgIHJldHVybiAndmFsdWUnO1xuICB9XG5cbiAgcmV0cnlMYXp5Q29sdW1uKGNvbHVtbjogVGFibGVDb2x1bW5Qcm92aWRlcjxUPik6IHZvaWQge1xuICAgIGNvbnN0IGsgPSBjb2x1bW4ua2V5O1xuICAgIGNvbnN0IHByZXYgPSB0aGlzLl9sYXp5RmV0Y2hDYW5jZWxzLmdldChrKTtcbiAgICBpZiAocHJldikgeyBwcmV2Lm5leHQoKTsgcHJldi5jb21wbGV0ZSgpOyB9XG4gICAgdGhpcy5fbGF6eUZldGNoQ2FuY2Vscy5kZWxldGUoayk7XG4gICAgY29uc3QgbmV3U3RhdHVzID0gbmV3IE1hcCh0aGlzLl9sYXp5Q29sdW1uU3RhdHVzKTtcbiAgICBuZXdTdGF0dXMuZGVsZXRlKGspO1xuICAgIHRoaXMuX2xhenlDb2x1bW5TdGF0dXMgPSBuZXdTdGF0dXM7XG4gICAgY29uc3QgbmV3RGF0YSA9IG5ldyBNYXAodGhpcy5fbGF6eUNvbHVtbkRhdGEpO1xuICAgIG5ld0RhdGEuZGVsZXRlKGspO1xuICAgIHRoaXMuX2xhenlDb2x1bW5EYXRhID0gbmV3RGF0YTtcbiAgICB0aGlzLnRyaWdnZXJMYXp5RmV0Y2goY29sdW1uKTtcbiAgfVxuXG4gIHRyaWdnZXJMYXp5RmV0Y2goY29sdW1uOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+KTogdm9pZCB7XG4gICAgaWYgKCFjb2x1bW4ubGF6eSkgcmV0dXJuO1xuICAgIGNvbnN0IGsgPSBjb2x1bW4ua2V5O1xuICAgIGlmICh0aGlzLl9sYXp5Q29sdW1uU3RhdHVzLmdldChrKSA9PT0gJ2xvYWRpbmcnKSByZXR1cm47XG5cbiAgICBjb25zdCBwcmV2ID0gdGhpcy5fbGF6eUZldGNoQ2FuY2Vscy5nZXQoayk7XG4gICAgaWYgKHByZXYpIHsgcHJldi5uZXh0KCk7IHByZXYuY29tcGxldGUoKTsgfVxuICAgIGNvbnN0IGNhbmNlbCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAgIHRoaXMuX2xhenlGZXRjaENhbmNlbHMuc2V0KGssIGNhbmNlbCQpO1xuXG4gICAgY29uc3QgbmV3U3RhdHVzMSA9IG5ldyBNYXAodGhpcy5fbGF6eUNvbHVtblN0YXR1cyk7XG4gICAgbmV3U3RhdHVzMS5zZXQoaywgJ2xvYWRpbmcnKTtcbiAgICB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzID0gbmV3U3RhdHVzMTtcbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcblxuICAgIGNvbHVtbi5sYXp5LmZldGNoRm4oKS5waXBlKFxuICAgICAgdGFrZSgxKSxcbiAgICAgIHRha2VVbnRpbChjYW5jZWwkKSxcbiAgICApLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAodmFsdWVzOiBhbnlbXSkgPT4ge1xuICAgICAgICBjb25zdCByb3dNYXAgPSBuZXcgTWFwPGFueSwgYW55PigpO1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5fcmVzb2x2ZWREYXRhO1xuICAgICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUsIGkpID0+IHtcbiAgICAgICAgICBpZiAoaSA8IGRhdGEubGVuZ3RoKSByb3dNYXAuc2V0KGRhdGFbaV0sIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgTWFwKHRoaXMuX2xhenlDb2x1bW5EYXRhKTtcbiAgICAgICAgbmV3RGF0YS5zZXQoaywgcm93TWFwKTtcbiAgICAgICAgdGhpcy5fbGF6eUNvbHVtbkRhdGEgPSBuZXdEYXRhO1xuICAgICAgICBjb25zdCBuZXdTdGF0dXMyID0gbmV3IE1hcCh0aGlzLl9sYXp5Q29sdW1uU3RhdHVzKTtcbiAgICAgICAgbmV3U3RhdHVzMi5zZXQoaywgJ2xvYWRlZCcpO1xuICAgICAgICB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzID0gbmV3U3RhdHVzMjtcbiAgICAgICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG4gICAgICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICBjb25zdCBuZXdTdGF0dXNFcnIgPSBuZXcgTWFwKHRoaXMuX2xhenlDb2x1bW5TdGF0dXMpO1xuICAgICAgICBuZXdTdGF0dXNFcnIuc2V0KGssICdlcnJvcicpO1xuICAgICAgICB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzID0gbmV3U3RhdHVzRXJyO1xuICAgICAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICAgICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBHcm91cGVtZW50IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHRvZ2dsZUdyb3VwQ29sbGFwc2UoZ3JvdXBLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jb2xsYXBzZWRHcm91cHMuaGFzKGdyb3VwS2V5KSkge1xuICAgICAgdGhpcy5fY29sbGFwc2VkR3JvdXBzLmRlbGV0ZShncm91cEtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2NvbGxhcHNlZEdyb3Vwcy5jbGVhcigpO1xuICAgICAgdGhpcy5fY29sbGFwc2VkR3JvdXBzLmFkZChncm91cEtleSk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2Nyb2xsVG9Hcm91cEhlYWRlcihncm91cEtleSksIDApO1xuICAgIH1cbiAgICAvLyBDb3VydC1jaXJjdWl0IGRlIHJlZnJlc2hWaWV3TW9kZWwgOiBsYSBkYXRhIGV0IGxlcyBjb2xvbm5lcyBuJ29udCBwYXMgY2hhbmfDqSxcbiAgICAvLyBzZXVsIGwnw6l0YXQgY29sbGFwc2VkIGNoYW5nZSDigJQgcmVwcm9qZWN0aW9uIGRpcmVjdGUgc2FucyByZWJ1aWxkIGNvbXBsZXRcbiAgICB0aGlzLl9wcm9qZWN0Q3VycmVudFBhZ2UoKTtcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbFRvR3JvdXBIZWFkZXIoZ3JvdXBLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMudGFibGVCb2R5U2Nyb2xsUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghY29udGFpbmVyKSByZXR1cm47XG4gICAgY29uc3Qgcm93ID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KGB0cltkYXRhLWdyb3VwLWtleT1cIiR7Q1NTLmVzY2FwZShncm91cEtleSl9XCJdYCk7XG4gICAgaWYgKCFyb3cpIHJldHVybjtcbiAgICBjb25zdCBoZWFkZXJIZWlnaHQgPSBwYXJzZUZsb2F0KFxuICAgICAgdGhpcy5fZWwubmF0aXZlRWxlbWVudC5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCctLWFjdHVhbC1oZWFkZXItaGVpZ2h0JykgfHwgJzU2J1xuICAgICkgfHwgNTY7XG4gICAgY29uc3QgY29udGFpbmVyUmVjdCA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCByb3dSZWN0ID0gcm93LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGN1cnJlbnRTY3JvbGxUb3AgPSBjb250YWluZXIuc2Nyb2xsVG9wO1xuICAgIGNvbnN0IHRhcmdldFNjcm9sbFRvcCA9IGN1cnJlbnRTY3JvbGxUb3AgKyAocm93UmVjdC50b3AgLSBjb250YWluZXJSZWN0LnRvcCkgLSBoZWFkZXJIZWlnaHQ7XG4gICAgY29udGFpbmVyLnNjcm9sbFRvKHsgdG9wOiB0YXJnZXRTY3JvbGxUb3AsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgfVxuXG4gIGlzR3JvdXBDb2xsYXBzZWQoZ3JvdXBLZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9kZWZhdWx0R3JvdXBDb2xsYXBzZWQgPyAhdGhpcy5fY29sbGFwc2VkR3JvdXBzLmhhcyhncm91cEtleSkgOiB0aGlzLl9jb2xsYXBzZWRHcm91cHMuaGFzKGdyb3VwS2V5KTtcbiAgfVxuXG4gIGdyb3VwUGFnZUJhY2soZ3JvdXBLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLl9ncm91cFBhZ2VzLmdldChncm91cEtleSkgPz8gMDtcbiAgICBpZiAoY3VycmVudCA+IDApIHtcbiAgICAgIHRoaXMuX2dyb3VwUGFnZXMuc2V0KGdyb3VwS2V5LCBjdXJyZW50IC0gMSk7XG4gICAgICB0aGlzLl9wcm9qZWN0Q3VycmVudFBhZ2UoKTtcbiAgICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBncm91cFBhZ2VGb3J3YXJkKGdyb3VwS2V5OiBzdHJpbmcsIHRvdGFsQ291bnQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG1heFBhZ2UgPSBNYXRoLmNlaWwodG90YWxDb3VudCAvIHRoaXMuZ3JvdXBQYWdlU2l6ZSkgLSAxO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLl9ncm91cFBhZ2VzLmdldChncm91cEtleSkgPz8gMDtcbiAgICBpZiAoY3VycmVudCA8IG1heFBhZ2UpIHtcbiAgICAgIHRoaXMuX2dyb3VwUGFnZXMuc2V0KGdyb3VwS2V5LCBjdXJyZW50ICsgMSk7XG4gICAgICB0aGlzLl9wcm9qZWN0Q3VycmVudFBhZ2UoKTtcbiAgICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgQ29sb25uZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0IGhhc0FkZGFibGVDb2x1bW5zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm1lbnVCYXNlQ29sdW1ucy5sZW5ndGggPiAwIHx8IHRoaXMubWVudU9wdGlvbmFsQ29sdW1ucy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IG1lbnVCYXNlQ29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLnVuaXF1ZUNvbHVtbnNCeUtleSgodGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zIHx8IFtdKS5maWx0ZXIoKGMpID0+ICFjLm9wdGlvbmFsKSk7XG4gIH1cblxuICBnZXQgbWVudU9wdGlvbmFsQ29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLnVuaXF1ZUNvbHVtbnNCeUtleSgodGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zIHx8IFtdKS5maWx0ZXIoKGMpID0+IGMub3B0aW9uYWwpKTtcbiAgfVxuXG4gIGdldCBhdmFpbGFibGVDb2x1bW5zVG9BZGQoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICBjb25zdCBhY3RpdmVLZXlzID0gbmV3IFNldCh0aGlzLmFjdGl2ZUNvbHVtbnMubWFwKChjb2x1bW4pID0+IGNvbHVtbi5rZXkpKTtcbiAgICByZXR1cm4gKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyB8fCBbXSkuZmlsdGVyKChjKSA9PiBjLm9wdGlvbmFsICYmICFhY3RpdmVLZXlzLmhhcyhjLmtleSkpO1xuICB9XG5cbiAgZ2V0IGFsbG93Q29sdW1uUmVtb3ZhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZENvbmZpZy52aWV3Py5lbmFibGVDb2x1bW5SZW1vdmFsICE9PSBmYWxzZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBTbGljZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0IGhhc1NsaWNlQ29uZmlnKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5yZXNvbHZlZENvbmZpZy5zbGljZXM/Lmxlbmd0aCA/PyAwKSA+IDA7XG4gIH1cblxuICBnZXQgc2hvd1NsaWNlUGFuZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2xpY2VQYW5lbFJlZj8uc2hvd1BhbmVsID8/ICh0aGlzLmhhc1NsaWNlQ29uZmlnICYmIHRoaXMuX3Jlc29sdmVkRGF0YS5sZW5ndGggPiAwKTtcbiAgfVxuXG4gIGdldCBzaG93QWRkU2xpY2VCdXR0b24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1ZpZXdCdXR0b24gJiYgKCh0aGlzLnJlc29sdmVkQ29uZmlnLnNsaWNlcz8ubGVuZ3RoID8/IDApID4gMCB8fCB0aGlzLl9hbGxEeW5hbWljU2xpY2VDb2x1bW5zLmxlbmd0aCA+IDApO1xuICB9XG5cbiAgZ2V0IHN0YXRpY1NsaWNlc0Zvck1lbnUoKTogQXJyYXk8eyBrZXk6IHN0cmluZzsgdGl0bGU6IHN0cmluZzsgaWNvbj86IHN0cmluZyB9PiB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY1NsaWNlc0Zvck1lbnU7XG4gIH1cblxuICBnZXQgYXZhaWxhYmxlQ29sdW1uc0ZvckR5bmFtaWNTbGljZSgpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLl9hdmFpbGFibGVDb2x1bW5zRm9yRHluYW1pY1NsaWNlO1xuICB9XG5cbiAgaXNTdGF0aWNTbGljZVZpc2libGUoY29sdW1uS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zbGljZVBhbmVsUmVmPy5pc1N0YXRpY1NsaWNlVmlzaWJsZShjb2x1bW5LZXkpID8/IHRydWU7XG4gIH1cblxuICB0b2dnbGVTdGF0aWNTbGljZShjb2x1bW5LZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2xpY2VQYW5lbFJlZj8udG9nZ2xlU3RhdGljU2xpY2UoY29sdW1uS2V5KTtcbiAgfVxuXG4gIGFkZER5bmFtaWNTbGljZShjb2x1bW46IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4pOiB2b2lkIHtcbiAgICB0aGlzLnNsaWNlUGFuZWxSZWY/LmFkZER5bmFtaWNTbGljZShjb2x1bW4pO1xuICAgIGlmIChjb2x1bW4ubGF6eSAmJiB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzLmdldChjb2x1bW4ua2V5KSAhPT0gJ2xvYWRlZCcpIHtcbiAgICAgIHRoaXMudHJpZ2dlckxhenlGZXRjaChjb2x1bW4pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhbGxEeW5hbWljU2xpY2VDb2x1bW5zKCk6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbER5bmFtaWNTbGljZUNvbHVtbnM7XG4gIH1cblxuICBpc0R5bmFtaWNTbGljZUFjdGl2ZShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmVEeW5hbWljU2xpY2VDb2x1bW5zLnNvbWUoYyA9PiBjLmtleSA9PT0ga2V5KTtcbiAgfVxuXG4gIHRvZ2dsZUR5bmFtaWNTbGljZShjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0R5bmFtaWNTbGljZUFjdGl2ZShjb2wua2V5KSkge1xuICAgICAgdGhpcy5yZW1vdmVEeW5hbWljU2xpY2VCeUtleShjb2wua2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGREeW5hbWljU2xpY2UoY29sKTtcbiAgICB9XG4gIH1cblxuICBvblNsaWNlRmlsdGVyQ2hhbmdlKHByZWQ6IChyb3c6IFQpID0+IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZVNsaWNlRmlsdGVyID0gcHJlZDtcbiAgICB0aGlzLl9wcmVzZXJ2ZVBhZ2VJbmRleCA9IDA7XG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG4gICAgdGhpcy5wYWdpbmF0b3I/LmZpcnN0UGFnZSgpO1xuICB9XG5cbiAgb25EeW5hbWljU2xpY2VLZXlzQ2hhbmdlKGtleXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgYWxsQ29scyA9IHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyA/PyBbXTtcbiAgICBjb25zdCBzdGF0aWNLZXlzID0gbmV3IFNldChcbiAgICAgICh0aGlzLnJlc29sdmVkQ29uZmlnLnNsaWNlcyA/PyBbXSkubWFwKHMgPT4gcy5jb2x1bW5LZXkpLmZpbHRlcigoayk6IGsgaXMgc3RyaW5nID0+ICEhaylcbiAgICApO1xuICAgIGNvbnN0IGR5bmFtaWNLZXlTZXQgPSBuZXcgU2V0KGtleXMpO1xuICAgIGNvbnN0IGV4aXN0aW5nS2V5cyA9IG5ldyBTZXQoWy4uLnN0YXRpY0tleXMsIC4uLmR5bmFtaWNLZXlTZXRdKTtcbiAgICB0aGlzLl9hY3RpdmVEeW5hbWljU2xpY2VDb2x1bW5zID0ga2V5c1xuICAgICAgLm1hcChrID0+IGFsbENvbHMuZmluZChjID0+IGMua2V5ID09PSBrKSlcbiAgICAgIC5maWx0ZXIoKGMpOiBjIGlzIFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4gPT4gISFjKTtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgdGhpcy5fYXZhaWxhYmxlQ29sdW1uc0ZvckR5bmFtaWNTbGljZSA9IGFsbENvbHMuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuc2xpY2VhYmxlID09PSBmYWxzZSB8fCBleGlzdGluZ0tleXMuaGFzKGMua2V5KSB8fCBzZWVuLmhhcyhjLmtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgIHNlZW4uYWRkKGMua2V5KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICAgIHRoaXMuX2NvbXB1dGVTbGljZUxhYmVsKCk7XG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZ2V0IGVtcHR5U3RhdGVMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLmxhYmVscz8uZW1wdHkgfHwgJ0F1Y3VuZSBkb25uw6llJztcbiAgfVxuXG4gIGdldCBsb2FkaW5nU3RhdGVMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLmxhYmVscz8ubG9hZGluZyB8fCAnQ2hhcmdlbWVudCBkZXMgZG9ubsOpZXMuLi4nO1xuICB9XG5cbiAgZ2V0IGVmZmVjdGl2ZUlzTG9hZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc0xvYWRpbmcgfHwgdGhpcy5fcGVuZGluZ1JlbmRlciAhPT0gbnVsbDtcbiAgfVxuXG4gIGdldCBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5lZmZlY3RpdmVJc0xvYWRpbmcgJiYgdGhpcy5fYWxsRmlsdGVyZWRSb3dzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIGdldCBzaG93UGFnaW5hdGlvbigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5hY3RpdmVHcm91cEJ5S2V5ICE9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcucGFnaW5hdGlvbj8uZW5hYmxlZCAhPT0gZmFsc2U7XG4gIH1cblxuICBnZXQgaXNDb2x1bW5EcmFnRHJvcEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcudmlldz8uZW5hYmxlQ29sdW1uRHJhZ0Ryb3AgPT09IHRydWU7XG4gIH1cblxuICBnZXQgdG90YWxSb3dzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlR3JvdXBCeUtleVxuICAgICAgPyB0aGlzLnRhYmxlRGF0YVNvdXJjZS5kYXRhLmZpbHRlcigocikgPT4gIXIuX19ncm91cEhlYWRlcikubGVuZ3RoXG4gICAgICA6IHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGg7XG4gIH1cblxuICAvLyDilIDilIAgR2VzdGlvbiBkZXMgY29sb25uZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgb25BZGRDb2x1bW4oY29sdW1uOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy51c2VyQ3VzdG9taXplZENvbHVtbnMgPSB0cnVlO1xuICAgIGNvbnN0IGNvbmZpZ0NvbHMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgPz8gW107XG4gICAgY29uc3QgY29uZmlnSW5kZXggPSBjb25maWdDb2xzLmZpbmRJbmRleChjID0+IGMua2V5ID09PSBjb2x1bW4ua2V5KTtcbiAgICBpZiAoY29uZmlnSW5kZXggPT09IC0xKSB7XG4gICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMgPSBbLi4udGhpcy5hY3RpdmVDb2x1bW5zLCBjb2x1bW5dO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBpbnNlcnRCZWZvcmUgPSB0aGlzLmFjdGl2ZUNvbHVtbnMuZmluZEluZGV4KGMgPT4ge1xuICAgICAgICBjb25zdCBjaSA9IGNvbmZpZ0NvbHMuZmluZEluZGV4KGNjID0+IGNjLmtleSA9PT0gYy5rZXkpO1xuICAgICAgICByZXR1cm4gY2kgIT09IC0xICYmIGNpID4gY29uZmlnSW5kZXg7XG4gICAgICB9KTtcbiAgICAgIGlmIChpbnNlcnRCZWZvcmUgPT09IC0xKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlQ29sdW1ucyA9IFsuLi50aGlzLmFjdGl2ZUNvbHVtbnMsIGNvbHVtbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjb3B5ID0gWy4uLnRoaXMuYWN0aXZlQ29sdW1uc107XG4gICAgICAgIGNvcHkuc3BsaWNlKGluc2VydEJlZm9yZSwgMCwgY29sdW1uKTtcbiAgICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zID0gY29weTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSB0aGlzLnBhZ2luYXRvcj8ucGFnZUluZGV4ID8/IG51bGw7XG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG5cbiAgICBpZiAoY29sdW1uLmxhenkpIHtcbiAgICAgIHRoaXMudHJpZ2dlckxhenlGZXRjaChjb2x1bW4pO1xuICAgIH1cblxuICAgIHRoaXMuYWRkUmVxdWVzdGVkLmVtaXQoKTtcbiAgICB0aGlzLmNvbHVtbkFkZGVkLmVtaXQoY29sdW1uKTtcbiAgfVxuXG4gIG9uQ29sdW1uVmlzaWJpbGl0eUNoYW5nZShjb2x1bW46IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4sIGNoZWNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBpc1Zpc2libGUgPSB0aGlzLmlzQ29sdW1uVmlzaWJsZShjb2x1bW4ua2V5KTtcblxuICAgIGlmIChjaGVja2VkICYmICFpc1Zpc2libGUpIHtcbiAgICAgIHRoaXMub25BZGRDb2x1bW4oY29sdW1uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNoZWNrZWQgJiYgaXNWaXNpYmxlKSB7XG4gICAgICBpZiAoIWNvbHVtbi5vcHRpb25hbCAmJiAhdGhpcy5hbGxvd0NvbHVtblJlbW92YWwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hY3RpdmVDb2x1bW5zLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy51c2VyQ3VzdG9taXplZENvbHVtbnMgPSB0cnVlO1xuICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zID0gdGhpcy5hY3RpdmVDb2x1bW5zLmZpbHRlcigoaXRlbSkgPT4gaXRlbS5rZXkgIT09IGNvbHVtbi5rZXkpO1xuICAgICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSB0aGlzLnBhZ2luYXRvcj8ucGFnZUluZGV4ID8/IG51bGw7XG4gICAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICAgIHRoaXMuY29sdW1uUmVtb3ZlZC5lbWl0KGNvbHVtbik7XG4gICAgfVxuICB9XG5cbiAgaXNDb2x1bW5WaXNpYmxlKGNvbHVtbktleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlQ29sdW1ucy5zb21lKChjb2x1bW4pID0+IGNvbHVtbi5rZXkgPT09IGNvbHVtbktleSk7XG4gIH1cblxuICBvblJlbW92ZUNvbHVtbihjb2x1bW5LZXk6IHN0cmluZywgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dDb2x1bW5SZW1vdmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5hY3RpdmVDb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0ua2V5ID09PSBjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uIHx8ICF0aGlzLmNhblJlbW92ZUNvbHVtbihjb2x1bW4pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy51c2VyQ3VzdG9taXplZENvbHVtbnMgPSB0cnVlO1xuICAgIHRoaXMuYWN0aXZlQ29sdW1ucyA9IHRoaXMuYWN0aXZlQ29sdW1ucy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0ua2V5ICE9PSBjb2x1bW5LZXkpO1xuXG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG4gICAgdGhpcy5jb2x1bW5SZW1vdmVkLmVtaXQoY29sdW1uKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBMaWduZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0Q2VsbFRlbXBsYXRlKGtleTogc3RyaW5nKTogVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IGFueTsgaW5kZXg6IG51bWJlciB9PiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9jZWxsRGVmcz8uZmluZCgoZCkgPT4gZC5jb2x1bW5LZXkgPT09IGtleSk/LnRlbXBsYXRlID8/IG51bGw7XG4gIH1cblxuICBnZXQgaGFzQ3VzdG9tQ2VsbERlZnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLl9jZWxsRGVmcz8ubGVuZ3RoID8/IDApID4gMDtcbiAgfVxuXG4gIGdldCBoYXNSb3dDbGlja0hhbmRsZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucm93U2VsZWN0ZWQub2JzZXJ2ZWQgfHwgISF0aGlzLmNvbmZpZz8ub25Sb3dTZWxlY3RlZDtcbiAgfVxuXG4gIHRyYWNrUm93Rm4gPSAoX2luZGV4OiBudW1iZXIsIHJvdzogYW55KTogYW55ID0+XG4gICAgcm93Ll9fZ3JvdXBIZWFkZXIgPyBgX19ncm91cF8ke3Jvdy5fX2dyb3VwS2V5fWAgOiByb3cuX19pbmRleCA/PyBfaW5kZXg7XG5cbiAgZ2V0Um93Q2xhc3Mocm93OiBhbnkpOiBzdHJpbmcgfCBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+IHtcbiAgICBjb25zdCBmbiA9IHRoaXMucmVzb2x2ZWRDb25maWcucm93Q2xhc3M7XG4gICAgaWYgKCFmbiB8fCByb3c/Ll9fZ3JvdXBIZWFkZXIpIHJldHVybiB7fTtcbiAgICByZXR1cm4gZm4ocm93Ll9fcmF3ID8/IHJvdywgcm93Ll9faW5kZXggPz8gMCk7XG4gIH1cblxuICBvblJvd0NsaWNrKHJvdzogYW55LCBldmVudDogTW91c2VFdmVudCB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAocm93Py5fX2dyb3VwSGVhZGVyKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmhhc1Jvd0NsaWNrSGFuZGxlcikgcmV0dXJuO1xuICAgIGNvbnN0IHJlc29sdmVkID0gKHJvdz8uX19yYXcgPz8gcm93KSBhcyBUO1xuICAgIHRoaXMucm93U2VsZWN0ZWQuZW1pdChyZXNvbHZlZCk7XG4gICAgdGhpcy5jb25maWc/Lm9uUm93U2VsZWN0ZWQ/LihyZXNvbHZlZCwgZXZlbnQpO1xuICB9XG5cbiAgLy8g4pSA4pSAIERyYWcgJiBkcm9wIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIG9uSGVhZGVyRHJhZ1N0YXJ0KGNvbHVtbktleTogc3RyaW5nLCBldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzQ29sdW1uRHJhZ0Ryb3BFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnZ2VkQ29sdW1uS2V5ID0gY29sdW1uS2V5O1xuICAgIHRoaXMuZHJhZ092ZXJDb2x1bW5LZXkgPSBudWxsO1xuICAgIGlmIChldmVudC5kYXRhVHJhbnNmZXIpIHtcbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnO1xuICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLnNldERhdGEoJ3RleHQvcGxhaW4nLCBjb2x1bW5LZXkpO1xuICAgIH1cbiAgfVxuXG4gIG9uSGVhZGVyRHJhZ092ZXIoY29sdW1uS2V5OiBzdHJpbmcsIGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNDb2x1bW5EcmFnRHJvcEVuYWJsZWQgfHwgIXRoaXMuZHJhZ2dlZENvbHVtbktleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9IGNvbHVtbktleTtcbiAgfVxuXG4gIG9uSGVhZGVyRHJvcCh0YXJnZXRDb2x1bW5LZXk6IHN0cmluZywgZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0NvbHVtbkRyYWdEcm9wRW5hYmxlZCB8fCAhdGhpcy5kcmFnZ2VkQ29sdW1uS2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IHByZXZpb3VzSW5kZXggPSB0aGlzLmFjdGl2ZUNvbHVtbnMuZmluZEluZGV4KChjb2x1bW4pID0+IGNvbHVtbi5rZXkgPT09IHRoaXMuZHJhZ2dlZENvbHVtbktleSk7XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5hY3RpdmVDb2x1bW5zLmZpbmRJbmRleCgoY29sdW1uKSA9PiBjb2x1bW4ua2V5ID09PSB0YXJnZXRDb2x1bW5LZXkpO1xuXG4gICAgaWYgKHByZXZpb3VzSW5kZXggPT09IC0xIHx8IGN1cnJlbnRJbmRleCA9PT0gLTEgfHwgcHJldmlvdXNJbmRleCA9PT0gY3VycmVudEluZGV4KSB7XG4gICAgICB0aGlzLm9uSGVhZGVyRHJhZ0VuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXNlckN1c3RvbWl6ZWRDb2x1bW5zID0gdHJ1ZTtcbiAgICBjb25zdCByZW9yZGVyZWQgPSBbLi4udGhpcy5hY3RpdmVDb2x1bW5zXTtcbiAgICBjb25zdCBbbW92ZWRdID0gcmVvcmRlcmVkLnNwbGljZShwcmV2aW91c0luZGV4LCAxKTtcbiAgICByZW9yZGVyZWQuc3BsaWNlKGN1cnJlbnRJbmRleCwgMCwgbW92ZWQpO1xuICAgIHRoaXMuYWN0aXZlQ29sdW1ucyA9IHJlb3JkZXJlZDtcbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICB0aGlzLm9uSGVhZGVyRHJhZ0VuZCgpO1xuICB9XG5cbiAgb25IZWFkZXJEcmFnRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuZHJhZ2dlZENvbHVtbktleSA9IG51bGw7XG4gICAgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9IG51bGw7XG4gIH1cblxuICBpc0hlYWRlckRyb3BUYXJnZXQoY29sdW1uS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRyYWdnZWRDb2x1bW5LZXkgJiYgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9PT0gY29sdW1uS2V5ICYmIHRoaXMuZHJhZ2dlZENvbHVtbktleSAhPT0gY29sdW1uS2V5O1xuICB9XG5cbiAgY2FuUmVtb3ZlQ29sdW1uKGNvbHVtbjogVGFibGVDb2x1bW5Qcm92aWRlcjxUPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmFsbG93Q29sdW1uUmVtb3ZhbCAmJlxuICAgICAgY29sdW1uLnJlbW92YWJsZSAhPT0gZmFsc2UgJiZcbiAgICAgIHRoaXMuYWN0aXZlQ29sdW1ucy5sZW5ndGggPiAxXG4gICAgKTtcbiAgfVxuXG4gIGlzQ2VsbEVtcHR5KHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdmFsdWUgPT09ICcnIHx8IHZhbHVlID09IG51bGw7XG4gIH1cblxuICBhc1RpdGxlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFBpcGVsaW5lIGRlIGRvbm7DqWVzIChwcml2w6kpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgcmVmcmVzaFZpZXdNb2RlbCgpOiB2b2lkIHtcbiAgICB0aGlzLl9yZXNvbHZlZERhdGEgPSB0aGlzLnJlc29sdmVEYXRhKCk7XG4gICAgdGhpcy5yZXNvbHZlZENvbmZpZyA9IHRoaXMuYnVpbGRFZmZlY3RpdmVDb25maWcoKTtcbiAgICB0aGlzLl9jb2x1bW5NYXAgPSBuZXcgTWFwKCh0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgfHwgW10pLm1hcChjID0+IFtjLmtleSwgY10pKTtcbiAgICBjb25zdCBkZWZhdWx0Q29sdW1ucyA9ICh0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgfHwgW10pLmZpbHRlcihjID0+ICFjLm9wdGlvbmFsKTtcblxuICAgIGlmICghdGhpcy51c2VyQ3VzdG9taXplZENvbHVtbnMgfHwgdGhpcy5hY3RpdmVDb2x1bW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zID0gWy4uLmRlZmF1bHRDb2x1bW5zXTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYWxsb3dlZEtleXMgPSBuZXcgU2V0KFxuICAgICAgICAodGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zIHx8IFtdKS5tYXAoKGNvbHVtbikgPT4gY29sdW1uLmtleSlcbiAgICAgICk7XG4gICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMgPSB0aGlzLmFjdGl2ZUNvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IGFsbG93ZWRLZXlzLmhhcyhjb2x1bW4ua2V5KSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJlZENvbHVtbnMgPSB0aGlzLmFjdGl2ZUNvbHVtbnMubWFwKChjb2x1bW4pID0+IGNvbHVtbi5rZXkpO1xuXG4gICAgdGhpcy5wYWdlU2l6ZSA9IHRoaXMucGFnaW5hdG9yPy5wYWdlU2l6ZSB8fCB0aGlzLnJlc29sdmVQYWdlU2l6ZSgpO1xuICAgIHRoaXMucGFnZVNpemVPcHRpb25zID0gdGhpcy5yZXNvbHZlUGFnZVNpemVPcHRpb25zKCk7XG4gICAgdGhpcy5wYWdlU2l6ZU9wdGlvbnNHcm91cEJ5ID0gdGhpcy5yZXNvbHZlUGFnZVNpemVPcHRpb25zR3JvdXBCeSgpO1xuICAgIGlmICh0aGlzLmdyb3VwUGFnZVNpemUgIT09IDAgJiYgIXRoaXMucGFnZVNpemVPcHRpb25zR3JvdXBCeS5pbmNsdWRlcyh0aGlzLmdyb3VwUGFnZVNpemUpKSB7XG4gICAgICB0aGlzLmdyb3VwUGFnZVNpemUgPSB0aGlzLnJlc29sdmVEZWZhdWx0R3JvdXBQYWdlU2l6ZSgpO1xuICAgIH1cblxuICAgIHRoaXMuYXR0YWNoUGFnaW5hdG9yKCk7XG4gICAgdGhpcy5hdHRhY2hTb3J0KCk7XG5cbiAgICAvLyBNaXNlIMOgIGpvdXIgZGVzIHByb3ByacOpdMOpcyBzdGFibGVzIHBvdXIgbGVzIGJpbmRpbmdzIGR1IHRlbXBsYXRlXG4gICAgdGhpcy5fc2xpY2VDb25maWdzID0gdGhpcy5yZXNvbHZlZENvbmZpZy5zbGljZXMgPz8gW107XG4gICAgdGhpcy5fc2xpY2VDb2x1bW5zID0gdGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zID8/IFtdO1xuICAgIHRoaXMuX3NsaWNlRGF0YSA9IHRoaXMuX3Jlc29sdmVkRGF0YTtcbiAgICB0aGlzLl9zbGljZVNob3dUb2dnbGUgPSB0aGlzLnJlc29sdmVkQ29uZmlnLmVuYWJsZVNsaWNlVG9nZ2xlICE9PSBmYWxzZTtcbiAgICB0aGlzLl9zdGF0aWNTbGljZXNGb3JNZW51ID0gKHRoaXMucmVzb2x2ZWRDb25maWcuc2xpY2VzID8/IFtdKVxuICAgICAgLmZpbHRlcihzID0+ICEhcy5jb2x1bW5LZXkpXG4gICAgICAubWFwKHMgPT4ge1xuICAgICAgICBjb25zdCBjb2xJY29uID0gKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyA/PyBbXSkuZmluZChjID0+IGMua2V5ID09PSBzLmNvbHVtbktleSk/Lmljb247XG4gICAgICAgIHJldHVybiB7IGtleTogcy5jb2x1bW5LZXkhLCB0aXRsZTogcy50aXRsZSB8fCBodW1hbml6ZUtleShzLmNvbHVtbktleSEpLCBpY29uOiBzLmljb24gPz8gY29sSWNvbiB9O1xuICAgICAgfSk7XG4gICAgaWYgKCF0aGlzLl9hY3RpdmVTb3J0LmFjdGl2ZSAmJiB0aGlzLnJlc29sdmVkQ29uZmlnLmRlZmF1bHRTb3J0KSB7XG4gICAgICB0aGlzLl9tYXRTb3J0QWN0aXZlID0gdGhpcy5yZXNvbHZlZENvbmZpZy5kZWZhdWx0U29ydC5hY3RpdmU7XG4gICAgICB0aGlzLl9tYXRTb3J0RGlyZWN0aW9uID0gdGhpcy5yZXNvbHZlZENvbmZpZy5kZWZhdWx0U29ydC5kaXJlY3Rpb247XG4gICAgfVxuICAgIGNvbnN0IHN0YXRpY0tleXMgPSBuZXcgU2V0KFxuICAgICAgKHRoaXMucmVzb2x2ZWRDb25maWcuc2xpY2VzID8/IFtdKS5tYXAocyA9PiBzLmNvbHVtbktleSkuZmlsdGVyKChrKTogayBpcyBzdHJpbmcgPT4gISFrKVxuICAgICk7XG4gICAgY29uc3QgYWN0aXZlRHluS2V5cyA9IG5ldyBTZXQodGhpcy5fYWN0aXZlRHluYW1pY1NsaWNlQ29sdW1ucy5tYXAoYyA9PiBjLmtleSkpO1xuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICB0aGlzLl9hdmFpbGFibGVDb2x1bW5zRm9yRHluYW1pY1NsaWNlID0gKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyA/PyBbXSkuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuc2xpY2VhYmxlID09PSBmYWxzZSB8fCBzdGF0aWNLZXlzLmhhcyhjLmtleSkgfHwgYWN0aXZlRHluS2V5cy5oYXMoYy5rZXkpIHx8IHNlZW4uaGFzKGMua2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKCFjLmhlYWRlciAmJiBjLnNsaWNlYWJsZSAhPT0gdHJ1ZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgc2Vlbi5hZGQoYy5rZXkpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG4gICAgY29uc3Qgc2VlbjIgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICB0aGlzLl9hbGxEeW5hbWljU2xpY2VDb2x1bW5zID0gKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyA/PyBbXSkuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuc2xpY2VhYmxlID09PSBmYWxzZSB8fCBzdGF0aWNLZXlzLmhhcyhjLmtleSkgfHwgc2VlbjIuaGFzKGMua2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKCFjLmhlYWRlciAmJiBjLnNsaWNlYWJsZSAhPT0gdHJ1ZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgc2VlbjIuYWRkKGMua2V5KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICAgIHRoaXMuX2NvbXB1dGVTbGljZUxhYmVsKCk7XG5cbiAgICB0aGlzLl9zY2hlZHVsZVJlbmRlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tcHV0ZVNsaWNlTGFiZWwoKTogdm9pZCB7XG4gICAgY29uc3QgdmlzaWJsZVN0YXRpY0NvdW50ID0gdGhpcy5zbGljZVBhbmVsUmVmPy5zdGF0aWNTbGljZUNvdW50XG4gICAgICA/PyB0aGlzLl9zbGljZUNvbmZpZ3MubGVuZ3RoO1xuICAgIGNvbnN0IHRvdGFsID0gdmlzaWJsZVN0YXRpY0NvdW50ICsgdGhpcy5fYWN0aXZlRHluYW1pY1NsaWNlQ29sdW1ucy5sZW5ndGg7XG4gICAgaWYgKHRvdGFsID09PSAwKSB7IHRoaXMuX2FjdGl2ZVNsaWNlQnlMYWJlbCA9ICdBdWN1bic7IHJldHVybjsgfVxuICAgIGlmICh0b3RhbCA9PT0gMSkge1xuICAgICAgaWYgKHZpc2libGVTdGF0aWNDb3VudCA9PT0gMSkge1xuICAgICAgICBjb25zdCBmaXJzdCA9IHRoaXMuX3NsaWNlQ29uZmlncy5maW5kKFxuICAgICAgICAgIHMgPT4gIXMuY29sdW1uS2V5IHx8IHRoaXMuaXNTdGF0aWNTbGljZVZpc2libGUocy5jb2x1bW5LZXkpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNsaWNlQnlMYWJlbCA9IGZpcnN0Py50aXRsZSB8fCBmaXJzdD8uY29sdW1uS2V5IHx8ICcxJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWN0aXZlU2xpY2VCeUxhYmVsID0gdGhpcy5fYWN0aXZlRHluYW1pY1NsaWNlQ29sdW1uc1swXT8uaGVhZGVyIHx8ICcxJztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fYWN0aXZlU2xpY2VCeUxhYmVsID0gYCR7dG90YWx9IGFjdGlmc2A7XG4gIH1cblxuICBwcml2YXRlIF9zY2hlZHVsZVJlbmRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcGVuZGluZ1JlbmRlciAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3BlbmRpbmdSZW5kZXIpO1xuICAgICAgdGhpcy5fcGVuZGluZ1JlbmRlciA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuX3BlbmRpbmdSZW5kZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX3BlbmRpbmdSZW5kZXIgPSBudWxsO1xuICAgICAgdGhpcy5fZXhlY3V0ZVJlbmRlcigpO1xuICAgIH0sIDApO1xuICB9XG5cbiAgcHJpdmF0ZSBfZXhlY3V0ZVJlbmRlcigpOiB2b2lkIHtcbiAgICBjb25zdCBjYXRlZ29yeVJvd3MgPSB0aGlzLmdldENhdGVnb3J5RmlsdGVyZWREYXRhKCk7XG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBCeUtleSkge1xuICAgICAgLy8gRW4gbW9kZSBncm91cEJ5LCBwcm9qZWN0Um93cyBnw6hyZSB0b3V0IGxlIHRyaSBpbnRlcm5lbWVudCDigJQgcGFzIGRlIHNvcnQgZ2xvYmFsIGludXRpbGVcbiAgICAgIHRoaXMuX2FsbEZpbHRlcmVkUm93cyA9IGNhdGVnb3J5Um93cztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY29tcGFyZUZuID0gdGhpcy5fYnVpbGRTb3J0Q29tcGFyYXRvcigpO1xuICAgICAgdGhpcy5fYWxsRmlsdGVyZWRSb3dzID0gY29tcGFyZUZuID8gWy4uLmNhdGVnb3J5Um93c10uc29ydChjb21wYXJlRm4pIDogY2F0ZWdvcnlSb3dzO1xuICAgIH1cblxuICAgIC8vIE1ldHRyZSDDoCBqb3VyIGxlIHBhZ2luYXRvciBhdmVjIGxlIG5vdXZlYXUgdG90YWxcbiAgICBpZiAodGhpcy5wYWdpbmF0b3IpIHtcbiAgICAgIGNvbnN0IHNhdmVkSW5kZXggPSB0aGlzLl9wcmVzZXJ2ZVBhZ2VJbmRleCA/PyB0aGlzLnBhZ2luYXRvci5wYWdlSW5kZXg7XG4gICAgICBjb25zdCBtYXhQYWdlID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGggLyB0aGlzLnBhZ2VTaXplKSAtIDEpO1xuICAgICAgdGhpcy5wYWdpbmF0b3IubGVuZ3RoID0gdGhpcy5fYWxsRmlsdGVyZWRSb3dzLmxlbmd0aDtcbiAgICAgIHRoaXMucGFnaW5hdG9yLnBhZ2VJbmRleCA9IE1hdGgubWluKHNhdmVkSW5kZXgsIG1heFBhZ2UpO1xuICAgICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMuX3Byb2plY3RDdXJyZW50UGFnZSgpO1xuICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgX3Byb2plY3RDdXJyZW50UGFnZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hY3RpdmVHcm91cEJ5S2V5KSB7XG4gICAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5kYXRhID0gdGhpcy5wcm9qZWN0Um93cyh0aGlzLl9hbGxGaWx0ZXJlZFJvd3MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VJbmRleCA9IHRoaXMucGFnaW5hdG9yPy5wYWdlSW5kZXggPz8gMDtcbiAgICBjb25zdCBzdGFydCA9IHBhZ2VJbmRleCAqIHRoaXMucGFnZVNpemU7XG4gICAgY29uc3QgcGFnZVJvd3MgPSB0aGlzLl9hbGxGaWx0ZXJlZFJvd3Muc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgdGhpcy5wYWdlU2l6ZSk7XG5cbiAgICBjb25zdCBwcm9qZWN0ZWQ6IGFueVtdID0gW107XG4gICAgcGFnZVJvd3MuZm9yRWFjaCgocm93LCBpKSA9PiB7XG4gICAgICBjb25zdCBpZHggPSBzdGFydCArIGk7XG4gICAgICBjb25zdCBwOiBhbnkgPSB7IF9fcmF3OiByb3csIF9faW5kZXg6IGlkeCB9O1xuICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICBwW2NvbC5rZXldID0gdGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGNvbCwgcm93LCBpZHgpO1xuICAgICAgfSk7XG4gICAgICBwcm9qZWN0ZWQucHVzaChwKTtcbiAgICB9KTtcbiAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5kYXRhID0gcHJvamVjdGVkO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEVmZmVjdGl2ZUNvbmZpZygpOiBUYWJsZVByb3ZpZGVyPFQ+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZyB8fCB7fTtcbiAgICBjb25zdCByb3dzID0gdGhpcy5fcmVzb2x2ZWREYXRhO1xuXG4gICAgY29uc3QgY29sdW1ucyA9XG4gICAgICBjb25maWcuY29sdW1ucyB8fFxuICAgICAgdGhpcy5jb2x1bW5zQ29uZmlnIHx8XG4gICAgICB0aGlzLnJlc29sdmVDb2x1bW5zRnJvbUNvbXBhdChyb3dzKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5jb25maWcsXG4gICAgICBjb2x1bW5zLFxuICAgICAgc2xpY2VzOiBjb25maWcuc2xpY2VzIHx8IFtdLFxuICAgICAgZW5hYmxlU2xpY2VUb2dnbGU6IGNvbmZpZy5lbmFibGVTbGljZVRvZ2dsZSA/PyB0cnVlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVEYXRhKCk6IFRbXSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5kYXRhKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kYXRhU291cmNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UgJiYgQXJyYXkuaXNBcnJheSgodGhpcy5kYXRhU291cmNlIGFzIGFueSkuZGF0YSkpIHtcbiAgICAgIHJldHVybiAodGhpcy5kYXRhU291cmNlIGFzIGFueSkuZGF0YTtcbiAgICB9XG5cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVDb2x1bW5zRnJvbUNvbXBhdChyb3dzOiBUW10pOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIGlmICh0aGlzLmRpc3BsYXllZENvbHVtbnM/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheWVkQ29sdW1ucy5tYXAoKGtleSkgPT4gKHtcbiAgICAgICAga2V5LFxuICAgICAgICBoZWFkZXI6IHRoaXMuY29sdW1uTGFiZWxzPy5ba2V5XSB8fCBodW1hbml6ZUtleShrZXkpLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGZpcnN0Um93ID0gcm93c1swXSBhcyBhbnk7XG4gICAgaWYgKCFmaXJzdFJvdyB8fCB0eXBlb2YgZmlyc3RSb3cgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGZpcnN0Um93KS5tYXAoKGtleSkgPT4gKHtcbiAgICAgIGtleSxcbiAgICAgIGhlYWRlcjogdGhpcy5jb2x1bW5MYWJlbHM/LltrZXldIHx8IGh1bWFuaXplS2V5KGtleSksXG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDYXRlZ29yeUZpbHRlcmVkRGF0YSgpOiBUW10ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9yZXNvbHZlZERhdGE7XG5cbiAgICBsZXQgZmlsdGVyZWQgPSBkYXRhLmZpbHRlcih0aGlzLmFjdGl2ZVNsaWNlRmlsdGVyKTtcblxuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5zZWFyY2hRdWVyeT8udHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHF1ZXJ5KSB7XG4gICAgICBmaWx0ZXJlZCA9IGZpbHRlcmVkLmZpbHRlcigocm93KSA9PlxuICAgICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMuc29tZSgoY29sKSA9PiB7XG4gICAgICAgICAgY29uc3QgdmFsID0gdGhpcy5nZXRMYXp5QXdhcmVWYWx1ZShjb2wua2V5LCByb3cpO1xuICAgICAgICAgIHJldHVybiB2YWwgIT0gbnVsbCAmJiBTdHJpbmcodmFsKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHF1ZXJ5KTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgfVxuXG4gIHByaXZhdGUgcHJvamVjdFJvd3Mocm93czogVFtdKTogYW55W10ge1xuICAgIGNvbnN0IGdyb3VwS2V5ID0gdGhpcy5hY3RpdmVHcm91cEJ5S2V5O1xuXG4gICAgaWYgKCFncm91cEtleSkge1xuICAgICAgY29uc3QgcmVzdWx0OiBhbnlbXSA9IFtdO1xuICAgICAgcm93cy5mb3JFYWNoKChyb3csIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHByb2plY3RlZDogYW55ID0geyBfX3Jhdzogcm93LCBfX2luZGV4OiBpbmRleCB9O1xuICAgICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgICAgcHJvamVjdGVkW2NvbC5rZXldID0gdGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGNvbCwgcm93LCBpbmRleCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQucHVzaChwcm9qZWN0ZWQpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGNvbnN0IGdyb3VwQ29sRGVmID0gdGhpcy5fY29sdW1uTWFwLmdldChncm91cEtleSk7XG4gICAgY29uc3QgZ3JvdXBMYXp5U3RhdHVzID0gZ3JvdXBDb2xEZWY/LmxhenkgPyAodGhpcy5fbGF6eUNvbHVtblN0YXR1cy5nZXQoZ3JvdXBLZXkpID8/ICdpZGxlJykgOiAnbG9hZGVkJztcblxuICAgIGlmIChncm91cExhenlTdGF0dXMgIT09ICdsb2FkZWQnKSB7XG4gICAgICB0aGlzLl90b3RhbEZpbHRlcmVkQ291bnQgPSByb3dzLmxlbmd0aDtcbiAgICAgIHJldHVybiBbeyBfX2dyb3VwSGVhZGVyOiB0cnVlLCBfX2dyb3VwS2V5OiAnX19sYXp5X2xvYWRpbmdfXycsIF9fZ3JvdXBDb3VudDogcm93cy5sZW5ndGgsIF9fZ3JvdXBQYWdlOiAwLCBfX2dyb3VwUGFnZUNvdW50OiAxIH1dO1xuICAgIH1cblxuICAgIGNvbnN0IGVmZmVjdGl2ZVNvcnQgPSB0aGlzLl9hY3RpdmVTb3J0LmFjdGl2ZSAmJiB0aGlzLl9hY3RpdmVTb3J0LmRpcmVjdGlvblxuICAgICAgPyB0aGlzLl9hY3RpdmVTb3J0XG4gICAgICA6IHRoaXMucmVzb2x2ZWRDb25maWcuZGVmYXVsdFNvcnQgPz8geyBhY3RpdmU6ICcnLCBkaXJlY3Rpb246ICcnIGFzIGNvbnN0IH07XG5cbiAgICAvLyBWw6lyaWZpZSBzaSBsZSBjYWNoZSBlc3QgZW5jb3JlIHZhbGlkZSAobcOqbWUgcsOpZsOpcmVuY2UgZGUgcm93cyArIG3Dqm1lIHBhcmFtw6h0cmVzIGRlIHRyaS9ncm91cGUpXG4gICAgY29uc3QgY2FjaGVWYWxpZCA9XG4gICAgICB0aGlzLl9ncm91cENhY2hlUm93cyA9PT0gcm93cyAmJlxuICAgICAgdGhpcy5fZ3JvdXBDYWNoZUtleSA9PT0gZ3JvdXBLZXkgJiZcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVTb3J0T3JkZXIgPT09IHRoaXMuZ3JvdXBTb3J0T3JkZXIgJiZcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVTb3J0QWN0aXZlID09PSAoZWZmZWN0aXZlU29ydC5hY3RpdmUgPz8gJycpICYmXG4gICAgICB0aGlzLl9ncm91cENhY2hlU29ydERpciA9PT0gKGVmZmVjdGl2ZVNvcnQuZGlyZWN0aW9uID8/ICcnKTtcblxuICAgIGxldCBncm91cE9yZGVyOiBzdHJpbmdbXTtcbiAgICBsZXQgZ3JvdXBNYXA6IE1hcDxzdHJpbmcsIFRbXT47XG5cbiAgICBpZiAoY2FjaGVWYWxpZCkge1xuICAgICAgZ3JvdXBPcmRlciA9IHRoaXMuX2dyb3VwQ2FjaGVPcmRlcjtcbiAgICAgIGdyb3VwTWFwID0gdGhpcy5fZ3JvdXBDYWNoZU1hcDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHLDqS1jYWxjdWwgZGVzIHZhbGV1cnMgZGUgZ3JvdXBlIGVuIHVuIHNldWwgcGFzc2FnZSAow6l2aXRlIE8obikgZmluZCgpIHBhciBjb21wYXJhaXNvbilcbiAgICAgIGNvbnN0IGdyb3VwVmFsdWVDYWNoZSA9IG5ldyBNYXA8VCwgc3RyaW5nPigpO1xuICAgICAgcm93cy5mb3JFYWNoKHJvdyA9PiBncm91cFZhbHVlQ2FjaGUuc2V0KHJvdywgU3RyaW5nKHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoZ3JvdXBLZXksIHJvdykgPz8gJycpKSk7XG5cbiAgICAgIC8vIFByw6ktY2FsY3VsIGRlcyB2YWxldXJzIGRlIHRyaSAow6l2aXRlIE8obiBsb2cgbikgw5cgZ2V0TGF6eUF3YXJlVmFsdWUgZGFucyBsZSBjb21wYXJhdGV1cilcbiAgICAgIGxldCBmYXN0Q29tcGFyZUZuOiAoKGE6IFQsIGI6IFQpID0+IG51bWJlcikgfCBudWxsID0gbnVsbDtcbiAgICAgIGlmIChlZmZlY3RpdmVTb3J0LmFjdGl2ZSAmJiBlZmZlY3RpdmVTb3J0LmRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBzb3J0VmFsdWVDYWNoZSA9IG5ldyBNYXA8VCwgYW55PigpO1xuICAgICAgICByb3dzLmZvckVhY2gocm93ID0+IHNvcnRWYWx1ZUNhY2hlLnNldChyb3csIHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoZWZmZWN0aXZlU29ydC5hY3RpdmUsIHJvdykpKTtcbiAgICAgICAgY29uc3QgZGlyID0gZWZmZWN0aXZlU29ydC5kaXJlY3Rpb247XG4gICAgICAgIGZhc3RDb21wYXJlRm4gPSAoYTogVCwgYjogVCk6IG51bWJlciA9PiB7XG4gICAgICAgICAgY29uc3QgdmEgPSBzb3J0VmFsdWVDYWNoZS5nZXQoYSk7XG4gICAgICAgICAgY29uc3QgdmIgPSBzb3J0VmFsdWVDYWNoZS5nZXQoYik7XG4gICAgICAgICAgbGV0IGNtcCA9IDA7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIHZiID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgY21wID0gdmEgPCB2YiA/IC0xIDogdmEgPiB2YiA/IDEgOiAwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzYSA9IHZhID09IG51bGwgPyAnJyA6IFN0cmluZyh2YSkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGNvbnN0IHNiID0gdmIgPT0gbnVsbCA/ICcnIDogU3RyaW5nKHZiKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgY21wID0gc2EgPCBzYiA/IC0xIDogc2EgPiBzYiA/IDEgOiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZGlyID09PSAnYXNjJyA/IGNtcCA6IC1jbXA7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5yb3dzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhID0gZ3JvdXBWYWx1ZUNhY2hlLmdldChhKSE7XG4gICAgICAgIGNvbnN0IHZiID0gZ3JvdXBWYWx1ZUNhY2hlLmdldChiKSE7XG4gICAgICAgIGNvbnN0IGNtcCA9IHZhLmxvY2FsZUNvbXBhcmUodmIpO1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cFNvcnRPcmRlciA9PT0gJ2Rlc2MnID8gLWNtcCA6IGNtcDtcbiAgICAgIH0pO1xuXG4gICAgICBncm91cE9yZGVyID0gW107XG4gICAgICBncm91cE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBUW10+KCk7XG4gICAgICBzb3J0ZWQuZm9yRWFjaCgocm93KSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwVmFsdWUgPSBncm91cFZhbHVlQ2FjaGUuZ2V0KHJvdykhO1xuICAgICAgICBpZiAoIWdyb3VwTWFwLmhhcyhncm91cFZhbHVlKSkge1xuICAgICAgICAgIGdyb3VwT3JkZXIucHVzaChncm91cFZhbHVlKTtcbiAgICAgICAgICBncm91cE1hcC5zZXQoZ3JvdXBWYWx1ZSwgW10pO1xuICAgICAgICB9XG4gICAgICAgIGdyb3VwTWFwLmdldChncm91cFZhbHVlKSEucHVzaChyb3cpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFRyaSBpbnRyYS1ncm91cGUgc3RvY2vDqSBkYW5zIGxlIGNhY2hlIOKAlCDDqXZpdGUgbGUgcmUtdHJpIHN1ciBjb2xsYXBzZS9leHBhbmQvcGFnaW5hdGlvblxuICAgICAgaWYgKGZhc3RDb21wYXJlRm4pIHtcbiAgICAgICAgY29uc3QgZm4gPSBmYXN0Q29tcGFyZUZuO1xuICAgICAgICBncm91cE1hcC5mb3JFYWNoKChncm91cFJvd3MsIGtleSkgPT4ge1xuICAgICAgICAgIGdyb3VwTWFwLnNldChrZXksIFsuLi5ncm91cFJvd3NdLnNvcnQoZm4pKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIE1pc2UgZW4gY2FjaGVcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVSb3dzID0gcm93cztcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVLZXkgPSBncm91cEtleTtcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVTb3J0T3JkZXIgPSB0aGlzLmdyb3VwU29ydE9yZGVyO1xuICAgICAgdGhpcy5fZ3JvdXBDYWNoZVNvcnRBY3RpdmUgPSBlZmZlY3RpdmVTb3J0LmFjdGl2ZSA/PyAnJztcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGVTb3J0RGlyID0gZWZmZWN0aXZlU29ydC5kaXJlY3Rpb24gPz8gJyc7XG4gICAgICB0aGlzLl9ncm91cENhY2hlT3JkZXIgPSBncm91cE9yZGVyO1xuICAgICAgdGhpcy5fZ3JvdXBDYWNoZU1hcCA9IGdyb3VwTWFwO1xuICAgIH1cblxuICAgIHRoaXMuX3RvdGFsRmlsdGVyZWRDb3VudCA9IHJvd3MubGVuZ3RoO1xuXG4gICAgLy8gUHJvdGVjdGlvbiBjb250cmUgbGVzIGpldXggZGUgZG9ubsOpZXMgw6AgdHJvcCBoYXV0ZSBjYXJkaW5hbGl0w6lcbiAgICBpZiAoZ3JvdXBPcmRlci5sZW5ndGggPiBUYWJsZUNvbXBvbmVudC5NQVhfR1JPVVBfQ09VTlQpIHtcbiAgICAgIHJldHVybiBbeyBfX2dyb3VwSGVhZGVyOiB0cnVlLCBfX2dyb3VwS2V5OiAnX190b29fbWFueV9ncm91cHNfXycsIF9fZ3JvdXBDb3VudDogZ3JvdXBPcmRlci5sZW5ndGgsIF9fZ3JvdXBQYWdlOiAwLCBfX2dyb3VwUGFnZUNvdW50OiAxIH1dO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VTaXplID0gdGhpcy5ncm91cFBhZ2VTaXplO1xuICAgIGNvbnN0IHJlc3VsdDogYW55W10gPSBbXTtcblxuICAgIGdyb3VwT3JkZXIuZm9yRWFjaCgoZ3JvdXBWYWx1ZSkgPT4ge1xuICAgICAgY29uc3QgZ3JvdXBSb3dzID0gZ3JvdXBNYXAuZ2V0KGdyb3VwVmFsdWUpITtcbiAgICAgIGNvbnN0IHRvdGFsQ291bnQgPSBncm91cFJvd3MubGVuZ3RoO1xuICAgICAgY29uc3QgY3VycmVudFBhZ2UgPSBwYWdlU2l6ZSA9PT0gMCA/IDAgOiAodGhpcy5fZ3JvdXBQYWdlcy5nZXQoZ3JvdXBWYWx1ZSkgPz8gMCk7XG4gICAgICBjb25zdCBwYWdlQ291bnQgPSBwYWdlU2l6ZSA9PT0gMCA/IDEgOiBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWxDb3VudCAvIHBhZ2VTaXplKSk7XG4gICAgICBjb25zdCBjb2xsYXBzZWQgPSB0aGlzLmlzR3JvdXBDb2xsYXBzZWQoZ3JvdXBWYWx1ZSk7XG5cbiAgICAgIHJlc3VsdC5wdXNoKHsgX19ncm91cEhlYWRlcjogdHJ1ZSwgX19ncm91cEtleTogZ3JvdXBWYWx1ZSwgX19ncm91cENvdW50OiB0b3RhbENvdW50LCBfX2dyb3VwUGFnZTogY3VycmVudFBhZ2UsIF9fZ3JvdXBQYWdlQ291bnQ6IHBhZ2VDb3VudCB9KTtcblxuICAgICAgaWYgKCFjb2xsYXBzZWQpIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBwYWdlU2l6ZSA9PT0gMCA/IDAgOiBjdXJyZW50UGFnZSAqIHBhZ2VTaXplO1xuICAgICAgICBjb25zdCBlbmQgPSBwYWdlU2l6ZSA9PT0gMCA/IHRvdGFsQ291bnQgOiBNYXRoLm1pbihzdGFydCArIHBhZ2VTaXplLCB0b3RhbENvdW50KTtcbiAgICAgICAgZ3JvdXBSb3dzLnNsaWNlKHN0YXJ0LCBlbmQpLmZvckVhY2goKHJvdywgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlkeCA9IHN0YXJ0ICsgaTtcbiAgICAgICAgICBjb25zdCBwcm9qZWN0ZWQ6IGFueSA9IHsgX19yYXc6IHJvdywgX19pbmRleDogaWR4IH07XG4gICAgICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICAgICAgcHJvamVjdGVkW2NvbC5rZXldID0gdGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGNvbCwgcm93LCBpZHgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHByb2plY3RlZCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgX2J1aWxkU29ydENvbXBhcmF0b3IoKTogKChhOiBULCBiOiBUKSA9PiBudW1iZXIpIHwgbnVsbCB7XG4gICAgY29uc3Qgc29ydCA9IHRoaXMuX2FjdGl2ZVNvcnQuYWN0aXZlICYmIHRoaXMuX2FjdGl2ZVNvcnQuZGlyZWN0aW9uXG4gICAgICA/IHRoaXMuX2FjdGl2ZVNvcnRcbiAgICAgIDogdGhpcy5yZXNvbHZlZENvbmZpZy5kZWZhdWx0U29ydCA/PyB7IGFjdGl2ZTogJycsIGRpcmVjdGlvbjogJycgYXMgY29uc3QgfTtcbiAgICBjb25zdCB7IGFjdGl2ZSwgZGlyZWN0aW9uIH0gPSBzb3J0O1xuICAgIGlmICghYWN0aXZlIHx8ICFkaXJlY3Rpb24pIHJldHVybiBudWxsO1xuICAgIHJldHVybiAoYTogVCwgYjogVCk6IG51bWJlciA9PiB7XG4gICAgICBjb25zdCB2YSA9IHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoYWN0aXZlLCBhKTtcbiAgICAgIGNvbnN0IHZiID0gdGhpcy5nZXRMYXp5QXdhcmVWYWx1ZShhY3RpdmUsIGIpO1xuICAgICAgbGV0IGNtcCA9IDA7XG4gICAgICBpZiAodHlwZW9mIHZhID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgdmIgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGNtcCA9IHZhIDwgdmIgPyAtMSA6IHZhID4gdmIgPyAxIDogMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHNhID0gdmEgPT0gbnVsbCA/ICcnIDogU3RyaW5nKHZhKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBjb25zdCBzYiA9IHZiID09IG51bGwgPyAnJyA6IFN0cmluZyh2YikudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgY21wID0gc2EgPCBzYiA/IC0xIDogc2EgPiBzYiA/IDEgOiAwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRpcmVjdGlvbiA9PT0gJ2FzYycgPyBjbXAgOiAtY21wO1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldExhenlBd2FyZVZhbHVlKGNvbHVtbktleTogc3RyaW5nLCByb3c6IFQpOiBhbnkge1xuICAgIGNvbnN0IGNvbERlZiA9IHRoaXMuX2NvbHVtbk1hcC5nZXQoY29sdW1uS2V5KTtcbiAgICBpZiAoY29sRGVmPy5sYXp5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGF6eUNvbHVtbkRhdGEuZ2V0KGNvbHVtbktleSk/LmdldChyb3cpID8/IG51bGw7XG4gICAgfVxuICAgIGlmIChjb2xEZWY/LnNvcnRWYWx1ZSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShjb2xEZWYuc29ydFZhbHVlKHJvdywgMCkpO1xuICAgIH1cbiAgICBpZiAoY29sRGVmPy52YWx1ZSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShjb2xEZWYudmFsdWUocm93LCAwKSk7XG4gICAgfVxuICAgIHJldHVybiAocm93IGFzIGFueSlbY29sdW1uS2V5XTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUNlbGxWYWx1ZShjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4sIHJvdzogVCwgaW5kZXg6IG51bWJlcik6IGFueSB7XG4gICAgaWYgKGNvbC5sYXp5KSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzLmdldChjb2wua2V5KSA/PyAnaWRsZSc7XG4gICAgICBpZiAoc3RhdHVzID09PSAnbG9hZGluZycpIHJldHVybiAnX19sYXp5X2xvYWRpbmdfXyc7XG4gICAgICBpZiAoc3RhdHVzID09PSAnZXJyb3InKSByZXR1cm4gJ19fbGF6eV9lcnJvcl9fJztcbiAgICAgIGlmIChzdGF0dXMgPT09ICdsb2FkZWQnKSB7XG4gICAgICAgIGNvbnN0IHJvd01hcCA9IHRoaXMuX2xhenlDb2x1bW5EYXRhLmdldChjb2wua2V5KTtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyb3dNYXA/LmdldChyb3cpID8/ICcnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgY29uc3QgdmFsdWVQcm92aWRlciA9IGNvbC52YWx1ZTtcbiAgICBjb25zdCByYXdWYWx1ZSA9IHZhbHVlUHJvdmlkZXIgPyB2YWx1ZVByb3ZpZGVyKHJvdywgaW5kZXgpIDogKHJvdyBhcyBhbnkpPy5bY29sLmtleV07XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyYXdWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYWdlU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1heCgxLCB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplIHx8IHRoaXMucGFnZVNpemUgfHwgNSk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYWdlU2l6ZU9wdGlvbnMoKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplT3B0aW9ucyB8fCBbNSwgMTAsIDIwXTtcbiAgICBjb25zdCB1bmlxdWUgPSBbLi4ubmV3IFNldChvcHRpb25zLmZpbHRlcigodmFsdWUpID0+IHZhbHVlID4gMCkpXTtcblxuICAgIGlmICghdW5pcXVlLmluY2x1ZGVzKHRoaXMucGFnZVNpemUpKSB7XG4gICAgICB1bmlxdWUucHVzaCh0aGlzLnBhZ2VTaXplKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVBhZ2VTaXplT3B0aW9uc0dyb3VwQnkoKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplT3B0aW9uc0dyb3VwQnkgfHwgdGhpcy5yZXNvbHZlZENvbmZpZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnMgfHwgWzUsIDEwLCAyMF07XG4gICAgY29uc3QgdW5pcXVlID0gWy4uLm5ldyBTZXQob3B0aW9ucy5maWx0ZXIoKHYpID0+IHYgPiAwKSldO1xuICAgIGlmICh0aGlzLmdyb3VwUGFnZVNpemUgPiAwICYmICF1bmlxdWUuaW5jbHVkZXModGhpcy5ncm91cFBhZ2VTaXplKSkge1xuICAgICAgdW5pcXVlLnB1c2godGhpcy5ncm91cFBhZ2VTaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuaXF1ZS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVEZWZhdWx0R3JvdXBQYWdlU2l6ZSgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNmZyA9IHRoaXMucmVzb2x2ZWRDb25maWc7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnNHcm91cEJ5IHx8IGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnM/Lmxlbmd0aCkgcmV0dXJuIG9wdGlvbnNbMF07XG4gICAgcmV0dXJuIGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZSB8fCA1O1xuICB9XG5cbiAgcHJpdmF0ZSB1bmlxdWVDb2x1bW5zQnlLZXkoY29sdW1uczogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcmV0dXJuIGNvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IHtcbiAgICAgIGlmIChzZWVuLmhhcyhjb2x1bW4ua2V5KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBzZWVuLmFkZChjb2x1bW4ua2V5KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhdHRhY2hQYWdpbmF0b3IoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3dQYWdpbmF0aW9uKSB7XG4gICAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5wYWdpbmF0b3IgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucGFnaW5hdG9yKSByZXR1cm47XG5cbiAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5wYWdpbmF0b3IgPSBudWxsO1xuICAgIHRoaXMucGFnaW5hdG9yLnBhZ2VTaXplID0gdGhpcy5wYWdlU2l6ZTtcblxuICAgIGlmICh0aGlzLl9wYWdpbmF0b3JTdWJzY3JpYmVkICE9PSB0aGlzLnBhZ2luYXRvcikge1xuICAgICAgdGhpcy5fcGFnaW5hdG9yU3Vic2NyaWJlZCA9IHRoaXMucGFnaW5hdG9yO1xuICAgICAgdGhpcy5wYWdpbmF0b3IucGFnZS5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucGFnZVNpemUgPSB0aGlzLnBhZ2luYXRvciEucGFnZVNpemU7XG4gICAgICAgIGlmICh0aGlzLl9wZW5kaW5nUmVuZGVyICE9PSBudWxsKSByZXR1cm47XG4gICAgICAgIHRoaXMuX3Byb2plY3RDdXJyZW50UGFnZSgpO1xuICAgICAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGF0dGFjaFNvcnQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNvcnQpIHJldHVybjtcblxuICAgIHRoaXMudGFibGVEYXRhU291cmNlLnNvcnQgPSBudWxsIGFzIGFueTtcblxuICAgIGlmICh0aGlzLl9zb3J0U3Vic2NyaWJlZCAhPT0gdGhpcy5zb3J0KSB7XG4gICAgICB0aGlzLl9zb3J0U3Vic2NyaWJlZCA9IHRoaXMuc29ydDtcbiAgICAgIHRoaXMuc29ydC5zb3J0Q2hhbmdlLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fYWN0aXZlU29ydCA9IHtcbiAgICAgICAgICBhY3RpdmU6IHRoaXMuc29ydC5hY3RpdmUsXG4gICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLnNvcnQuZGlyZWN0aW9uLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zY2hlZHVsZVJlbmRlcigpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbn1cblxuIiwiPHNlY3Rpb24gY2xhc3M9XCJqcXVlcnktdGFibGUtd3JhcHBlclwiPlxuICA8aGVhZGVyIGNsYXNzPVwidGFibGUtaGVhZGVyXCIgKm5nSWY9XCJzaG93VGl0bGVcIj5cbiAgICA8aDM+e3sgdGl0bGUgfX08L2gzPlxuICA8L2hlYWRlcj5cblxuICA8ZGl2XG4gICAgY2xhc3M9XCJ0YWJsZS1sYXlvdXRcIlxuICAgIFtjbGFzcy5zbGljZS1jb2xsYXBzZWRdPVwic2hvd1NsaWNlUGFuZWwgJiYgKHNsaWNlUGFuZWxSZWY/LmlzQ29sbGFwc2VkID8/IGZhbHNlKVwiXG4gICAgW2NsYXNzLm5vLXNsaWNlXT1cIiFzaG93U2xpY2VQYW5lbFwiXG4gID5cbiAgICA8c2xpY2UtcGFuZWxcbiAgICAgIFtzdHlsZS5kaXNwbGF5XT1cInNob3dTbGljZVBhbmVsID8gbnVsbCA6ICdub25lJ1wiXG4gICAgICBbc2xpY2VDb25maWdzXT1cIl9zbGljZUNvbmZpZ3NcIlxuICAgICAgW2NvbHVtbnNdPVwiX3NsaWNlQ29sdW1uc1wiXG4gICAgICBbZGF0YV09XCJfc2xpY2VEYXRhXCJcbiAgICAgIFtsYXp5RGF0YV09XCJfbGF6eUNvbHVtbkRhdGFcIlxuICAgICAgW2xhenlTdGF0dXNdPVwiX2xhenlDb2x1bW5TdGF0dXNcIlxuICAgICAgW3Nob3dUb2dnbGVdPVwiX3NsaWNlU2hvd1RvZ2dsZVwiXG4gICAgICAoZmlsdGVyQ2hhbmdlKT1cIm9uU2xpY2VGaWx0ZXJDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAoZHluYW1pY1NsaWNlS2V5c0NoYW5nZSk9XCJvbkR5bmFtaWNTbGljZUtleXNDaGFuZ2UoJGV2ZW50KVwiXG4gICAgPjwvc2xpY2UtcGFuZWw+XG5cbiAgICA8ZGl2IGNsYXNzPVwidGFibGUtc2hlbGxcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS10b29sYmFyXCIgKm5nSWY9XCJzaG93VG9vbGJhclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdG9vbGJhci1sZWZ0XCI+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInNob3dTZWFyY2hCYXJcIiBjbGFzcz1cInNlYXJjaC1pbnB1dC13cmFwcGVyXCI+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwic2VhcmNoLWljb25cIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCI4LjVcIiBjeT1cIjguNVwiIHI9XCI1LjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIi8+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTMgMTNMMTcgMTdcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VhcmNoUXVlcnlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvblNlYXJjaENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJSZWNoZXJjaGVyLi4uXCJcbiAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2VhcmNoUXVlcnlcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZWFyY2gtY2xlYXItYnRuXCIgKGNsaWNrKT1cInNlYXJjaFF1ZXJ5ID0gJyc7IG9uU2VhcmNoQ2hhbmdlKClcIj7DlzwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzZWFyY2gtY291bnRcIj57eyBmaWx0ZXJlZFJvd0NvdW50IH19PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cInNob3dWaWV3QnV0dG9uXCIgY2xhc3M9XCJ0YWJsZS10b29sYmFyLXJpZ2h0XCI+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2aWV3LWJ0blwiIFttYXRNZW51VHJpZ2dlckZvcl09XCJ2aWV3TWVudVwiICN2aWV3TWVudVRyaWdnZXI9XCJtYXRNZW51VHJpZ2dlclwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidmlldy1idG4taWNvblwiPnNldHRpbmdzPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIFZpZXdcbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIDxtYXQtbWVudSAjdmlld01lbnU9XCJtYXRNZW51XCIgW3BhbmVsQ2xhc3NdPVwiJ3ZpZXctbWVudS1wYW5lbCdcIj5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93RmllbGRzXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZmllbGRzU3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPkNoYW1wczwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aWV3LW1lbnUtc3ViLXZhbHVlXCI+e3sgdmlzaWJsZUNvbHVtbnMubGVuZ3RoIH19L3t7IHRvdGFsQ29sdW1uQ291bnQgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93R3JvdXBCeVNlY3Rpb25cIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJncm91cEJ5U3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPkdyb3VwIGJ5PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1zdWItdmFsdWVcIj57eyBhY3RpdmVHcm91cEJ5TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93QWRkU2xpY2VCdXR0b25cIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJzbGljZUJ5U3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPlNsaWNlIGJ5PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1zdWItdmFsdWVcIj57eyBhY3RpdmVTbGljZUJ5TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuXG4gICAgICAgICAgPG1hdC1tZW51ICNmaWVsZHNTdWJNZW51PVwibWF0TWVudVwiIFtwYW5lbENsYXNzXT1cIid2aWV3LXN1Ym1lbnUtcGFuZWwnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmlldy1zdWJtZW51XCIgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1tZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIG1lbnVCYXNlQ29sdW1uc1wiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFjb2x1bW4ub3B0aW9uYWwgJiYgIWFsbG93Q29sdW1uUmVtb3ZhbFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29sdW1uVmlzaWJpbGl0eUNoYW5nZShjb2x1bW4sICFpc0NvbHVtblZpc2libGUoY29sdW1uLmtleSkpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aWV3LW1lbnUtY2hlY2tcIj57eyBpc0NvbHVtblZpc2libGUoY29sdW1uLmtleSkgPyAn4pyTJyA6ICcnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbHVtbi5pY29uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIiBmb250U2V0PVwibWF0ZXJpYWwtaWNvbnMtb3V0bGluZWRcIj57eyBjb2x1bW4uaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAge3sgY29sTGFiZWwoY29sdW1uKSB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lbnVPcHRpb25hbENvbHVtbnMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1tZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIG1lbnVPcHRpb25hbENvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIihpc0NvbHVtblZpc2libGUoY29sdW1uLmtleSkgJiYgdmlzaWJsZUNvbHVtbnMubGVuZ3RoID09PSAxKSB8fCBnZXRMYXp5Q29sdW1uU3RhdHVzKGNvbHVtbi5rZXkpID09PSAnbG9hZGluZydcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29sdW1uVmlzaWJpbGl0eUNoYW5nZShjb2x1bW4sICFpc0NvbHVtblZpc2libGUoY29sdW1uLmtleSkpXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1jaGVja1wiPnt7IGlzQ29sdW1uVmlzaWJsZShjb2x1bW4ua2V5KSA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb2x1bW4uaWNvblwiIGNsYXNzPVwidmlldy1tZW51LWNvbC1pY29uXCIgZm9udFNldD1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+e3sgY29sdW1uLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAge3sgY29sTGFiZWwoY29sdW1uKSB9fVxuICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4ubGF6eSAmJiBnZXRMYXp5Q29sdW1uU3RhdHVzKGNvbHVtbi5rZXkpID09PSAnbG9hZGluZydcIiBjbGFzcz1cImxhenktbWVudS1zcGlubmVyXCI+4oa7PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4ubGF6eSAmJiBnZXRMYXp5Q29sdW1uU3RhdHVzKGNvbHVtbi5rZXkpID09PSAnZXJyb3InXCIgY2xhc3M9XCJsYXp5LW1lbnUtZXJyb3JcIiB0aXRsZT1cIkVycmV1ciBkZSBjaGFyZ2VtZW50XCI+4pqgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LW1lbnU+XG5cbiAgICAgICAgICA8bWF0LW1lbnUgI2dyb3VwQnlTdWJNZW51PVwibWF0TWVudVwiIFtwYW5lbENsYXNzXT1cIid2aWV3LXN1Ym1lbnUtcGFuZWwnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmlldy1zdWJtZW51XCIgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1tZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgY29sIG9mIGdyb3VwQnlDb2x1bW5zXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImFjdGl2ZUdyb3VwQnlLZXkgPT09IGNvbC5rZXlcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkdyb3VwQnlDaGFuZ2UoYWN0aXZlR3JvdXBCeUtleSA9PT0gY29sLmtleSA/IG51bGwgOiBjb2wua2V5KVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LWNoZWNrXCI+e3sgYWN0aXZlR3JvdXBCeUtleSA9PT0gY29sLmtleSA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29sLmljb25cIiBjbGFzcz1cInZpZXctbWVudS1jb2wtaWNvblwiIGZvbnRTZXQ9XCJtYXRlcmlhbC1pY29ucy1vdXRsaW5lZFwiPnt7IGNvbC5pY29uIH19PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICB7eyBjb2xMYWJlbChjb2wpIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtbWVudT5cblxuICAgICAgICAgIDxtYXQtbWVudSAjc2xpY2VCeVN1Yk1lbnU9XCJtYXRNZW51XCIgW3BhbmVsQ2xhc3NdPVwiJ3ZpZXctc3VibWVudS1wYW5lbCdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2aWV3LXN1Ym1lbnVcIiAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtaXRlbVwiICpuZ0Zvcj1cImxldCBzIG9mIHN0YXRpY1NsaWNlc0Zvck1lbnVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTdGF0aWNTbGljZShzLmtleSlcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1jaGVja1wiPnt7IGlzU3RhdGljU2xpY2VWaXNpYmxlKHMua2V5KSA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwicy5pY29uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIiBmb250U2V0PVwibWF0ZXJpYWwtaWNvbnMtb3V0bGluZWRcIj57eyBzLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7IHMudGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhbGxEeW5hbWljU2xpY2VDb2x1bW5zLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1pdGVtXCIgKm5nRm9yPVwibGV0IGNvbCBvZiBhbGxEeW5hbWljU2xpY2VDb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNEeW5hbWljU2xpY2VBY3RpdmUoY29sLmtleSlcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUR5bmFtaWNTbGljZShjb2wpXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1jaGVja1wiPnt7IGlzRHluYW1pY1NsaWNlQWN0aXZlKGNvbC5rZXkpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbC5pY29uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIiBmb250U2V0PVwibWF0ZXJpYWwtaWNvbnMtb3V0bGluZWRcIj57eyBjb2wuaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICB7eyBjb2xMYWJlbChjb2wpIH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWJvZHktd3JhcHBlclwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWJvZHktc2Nyb2xsXCIgI3RhYmxlQm9keVNjcm9sbD5cbiAgICAgIDx0YWJsZSBtYXQtdGFibGUgbWF0U29ydCBbZGF0YVNvdXJjZV09XCJ0YWJsZURhdGFTb3VyY2VcIiBjbGFzcz1cImpxdWVyeS10YWJsZVwiXG4gICAgICAgICAgICAgW3RyYWNrQnldPVwidHJhY2tSb3dGblwiXG4gICAgICAgICAgICAgW21hdFNvcnRBY3RpdmVdPVwiX21hdFNvcnRBY3RpdmVcIiBbbWF0U29ydERpcmVjdGlvbl09XCJfbWF0U29ydERpcmVjdGlvblwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdmlzaWJsZUNvbHVtbnNcIiBbbWF0Q29sdW1uRGVmXT1cImNvbHVtbi5rZXlcIj5cbiAgICAgICAgICA8dGhcbiAgICAgICAgICAgIG1hdC1oZWFkZXItY2VsbFxuICAgICAgICAgICAgKm1hdEhlYWRlckNlbGxEZWZcbiAgICAgICAgICAgIFttYXQtc29ydC1oZWFkZXJdPVwiY29sdW1uLnNvcnRhYmxlICE9PSBmYWxzZSA/IGNvbHVtbi5rZXkgOiAnJ1wiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiY29sdW1uLnNvcnRhYmxlID09PSBmYWxzZVwiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sdW1uLndpZHRoIHx8IG51bGxcIlxuICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aF09XCJjb2x1bW4ud2lkdGggfHwgbnVsbFwiXG4gICAgICAgICAgICBbY2xhc3MuZHJhZy1lbmFibGVkXT1cImlzQ29sdW1uRHJhZ0Ryb3BFbmFibGVkXCJcbiAgICAgICAgICAgIFtjbGFzcy5kcm9wLXRhcmdldF09XCJpc0hlYWRlckRyb3BUYXJnZXQoY29sdW1uLmtleSlcIlxuICAgICAgICAgICAgKGRyYWdvdmVyKT1cIm9uSGVhZGVyRHJhZ092ZXIoY29sdW1uLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAoZHJvcCk9XCJvbkhlYWRlckRyb3AoY29sdW1uLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWQtY2VsbFwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb2x1bW4uaWNvblwiIGNsYXNzPVwiaGVhZC1pY29uXCIgZm9udFNldD1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+e3sgY29sdW1uLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlYWQtdGV4dFwiIFt0aXRsZV09XCJjb2x1bW4uaGVhZGVyXCI+e3sgY29sdW1uLmhlYWRlciB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAqbmdJZj1cImlzQ29sdW1uRHJhZ0Ryb3BFbmFibGVkXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImRyYWctaGFuZGxlXCJcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uSGVhZGVyRHJhZ1N0YXJ0KGNvbHVtbi5rZXksICRldmVudClcIlxuICAgICAgICAgICAgICAgIChkcmFnZW5kKT1cIm9uSGVhZGVyRHJhZ0VuZCgpXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5kcmFnX2luZGljYXRvcjwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sdW1uLndpZHRoIHx8IG51bGxcIlxuICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aF09XCJjb2x1bW4ud2lkdGggfHwgbnVsbFwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENlbGxUZW1wbGF0ZShjb2x1bW4ua2V5KSBhcyBjdXN0b21UcGw7IGVsc2UgZGVmYXVsdENlbGxUcGxcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImN1c3RvbVRwbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IHJvdy5fX3JhdywgaW5kZXg6IHJvdy5fX2luZGV4IH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0Q2VsbFRwbD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwiY29sdW1uLmxhenkgPyBnZXRMYXp5UmVuZGVyVHlwZShyb3dbY29sdW1uLmtleV0pIDogJ3ZhbHVlJ1wiPlxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInbG9hZGluZydcIiBjbGFzcz1cImxhenktc2tlbGV0b25cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdTd2l0Y2hDYXNlPVwiJ2Vycm9yJ1wiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImxhenktZXJyb3ItYnRuXCIgKGNsaWNrKT1cInJldHJ5TGF6eUNvbHVtbihjb2x1bW4pXCIgdGl0bGU9XCJFcnJldXIgZGUgY2hhcmdlbWVudCDigJQgY2xpcXVlciBwb3VyIHLDqWVzc2F5ZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGF6eS1lcnJvci1pY29uXCI+4pqgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYXp5LWVycm9yLWxhYmVsXCI+UsOpZXNzYXllcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hEZWZhdWx0IGNsYXNzPVwiY2VsbC10ZXh0XCIgW2NsYXNzLmNlbGwtZW1wdHldPVwiaXNDZWxsRW1wdHkocm93W2NvbHVtbi5rZXldKVwiIFt0aXRsZV09XCJhc1RpdGxlKHJvd1tjb2x1bW4ua2V5XSlcIj57eyBpc0NlbGxFbXB0eShyb3dbY29sdW1uLmtleV0pID8gJ04vQScgOiByb3dbY29sdW1uLmtleV0gfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cInJlbmRlcmVkQ29sdW1uczsgc3RpY2t5OiB0cnVlXCI+PC90cj5cbiAgICAgICAgPHRyXG4gICAgICAgICAgbWF0LXJvd1xuICAgICAgICAgICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiByZW5kZXJlZENvbHVtbnM7IHdoZW46ICFpc0dyb3VwSGVhZGVyXCJcbiAgICAgICAgICBbYXR0ci50YWJpbmRleF09XCJoYXNSb3dDbGlja0hhbmRsZXIgPyAwIDogbnVsbFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0Um93Q2xhc3Mocm93KVwiXG4gICAgICAgICAgW2NsYXNzLm5vLXBvaW50ZXJdPVwiIWhhc1Jvd0NsaWNrSGFuZGxlclwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uUm93Q2xpY2socm93LCAkZXZlbnQpXCJcbiAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvblJvd0NsaWNrKHJvdywgbnVsbClcIlxuICAgICAgICAgIChrZXlkb3duLnNwYWNlKT1cIm9uUm93Q2xpY2socm93LCBudWxsKVwiXG4gICAgICAgID48L3RyPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIl9fZ3JvdXBfcm93XCI+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIFthdHRyLmNvbHNwYW5dPVwicmVuZGVyZWRDb2x1bW5zLmxlbmd0aFwiIGNsYXNzPVwiZ3JvdXAtaGVhZGVyLWNlbGxcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1oZWFkZXItbGFiZWxcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncm91cC1jaGV2cm9uXCIgW2NsYXNzLmNvbGxhcHNlZF09XCJpc0dyb3VwQ29sbGFwc2VkKHJvdy5fX2dyb3VwS2V5KVwiICpuZ0lmPVwicm93Ll9fZ3JvdXBLZXkgIT09ICdfX2xhenlfbG9hZGluZ19fJyAmJiByb3cuX19ncm91cEtleSAhPT0gJ19fdG9vX21hbnlfZ3JvdXBzX18nXCI+4oC6PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInJvdy5fX2dyb3VwS2V5ICE9PSAnX19sYXp5X2xvYWRpbmdfXycgJiYgcm93Ll9fZ3JvdXBLZXkgIT09ICdfX3Rvb19tYW55X2dyb3Vwc19fJ1wiIGNsYXNzPVwiZ3JvdXAta2V5LWxhYmVsXCI+e3sgcm93Ll9fZ3JvdXBLZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwicm93Ll9fZ3JvdXBLZXkgPT09ICdfX2xhenlfbG9hZGluZ19fJ1wiIGNsYXNzPVwibGF6eS1za2VsZXRvbiBncm91cC1sYXp5LWtleS1za2VsZXRvblwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJyb3cuX19ncm91cEtleSA9PT0gJ19fdG9vX21hbnlfZ3JvdXBzX18nXCIgY2xhc3M9XCJncm91cC10b28tbWFueS1sYWJlbFwiPuKaoCBUcm9wIGRlIGdyb3VwZXMgKHt7IHJvdy5fX2dyb3VwQ291bnQgfX0pIOKAlCBhZmZpbmV6IGxlcyBkb25uw6llcyBvdSBjaG9pc2lzc2V6IHVuZSBhdXRyZSBjb2xvbm5lPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyb3VwLWNvdW50LWJhZGdlXCI+e3sgcm93Ll9fZ3JvdXBDb3VudCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLXBhZ2luYXRpb25cIiAqbmdJZj1cIiFpc0dyb3VwQ29sbGFwc2VkKHJvdy5fX2dyb3VwS2V5KSAmJiByb3cuX19ncm91cFBhZ2VDb3VudCA+IDFcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJncm91cC1wYWdlLWJ0blwiIFtkaXNhYmxlZF09XCJyb3cuX19ncm91cFBhZ2UgPT09IDBcIiAoY2xpY2spPVwiZ3JvdXBQYWdlQmFjayhyb3cuX19ncm91cEtleSlcIj7igLk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyb3VwLXBhZ2UtaW5mb1wiPnt7IHJvdy5fX2dyb3VwUGFnZSArIDEgfX3CoC/CoHt7IHJvdy5fX2dyb3VwUGFnZUNvdW50IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZ3JvdXAtcGFnZS1idG5cIiBbZGlzYWJsZWRdPVwicm93Ll9fZ3JvdXBQYWdlID49IHJvdy5fX2dyb3VwUGFnZUNvdW50IC0gMVwiIChjbGljayk9XCJncm91cFBhZ2VGb3J3YXJkKHJvdy5fX2dyb3VwS2V5LCByb3cuX19ncm91cENvdW50KVwiPuKAujwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8dHIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogWydfX2dyb3VwX3JvdyddOyB3aGVuOiBpc0dyb3VwSGVhZGVyXCJcbiAgICAgICAgICAgIGNsYXNzPVwiZ3JvdXAtaGVhZGVyLXJvd1wiXG4gICAgICAgICAgICBbY2xhc3MuZ3JvdXAtaGVhZGVyLWxvYWRpbmddPVwicm93Ll9fZ3JvdXBLZXkgPT09ICdfX2xhenlfbG9hZGluZ19fJ1wiXG4gICAgICAgICAgICBbY2xhc3MuZ3JvdXAtaGVhZGVyLXRvby1tYW55XT1cInJvdy5fX2dyb3VwS2V5ID09PSAnX190b29fbWFueV9ncm91cHNfXydcIlxuICAgICAgICAgICAgW2F0dHIuZGF0YS1ncm91cC1rZXldPVwicm93Ll9fZ3JvdXBLZXlcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInJvdy5fX2dyb3VwS2V5ICE9PSAnX19sYXp5X2xvYWRpbmdfXycgJiYgcm93Ll9fZ3JvdXBLZXkgIT09ICdfX3Rvb19tYW55X2dyb3Vwc19fJyAmJiB0b2dnbGVHcm91cENvbGxhcHNlKHJvdy5fX2dyb3VwS2V5KVwiPjwvdHI+XG4gICAgICAgIDx0ciBjbGFzcz1cIm1hdC1tZGMtcm93IG5vLWRhdGEtcm93XCIgKm1hdE5vRGF0YVJvdz5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJtYXQtbWRjLWNlbGwgbm8tZGF0YS1jZWxsXCIgW2F0dHIuY29sc3Bhbl09XCJyZW5kZXJlZENvbHVtbnMubGVuZ3RoXCI+PC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj48IS0tIC90YWJsZS1ib2R5LXNjcm9sbCAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1ib2R5LW92ZXJsYXlcIiAqbmdJZj1cImVmZmVjdGl2ZUlzTG9hZGluZyB8fCBpc0VtcHR5XCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGFibGUtYm9keS1vdmVybGF5LXRleHRcIj57eyBlZmZlY3RpdmVJc0xvYWRpbmcgPyBsb2FkaW5nU3RhdGVMYWJlbCA6IGVtcHR5U3RhdGVMYWJlbCB9fTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+PCEtLSAvdGFibGUtYm9keS13cmFwcGVyIC0tPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWJhclwiICpuZ0lmPVwic2hvd1BhZ2luYXRpb25cIj5cbiAgICAgICAgPG1hdC1wYWdpbmF0b3JcbiAgICAgICAgICBbbGVuZ3RoXT1cInRvdGFsUm93c1wiXG4gICAgICAgICAgW3BhZ2VTaXplXT1cInBhZ2VTaXplXCJcbiAgICAgICAgICBbcGFnZVNpemVPcHRpb25zXT1cInBhZ2VTaXplT3B0aW9uc1wiXG4gICAgICAgID48L21hdC1wYWdpbmF0b3I+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXJcIiAqbmdJZj1cImFjdGl2ZUdyb3VwQnlLZXlcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXItY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXItbGVmdFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJncm91cC1yZXNldC1idG5cIiAoY2xpY2spPVwib25Hcm91cEJ5Q2hhbmdlKG51bGwpXCI+XG4gICAgICAgICAgICAgIDxzdmcgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwiZ3JvdXAtcmVzZXQtaWNvblwiPlxuICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMyA4YTUgNSAwIDEgMCA1LTUgNSA1IDAgMCAwLTMuNTQgMS40NkwzIDNcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjRcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zIDN2Mi41SDUuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIFJldGlyZXIgbGUgZ3JvdXBlXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1iYXItc2VwYXJhdG9yXCI+PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JvdXAtc29ydC1jb250cm9sc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyb3VwLXNvcnQtbGFiZWxcIj5UcmllciA6PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImdyb3VwLXNvcnQtYnRuXCIgW2NsYXNzLmFjdGl2ZV09XCJncm91cFNvcnRPcmRlciA9PT0gJ2FzYydcIiAoY2xpY2spPVwib25Hcm91cFNvcnRUb2dnbGUoJ2FzYycpXCIgdGl0bGU9XCJBIOKGkiBaXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmFycm93X3Vwd2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImdyb3VwLXNvcnQtYnRuXCIgW2NsYXNzLmFjdGl2ZV09XCJncm91cFNvcnRPcmRlciA9PT0gJ2Rlc2MnXCIgKGNsaWNrKT1cIm9uR3JvdXBTb3J0VG9nZ2xlKCdkZXNjJylcIiB0aXRsZT1cIlog4oaSIEFcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemUtbGFiZWxcIj5MaWduZXMgcGFyIGdyb3VwZSA6PC9kaXY+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBzdWJzY3JpcHRTaXppbmc9XCJkeW5hbWljXCIgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemUtc2VsZWN0XCI+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJncm91cFBhZ2VTaXplXCJcbiAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkdyb3VwUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgcGFuZWxDbGFzcz1cIm1hdC1tZGMtcGFnaW5hdG9yLXNlbGVjdC1wYWdlLXNpemUgZ3JvdXAtcGFnZS1zaXplLXBhbmVsXCJcbiAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCInYXV0bydcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QtdHJpZ2dlcj57eyBncm91cFBhZ2VTaXplID09PSAwID8gJ1RvdXRlcycgOiBncm91cFBhZ2VTaXplIH19PC9tYXQtc2VsZWN0LXRyaWdnZXI+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBwYWdlU2l6ZU9wdGlvbnNHcm91cEJ5XCIgW3ZhbHVlXT1cIm9wdFwiPnt7IG9wdCB9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMFwiPlRvdXRlczwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3NlY3Rpb24+XG4iXX0=
|
|
1403
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktdGFibGUvc3JjL2xpYi9jb21wb25lbnQvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktdGFibGUvc3JjL2xpYi9jb21wb25lbnQvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBbUMsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUF3QixNQUFNLEVBQUUsU0FBUyxFQUE4QixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDelEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDakcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFN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Z0JBRUcsWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxhQUFhO3NCQUF0QixNQUFNO2dCQUVHLGFBQWE7c0JBQXRCLE1BQU07Z0JBR0gsU0FBUztzQkFEWixTQUFTO3VCQUFDLFlBQVk7Z0JBVUgsSUFBSTtzQkFBdkIsU0FBUzt1QkFBQyxPQUFPO2dCQUNZLGtCQUFrQjtzQkFBL0MsU0FBUzt1QkFBQyxpQkFBaUI7Z0JBQ0ksYUFBYTtzQkFBNUMsU0FBUzt1QkFBQyxtQkFBbUI7Z0JBQ0EsZUFBZTtzQkFBNUMsU0FBUzt1QkFBQyxpQkFBaUI7Z0JBQ1UsU0FBUztzQkFBOUMsZUFBZTt1QkFBQyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbnRlbnRDaGlsZHJlbiwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LCBOZ1pvbmUsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgU2ltcGxlQ2hhbmdlcywgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGl2aWRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpdmlkZXInO1xuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xuaW1wb3J0IHsgTWF0TWVudU1vZHVsZSwgTWF0TWVudVRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9tZW51JztcbmltcG9ydCB7IE1hdFBhZ2luYXRvciwgTWF0UGFnaW5hdG9ySW50bCwgTWF0UGFnaW5hdG9yTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcGFnaW5hdG9yJztcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5pbXBvcnQgeyBNYXRTb3J0LCBNYXRTb3J0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc29ydCc7XG5pbXBvcnQgeyBNYXRUYWJsZURhdGFTb3VyY2UsIE1hdFRhYmxlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBUYWJsZUNvbHVtblByb3ZpZGVyLCBUYWJsZVByb3ZpZGVyLCBUYWJsZVZpZXdDb25maWcgfSBmcm9tICcuLi9qcXVlcnktdGFibGUubW9kZWwnO1xuaW1wb3J0IHsgSnF0STE4biwgSlFUX0kxOE4sIEpRVF9JMThOX0RFRkFVTFRTIH0gZnJvbSAnLi4vanF0LWkxOG4udG9rZW4nO1xuaW1wb3J0IHsgSnF0Q2VsbERlZkRpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZS9qcXQtY2VsbC1kZWYuZGlyZWN0aXZlJztcbmltcG9ydCB7IFNsaWNlQ29uZmlnIH0gZnJvbSAnLi9zbGljZS1wYW5lbC9zbGljZS1wYW5lbC5tb2RlbCc7XG5pbXBvcnQgeyBTbGljZVBhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zbGljZS1wYW5lbC9zbGljZS1wYW5lbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgZ2V0RnJlbmNoUGFnaW5hdG9ySW50bCwgaHVtYW5pemVLZXksIG5vcm1hbGl6ZUNlbGxWYWx1ZSB9IGZyb20gJy4vdGFibGUudXRpbHMnO1xuaW1wb3J0IHsgVmlld0ZhY2FkZSB9IGZyb20gJy4vdmlldy92aWV3LmZhY2FkZSc7XG5pbXBvcnQgeyBMYXp5Q29sdW1uTWFuYWdlciB9IGZyb20gJy4vbGF6eS1jb2x1bW4tbWFuYWdlcic7XG5pbXBvcnQgeyBUYWJsZVByZWZlcmVuY2VzTWFuYWdlciB9IGZyb20gJy4vdGFibGUtcHJlZmVyZW5jZXMubWFuYWdlcic7XG5pbXBvcnQgeyBHcm91cEJ5TWFuYWdlciB9IGZyb20gJy4vZ3JvdXAtYnkubWFuYWdlcic7XG5pbXBvcnQgeyBFeHBvcnRNYW5hZ2VyIH0gZnJvbSAnLi9leHBvcnQubWFuYWdlcic7XG5pbXBvcnQge1xuICBHUk9VUF9ST1dfQ09MVU1OLCBHUk9VUF9IRUFERVJfTUFSS0VSLFxuICBHUk9VUF9LRVlfTEFaWV9MT0FESU5HLCBHUk9VUF9LRVlfVE9PX01BTlksXG4gIFJPV19SQVdfS0VZLCBST1dfSU5ERVhfS0VZLFxuICBST1dfR1JPVVBfS0VZLCBST1dfR1JPVVBfQ09VTlQsIFJPV19HUk9VUF9QQUdFLCBST1dfR1JPVVBfUEFHRV9DT1VOVCxcbiAgTEFaWV9MT0FESU5HX1ZBTFVFLCBMQVpZX0VSUk9SX1ZBTFVFLFxufSBmcm9tICcuL3RhYmxlLmNvbnN0YW50cyc7XG5cbi8qKiBDYWNoZSBpbnRlcm5lIGR1IGdyb3VwZW1lbnQg4oCUIGludmFsaWTDqSBkw6hzIHF1ZSBsZXMgZG9ubsOpZXMsIGxhIGNsw6kgb3UgbGVzIHBhcmFtw6h0cmVzIGRlIHRyaSBjaGFuZ2VudC4gKi9cbmludGVyZmFjZSBHcm91cEJ5Q2FjaGU8VD4ge1xuICByb3dzOiBUW107XG4gIGtleTogc3RyaW5nO1xuICBzb3J0T3JkZXI6ICdhc2MnIHwgJ2Rlc2MnO1xuICBzb3J0QWN0aXZlOiBzdHJpbmc7XG4gIHNvcnREaXI6IHN0cmluZztcbiAgb3JkZXI6IHN0cmluZ1tdO1xuICBtYXA6IE1hcDxzdHJpbmcsIFRbXT47XG59XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ2pxdWVyeS10YWJsZScsXG4gIGltcG9ydHM6IFsgQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgTWF0VGFibGVNb2R1bGUsIE1hdEJ1dHRvbk1vZHVsZSwgTWF0RGl2aWRlck1vZHVsZSwgTWF0UGFnaW5hdG9yTW9kdWxlLCBNYXRTb3J0TW9kdWxlLCBNYXRNZW51TW9kdWxlLCBNYXRJY29uTW9kdWxlLCBNYXRTZWxlY3RNb2R1bGUsIFNsaWNlUGFuZWxDb21wb25lbnQgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGFibGUuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW3sgcHJvdmlkZTogTWF0UGFnaW5hdG9ySW50bCwgdXNlRmFjdG9yeTogZ2V0RnJlbmNoUGFnaW5hdG9ySW50bCB9XSxcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQ8VCA9IGFueT4gaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGNvbmZpZz86IFRhYmxlUHJvdmlkZXI8VD47XG5cbiAgQElucHV0KCkgZGF0YVNvdXJjZT86IFRbXSB8IHsgZGF0YTogVFtdIH07XG4gIEBJbnB1dCgpIGRhdGE/OiBUW107XG4gIEBJbnB1dCgpIGRpc3BsYXllZENvbHVtbnM/OiBzdHJpbmdbXTtcbiAgQElucHV0KCkgY29sdW1uc0NvbmZpZz86IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXTtcblxuICAvKipcbiAgICogTW9kZSBIVE1MIDogYWN0aXZlIGV0IGNvbmZpZ3VyZSBsZSBwYW5uZWF1IFZpZXcgaW5kw6lwZW5kYW1tZW50IGR1IGBbY29uZmlnXWAuXG4gICAqIFByZW5kIGxlIGRlc3N1cyBzdXIgYGNvbmZpZy52aWV3YCBzaSBkw6lmaW5pLlxuICAgKiBFeGVtcGxlIDogYDxqcXVlcnktdGFibGUgW3ZpZXddPVwieyBlbmFibGVkOiB0cnVlIH1cIj5gXG4gICAqL1xuICBASW5wdXQoKSB2aWV3PzogVGFibGVWaWV3Q29uZmlnO1xuXG4gIEBJbnB1dCgpIGNvbHVtbkxhYmVscz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIEBJbnB1dCgpIGlzTG9hZGluZyA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBhZGRSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5BZGRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVDb2x1bW5Qcm92aWRlcjxUPj4oKTtcbiAgQE91dHB1dCgpIGNvbHVtblJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4+KCk7XG4gIEBPdXRwdXQoKSBjYXRlZ29yeVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSByb3dTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcblxuICAvKiogw4ltaXMgw6AgY2hhcXVlIGNoYW5nZW1lbnQgZGUgdHJpICh5IGNvbXByaXMgbGUgdHJpIGluaXRpYWwpLiAqL1xuICBAT3V0cHV0KCkgc29ydENoYW5nZSAgICA9IG5ldyBFdmVudEVtaXR0ZXI8eyBhY3RpdmU6IHN0cmluZzsgZGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyB8ICcnIH0+KCk7XG4gIC8qKiDDiW1pcyDDoCBjaGFxdWUgY2hhbmdlbWVudCBkZSBwYWdlIG91IGRlIHRhaWxsZSBkZSBwYWdlLiAqL1xuICBAT3V0cHV0KCkgcGFnZUNoYW5nZSAgICA9IG5ldyBFdmVudEVtaXR0ZXI8eyBwYWdlSW5kZXg6IG51bWJlcjsgcGFnZVNpemU6IG51bWJlciB9PigpO1xuICAvKiogw4ltaXMgw6AgY2hhcXVlIGNoYW5nZW1lbnQgZGUgbGEgcmVjaGVyY2hlIHRleHRlLiAqL1xuICBAT3V0cHV0KCkgc2VhcmNoQ2hhbmdlICA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogw4ltaXMgcXVhbmQgbGUgR3JvdXAgYnkgY2hhbmdlIChjbMOpIGRlIGNvbG9ubmUsIG91IGBudWxsYCBzaSBkw6lzYWN0aXbDqSkuICovXG4gIEBPdXRwdXQoKSBncm91cEJ5Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmcgfCBudWxsPigpO1xuICAvKiogw4ltaXMgcXVhbmQgbGEgbGlzdGUgZGVzIGNvbG9ubmVzIHZpc2libGVzIGNoYW5nZSAoY2zDqXMgZGFucyBs4oCZb3JkcmUgZOKAmWFmZmljaGFnZSkuICovXG4gIEBPdXRwdXQoKSBjb2x1bW5zQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmdbXT4oKTtcblxuICBAVmlld0NoaWxkKE1hdFBhZ2luYXRvcilcbiAgc2V0IHBhZ2luYXRvcih2YWx1ZTogTWF0UGFnaW5hdG9yIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fcGFnaW5hdG9yID0gdmFsdWU7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLmF0dGFjaFBhZ2luYXRvcigpO1xuICAgICAgdGhpcy5fc2NoZWR1bGVSZW5kZXIoKTtcbiAgICB9XG4gIH1cbiAgZ2V0IHBhZ2luYXRvcigpOiBNYXRQYWdpbmF0b3IgfCB1bmRlZmluZWQgeyByZXR1cm4gdGhpcy5fcGFnaW5hdG9yOyB9XG4gIHByaXZhdGUgX3BhZ2luYXRvcj86IE1hdFBhZ2luYXRvcjtcbiAgQFZpZXdDaGlsZChNYXRTb3J0KSBzb3J0PzogTWF0U29ydDtcbiAgQFZpZXdDaGlsZCgndGFibGVCb2R5U2Nyb2xsJykgdGFibGVCb2R5U2Nyb2xsUmVmPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoU2xpY2VQYW5lbENvbXBvbmVudCkgc2xpY2VQYW5lbFJlZj86IFNsaWNlUGFuZWxDb21wb25lbnQ8VD47XG4gIEBWaWV3Q2hpbGQoJ3ZpZXdNZW51VHJpZ2dlcicpIHZpZXdNZW51VHJpZ2dlcj86IE1hdE1lbnVUcmlnZ2VyO1xuICBAQ29udGVudENoaWxkcmVuKEpxdENlbGxEZWZEaXJlY3RpdmUpIF9jZWxsRGVmcyE6IFF1ZXJ5TGlzdDxKcXRDZWxsRGVmRGlyZWN0aXZlPjtcbiAgLyoqIE1hcCBjbMOp4oaSVGVtcGxhdGVSZWYgcHLDqS1jYWxjdWzDqWUgZGVwdWlzIF9jZWxsRGVmcy4gTWlzZSDDoCBqb3VyIGRhbnMgbmdBZnRlckNvbnRlbnRJbml0IGV0IHN1ciBfY2VsbERlZnMuY2hhbmdlcy4gKi9cbiAgcHJpdmF0ZSBfY2VsbERlZk1hcCA9IG5ldyBNYXA8c3RyaW5nLCBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogYW55OyBpbmRleDogbnVtYmVyIH0+PigpO1xuXG4gIHJlbmRlcmVkQ29sdW1uczogc3RyaW5nW10gPSBbXTtcbiAgdGFibGVEYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZTxhbnk+KFtdKTtcblxuICAvKiogQ29uc3RhbnRlIGV4cG9zw6llIGF1IHRlbXBsYXRlIHBvdXIgbGUgbWF0Q29sdW1uRGVmIGRlIGxhIGxpZ25lIGRlIGdyb3VwZS4gKi9cbiAgcmVhZG9ubHkgX0dST1VQX1JPV19DT0xVTU4gPSBHUk9VUF9ST1dfQ09MVU1OO1xuICAvKiogQ2zDqXMgZCdhY2PDqHMgYXV4IHByb3ByacOpdMOpcyBkZXMgbGlnbmVzIHByb2pldMOpZXMg4oCUIGV4cG9zw6llcyBwb3VyIGxlIHRlbXBsYXRlLiAqL1xuICByZWFkb25seSBfUk9XX1JBV19LRVkgPSBST1dfUkFXX0tFWTtcbiAgcmVhZG9ubHkgX1JPV19JTkRFWF9LRVkgPSBST1dfSU5ERVhfS0VZO1xuICByZWFkb25seSBfUk9XX0dST1VQX0tFWSA9IFJPV19HUk9VUF9LRVk7XG4gIHJlYWRvbmx5IF9ST1dfR1JPVVBfQ09VTlQgPSBST1dfR1JPVVBfQ09VTlQ7XG4gIHJlYWRvbmx5IF9ST1dfR1JPVVBfUEFHRSA9IFJPV19HUk9VUF9QQUdFO1xuICByZWFkb25seSBfUk9XX0dST1VQX1BBR0VfQ09VTlQgPSBST1dfR1JPVVBfUEFHRV9DT1VOVDtcblxuICAvKiogRmFjYWRlIFZpZXcgOiDDqXRhdCBldCBhY3Rpb25zIGNlbnRyYWxpc8OpcyAoQ2hhbXBzIC8gR3JvdXAgYnkgLyBTbGljZSBieSkgKi9cbiAgcmVhZG9ubHkgX3ZpZXcgPSBuZXcgVmlld0ZhY2FkZTxUPigpO1xuXG4gIC8qKlxuICAgKiBTbmFwc2hvdCBzdGFibGUgc3luY2hyb25pc8OpIGRlcHVpcyBfdmlldy5maWVsZHMuYWN0aXZlQ29sdW1ucyBkYW5zIHJlZnJlc2hWaWV3TW9kZWwoKS5cbiAgICogUHJvcHJpw6l0w6kgKG5vbiBnZXR0ZXIpIHBvdXIgcXUnQW5ndWxhciBwdWlzc2UgbGEgc3VpdnJlIHNhbnMgTkcwMTAwLlxuICAgKi9cbiAgYWN0aXZlQ29sdW1uczogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdID0gW107XG5cbiAgYWN0aXZlU2xpY2VGaWx0ZXI6IChyb3c6IFQpID0+IGJvb2xlYW4gPSAoKSA9PiB0cnVlO1xuXG4gIC8vIFByb3ByacOpdMOpcyBzdGFibGVzIHBvdXIgbGVzIGJpbmRpbmdzIGR1IHRlbXBsYXRlIChjb250cmUgZXJyZXVyIE5HMDEwMClcbiAgX3NsaWNlQ29uZmlnczogYW55W10gPSBbXTtcbiAgX3NsaWNlQ29sdW1uczogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdID0gW107XG4gIF9zbGljZURhdGE6IFRbXSA9IFtdO1xuICBfc2xpY2VTaG93VG9nZ2xlID0gdHJ1ZTtcbiAgLyoqIFNuYXBzaG90IHN0YWJsZSBkZSBsYSB2aXNpYmlsaXTDqSBkdSBwYW5uZWF1IHNsaWNlIOKAlCBqYW1haXMgY2FsY3Vsw6kgZGVwdWlzIEBWaWV3Q2hpbGQgKi9cbiAgX3Nob3dTbGljZVBhbmVsID0gZmFsc2U7XG4gIC8qKiBTbmFwc2hvdCBzdGFibGUgZGUgbCfDqXRhdCBjb2xsYXBzZWQgZHUgcGFubmVhdSBzbGljZSwgbWlzIMOgIGpvdXIgdmlhIChjb2xsYXBzZWRDaGFuZ2UpICovXG4gIF9zbGljZVBhbmVsQ29sbGFwc2VkID0gZmFsc2U7XG5cbiAgLy8gRMOpbMOpZ3XDqXMgdmVycyBfdmlldyAoY29uc2VydsOpcyBwb3VyIGNvbXBhdGliaWxpdMOpIHRlbXBsYXRlIHNhbnMgcmVmYWN0b3JpbmcgSFRNTClcbiAgZ2V0IF9zdGF0aWNTbGljZXNGb3JNZW51KCk6IEFycmF5PHsga2V5OiBzdHJpbmc7IHRpdGxlOiBzdHJpbmc7IGljb24/OiBzdHJpbmcgfT4geyByZXR1cm4gdGhpcy5fdmlldy5zdGF0aWNTbGljZXNGb3JNZW51OyB9XG4gIGdldCBfYWN0aXZlRHluYW1pY1NsaWNlQ29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10geyByZXR1cm4gdGhpcy5fdmlldy5zbGljZUJ5LmFjdGl2ZUR5bmFtaWNDb2x1bW5zOyB9XG4gIGdldCBfYXZhaWxhYmxlQ29sdW1uc0ZvckR5bmFtaWNTbGljZSgpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10geyByZXR1cm4gdGhpcy5fdmlldy5zbGljZUJ5LmF2YWlsYWJsZUZvckR5bmFtaWM7IH1cbiAgZ2V0IF9hbGxEeW5hbWljU2xpY2VDb2x1bW5zKCk6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSB7IHJldHVybiB0aGlzLl92aWV3LnNsaWNlQnkuYWxsRHluYW1pY0NvbHVtbnM7IH1cbiAgZ2V0IF9hY3RpdmVTbGljZUJ5TGFiZWwoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX3ZpZXcuc2xpY2VCeS5hY3RpdmVMYWJlbDsgfVxuICBfc2xpY2VCeU1lbnVJdGVtczogQXJyYXk8eyBpc1N0YXRpYzogYm9vbGVhbjsga2V5OiBzdHJpbmc7IHRpdGxlOiBzdHJpbmc7IGljb24/OiBzdHJpbmc7IGNvbD86IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4gfT4gPSBbXTtcblxuICBzZWFyY2hRdWVyeSA9ICcnO1xuICBnZXQgYWN0aXZlR3JvdXBCeUtleSgpOiBzdHJpbmcgfCBudWxsIHsgcmV0dXJuIHRoaXMuX3ZpZXcuZ3JvdXBCeS5hY3RpdmVLZXk7IH1cbiAgX21hdFNvcnRBY3RpdmUgPSAnJztcbiAgX21hdFNvcnREaXJlY3Rpb246ICdhc2MnIHwgJ2Rlc2MnIHwgJycgPSAnJztcbiAgcHJpdmF0ZSBfYWN0aXZlU29ydDogeyBhY3RpdmU6IHN0cmluZzsgZGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyB8ICcnIH0gPSB7IGFjdGl2ZTogJycsIGRpcmVjdGlvbjogJycgfTtcbiAgcHJpdmF0ZSBfc29ydFN1YnNjcmliZWQ6IE1hdFNvcnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIF90b3RhbEZpbHRlcmVkQ291bnQgPSAwO1xuXG4gIC8qKiBHZXN0aW9ubmFpcmUgZHUgbW9kZSBHcm91cCBCeSAow6l0YXQgY29sbGFwc2VkLCBwYWdpbmF0aW9uLCB0cmkgZGVzIGdyb3VwZXMpLiAqL1xuICByZWFkb25seSBfZ3JvdXBCeSA9IG5ldyBHcm91cEJ5TWFuYWdlcihcbiAgICAoKSA9PiB7IHRoaXMuX3Byb2plY3RDdXJyZW50UGFnZSgpOyB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7IH0sXG4gICAgKCkgPT4gdGhpcy5yZWZyZXNoVmlld01vZGVsKCksXG4gICk7XG5cbiAgLyoqIETDqWzDqWd1w6lzIHZlcnMgR3JvdXBCeU1hbmFnZXIgcG91ciBsYSBjb21wYXRpYmlsaXTDqSBkZXMgdGVtcGxhdGVzLiAqL1xuICBnZXQgZ3JvdXBQYWdlU2l6ZSgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fZ3JvdXBCeS5ncm91cFBhZ2VTaXplOyB9XG4gIHNldCBncm91cFBhZ2VTaXplKHY6IG51bWJlcikgeyB0aGlzLl9ncm91cEJ5Lmdyb3VwUGFnZVNpemUgPSB2OyB9XG4gIGdldCBncm91cFNvcnRPcmRlcigpOiAnYXNjJyB8ICdkZXNjJyB7IHJldHVybiB0aGlzLl9ncm91cEJ5Lmdyb3VwU29ydE9yZGVyOyB9XG4gIHNldCBncm91cFNvcnRPcmRlcih2OiAnYXNjJyB8ICdkZXNjJykgeyB0aGlzLl9ncm91cEJ5Lmdyb3VwU29ydE9yZGVyID0gdjsgfVxuXG4gIC8qKiBHZXN0aW9ubmFpcmUgZHUgY3ljbGUgZGUgdmllIGRlcyBjb2xvbm5lcyBsYXp5IChmZXRjaCwgYW5udWxhdGlvbiwgc3RhdHV0cywgZG9ubsOpZXMpLiAqL1xuICBwcml2YXRlIF9sYXp5ID0gbmV3IExhenlDb2x1bW5NYW5hZ2VyPFQ+KCk7XG4gIC8qKiBDb21wYXRpYmlsaXTDqSB0ZW1wbGF0ZSA6IHJldG91cm5lIGxhIG1hcCBkZSBzdGF0dXRzIGxhenkuICovXG4gIGdldCBfbGF6eUNvbHVtblN0YXR1cygpIHsgcmV0dXJuIHRoaXMuX2xhenkuc3RhdHVzOyB9XG4gIC8qKiBDb21wYXRpYmlsaXTDqSB0ZW1wbGF0ZSA6IHJldG91cm5lIGxhIG1hcCBkZSBkb25uw6llcyBsYXp5LiAqL1xuICBnZXQgX2xhenlDb2x1bW5EYXRhKCkgeyByZXR1cm4gdGhpcy5fbGF6eS5kYXRhOyB9XG4gIHByaXZhdGUgX2NkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgX2VsID0gaW5qZWN0KEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KTtcbiAgcHJpdmF0ZSBfbmdab25lID0gaW5qZWN0KE5nWm9uZSk7XG4gIHByaXZhdGUgX2kxOG5SYXcgPSBpbmplY3QoSlFUX0kxOE4sIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgLyoqIExhYmVscyBkZSBs4oCZaW50ZXJmYWNlLiBGdXNpb25uw6lzIGRlcHVpcyBKUVRfSTE4Tl9ERUZBVUxUUyBldCBsZSB0b2tlbiBKUVRfSTE4TiBpbmplY3TDqS4gKi9cbiAgcmVhZG9ubHkgaTE4bjogSnF0STE4biA9IHsgLi4uSlFUX0kxOE5fREVGQVVMVFMsIC4uLih0aGlzLl9pMThuUmF3ID8/IHt9KSB9O1xuXG4gIGlzR3JvdXBIZWFkZXIgPSAoXzogbnVtYmVyLCByb3c6IGFueSk6IGJvb2xlYW4gPT4gcm93W0dST1VQX0hFQURFUl9NQVJLRVJdID09PSB0cnVlO1xuXG4gIC8qKiBSZXRvdXJuZSB0cnVlIHNpIGxhIGxpZ25lIGRlIGdyb3VwZSBlc3QgdW5lIGxpZ25lIG5vcm1hbGUgKG5pIGxhenksIG5pIHRvby1tYW55KS4gKi9cbiAgaXNOb3JtYWxHcm91cFJvdyhyb3c6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiByb3dbUk9XX0dST1VQX0tFWV0gIT09IEdST1VQX0tFWV9MQVpZX0xPQURJTkcgJiYgcm93W1JPV19HUk9VUF9LRVldICE9PSBHUk9VUF9LRVlfVE9PX01BTlk7XG4gIH1cbiAgaXNHcm91cFJvd0xvYWRpbmcocm93OiBhbnkpOiBib29sZWFuIHsgcmV0dXJuIHJvd1tST1dfR1JPVVBfS0VZXSA9PT0gR1JPVVBfS0VZX0xBWllfTE9BRElORzsgfVxuICBpc0dyb3VwUm93VG9vTWFueShyb3c6IGFueSk6IGJvb2xlYW4geyByZXR1cm4gcm93W1JPV19HUk9VUF9LRVldID09PSBHUk9VUF9LRVlfVE9PX01BTlk7IH1cblxuICAvKiogR8OocmUgbGUgY2xpYyBzdXIgdW5lIGxpZ25lIGQnZW4tdMOqdGUgZGUgZ3JvdXBlIChuby1vcCBwb3VyIGxlcyDDqXRhdHMgc3DDqWNpYXV4KS4gKi9cbiAgb25Hcm91cEhlYWRlckNsaWNrKHJvdzogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTm9ybWFsR3JvdXBSb3cocm93KSkgcmV0dXJuO1xuICAgIHRoaXMudG9nZ2xlR3JvdXBDb2xsYXBzZShyb3dbUk9XX0dST1VQX0tFWV0pO1xuICB9XG5cbiAgLyoqIEdlc3Rpb25uYWlyZSBleHBvcnQgQ1NWLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9leHBvcnQgPSBuZXcgRXhwb3J0TWFuYWdlcjxUPihcbiAgICAoKSA9PiB0aGlzLl9hbGxGaWx0ZXJlZFJvd3MsXG4gICAgKCkgPT4gdGhpcy5hY3RpdmVDb2x1bW5zLFxuICAgICgpID0+IHRoaXMucmVzb2x2ZWRDb25maWcuZXhwb3J0LFxuICAgIChjb2wsIHJvdywgaWR4KSA9PiB0aGlzLnJlc29sdmVDZWxsVmFsdWUoY29sLCByb3csIGlkeCksXG4gICk7XG5cbiAgLy8g4pSA4pSAIExpZmVjeWNsZVxuXG4gIHBhZ2VTaXplID0gNTtcbiAgcGFnZVNpemVPcHRpb25zOiBudW1iZXJbXSA9IFs1LCAxMCwgMjBdO1xuICBwYWdlU2l6ZU9wdGlvbnNHcm91cEJ5OiBudW1iZXJbXSA9IFs1LCAxMCwgMjBdO1xuXG4gIGRyYWdnZWRDb2x1bW5LZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBkcmFnT3ZlckNvbHVtbktleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8g4pSA4pSAIE1vZGUgw6lkaXRpb24gKFByw6lmw6lyZW5jZXMpXG4gIC8qKiBWcmFpIHF1YW5kIGxlIG1vZGUgw6lkaXRpb24gZXN0IGFjdGlmIChyZXNpemUgKyBkcmFnIGNvbG9ubmVzLCBpbnRlcmFjdGlvbnMgZMOpc2FjdGl2w6llcykuICovXG4gIF9lZGl0TW9kZSA9IGZhbHNlO1xuICAvKiogTGFyZ2V1cnMgZGUgY29sb25uZXMgcGVyc29ubmFsaXPDqWVzIHBhciBsJ3V0aWxpc2F0ZXVyIChjbMOpIOKGkiBweCkuICovXG4gIF9jb2x1bW5XaWR0aHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgLyoqIE1lc3NhZ2UgZGUgZmVlZGJhY2sgYXByw6hzIHNhdmUvY2xlYXIuIGBudWxsYCA9IHBhcyBkZSBtZXNzYWdlLiAqL1xuICBfcHJlZmVyZW5jZXNNZXNzYWdlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFZyYWkgc2kgdW5lIGNvbmZpZ3VyYXRpb24gZXN0IHNhdXZlZ2FyZMOpZSBwb3VyIGNlIHRhYmxlYXUuICovXG4gIF9oYXNTYXZlZENvbmZpZyA9IGZhbHNlO1xuICBwcml2YXRlIF9wcmVmZXJlbmNlc01hbmFnZXI6IFRhYmxlUHJlZmVyZW5jZXNNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX3Jlc2l6ZVN0YXRlOiB7IGtleTogc3RyaW5nOyBzdGFydFg6IG51bWJlcjsgc3RhcnRXaWR0aDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIER5bmFtaWMgc2xpY2Uga2V5cyDDoCByZXN0YXVyZXIgYXByw6hzIG5nQWZ0ZXJWaWV3SW5pdCAoc2xpY2VQYW5lbFJlZiBwYXMgZW5jb3JlIGRpc3BvKS4gKi9cbiAgcHJpdmF0ZSBfcGVuZGluZ0R5bmFtaWNTbGljZUtleXM6IHN0cmluZ1tdIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBGaWx0cmVzIGRlIHNsaWNlIMOgIHJlc3RhdXJlciBhcHLDqHMgbmdBZnRlclZpZXdJbml0IChzbGljZVBhbmVsUmVmIHBhcyBlbmNvcmUgZGlzcG8pLiAqL1xuICBwcml2YXRlIF9wZW5kaW5nU2xpY2VGaWx0ZXJzOiBSZWNvcmQ8bnVtYmVyLCBzdHJpbmdbXT4gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlc29sdmVkQ29uZmlnOiBUYWJsZVByb3ZpZGVyPFQ+ID0geyBjb2x1bW5zOiBbXSB9O1xuICBwcml2YXRlIF9jb2x1bW5NYXA6IE1hcDxzdHJpbmcsIFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIF9yZXNvbHZlZERhdGE6IFRbXSA9IFtdO1xuICBwcml2YXRlIF9wcmVzZXJ2ZVBhZ2VJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2luaXRpYWxTZWFyY2hBcHBsaWVkID0gZmFsc2U7XG5cbiAgLy8gU2V1aWwgYXUtZGVsw6AgZHVxdWVsIGxlIHJlbmR1IGdyb3Vww6kgZXN0IGJsb3F1w6kgcG91ciBwcm90w6lnZXIgbGUgbmF2aWdhdGV1clxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBNQVhfR1JPVVBfQ09VTlQgPSA1MDA7XG5cbiAgLy8g4pSA4pSAIE9wdGltaXNhdGlvbiBwZXJmb3JtYW5jZVxuICBwcml2YXRlIF9hbGxGaWx0ZXJlZFJvd3M6IFRbXSA9IFtdO1xuICBwcml2YXRlIF9wYWdpbmF0b3JTdWJzY3JpYmVkOiBNYXRQYWdpbmF0b3IgfCBudWxsID0gbnVsbDtcblxuICAvKiogQ2FjaGUgZ3JvdXBCeSDigJQgaW52YWxpZMOpIGTDqHMgcXVlIHJvd3Mva2V5L3RyaSBjaGFuZ2VudC4gKi9cbiAgcHJpdmF0ZSBfZ3JvdXBDYWNoZTogR3JvdXBCeUNhY2hlPFQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX3BlbmRpbmdSZW5kZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBfc3RhdGljU2xpY2VIaWRkZW5LZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHByaXZhdGUgX2NvbmZpZ0hpZGRlbktleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuXG4gIC8qKiBDbMOpcyBkZXMgY29sb25uZXMgdmlzaWJsZXMgZHUgZGVybmllciDDqW1pc3Npb24gY29sdW1uc0NoYW5nZSAocG91ciDDqXZpdGVyIGxlcyDDqW1pc3Npb25zIGR1cGxpcXVlbWVudCkuICovXG4gIHByaXZhdGUgX3ByZXZDb2x1bW5LZXlzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCBkYXRhQ2hhbmdlZCA9ICEhKGNoYW5nZXNbJ2NvbmZpZyddIHx8IGNoYW5nZXNbJ2RhdGEnXSB8fCBjaGFuZ2VzWydkYXRhU291cmNlJ10pO1xuICAgIGlmIChkYXRhQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fbGF6eS5jYW5jZWxBbGwoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2NvbmZpZyddICYmICF0aGlzLl9pbml0aWFsU2VhcmNoQXBwbGllZCkge1xuICAgICAgY29uc3QgaW5pdGlhbCA9IHRoaXMuY29uZmlnPy5zZWFyY2g/LmluaXRpYWxRdWVyeTtcbiAgICAgIGlmIChpbml0aWFsICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zZWFyY2hRdWVyeSA9IGluaXRpYWw7XG4gICAgICAgIHRoaXMuX2luaXRpYWxTZWFyY2hBcHBsaWVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG4gICAgaWYgKGRhdGFDaGFuZ2VkKSB7XG4gICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMuZmlsdGVyKGMgPT4gYy5sYXp5KS5mb3JFYWNoKGMgPT4gdGhpcy50cmlnZ2VyTGF6eUZldGNoKGMpKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVidWlsZENlbGxEZWZNYXAoKTtcbiAgICB0aGlzLl9jZWxsRGVmcy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuX3JlYnVpbGRDZWxsRGVmTWFwKCk7XG4gICAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5hdHRhY2hQYWdpbmF0b3IoKTtcbiAgICB0aGlzLmF0dGFjaFNvcnQoKTtcbiAgICB0aGlzLl9tZWFzdXJlSGVhZGVySGVpZ2h0KCk7XG4gICAgdGhpcy5fYXBwbHlQZW5kaW5nRHluYW1pY1NsaWNlS2V5cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBfYXBwbHlQZW5kaW5nRHluYW1pY1NsaWNlS2V5cygpOiB2b2lkIHtcbiAgICBjb25zdCBoYXNQZW5kaW5nRHluYW1pYyA9ICEhdGhpcy5fcGVuZGluZ0R5bmFtaWNTbGljZUtleXM7XG4gICAgY29uc3QgaGFzUGVuZGluZ0ZpbHRlcnMgPSAhIXRoaXMuX3BlbmRpbmdTbGljZUZpbHRlcnM7XG4gICAgaWYgKCFoYXNQZW5kaW5nRHluYW1pYyAmJiAhaGFzUGVuZGluZ0ZpbHRlcnMpIHJldHVybjtcblxuICAgIGNvbnN0IGFsbENvbHMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgPz8gW107XG4gICAgY29uc3Qga2V5cyA9IGhhc1BlbmRpbmdEeW5hbWljID8gWy4uLnRoaXMuX3BlbmRpbmdEeW5hbWljU2xpY2VLZXlzIV0gOiBbXTtcbiAgICBjb25zdCBmaWx0ZXJzID0gdGhpcy5fcGVuZGluZ1NsaWNlRmlsdGVycyA/IHsgLi4udGhpcy5fcGVuZGluZ1NsaWNlRmlsdGVycyB9IDogbnVsbDtcbiAgICB0aGlzLl9wZW5kaW5nRHluYW1pY1NsaWNlS2V5cyA9IG51bGw7XG4gICAgdGhpcy5fcGVuZGluZ1NsaWNlRmlsdGVycyA9IG51bGw7XG5cbiAgICAvLyBUb3V0IGVzdCBkaWZmw6lyw6kgZGFucyBsZSBtw6ptZSBzZXRUaW1lb3V0IHBvdXIgOlxuICAgIC8vIDEuIMOJdml0ZXIgTkcwMTAwIChtb2RpZmljYXRpb25zIGFwcsOocyB2w6lyaWZpY2F0aW9uIGRhbnMgbmdBZnRlclZpZXdJbml0KVxuICAgIC8vIDIuIEdhcmFudGlyIHF1ZSBsZXMgZHluYW1pYyBzbGljZXMgc29udCBham91dMOpZXMgQVZBTlQgbGEgcmVzdGF1cmF0aW9uIGRlcyBmaWx0cmVzXG4gICAgLy8gICAgKGxlcyBpbmRpY2VzIGRhbnMgc2xpY2VGaWx0ZXJzIGTDqXBlbmRlbnQgZGUgbCdvcmRyZSBmaW5hbCBkZSBfY2FjaGVkU2xpY2VzKVxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbCA9IGFsbENvbHMuZmluZChjID0+IGMua2V5ID09PSBrZXkpO1xuICAgICAgICBpZiAoY29sKSB0aGlzLmFkZER5bmFtaWNTbGljZShjb2wpO1xuICAgICAgfSk7XG4gICAgICBpZiAoZmlsdGVycykge1xuICAgICAgICBpZiAodGhpcy5zbGljZVBhbmVsUmVmKSB7XG4gICAgICAgICAgdGhpcy5zbGljZVBhbmVsUmVmLnJlc3RvcmVGaWx0ZXJzKGZpbHRlcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHNsaWNlUGFuZWxSZWYgdG91am91cnMgbnVsbCAoZG9ubsOpZXMgcGFzIGVuY29yZSBhcnJpdsOpZXMpIDpcbiAgICAgICAgICAvLyByZW1ldHRyZSBlbiBhdHRlbnRlIHBvdXIgcXVlIF9yZWNvbXB1dGVTaG93U2xpY2VQYW5lbCBsZXMgYXBwbGlxdWVcbiAgICAgICAgICB0aGlzLl9wZW5kaW5nU2xpY2VGaWx0ZXJzID0gZmlsdGVycztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3BlbmRpbmdSZW5kZXIgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9wZW5kaW5nUmVuZGVyKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3ByZWZlcmVuY2VzTWVzc2FnZVRpbWVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlVGltZXIpO1xuICAgIH1cbiAgICAvLyBOZXR0b2llIHVuIMOpdmVudHVlbCByZXNpemUgZW4gY291cnMgKGxpc3RlbmVycyB3aW5kb3cgbm9uIHJldGlyw6lzKVxuICAgIHRoaXMuX3Jlc2l6ZVN0YXRlID0gbnVsbDtcbiAgICB0aGlzLl9kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5fZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB0aGlzLl92aWV3LmRlc3Ryb3koKTtcbiAgfVxuXG4gIHByaXZhdGUgX21lYXN1cmVIZWFkZXJIZWlnaHQoKTogdm9pZCB7XG4gICAgY29uc3QgbWVhc3VyZSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlclJvdyA9IHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcigndHIubWF0LW1kYy1oZWFkZXItcm93JykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBpZiAoaGVhZGVyUm93KSB7XG4gICAgICAgIGNvbnN0IGggPSBoZWFkZXJSb3cuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuICAgICAgICBpZiAoaCA+IDApIHtcbiAgICAgICAgICB0aGlzLl9lbC5uYXRpdmVFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWFjdHVhbC1oZWFkZXItaGVpZ2h0JywgaCArICdweCcpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gSGVhZGVyIHBhcyBlbmNvcmUgcmVuZHUgKGV4OiBsYXp5IEFuZ3VsYXIgTWF0ZXJpYWwpLCBvbiByw6llc3NhaWUgYXByw6hzIGxlIHByb2NoYWluIGZyYW1lXG4gICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IG1lYXN1cmUoKSkpO1xuICAgIH07XG4gICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBtZWFzdXJlKCkpKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBHZXR0ZXJzIGQnYWZmaWNoYWdlXG5cbiAgZ2V0IHRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcudGl0bGUgPz8gJyc7XG4gIH1cblxuICBnZXQgc2hvd1RpdGxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMucmVzb2x2ZWRDb25maWcudGl0bGU7XG4gIH1cblxuICBnZXQgdmlzaWJsZUNvbHVtbnMoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVDb2x1bW5zO1xuICB9XG5cbiAgZ2V0IHNob3dTZWFyY2hCYXIoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLnNlYXJjaD8uZW5hYmxlZCA9PT0gdHJ1ZTsgfVxuICBnZXQgc2hvd1ZpZXdCdXR0b24oKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl92aWV3LmVuYWJsZWQgfHwgdGhpcy5zaG93RXhwb3J0QnV0dG9uIHx8IHRoaXMuc2hvd1ByZWZlcmVuY2VzTWVudTsgfVxuICBnZXQgc2hvd1NsaWNlRXhwYW5kQnRuKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fc2hvd1NsaWNlUGFuZWwgJiYgdGhpcy5fc2xpY2VQYW5lbENvbGxhcHNlZCAmJiB0aGlzLl9zbGljZVNob3dUb2dnbGU7IH1cbiAgZ2V0IHNob3dFeHBvcnRCdXR0b24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcuZXhwb3J0Py5lbmFibGVkID09PSB0cnVlO1xuICB9XG4gIGdldCBzaG93UHJlZmVyZW5jZXNNZW51KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLnByZWZlcmVuY2VzPy5lbmFibGVkID09PSB0cnVlO1xuICB9XG4gIGdldCBoYXNTYXZlZFByZWZlcmVuY2VzKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5faGFzU2F2ZWRDb25maWc7IH1cblxuICBnZXQgc2hvd1Rvb2xiYXIoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNob3dTZWFyY2hCYXIgfHwgdGhpcy5zaG93Vmlld0J1dHRvbiB8fCB0aGlzLnNob3dTbGljZUV4cGFuZEJ0bjsgfVxuXG4gIGV4cGFuZFNsaWNlUGFuZWwoKTogdm9pZCB7XG4gICAgdGhpcy5zbGljZVBhbmVsUmVmPy50b2dnbGVQYW5lbCgpO1xuICB9XG4gIGdldCBzaG93RmllbGRzKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fdmlldy5zaG93RmllbGRzOyB9XG4gIGdldCBzaG93R3JvdXBCeVNlY3Rpb24oKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl92aWV3LnNob3dHcm91cEJ5U2VjdGlvbjsgfVxuXG4gIGdldCBmaWx0ZXJlZFJvd0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlR3JvdXBCeUtleSA/IHRoaXMuX3RvdGFsRmlsdGVyZWRDb3VudCA6IHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGg7XG4gIH1cblxuICBnZXQgYWN0aXZlR3JvdXBCeUxhYmVsKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl92aWV3LmFjdGl2ZUdyb3VwQnlMYWJlbDsgfVxuXG4gIGdldCB0b3RhbENvbHVtbkNvdW50KCk6IG51bWJlciB7IHJldHVybiB0aGlzLl92aWV3LnRvdGFsQ29sdW1uQ291bnQ7IH1cblxuICBnZXQgYWN0aXZlU2xpY2VCeUxhYmVsKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl92aWV3LnNsaWNlQnkuYWN0aXZlTGFiZWw7IH1cblxuICBnZXQgYWN0aXZlRHluYW1pY1NsaWNlQ29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10geyByZXR1cm4gdGhpcy5fdmlldy5zbGljZUJ5LmFjdGl2ZUR5bmFtaWNDb2x1bW5zOyB9XG5cbiAgcmVtb3ZlRHluYW1pY1NsaWNlQnlLZXkoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWNlUGFuZWxSZWY/LnJlbW92ZUR5bmFtaWNTbGljZUJ5S2V5KGtleSk7XG4gIH1cblxuICBnZXQgZ3JvdXBCeUNvbHVtbnMoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHsgcmV0dXJuIHRoaXMuX3ZpZXcuZ3JvdXBCeUNvbHVtbnM7IH1cblxuICBjb2xMYWJlbChjb2w6IHsga2V5OiBzdHJpbmc7IGhlYWRlcj86IHN0cmluZyB9KTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX3ZpZXcuY29sTGFiZWwoY29sKTsgfVxuXG4gIC8vIOKUgOKUgCBBY3Rpb25zIHV0aWxpc2F0ZXVyXG5cbiAgb25TZWFyY2hDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSAwO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICAgIHRoaXMucGFnaW5hdG9yPy5maXJzdFBhZ2UoKTtcbiAgICB0aGlzLnNlYXJjaENoYW5nZS5lbWl0KHRoaXMuc2VhcmNoUXVlcnkpO1xuICB9XG5cbiAgb25Hcm91cEJ5Q2hhbmdlKGtleTogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX3ZpZXcuc2V0R3JvdXBCeShrZXkpO1xuICAgIHRoaXMuX2dyb3VwQnkuc2V0RGVmYXVsdENvbGxhcHNlZChrZXkgIT09IG51bGwpO1xuICAgIHRoaXMuX2dyb3VwQnkucmVzZXQoKTtcbiAgICB0aGlzLl9ncm91cEJ5Lmdyb3VwUGFnZVNpemUgPSB0aGlzLnJlc29sdmVEZWZhdWx0R3JvdXBQYWdlU2l6ZSgpO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICAgIHRoaXMucGFnaW5hdG9yPy5maXJzdFBhZ2UoKTtcbiAgICB0aGlzLmdyb3VwQnlDaGFuZ2UuZW1pdChrZXkpO1xuICAgIGlmIChrZXkpIHtcbiAgICAgIHRoaXMudmlld01lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgICAgIGNvbnN0IGNvbERlZiA9ICh0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgfHwgW10pLmZpbmQoYyA9PiBjLmtleSA9PT0ga2V5KTtcbiAgICAgIGlmIChjb2xEZWY/LmxhenkgJiYgdGhpcy5fbGF6eUNvbHVtblN0YXR1cy5nZXQoa2V5KSAhPT0gJ2xvYWRlZCcpIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyTGF6eUZldGNoKGNvbERlZik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy50YWJsZUJvZHlTY3JvbGxSZWY/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgICAgIH0sIDApKTtcbiAgICB9XG4gIH1cblxuICBvbkdyb3VwUGFnZVNpemVDaGFuZ2Uoc2l6ZTogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fZ3JvdXBCeS5vbkdyb3VwUGFnZVNpemVDaGFuZ2UoTnVtYmVyKHNpemUpKTtcbiAgfVxuXG4gIG9uR3JvdXBTb3J0VG9nZ2xlKGRpcjogJ2FzYycgfCAnZGVzYycpOiB2b2lkIHtcbiAgICB0aGlzLl9ncm91cEJ5Lm9uR3JvdXBTb3J0VG9nZ2xlKGRpciwgKGtleSkgPT4ge1xuICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxUb0dyb3VwSGVhZGVyKGtleSksIDApKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBMYXp5IGxvYWRpbmdcblxuICBnZXRMYXp5Q29sdW1uU3RhdHVzKGtleTogc3RyaW5nKTogJ2lkbGUnIHwgJ2xvYWRpbmcnIHwgJ2xvYWRlZCcgfCAnZXJyb3InIHtcbiAgICByZXR1cm4gdGhpcy5fbGF6eS5nZXRTdGF0dXMoa2V5KTtcbiAgfVxuXG4gIGdldExhenlSZW5kZXJUeXBlKHJvd1ZhbHVlOiBhbnkpOiAnbG9hZGluZycgfCAnZXJyb3InIHwgJ3ZhbHVlJyB7XG4gICAgcmV0dXJuIHRoaXMuX2xhenkuZ2V0UmVuZGVyVHlwZShyb3dWYWx1ZSk7XG4gIH1cblxuICByZXRyeUxhenlDb2x1bW4oY29sdW1uOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5fbGF6eS5yZXRyeShjb2x1bW4sIHRoaXMuX3Jlc29sdmVkRGF0YSwgdGhpcy5fbGF6eUNhbGxiYWNrcygpKTtcbiAgfVxuXG4gIHRyaWdnZXJMYXp5RmV0Y2goY29sdW1uOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5fbGF6eS5mZXRjaChjb2x1bW4sIHRoaXMuX3Jlc29sdmVkRGF0YSwgdGhpcy5fbGF6eUNhbGxiYWNrcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2xhenlDYWxsYmFja3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9uUmVmcmVzaDogKCkgPT4gdGhpcy5yZWZyZXNoVmlld01vZGVsKCksXG4gICAgICBvbk1hcmtGb3JDaGVjazogKCkgPT4gdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpLFxuICAgIH07XG4gIH1cblxuICAvLyDilIDilIAgR3JvdXBlbWVudFxuXG4gIHRvZ2dsZUdyb3VwQ29sbGFwc2UoZ3JvdXBLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuX2dyb3VwQnkudG9nZ2xlR3JvdXBDb2xsYXBzZShncm91cEtleSwgKGtleSkgPT4ge1xuICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxUb0dyb3VwSGVhZGVyKGtleSksIDApKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9Hcm91cEhlYWRlcihncm91cEtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy50YWJsZUJvZHlTY3JvbGxSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFjb250YWluZXIpIHJldHVybjtcbiAgICBjb25zdCByb3cgPSBjb250YWluZXIucXVlcnlTZWxlY3RvcjxIVE1MRWxlbWVudD4oYHRyW2RhdGEtZ3JvdXAta2V5PVwiJHtDU1MuZXNjYXBlKGdyb3VwS2V5KX1cIl1gKTtcbiAgICBpZiAoIXJvdykgcmV0dXJuO1xuICAgIGNvbnN0IGhlYWRlckhlaWdodCA9IHBhcnNlRmxvYXQoXG4gICAgICB0aGlzLl9lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmdldFByb3BlcnR5VmFsdWUoJy0tYWN0dWFsLWhlYWRlci1oZWlnaHQnKSB8fCAnNTYnXG4gICAgKSB8fCA1NjtcbiAgICBjb25zdCBjb250YWluZXJSZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHJvd1JlY3QgPSByb3cuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgY3VycmVudFNjcm9sbFRvcCA9IGNvbnRhaW5lci5zY3JvbGxUb3A7XG4gICAgY29uc3QgdGFyZ2V0U2Nyb2xsVG9wID0gY3VycmVudFNjcm9sbFRvcCArIChyb3dSZWN0LnRvcCAtIGNvbnRhaW5lclJlY3QudG9wKSAtIGhlYWRlckhlaWdodDtcbiAgICBjb250YWluZXIuc2Nyb2xsVG8oeyB0b3A6IHRhcmdldFNjcm9sbFRvcCwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICB9XG5cbiAgaXNHcm91cENvbGxhcHNlZChncm91cEtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2dyb3VwQnkuaXNHcm91cENvbGxhcHNlZChncm91cEtleSk7XG4gIH1cblxuICBncm91cFBhZ2VCYWNrKGdyb3VwS2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9ncm91cEJ5Lmdyb3VwUGFnZUJhY2soZ3JvdXBLZXkpO1xuICB9XG5cbiAgZ3JvdXBQYWdlRm9yd2FyZChncm91cEtleTogc3RyaW5nLCB0b3RhbENvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9ncm91cEJ5Lmdyb3VwUGFnZUZvcndhcmQoZ3JvdXBLZXksIHRvdGFsQ291bnQpO1xuICB9XG5cbiAgLy8g4pSA4pSAIENvbG9ubmVzXG5cbiAgZ2V0IGhhc0FkZGFibGVDb2x1bW5zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl92aWV3Lm1lbnVCYXNlQ29sdW1ucy5sZW5ndGggPiAwIHx8IHRoaXMuX3ZpZXcubWVudU9wdGlvbmFsQ29sdW1ucy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IG1lbnVCYXNlQ29sdW1ucygpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLl92aWV3Lm1lbnVCYXNlQ29sdW1ucztcbiAgfVxuXG4gIGdldCBtZW51T3B0aW9uYWxDb2x1bW5zKCk6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZXcubWVudU9wdGlvbmFsQ29sdW1ucztcbiAgfVxuXG4gIGdldCBhdmFpbGFibGVDb2x1bW5zVG9BZGQoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICBjb25zdCBhY3RpdmVLZXlzID0gbmV3IFNldCh0aGlzLmFjdGl2ZUNvbHVtbnMubWFwKChjb2x1bW4pID0+IGNvbHVtbi5rZXkpKTtcbiAgICByZXR1cm4gKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyB8fCBbXSkuZmlsdGVyKChjKSA9PiBjLm9wdGlvbmFsICYmICFhY3RpdmVLZXlzLmhhcyhjLmtleSkpO1xuICB9XG5cbiAgZ2V0IGFsbG93Q29sdW1uUmVtb3ZhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdmlldy5hbGxvd0NvbHVtblJlbW92YWw7XG4gIH1cblxuICAvLyDilIDilIAgU2xpY2VzXG5cbiAgZ2V0IGhhc1NsaWNlQ29uZmlnKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5yZXNvbHZlZENvbmZpZy5zbGljZXM/Lmxlbmd0aCA/PyAwKSA+IDA7XG4gIH1cblxuICBnZXQgc2hvd1NsaWNlUGFuZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3Nob3dTbGljZVBhbmVsO1xuICB9XG5cbiAgb25TbGljZVBhbmVsQ29sbGFwc2VkQ2hhbmdlKGNvbGxhcHNlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuX3NsaWNlUGFuZWxDb2xsYXBzZWQgPSBjb2xsYXBzZWQ7XG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVjb21wdXRlU2hvd1NsaWNlUGFuZWwoKTogdm9pZCB7XG4gICAgY29uc3QgaGFzQ2ZnID0gdGhpcy5fc2xpY2VDb25maWdzLmxlbmd0aCA+IDAgfHwgdGhpcy5fdmlldy5zbGljZUJ5LmFjdGl2ZUR5bmFtaWNDb2x1bW5zLmxlbmd0aCA+IDA7XG4gICAgY29uc3Qgd2FzVmlzaWJsZSA9IHRoaXMuX3Nob3dTbGljZVBhbmVsO1xuICAgIHRoaXMuX3Nob3dTbGljZVBhbmVsID0gaGFzQ2ZnICYmIHRoaXMuX3Jlc29sdmVkRGF0YS5sZW5ndGggPiAwO1xuICAgIC8vIExlIFNsaWNlUGFuZWxDb21wb25lbnQgdmllbnQgZCfDqnRyZSByZW5kdSBwb3VyIGxhIDHDqHJlIGZvaXNcbiAgICAvLyAoZG9ubsOpZXMgYXJyaXbDqWVzKSDihpIgYXBwbGlxdWVyIGxlcyBmaWx0cmVzIGVuIGF0dGVudGVcbiAgICBpZiAoIXdhc1Zpc2libGUgJiYgdGhpcy5fc2hvd1NsaWNlUGFuZWwgJiYgdGhpcy5fcGVuZGluZ1NsaWNlRmlsdGVycykge1xuICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuX3BlbmRpbmdTbGljZUZpbHRlcnM7XG4gICAgICB0aGlzLl9wZW5kaW5nU2xpY2VGaWx0ZXJzID0gbnVsbDtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNsaWNlUGFuZWxSZWY/LnJlc3RvcmVGaWx0ZXJzKGZpbHRlcnMpO1xuICAgICAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgc2hvd0FkZFNsaWNlQnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl92aWV3LnNob3dTbGljZUJ5U2VjdGlvbjtcbiAgfVxuXG4gIGdldCBzdGF0aWNTbGljZXNGb3JNZW51KCk6IEFycmF5PHsga2V5OiBzdHJpbmc7IHRpdGxlOiBzdHJpbmc7IGljb24/OiBzdHJpbmcgfT4ge1xuICAgIHJldHVybiB0aGlzLl92aWV3LnN0YXRpY1NsaWNlc0Zvck1lbnU7XG4gIH1cblxuICBnZXQgYXZhaWxhYmxlQ29sdW1uc0ZvckR5bmFtaWNTbGljZSgpOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLl92aWV3LnNsaWNlQnkuYXZhaWxhYmxlRm9yRHluYW1pYztcbiAgfVxuXG4gIGlzU3RhdGljU2xpY2VWaXNpYmxlKGNvbHVtbktleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLl9zdGF0aWNTbGljZUhpZGRlbktleXMuaGFzKGNvbHVtbktleSk7XG4gIH1cblxuICB0b2dnbGVTdGF0aWNTbGljZShjb2x1bW5LZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0KHRoaXMuX3N0YXRpY1NsaWNlSGlkZGVuS2V5cyk7XG4gICAgaWYgKG5leHQuaGFzKGNvbHVtbktleSkpIG5leHQuZGVsZXRlKGNvbHVtbktleSk7XG4gICAgZWxzZSBuZXh0LmFkZChjb2x1bW5LZXkpO1xuICAgIHRoaXMuX3N0YXRpY1NsaWNlSGlkZGVuS2V5cyA9IG5leHQ7XG4gICAgdGhpcy5fdmlldy51cGRhdGVIaWRkZW5TdGF0aWNLZXlzKHRoaXMuX3N0YXRpY1NsaWNlSGlkZGVuS2V5cyk7XG4gICAgdGhpcy5fc2xpY2VDb25maWdzID0gdGhpcy5fY29tcHV0ZVNsaWNlQ29uZmlncygpO1xuICAgIC8vIFNpIHVuZSBzbGljZSB2aWVudCBkJ8OqdHJlIGNhY2jDqWUsIHLDqWluaXRpYWxpc2UgbGUgZmlsdHJlIGFjdGlmIHBvdXIgw6l2aXRlclxuICAgIC8vIHVuIGZpbHRyZSBvcnBoZWxpbiAobGEgc2xpY2Ugbidlc3QgcGx1cyB2aXNpYmxlIG1haXMgc29uIGZpbHRyZSByZXN0ZXJhaXQgYWN0aWYpXG4gICAgaWYgKG5leHQuaGFzKGNvbHVtbktleSkpIHtcbiAgICAgIHRoaXMuYWN0aXZlU2xpY2VGaWx0ZXIgPSAoKSA9PiB0cnVlO1xuICAgIH1cbiAgICB0aGlzLl9yZWNvbXB1dGVTaG93U2xpY2VQYW5lbCgpO1xuICAgIHRoaXMuX3NjaGVkdWxlUmVuZGVyKCk7XG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgYWRkRHluYW1pY1NsaWNlKGNvbHVtbjogVGFibGVDb2x1bW5Qcm92aWRlcjxUPik6IHZvaWQge1xuICAgIHRoaXMuc2xpY2VQYW5lbFJlZj8uYWRkRHluYW1pY1NsaWNlKGNvbHVtbik7XG4gICAgaWYgKGNvbHVtbi5sYXp5ICYmIHRoaXMuX2xhenlDb2x1bW5TdGF0dXMuZ2V0KGNvbHVtbi5rZXkpICE9PSAnbG9hZGVkJykge1xuICAgICAgdGhpcy50cmlnZ2VyTGF6eUZldGNoKGNvbHVtbik7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGFsbER5bmFtaWNTbGljZUNvbHVtbnMoKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsRHluYW1pY1NsaWNlQ29sdW1ucztcbiAgfVxuXG4gIGlzRHluYW1pY1NsaWNlQWN0aXZlKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZXcuaXNEeW5hbWljU2xpY2VBY3RpdmUoa2V5KTtcbiAgfVxuXG4gIHRvZ2dsZUR5bmFtaWNTbGljZShjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0R5bmFtaWNTbGljZUFjdGl2ZShjb2wua2V5KSkge1xuICAgICAgdGhpcy5yZW1vdmVEeW5hbWljU2xpY2VCeUtleShjb2wua2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGREeW5hbWljU2xpY2UoY29sKTtcbiAgICB9XG4gIH1cblxuICBvblNsaWNlRmlsdGVyQ2hhbmdlKHByZWQ6IChyb3c6IFQpID0+IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZVNsaWNlRmlsdGVyID0gcHJlZDtcbiAgICB0aGlzLl9wcmVzZXJ2ZVBhZ2VJbmRleCA9IDA7XG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG4gICAgdGhpcy5wYWdpbmF0b3I/LmZpcnN0UGFnZSgpO1xuICB9XG5cbiAgb25EeW5hbWljU2xpY2VLZXlzQ2hhbmdlKGtleXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgdGhpcy5fdmlldy5vbkR5bmFtaWNTbGljZUtleXNDaGFuZ2Uoa2V5cyk7XG4gICAgdGhpcy5fcmVjb21wdXRlU2hvd1NsaWNlUGFuZWwoKTtcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgZW1wdHlTdGF0ZUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRDb25maWcubGFiZWxzPy5lbXB0eSB8fCB0aGlzLmkxOG4uZW1wdHlTdGF0ZTtcbiAgfVxuXG4gIGdldCBsb2FkaW5nU3RhdGVMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVkQ29uZmlnLmxhYmVscz8ubG9hZGluZyB8fCB0aGlzLmkxOG4ubG9hZGluZ1N0YXRlO1xuICB9XG5cbiAgZ2V0IGVmZmVjdGl2ZUlzTG9hZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc0xvYWRpbmc7XG4gIH1cblxuICBnZXQgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICAvLyBfcGVuZGluZ1JlbmRlciA6IGxlIHJlbmR1IGludGVybmUgbidlc3QgcGFzIGVuY29yZSB0ZXJtaW7DqSDihpIgcGFzIGRlIG1lc3NhZ2UgdmlkZSBwcsOpbWF0dXLDqVxuICAgIHJldHVybiAhdGhpcy5pc0xvYWRpbmcgJiYgdGhpcy5fcGVuZGluZ1JlbmRlciA9PT0gbnVsbCAmJiB0aGlzLl9hbGxGaWx0ZXJlZFJvd3MubGVuZ3RoID09PSAwO1xuICB9XG5cbiAgZ2V0IHNob3dQYWdpbmF0aW9uKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmFjdGl2ZUdyb3VwQnlLZXkgIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZENvbmZpZy5wYWdpbmF0aW9uPy5lbmFibGVkICE9PSBmYWxzZTtcbiAgfVxuXG4gIGdldCBpc0NvbHVtbkRyYWdEcm9wRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdmlldy5pc0NvbHVtbkRyYWdEcm9wRW5hYmxlZDtcbiAgfVxuXG4gIGdldCB0b3RhbFJvd3MoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVHcm91cEJ5S2V5XG4gICAgICA/IHRoaXMudGFibGVEYXRhU291cmNlLmRhdGEuZmlsdGVyKChyKSA9PiAhcltHUk9VUF9IRUFERVJfTUFSS0VSXSkubGVuZ3RoXG4gICAgICA6IHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGg7XG4gIH1cblxuICAvLyDilIDilIAgR2VzdGlvbiBkZXMgY29sb25uZXNcblxuICBvbkFkZENvbHVtbihjb2x1bW46IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4pOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3LmFkZENvbHVtbihjb2x1bW4pO1xuICAgIHRoaXMuX3ByZXNlcnZlUGFnZUluZGV4ID0gdGhpcy5wYWdpbmF0b3I/LnBhZ2VJbmRleCA/PyBudWxsO1xuICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuXG4gICAgaWYgKGNvbHVtbi5sYXp5KSB7XG4gICAgICB0aGlzLnRyaWdnZXJMYXp5RmV0Y2goY29sdW1uKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZFJlcXVlc3RlZC5lbWl0KCk7XG4gICAgdGhpcy5jb2x1bW5BZGRlZC5lbWl0KGNvbHVtbik7XG4gIH1cblxuICBvbkNvbHVtblZpc2liaWxpdHlDaGFuZ2UoY29sdW1uOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+LCBjaGVja2VkOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgaXNWaXNpYmxlID0gdGhpcy5fdmlldy5pc0NvbHVtblZpc2libGUoY29sdW1uLmtleSk7XG5cbiAgICBpZiAoY2hlY2tlZCAmJiAhaXNWaXNpYmxlKSB7XG4gICAgICB0aGlzLm9uQWRkQ29sdW1uKGNvbHVtbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjaGVja2VkICYmIGlzVmlzaWJsZSkge1xuICAgICAgY29uc3QgcmVtb3ZlZCA9IHRoaXMuX3ZpZXcucmVtb3ZlQ29sdW1uKGNvbHVtbi5rZXkpO1xuICAgICAgaWYgKCFyZW1vdmVkKSByZXR1cm47XG4gICAgICB0aGlzLl9wcmVzZXJ2ZVBhZ2VJbmRleCA9IHRoaXMucGFnaW5hdG9yPy5wYWdlSW5kZXggPz8gbnVsbDtcbiAgICAgIHRoaXMucmVmcmVzaFZpZXdNb2RlbCgpO1xuICAgICAgdGhpcy5jb2x1bW5SZW1vdmVkLmVtaXQoY29sdW1uKTtcbiAgICB9XG4gIH1cblxuICBpc0NvbHVtblZpc2libGUoY29sdW1uS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVDb2x1bW5zLnNvbWUoYyA9PiBjLmtleSA9PT0gY29sdW1uS2V5KTtcbiAgfVxuXG4gIG9uUmVtb3ZlQ29sdW1uKGNvbHVtbktleTogc3RyaW5nLCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuYWN0aXZlQ29sdW1ucy5maW5kKGl0ZW0gPT4gaXRlbS5rZXkgPT09IGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHJldHVybjtcbiAgICBjb25zdCByZW1vdmVkID0gdGhpcy5fdmlldy5yZW1vdmVDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIXJlbW92ZWQpIHJldHVybjtcbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICB0aGlzLmNvbHVtblJlbW92ZWQuZW1pdChjb2x1bW4pO1xuICB9XG5cbiAgLy8g4pSA4pSAIExpZ25lc1xuXG4gIHByaXZhdGUgX3JlYnVpbGRDZWxsRGVmTWFwKCk6IHZvaWQge1xuICAgIHRoaXMuX2NlbGxEZWZNYXAgPSBuZXcgTWFwKFxuICAgICAgKHRoaXMuX2NlbGxEZWZzID8/IFtdKS5tYXAoZCA9PiBbZC5jb2x1bW5LZXksIGQudGVtcGxhdGVdIGFzIFtzdHJpbmcsIFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBhbnk7IGluZGV4OiBudW1iZXIgfT5dKVxuICAgICk7XG4gIH1cblxuICBnZXRDZWxsVGVtcGxhdGUoa2V5OiBzdHJpbmcpOiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogYW55OyBpbmRleDogbnVtYmVyIH0+IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2NlbGxEZWZNYXAuZ2V0KGtleSkgPz8gbnVsbDtcbiAgfVxuXG4gIGdldCBoYXNDdXN0b21DZWxsRGVmcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY2VsbERlZk1hcC5zaXplID4gMDtcbiAgfVxuXG4gIGdldCBoYXNSb3dDbGlja0hhbmRsZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucm93U2VsZWN0ZWQub2JzZXJ2ZWQgfHwgISF0aGlzLnJlc29sdmVkQ29uZmlnLm9uUm93U2VsZWN0ZWQ7XG4gIH1cblxuICAvKiogTGFyZ2V1ciBtaW5pbWFsZSBkdSB0YWJsZWF1IGVuIHB4LCBjYWxjdWzDqWUgZGVwdWlzIGxlcyBsYXJnZXVycyBleHBsaWNpdGVzIGRlcyBjb2xvbm5lcyBhY3RpdmVzLlxuICAgKiBSZXRvdXJuZSBudWxsIHNpIGF1Y3VuZSBjb2xvbm5lIG4nYSBkZSBsYXJnZXVyIGTDqWZpbmllIChsZSB0YWJsZWF1IHJlbXBsaXQgYWxvcnMgMTAwJSBkdSBjb250ZW5ldXIpLlxuICAgKiBTZXVsZXMgbGVzIHZhbGV1cnMgZXhwbGljaXRlbWVudCBlbiBgcHhgIHNvbnQgc29tbWFibGVzIDsgbGVzIHBvdXJjZW50YWdlcyBvdSBhdXRyZXMgdW5pdMOpcyBzb250IGlnbm9yw6lzLiAqL1xuICBnZXQgdGFibGVNaW5XaWR0aCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBoYXNTb21lRXhwbGljaXRXaWR0aCA9IHRoaXMuYWN0aXZlQ29sdW1ucy5zb21lKGMgPT4gYy53aWR0aCk7XG4gICAgaWYgKCFoYXNTb21lRXhwbGljaXRXaWR0aCkgcmV0dXJuIG51bGw7XG4gICAgbGV0IHN1bSA9IDA7XG4gICAgZm9yIChjb25zdCBjb2wgb2YgdGhpcy5hY3RpdmVDb2x1bW5zKSB7XG4gICAgICBpZiAoY29sLndpZHRoKSB7XG4gICAgICAgIGNvbnN0IGlzUHggPSBjb2wud2lkdGgudHJpbSgpLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgoJ3B4Jyk7XG4gICAgICAgIGNvbnN0IHB4ID0gTnVtYmVyLnBhcnNlRmxvYXQoY29sLndpZHRoKTtcbiAgICAgICAgaWYgKGlzUHggJiYgIU51bWJlci5pc05hTihweCkpIHsgc3VtICs9IHB4OyB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdW0gKz0gMTIwOyAvLyBsYXJnZXVyIG1pbmltYWxlIGVzdGltw6llIHBvdXIgdW5lIGNvbG9ubmUgc2FucyBsYXJnZXVyIGV4cGxpY2l0ZVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3VtICsgJ3B4JztcbiAgfVxuXG4gIHRyYWNrUm93Rm4gPSAoX2luZGV4OiBudW1iZXIsIHJvdzogYW55KTogYW55ID0+XG4gICAgcm93W0dST1VQX0hFQURFUl9NQVJLRVJdID8gYF9fZ3JvdXBfJHtyb3dbUk9XX0dST1VQX0tFWV19YCA6IHJvd1tST1dfSU5ERVhfS0VZXSA/PyBfaW5kZXg7XG5cbiAgZ2V0Um93Q2xhc3Mocm93OiBhbnkpOiBzdHJpbmcgfCBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+IHtcbiAgICBjb25zdCBmbiA9IHRoaXMucmVzb2x2ZWRDb25maWcucm93Q2xhc3M7XG4gICAgaWYgKCFmbiB8fCByb3c/LltHUk9VUF9IRUFERVJfTUFSS0VSXSkgcmV0dXJuIHt9O1xuICAgIHJldHVybiBmbihyb3dbUk9XX1JBV19LRVldID8/IHJvdywgcm93W1JPV19JTkRFWF9LRVldID8/IDApO1xuICB9XG5cbiAgb25Sb3dDbGljayhyb3c6IGFueSwgZXZlbnQ6IE1vdXNlRXZlbnQgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHJvdz8uW0dST1VQX0hFQURFUl9NQVJLRVJdKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmhhc1Jvd0NsaWNrSGFuZGxlcikgcmV0dXJuO1xuICAgIGNvbnN0IHJlc29sdmVkID0gKHJvdz8uW1JPV19SQVdfS0VZXSA/PyByb3cpIGFzIFQ7XG4gICAgdGhpcy5yZXNvbHZlZENvbmZpZy5vblJvd1NlbGVjdGVkPy4ocmVzb2x2ZWQsIGV2ZW50KTtcbiAgICB0aGlzLnJvd1NlbGVjdGVkLmVtaXQocmVzb2x2ZWQpO1xuICB9XG5cbiAgLy8g4pSA4pSAIERyYWcgJiBkcm9wXG5cbiAgb25IZWFkZXJEcmFnU3RhcnQoY29sdW1uS2V5OiBzdHJpbmcsIGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNDb2x1bW5EcmFnRHJvcEVuYWJsZWQgJiYgIXRoaXMuX2VkaXRNb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnZ2VkQ29sdW1uS2V5ID0gY29sdW1uS2V5O1xuICAgIHRoaXMuZHJhZ092ZXJDb2x1bW5LZXkgPSBudWxsO1xuICAgIGlmIChldmVudC5kYXRhVHJhbnNmZXIpIHtcbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnO1xuICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLnNldERhdGEoJ3RleHQvcGxhaW4nLCBjb2x1bW5LZXkpO1xuICAgIH1cbiAgfVxuXG4gIG9uSGVhZGVyRHJhZ092ZXIoY29sdW1uS2V5OiBzdHJpbmcsIGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoKCF0aGlzLmlzQ29sdW1uRHJhZ0Ryb3BFbmFibGVkICYmICF0aGlzLl9lZGl0TW9kZSkgfHwgIXRoaXMuZHJhZ2dlZENvbHVtbktleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9IGNvbHVtbktleTtcbiAgfVxuXG4gIG9uSGVhZGVyRHJvcCh0YXJnZXRDb2x1bW5LZXk6IHN0cmluZywgZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xuICAgIGlmICgoIXRoaXMuaXNDb2x1bW5EcmFnRHJvcEVuYWJsZWQgJiYgIXRoaXMuX2VkaXRNb2RlKSB8fCAhdGhpcy5kcmFnZ2VkQ29sdW1uS2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IG1vdmVkID0gdGhpcy5fdmlldy5yZW9yZGVyQ29sdW1ucyh0aGlzLmRyYWdnZWRDb2x1bW5LZXksIHRhcmdldENvbHVtbktleSk7XG4gICAgaWYgKCFtb3ZlZCkge1xuICAgICAgdGhpcy5vbkhlYWRlckRyYWdFbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlZnJlc2hWaWV3TW9kZWwoKTtcbiAgICB0aGlzLm9uSGVhZGVyRHJhZ0VuZCgpO1xuICB9XG5cbiAgb25IZWFkZXJEcmFnRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuZHJhZ2dlZENvbHVtbktleSA9IG51bGw7XG4gICAgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9IG51bGw7XG4gIH1cblxuICBpc0hlYWRlckRyb3BUYXJnZXQoY29sdW1uS2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRyYWdnZWRDb2x1bW5LZXkgJiYgdGhpcy5kcmFnT3ZlckNvbHVtbktleSA9PT0gY29sdW1uS2V5ICYmIHRoaXMuZHJhZ2dlZENvbHVtbktleSAhPT0gY29sdW1uS2V5O1xuICB9XG5cbiAgLy8g4pSA4pSAIFByw6lmw6lyZW5jZXMgOiBtb2RlIMOpZGl0aW9uXG5cbiAgZW50ZXJFZGl0TW9kZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9lZGl0TW9kZSA9IHRydWU7XG4gICAgdGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlID0gbnVsbDtcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBjb25maXJtRWRpdE1vZGUoKTogdm9pZCB7XG4gICAgdGhpcy5fZWRpdE1vZGUgPSBmYWxzZTtcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogRMOpbWFycmUgbGUgcmVzaXplIGQndW5lIGNvbG9ubmUgKG1vdXNlZG93biBzdXIgbGEgcG9pZ27DqWUgZHJvaXRlKS4gKi9cbiAgb25SZXNpemVTdGFydChjb2x1bW5LZXk6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX2VkaXRNb2RlKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGNvbnN0IHRoID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdCgndGgnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKCF0aCkgcmV0dXJuO1xuXG4gICAgdGhpcy5fcmVzaXplU3RhdGUgPSB7IGtleTogY29sdW1uS2V5LCBzdGFydFg6IGV2ZW50LmNsaWVudFgsIHN0YXJ0V2lkdGg6IHRoLm9mZnNldFdpZHRoIH07XG5cbiAgICBjb25zdCBvbk1vdmUgPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9yZXNpemVTdGF0ZSkge1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3ZlKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvblVwKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVsdGEgPSBlLmNsaWVudFggLSB0aGlzLl9yZXNpemVTdGF0ZS5zdGFydFg7XG4gICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KDYwLCB0aGlzLl9yZXNpemVTdGF0ZS5zdGFydFdpZHRoICsgZGVsdGEpO1xuICAgICAgdGhpcy5fY29sdW1uV2lkdGhzID0geyAuLi50aGlzLl9jb2x1bW5XaWR0aHMsIFt0aGlzLl9yZXNpemVTdGF0ZS5rZXldOiBuZXdXaWR0aCB9O1xuICAgICAgLy8gZGV0ZWN0Q2hhbmdlcygpIHBvdXIgZm9yY2VyIGxhIG1pc2Ugw6Agam91ciBpbW3DqWRpYXRlIGVuIG1vZGUgT25QdXNoXG4gICAgICAvLyAobGVzIGxpc3RlbmVycyB3aW5kb3cgdG91cm5lbnQgaG9ycyB6b25lIEFuZ3VsYXIgYXZlYyBydW5PdXRzaWRlQW5ndWxhcilcbiAgICAgIHRoaXMuX2Nkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IG9uVXAgPSAoKSA9PiB7XG4gICAgICB0aGlzLl9yZXNpemVTdGF0ZSA9IG51bGw7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3ZlKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgb25VcCk7XG4gICAgfTtcblxuICAgIC8vIExpc3RlbmVycyBob3JzIHpvbmUgQW5ndWxhciBwb3VyIMOpdml0ZXIgZGVzIGN5Y2xlcyBDRCDDoCBjaGFxdWUgbW91c2Vtb3ZlXG4gICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdmUpO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvblVwKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBSZXRvdXJuZSBsYSBsYXJnZXVyIENTUyBkJ3VuZSBjb2xvbm5lIChweCBzaSBwZXJzb25uYWxpc8OpZSwgc2lub24gbGEgdmFsZXVyIGRlIGNvbmZpZyBvdSBhdXRvKS4gKi9cbiAgZ2V0Q29sdW1uV2lkdGgoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLl9jb2x1bW5XaWR0aHNba2V5XSAhPSBudWxsKSByZXR1cm4gdGhpcy5fY29sdW1uV2lkdGhzW2tleV0gKyAncHgnO1xuICAgIGNvbnN0IGNvbCA9IHRoaXMuX2NvbHVtbk1hcC5nZXQoa2V5KTtcbiAgICByZXR1cm4gY29sPy53aWR0aCA/PyAnYXV0byc7XG4gIH1cblxuICAvLyDilIDilIAgUHLDqWbDqXJlbmNlcyA6IHNhdmUgLyBjbGVhclxuXG4gIHNhdmVQcmVmZXJlbmNlcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX3ByZWZlcmVuY2VzTWFuYWdlcikgcmV0dXJuO1xuICAgIGNvbnN0IGR5bmFtaWNTbGljZUtleXMgPSB0aGlzLl92aWV3LnNsaWNlQnkuYWN0aXZlRHluYW1pY0NvbHVtbnMubWFwKGMgPT4gYy5rZXkpO1xuICAgIGNvbnN0IGNvbmZpZzogaW1wb3J0KCcuLi9qcXVlcnktdGFibGUubW9kZWwnKS5TYXZlZFRhYmxlQ29uZmlnID0ge1xuICAgICAgc2VhcmNoOiAgICAgICAgICAgICAgdGhpcy5zZWFyY2hRdWVyeSB8fCB1bmRlZmluZWQsXG4gICAgICBncm91cEJ5OiAgICAgICAgICAgICB0aGlzLmFjdGl2ZUdyb3VwQnlLZXksXG4gICAgICBjb2x1bW5PcmRlcjogICAgICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMubWFwKGMgPT4gYy5rZXkpLFxuICAgICAgdmlzaWJsZUNvbHVtbnM6ICAgICAgdGhpcy5hY3RpdmVDb2x1bW5zLm1hcChjID0+IGMua2V5KSxcbiAgICAgIGNvbHVtbldpZHRoczogICAgICAgIE9iamVjdC5rZXlzKHRoaXMuX2NvbHVtbldpZHRocykubGVuZ3RoID8geyAuLi50aGlzLl9jb2x1bW5XaWR0aHMgfSA6IHVuZGVmaW5lZCxcbiAgICAgIHNsaWNlUGFuZWxDb2xsYXBzZWQ6IHRoaXMuX3NsaWNlUGFuZWxDb2xsYXBzZWQsXG4gICAgICBoaWRkZW5TbGljZUtleXM6ICAgICBbLi4udGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzXSxcbiAgICAgIGR5bmFtaWNTbGljZUtleXM6ICAgIGR5bmFtaWNTbGljZUtleXMubGVuZ3RoID8gZHluYW1pY1NsaWNlS2V5cyA6IHVuZGVmaW5lZCxcbiAgICAgIHNsaWNlRmlsdGVyczogICAgICAgIHRoaXMuc2xpY2VQYW5lbFJlZiA/IHRoaXMuc2xpY2VQYW5lbFJlZi5nZXRBY3RpdmVGaWx0ZXJzKCkgOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgICB0aGlzLl9wcmVmZXJlbmNlc01hbmFnZXIuc2F2ZShjb25maWcpO1xuICAgIHRoaXMuX2hhc1NhdmVkQ29uZmlnID0gdHJ1ZTtcbiAgICB0aGlzLl9zaG93UHJlZmVyZW5jZXNNZXNzYWdlKHRoaXMuaTE4bi5wcmVmZXJlbmNlc1NhdmVkTWVzc2FnZSk7XG4gIH1cblxuICBjbGVhclByZWZlcmVuY2VzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fcHJlZmVyZW5jZXNNYW5hZ2VyKSByZXR1cm47XG4gICAgdGhpcy5fcHJlZmVyZW5jZXNNYW5hZ2VyLmNsZWFyKCk7XG4gICAgdGhpcy5faGFzU2F2ZWRDb25maWcgPSBmYWxzZTtcblxuICAgIC8vIENhcHR1cmVyIGxlcyBkeW5hbWljIHNsaWNlcyBhY3RpdmVzIEFWQU5UIGxlIHJlc2V0IChyZXNldFRvRGVmYXVsdHMoKSBsZXMgdmlkZSlcbiAgICBjb25zdCBkeW5hbWljU2xpY2VzVG9SZW1vdmUgPSB0aGlzLl92aWV3LnNsaWNlQnkuYWN0aXZlRHluYW1pY0NvbHVtbnMuc2xpY2UoKTtcblxuICAgIC8vIFJlc2V0IGNvbXBsZXQgZGUgbCfDqXRhdCB2ZXJzIGxlcyB2YWxldXJzIHBhciBkw6lmYXV0IGRlIGxhIGNvbmZpZ1xuICAgIHRoaXMuc2VhcmNoUXVlcnkgPSAnJztcbiAgICB0aGlzLl9jb2x1bW5XaWR0aHMgPSB7fTtcbiAgICB0aGlzLl9zbGljZVBhbmVsQ29sbGFwc2VkID0gZmFsc2U7XG4gICAgdGhpcy5fZ3JvdXBCeS5yZXNldCgpO1xuICAgIHRoaXMuX2dyb3VwQnkuc2V0RGVmYXVsdENvbGxhcHNlZChmYWxzZSk7XG5cbiAgICAvLyBTbGljZXMgc3RhdGlxdWVzIDogcmV2ZW5pciBhdXggc2V1bGVzIGNlbGxlcyBjYWNow6llcyBwYXIgbGEgY29uZmlnIChwYXMgcGFyIGwndXRpbGlzYXRldXIpXG4gICAgdGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzID0gbmV3IFNldCh0aGlzLl9jb25maWdIaWRkZW5LZXlzKTtcbiAgICB0aGlzLl92aWV3LnVwZGF0ZUhpZGRlblN0YXRpY0tleXModGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzKTtcblxuICAgIC8vIENvbG9ubmVzIGV0IGdyb3VwQnkgOiByZXNldCB2aWEgbGEgZmFjYWRlIChyZXRpcmUgbGVzIG9wdGlvbm5lbGxlcywgcmVtZXQgbCdvcmRyZSBjb25maWcpXG4gICAgdGhpcy5fdmlldy5yZXNldFRvRGVmYXVsdHMoKTtcblxuICAgIC8vIER5bmFtaWMgc2xpY2VzIDogbGVzIHJldGlyZXIgZHUgc2xpY2UgcGFuZWwgYXZlYyBsYSBsaXN0ZSBjYXB0dXLDqWUgYXZhbnQgbGUgcmVzZXRcbiAgICBkeW5hbWljU2xpY2VzVG9SZW1vdmUuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgdGhpcy5zbGljZVBhbmVsUmVmPy5yZW1vdmVEeW5hbWljU2xpY2VCeUtleShjb2wua2V5KTtcbiAgICB9KTtcblxuICAgIC8vIEZpbHRyZSBkZSBzbGljZSBhY3RpZlxuICAgIHRoaXMuYWN0aXZlU2xpY2VGaWx0ZXIgPSAoKSA9PiB0cnVlO1xuICAgIGlmICh0aGlzLnNsaWNlUGFuZWxSZWYpIHRoaXMuc2xpY2VQYW5lbFJlZi5yZXN0b3JlRmlsdGVycyh7fSk7XG5cbiAgICAvLyBSYWZyYcOuY2hpdCB0b3V0ZSBsYSB2dWVcbiAgICB0aGlzLmFjdGl2ZUNvbHVtbnMgPSB0aGlzLl92aWV3LmZpZWxkcy5hY3RpdmVDb2x1bW5zO1xuICAgIHRoaXMucmVuZGVyZWRDb2x1bW5zID0gdGhpcy5hY3RpdmVDb2x1bW5zLm1hcChjID0+IGMua2V5KTtcbiAgICB0aGlzLl9wZW5kaW5nRHluYW1pY1NsaWNlS2V5cyA9IG51bGw7XG4gICAgdGhpcy5fcGVuZGluZ1NsaWNlRmlsdGVycyA9IG51bGw7XG4gICAgdGhpcy5yZWZyZXNoVmlld01vZGVsKCk7XG5cbiAgICB0aGlzLl9zaG93UHJlZmVyZW5jZXNNZXNzYWdlKHRoaXMuaTE4bi5wcmVmZXJlbmNlc0NsZWFyZWRNZXNzYWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgX3ByZWZlcmVuY2VzTWVzc2FnZVRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgX3Nob3dQcmVmZXJlbmNlc01lc3NhZ2UobXNnOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlVGltZXIgIT09IG51bGwpIGNsZWFyVGltZW91dCh0aGlzLl9wcmVmZXJlbmNlc01lc3NhZ2VUaW1lcik7XG4gICAgdGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlID0gbXNnO1xuICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLl9wcmVmZXJlbmNlc01lc3NhZ2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlVGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5fcHJlZmVyZW5jZXNNZXNzYWdlID0gbnVsbDtcbiAgICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9LCA0MDAwKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwcGx5UHJlZmVyZW5jZXMoc2F2ZWQ6IGltcG9ydCgnLi4vanF1ZXJ5LXRhYmxlLm1vZGVsJykuU2F2ZWRUYWJsZUNvbmZpZyB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAoIXNhdmVkKSByZXR1cm47XG4gICAgLy8gUmVjaGVyY2hlXG4gICAgaWYgKHNhdmVkLnNlYXJjaCkgdGhpcy5zZWFyY2hRdWVyeSA9IHNhdmVkLnNlYXJjaDtcbiAgICAvLyBMYXJnZXVycyBjb2xvbm5lc1xuICAgIGlmIChzYXZlZC5jb2x1bW5XaWR0aHMpIHRoaXMuX2NvbHVtbldpZHRocyA9IHsgLi4uc2F2ZWQuY29sdW1uV2lkdGhzIH07XG4gICAgLy8gR3JvdXAgYnlcbiAgICBpZiAoc2F2ZWQuZ3JvdXBCeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLl92aWV3LnNldEdyb3VwQnkoc2F2ZWQuZ3JvdXBCeSk7XG4gICAgICBpZiAoc2F2ZWQuZ3JvdXBCeSkge1xuICAgICAgICB0aGlzLl9ncm91cEJ5LnNldERlZmF1bHRDb2xsYXBzZWQodHJ1ZSk7XG4gICAgICAgIHRoaXMuX2dyb3VwQnkucmVzZXQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gw4l0YXQgcGFubmVhdSBzbGljZVxuICAgIGlmIChzYXZlZC5zbGljZVBhbmVsQ29sbGFwc2VkICE9PSB1bmRlZmluZWQpIHRoaXMuX3NsaWNlUGFuZWxDb2xsYXBzZWQgPSBzYXZlZC5zbGljZVBhbmVsQ29sbGFwc2VkO1xuICAgIC8vIFNsaWNlcyBzdGF0aXF1ZXMgY2FjaMOpZXMg4oCUIG9uIHV0aWxpc2UgbGEgdmFsZXVyIGV4YWN0ZSBzYXV2ZWdhcmTDqWUgKHBhcyBsZXMgZGVmYXVsdHMgZGUgY29uZmlnKVxuICAgIGlmIChzYXZlZC5oaWRkZW5TbGljZUtleXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzID0gbmV3IFNldChzYXZlZC5oaWRkZW5TbGljZUtleXMpO1xuICAgICAgdGhpcy5fdmlldy51cGRhdGVIaWRkZW5TdGF0aWNLZXlzKHRoaXMuX3N0YXRpY1NsaWNlSGlkZGVuS2V5cyk7XG4gICAgfVxuICAgIC8vIENvbG9ubmVzIHZpc2libGVzICsgb3JkcmUg4oCUIHJlY29uc3RydWl0IGFjdGl2ZUNvbHVtbnMgZW4gdW5lIHNldWxlIHBhc3NlLlxuICAgIC8vIE9uIHBhcnQgZGUgc2F2ZWQuY29sdW1uT3JkZXIgKG9yZHJlIHNhdXZlZ2FyZMOpKSBzaSBkaXNwb25pYmxlLCBzaW5vbiBzYXZlZC52aXNpYmxlQ29sdW1ucy5cbiAgICAvLyBDZWxhIGfDqHJlIMOgIGxhIGZvaXMgOiBjb2xvbm5lcyBvcHRpb25uZWxsZXMgYWpvdXTDqWVzLCBjb2xvbm5lcyByZXRpcsOpZXMsIGV0IHLDqW9yZG9ubmFuY2VtZW50LlxuICAgIGNvbnN0IHRhcmdldEtleXMgPSBzYXZlZC5jb2x1bW5PcmRlciA/PyBzYXZlZC52aXNpYmxlQ29sdW1ucztcbiAgICBpZiAodGFyZ2V0S2V5cz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBhbGxCeUtleSA9IG5ldyBNYXAoKHRoaXMucmVzb2x2ZWRDb25maWcuY29sdW1ucyA/PyBbXSkubWFwKGMgPT4gW2Mua2V5LCBjXSkpO1xuICAgICAgLy8gQ29sb25uZXMgZGFucyBsJ29yZHJlIHNhdXZlZ2FyZMOpIChvbiBuZSBnYXJkZSBxdWUgY2VsbGVzIGNvbm51ZXMgZGUgbGEgY29uZmlnKVxuICAgICAgY29uc3Qgb3JkZXJlZCA9IHRhcmdldEtleXNcbiAgICAgICAgLm1hcChrZXkgPT4gYWxsQnlLZXkuZ2V0KGtleSkpXG4gICAgICAgIC5maWx0ZXIoKGMpOiBjIGlzIFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4gPT4gYyAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIC8vIENvbG9ubmVzIGFjdGl2ZXMgYWN0dWVsbGxlbWVudCBub24gcHLDqXNlbnRlcyBkYW5zIHRhcmdldEtleXMgKG5vbi1vcHRpb25hbCBwYXNzw6llcyBzb3VzIHNpbGVuY2UpXG4gICAgICAvLyDihpIgb24gbGVzIGV4Y2x1dCA6IGwndXRpbGlzYXRldXIgYXZhaXQgZXhwbGljaXRlbWVudCBjaG9pc2kgY2Ugc291cy1lbnNlbWJsZVxuICAgICAgaWYgKG9yZGVyZWQubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLl92aWV3LnNldEFjdGl2ZUNvbHVtbnMob3JkZXJlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIER5bmFtaWMgc2xpY2VzIOKAlCBkaWZmw6lyw6kgOiBzbGljZVBhbmVsUmVmIHBhcyBlbmNvcmUgZGlzcG9uaWJsZSBhdSBtb21lbnQgZGUgbmdPbkNoYW5nZXNcbiAgICBpZiAoc2F2ZWQuZHluYW1pY1NsaWNlS2V5cz8ubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9wZW5kaW5nRHluYW1pY1NsaWNlS2V5cyA9IHNhdmVkLmR5bmFtaWNTbGljZUtleXM7XG4gICAgfVxuICAgIC8vIEZpbHRyZXMgYWN0aWZzIGR1IHNsaWNlIHBhbmVsXG4gICAgLy8gRmlsdHJlcyBhY3RpZnMgZHUgc2xpY2UgcGFuZWwg4oCUIHRvdWpvdXJzIHN0b2Nrw6lzIGVuIHBlbmRpbmcgOlxuICAgIC8vIGFwcGxpcXXDqXMgcGFyIF9hcHBseVBlbmRpbmdEeW5hbWljU2xpY2VLZXlzIChzaSBkeW5hbWljIHNsaWNlcykgb3VcbiAgICAvLyBwYXIgX3JlY29tcHV0ZVNob3dTbGljZVBhbmVsIChxdWFuZCBsZXMgZG9ubsOpZXMgYXJyaXZlbnQgZXQgcmVuZGVudCBsZSBwYW5lbCB2aXNpYmxlKVxuICAgIGlmIChzYXZlZC5zbGljZUZpbHRlcnMgJiYgT2JqZWN0LmtleXMoc2F2ZWQuc2xpY2VGaWx0ZXJzKS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3BlbmRpbmdTbGljZUZpbHRlcnMgPSBzYXZlZC5zbGljZUZpbHRlcnM7XG4gICAgfVxuICB9XG5cbiAgY2FuUmVtb3ZlQ29sdW1uKGNvbHVtbjogVGFibGVDb2x1bW5Qcm92aWRlcjxUPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLl92aWV3LmFsbG93Q29sdW1uUmVtb3ZhbCAmJlxuICAgICAgY29sdW1uLnJlbW92YWJsZSAhPT0gZmFsc2UgJiZcbiAgICAgIHRoaXMuYWN0aXZlQ29sdW1ucy5sZW5ndGggPiAxXG4gICAgKTtcbiAgfVxuXG4gIGlzQ2VsbEVtcHR5KHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdmFsdWUgPT09ICcnIHx8IHZhbHVlID09IG51bGw7XG4gIH1cblxuICBhc1RpdGxlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIEV4cG9ydCBDU1ZcblxuICBvbkV4cG9ydCgpOiB2b2lkIHtcbiAgICB0aGlzLl9leHBvcnQuZXhwb3J0KCk7XG4gIH1cblxuICAvLyDilIDilIAgUGlwZWxpbmUgZGUgZG9ubsOpZXMgKHByaXbDqSlcblxuICBwcml2YXRlIHJlZnJlc2hWaWV3TW9kZWwoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVzb2x2ZWREYXRhID0gdGhpcy5yZXNvbHZlRGF0YSgpO1xuICAgIHRoaXMucmVzb2x2ZWRDb25maWcgPSB0aGlzLmJ1aWxkRWZmZWN0aXZlQ29uZmlnKCk7XG4gICAgdGhpcy5fY29sdW1uTWFwID0gbmV3IE1hcCgodGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zIHx8IFtdKS5tYXAoYyA9PiBbYy5rZXksIGNdKSk7XG5cbiAgICAvLyDilIDilIAgSW5pdGlhbGlzZXIgbGUgZ2VzdGlvbm5haXJlIGRlIHByw6lmw6lyZW5jZXMgc2kgbCdvcHRpb24gZXN0IGFjdGl2w6llXG4gICAgY29uc3QgcHJlZnNJZCA9IHRoaXMucmVzb2x2ZWRDb25maWcucHJlZmVyZW5jZXM/LmVuYWJsZWRcbiAgICAgID8gdGhpcy5yZXNvbHZlZENvbmZpZy5wcmVmZXJlbmNlcy50YWJsZUlkXG4gICAgICA6IG51bGw7XG4gICAgY29uc3QgY3VycmVudElkID0gcHJlZnNJZCA/PyBudWxsO1xuICAgIC8vIFByw6lmw6lyZW5jZXMgw6AgYXBwbGlxdWVyIGFwcsOocyBfdmlldy51cGRhdGUoKSAocXVhbmQgYWN0aXZlQ29sdW1ucyBlc3QgZMOpasOgIHBldXBsw6kpXG4gICAgbGV0IHBlbmRpbmdQcmVmczogaW1wb3J0KCcuLi9qcXVlcnktdGFibGUubW9kZWwnKS5TYXZlZFRhYmxlQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gICAgaWYgKGN1cnJlbnRJZCAmJiB0aGlzLl9wcmVmZXJlbmNlc01hbmFnZXI/LmtleSAhPT0gKCdqcXRfcHJlZnNfJyArIGN1cnJlbnRJZCkpIHtcbiAgICAgIHRoaXMuX3ByZWZlcmVuY2VzTWFuYWdlciA9IG5ldyBUYWJsZVByZWZlcmVuY2VzTWFuYWdlcihjdXJyZW50SWQpO1xuICAgICAgdGhpcy5faGFzU2F2ZWRDb25maWcgPSB0aGlzLl9wcmVmZXJlbmNlc01hbmFnZXIuaGFzU2F2ZWQoKTtcbiAgICAgIHBlbmRpbmdQcmVmcyA9IHRoaXMuX3ByZWZlcmVuY2VzTWFuYWdlci5sb2FkKCk7XG4gICAgfSBlbHNlIGlmICghY3VycmVudElkKSB7XG4gICAgICB0aGlzLl9wcmVmZXJlbmNlc01hbmFnZXIgPSBudWxsO1xuICAgICAgdGhpcy5faGFzU2F2ZWRDb25maWcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBEw6lsw6hndWUgw6AgbGEgZmFjYWRlIDogbWlzZSDDoCBqb3VyIGRlIGwnw6l0YXQgVmlldyAoY29sb25uZXMsIGdyb3VwQnkgbWV0YSwgc2xpY2VCeSBtZXRhKVxuICAgIHRoaXMuX3ZpZXcudXBkYXRlKHtcbiAgICAgIGNvbmZpZzogdGhpcy5yZXNvbHZlZENvbmZpZy52aWV3LFxuICAgICAgY29sdW1uczogdGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zID8/IFtdLFxuICAgICAgc2xpY2VDb25maWdzOiB0aGlzLnJlc29sdmVkQ29uZmlnLnNsaWNlcyA/PyBbXSxcbiAgICB9KTtcblxuICAgIC8vIFN5bmNocm9uaXNlIGxhIHByb3ByacOpdMOpIHN0YWJsZSAow6l2aXRlIE5HMDEwMCDigJQgbGEgZmFjYWRlIGVzdCBzb3VyY2UgZGUgdsOpcml0w6kpXG4gICAgdGhpcy5hY3RpdmVDb2x1bW5zID0gdGhpcy5fdmlldy5maWVsZHMuYWN0aXZlQ29sdW1ucztcblxuICAgIHRoaXMucmVuZGVyZWRDb2x1bW5zID0gdGhpcy5hY3RpdmVDb2x1bW5zLm1hcChjID0+IGMua2V5KTtcblxuICAgIHRoaXMucGFnZVNpemUgPSB0aGlzLnBhZ2luYXRvcj8ucGFnZVNpemUgfHwgdGhpcy5yZXNvbHZlUGFnZVNpemUoKTtcbiAgICB0aGlzLnBhZ2VTaXplT3B0aW9ucyA9IHRoaXMucmVzb2x2ZVBhZ2VTaXplT3B0aW9ucygpO1xuICAgIHRoaXMucGFnZVNpemVPcHRpb25zR3JvdXBCeSA9IHRoaXMucmVzb2x2ZVBhZ2VTaXplT3B0aW9uc0dyb3VwQnkoKTtcbiAgICBpZiAodGhpcy5ncm91cFBhZ2VTaXplICE9PSAwICYmICF0aGlzLnBhZ2VTaXplT3B0aW9uc0dyb3VwQnkuaW5jbHVkZXModGhpcy5ncm91cFBhZ2VTaXplKSkge1xuICAgICAgdGhpcy5ncm91cFBhZ2VTaXplID0gdGhpcy5yZXNvbHZlRGVmYXVsdEdyb3VwUGFnZVNpemUoKTtcbiAgICB9XG5cbiAgICB0aGlzLmF0dGFjaFBhZ2luYXRvcigpO1xuICAgIHRoaXMuYXR0YWNoU29ydCgpO1xuXG4gICAgLy8gUsOpaW5pdGlhbGlzZSBfc3RhdGljU2xpY2VIaWRkZW5LZXlzIHNldWxlbWVudCBzaSBsZXMgY2zDqXMgaGlkZGVuIGRlIGxhIGNvbmZpZyBvbnQgdnJhaW1lbnQgY2hhbmfDqVxuICAgIC8vIEVUIHF1J2lsIG4neSBhIHBhcyBkZSBwcsOpZsOpcmVuY2VzIHNhdXZlZ2FyZMOpZXMgKHF1aSBnw6lyZXJvbnQgaGlkZGVuU2xpY2VLZXlzIGVsbGVzLW3Dqm1lcykuXG4gICAgY29uc3QgbmV3Q29uZmlnSGlkZGVuID0gbmV3IFNldDxzdHJpbmc+KFxuICAgICAgKHRoaXMucmVzb2x2ZWRDb25maWcuc2xpY2VzID8/IFtdKS5maWx0ZXIocyA9PiBzLmhpZGRlbiAmJiBzLmNvbHVtbktleSkubWFwKHMgPT4gcy5jb2x1bW5LZXkhKVxuICAgICk7XG4gICAgaWYgKCFUYWJsZUNvbXBvbmVudC5fc2V0c0VxdWFsKG5ld0NvbmZpZ0hpZGRlbiwgdGhpcy5fY29uZmlnSGlkZGVuS2V5cykpIHtcbiAgICAgIHRoaXMuX2NvbmZpZ0hpZGRlbktleXMgPSBuZXdDb25maWdIaWRkZW47XG4gICAgICAvLyBOJ8OpY3Jhc2VyIF9zdGF0aWNTbGljZUhpZGRlbktleXMgcXVlIHNpIG9uIG4nZXN0IFBBUyBlbiB0cmFpbiBkJ2FwcGxpcXVlciBkZXMgcHJlZnNcbiAgICAgIC8vIChwZW5kaW5nUHJlZnMgbGVzIGfDqHJlcmEgbHVpLW3Dqm1lIHZpYSBfYXBwbHlQcmVmZXJlbmNlcyDihpIgaGlkZGVuU2xpY2VLZXlzKVxuICAgICAgaWYgKCFwZW5kaW5nUHJlZnMpIHtcbiAgICAgICAgdGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzID0gbmV3IFNldChuZXdDb25maWdIaWRkZW4pO1xuICAgICAgICB0aGlzLl92aWV3LnVwZGF0ZUhpZGRlblN0YXRpY0tleXModGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBcHBsaXF1ZSBsZXMgcHLDqWbDqXJlbmNlcyBJQ0ksIEFQUsOIUyBfdmlldy51cGRhdGUoKSBFVCBhcHLDqHMgX2NvbmZpZ0hpZGRlbktleXMgbWlzIMOgIGpvdXIsXG4gICAgLy8gbWFpcyBhdmFudCBfY29tcHV0ZVNsaWNlQ29uZmlncygpIHBvdXIgcXVlIGhpZGRlblNsaWNlS2V5cyBzb2l0IGTDqWrDoCByZXN0YXVyw6kuXG4gICAgaWYgKHBlbmRpbmdQcmVmcykge1xuICAgICAgdGhpcy5fYXBwbHlQcmVmZXJlbmNlcyhwZW5kaW5nUHJlZnMpO1xuICAgIH1cblxuICAgIC8vIFByb3ByacOpdMOpcyBzdGFibGVzIHBvdXIgbGVzIGJpbmRpbmdzIGR1IHRlbXBsYXRlXG4gICAgLy8gT24gcmVjYWxjdWxlIF9zbGljZUNvbmZpZ3MgZW4gcmVmbMOpdGFudCBsJ8OpdGF0IGNvdXJhbnQgZGVzIHNsaWNlcyBjYWNow6llcyxcbiAgICAvLyBwb3VyIHF1ZSBTbGljZVBhbmVsQ29tcG9uZW50Lm5nT25Jbml0IHJlw6dvaXZlIGxhIGJvbm5lIHZhbGV1ciBkZSBgaGlkZGVuYFxuICAgIC8vIG3Dqm1lIHF1YW5kIGxlIGNvbXBvc2FudCBlc3QgY3LDqcOpIHBvdXIgbGEgMcOocmUgZm9pcyBhcHLDqHMgdW4gdG9nZ2xlLlxuICAgIHRoaXMuX3NsaWNlQ29uZmlncyA9IHRoaXMuX2NvbXB1dGVTbGljZUNvbmZpZ3MoKTtcbiAgICB0aGlzLl9zbGljZUNvbHVtbnMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLmNvbHVtbnMgPz8gW107XG4gICAgdGhpcy5fc2xpY2VEYXRhID0gdGhpcy5fcmVzb2x2ZWREYXRhO1xuICAgIHRoaXMuX3NsaWNlU2hvd1RvZ2dsZSA9IHRoaXMucmVzb2x2ZWRDb25maWcuZW5hYmxlU2xpY2VUb2dnbGUgIT09IGZhbHNlO1xuICAgIHRoaXMuX3JlY29tcHV0ZVNob3dTbGljZVBhbmVsKCk7XG4gICAgaWYgKCF0aGlzLl9hY3RpdmVTb3J0LmFjdGl2ZSAmJiB0aGlzLnJlc29sdmVkQ29uZmlnLmRlZmF1bHRTb3J0KSB7XG4gICAgICB0aGlzLl9tYXRTb3J0QWN0aXZlID0gdGhpcy5yZXNvbHZlZENvbmZpZy5kZWZhdWx0U29ydC5hY3RpdmU7XG4gICAgICB0aGlzLl9tYXRTb3J0RGlyZWN0aW9uID0gdGhpcy5yZXNvbHZlZENvbmZpZy5kZWZhdWx0U29ydC5kaXJlY3Rpb247XG4gICAgfVxuICAgIHRoaXMuX2J1aWxkU2xpY2VCeU1lbnVJdGVtcygpO1xuXG4gICAgdGhpcy5fc2NoZWR1bGVSZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBSZXRvdXJuZSB1bmlxdWVtZW50IGxlcyBzbGljZXMgdmlzaWJsZXMgKG5vbiBjYWNow6llcyBwYXIgX3N0YXRpY1NsaWNlSGlkZGVuS2V5cykuXG4gICAqIExlIFNsaWNlUGFuZWxDb21wb25lbnQgYWZmaWNoZSB0b3V0IGNlIHF1J2lsIHJlw6dvaXQg4oCUIGMnZXN0IGljaSBxdWUgc2UgZmFpdCBsZSBmaWx0cmFnZS4gKi9cbiAgcHJpdmF0ZSBfY29tcHV0ZVNsaWNlQ29uZmlncygpOiBTbGljZUNvbmZpZzxUPltdIHtcbiAgICByZXR1cm4gKHRoaXMucmVzb2x2ZWRDb25maWcuc2xpY2VzID8/IFtdKS5maWx0ZXIoXG4gICAgICBzID0+ICFzLmNvbHVtbktleSB8fCAhdGhpcy5fc3RhdGljU2xpY2VIaWRkZW5LZXlzLmhhcyhzLmNvbHVtbktleSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX3NldHNFcXVhbChhOiBTZXQ8c3RyaW5nPiwgYjogU2V0PHN0cmluZz4pOiBib29sZWFuIHtcbiAgICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IHYgb2YgYSkgaWYgKCFiLmhhcyh2KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfYnVpbGRTbGljZUJ5TWVudUl0ZW1zKCk6IHZvaWQge1xuICAgIGNvbnN0IHN0YXRpY1NsaWNlTWFwID0gbmV3IE1hcCh0aGlzLl9zdGF0aWNTbGljZXNGb3JNZW51Lm1hcChzID0+IFtzLmtleSwgc10pKTtcbiAgICBjb25zdCBkeW5hbWljU2xpY2VTZXQgPSBuZXcgU2V0KHRoaXMuX2FsbER5bmFtaWNTbGljZUNvbHVtbnMubWFwKGMgPT4gYy5rZXkpKTtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgaXRlbXM6IEFycmF5PHsgaXNTdGF0aWM6IGJvb2xlYW47IGtleTogc3RyaW5nOyB0aXRsZTogc3RyaW5nOyBpY29uPzogc3RyaW5nOyBjb2w/OiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+IH0+ID0gW107XG4gICAgZm9yIChjb25zdCBjb2wgb2YgdGhpcy5yZXNvbHZlZENvbmZpZy5jb2x1bW5zID8/IFtdKSB7XG4gICAgICBpZiAoc2Vlbi5oYXMoY29sLmtleSkpIGNvbnRpbnVlO1xuICAgICAgaWYgKHN0YXRpY1NsaWNlTWFwLmhhcyhjb2wua2V5KSkge1xuICAgICAgICBjb25zdCBzID0gc3RhdGljU2xpY2VNYXAuZ2V0KGNvbC5rZXkpITtcbiAgICAgICAgaXRlbXMucHVzaCh7IGlzU3RhdGljOiB0cnVlLCBrZXk6IHMua2V5LCB0aXRsZTogcy50aXRsZSwgaWNvbjogcy5pY29uIH0pO1xuICAgICAgICBzZWVuLmFkZChjb2wua2V5KTtcbiAgICAgIH0gZWxzZSBpZiAoZHluYW1pY1NsaWNlU2V0Lmhhcyhjb2wua2V5KSkge1xuICAgICAgICBpdGVtcy5wdXNoKHsgaXNTdGF0aWM6IGZhbHNlLCBrZXk6IGNvbC5rZXksIHRpdGxlOiB0aGlzLmNvbExhYmVsKGNvbCksIGljb246IGNvbC5pY29uLCBjb2wgfSk7XG4gICAgICAgIHNlZW4uYWRkKGNvbC5rZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHMgb2YgdGhpcy5fc3RhdGljU2xpY2VzRm9yTWVudSkge1xuICAgICAgaWYgKCFzZWVuLmhhcyhzLmtleSkpIHtcbiAgICAgICAgaXRlbXMucHVzaCh7IGlzU3RhdGljOiB0cnVlLCBrZXk6IHMua2V5LCB0aXRsZTogcy50aXRsZSwgaWNvbjogcy5pY29uIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl9zbGljZUJ5TWVudUl0ZW1zID0gaXRlbXM7XG4gIH1cblxuICBnZXQgc2xpY2VCeU1lbnVJdGVtcygpIHsgcmV0dXJuIHRoaXMuX3NsaWNlQnlNZW51SXRlbXM7IH1cblxuICBvblNsaWNlTWVudUl0ZW1DbGljayhpdGVtOiB7IGlzU3RhdGljOiBib29sZWFuOyBrZXk6IHN0cmluZzsgY29sPzogVGFibGVDb2x1bW5Qcm92aWRlcjxUPiB9KTogdm9pZCB7XG4gICAgaWYgKGl0ZW0uaXNTdGF0aWMpIHtcbiAgICAgIHRoaXMudG9nZ2xlU3RhdGljU2xpY2UoaXRlbS5rZXkpO1xuICAgIH0gZWxzZSBpZiAoaXRlbS5jb2wpIHtcbiAgICAgIHRoaXMudG9nZ2xlRHluYW1pY1NsaWNlKGl0ZW0uY29sKTtcbiAgICB9XG4gIH1cblxuICBpc1NsaWNlTWVudUl0ZW1BY3RpdmUoaXRlbTogeyBpc1N0YXRpYzogYm9vbGVhbjsga2V5OiBzdHJpbmcgfSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpdGVtLmlzU3RhdGljID8gdGhpcy5pc1N0YXRpY1NsaWNlVmlzaWJsZShpdGVtLmtleSkgOiB0aGlzLmlzRHluYW1pY1NsaWNlQWN0aXZlKGl0ZW0ua2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgX3NjaGVkdWxlUmVuZGVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nUmVuZGVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5fcGVuZGluZ1JlbmRlcik7XG4gICAgICB0aGlzLl9wZW5kaW5nUmVuZGVyID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRoaXMuX3BlbmRpbmdSZW5kZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fcGVuZGluZ1JlbmRlciA9IG51bGw7XG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy5fZXhlY3V0ZVJlbmRlcigpKTtcbiAgICAgIH0sIDApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZXhlY3V0ZVJlbmRlcigpOiB2b2lkIHtcbiAgICBjb25zdCBjYXRlZ29yeVJvd3MgPSB0aGlzLmdldENhdGVnb3J5RmlsdGVyZWREYXRhKCk7XG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBCeUtleSkge1xuICAgICAgLy8gRW4gbW9kZSBncm91cEJ5LCBwcm9qZWN0Um93cyBnw6hyZSB0b3V0IGxlIHRyaSBpbnRlcm5lbWVudCDigJQgcGFzIGRlIHNvcnQgZ2xvYmFsIGludXRpbGVcbiAgICAgIHRoaXMuX2FsbEZpbHRlcmVkUm93cyA9IGNhdGVnb3J5Um93cztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY29tcGFyZUZuID0gdGhpcy5fYnVpbGRTb3J0Q29tcGFyYXRvcigpO1xuICAgICAgdGhpcy5fYWxsRmlsdGVyZWRSb3dzID0gY29tcGFyZUZuID8gWy4uLmNhdGVnb3J5Um93c10uc29ydChjb21wYXJlRm4pIDogY2F0ZWdvcnlSb3dzO1xuICAgIH1cblxuICAgIC8vIE1ldHRyZSDDoCBqb3VyIGxlIHBhZ2luYXRvciBhdmVjIGxlIG5vdXZlYXUgdG90YWxcbiAgICBpZiAodGhpcy5wYWdpbmF0b3IpIHtcbiAgICAgIGNvbnN0IHNhdmVkSW5kZXggPSB0aGlzLl9wcmVzZXJ2ZVBhZ2VJbmRleCA/PyB0aGlzLnBhZ2luYXRvci5wYWdlSW5kZXg7XG4gICAgICBjb25zdCBtYXhQYWdlID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKHRoaXMuX2FsbEZpbHRlcmVkUm93cy5sZW5ndGggLyB0aGlzLnBhZ2VTaXplKSAtIDEpO1xuICAgICAgdGhpcy5wYWdpbmF0b3IubGVuZ3RoID0gdGhpcy5fYWxsRmlsdGVyZWRSb3dzLmxlbmd0aDtcbiAgICAgIHRoaXMucGFnaW5hdG9yLnBhZ2VJbmRleCA9IE1hdGgubWluKHNhdmVkSW5kZXgsIG1heFBhZ2UpO1xuICAgICAgdGhpcy5fcHJlc2VydmVQYWdlSW5kZXggPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMuX3Byb2plY3RDdXJyZW50UGFnZSgpO1xuICAgIC8vIGRldGVjdENoYW5nZXMoKSBhdSBsaWV1IGRlIG1hcmtGb3JDaGVjaygpIDogbWV0IMOgIGpvdXIgdW5pcXVlbWVudCBDRSBjb21wb3NhbnRcbiAgICAvLyBzYW5zIGTDqWNsZW5jaGVyIHVuIGN5Y2xlIENEIGdsb2JhbCBxdWkgcHJvdm9xdWVyYWl0IE5HMDEwMCBkYW5zIGxlcyBwYXJlbnRzLlxuICAgIHRoaXMuX2Nkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIF9wcm9qZWN0Q3VycmVudFBhZ2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBCeUtleSkge1xuICAgICAgdGhpcy50YWJsZURhdGFTb3VyY2UuZGF0YSA9IHRoaXMucHJvamVjdFJvd3ModGhpcy5fYWxsRmlsdGVyZWRSb3dzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlSW5kZXggPSB0aGlzLnBhZ2luYXRvcj8ucGFnZUluZGV4ID8/IDA7XG4gICAgY29uc3Qgc3RhcnQgPSBwYWdlSW5kZXggKiB0aGlzLnBhZ2VTaXplO1xuICAgIGNvbnN0IHBhZ2VSb3dzID0gdGhpcy5fYWxsRmlsdGVyZWRSb3dzLnNsaWNlKHN0YXJ0LCBzdGFydCArIHRoaXMucGFnZVNpemUpO1xuXG4gICAgY29uc3QgcHJvamVjdGVkOiBhbnlbXSA9IFtdO1xuICAgIHBhZ2VSb3dzLmZvckVhY2goKHJvdywgaSkgPT4ge1xuICAgICAgY29uc3QgaWR4ID0gc3RhcnQgKyBpO1xuICAgICAgY29uc3QgcDogYW55ID0geyBbUk9XX1JBV19LRVldOiByb3csIFtST1dfSU5ERVhfS0VZXTogaWR4IH07XG4gICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgIHBbY29sLmtleV0gPSB0aGlzLnJlc29sdmVDZWxsVmFsdWUoY29sLCByb3csIGlkeCk7XG4gICAgICB9KTtcbiAgICAgIHByb2plY3RlZC5wdXNoKHApO1xuICAgIH0pO1xuICAgIHRoaXMudGFibGVEYXRhU291cmNlLmRhdGEgPSBwcm9qZWN0ZWQ7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRWZmZWN0aXZlQ29uZmlnKCk6IFRhYmxlUHJvdmlkZXI8VD4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnIHx8IHt9O1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLl9yZXNvbHZlZERhdGE7XG5cbiAgICBjb25zdCBjb2x1bW5zID1cbiAgICAgIGNvbmZpZy5jb2x1bW5zIHx8XG4gICAgICB0aGlzLmNvbHVtbnNDb25maWcgfHxcbiAgICAgIHRoaXMucmVzb2x2ZUNvbHVtbnNGcm9tQ29tcGF0KHJvd3MpO1xuXG4gICAgLy8gTW9kZSBIVE1MIDogW3ZpZXddIHByZW5kIGxlIGRlc3N1cyBzdXIgY29uZmlnLnZpZXcgc2kgZm91cm5pIChQaGFzZSAzKS5cbiAgICBjb25zdCB2aWV3ID0gdGhpcy52aWV3ID8/IGNvbmZpZy52aWV3O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmNvbmZpZyxcbiAgICAgIGNvbHVtbnMsXG4gICAgICB2aWV3LFxuICAgICAgc2xpY2VzOiBjb25maWcuc2xpY2VzIHx8IFtdLFxuICAgICAgZW5hYmxlU2xpY2VUb2dnbGU6IGNvbmZpZy5lbmFibGVTbGljZVRvZ2dsZSA/PyB0cnVlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVEYXRhKCk6IFRbXSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5kYXRhKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kYXRhU291cmNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UgJiYgQXJyYXkuaXNBcnJheSgodGhpcy5kYXRhU291cmNlIGFzIGFueSkuZGF0YSkpIHtcbiAgICAgIHJldHVybiAodGhpcy5kYXRhU291cmNlIGFzIGFueSkuZGF0YTtcbiAgICB9XG5cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVDb2x1bW5zRnJvbUNvbXBhdChyb3dzOiBUW10pOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10ge1xuICAgIGlmICh0aGlzLmRpc3BsYXllZENvbHVtbnM/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheWVkQ29sdW1ucy5tYXAoKGtleSkgPT4gKHtcbiAgICAgICAga2V5LFxuICAgICAgICBoZWFkZXI6IHRoaXMuY29sdW1uTGFiZWxzPy5ba2V5XSB8fCBodW1hbml6ZUtleShrZXkpLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGZpcnN0Um93ID0gcm93c1swXSBhcyBhbnk7XG4gICAgaWYgKCFmaXJzdFJvdyB8fCB0eXBlb2YgZmlyc3RSb3cgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGZpcnN0Um93KS5tYXAoKGtleSkgPT4gKHtcbiAgICAgIGtleSxcbiAgICAgIGhlYWRlcjogdGhpcy5jb2x1bW5MYWJlbHM/LltrZXldIHx8IGh1bWFuaXplS2V5KGtleSksXG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDYXRlZ29yeUZpbHRlcmVkRGF0YSgpOiBUW10ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9yZXNvbHZlZERhdGE7XG5cbiAgICBsZXQgZmlsdGVyZWQgPSBkYXRhLmZpbHRlcih0aGlzLmFjdGl2ZVNsaWNlRmlsdGVyKTtcblxuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5zZWFyY2hRdWVyeT8udHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHF1ZXJ5KSB7XG4gICAgICBjb25zdCByZXN0cmljdGVkS2V5cyA9IHRoaXMucmVzb2x2ZWRDb25maWcuc2VhcmNoPy5zZWFyY2hDb2x1bW5zO1xuICAgICAgY29uc3Qgc2VhcmNoQ29scyA9IHJlc3RyaWN0ZWRLZXlzPy5sZW5ndGhcbiAgICAgICAgPyBbLi4udGhpcy5fY29sdW1uTWFwLnZhbHVlcygpXS5maWx0ZXIoY29sID0+IHJlc3RyaWN0ZWRLZXlzLmluY2x1ZGVzKGNvbC5rZXkpKVxuICAgICAgICA6IFsuLi50aGlzLl9jb2x1bW5NYXAudmFsdWVzKCldO1xuICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIoKHJvdykgPT5cbiAgICAgICAgc2VhcmNoQ29scy5zb21lKChjb2wpID0+IHtcbiAgICAgICAgICBjb25zdCB2YWwgPSB0aGlzLmdldERpc3BsYXlWYWx1ZUZvclNlYXJjaChjb2wsIHJvdyk7XG4gICAgICAgICAgcmV0dXJuIHZhbCAhPSBudWxsICYmIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbHRlcmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9qZWN0Um93cyhyb3dzOiBUW10pOiBhbnlbXSB7XG4gICAgY29uc3QgZ3JvdXBLZXkgPSB0aGlzLmFjdGl2ZUdyb3VwQnlLZXk7XG5cbiAgICBpZiAoIWdyb3VwS2V5KSB7XG4gICAgICBjb25zdCByZXN1bHQ6IGFueVtdID0gW107XG4gICAgICByb3dzLmZvckVhY2goKHJvdywgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgcHJvamVjdGVkOiBhbnkgPSB7IFtST1dfUkFXX0tFWV06IHJvdywgW1JPV19JTkRFWF9LRVldOiBpbmRleCB9O1xuICAgICAgICB0aGlzLmFjdGl2ZUNvbHVtbnMuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgICAgcHJvamVjdGVkW2NvbC5rZXldID0gdGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGNvbCwgcm93LCBpbmRleCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQucHVzaChwcm9qZWN0ZWQpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGNvbnN0IGdyb3VwQ29sRGVmID0gdGhpcy5fY29sdW1uTWFwLmdldChncm91cEtleSk7XG4gICAgY29uc3QgZ3JvdXBMYXp5U3RhdHVzID0gZ3JvdXBDb2xEZWY/LmxhenkgPyAodGhpcy5fbGF6eUNvbHVtblN0YXR1cy5nZXQoZ3JvdXBLZXkpID8/ICdpZGxlJykgOiAnbG9hZGVkJztcblxuICAgIGlmIChncm91cExhenlTdGF0dXMgIT09ICdsb2FkZWQnKSB7XG4gICAgICB0aGlzLl90b3RhbEZpbHRlcmVkQ291bnQgPSByb3dzLmxlbmd0aDtcbiAgICAgIHJldHVybiBbeyBbR1JPVVBfSEVBREVSX01BUktFUl06IHRydWUsIFtST1dfR1JPVVBfS0VZXTogR1JPVVBfS0VZX0xBWllfTE9BRElORywgW1JPV19HUk9VUF9DT1VOVF06IHJvd3MubGVuZ3RoLCBbUk9XX0dST1VQX1BBR0VdOiAwLCBbUk9XX0dST1VQX1BBR0VfQ09VTlRdOiAxIH1dO1xuICAgIH1cblxuICAgIGNvbnN0IGVmZmVjdGl2ZVNvcnQgPSB0aGlzLl9hY3RpdmVTb3J0LmFjdGl2ZSAmJiB0aGlzLl9hY3RpdmVTb3J0LmRpcmVjdGlvblxuICAgICAgPyB0aGlzLl9hY3RpdmVTb3J0XG4gICAgICA6IHRoaXMucmVzb2x2ZWRDb25maWcuZGVmYXVsdFNvcnQgPz8geyBhY3RpdmU6ICcnLCBkaXJlY3Rpb246ICcnIGFzIGNvbnN0IH07XG5cbiAgICAvLyBWw6lyaWZpZSBzaSBsZSBjYWNoZSBlc3QgZW5jb3JlIHZhbGlkZSAobcOqbWUgcsOpZsOpcmVuY2UgZGUgcm93cyArIG3Dqm1lIHBhcmFtw6h0cmVzIGRlIHRyaS9ncm91cGUpXG4gICAgY29uc3QgY2FjaGVWYWxpZCA9XG4gICAgICB0aGlzLl9ncm91cENhY2hlICE9PSBudWxsICYmXG4gICAgICB0aGlzLl9ncm91cENhY2hlLnJvd3MgPT09IHJvd3MgJiZcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGUua2V5ID09PSBncm91cEtleSAmJlxuICAgICAgdGhpcy5fZ3JvdXBDYWNoZS5zb3J0T3JkZXIgPT09IHRoaXMuX2dyb3VwQnkuZ3JvdXBTb3J0T3JkZXIgJiZcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGUuc29ydEFjdGl2ZSA9PT0gKGVmZmVjdGl2ZVNvcnQuYWN0aXZlID8/ICcnKSAmJlxuICAgICAgdGhpcy5fZ3JvdXBDYWNoZS5zb3J0RGlyID09PSAoZWZmZWN0aXZlU29ydC5kaXJlY3Rpb24gPz8gJycpO1xuXG4gICAgbGV0IGdyb3VwT3JkZXI6IHN0cmluZ1tdO1xuICAgIGxldCBncm91cE1hcDogTWFwPHN0cmluZywgVFtdPjtcblxuICAgIGlmIChjYWNoZVZhbGlkKSB7XG4gICAgICBncm91cE9yZGVyID0gdGhpcy5fZ3JvdXBDYWNoZSEub3JkZXI7XG4gICAgICBncm91cE1hcCA9IHRoaXMuX2dyb3VwQ2FjaGUhLm1hcDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHLDqS1jYWxjdWwgZGVzIHZhbGV1cnMgZGUgZ3JvdXBlIGVuIHVuIHNldWwgcGFzc2FnZSAow6l2aXRlIE8obikgZmluZCgpIHBhciBjb21wYXJhaXNvbilcbiAgICAgIGNvbnN0IGdyb3VwVmFsdWVDYWNoZSA9IG5ldyBNYXA8VCwgc3RyaW5nPigpO1xuICAgICAgcm93cy5mb3JFYWNoKHJvdyA9PiBncm91cFZhbHVlQ2FjaGUuc2V0KHJvdywgU3RyaW5nKHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoZ3JvdXBLZXksIHJvdykgPz8gJycpKSk7XG5cbiAgICAgIC8vIFByw6ktY2FsY3VsIGRlcyB2YWxldXJzIGRlIHRyaSAow6l2aXRlIE8obiBsb2cgbikgw5cgZ2V0TGF6eUF3YXJlVmFsdWUgZGFucyBsZSBjb21wYXJhdGV1cilcbiAgICAgIGxldCBmYXN0Q29tcGFyZUZuOiAoKGE6IFQsIGI6IFQpID0+IG51bWJlcikgfCBudWxsID0gbnVsbDtcbiAgICAgIGlmIChlZmZlY3RpdmVTb3J0LmFjdGl2ZSAmJiBlZmZlY3RpdmVTb3J0LmRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBzb3J0VmFsdWVDYWNoZSA9IG5ldyBNYXA8VCwgYW55PigpO1xuICAgICAgICByb3dzLmZvckVhY2gocm93ID0+IHNvcnRWYWx1ZUNhY2hlLnNldChyb3csIHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoZWZmZWN0aXZlU29ydC5hY3RpdmUsIHJvdykpKTtcbiAgICAgICAgY29uc3QgZGlyID0gZWZmZWN0aXZlU29ydC5kaXJlY3Rpb247XG4gICAgICAgIGZhc3RDb21wYXJlRm4gPSAoYTogVCwgYjogVCk6IG51bWJlciA9PiB7XG4gICAgICAgICAgY29uc3QgdmEgPSBzb3J0VmFsdWVDYWNoZS5nZXQoYSk7XG4gICAgICAgICAgY29uc3QgdmIgPSBzb3J0VmFsdWVDYWNoZS5nZXQoYik7XG4gICAgICAgICAgbGV0IGNtcCA9IDA7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIHZiID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgY21wID0gdmEgPCB2YiA/IC0xIDogdmEgPiB2YiA/IDEgOiAwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzYSA9IHZhID09IG51bGwgPyAnJyA6IFN0cmluZyh2YSkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGNvbnN0IHNiID0gdmIgPT0gbnVsbCA/ICcnIDogU3RyaW5nKHZiKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgY21wID0gc2EgPCBzYiA/IC0xIDogc2EgPiBzYiA/IDEgOiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZGlyID09PSAnYXNjJyA/IGNtcCA6IC1jbXA7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5yb3dzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhID0gZ3JvdXBWYWx1ZUNhY2hlLmdldChhKSE7XG4gICAgICAgIGNvbnN0IHZiID0gZ3JvdXBWYWx1ZUNhY2hlLmdldChiKSE7XG4gICAgICAgIGNvbnN0IGNtcCA9IHZhLmxvY2FsZUNvbXBhcmUodmIpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZ3JvdXBCeS5ncm91cFNvcnRPcmRlciA9PT0gJ2Rlc2MnID8gLWNtcCA6IGNtcDtcbiAgICAgIH0pO1xuXG4gICAgICBncm91cE9yZGVyID0gW107XG4gICAgICBncm91cE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBUW10+KCk7XG4gICAgICBzb3J0ZWQuZm9yRWFjaCgocm93KSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwVmFsdWUgPSBncm91cFZhbHVlQ2FjaGUuZ2V0KHJvdykhO1xuICAgICAgICBpZiAoIWdyb3VwTWFwLmhhcyhncm91cFZhbHVlKSkge1xuICAgICAgICAgIGdyb3VwT3JkZXIucHVzaChncm91cFZhbHVlKTtcbiAgICAgICAgICBncm91cE1hcC5zZXQoZ3JvdXBWYWx1ZSwgW10pO1xuICAgICAgICB9XG4gICAgICAgIGdyb3VwTWFwLmdldChncm91cFZhbHVlKSEucHVzaChyb3cpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFRyaSBpbnRyYS1ncm91cGUgc3RvY2vDqSBkYW5zIGxlIGNhY2hlIOKAlCDDqXZpdGUgbGUgcmUtdHJpIHN1ciBjb2xsYXBzZS9leHBhbmQvcGFnaW5hdGlvblxuICAgICAgaWYgKGZhc3RDb21wYXJlRm4pIHtcbiAgICAgICAgY29uc3QgZm4gPSBmYXN0Q29tcGFyZUZuO1xuICAgICAgICBncm91cE1hcC5mb3JFYWNoKChncm91cFJvd3MsIGtleSkgPT4ge1xuICAgICAgICAgIGdyb3VwTWFwLnNldChrZXksIFsuLi5ncm91cFJvd3NdLnNvcnQoZm4pKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIE1pc2UgZW4gY2FjaGVcbiAgICAgIHRoaXMuX2dyb3VwQ2FjaGUgPSB7XG4gICAgICAgIHJvd3MsXG4gICAgICAgIGtleTogZ3JvdXBLZXksXG4gICAgICAgIHNvcnRPcmRlcjogdGhpcy5fZ3JvdXBCeS5ncm91cFNvcnRPcmRlcixcbiAgICAgICAgc29ydEFjdGl2ZTogZWZmZWN0aXZlU29ydC5hY3RpdmUgPz8gJycsXG4gICAgICAgIHNvcnREaXI6IGVmZmVjdGl2ZVNvcnQuZGlyZWN0aW9uID8/ICcnLFxuICAgICAgICBvcmRlcjogZ3JvdXBPcmRlcixcbiAgICAgICAgbWFwOiBncm91cE1hcCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5fdG90YWxGaWx0ZXJlZENvdW50ID0gcm93cy5sZW5ndGg7XG5cbiAgICAvLyBQcm90ZWN0aW9uIGNvbnRyZSBsZXMgamV1eCBkZSBkb25uw6llcyDDoCB0cm9wIGhhdXRlIGNhcmRpbmFsaXTDqVxuICAgIGlmIChncm91cE9yZGVyLmxlbmd0aCA+IFRhYmxlQ29tcG9uZW50Lk1BWF9HUk9VUF9DT1VOVCkge1xuICAgICAgcmV0dXJuIFt7IFtHUk9VUF9IRUFERVJfTUFSS0VSXTogdHJ1ZSwgW1JPV19HUk9VUF9LRVldOiBHUk9VUF9LRVlfVE9PX01BTlksIFtST1dfR1JPVVBfQ09VTlRdOiBncm91cE9yZGVyLmxlbmd0aCwgW1JPV19HUk9VUF9QQUdFXTogMCwgW1JPV19HUk9VUF9QQUdFX0NPVU5UXTogMSB9XTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWdlU2l6ZSA9IHRoaXMuZ3JvdXBQYWdlU2l6ZTtcbiAgICBjb25zdCByZXN1bHQ6IGFueVtdID0gW107XG5cbiAgICBncm91cE9yZGVyLmZvckVhY2goKGdyb3VwVmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwUm93cyA9IGdyb3VwTWFwLmdldChncm91cFZhbHVlKSE7XG4gICAgICBjb25zdCB0b3RhbENvdW50ID0gZ3JvdXBSb3dzLmxlbmd0aDtcbiAgICAgIGNvbnN0IGN1cnJlbnRQYWdlID0gcGFnZVNpemUgPT09IDAgPyAwIDogdGhpcy5fZ3JvdXBCeS5nZXRQYWdlKGdyb3VwVmFsdWUpO1xuICAgICAgY29uc3QgcGFnZUNvdW50ID0gcGFnZVNpemUgPT09IDAgPyAxIDogTWF0aC5tYXgoMSwgTWF0aC5jZWlsKHRvdGFsQ291bnQgLyBwYWdlU2l6ZSkpO1xuICAgICAgY29uc3QgY29sbGFwc2VkID0gdGhpcy5pc0dyb3VwQ29sbGFwc2VkKGdyb3VwVmFsdWUpO1xuXG4gICAgICByZXN1bHQucHVzaCh7IFtHUk9VUF9IRUFERVJfTUFSS0VSXTogdHJ1ZSwgW1JPV19HUk9VUF9LRVldOiBncm91cFZhbHVlLCBbUk9XX0dST1VQX0NPVU5UXTogdG90YWxDb3VudCwgW1JPV19HUk9VUF9QQUdFXTogY3VycmVudFBhZ2UsIFtST1dfR1JPVVBfUEFHRV9DT1VOVF06IHBhZ2VDb3VudCB9KTtcblxuICAgICAgaWYgKCFjb2xsYXBzZWQpIHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBwYWdlU2l6ZSA9PT0gMCA/IDAgOiBjdXJyZW50UGFnZSAqIHBhZ2VTaXplO1xuICAgICAgICBjb25zdCBlbmQgPSBwYWdlU2l6ZSA9PT0gMCA/IHRvdGFsQ291bnQgOiBNYXRoLm1pbihzdGFydCArIHBhZ2VTaXplLCB0b3RhbENvdW50KTtcbiAgICAgICAgZ3JvdXBSb3dzLnNsaWNlKHN0YXJ0LCBlbmQpLmZvckVhY2goKHJvdywgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlkeCA9IHN0YXJ0ICsgaTtcbiAgICAgICAgICBjb25zdCBwcm9qZWN0ZWQ6IGFueSA9IHsgW1JPV19SQVdfS0VZXTogcm93LCBbUk9XX0lOREVYX0tFWV06IGlkeCB9O1xuICAgICAgICAgIHRoaXMuYWN0aXZlQ29sdW1ucy5mb3JFYWNoKChjb2wpID0+IHtcbiAgICAgICAgICAgIHByb2plY3RlZFtjb2wua2V5XSA9IHRoaXMucmVzb2x2ZUNlbGxWYWx1ZShjb2wsIHJvdywgaWR4KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXN1bHQucHVzaChwcm9qZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIF9idWlsZFNvcnRDb21wYXJhdG9yKCk6ICgoYTogVCwgYjogVCkgPT4gbnVtYmVyKSB8IG51bGwge1xuICAgIGNvbnN0IHNvcnQgPSB0aGlzLl9hY3RpdmVTb3J0LmFjdGl2ZSAmJiB0aGlzLl9hY3RpdmVTb3J0LmRpcmVjdGlvblxuICAgICAgPyB0aGlzLl9hY3RpdmVTb3J0XG4gICAgICA6IHRoaXMucmVzb2x2ZWRDb25maWcuZGVmYXVsdFNvcnQgPz8geyBhY3RpdmU6ICcnLCBkaXJlY3Rpb246ICcnIGFzIGNvbnN0IH07XG4gICAgY29uc3QgeyBhY3RpdmUsIGRpcmVjdGlvbiB9ID0gc29ydDtcbiAgICBpZiAoIWFjdGl2ZSB8fCAhZGlyZWN0aW9uKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gKGE6IFQsIGI6IFQpOiBudW1iZXIgPT4ge1xuICAgICAgY29uc3QgdmEgPSB0aGlzLmdldExhenlBd2FyZVZhbHVlKGFjdGl2ZSwgYSk7XG4gICAgICBjb25zdCB2YiA9IHRoaXMuZ2V0TGF6eUF3YXJlVmFsdWUoYWN0aXZlLCBiKTtcbiAgICAgIGxldCBjbXAgPSAwO1xuICAgICAgaWYgKHR5cGVvZiB2YSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIHZiID09PSAnbnVtYmVyJykge1xuICAgICAgICBjbXAgPSB2YSA8IHZiID8gLTEgOiB2YSA+IHZiID8gMSA6IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzYSA9IHZhID09IG51bGwgPyAnJyA6IFN0cmluZyh2YSkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgY29uc3Qgc2IgPSB2YiA9PSBudWxsID8gJycgOiBTdHJpbmcodmIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGNtcCA9IHNhIDwgc2IgPyAtMSA6IHNhID4gc2IgPyAxIDogMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkaXJlY3Rpb24gPT09ICdhc2MnID8gY21wIDogLWNtcDtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldG91cm5lIGxhIHZhbGV1ciB0ZWxsZSBxdSdlbGxlIGVzdCBhZmZpY2jDqWUgZGFucyBsYSBjZWxsdWxlLCBlbiBzdWl2YW50IGV4YWN0ZW1lbnRcbiAgICogbGUgbcOqbWUgY2hlbWluIHF1ZSByZXNvbHZlQ2VsbFZhbHVlIOKAlCB1dGlsaXPDqWUgcG91ciBsYSByZWNoZXJjaGUgcGxlaW4tdGV4dGUuXG4gICAqIE5lIHBhc3NlIHBhcyBwYXIgc29ydFZhbHVlICh2YWxldXIgYnJ1dGUgZGUgdHJpKSBjb250cmFpcmVtZW50IMOgIGdldExhenlBd2FyZVZhbHVlLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXREaXNwbGF5VmFsdWVGb3JTZWFyY2goY29sOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+LCByb3c6IFQpOiBhbnkge1xuICAgIGlmIChjb2wubGF6eSkge1xuICAgICAgY29uc3Qgc3RhdHVzID0gdGhpcy5fbGF6eUNvbHVtblN0YXR1cy5nZXQoY29sLmtleSkgPz8gJ2lkbGUnO1xuICAgICAgaWYgKHN0YXR1cyAhPT0gJ2xvYWRlZCcpIHJldHVybiBudWxsO1xuICAgICAgY29uc3Qgcm93TWFwID0gdGhpcy5fbGF6eUNvbHVtbkRhdGEuZ2V0KGNvbC5rZXkpO1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyb3dNYXA/LmdldChyb3cpID8/ICcnKTtcbiAgICB9XG4gICAgaWYgKGNvbC5zZWFyY2hWYWx1ZSkge1xuICAgICAgcmV0dXJuIGNvbC5zZWFyY2hWYWx1ZShyb3csIDApO1xuICAgIH1cbiAgICBjb25zdCByYXdWYWx1ZSA9IGNvbC52YWx1ZSA/IGNvbC52YWx1ZShyb3csIDApIDogKHJvdyBhcyBhbnkpPy5bY29sLmtleV07XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyYXdWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGdldExhenlBd2FyZVZhbHVlKGNvbHVtbktleTogc3RyaW5nLCByb3c6IFQpOiBhbnkge1xuICAgIGNvbnN0IGNvbERlZiA9IHRoaXMuX2NvbHVtbk1hcC5nZXQoY29sdW1uS2V5KTtcbiAgICBpZiAoY29sRGVmPy5sYXp5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGF6eUNvbHVtbkRhdGEuZ2V0KGNvbHVtbktleSk/LmdldChyb3cpID8/IG51bGw7XG4gICAgfVxuICAgIGlmIChjb2xEZWY/LnNvcnRWYWx1ZSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShjb2xEZWYuc29ydFZhbHVlKHJvdywgMCkpO1xuICAgIH1cbiAgICBpZiAoY29sRGVmPy52YWx1ZSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShjb2xEZWYudmFsdWUocm93LCAwKSk7XG4gICAgfVxuICAgIHJldHVybiAocm93IGFzIGFueSlbY29sdW1uS2V5XTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUNlbGxWYWx1ZShjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4sIHJvdzogVCwgaW5kZXg6IG51bWJlcik6IGFueSB7XG4gICAgaWYgKGNvbC5sYXp5KSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSB0aGlzLl9sYXp5Q29sdW1uU3RhdHVzLmdldChjb2wua2V5KSA/PyAnaWRsZSc7XG4gICAgICBpZiAoc3RhdHVzID09PSAnbG9hZGluZycpIHJldHVybiBMQVpZX0xPQURJTkdfVkFMVUU7XG4gICAgICBpZiAoc3RhdHVzID09PSAnZXJyb3InKSByZXR1cm4gTEFaWV9FUlJPUl9WQUxVRTtcbiAgICAgIGlmIChzdGF0dXMgPT09ICdsb2FkZWQnKSB7XG4gICAgICAgIGNvbnN0IHJvd01hcCA9IHRoaXMuX2xhenlDb2x1bW5EYXRhLmdldChjb2wua2V5KTtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyb3dNYXA/LmdldChyb3cpID8/ICcnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgY29uc3QgdmFsdWVQcm92aWRlciA9IGNvbC52YWx1ZTtcbiAgICBjb25zdCByYXdWYWx1ZSA9IHZhbHVlUHJvdmlkZXIgPyB2YWx1ZVByb3ZpZGVyKHJvdywgaW5kZXgpIDogKHJvdyBhcyBhbnkpPy5bY29sLmtleV07XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUNlbGxWYWx1ZShyYXdWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYWdlU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1heCgxLCB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplIHx8IHRoaXMucGFnZVNpemUgfHwgNSk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYWdlU2l6ZU9wdGlvbnMoKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplT3B0aW9ucyB8fCBbNSwgMTAsIDIwXTtcbiAgICBjb25zdCB1bmlxdWUgPSBbLi4ubmV3IFNldChvcHRpb25zLmZpbHRlcigodmFsdWUpID0+IHZhbHVlID4gMCkpXTtcblxuICAgIGlmICghdW5pcXVlLmluY2x1ZGVzKHRoaXMucGFnZVNpemUpKSB7XG4gICAgICB1bmlxdWUucHVzaCh0aGlzLnBhZ2VTaXplKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVBhZ2VTaXplT3B0aW9uc0dyb3VwQnkoKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVkQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplT3B0aW9uc0dyb3VwQnkgfHwgdGhpcy5yZXNvbHZlZENvbmZpZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnMgfHwgWzUsIDEwLCAyMF07XG4gICAgY29uc3QgdW5pcXVlID0gWy4uLm5ldyBTZXQob3B0aW9ucy5maWx0ZXIoKHYpID0+IHYgPiAwKSldO1xuICAgIGlmICh0aGlzLmdyb3VwUGFnZVNpemUgPiAwICYmICF1bmlxdWUuaW5jbHVkZXModGhpcy5ncm91cFBhZ2VTaXplKSkge1xuICAgICAgdW5pcXVlLnB1c2godGhpcy5ncm91cFBhZ2VTaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuaXF1ZS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVEZWZhdWx0R3JvdXBQYWdlU2l6ZSgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNmZyA9IHRoaXMucmVzb2x2ZWRDb25maWc7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnNHcm91cEJ5IHx8IGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZU9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnM/Lmxlbmd0aCkgcmV0dXJuIG9wdGlvbnNbMF07XG4gICAgcmV0dXJuIGNmZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZSB8fCA1O1xuICB9XG5cbiAgcHJpdmF0ZSB1bmlxdWVDb2x1bW5zQnlLZXkoY29sdW1uczogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdKTogVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdIHtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcmV0dXJuIGNvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IHtcbiAgICAgIGlmIChzZWVuLmhhcyhjb2x1bW4ua2V5KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBzZWVuLmFkZChjb2x1bW4ua2V5KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhdHRhY2hQYWdpbmF0b3IoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3dQYWdpbmF0aW9uKSB7XG4gICAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5wYWdpbmF0b3IgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucGFnaW5hdG9yKSByZXR1cm47XG5cbiAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5wYWdpbmF0b3IgPSBudWxsO1xuICAgIHRoaXMucGFnaW5hdG9yLnBhZ2VTaXplID0gdGhpcy5wYWdlU2l6ZTtcblxuICAgIGlmICh0aGlzLl9wYWdpbmF0b3JTdWJzY3JpYmVkICE9PSB0aGlzLnBhZ2luYXRvcikge1xuICAgICAgdGhpcy5fcGFnaW5hdG9yU3Vic2NyaWJlZCA9IHRoaXMucGFnaW5hdG9yO1xuICAgICAgdGhpcy5wYWdpbmF0b3IucGFnZS5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucGFnZVNpemUgPSB0aGlzLnBhZ2luYXRvciEucGFnZVNpemU7XG4gICAgICAgIHRoaXMucGFnZUNoYW5nZS5lbWl0KHsgcGFnZUluZGV4OiB0aGlzLnBhZ2luYXRvciEucGFnZUluZGV4LCBwYWdlU2l6ZTogdGhpcy5wYWdpbmF0b3IhLnBhZ2VTaXplIH0pO1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1JlbmRlciAhPT0gbnVsbCkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9wcm9qZWN0Q3VycmVudFBhZ2UoKTtcbiAgICAgICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhdHRhY2hTb3J0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zb3J0KSByZXR1cm47XG5cbiAgICB0aGlzLnRhYmxlRGF0YVNvdXJjZS5zb3J0ID0gbnVsbCBhcyBhbnk7XG5cbiAgICBpZiAodGhpcy5fc29ydFN1YnNjcmliZWQgIT09IHRoaXMuc29ydCkge1xuICAgICAgdGhpcy5fc29ydFN1YnNjcmliZWQgPSB0aGlzLnNvcnQ7XG4gICAgICB0aGlzLnNvcnQuc29ydENoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvcnQgPSB7XG4gICAgICAgICAgYWN0aXZlOiB0aGlzLnNvcnQuYWN0aXZlLFxuICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5zb3J0LmRpcmVjdGlvbixcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zb3J0Q2hhbmdlLmVtaXQoeyBhY3RpdmU6IHRoaXMuc29ydC5hY3RpdmUsIGRpcmVjdGlvbjogdGhpcy5zb3J0LmRpcmVjdGlvbiB9KTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVSZW5kZXIoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiPHNlY3Rpb24gY2xhc3M9XCJqcXVlcnktdGFibGUtd3JhcHBlclwiPlxuICA8aGVhZGVyIGNsYXNzPVwidGFibGUtaGVhZGVyXCIgKm5nSWY9XCJzaG93VGl0bGVcIj5cbiAgICA8aDM+e3sgdGl0bGUgfX08L2gzPlxuICA8L2hlYWRlcj5cblxuICA8ZGl2XG4gICAgY2xhc3M9XCJ0YWJsZS1sYXlvdXRcIlxuICAgIFtjbGFzcy5uby1zbGljZV09XCIhX3Nob3dTbGljZVBhbmVsIHx8IF9zbGljZVBhbmVsQ29sbGFwc2VkXCJcbiAgPlxuICAgIDxzbGljZS1wYW5lbFxuICAgICAgW3N0eWxlLmRpc3BsYXldPVwiIV9zaG93U2xpY2VQYW5lbCB8fCBfc2xpY2VQYW5lbENvbGxhcHNlZCA/ICdub25lJyA6IG51bGxcIlxuICAgICAgW3NsaWNlQ29uZmlnc109XCJfc2xpY2VDb25maWdzXCJcbiAgICAgIFtjb2x1bW5zXT1cIl9zbGljZUNvbHVtbnNcIlxuICAgICAgW2RhdGFdPVwiX3NsaWNlRGF0YVwiXG4gICAgICBbbGF6eURhdGFdPVwiX2xhenlDb2x1bW5EYXRhXCJcbiAgICAgIFtsYXp5U3RhdHVzXT1cIl9sYXp5Q29sdW1uU3RhdHVzXCJcbiAgICAgIFtzaG93VG9nZ2xlXT1cIl9zbGljZVNob3dUb2dnbGVcIlxuICAgICAgW2NvbGxhcHNlZEJ5RGVmYXVsdF09XCJfc2xpY2VQYW5lbENvbGxhcHNlZFwiXG4gICAgICAoZmlsdGVyQ2hhbmdlKT1cIm9uU2xpY2VGaWx0ZXJDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAoZHluYW1pY1NsaWNlS2V5c0NoYW5nZSk9XCJvbkR5bmFtaWNTbGljZUtleXNDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAoY29sbGFwc2VkQ2hhbmdlKT1cIm9uU2xpY2VQYW5lbENvbGxhcHNlZENoYW5nZSgkZXZlbnQpXCJcbiAgICA+PC9zbGljZS1wYW5lbD5cblxuICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1zaGVsbFwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXRvb2xiYXJcIiAqbmdJZj1cInNob3dUb29sYmFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS10b29sYmFyLWxlZnRcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cInNob3dTbGljZUV4cGFuZEJ0blwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2xpY2UtZXhwYW5kLWJ0blwiXG4gICAgICAgICAgICBbdGl0bGVdPVwiaTE4bi5leHBhbmRGaWx0ZXJUaXRsZVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwYW5kU2xpY2VQYW5lbCgpXCJcbiAgICAgICAgICA+PG1hdC1pY29uIGNsYXNzPVwic2xpY2UtZXhwYW5kLW1hdC1pY29uXCI+bWVudTwvbWF0LWljb24+PC9idXR0b24+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInNob3dTZWFyY2hCYXJcIiBjbGFzcz1cInNlYXJjaC1pbnB1dC13cmFwcGVyXCI+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwic2VhcmNoLWljb25cIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCI4LjVcIiBjeT1cIjguNVwiIHI9XCI1LjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIi8+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTMgMTNMMTcgMTdcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VhcmNoUXVlcnlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvblNlYXJjaENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImkxOG4uc2VhcmNoUGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzZWFyY2hRdWVyeVwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNlYXJjaC1jbGVhci1idG5cIiAoY2xpY2spPVwic2VhcmNoUXVlcnkgPSAnJzsgb25TZWFyY2hDaGFuZ2UoKVwiPsOXPC9idXR0b24+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNlYXJjaC1jb3VudFwiPnt7IGZpbHRlcmVkUm93Q291bnQgfX08L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwic2hvd1ZpZXdCdXR0b25cIiBjbGFzcz1cInRhYmxlLXRvb2xiYXItcmlnaHRcIj5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2hvd1ZpZXdCdXR0b25cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2aWV3LWJ0blwiIFttYXRNZW51VHJpZ2dlckZvcl09XCJ2aWV3TWVudVwiICN2aWV3TWVudVRyaWdnZXI9XCJtYXRNZW51VHJpZ2dlclwiIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1ZpZXcnXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ2aWV3LWJ0bi1pY29uXCI+c2V0dGluZ3M8L21hdC1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgPG1hdC1tZW51ICN2aWV3TWVudT1cIm1hdE1lbnVcIiBbcGFuZWxDbGFzc109XCIndmlldy1tZW51LXBhbmVsJ1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInNob3dGaWVsZHNcIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJmaWVsZHNTdWJNZW51XCIgY2xhc3M9XCJ2aWV3LW1lbnUtc3ViLXRyaWdnZXJcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aWV3LW1lbnUtc3ViLWxhYmVsXCI+e3sgaTE4bi52aWV3TWVudUZpZWxkcyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aWV3LW1lbnUtc3ViLXZhbHVlXCI+e3sgdmlzaWJsZUNvbHVtbnMubGVuZ3RoIH19L3t7IHRvdGFsQ29sdW1uQ291bnQgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93R3JvdXBCeVNlY3Rpb25cIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJncm91cEJ5U3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPnt7IGkxOG4udmlld01lbnVHcm91cEJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1zdWItdmFsdWVcIj57eyBhY3RpdmVHcm91cEJ5TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93QWRkU2xpY2VCdXR0b25cIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJzbGljZUJ5U3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPnt7IGkxOG4udmlld01lbnVTbGljZUJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1zdWItdmFsdWVcIj57eyBhY3RpdmVTbGljZUJ5TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cInNob3dFeHBvcnRCdXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1leHBvcnQtZGl2aWRlclwiPjwvbWF0LWRpdmlkZXI+XG4gICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2hvd0V4cG9ydEJ1dHRvblwiIG1hdC1tZW51LWl0ZW0gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1tZW51LWV4cG9ydC1pdGVtXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRXhwb3J0KCk7IHZpZXdNZW51VHJpZ2dlci5jbG9zZU1lbnUoKVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ2aWV3LW1lbnUtZXhwb3J0LWljb25cIj5kb3dubG9hZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPnt7IGkxOG4uZXhwb3J0QnV0dG9uTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cInNob3dQcmVmZXJlbmNlc01lbnVcIiBjbGFzcz1cInZpZXctbWVudS1leHBvcnQtZGl2aWRlclwiPjwvbWF0LWRpdmlkZXI+XG4gICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2hvd1ByZWZlcmVuY2VzTWVudVwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cInByZWZlcmVuY2VzU3ViTWVudVwiIGNsYXNzPVwidmlldy1tZW51LXN1Yi10cmlnZ2VyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LXN1Yi1sYWJlbFwiPnt7IGkxOG4ucHJlZmVyZW5jZXNNZW51TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuXG4gICAgICAgICAgPG1hdC1tZW51ICNwcmVmZXJlbmNlc1N1Yk1lbnU9XCJtYXRNZW51XCIgW3BhbmVsQ2xhc3NdPVwiJ3ZpZXctc3VibWVudS1wYW5lbCdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2aWV3LXN1Ym1lbnVcIiAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtaXRlbVwiIChtb3VzZWRvd24pPVwiZW50ZXJFZGl0TW9kZSgpOyB2aWV3TWVudVRyaWdnZXIuY2xvc2VNZW51KClcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIj5lZGl0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICB7eyBpMThuLnByZWZlcmVuY2VzRWRpdCB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtaXRlbVwiIChtb3VzZWRvd24pPVwic2F2ZVByZWZlcmVuY2VzKCk7IHZpZXdNZW51VHJpZ2dlci5jbG9zZU1lbnUoKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInZpZXctbWVudS1jb2wtaWNvblwiPnNhdmU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7IGkxOG4ucHJlZmVyZW5jZXNTYXZlIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1pdGVtXCIgW2Rpc2FibGVkXT1cIiFoYXNTYXZlZFByZWZlcmVuY2VzXCIgKG1vdXNlZG93bik9XCJjbGVhclByZWZlcmVuY2VzKCk7IHZpZXdNZW51VHJpZ2dlci5jbG9zZU1lbnUoKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInZpZXctbWVudS1jb2wtaWNvblwiPmRlbGV0ZV9vdXRsaW5lPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICB7eyBpMThuLnByZWZlcmVuY2VzQ2xlYXIgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuXG4gICAgICAgICAgPG1hdC1tZW51ICNmaWVsZHNTdWJNZW51PVwibWF0TWVudVwiIFtwYW5lbENsYXNzXT1cIid2aWV3LXN1Ym1lbnUtcGFuZWwnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmlldy1zdWJtZW51XCIgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1tZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIG1lbnVCYXNlQ29sdW1uc1wiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFjb2x1bW4ub3B0aW9uYWwgJiYgIWFsbG93Q29sdW1uUmVtb3ZhbFwiXG4gICAgICAgICAgICAgICAgKG1vdXNlZG93bik9XCJvbkNvbHVtblZpc2liaWxpdHlDaGFuZ2UoY29sdW1uLCAhaXNDb2x1bW5WaXNpYmxlKGNvbHVtbi5rZXkpKVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LWNoZWNrXCI+e3sgaXNDb2x1bW5WaXNpYmxlKGNvbHVtbi5rZXkpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb2x1bW4uaWNvblwiIGNsYXNzPVwidmlldy1tZW51LWNvbC1pY29uXCIgZm9udFNldD1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+e3sgY29sdW1uLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7IGNvbExhYmVsKGNvbHVtbikgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtZW51T3B0aW9uYWxDb2x1bW5zLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1pdGVtXCIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBtZW51T3B0aW9uYWxDb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIoaXNDb2x1bW5WaXNpYmxlKGNvbHVtbi5rZXkpICYmIHZpc2libGVDb2x1bW5zLmxlbmd0aCA9PT0gMSkgfHwgZ2V0TGF6eUNvbHVtblN0YXR1cyhjb2x1bW4ua2V5KSA9PT0gJ2xvYWRpbmcnXCJcbiAgICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25Db2x1bW5WaXNpYmlsaXR5Q2hhbmdlKGNvbHVtbiwgIWlzQ29sdW1uVmlzaWJsZShjb2x1bW4ua2V5KSlcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlldy1tZW51LWNoZWNrXCI+e3sgaXNDb2x1bW5WaXNpYmxlKGNvbHVtbi5rZXkpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbHVtbi5pY29uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIiBmb250U2V0PVwibWF0ZXJpYWwtaWNvbnMtb3V0bGluZWRcIj57eyBjb2x1bW4uaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICB7eyBjb2xMYWJlbChjb2x1bW4pIH19XG4gICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImNvbHVtbi5sYXp5ICYmIGdldExhenlDb2x1bW5TdGF0dXMoY29sdW1uLmtleSkgPT09ICdsb2FkaW5nJ1wiIGNsYXNzPVwibGF6eS1tZW51LXNwaW5uZXJcIj7ihrs8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImNvbHVtbi5sYXp5ICYmIGdldExhenlDb2x1bW5TdGF0dXMoY29sdW1uLmtleSkgPT09ICdlcnJvcidcIiBjbGFzcz1cImxhenktbWVudS1lcnJvclwiIFt0aXRsZV09XCJpMThuLmxhenlFcnJvck1lbnVUaXRsZVwiPuKaoDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuXG4gICAgICAgICAgPG1hdC1tZW51ICNncm91cEJ5U3ViTWVudT1cIm1hdE1lbnVcIiBbcGFuZWxDbGFzc109XCIndmlldy1zdWJtZW51LXBhbmVsJ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZpZXctc3VibWVudVwiIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1pdGVtXCIgKm5nRm9yPVwibGV0IGNvbCBvZiBncm91cEJ5Q29sdW1uc1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJhY3RpdmVHcm91cEJ5S2V5ID09PSBjb2wua2V5XCJcbiAgICAgICAgICAgICAgICAobW91c2Vkb3duKT1cIm9uR3JvdXBCeUNoYW5nZShhY3RpdmVHcm91cEJ5S2V5ID09PSBjb2wua2V5ID8gbnVsbCA6IGNvbC5rZXkpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aWV3LW1lbnUtY2hlY2tcIj57eyBhY3RpdmVHcm91cEJ5S2V5ID09PSBjb2wua2V5ID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb2wuaWNvblwiIGNsYXNzPVwidmlldy1tZW51LWNvbC1pY29uXCIgZm9udFNldD1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+e3sgY29sLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7IGNvbExhYmVsKGNvbCkgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuXG4gICAgICAgICAgPG1hdC1tZW51ICNzbGljZUJ5U3ViTWVudT1cIm1hdE1lbnVcIiBbcGFuZWxDbGFzc109XCIndmlldy1zdWJtZW51LXBhbmVsJ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZpZXctc3VibWVudVwiIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctbWVudS1pdGVtXCIgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2xpY2VCeU1lbnVJdGVtc1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpc1NsaWNlTWVudUl0ZW1BY3RpdmUoaXRlbSlcIlxuICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25TbGljZU1lbnVJdGVtQ2xpY2soaXRlbSlcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbWVudS1jaGVja1wiPnt7IGlzU2xpY2VNZW51SXRlbUFjdGl2ZShpdGVtKSA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiaXRlbS5pY29uXCIgY2xhc3M9XCJ2aWV3LW1lbnUtY29sLWljb25cIiBmb250U2V0PVwibWF0ZXJpYWwtaWNvbnMtb3V0bGluZWRcIj57eyBpdGVtLmljb24gfX08L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIHt7IGl0ZW0udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC1tZW51PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwidGFibGUtYm9keS13cmFwcGVyXCI+XG5cbiAgICAgIDwhLS0gQmFubmnDqHJlIG1lc3NhZ2UgcHLDqWbDqXJlbmNlcyAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJfcHJlZmVyZW5jZXNNZXNzYWdlXCIgY2xhc3M9XCJwcmVmZXJlbmNlcy1tZXNzYWdlXCI+XG4gICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInByZWZlcmVuY2VzLW1lc3NhZ2UtaWNvblwiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPnt7IF9wcmVmZXJlbmNlc01lc3NhZ2UgfX08L3NwYW4+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBCb3V0b24gZGUgY29uZmlybWF0aW9uIGR1IG1vZGUgw6lkaXRpb24gLS0+XG4gICAgICA8YnV0dG9uXG4gICAgICAgICpuZ0lmPVwiX2VkaXRNb2RlXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiZWRpdC1jb25maXJtLWJ0blwiXG4gICAgICAgIFt0aXRsZV09XCJpMThuLnByZWZlcmVuY2VzQ29uZmlybUVkaXRcIlxuICAgICAgICAoY2xpY2spPVwiY29uZmlybUVkaXRNb2RlKClcIlxuICAgICAgPlxuICAgICAgICA8bWF0LWljb24+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWJvZHktc2Nyb2xsXCIgI3RhYmxlQm9keVNjcm9sbD5cbiAgICAgIDx0YWJsZSBtYXQtdGFibGUgbWF0U29ydCBbZGF0YVNvdXJjZV09XCJ0YWJsZURhdGFTb3VyY2VcIiBjbGFzcz1cImpxdWVyeS10YWJsZVwiXG4gICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aF09XCJ0YWJsZU1pbldpZHRoXCJcbiAgICAgICAgICAgICBbdHJhY2tCeV09XCJ0cmFja1Jvd0ZuXCJcbiAgICAgICAgICAgICBbbWF0U29ydEFjdGl2ZV09XCJfbWF0U29ydEFjdGl2ZVwiIFttYXRTb3J0RGlyZWN0aW9uXT1cIl9tYXRTb3J0RGlyZWN0aW9uXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiB2aXNpYmxlQ29sdW1uc1wiIFttYXRDb2x1bW5EZWZdPVwiY29sdW1uLmtleVwiPlxuICAgICAgICAgIDx0aFxuICAgICAgICAgICAgbWF0LWhlYWRlci1jZWxsXG4gICAgICAgICAgICAqbWF0SGVhZGVyQ2VsbERlZlxuICAgICAgICAgICAgW21hdC1zb3J0LWhlYWRlcl09XCIoIV9lZGl0TW9kZSAmJiBjb2x1bW4uc29ydGFibGUgIT09IGZhbHNlKSA/IGNvbHVtbi5rZXkgOiAnJ1wiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiX2VkaXRNb2RlIHx8IGNvbHVtbi5zb3J0YWJsZSA9PT0gZmFsc2VcIlxuICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImdldENvbHVtbldpZHRoKGNvbHVtbi5rZXkpXCJcbiAgICAgICAgICAgIFtjbGFzcy5kcmFnLWVuYWJsZWRdPVwiaXNDb2x1bW5EcmFnRHJvcEVuYWJsZWQgfHwgX2VkaXRNb2RlXCJcbiAgICAgICAgICAgIFtjbGFzcy5kcm9wLXRhcmdldF09XCJpc0hlYWRlckRyb3BUYXJnZXQoY29sdW1uLmtleSlcIlxuICAgICAgICAgICAgW2NsYXNzLmVkaXQtbW9kZS1oZWFkZXJdPVwiX2VkaXRNb2RlXCJcbiAgICAgICAgICAgIChkcmFnb3Zlcik9XCJvbkhlYWRlckRyYWdPdmVyKGNvbHVtbi5rZXksICRldmVudClcIlxuICAgICAgICAgICAgKGRyb3ApPVwib25IZWFkZXJEcm9wKGNvbHVtbi5rZXksICRldmVudClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkLWNlbGxcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29sdW1uLmljb25cIiBjbGFzcz1cImhlYWQtaWNvblwiIGZvbnRTZXQ9XCJtYXRlcmlhbC1pY29ucy1vdXRsaW5lZFwiPnt7IGNvbHVtbi5pY29uIH19PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoZWFkLXRleHRcIiBbdGl0bGVdPVwiY29sdW1uLmhlYWRlclwiPnt7IGNvbHVtbi5oZWFkZXIgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJpc0NvbHVtbkRyYWdEcm9wRW5hYmxlZCB8fCBfZWRpdE1vZGVcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZHJhZy1oYW5kbGVcIlxuICAgICAgICAgICAgICAgIGRyYWdnYWJsZT1cInRydWVcIlxuICAgICAgICAgICAgICAgIChkcmFnc3RhcnQpPVwib25IZWFkZXJEcmFnU3RhcnQoY29sdW1uLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKGRyYWdlbmQpPVwib25IZWFkZXJEcmFnRW5kKClcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmRyYWdfaW5kaWNhdG9yPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tIFBvaWduw6llIGRlIHJlc2l6ZSAodmlzaWJsZSB1bmlxdWVtZW50IGVuIG1vZGUgw6lkaXRpb24pIC0tPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgKm5nSWY9XCJfZWRpdE1vZGVcIlxuICAgICAgICAgICAgICBjbGFzcz1cImNvbC1yZXNpemUtaGFuZGxlXCJcbiAgICAgICAgICAgICAgZHJhZ2dhYmxlPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAobW91c2Vkb3duKT1cIm9uUmVzaXplU3RhcnQoY29sdW1uLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgICA+PC9zcGFuPlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0Q29sdW1uV2lkdGgoY29sdW1uLmtleSlcIlxuICAgICAgICAgICAgW2NsYXNzLmVkaXQtbW9kZS1jZWxsXT1cIl9lZGl0TW9kZVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFfZWRpdE1vZGU7IGVsc2UgZWRpdE1vZGVDZWxsVHBsXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDZWxsVGVtcGxhdGUoY29sdW1uLmtleSkgYXMgY3VzdG9tVHBsOyBlbHNlIGRlZmF1bHRDZWxsVHBsXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImN1c3RvbVRwbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IHJvd1tfUk9XX1JBV19LRVldLCBpbmRleDogcm93W19ST1dfSU5ERVhfS0VZXSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRDZWxsVHBsPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImNvbHVtbi5sYXp5ID8gZ2V0TGF6eVJlbmRlclR5cGUocm93W2NvbHVtbi5rZXldKSA6ICd2YWx1ZSdcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInbG9hZGluZydcIiBjbGFzcz1cImxhenktc2tlbGV0b25cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ1N3aXRjaENhc2U9XCInZXJyb3InXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibGF6eS1lcnJvci1idG5cIiAoY2xpY2spPVwicmV0cnlMYXp5Q29sdW1uKGNvbHVtbilcIiBbdGl0bGVdPVwiaTE4bi5sYXp5RXJyb3JUaXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhenktZXJyb3ItaWNvblwiPuKaoDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYXp5LWVycm9yLWxhYmVsXCI+e3sgaTE4bi5sYXp5UmV0cnkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaERlZmF1bHQgY2xhc3M9XCJjZWxsLXRleHRcIiBbY2xhc3MuY2VsbC1lbXB0eV09XCJpc0NlbGxFbXB0eShyb3dbY29sdW1uLmtleV0pXCIgW3RpdGxlXT1cImFzVGl0bGUocm93W2NvbHVtbi5rZXldKVwiPnt7IGlzQ2VsbEVtcHR5KHJvd1tjb2x1bW4ua2V5XSkgPyBpMThuLmNlbGxFbXB0eSA6IHJvd1tjb2x1bW4ua2V5XSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNlZGl0TW9kZUNlbGxUcGw+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY2VsbC10ZXh0IGNlbGwtZWRpdC1tb2RlXCIgW3RpdGxlXT1cImFzVGl0bGUocm93W2NvbHVtbi5rZXldKVwiPnt7IHJvd1tjb2x1bW4ua2V5XSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPHRyIG1hdC1oZWFkZXItcm93ICptYXRIZWFkZXJSb3dEZWY9XCJyZW5kZXJlZENvbHVtbnM7IHN0aWNreTogdHJ1ZVwiPjwvdHI+XG4gICAgICAgIDx0clxuICAgICAgICAgIG1hdC1yb3dcbiAgICAgICAgICAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogcmVuZGVyZWRDb2x1bW5zOyB3aGVuOiAhaXNHcm91cEhlYWRlclwiXG4gICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwiaGFzUm93Q2xpY2tIYW5kbGVyICYmICFfZWRpdE1vZGUgPyAwIDogbnVsbFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwiZ2V0Um93Q2xhc3Mocm93KVwiXG4gICAgICAgICAgW2NsYXNzLm5vLXBvaW50ZXJdPVwiIWhhc1Jvd0NsaWNrSGFuZGxlciB8fCBfZWRpdE1vZGVcIlxuICAgICAgICAgIFtjbGFzcy5lZGl0LW1vZGUtcm93XT1cIl9lZGl0TW9kZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiFfZWRpdE1vZGUgJiYgb25Sb3dDbGljayhyb3csICRldmVudClcIlxuICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cIiFfZWRpdE1vZGUgJiYgb25Sb3dDbGljayhyb3csIG51bGwpXCJcbiAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCIhX2VkaXRNb2RlICYmIG9uUm93Q2xpY2socm93LCBudWxsKVwiXG4gICAgICAgID48L3RyPlxuICAgICAgICA8bmctY29udGFpbmVyIFttYXRDb2x1bW5EZWZdPVwiX0dST1VQX1JPV19DT0xVTU5cIj5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2F0dHIuY29sc3Bhbl09XCJyZW5kZXJlZENvbHVtbnMubGVuZ3RoXCIgY2xhc3M9XCJncm91cC1oZWFkZXItY2VsbFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWhlYWRlci1sYWJlbFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyb3VwLWNoZXZyb25cIiBbY2xhc3MuY29sbGFwc2VkXT1cImlzR3JvdXBDb2xsYXBzZWQocm93W19ST1dfR1JPVVBfS0VZXSlcIiAqbmdJZj1cImlzTm9ybWFsR3JvdXBSb3cocm93KVwiPuKAujwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJpc05vcm1hbEdyb3VwUm93KHJvdylcIiBjbGFzcz1cImdyb3VwLWtleS1sYWJlbFwiPnt7IHJvd1tfUk9XX0dST1VQX0tFWV0gfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiaXNHcm91cFJvd0xvYWRpbmcocm93KVwiIGNsYXNzPVwibGF6eS1za2VsZXRvbiBncm91cC1sYXp5LWtleS1za2VsZXRvblwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJpc0dyb3VwUm93VG9vTWFueShyb3cpXCIgY2xhc3M9XCJncm91cC10b28tbWFueS1sYWJlbFwiPnt7IGkxOG4uZ3JvdXBUb29NYW55KHJvd1tfUk9XX0dST1VQX0NPVU5UXSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JvdXAtY291bnQtYmFkZ2VcIj57eyByb3dbX1JPV19HUk9VUF9DT1VOVF0gfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1wYWdpbmF0aW9uXCIgKm5nSWY9XCIhaXNHcm91cENvbGxhcHNlZChyb3dbX1JPV19HUk9VUF9LRVldKSAmJiByb3dbX1JPV19HUk9VUF9QQUdFX0NPVU5UXSA+IDFcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJncm91cC1wYWdlLWJ0blwiIFtkaXNhYmxlZF09XCJyb3dbX1JPV19HUk9VUF9QQUdFXSA9PT0gMFwiIChjbGljayk9XCJncm91cFBhZ2VCYWNrKHJvd1tfUk9XX0dST1VQX0tFWV0pXCI+4oC5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncm91cC1wYWdlLWluZm9cIj57eyByb3dbX1JPV19HUk9VUF9QQUdFXSArIDEgfX0gLyB7eyByb3dbX1JPV19HUk9VUF9QQUdFX0NPVU5UXSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImdyb3VwLXBhZ2UtYnRuXCIgW2Rpc2FibGVkXT1cInJvd1tfUk9XX0dST1VQX1BBR0VdID49IHJvd1tfUk9XX0dST1VQX1BBR0VfQ09VTlRdIC0gMVwiIChjbGljayk9XCJncm91cFBhZ2VGb3J3YXJkKHJvd1tfUk9XX0dST1VQX0tFWV0sIHJvd1tfUk9XX0dST1VQX0NPVU5UXSlcIj7igLo8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IFtfR1JPVVBfUk9XX0NPTFVNTl07IHdoZW46IGlzR3JvdXBIZWFkZXJcIlxuICAgICAgICAgICAgY2xhc3M9XCJncm91cC1oZWFkZXItcm93XCJcbiAgICAgICAgICAgIFtjbGFzcy5ncm91cC1oZWFkZXItbG9hZGluZ109XCJpc0dyb3VwUm93TG9hZGluZyhyb3cpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ncm91cC1oZWFkZXItdG9vLW1hbnldPVwiaXNHcm91cFJvd1Rvb01hbnkocm93KVwiXG4gICAgICAgICAgICBbYXR0ci5kYXRhLWdyb3VwLWtleV09XCJyb3dbX1JPV19HUk9VUF9LRVldXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkdyb3VwSGVhZGVyQ2xpY2socm93KVwiPjwvdHI+XG4gICAgICAgIDx0ciBjbGFzcz1cIm1hdC1tZGMtcm93IG5vLWRhdGEtcm93XCIgKm1hdE5vRGF0YVJvdz5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJtYXQtbWRjLWNlbGwgbm8tZGF0YS1jZWxsXCIgW2F0dHIuY29sc3Bhbl09XCJyZW5kZXJlZENvbHVtbnMubGVuZ3RoXCI+PC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj48IS0tIC90YWJsZS1ib2R5LXNjcm9sbCAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1ib2R5LW92ZXJsYXlcIiAqbmdJZj1cImVmZmVjdGl2ZUlzTG9hZGluZyB8fCBpc0VtcHR5XCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGFibGUtYm9keS1vdmVybGF5LXRleHRcIj57eyBlZmZlY3RpdmVJc0xvYWRpbmcgPyBsb2FkaW5nU3RhdGVMYWJlbCA6IGVtcHR5U3RhdGVMYWJlbCB9fTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+PCEtLSAvdGFibGUtYm9keS13cmFwcGVyIC0tPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiYm90dG9tLWJhclwiICpuZ0lmPVwic2hvd1BhZ2luYXRpb25cIj5cbiAgICAgICAgPG1hdC1wYWdpbmF0b3JcbiAgICAgICAgICBbbGVuZ3RoXT1cInRvdGFsUm93c1wiXG4gICAgICAgICAgW3BhZ2VTaXplXT1cInBhZ2VTaXplXCJcbiAgICAgICAgICBbcGFnZVNpemVPcHRpb25zXT1cInBhZ2VTaXplT3B0aW9uc1wiXG4gICAgICAgID48L21hdC1wYWdpbmF0b3I+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXJcIiAqbmdJZj1cImFjdGl2ZUdyb3VwQnlLZXlcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXItY29udGFpbmVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJvdHRvbS1iYXItbGVmdFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJncm91cC1yZXNldC1idG5cIiAoY2xpY2spPVwib25Hcm91cEJ5Q2hhbmdlKG51bGwpXCI+XG4gICAgICAgICAgICAgIDxzdmcgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwiZ3JvdXAtcmVzZXQtaWNvblwiPlxuICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMyA4YTUgNSAwIDEgMCA1LTUgNSA1IDAgMCAwLTMuNTQgMS40NkwzIDNcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjRcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zIDN2Mi41SDUuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIHt7IGkxOG4uZ3JvdXBSZW1vdmUgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLWJhci1zZXBhcmF0b3JcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1zb3J0LWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JvdXAtc29ydC1sYWJlbFwiPnt7IGkxOG4uZ3JvdXBTb3J0TGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZ3JvdXAtc29ydC1idG5cIiBbY2xhc3MuYWN0aXZlXT1cImdyb3VwU29ydE9yZGVyID09PSAnYXNjJ1wiIChjbGljayk9XCJvbkdyb3VwU29ydFRvZ2dsZSgnYXNjJylcIiBbdGl0bGVdPVwiaTE4bi5ncm91cFNvcnRBc2NcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+YXJyb3dfdXB3YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZ3JvdXAtc29ydC1idG5cIiBbY2xhc3MuYWN0aXZlXT1cImdyb3VwU29ydE9yZGVyID09PSAnZGVzYydcIiAoY2xpY2spPVwib25Hcm91cFNvcnRUb2dnbGUoJ2Rlc2MnKVwiIFt0aXRsZV09XCJpMThuLmdyb3VwU29ydERlc2NcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemUtbGFiZWxcIj57eyBpMThuLmdyb3VwUm93c1Blckdyb3VwIH19PC9kaXY+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBzdWJzY3JpcHRTaXppbmc9XCJkeW5hbWljXCIgY2xhc3M9XCJtYXQtbWRjLXBhZ2luYXRvci1wYWdlLXNpemUtc2VsZWN0XCI+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJncm91cFBhZ2VTaXplXCJcbiAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkdyb3VwUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgcGFuZWxDbGFzcz1cIm1hdC1tZGMtcGFnaW5hdG9yLXNlbGVjdC1wYWdlLXNpemUgZ3JvdXAtcGFnZS1zaXplLXBhbmVsXCJcbiAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCInYXV0bydcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QtdHJpZ2dlcj57eyBncm91cFBhZ2VTaXplID09PSAwID8gaTE4bi5ncm91cFNob3dBbGwgOiBncm91cFBhZ2VTaXplIH19PC9tYXQtc2VsZWN0LXRyaWdnZXI+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBwYWdlU2l6ZU9wdGlvbnNHcm91cEJ5XCIgW3ZhbHVlXT1cIm9wdFwiPnt7IG9wdCB9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMFwiPnt7IGkxOG4uZ3JvdXBTaG93QWxsIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvc2VjdGlvbj5cbiJdfQ==
|