@esfaenza/es-table 11.2.22-beta4 → 11.2.22-beta40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/bundles/esfaenza-es-table.umd.js +3201 -3008
  2. package/bundles/esfaenza-es-table.umd.js.map +1 -1
  3. package/bundles/esfaenza-es-table.umd.min.js +1 -15
  4. package/bundles/esfaenza-es-table.umd.min.js.map +1 -1
  5. package/esfaenza-es-table.d.ts +6 -5
  6. package/esfaenza-es-table.metadata.json +1 -1
  7. package/esm2015/esfaenza-es-table.js +7 -6
  8. package/esm2015/lib/components/es-table/es_table.component.js +1316 -0
  9. package/esm2015/lib/components/es-table/es_table.component.loc.js +36 -0
  10. package/esm2015/lib/components/es-td/es_td.component.js +106 -0
  11. package/esm2015/lib/components/es-th/es_th.component.js +160 -0
  12. package/esm2015/lib/components/pager/table_pager.component.js +106 -0
  13. package/esm2015/lib/components/pager/table_pager.component.loc.js +22 -0
  14. package/esm2015/lib/core/handlers/classes/ColumnMetadataHandler.js +667 -0
  15. package/esm2015/lib/core/handlers/classes/DynamicModeHandler.js +64 -0
  16. package/esm2015/lib/core/handlers/classes/ExportHandler.js +43 -0
  17. package/esm2015/lib/core/handlers/classes/HierarchyModeHandler.js +136 -0
  18. package/esm2015/lib/core/handlers/classes/ItemsHandler.js +130 -0
  19. package/esm2015/lib/core/handlers/classes/ReportModeHandler.js +70 -0
  20. package/esm2015/lib/core/handlers/classes/RowGroupingHandler.js +475 -0
  21. package/esm2015/lib/core/handlers/classes/SelectionHandler.js +527 -0
  22. package/esm2015/lib/core/handlers/classes/UtilitiesHandler.js +169 -0
  23. package/esm2015/lib/core/handlers/index.js +10 -0
  24. package/esm2015/lib/domain/configuration/EsTableDefaultable.js +4 -0
  25. package/esm2015/lib/domain/configuration/EsTableModuleConfig.js +4 -0
  26. package/esm2015/lib/domain/internals/classes/EsTableColumn.js +1 -1
  27. package/esm2015/lib/domain/internals/classes/ThElement.js +2 -0
  28. package/esm2015/lib/domain/internals/index.js +2 -1
  29. package/esm2015/lib/es-table.module.js +6 -6
  30. package/esm2015/lib/tokens.js +1 -1
  31. package/esm2015/public-api.js +6 -6
  32. package/fesm2015/esfaenza-es-table.js +2865 -2695
  33. package/fesm2015/esfaenza-es-table.js.map +1 -1
  34. package/lib/components/es-table/es_table.component.d.ts +632 -0
  35. package/lib/{es_table.component.loc.d.ts → components/es-table/es_table.component.loc.d.ts} +0 -0
  36. package/lib/{es_td.component.d.ts → components/es-td/es_td.component.d.ts} +0 -0
  37. package/lib/{es_th.component.d.ts → components/es-th/es_th.component.d.ts} +6 -0
  38. package/lib/{pager → components/pager}/table_pager.component.d.ts +8 -1
  39. package/lib/{pager → components/pager}/table_pager.component.loc.d.ts +0 -0
  40. package/lib/core/handlers/classes/ColumnMetadataHandler.d.ts +159 -0
  41. package/lib/core/handlers/classes/DynamicModeHandler.d.ts +32 -0
  42. package/lib/core/handlers/classes/ExportHandler.d.ts +22 -0
  43. package/lib/core/handlers/classes/HierarchyModeHandler.d.ts +40 -0
  44. package/lib/core/handlers/classes/ItemsHandler.d.ts +41 -0
  45. package/lib/core/handlers/classes/ReportModeHandler.d.ts +21 -0
  46. package/lib/core/handlers/classes/RowGroupingHandler.d.ts +114 -0
  47. package/lib/core/handlers/classes/SelectionHandler.d.ts +149 -0
  48. package/lib/core/handlers/classes/UtilitiesHandler.d.ts +67 -0
  49. package/lib/core/handlers/index.d.ts +9 -0
  50. package/lib/{models → domain/configuration}/EsTableDefaultable.d.ts +0 -0
  51. package/lib/{models → domain/configuration}/EsTableModuleConfig.d.ts +0 -0
  52. package/lib/domain/internals/classes/EsTableColumn.d.ts +2 -0
  53. package/lib/domain/internals/classes/ThElement.d.ts +13 -0
  54. package/lib/domain/internals/index.d.ts +1 -0
  55. package/lib/es-table.module.d.ts +1 -1
  56. package/lib/tokens.d.ts +1 -1
  57. package/package.json +1 -1
  58. package/public-api.d.ts +5 -5
  59. package/esm2015/lib/es_table.component.js +0 -3444
  60. package/esm2015/lib/es_table.component.loc.js +0 -35
  61. package/esm2015/lib/es_td.component.js +0 -106
  62. package/esm2015/lib/es_th.component.js +0 -150
  63. package/esm2015/lib/models/EsTableDefaultable.js +0 -4
  64. package/esm2015/lib/models/EsTableModuleConfig.js +0 -4
  65. package/esm2015/lib/pager/table_pager.component.js +0 -92
  66. package/esm2015/lib/pager/table_pager.component.loc.js +0 -22
  67. package/lib/es_table.component.d.ts +0 -1186
@@ -0,0 +1,667 @@
1
+ // Modelli
2
+ import { AppOrdering, EsTableColumn } from "../../../domain";
3
+ /** Classe che gestisce tutte le informaizoni relative alle colonne: visibilità, posizione, stato di pin/unpin, ecc ecc... */
4
+ export class ColumnMetadataHandler {
5
+ /** @ignore Costruttore*/
6
+ constructor(est, utilities, utiExts, prefService, rgH) {
7
+ this.est = est;
8
+ this.utilities = utilities;
9
+ this.utiExts = utiExts;
10
+ this.prefService = prefService;
11
+ this.rgH = rgH;
12
+ }
13
+ /**
14
+ * Metodo che gestisce il cambio di Ordinamento di una colonna
15
+ *
16
+ * @param {string} id ID della colonna il cui oridnamento è cambiato
17
+ * @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
18
+ */
19
+ handleTHOrderChange(id, order) {
20
+ let orders = this.est.viewMode ? this.est.View.orders : this.est.arrayOrders;
21
+ let orderToAdd = true;
22
+ let orderToRemove = null;
23
+ // Se per qualche motivo il costruttore non è passato (cache tarpate o simila) fixo
24
+ if (!orders && this.est.viewMode)
25
+ this.est.View.orders = [];
26
+ else if (!orders && this.est.arrayMode)
27
+ this.est.arrayOrders = [];
28
+ for (let i = 0; i < orders.length; i++) {
29
+ let t = orders[i];
30
+ if (t.id == id) {
31
+ if (order) {
32
+ t.order = order;
33
+ orderToAdd = false;
34
+ }
35
+ else
36
+ orderToRemove = i;
37
+ }
38
+ }
39
+ if (orderToRemove != null) {
40
+ orders.splice(orderToRemove, 1);
41
+ }
42
+ else if (orderToAdd) {
43
+ if (this.est.MultipleOrderingDirectives)
44
+ orders.push(new AppOrdering(id, order));
45
+ else {
46
+ if (this.est.viewMode)
47
+ this.est.View.orders = [new AppOrdering(id, order)];
48
+ else if (this.est.arrayMode)
49
+ this.est.arrayOrders = [new AppOrdering(id, order)];
50
+ }
51
+ }
52
+ this.est.onOrderChanged.emit({ id, order });
53
+ if (this.est.viewMode) {
54
+ if (this.est.groupSearchRequestsCache.length > 0)
55
+ this.rgH.emitRowGroupingSearches(id, orders);
56
+ else
57
+ this.est.emitSearchRequest(false);
58
+ }
59
+ else if (this.est.arrayMode)
60
+ this.est.internalWriteValue();
61
+ }
62
+ /**
63
+ * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
64
+ *
65
+ * Costo: 1 scan EsThs
66
+ *
67
+ * @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
68
+ */
69
+ reviewColumnsList(ths) {
70
+ this.est.TMPColumnsList = [];
71
+ if (ths.length == 0)
72
+ return;
73
+ // Appena il contentChildren è valorizzato scorro tutti gli header
74
+ for (let i = 0; i < ths.length; i++) {
75
+ let th = ths[i];
76
+ if (this.utilities.isEsTh(th)) {
77
+ // Se non ho un id il th è considerato inerte
78
+ if (!th.ID)
79
+ continue;
80
+ th.OrderBy = this.est.OrderByColumn;
81
+ // Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
82
+ // Di default la visibilità è quella impostata nel componente
83
+ if (this.est.HiddenColumns || th.Visible)
84
+ this.est.TMPColumnsList.push(new EsTableColumn(th.ID, th.Description, th.Visible, th.Fixed, null, null, null));
85
+ }
86
+ else {
87
+ let column = th.th;
88
+ // Se non ho un id il th è considerato inerte
89
+ if (!column)
90
+ continue;
91
+ // Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
92
+ // Di default la visibilità è quella impostata nel componente
93
+ if ((this.est.HiddenColumns || th.thVisible) && th.thIf) {
94
+ let previouslyPinned = !this.est.ColumnsList || this.est.ColumnsList.length == 0 ? null : this.est.ColumnsList.find(t => t.id == column) || null;
95
+ let toAdd = new EsTableColumn(column, null, th.thVisible, (th.thFixed || th.thGroup), previouslyPinned == null ? th.thPinned : previouslyPinned.pinned, th.thPinnedWidth, th.Template);
96
+ if (previouslyPinned)
97
+ toAdd.prev_index = previouslyPinned.prev_index;
98
+ this.est.TMPColumnsList.push(toAdd);
99
+ }
100
+ }
101
+ }
102
+ this.est.ColumnsList = [];
103
+ this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
104
+ }
105
+ /**
106
+ * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
107
+ */
108
+ moveFixedColumnsAtTheBeginning(ths, tds) {
109
+ let thsCache = {};
110
+ let fixeds = 0, pinneds = 0;
111
+ let columnsCache = {};
112
+ let columnsIndexCache = {};
113
+ // Creo la cache delle colonne
114
+ for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
115
+ let col = this.est.ColumnsList[coli];
116
+ columnsCache[col.id] = col;
117
+ }
118
+ // Sposto tutti gli header fixed o pinned all'inizio
119
+ for (let i = 0; i < ths.length; i++) {
120
+ let th = ths[i];
121
+ if (this.utilities.isEsTh(th)) {
122
+ thsCache[th.ID] = th;
123
+ if (th.Fixed) {
124
+ if (i != pinneds + fixeds)
125
+ this.utilities.arrayMove(ths, i, pinneds + fixeds);
126
+ fixeds++;
127
+ }
128
+ }
129
+ else {
130
+ thsCache[th.th] = th;
131
+ // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
132
+ th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
133
+ if (th.thPinned) {
134
+ if (i != pinneds)
135
+ this.utilities.arrayMove(ths, i, pinneds);
136
+ pinneds++;
137
+ }
138
+ //In questo caso sono informazioni statiche invece, non modificabili dall'utente, quindi non mi dò preoccupazioni
139
+ if (th.thFixed || th.thGroup) {
140
+ if (i != pinneds + fixeds)
141
+ this.utilities.arrayMove(ths, i, pinneds + fixeds);
142
+ fixeds++;
143
+ }
144
+ }
145
+ }
146
+ if (this.utilities.isEsTh(ths[0]) || this.utilities.isEsTd(tds[0]))
147
+ return;
148
+ // Cache degli indici per riposizionare i td come i th
149
+ for (let i = 0; i < ths.length; i++)
150
+ columnsIndexCache[ths[i].th] = i;
151
+ // Riordino le celle per fargli mantenere la stessa struttura dei th
152
+ let newTds = new Array(ths.length);
153
+ for (let i = 0; i < tds.length; i++) {
154
+ let item = tds[i];
155
+ newTds[columnsIndexCache[item.td]] = item;
156
+ }
157
+ this.est.HasPinnedColumns = pinneds > 0;
158
+ }
159
+ /** In base alla configurazione delle colonne calcola le dimenioni delle colonne pinnate */
160
+ evaluatePinnedColumnsWidth() {
161
+ if (!this.est.HasPinnedColumns)
162
+ return;
163
+ this.est.PinnedContainerWidth = 0;
164
+ for (let i = 0; i < this.est.ColumnsList.length; i++) {
165
+ let col = this.est.ColumnsList[i];
166
+ if (col.pinned && col.visible)
167
+ this.est.PinnedContainerWidth += col.pinnedWidth;
168
+ }
169
+ this.est.PinnedContainerWidth += this.est.Selection ? 25 : 0;
170
+ }
171
+ /**
172
+ * Terminato il binding delle colonne da **reviewColumnsList** e della **View** dal **writeValue** questo metodo si occupa
173
+ * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
174
+ *
175
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
176
+ */
177
+ alignColumnsIfLoadedView(view) {
178
+ let emitChanged = this.est.viewMode && view.savedstate;
179
+ let newColset = [];
180
+ if (!this.est.ColumnsList || this.est.ColumnsList.length == 0)
181
+ return;
182
+ let columns = this.est.viewMode ? view.columns : this.est.arrayColumns;
183
+ this.est.ColumnsList.forEach(c => {
184
+ // Se la colonna è pinnata mi arriva col simoleon, ma anche se è una composizione di più colonne
185
+ let exCl = columns.filter(cc => (cc.startsWith('§') ? cc.substring(1) : cc) == c.id);
186
+ // Se la colonna è pinnata aggiorno l'informazione nella view
187
+ if (exCl.length == 1)
188
+ c.pinned = exCl[0].startsWith('§');
189
+ // Se l'appsearch viene da uno stato precedente, uso le informazioni sulle colonne che ha dentro, altrimenti sovrascrivo tutto **
190
+ if (c.visible && columns.length == 0)
191
+ newColset.push(c.id);
192
+ // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
193
+ else if (exCl.length == 1 && !c.visible)
194
+ c.visible = true;
195
+ // Allineamento sull'AppSearch per casistiche inverse al di sopra
196
+ else if (exCl.length == 0 && c.visible)
197
+ c.visible = false;
198
+ });
199
+ // Non ho colonne nella appsearch, vuol dire che sono al primo binding
200
+ if (columns.length == 0) {
201
+ if (this.est.viewMode)
202
+ view.columns = newColset;
203
+ else
204
+ this.est.arrayColumns = newColset;
205
+ }
206
+ if ((this.est.viewMode && view.savedstate) && this.est.ColumnsOrdering && view.column_ordering.length > 0) {
207
+ // Scorro gli ordinamenti che avevo salvato e ricreo la ColumnsList in base a loro
208
+ let newColList = [];
209
+ view.column_ordering.forEach(co => {
210
+ this.est.ColumnsList.forEach(c => {
211
+ if (c.id == co)
212
+ newColList.push(c);
213
+ });
214
+ });
215
+ this.est.ColumnsList = newColList;
216
+ }
217
+ // In ogni caso questo non mi serve più, lo resetto **
218
+ if (this.est.viewMode)
219
+ view.savedstate = false;
220
+ if (emitChanged)
221
+ this.est.changed();
222
+ }
223
+ /**
224
+ * In base alla visibilità registrata nelle **ColumnsList** questo metodo si occupa di prendere tutti i **EsThs** ed **EsTds** relativi e nasonderli/mostrarli
225
+ *
226
+ * Costo: 1 scan ColumnsList, 1 scan EsThs, 1 scan EsTds
227
+ *
228
+ * @param {EsTh[] | EsThDirective[]} ths Header della tabella
229
+ * @param {EsTd[] | EsTdDirective[]} tds Celle della tabella
230
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
231
+ */
232
+ refreshColumnsVisibility(ths, tds, view) {
233
+ let newColset = [];
234
+ let fixedThs = {};
235
+ let columnsCache = {};
236
+ for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
237
+ let col = this.est.ColumnsList[coli];
238
+ columnsCache[col.id] = col;
239
+ if (col.visible)
240
+ newColset.push((col.pinned ? "§" : "") + col.id);
241
+ }
242
+ if (view)
243
+ view.columns = newColset;
244
+ else
245
+ this.est.arrayColumns = newColset;
246
+ // Da qui in poi devono essere eseguiti SOLO in fase di writeValue quindi devo assicurarmi di passarli null in tutti i passaggi diversi da quello
247
+ if (ths) {
248
+ // Definisco se la colonna è visibile in base alla sua rappresentazione locale in ColumnsList
249
+ for (let i = 0; i < ths.length; i++) {
250
+ let th = ths[i];
251
+ if (this.utilities.isEsTh(th)) {
252
+ th.Visible = th.Fixed || (columnsCache[th.ID] ? columnsCache[th.ID].visible : th.Visible);
253
+ if (th.Fixed)
254
+ fixedThs[th.ID] = true;
255
+ }
256
+ else {
257
+ th.thVisible = th.thFixed || (columnsCache[th.th] ? columnsCache[th.th].visible : th.thVisible);
258
+ if (th.thFixed || th.thGroup)
259
+ fixedThs[th.th] = true;
260
+ }
261
+ }
262
+ }
263
+ if (tds) {
264
+ // Definisco se la cella è visibile in base alla sua rappresentazione locale in ColumnsList
265
+ for (let i = 0; i < tds.length; i++) {
266
+ let td = tds[i];
267
+ if (this.utilities.isEsTd(td))
268
+ td.Visible = fixedThs[td.ID] || (columnsCache[td.ID] ? columnsCache[td.ID].visible : td.Visible);
269
+ else
270
+ td.tdVisible = fixedThs[td.td] || (columnsCache[td.td] ? columnsCache[td.td].visible : td.tdVisible);
271
+ }
272
+ }
273
+ this.est.changed();
274
+ }
275
+ /**
276
+ * Allinea gli ordinamenti dati fra le **EsThs** e le informazioni all'interno della View bindata
277
+ *
278
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
279
+ * @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
280
+ */
281
+ alignHeadersOrdering(ths, view) {
282
+ let orders = view ? view.orders : this.est.arrayOrders;
283
+ for (let i = 0; i < ths.length; i++) {
284
+ let th = ths[i];
285
+ if (this.utilities.isEsTh(th)) {
286
+ th.Order = null;
287
+ // Assegno tutti gli ordinamenti che mi vengono da AppSearch. Sono i più importanti. Non faccio cache o cose strano perché tanto questa
288
+ // variabile sarà sempre massimo 3 elementi
289
+ for (let i = 0; i < orders.length; i++) {
290
+ let or = orders[i];
291
+ if (or.id == th.ID)
292
+ th.Order = or.order;
293
+ }
294
+ }
295
+ else {
296
+ th.thOrder = null;
297
+ for (let i = 0; i < orders.length; i++) {
298
+ let or = orders[i];
299
+ if (or.id == th.th)
300
+ th.thOrder = or.order;
301
+ }
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Genera tutte le informazioni che servono per gestire il raggruppamento degli header
307
+ *
308
+ * @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
309
+ *
310
+ * @returns {{ leafs: EsTh[] | EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} Oggetto contenente la lista delle foglie (header base), il livello
311
+ * massimo di raggruppamento raggiunto, una cache in cui vengono indicati tutti i gruppi che sono "parent" (quindi che raggruppano almeno 1 header) e la cache degli header
312
+ */
313
+ evaluateHeadersGroupingInfos(ths) {
314
+ // Pregiro per trovare i parent
315
+ let parentsCache = {};
316
+ let thsCache = {};
317
+ for (let i = 0; i < ths.length; i++) {
318
+ let th = ths[i];
319
+ if (this.utilities.isEsTh(th))
320
+ continue;
321
+ thsCache[th.th] = th;
322
+ if (th.thParent && !parentsCache[th.thParent])
323
+ parentsCache[th.thParent] = true;
324
+ }
325
+ // Secondo giro per beccare il livello massimo e la lista di foglie (th senza parent)
326
+ let hMaxLevel = 0;
327
+ let leafs = [];
328
+ for (let i = 0; i < ths.length; i++) {
329
+ let th = ths[i];
330
+ if (this.utilities.isEsTh(th)) {
331
+ leafs.push(th);
332
+ continue;
333
+ }
334
+ // Se sono una foglia vedo quanti livelli ci sono sopra
335
+ if (!parentsCache[th.th]) {
336
+ leafs.push(th);
337
+ let tmp = this.jumpsToFinalParent(th, thsCache);
338
+ hMaxLevel = tmp > hMaxLevel ? tmp : hMaxLevel;
339
+ }
340
+ }
341
+ return { leafs: leafs, groupingLevel: hMaxLevel, parentsCache: parentsCache, thsCache: thsCache };
342
+ }
343
+ /**
344
+ * Genera gli header groups da una lista di info sui th all'interno della variabile **TMPRowThGroups**
345
+ *
346
+ * @param {{ leafs: EsTh[] | EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} infos Informazioni di raggruppamento valutate precedentemente
347
+ */
348
+ evaluateHeaderGroups(infos) {
349
+ if (infos.groupingLevel == 0)
350
+ return;
351
+ // Giro 2.5, creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate
352
+ let expandedGroups = [];
353
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
354
+ for (let l = 0; l < infos.groupingLevel; l++) {
355
+ expandedGroups.push([]);
356
+ for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
357
+ expandedGroups[l].push("");
358
+ }
359
+ // Ordino le foglie in base agli ordinamenti delle colonne
360
+ let orderedLeafs = [];
361
+ for (let i = 0; i < this.est.OrderDirectives.length; i++) {
362
+ let leaf = infos.thsCache[this.est.OrderDirectives[i]];
363
+ if (leaf.thVisible && !leaf.thPinned)
364
+ orderedLeafs.push(leaf);
365
+ }
366
+ // Terzo giro per creare l'array group con tutti i riferimenti del caso
367
+ let currentParent = "";
368
+ for (let i = 0; i < orderedLeafs.length; i++) {
369
+ let refTh = orderedLeafs[i];
370
+ let prevTh = i - 1 >= 0 ? orderedLeafs[i - 1] : null;
371
+ // Parent diverso da prima, metto il bordo a sinistra e a destra della cella precedente (se c'è)
372
+ // All'ultimo giro metto il bordo a destra. Tutto questo lo rieseguo per ogni cella in modo da ripulire eventuali a cui avevo assegnato tag precedentemente
373
+ refTh._lbord = refTh.thParent != currentParent;
374
+ refTh._rbord = visibleUnpinnedLeafs.length == i + 1;
375
+ if (prevTh)
376
+ prevTh._rbord = refTh.thParent != currentParent;
377
+ currentParent = refTh.thParent;
378
+ // Per ogni gruppo srotolo il parent nella matrice dei raggruppamenti
379
+ for (let l = 0; l < infos.groupingLevel; l++) {
380
+ let parent = refTh.thParent;
381
+ if (parent && !refTh.thPinned) {
382
+ expandedGroups[l][i] = parent;
383
+ refTh = infos.thsCache[parent];
384
+ }
385
+ }
386
+ }
387
+ // Quarto giro per compattarlo nell'elemento finale su cui bindarmi
388
+ currentParent = "";
389
+ let currentSpan = 0;
390
+ this.est.TMPRowThGroups = [];
391
+ for (let l = 0; l < expandedGroups.length; l++) {
392
+ let levelArray = [];
393
+ this.est.TMPRowThGroups.push(levelArray);
394
+ if (this.est.Selection || this.est.HasPinnedColumns)
395
+ levelArray.push({ Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
396
+ for (let h = 0; h < expandedGroups[l].length; h++) {
397
+ let item = expandedGroups[l][h];
398
+ if (item == currentParent)
399
+ currentSpan++;
400
+ else {
401
+ if (currentSpan > 0)
402
+ levelArray.push({ Span: currentSpan, Template: (currentParent ? infos.thsCache[currentParent].Template : null), Borders: !!currentParent });
403
+ currentSpan = 1;
404
+ currentParent = item;
405
+ }
406
+ }
407
+ // Ultima aggiunta che altrimenti mi rimarrebbe in cache
408
+ levelArray.push({ Span: currentSpan, Template: (currentParent ? infos.thsCache[currentParent].Template : null), Borders: !!currentParent });
409
+ if (this.est.Removal)
410
+ levelArray.push({ Span: 1, Template: null });
411
+ if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
412
+ levelArray.push({ Span: 1, Template: null });
413
+ currentSpan = 0;
414
+ currentParent = "";
415
+ }
416
+ }
417
+ /**
418
+ * Calcola il numero di salti da un header foglia all'ultimo parent della catena
419
+ *
420
+ * @param {EsThDirective} th Header da cui scorrere i padri per capire quanti livelli ci sono sopra
421
+ * @param {{ [index: string]: EsThDirective }} thsCache Cache degli header
422
+ */
423
+ jumpsToFinalParent(th, thsCache) {
424
+ let jumps = 0;
425
+ let parent = null;
426
+ do {
427
+ parent = th.thParent;
428
+ if (parent)
429
+ jumps++;
430
+ th = thsCache[parent];
431
+ } while (parent);
432
+ return jumps;
433
+ }
434
+ /**
435
+ * Metodo che genera l'ordine di default delle colonne
436
+ *
437
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
438
+ */
439
+ generateDefaultOrder(ths, view) {
440
+ if (ths.length == 0)
441
+ return;
442
+ let orderings = this.est.viewMode ? view.column_ordering : this.est.arrayColumnOrdering;
443
+ // Genero ordinamento di default da 0 fino a dove deve arrivare. Situazione attuale senza hotpotato
444
+ if (!orderings || orderings.length == 0) {
445
+ for (let i = 0; i < ths.length; i++) {
446
+ let th = ths[i];
447
+ let order = this.utilities.isEsTh(th) ? th.ID : th.th;
448
+ this.est.OrderDirectives.push(order);
449
+ }
450
+ }
451
+ else
452
+ this.est.OrderDirectives = orderings;
453
+ }
454
+ /**
455
+ * Applica l'ordine specificato alle varie colonne
456
+ *
457
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
458
+ * @param {boolean} finalize Se **true** significa che non mi aspetto di dover effettuare altre operazioni e posso renderizzare la situazione in base ai RowContext
459
+ * Senza finalize significa che mi aspetto altre operazioni che prima o poi richiameranno questa funzione col finalize.
460
+ *
461
+ * Ad esempio, una volta selezionato ordinamento fisico/logico delle colonne so che parte un altra ricerca che mi rivalorizzerà da "writeValue", che già chiama questa funzione.
462
+ * Mettendo solo la chiamata da "writeValue" come "finalizzante" mi assicuro che smanattamenti a frontend non causino flickering fino a quando non servono
463
+ */
464
+ applyOrdering(view, finalize) {
465
+ // Genero ordinamento per gli header
466
+ let newHeaders = [];
467
+ // Se devo finalizzare aggancio tutte le variabili di bind
468
+ if (finalize) {
469
+ this.est.OrderDirectives.forEach(o => {
470
+ let heaedrItem = this.est.TMPRowTHs.filter(t => t.ID == o)[0];
471
+ if (heaedrItem)
472
+ newHeaders.push(heaedrItem);
473
+ });
474
+ this.est.TMPRowTHs = newHeaders;
475
+ // Genero ordinamento per le celle
476
+ for (let i = 0; i < this.est.RowContexts.length; i++) {
477
+ let context = this.est.TMPRowTDs[this.est.RowContexts[i]];
478
+ let newContext = [];
479
+ this.est.OrderDirectives.forEach(o => {
480
+ let contextItem = context.filter(t => t.ID == o)[0];
481
+ newContext.push(contextItem);
482
+ });
483
+ this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
484
+ }
485
+ }
486
+ if (this.est.viewMode)
487
+ view.column_ordering = this.est.OrderDirectives;
488
+ else
489
+ this.est.arrayColumnOrdering = this.est.OrderDirectives;
490
+ this.est.changed();
491
+ }
492
+ /**
493
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata prima della colonna precedente
494
+ *
495
+ * @param {EsTableColumn} columnItem Colonna da spostare
496
+ */
497
+ sendUp(columnItem) {
498
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
499
+ if (this.est.TMPColumnsList[itemIndex - 1].fixed || this.est.TMPColumnsList[itemIndex - 1].pinned)
500
+ return;
501
+ this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex - 1);
502
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
503
+ let tmp = [];
504
+ this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
505
+ this.est.TMPColumnsList = tmp;
506
+ }
507
+ /**
508
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata dopo la colonna successiva
509
+ *
510
+ * @param {EsTableColumn} columnItem Colonna da spostare
511
+ */
512
+ sendDown(columnItem) {
513
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
514
+ this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex + 1);
515
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
516
+ let tmp = [];
517
+ this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
518
+ this.est.TMPColumnsList = tmp;
519
+ }
520
+ /**
521
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" pinna la colonna specificata
522
+ *
523
+ * @param {EsTableColumn} columnItem Colonna da spostare
524
+ */
525
+ pinOrUnpinColumn(columnItem) {
526
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
527
+ if (!columnItem.pinned) {
528
+ columnItem.prev_index = itemIndex;
529
+ //Quando pinno devo spostare l'elemento come ultima colonna pinnata o come prima colonna se non ce ne sono di pinnate
530
+ for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
531
+ if (!this.est.TMPColumnsList[i].pinned) {
532
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i);
533
+ break;
534
+ }
535
+ }
536
+ }
537
+ else {
538
+ //Quando spinno riporto l'elemento allo stesso indice in cui era prima (se sono stati fatti spostamenti nel mezzo cazzi dell'utente)
539
+ if (columnItem.prev_index != null && columnItem.prev_index != undefined)
540
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, columnItem.prev_index);
541
+ else {
542
+ // Se spinno senza un prev_index vuol dire che la colonna era pinnata da configurazione. La sposto nel primo punto disponibile
543
+ for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
544
+ if (!this.est.TMPColumnsList[i].pinned) {
545
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i - 1);
546
+ break;
547
+ }
548
+ }
549
+ }
550
+ }
551
+ columnItem.pinned = !columnItem.pinned;
552
+ }
553
+ /**
554
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" inverte le impostazioni di visibilità della colonna
555
+ *
556
+ * @param {EsTableColumn} columnItem Colonna da spostare
557
+ */
558
+ columnClicked(item) {
559
+ this.est.lastSelectedItemID = item.id;
560
+ if (!this.est.HiddenColumns || item.fixed)
561
+ return;
562
+ item.visible = !item.visible;
563
+ this.updateGlobalColVisCheck();
564
+ }
565
+ /** All'apertura della dialog "Ordinamento e Visibilità Colonne" ricarica le informazioni attuali per permettere la modifica */
566
+ resetColumnVisSelection() {
567
+ this.est.TMPColumnsList = [];
568
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
569
+ this.est.TMPColumnsList = [];
570
+ this.est.ColumnsList.forEach(c => { this.est.TMPColumnsList.push(Object.assign({}, c)); });
571
+ let reorderedColList = [];
572
+ if (this.est.ColumnsOrdering) {
573
+ this.est.OrderDirectives.forEach(o => {
574
+ let column = this.est.TMPColumnsList.filter(t => t.id == o)[0];
575
+ // Potrei non averne nel caso ci sia il flag HiddenColumns a false, evito di inserire degli undefined
576
+ if (column)
577
+ reorderedColList.push(column);
578
+ });
579
+ this.est.TMPColumnsList = reorderedColList;
580
+ }
581
+ this.updateGlobalColVisCheck();
582
+ }
583
+ /** Riaggiorna le **OrderDirectives** con le informazioni in **ColumnsList** */
584
+ refreshColumnOrdering() {
585
+ this.est.OrderDirectives = [];
586
+ for (let c = 0; c < this.est.ColumnsList.length; c++)
587
+ this.est.OrderDirectives.push(this.est.ColumnsList[c].id);
588
+ }
589
+ /** Effettua la selezione o meno del check globale (**globalColVisCheck**) di visibilità in base a se tutte le **TMPColumnsList** sono visibili o no */
590
+ updateGlobalColVisCheck() {
591
+ // TMPColList viene riempita di undefined nel caso in cui sia disattivata la selezione delle colonne nascoste
592
+ this.est.globalColVisCheck = this.est.TMPColumnsList.every(t => t.visible);
593
+ }
594
+ /**
595
+ * Funzione che effettua la conferma della visibilità e dell'ordine delle colonne.
596
+ *
597
+ * Questa selezione viene inoltre salvata nelle preferenze (**@esfaenza/preferences**), qualora l'Input **SavePreferences** fosse valorizzato
598
+ *
599
+ * @returns {boolean} **true** se non ci sono problemi, **false** altrimenti
600
+ */
601
+ confirmColumnVisibilitySelection() {
602
+ // Non permetto di non selezionare nulla
603
+ if (this.est.TMPColumnsList.every(t => !t.visible))
604
+ return false;
605
+ let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
606
+ this.est.ColumnsList = [];
607
+ this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
608
+ this.refreshColumnOrdering();
609
+ this.applyOrdering(castedView, false);
610
+ this.refreshColumnsVisibility(null, null, castedView);
611
+ //Salvo le preferences di questa view
612
+ //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
613
+ if (this.est.SavePreferences) {
614
+ if (!this.est.ngControl.name) {
615
+ console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
616
+ return false;
617
+ }
618
+ if (!this.prefService) {
619
+ console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
620
+ return false;
621
+ }
622
+ let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
623
+ let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
624
+ var toStore = { columns: JSON.parse(JSON.stringify(columns)), column_ordering: JSON.parse(JSON.stringify(columnsOrderings)) };
625
+ this.prefService.store(this.est.ngControl.name, toStore).subscribe();
626
+ }
627
+ // Rieseguo l'ultima ricerca bindata alla tabella
628
+ // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
629
+ if (this.est.viewMode)
630
+ setTimeout(() => {
631
+ if (this.est.MainGroupView) {
632
+ //this.emitSearchRequest(true, this.MainGroupView);
633
+ for (let i = 0; i < this.est.groupSearchRequestsCache.length; i++) {
634
+ let view = this.est.groupSearchRequestsCache[i].view;
635
+ view.columns = this.est.MainGroupView.columns;
636
+ view.column_ordering = this.est.MainGroupView.column_ordering;
637
+ this.est.emitSearchRequest(true, this.est.groupSearchRequestsCache[i].view);
638
+ }
639
+ }
640
+ else
641
+ this.est.emitSearchRequest(true);
642
+ });
643
+ else if (this.est.arrayMode)
644
+ setTimeout(() => { this.est.internalWriteValue(); });
645
+ // Lo vorrei mettere lato template ma no
646
+ this.est.lastSelectedItemID = null;
647
+ return true;
648
+ }
649
+ /**
650
+ * Effettuo l'unpinning di una colonna in maniera programmatica semplicemente eseguendo una per una le operazioni che verrebbero eseguite altrimenti
651
+ *
652
+ * @param {string} id Codice della colonna da spinnare
653
+ */
654
+ unpinColumn(id) {
655
+ this.resetColumnVisSelection();
656
+ this.pinOrUnpinColumn(this.est.TMPColumnsList.find(t => t.id == id));
657
+ this.confirmColumnVisibilitySelection();
658
+ }
659
+ /** Sul click nella checkbox di selezione globale si scorrono tutte le colonne e si impostano al valore della check globale */
660
+ globalColVisCheckChanged() {
661
+ this.est.TMPColumnsList.forEach(t => {
662
+ if (!t.fixed)
663
+ t.visible = this.est.globalColVisCheck;
664
+ });
665
+ }
666
+ }
667
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sdW1uTWV0YWRhdGFIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9jb3JlL2hhbmRsZXJzL2NsYXNzZXMvQ29sdW1uTWV0YWRhdGFIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWlCQSxVQUFVO0FBQ1YsT0FBTyxFQUFFLFdBQVcsRUFBYSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV4RSw2SEFBNkg7QUFDN0gsTUFBTSxPQUFPLHFCQUFxQjtJQUU5Qix5QkFBeUI7SUFDekIsWUFBb0IsR0FBcUIsRUFBVSxTQUEyQixFQUFVLE9BQXVCLEVBQVUsV0FBK0IsRUFBVSxHQUF1QjtRQUFySyxRQUFHLEdBQUgsR0FBRyxDQUFrQjtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQVUsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFBVSxnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFvQjtJQUFJLENBQUM7SUFFOUw7Ozs7O09BS0c7SUFDSSxtQkFBbUIsQ0FBQyxFQUFVLEVBQUUsS0FBcUI7UUFDeEQsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1FBQ2pHLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLGFBQWEsR0FBVyxJQUFJLENBQUM7UUFFakMsbUZBQW1GO1FBQ25GLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRO1lBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBdUIsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO2FBQzdDLElBQUksQ0FBQyxN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QUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztJQUM1QyxDQUFDO0lBRUQsOEhBQThIO0lBQ3ZILHdCQUF3QjtRQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDaEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUNSLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuZ3VsYXJcclxuaW1wb3J0IHsgVGVtcGxhdGVSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5cclxuLy8gTGlic1xyXG5pbXBvcnQgeyBVdGlsaXR5U2VydmljZSB9IGZyb20gXCJAZXNmYWVuemEvZXh0ZW5zaW9uc1wiO1xyXG5pbXBvcnQgeyBQcmVmZXJlbmNlc1NlcnZpY2UgfSBmcm9tIFwiQGVzZmFlbnphL3ByZWZlcmVuY2VzXCI7XHJcblxyXG4vLyBDb21wb25lbnRpIC8gRGlyZXR0aXZlXHJcbmltcG9ydCB7IEVzVGQgfSBmcm9tIFwiLi4vLi4vLi4vY29tcG9uZW50cy9lcy10ZC9lc190ZC5jb21wb25lbnRcIjtcclxuaW1wb3J0IHsgRXNUaCB9IGZyb20gXCIuLi8uLi8uLi9jb21wb25lbnRzL2VzLXRoL2VzX3RoLmNvbXBvbmVudFwiO1xyXG5pbXBvcnQgeyBFc1RhYmxlQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uLy4uL2NvbXBvbmVudHMvZXMtdGFibGUvZXNfdGFibGUuY29tcG9uZW50XCJcclxuaW1wb3J0IHsgRXNUZERpcmVjdGl2ZSB9IGZyb20gXCIuLi8uLi8uLi9kaXJlY3RpdmVzL2VzX3RkLmRpcmVjdGl2ZVwiO1xyXG5pbXBvcnQgeyBFc1RoRGlyZWN0aXZlIH0gZnJvbSBcIi4uLy4uLy4uL2RpcmVjdGl2ZXMvZXNfdGguZGlyZWN0aXZlXCI7XHJcblxyXG4vLyBIYW5kbGVyc1xyXG5pbXBvcnQgeyBVdGlsaXRpZXNIYW5kbGVyLCBSb3dHcm91cGluZ0hhbmRsZXIgfSBmcm9tIFwiLi5cIjtcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHsgQXBwT3JkZXJpbmcsIEFwcFNlYXJjaCwgRXNUYWJsZUNvbHVtbiB9IGZyb20gXCIuLi8uLi8uLi9kb21haW5cIjtcclxuXHJcbi8qKiBDbGFzc2UgY2hlIGdlc3Rpc2NlIHR1dHRlIGxlIGluZm9ybWFpem9uaSByZWxhdGl2ZSBhbGxlIGNvbG9ubmU6IHZpc2liaWxpdMOgLCBwb3NpemlvbmUsIHN0YXRvIGRpIHBpbi91bnBpbiwgZWNjIGVjYy4uLiAqL1xyXG5leHBvcnQgY2xhc3MgQ29sdW1uTWV0YWRhdGFIYW5kbGVyIHtcclxuXHJcbiAgICAvKiogQGlnbm9yZSBDb3N0cnV0dG9yZSovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVzdDogRXNUYWJsZUNvbXBvbmVudCwgcHJpdmF0ZSB1dGlsaXRpZXM6IFV0aWxpdGllc0hhbmRsZXIsIHByaXZhdGUgdXRpRXh0czogVXRpbGl0eVNlcnZpY2UsIHByaXZhdGUgcHJlZlNlcnZpY2U6IFByZWZlcmVuY2VzU2VydmljZSwgcHJpdmF0ZSByZ0g6IFJvd0dyb3VwaW5nSGFuZGxlcikgeyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlc3Rpc2NlIGlsIGNhbWJpbyBkaSBPcmRpbmFtZW50byBkaSB1bmEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBkZWxsYSBjb2xvbm5hIGlsIGN1aSBvcmlkbmFtZW50byDDqCBjYW1iaWF0b1xyXG4gICAgICogQHBhcmFtIHsnREVTQycgfCAnQVNDJ30gb3JkZXIgTnVvdm8gb3JkaW5lIHNlbGV6aW9uYXRvIHBlciBsYSBjb2xvbm5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYW5kbGVUSE9yZGVyQ2hhbmdlKGlkOiBzdHJpbmcsIG9yZGVyOiAnREVTQycgfCAnQVNDJykge1xyXG4gICAgICAgIGxldCBvcmRlcnMgPSB0aGlzLmVzdC52aWV3TW9kZSA/ICh0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5vcmRlcnMgOiB0aGlzLmVzdC5hcnJheU9yZGVycztcclxuICAgICAgICBsZXQgb3JkZXJUb0FkZCA9IHRydWU7XHJcbiAgICAgICAgbGV0IG9yZGVyVG9SZW1vdmU6IG51bWJlciA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIFNlIHBlciBxdWFsY2hlIG1vdGl2byBpbCBjb3N0cnV0dG9yZSBub24gw6ggcGFzc2F0byAoY2FjaGUgdGFycGF0ZSBvIHNpbWlsYSkgZml4b1xyXG4gICAgICAgIGlmICghb3JkZXJzICYmIHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAodGhpcy5lc3QuVmlldyBhcyBBcHBTZWFyY2g8YW55Pikub3JkZXJzID0gW107XHJcbiAgICAgICAgZWxzZSBpZiAoIW9yZGVycyAmJiB0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5T3JkZXJzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0ID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICBpZiAodC5pZCA9PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vcmRlciA9IG9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyVG9BZGQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclRvUmVtb3ZlID0gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9yZGVyVG9SZW1vdmUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBvcmRlcnMuc3BsaWNlKG9yZGVyVG9SZW1vdmUsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChvcmRlclRvQWRkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5NdWx0aXBsZU9yZGVyaW5nRGlyZWN0aXZlcylcclxuICAgICAgICAgICAgICAgIG9yZGVycy5wdXNoKG5ldyBBcHBPcmRlcmluZyhpZCwgb3JkZXIpKTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMuZXN0LlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLm9yZGVycyA9IFtuZXcgQXBwT3JkZXJpbmcoaWQsIG9yZGVyKV07XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuYXJyYXlPcmRlcnMgPSBbbmV3IEFwcE9yZGVyaW5nKGlkLCBvcmRlcildO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmVzdC5vbk9yZGVyQ2hhbmdlZC5lbWl0KHsgaWQsIG9yZGVyIH0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0Lmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZS5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZ0guZW1pdFJvd0dyb3VwaW5nU2VhcmNoZXMoaWQsIG9yZGVycyk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5lc3QuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5pbnRlcm5hbFdyaXRlVmFsdWUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUaHMqKiBlc3RyYXBwb2xvIGxhIGxpc3RhIGRpICoqRXNUYWJsZUNvbHVtbioqIGNoZSBxdWVzdGEgdGFiZWxsYSBkb3Zyw6AgZXZlbnR1YWxtZW50ZSBnZXN0aXJlIHBlciBWaXNpYmlsaXTDoCBlIE9yZGluZVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gRXNUaHNcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmV2aWV3Q29sdW1uc0xpc3QodGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQXBwZW5hIGlsIGNvbnRlbnRDaGlsZHJlbiDDqCB2YWxvcml6emF0byBzY29ycm8gdHV0dGkgZ2xpIGhlYWRlclxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnV0aWxpdGllcy5pc0VzVGgodGgpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZSBub24gaG8gdW4gaWQgaWwgdGggw6ggY29uc2lkZXJhdG8gaW5lcnRlXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoLklEKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoLk9yZGVyQnkgPSB0aGlzLmVzdC5PcmRlckJ5Q29sdW1uO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNhbHZvIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciBwZXIgZmFyIHBhcnRlIGRlbGxhIGxpc3RhIGRhIGN1aSBzY2VnbGllcmUgcXVhbGkgY29sb25uZSB2aXN1YWxpenphcmUvbmFzY29uZGVyZVxyXG4gICAgICAgICAgICAgICAgLy8gRGkgZGVmYXVsdCBsYSB2aXNpYmlsaXTDoCDDqCBxdWVsbGEgaW1wb3N0YXRhIG5lbCBjb21wb25lbnRlXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lc3QuSGlkZGVuQ29sdW1ucyB8fCB0aC5WaXNpYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LnB1c2gobmV3IEVzVGFibGVDb2x1bW4odGguSUQsIHRoLkRlc2NyaXB0aW9uLCB0aC5WaXNpYmxlLCB0aC5GaXhlZCwgbnVsbCwgbnVsbCwgbnVsbCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbiA9IHRoLnRoO1xyXG4gICAgICAgICAgICAgICAgLy8gU2Ugbm9uIGhvIHVuIGlkIGlsIHRoIMOoIGNvbnNpZGVyYXRvIGluZXJ0ZVxyXG4gICAgICAgICAgICAgICAgaWYgKCFjb2x1bW4pXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2Fsdm8gbGUgaW5mb3JtYXppb25pIGRlbGwnaGVhZGVyIHBlciBmYXIgcGFydGUgZGVsbGEgbGlzdGEgZGEgY3VpIHNjZWdsaWVyZSBxdWFsaSBjb2xvbm5lIHZpc3VhbGl6emFyZS9uYXNjb25kZXJlXHJcbiAgICAgICAgICAgICAgICAvLyBEaSBkZWZhdWx0IGxhIHZpc2liaWxpdMOgIMOoIHF1ZWxsYSBpbXBvc3RhdGEgbmVsIGNvbXBvbmVudGVcclxuICAgICAgICAgICAgICAgIGlmICgodGhpcy5lc3QuSGlkZGVuQ29sdW1ucyB8fCB0aC50aFZpc2libGUpICYmIHRoLnRoSWYpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcHJldmlvdXNseVBpbm5lZCA9ICF0aGlzLmVzdC5Db2x1bW5zTGlzdCB8fCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGggPT0gMCA/IG51bGwgOiB0aGlzLmVzdC5Db2x1bW5zTGlzdC5maW5kKHQgPT4gdC5pZCA9PSBjb2x1bW4pIHx8IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvQWRkID0gbmV3IEVzVGFibGVDb2x1bW4oY29sdW1uLCBudWxsLCB0aC50aFZpc2libGUsICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApLCBwcmV2aW91c2x5UGlubmVkID09IG51bGwgPyB0aC50aFBpbm5lZCA6IHByZXZpb3VzbHlQaW5uZWQucGlubmVkLCB0aC50aFBpbm5lZFdpZHRoLCB0aC5UZW1wbGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzbHlQaW5uZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvQWRkLnByZXZfaW5kZXggPSBwcmV2aW91c2x5UGlubmVkLnByZXZfaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QucHVzaCh0b0FkZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0aGlzLmVzdC5Db2x1bW5zTGlzdC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVuZGUgaSB0aCBlIGkgdGQgaW4gbW9kYWxpdMOgIGRpcmV0aXZlIGUgbGkgb3JkaW5hIGluIGJhc2UgYSBzZSBjaSBzb25vIGNvbG9ubmUgZml4ZWQgbyBtZW5vXHJcbiAgICAgKi9cclxuICAgICBwdWJsaWMgbW92ZUZpeGVkQ29sdW1uc0F0VGhlQmVnaW5uaW5nKHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGRbXSB8IEVzVGREaXJlY3RpdmVbXSkge1xyXG5cclxuICAgICAgICBsZXQgdGhzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBhbnk7IH0gPSB7fTtcclxuICAgICAgICBsZXQgZml4ZWRzID0gMCwgcGlubmVkcyA9IDA7XHJcbiAgICAgICAgbGV0IGNvbHVtbnNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGFibGVDb2x1bW47IH0gPSB7fTtcclxuICAgICAgICBsZXQgY29sdW1uc0luZGV4Q2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBudW1iZXI7IH0gPSB7fTtcclxuXHJcbiAgICAgICAgLy8gQ3JlbyBsYSBjYWNoZSBkZWxsZSBjb2xvbm5lXHJcbiAgICAgICAgZm9yIChsZXQgY29saSA9IDA7IGNvbGkgPCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU3Bvc3RvIHR1dHRpIGdsaSBoZWFkZXIgZml4ZWQgbyBwaW5uZWQgYWxsJ2luaXppb1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgaWYgKHRoaXMudXRpbGl0aWVzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRoc0NhY2hlW3RoLklEXSA9IHRoO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoLkZpeGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gcGlubmVkcyArIGZpeGVkcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXMuYXJyYXlNb3ZlKHRocywgaSwgcGlubmVkcyArIGZpeGVkcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZml4ZWRzKys7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhzQ2FjaGVbdGgudGhdID0gdGg7XHJcbiAgICAgICAgICAgICAgICAvLyBSaWFzc2Vnbm8gc2VtcHJlIHBlciByaXB1bGlyZSB2YWxvcmkgZGkgcGFydGVuemEgbyBwZXIgYWdnaW9ybmFybGkgaW4gY2FzbyBkaSBtb2RpZmljaGUgdXRlbnRlXHJcbiAgICAgICAgICAgICAgICB0aC50aFBpbm5lZCA9ICghY29sdW1uc0NhY2hlW3RoLnRoXSAmJiB0aC50aFBpbm5lZCkgfHwgKGNvbHVtbnNDYWNoZVt0aC50aF0gJiYgY29sdW1uc0NhY2hlW3RoLnRoXS5waW5uZWQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoLnRoUGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gcGlubmVkcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXMuYXJyYXlNb3ZlKHRocywgaSwgcGlubmVkcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcGlubmVkcysrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vSW4gcXVlc3RvIGNhc28gc29ubyBpbmZvcm1hemlvbmkgc3RhdGljaGUgaW52ZWNlLCBub24gbW9kaWZpY2FiaWxpIGRhbGwndXRlbnRlLCBxdWluZGkgbm9uIG1pIGTDsiBwcmVvY2N1cGF6aW9uaVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHBpbm5lZHMgKyBmaXhlZHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aHMsIGksIHBpbm5lZHMgKyBmaXhlZHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZpeGVkcysrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy51dGlsaXRpZXMuaXNFc1RoKHRoc1swXSkgfHwgdGhpcy51dGlsaXRpZXMuaXNFc1RkKHRkc1swXSkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQ2FjaGUgZGVnbGkgaW5kaWNpIHBlciByaXBvc2l6aW9uYXJlIGkgdGQgY29tZSBpIHRoXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGNvbHVtbnNJbmRleENhY2hlWyg8RXNUaERpcmVjdGl2ZT50aHNbaV0pLnRoXSA9IGk7XHJcblxyXG4gICAgICAgIC8vIFJpb3JkaW5vIGxlIGNlbGxlIHBlciBmYXJnbGkgbWFudGVuZXJlIGxhIHN0ZXNzYSBzdHJ1dHR1cmEgZGVpIHRoXHJcbiAgICAgICAgbGV0IG5ld1RkcyA9IG5ldyBBcnJheSh0aHMubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0ZHNbaV0gYXMgRXNUZERpcmVjdGl2ZTtcclxuICAgICAgICAgICAgbmV3VGRzW2NvbHVtbnNJbmRleENhY2hlW2l0ZW0udGRdXSA9IGl0ZW07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmVzdC5IYXNQaW5uZWRDb2x1bW5zID0gcGlubmVkcyA+IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEluIGJhc2UgYWxsYSBjb25maWd1cmF6aW9uZSBkZWxsZSBjb2xvbm5lIGNhbGNvbGEgbGUgZGltZW5pb25pIGRlbGxlIGNvbG9ubmUgcGlubmF0ZSAqL1xyXG4gICAgcHVibGljIGV2YWx1YXRlUGlubmVkQ29sdW1uc1dpZHRoKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5lc3QuSGFzUGlubmVkQ29sdW1ucylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLmVzdC5QaW5uZWRDb250YWluZXJXaWR0aCA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbaV07XHJcbiAgICAgICAgICAgIGlmIChjb2wucGlubmVkICYmIGNvbC52aXNpYmxlKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuUGlubmVkQ29udGFpbmVyV2lkdGggKz0gY29sLnBpbm5lZFdpZHRoO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmVzdC5QaW5uZWRDb250YWluZXJXaWR0aCArPSB0aGlzLmVzdC5TZWxlY3Rpb24gPyAyNSA6IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXJtaW5hdG8gaWwgYmluZGluZyBkZWxsZSBjb2xvbm5lIGRhICoqcmV2aWV3Q29sdW1uc0xpc3QqKiBlIGRlbGxhICoqVmlldyoqIGRhbCAqKndyaXRlVmFsdWUqKiBxdWVzdG8gbWV0b2RvIHNpIG9jY3VwYVxyXG4gICAgICogZGVsbCdhbGxpbmVhbWVudG8gZGVsbGUgaW5mb3JtYXppb25pIGZyYSBsZSBjb2xvbm5lIGNhbGNvbGF0ZSBpbnRlcm5hbWVudGUgZSBsZSBpbmZvcm1hemlvbmkgc3VsbGUgY29sb25uZSBjaGUgYXJyaXZhbm8gZGFsbCdBcHBTZWFyY2hcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICAgcHVibGljIGFsaWduQ29sdW1uc0lmTG9hZGVkVmlldyh2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBlbWl0Q2hhbmdlZCA9IHRoaXMuZXN0LnZpZXdNb2RlICYmIHZpZXcuc2F2ZWRzdGF0ZTtcclxuICAgICAgICBsZXQgbmV3Q29sc2V0ID0gW107XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5lc3QuQ29sdW1uc0xpc3QgfHwgdGhpcy5lc3QuQ29sdW1uc0xpc3QubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSB0aGlzLmVzdC52aWV3TW9kZSA/IHZpZXcuY29sdW1ucyA6IHRoaXMuZXN0LmFycmF5Q29sdW1ucztcclxuICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICAvLyBTZSBsYSBjb2xvbm5hIMOoIHBpbm5hdGEgbWkgYXJyaXZhIGNvbCBzaW1vbGVvbiwgbWEgYW5jaGUgc2Ugw6ggdW5hIGNvbXBvc2l6aW9uZSBkaSBwacO5IGNvbG9ubmVcclxuICAgICAgICAgICAgbGV0IGV4Q2wgPSBjb2x1bW5zLmZpbHRlcihjYyA9PiAoY2Muc3RhcnRzV2l0aCgnwqcnKSA/IGNjLnN1YnN0cmluZygxKSA6IGNjKSA9PSBjLmlkKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGxhIGNvbG9ubmEgw6ggcGlubmF0YSBhZ2dpb3JubyBsJ2luZm9ybWF6aW9uZSBuZWxsYSB2aWV3XHJcbiAgICAgICAgICAgIGlmIChleENsLmxlbmd0aCA9PSAxKVxyXG4gICAgICAgICAgICAgICAgYy5waW5uZWQgPSBleENsWzBdLnN0YXJ0c1dpdGgoJ8KnJyk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsJ2FwcHNlYXJjaCB2aWVuZSBkYSB1bm8gc3RhdG8gcHJlY2VkZW50ZSwgdXNvIGxlIGluZm9ybWF6aW9uaSBzdWxsZSBjb2xvbm5lIGNoZSBoYSBkZW50cm8sIGFsdHJpbWVudGkgc292cmFzY3Jpdm8gdHV0dG8gICoqXHJcbiAgICAgICAgICAgIGlmIChjLnZpc2libGUgJiYgY29sdW1ucy5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgICAgIG5ld0NvbHNldC5wdXNoKGMuaWQpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgaG8gdW5hIGNvbG9ubmEgbGF0byBBcHBTZWFyY2ggZSBuZWxsYSBDb2x1bW5MaXN0IG5vbiDDqCB2aXNpYmlsZSwgYWxsaW5lbyBhbGwnQXBwU2VhcmNoXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV4Q2wubGVuZ3RoID09IDEgJiYgIWMudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIGMudmlzaWJsZSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAvLyBBbGxpbmVhbWVudG8gc3VsbCdBcHBTZWFyY2ggcGVyIGNhc2lzdGljaGUgaW52ZXJzZSBhbCBkaSBzb3ByYVxyXG4gICAgICAgICAgICBlbHNlIGlmIChleENsLmxlbmd0aCA9PSAwICYmIGMudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIGMudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBOb24gaG8gY29sb25uZSBuZWxsYSBhcHBzZWFyY2gsIHZ1b2wgZGlyZSBjaGUgc29ubyBhbCBwcmltbyBiaW5kaW5nXHJcbiAgICAgICAgaWYgKGNvbHVtbnMubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAgICAgdmlldy5jb2x1bW5zID0gbmV3Q29sc2V0O1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5hcnJheUNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoKHRoaXMuZXN0LnZpZXdNb2RlICYmIHZpZXcuc2F2ZWRzdGF0ZSkgJiYgdGhpcy5lc3QuQ29sdW1uc09yZGVyaW5nICYmIHZpZXcuY29sdW1uX29yZGVyaW5nLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLy8gU2NvcnJvIGdsaSBvcmRpbmFtZW50aSBjaGUgYXZldm8gc2FsdmF0byBlIHJpY3JlbyBsYSBDb2x1bW5zTGlzdCBpbiBiYXNlIGEgbG9yb1xyXG4gICAgICAgICAgICBsZXQgbmV3Q29sTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbl9vcmRlcmluZy5mb3JFYWNoKGNvID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LkNvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMuaWQgPT0gY28pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NvbExpc3QucHVzaChjKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QgPSBuZXdDb2xMaXN0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSW4gb2duaSBjYXNvIHF1ZXN0byBub24gbWkgc2VydmUgcGnDuSwgbG8gcmVzZXR0byAgKipcclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgIHZpZXcuc2F2ZWRzdGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAoZW1pdENoYW5nZWQpXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmNoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluIGJhc2UgYWxsYSB2aXNpYmlsaXTDoCByZWdpc3RyYXRhIG5lbGxlICoqQ29sdW1uc0xpc3QqKiBxdWVzdG8gbWV0b2RvIHNpIG9jY3VwYSBkaSBwcmVuZGVyZSB0dXR0aSBpICoqRXNUaHMqKiBlZCAqKkVzVGRzKiogcmVsYXRpdmkgZSBuYXNvbmRlcmxpL21vc3RyYXJsaVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gQ29sdW1uc0xpc3QsIDEgc2NhbiBFc1RocywgMSBzY2FuIEVzVGRzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBIZWFkZXIgZGVsbGEgdGFiZWxsYVxyXG4gICAgICogQHBhcmFtIHtFc1RkW10gfCBFc1RkRGlyZWN0aXZlW119IHRkcyBDZWxsZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGRbXSB8IEVzVGREaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBsZXQgbmV3Q29sc2V0ID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkVGhzOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbjsgfSA9IHt9O1xyXG4gICAgICAgIGxldCBjb2x1bW5zQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uOyB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgY29saSA9IDA7IGNvbGkgPCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG4gICAgICAgICAgICBpZiAoY29sLnZpc2libGUpXHJcbiAgICAgICAgICAgICAgICBuZXdDb2xzZXQucHVzaCgoY29sLnBpbm5lZCA/IFwiwqdcIiA6IFwiXCIpICsgY29sLmlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZpZXcpXHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1ucyA9IG5ld0NvbHNldDtcclxuXHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5hcnJheUNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcblxyXG4gICAgICAgIC8vIERhIHF1aSBpbiBwb2kgZGV2b25vIGVzc2VyZSBlc2VndWl0aSBTT0xPIGluIGZhc2UgZGkgd3JpdGVWYWx1ZSBxdWluZGkgZGV2byBhc3NpY3VyYXJtaSBkaSBwYXNzYXJsaSBudWxsIGluIHR1dHRpIGkgcGFzc2FnZ2kgZGl2ZXJzaSBkYSBxdWVsbG9cclxuICAgICAgICBpZiAodGhzKSB7XHJcbiAgICAgICAgICAgIC8vIERlZmluaXNjbyBzZSBsYSBjb2xvbm5hIMOoIHZpc2liaWxlIGluIGJhc2UgYWxsYSBzdWEgcmFwcHJlc2VudGF6aW9uZSBsb2NhbGUgaW4gQ29sdW1uc0xpc3RcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51dGlsaXRpZXMuaXNFc1RoKHRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoLlZpc2libGUgPSB0aC5GaXhlZCB8fCAoY29sdW1uc0NhY2hlW3RoLklEXSA/IGNvbHVtbnNDYWNoZVt0aC5JRF0udmlzaWJsZSA6IHRoLlZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aC5GaXhlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZml4ZWRUaHNbdGguSURdID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoLnRoVmlzaWJsZSA9IHRoLnRoRml4ZWQgfHwgKGNvbHVtbnNDYWNoZVt0aC50aF0gPyBjb2x1bW5zQ2FjaGVbdGgudGhdLnZpc2libGUgOiB0aC50aFZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpeGVkVGhzW3RoLnRoXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0ZHMpIHtcclxuICAgICAgICAgICAgLy8gRGVmaW5pc2NvIHNlIGxhIGNlbGxhIMOoIHZpc2liaWxlIGluIGJhc2UgYWxsYSBzdWEgcmFwcHJlc2VudGF6aW9uZSBsb2NhbGUgaW4gQ29sdW1uc0xpc3RcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0ZCA9IHRkc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51dGlsaXRpZXMuaXNFc1RkKHRkKSlcclxuICAgICAgICAgICAgICAgICAgICB0ZC5WaXNpYmxlID0gZml4ZWRUaHNbdGQuSURdIHx8IChjb2x1bW5zQ2FjaGVbdGQuSURdID8gY29sdW1uc0NhY2hlW3RkLklEXS52aXNpYmxlIDogdGQuVmlzaWJsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRkLnRkVmlzaWJsZSA9IGZpeGVkVGhzW3RkLnRkXSB8fCAoY29sdW1uc0NhY2hlW3RkLnRkXSA/IGNvbHVtbnNDYWNoZVt0ZC50ZF0udmlzaWJsZSA6IHRkLnRkVmlzaWJsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZXN0LmNoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbGluZWEgZ2xpIG9yZGluYW1lbnRpIGRhdGkgZnJhIGxlICoqRXNUaHMqKiBlIGxlIGluZm9ybWF6aW9uaSBhbGwnaW50ZXJubyBkZWxsYSBWaWV3IGJpbmRhdGFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgIHB1YmxpYyBhbGlnbkhlYWRlcnNPcmRlcmluZyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBsZXQgb3JkZXJzID0gdmlldyA/IHZpZXcub3JkZXJzIDogdGhpcy5lc3QuYXJyYXlPcmRlcnM7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMudXRpbGl0aWVzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRoLk9yZGVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBc3NlZ25vIHR1dHRpIGdsaSBvcmRpbmFtZW50aSBjaGUgbWkgdmVuZ29ubyBkYSBBcHBTZWFyY2guIFNvbm8gaSBwacO5IGltcG9ydGFudGkuIE5vbiBmYWNjaW8gY2FjaGUgbyBjb3NlIHN0cmFubyBwZXJjaMOpIHRhbnRvIHF1ZXN0YVxyXG4gICAgICAgICAgICAgICAgLy8gdmFyaWFiaWxlIHNhcsOgIHNlbXByZSBtYXNzaW1vIDMgZWxlbWVudGlcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9yID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvci5pZCA9PSB0aC5JRClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGguT3JkZXIgPSBvci5vcmRlcjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoLnRoT3JkZXIgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgb3IgPSBvcmRlcnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yLmlkID09IHRoLnRoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aC50aE9yZGVyID0gb3Iub3JkZXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZW5lcmEgdHV0dGUgbGUgaW5mb3JtYXppb25pIGNoZSBzZXJ2b25vIHBlciBnZXN0aXJlIGlsIHJhZ2dydXBwYW1lbnRvIGRlZ2xpIGhlYWRlclxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3sgbGVhZnM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgZ3JvdXBpbmdMZXZlbDogbnVtYmVyLCBwYXJlbnRzQ2FjaGU6IGFueSwgdGhzQ2FjaGU6IGFueSB9fSBPZ2dldHRvIGNvbnRlbmVudGUgbGEgbGlzdGEgZGVsbGUgZm9nbGllIChoZWFkZXIgYmFzZSksIGlsIGxpdmVsbG9cclxuICAgICAqIG1hc3NpbW8gZGkgcmFnZ3J1cHBhbWVudG8gcmFnZ2l1bnRvLCB1bmEgY2FjaGUgaW4gY3VpIHZlbmdvbm8gaW5kaWNhdGkgdHV0dGkgaSBncnVwcGkgY2hlIHNvbm8gXCJwYXJlbnRcIiAocXVpbmRpIGNoZSByYWdncnVwcGFubyBhbG1lbm8gMSBoZWFkZXIpIGUgbGEgY2FjaGUgZGVnbGkgaGVhZGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBldmFsdWF0ZUhlYWRlcnNHcm91cGluZ0luZm9zKHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdKTogeyBsZWFmczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdOyBncm91cGluZ0xldmVsOiBudW1iZXI7IHBhcmVudHNDYWNoZTogYW55OyB0aHNDYWNoZTogYW55OyB9IHtcclxuICAgICAgICAvLyBQcmVnaXJvIHBlciB0cm92YXJlIGkgcGFyZW50XHJcbiAgICAgICAgbGV0IHBhcmVudHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IGJvb2xlYW47IH0gPSB7fTtcclxuICAgICAgICBsZXQgdGhzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RoRGlyZWN0aXZlOyB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBpZiAodGhpcy51dGlsaXRpZXMuaXNFc1RoKHRoKSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgdGhzQ2FjaGVbdGgudGhdID0gdGg7XHJcbiAgICAgICAgICAgIGlmICh0aC50aFBhcmVudCAmJiAhcGFyZW50c0NhY2hlW3RoLnRoUGFyZW50XSlcclxuICAgICAgICAgICAgICAgIHBhcmVudHNDYWNoZVt0aC50aFBhcmVudF0gPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2Vjb25kbyBnaXJvIHBlciBiZWNjYXJlIGlsIGxpdmVsbG8gbWFzc2ltbyBlIGxhIGxpc3RhIGRpIGZvZ2xpZSAodGggc2VuemEgcGFyZW50KVxyXG4gICAgICAgIGxldCBoTWF4TGV2ZWwgPSAwO1xyXG4gICAgICAgIGxldCBsZWFmczogYW55W10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnV0aWxpdGllcy5pc0VzVGgodGgpKSB7IGxlYWZzLnB1c2godGgpOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAvLyBTZSBzb25vIHVuYSBmb2dsaWEgdmVkbyBxdWFudGkgbGl2ZWxsaSBjaSBzb25vIHNvcHJhXHJcbiAgICAgICAgICAgIGlmICghcGFyZW50c0NhY2hlW3RoLnRoXSkge1xyXG4gICAgICAgICAgICAgICAgbGVhZnMucHVzaCh0aCk7XHJcbiAgICAgICAgICAgICAgICBsZXQgdG1wID0gdGhpcy5qdW1wc1RvRmluYWxQYXJlbnQodGgsIHRoc0NhY2hlKTtcclxuICAgICAgICAgICAgICAgIGhNYXhMZXZlbCA9IHRtcCA+IGhNYXhMZXZlbCA/IHRtcCA6IGhNYXhMZXZlbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgbGVhZnM6IGxlYWZzLCBncm91cGluZ0xldmVsOiBoTWF4TGV2ZWwsIHBhcmVudHNDYWNoZTogcGFyZW50c0NhY2hlLCB0aHNDYWNoZTogdGhzQ2FjaGUgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYSBnbGkgaGVhZGVyIGdyb3VwcyBkYSB1bmEgbGlzdGEgZGkgaW5mbyBzdWkgdGggYWxsJ2ludGVybm8gZGVsbGEgdmFyaWFiaWxlICoqVE1QUm93VGhHcm91cHMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7eyBsZWFmczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdLCBncm91cGluZ0xldmVsOiBudW1iZXIsIHBhcmVudHNDYWNoZTogYW55LCB0aHNDYWNoZTogYW55IH19IGluZm9zIEluZm9ybWF6aW9uaSBkaSByYWdncnVwcGFtZW50byB2YWx1dGF0ZSBwcmVjZWRlbnRlbWVudGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGV2YWx1YXRlSGVhZGVyR3JvdXBzKGluZm9zOiB7IGxlYWZzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW107IGdyb3VwaW5nTGV2ZWw6IG51bWJlcjsgcGFyZW50c0NhY2hlOiBhbnk7IHRoc0NhY2hlOiBhbnk7IH0pIHtcclxuICAgICAgICBpZiAoaW5mb3MuZ3JvdXBpbmdMZXZlbCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIEdpcm8gMi41LCBjcmVvIGwnb3V0cHV0IGRlaSByYWdncnVwcGFtZW50aSBwZXIgaGVhZGVyIGluIG1vZG8gZGEgbm9uIGRvdmVybWkgcHJlb2NjdXBhcmUgZGkgY2VsbGUgbm9uIGluaXppYWxpenphdGVcclxuICAgICAgICBsZXQgZXhwYW5kZWRHcm91cHMgPSBbXTtcclxuICAgICAgICBsZXQgdmlzaWJsZVVucGlubmVkTGVhZnM6IEVzVGhEaXJlY3RpdmVbXSA9ICg8YW55W10+aW5mb3MubGVhZnMpLmZpbHRlcigodDogRXNUaERpcmVjdGl2ZSkgPT4gdC50aFZpc2libGUgJiYgIXQudGhQaW5uZWQpO1xyXG4gICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgaW5mb3MuZ3JvdXBpbmdMZXZlbDsgbCsrKSB7XHJcbiAgICAgICAgICAgIGV4cGFuZGVkR3JvdXBzLnB1c2goW10pO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZpc2libGVVbnBpbm5lZExlYWZzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgZXhwYW5kZWRHcm91cHNbbF0ucHVzaChcIlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE9yZGlubyBsZSBmb2dsaWUgaW4gYmFzZSBhZ2xpIG9yZGluYW1lbnRpIGRlbGxlIGNvbG9ubmVcclxuICAgICAgICBsZXQgb3JkZXJlZExlYWZzID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGxlYWY6IEVzVGhEaXJlY3RpdmUgPSBpbmZvcy50aHNDYWNoZVt0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXNbaV1dO1xyXG4gICAgICAgICAgICBpZiAobGVhZi50aFZpc2libGUgJiYgIWxlYWYudGhQaW5uZWQpXHJcbiAgICAgICAgICAgICAgICBvcmRlcmVkTGVhZnMucHVzaChsZWFmKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFRlcnpvIGdpcm8gcGVyIGNyZWFyZSBsJ2FycmF5IGdyb3VwIGNvbiB0dXR0aSBpIHJpZmVyaW1lbnRpIGRlbCBjYXNvXHJcbiAgICAgICAgbGV0IGN1cnJlbnRQYXJlbnQgPSBcIlwiO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJlZExlYWZzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCByZWZUaDogRXNUaERpcmVjdGl2ZSA9IG9yZGVyZWRMZWFmc1tpXTtcclxuICAgICAgICAgICAgbGV0IHByZXZUaDogRXNUaERpcmVjdGl2ZSA9IGkgLSAxID49IDAgPyBvcmRlcmVkTGVhZnNbaSAtIDFdIDogbnVsbDtcclxuXHJcbiAgICAgICAgICAgIC8vIFBhcmVudCBkaXZlcnNvIGRhIHByaW1hLCBtZXR0byBpbCBib3JkbyBhIHNpbmlzdHJhIGUgYSBkZXN0cmEgZGVsbGEgY2VsbGEgcHJlY2VkZW50ZSAoc2UgYyfDqClcclxuICAgICAgICAgICAgLy8gQWxsJ3VsdGltbyBnaXJvIG1ldHRvIGlsIGJvcmRvIGEgZGVzdHJhLiBUdXR0byBxdWVzdG8gbG8gcmllc2VndW8gcGVyIG9nbmkgY2VsbGEgaW4gbW9kbyBkYSByaXB1bGlyZSBldmVudHVhbGkgYSBjdWkgYXZldm8gYXNzZWduYXRvIHRhZyBwcmVjZWRlbnRlbWVudGVcclxuICAgICAgICAgICAgKDxhbnk+cmVmVGgpLl9sYm9yZCA9IHJlZlRoLnRoUGFyZW50ICE9IGN1cnJlbnRQYXJlbnQ7XHJcbiAgICAgICAgICAgICg8YW55PnJlZlRoKS5fcmJvcmQgPSB2aXNpYmxlVW5waW5uZWRMZWFmcy5sZW5ndGggPT0gaSArIDE7XHJcbiAgICAgICAgICAgIGlmIChwcmV2VGgpXHJcbiAgICAgICAgICAgICAgICAoPGFueT5wcmV2VGgpLl9yYm9yZCA9IHJlZlRoLnRoUGFyZW50ICE9IGN1cnJlbnRQYXJlbnQ7XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gcmVmVGgudGhQYXJlbnQ7XHJcblxyXG4gICAgICAgICAgICAvLyBQZXIgb2duaSBncnVwcG8gc3JvdG9sbyBpbCBwYXJlbnQgbmVsbGEgbWF0cmljZSBkZWkgcmFnZ3J1cHBhbWVudGlcclxuICAgICAgICAgICAgZm9yIChsZXQgbCA9IDA7IGwgPCBpbmZvcy5ncm91cGluZ0xldmVsOyBsKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBwYXJlbnQgPSByZWZUaC50aFBhcmVudDtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgIXJlZlRoLnRoUGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwYW5kZWRHcm91cHNbbF1baV0gPSBwYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVmVGggPSBpbmZvcy50aHNDYWNoZVtwYXJlbnRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBRdWFydG8gZ2lybyBwZXIgY29tcGF0dGFybG8gbmVsbCdlbGVtZW50byBmaW5hbGUgc3UgY3VpIGJpbmRhcm1pXHJcbiAgICAgICAgY3VycmVudFBhcmVudCA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRTcGFuID0gMDtcclxuICAgICAgICB0aGlzLmVzdC5UTVBSb3dUaEdyb3VwcyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgZXhwYW5kZWRHcm91cHMubGVuZ3RoOyBsKyspIHtcclxuICAgICAgICAgICAgbGV0IGxldmVsQXJyYXk6IHsgU3BhbjogbnVtYmVyOyBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjsgUGlubmVkPzogYm9vbGVhbjsgQm9yZGVycz86IGJvb2xlYW47IH1bXSA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLmVzdC5UTVBSb3dUaEdyb3Vwcy5wdXNoKGxldmVsQXJyYXkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LlNlbGVjdGlvbiB8fCB0aGlzLmVzdC5IYXNQaW5uZWRDb2x1bW5zKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwsIFBpbm5lZDogdGhpcy5lc3QuSGFzUGlubmVkQ29sdW1ucyB9KTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGggPSAwOyBoIDwgZXhwYW5kZWRHcm91cHNbbF0ubGVuZ3RoOyBoKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtID0gZXhwYW5kZWRHcm91cHNbbF1baF07XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PSBjdXJyZW50UGFyZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFuKys7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFNwYW4gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBTcGFuOiBjdXJyZW50U3BhbiwgVGVtcGxhdGU6IChjdXJyZW50UGFyZW50ID8gaW5mb3MudGhzQ2FjaGVbY3VycmVudFBhcmVudF0uVGVtcGxhdGUgOiBudWxsKSwgQm9yZGVyczogISFjdXJyZW50UGFyZW50IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFuID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gaXRlbTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gVWx0aW1hIGFnZ2l1bnRhIGNoZSBhbHRyaW1lbnRpIG1pIHJpbWFycmViYmUgaW4gY2FjaGVcclxuICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogY3VycmVudFNwYW4sIFRlbXBsYXRlOiAoY3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLlRlbXBsYXRlIDogbnVsbCksIEJvcmRlcnM6ICEhY3VycmVudFBhcmVudCB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5SZW1vdmFsKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwgfSk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5lc3QuRXhwb3J0IHx8IHRoaXMuZXN0LkhpZGRlbkNvbHVtbnMgfHwgdGhpcy5lc3QuQ29sdW1uc09yZGVyaW5nIHx8IHRoaXMuZXN0LkNvcm5lck1lbnVPcHRpb25zKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwgfSk7XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50U3BhbiA9IDA7XHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBcIlwiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGNvbGEgaWwgbnVtZXJvIGRpIHNhbHRpIGRhIHVuIGhlYWRlciBmb2dsaWEgYWxsJ3VsdGltbyBwYXJlbnQgZGVsbGEgY2F0ZW5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlfSB0aCBIZWFkZXIgZGEgY3VpIHNjb3JyZXJlIGkgcGFkcmkgcGVyIGNhcGlyZSBxdWFudGkgbGl2ZWxsaSBjaSBzb25vIHNvcHJhXHJcbiAgICAgKiBAcGFyYW0ge3sgW2luZGV4OiBzdHJpbmddOiBFc1RoRGlyZWN0aXZlIH19IHRoc0NhY2hlIENhY2hlIGRlZ2xpIGhlYWRlclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGp1bXBzVG9GaW5hbFBhcmVudCh0aDogRXNUaERpcmVjdGl2ZSwgdGhzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RoRGlyZWN0aXZlOyB9KSB7XHJcbiAgICAgICAgbGV0IGp1bXBzID0gMDsgbGV0IHBhcmVudCA9IG51bGw7XHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBwYXJlbnQgPSB0aC50aFBhcmVudDtcclxuICAgICAgICAgICAgaWYgKHBhcmVudClcclxuICAgICAgICAgICAgICAgIGp1bXBzKys7XHJcbiAgICAgICAgICAgIHRoID0gdGhzQ2FjaGVbcGFyZW50XTtcclxuICAgICAgICB9IHdoaWxlIChwYXJlbnQpO1xyXG4gICAgICAgIHJldHVybiBqdW1wcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZ2VuZXJhIGwnb3JkaW5lIGRpIGRlZmF1bHQgZGVsbGUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZW5lcmF0ZURlZmF1bHRPcmRlcih0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBvcmRlcmluZ3MgPSB0aGlzLmVzdC52aWV3TW9kZSA/IHZpZXcuY29sdW1uX29yZGVyaW5nIDogdGhpcy5lc3QuYXJyYXlDb2x1bW5PcmRlcmluZztcclxuICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gZGkgZGVmYXVsdCBkYSAwIGZpbm8gYSBkb3ZlIGRldmUgYXJyaXZhcmUuIFNpdHVhemlvbmUgYXR0dWFsZSBzZW56YSBob3Rwb3RhdG9cclxuICAgICAgICBpZiAoIW9yZGVyaW5ncyB8fCBvcmRlcmluZ3MubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgICAgIGxldCBvcmRlciA9IHRoaXMudXRpbGl0aWVzLmlzRXNUaCh0aCkgPyB0aC5JRCA6IHRoLnRoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLnB1c2gob3JkZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcyA9IG9yZGVyaW5ncztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpY2EgbCdvcmRpbmUgc3BlY2lmaWNhdG8gYWxsZSB2YXJpZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmluYWxpemUgU2UgKip0cnVlKiogc2lnbmlmaWNhIGNoZSBub24gbWkgYXNwZXR0byBkaSBkb3ZlciBlZmZldHR1YXJlIGFsdHJlIG9wZXJhemlvbmkgZSBwb3NzbyByZW5kZXJpenphcmUgbGEgc2l0dWF6aW9uZSBpbiBiYXNlIGFpIFJvd0NvbnRleHRcclxuICAgICAqIFNlbnphIGZpbmFsaXplIHNpZ25pZmljYSBjaGUgbWkgYXNwZXR0byBhbHRyZSBvcGVyYXppb25pIGNoZSBwcmltYSBvIHBvaSByaWNoaWFtZXJhbm5vIHF1ZXN0YSBmdW56aW9uZSBjb2wgZmluYWxpemUuXHJcbiAgICAgKlxyXG4gICAgICogQWQgZXNlbXBpbywgdW5hIHZvbHRhIHNlbGV6aW9uYXRvIG9yZGluYW1lbnRvIGZpc2ljby9sb2dpY28gZGVsbGUgY29sb25uZSBzbyBjaGUgcGFydGUgdW4gYWx0cmEgcmljZXJjYSBjaGUgbWkgcml2YWxvcml6emVyw6AgZGEgXCJ3cml0ZVZhbHVlXCIsIGNoZSBnacOgIGNoaWFtYSBxdWVzdGEgZnVuemlvbmUuXHJcbiAgICAgKiBNZXR0ZW5kbyBzb2xvIGxhIGNoaWFtYXRhIGRhIFwid3JpdGVWYWx1ZVwiIGNvbWUgXCJmaW5hbGl6emFudGVcIiBtaSBhc3NpY3VybyBjaGUgc21hbmF0dGFtZW50aSBhIGZyb250ZW5kIG5vbiBjYXVzaW5vIGZsaWNrZXJpbmcgZmlubyBhIHF1YW5kbyBub24gc2Vydm9ub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXBwbHlPcmRlcmluZyh2aWV3OiBBcHBTZWFyY2g8YW55PiwgZmluYWxpemU6IGJvb2xlYW4pIHtcclxuICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gcGVyIGdsaSBoZWFkZXJcclxuICAgICAgICBsZXQgbmV3SGVhZGVycyA9IFtdO1xyXG5cclxuICAgICAgICAvLyBTZSBkZXZvIGZpbmFsaXp6YXJlIGFnZ2FuY2lvIHR1dHRlIGxlIHZhcmlhYmlsaSBkaSBiaW5kXHJcbiAgICAgICAgaWYgKGZpbmFsaXplKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlYWVkckl0ZW0gPSB0aGlzLmVzdC5UTVBSb3dUSHMuZmlsdGVyKHQgPT4gdC5JRCA9PSBvKVswXTtcclxuICAgICAgICAgICAgICAgIGlmIChoZWFlZHJJdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0hlYWRlcnMucHVzaChoZWFlZHJJdGVtKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0LlRNUFJvd1RIcyA9IG5ld0hlYWRlcnM7XHJcblxyXG4gICAgICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gcGVyIGxlIGNlbGxlXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuUm93Q29udGV4dHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy5lc3QuVE1QUm93VERzW3RoaXMuZXN0LlJvd0NvbnRleHRzW2ldXTtcclxuICAgICAgICAgICAgICAgIGxldCBuZXdDb250ZXh0ID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLmZvckVhY2gobyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRleHRJdGVtID0gY29udGV4dC5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0NvbnRleHQucHVzaChjb250ZXh0SXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5UTVBSb3dURHNbdGhpcy5lc3QuUm93Q29udGV4dHNbaV1dID0gbmV3Q29udGV4dDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbl9vcmRlcmluZyA9IHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcztcclxuXHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5hcnJheUNvbHVtbk9yZGVyaW5nID0gdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzO1xyXG5cclxuICAgICAgICB0aGlzLmVzdC5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBtZXR0ZSBsYSBjb2xvbm5hIHNwZWNpZmljYXRhIHByaW1hIGRlbGxhIGNvbG9ubmEgcHJlY2VkZW50ZVxyXG4gICpcclxuICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgKi9cclxuICAgIHB1YmxpYyBzZW5kVXAoY29sdW1uSXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIGxldCBpdGVtSW5kZXggPSB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5pbmRleE9mKGNvbHVtbkl0ZW0pO1xyXG4gICAgICAgIGlmICh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdFtpdGVtSW5kZXggLSAxXS5maXhlZCB8fCB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdFtpdGVtSW5kZXggLSAxXS5waW5uZWQpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB0aGlzLnV0aUV4dHMuc3dhcCh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpdGVtSW5kZXggLSAxKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcbiAgICAgICAgbGV0IHRtcCA9IFtdO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRtcC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QgPSB0bXA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBtZXR0ZSBsYSBjb2xvbm5hIHNwZWNpZmljYXRhIGRvcG8gbGEgY29sb25uYSBzdWNjZXNzaXZhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNlbmREb3duKGNvbHVtbkl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICBsZXQgaXRlbUluZGV4ID0gdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuaW5kZXhPZihjb2x1bW5JdGVtKTtcclxuICAgICAgICB0aGlzLnV0aUV4dHMuc3dhcCh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpdGVtSW5kZXggKyAxKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcbiAgICAgICAgbGV0IHRtcCA9IFtdO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRtcC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QgPSB0bXA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBwaW5uYSBsYSBjb2xvbm5hIHNwZWNpZmljYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBpbk9yVW5waW5Db2x1bW4oY29sdW1uSXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIGxldCBpdGVtSW5kZXggPSB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5pbmRleE9mKGNvbHVtbkl0ZW0pO1xyXG4gICAgICAgIGlmICghY29sdW1uSXRlbS5waW5uZWQpIHtcclxuICAgICAgICAgICAgY29sdW1uSXRlbS5wcmV2X2luZGV4ID0gaXRlbUluZGV4O1xyXG5cclxuICAgICAgICAgICAgLy9RdWFuZG8gcGlubm8gZGV2byBzcG9zdGFyZSBsJ2VsZW1lbnRvIGNvbWUgdWx0aW1hIGNvbG9ubmEgcGlubmF0YSBvIGNvbWUgcHJpbWEgY29sb25uYSBzZSBub24gY2UgbmUgc29ubyBkaSBwaW5uYXRlXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3RbaV0ucGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXMuYXJyYXlNb3ZlKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvL1F1YW5kbyBzcGlubm8gcmlwb3J0byBsJ2VsZW1lbnRvIGFsbG8gc3Rlc3NvIGluZGljZSBpbiBjdWkgZXJhIHByaW1hIChzZSBzb25vIHN0YXRpIGZhdHRpIHNwb3N0YW1lbnRpIG5lbCBtZXp6byBjYXp6aSBkZWxsJ3V0ZW50ZSlcclxuICAgICAgICAgICAgaWYgKGNvbHVtbkl0ZW0ucHJldl9pbmRleCAhPSBudWxsICYmIGNvbHVtbkl0ZW0ucHJldl9pbmRleCAhPSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgY29sdW1uSXRlbS5wcmV2X2luZGV4KTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZSBzcGlubm8gc2VuemEgdW4gcHJldl9pbmRleCB2dW9sIGRpcmUgY2hlIGxhIGNvbG9ubmEgZXJhIHBpbm5hdGEgZGEgY29uZmlndXJhemlvbmUuIExhIHNwb3N0byBuZWwgcHJpbW8gcHVudG8gZGlzcG9uaWJpbGVcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZXN0LlRNUENvbHVtbnNMaXN0W2ldLnBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaSAtIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbHVtbkl0ZW0ucGlubmVkID0gIWNvbHVtbkl0ZW0ucGlubmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgaW52ZXJ0ZSBsZSBpbXBvc3RhemlvbmkgZGkgdmlzaWJpbGl0w6AgZGVsbGEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb2x1bW5DbGlja2VkKGl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICB0aGlzLmVzdC5sYXN0U2VsZWN0ZWRJdGVtSUQgPSBpdGVtLmlkO1xyXG4gICAgICAgIGlmICghdGhpcy5lc3QuSGlkZGVuQ29sdW1ucyB8fCBpdGVtLmZpeGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGl0ZW0udmlzaWJsZSA9ICFpdGVtLnZpc2libGU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBBbGwnYXBlcnR1cmEgZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgcmljYXJpY2EgbGUgaW5mb3JtYXppb25pIGF0dHVhbGkgcGVyIHBlcm1ldHRlcmUgbGEgbW9kaWZpY2EgKi9cclxuICAgIHB1YmxpYyByZXNldENvbHVtblZpc1NlbGVjdGlvbigpIHtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIC8vIE5vbiBwb3NzbyBmYXJlIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5Db2x1bW5zTGlzdCkpIHBlcmNow6kgY29udGllbmUgcmlmZXJpbWVudGkgYSBUZW1wbGF0ZVJlZlxyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG5cclxuICAgICAgICBsZXQgcmVvcmRlcmVkQ29sTGlzdCA9IFtdO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5lc3QuQ29sdW1uc09yZGVyaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbiA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZpbHRlcih0ID0+IHQuaWQgPT0gbylbMF07XHJcbiAgICAgICAgICAgICAgICAvLyBQb3RyZWkgbm9uIGF2ZXJuZSBuZWwgY2FzbyBjaSBzaWEgaWwgZmxhZyBIaWRkZW5Db2x1bW5zIGEgZmFsc2UsIGV2aXRvIGRpIGluc2VyaXJlIGRlZ2xpIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbilcclxuICAgICAgICAgICAgICAgICAgICByZW9yZGVyZWRDb2xMaXN0LnB1c2goY29sdW1uKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IHJlb3JkZXJlZENvbExpc3Q7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUdsb2JhbENvbFZpc0NoZWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFJpYWdnaW9ybmEgbGUgKipPcmRlckRpcmVjdGl2ZXMqKiBjb24gbGUgaW5mb3JtYXppb25pIGluICAqKkNvbHVtbnNMaXN0KiogKi9cclxuICAgIHByaXZhdGUgcmVmcmVzaENvbHVtbk9yZGVyaW5nKCkge1xyXG4gICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aDsgYysrKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMucHVzaCh0aGlzLmVzdC5Db2x1bW5zTGlzdFtjXS5pZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEVmZmV0dHVhIGxhIHNlbGV6aW9uZSBvIG1lbm8gZGVsIGNoZWNrIGdsb2JhbGUgKCoqZ2xvYmFsQ29sVmlzQ2hlY2sqKikgZGkgdmlzaWJpbGl0w6AgaW4gYmFzZSBhIHNlIHR1dHRlIGxlICoqVE1QQ29sdW1uc0xpc3QqKiBzb25vIHZpc2liaWxpIG8gbm8gKi9cclxuICAgIHB1YmxpYyB1cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpIHtcclxuICAgICAgICAvLyBUTVBDb2xMaXN0IHZpZW5lIHJpZW1waXRhIGRpIHVuZGVmaW5lZCBuZWwgY2FzbyBpbiBjdWkgc2lhIGRpc2F0dGl2YXRhIGxhIHNlbGV6aW9uZSBkZWxsZSBjb2xvbm5lIG5hc2Nvc3RlXHJcbiAgICAgICAgdGhpcy5lc3QuZ2xvYmFsQ29sVmlzQ2hlY2sgPSB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5ldmVyeSh0ID0+IHQudmlzaWJsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGdW56aW9uZSBjaGUgZWZmZXR0dWEgbGEgY29uZmVybWEgZGVsbGEgdmlzaWJpbGl0w6AgZSBkZWxsJ29yZGluZSBkZWxsZSBjb2xvbm5lLlxyXG4gICAgICpcclxuICAgICAqIFF1ZXN0YSBzZWxlemlvbmUgdmllbmUgaW5vbHRyZSBzYWx2YXRhIG5lbGxlIHByZWZlcmVuemUgKCoqQGVzZmFlbnphL3ByZWZlcmVuY2VzKiopLCBxdWFsb3JhIGwnSW5wdXQgKipTYXZlUHJlZmVyZW5jZXMqKiBmb3NzZSB2YWxvcml6emF0b1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAqKnRydWUqKiBzZSBub24gY2kgc29ubyBwcm9ibGVtaSwgKipmYWxzZSoqIGFsdHJpbWVudGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbmZpcm1Db2x1bW5WaXNpYmlsaXR5U2VsZWN0aW9uKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIE5vbiBwZXJtZXR0byBkaSBub24gc2VsZXppb25hcmUgbnVsbGFcclxuICAgICAgICBpZiAodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZXZlcnkodCA9PiAhdC52aXNpYmxlKSlcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICBsZXQgY2FzdGVkVmlldyA9IHRoaXMuZXN0LnZpZXdNb2RlID8gKHRoaXMuZXN0Lk1haW5Hcm91cFZpZXcgfHwgdGhpcy5lc3QuVmlldyBhcyBBcHBTZWFyY2g8YW55PikgOiBudWxsO1xyXG4gICAgICAgIHRoaXMuZXN0LkNvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdGhpcy5lc3QuQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hDb2x1bW5PcmRlcmluZygpO1xyXG4gICAgICAgIHRoaXMuYXBwbHlPcmRlcmluZyhjYXN0ZWRWaWV3LCBmYWxzZSk7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KG51bGwsIG51bGwsIGNhc3RlZFZpZXcpO1xyXG5cclxuICAgICAgICAvL1NhbHZvIGxlIHByZWZlcmVuY2VzIGRpIHF1ZXN0YSB2aWV3XHJcbiAgICAgICAgLy9EaSBkZWZhdWx0IHJlZ2lzdHJvIG9yZGluYW1lbnRvIGUgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZSBuZWxsYSB2aXN0YS4gU29sbyBsZSBjb3NlIGRpIFVJXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZXN0Lm5nQ29udHJvbC5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBhdmVyZSB1biAnbmFtZScgcGVyIGxhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wcmVmU2VydmljZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgY2hlIGlsIHBhY2NoZXR0byBAZXNmYWVuemEvcHJlZmVyZW5jZXMgc2lhIGluc3RhbGxhdG9cIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCBjb2x1bW5zID0gdGhpcy5lc3QuYXJyYXlNb2RlID8gdGhpcy5lc3QuYXJyYXlDb2x1bW5zIDogY2FzdGVkVmlldy5jb2x1bW5zO1xyXG4gICAgICAgICAgICBsZXQgY29sdW1uc09yZGVyaW5ncyA9IHRoaXMuZXN0LmFycmF5TW9kZSA/IHRoaXMuZXN0LmFycmF5Q29sdW1uT3JkZXJpbmcgOiBjYXN0ZWRWaWV3LmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgdmFyIHRvU3RvcmUgPSB7IGNvbHVtbnM6IDxzdHJpbmdbXT5KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNvbHVtbnMpKSwgY29sdW1uX29yZGVyaW5nOiA8c3RyaW5nW10+SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb2x1bW5zT3JkZXJpbmdzKSkgfTtcclxuICAgICAgICAgICAgdGhpcy5wcmVmU2VydmljZS5zdG9yZSg8c3RyaW5nPnRoaXMuZXN0Lm5nQ29udHJvbC5uYW1lLCB0b1N0b3JlKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJpZXNlZ3VvIGwndWx0aW1hIHJpY2VyY2EgYmluZGF0YSBhbGxhIHRhYmVsbGFcclxuICAgICAgICAvLyBNaSBhc3NpY3VybyBkaSBmYXJsbyBkb3BvIGwnZXNwYW5zaW9uZSBkZWwgY2hhbmdlZCBvIHJpc2NoaW8gY2hlIGxhIHJpY2VyY2EgbWkgcmlkaWEgY29sb25uZSBjaGUgaW4gcmVhbHTDoCBub24gZXNpc3Rvbm9cclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZXN0Lk1haW5Hcm91cFZpZXcpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuZW1pdFNlYXJjaFJlcXVlc3QodHJ1ZSwgdGhpcy5NYWluR3JvdXBWaWV3KTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0Lmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmlldyA9IHRoaXMuZXN0Lmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZVtpXS52aWV3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3LmNvbHVtbnMgPSB0aGlzLmVzdC5NYWluR3JvdXBWaWV3LmNvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nID0gdGhpcy5lc3QuTWFpbkdyb3VwVmlldy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXN0LmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHRoaXMuZXN0Lmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZVtpXS52aWV3KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXN0LmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICBlbHNlIGlmICh0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyB0aGlzLmVzdC5pbnRlcm5hbFdyaXRlVmFsdWUoKTsgfSk7XHJcblxyXG4gICAgICAgIC8vIExvIHZvcnJlaSBtZXR0ZXJlIGxhdG8gdGVtcGxhdGUgbWEgbm9cclxuICAgICAgICB0aGlzLmVzdC5sYXN0U2VsZWN0ZWRJdGVtSUQgPSBudWxsO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dW8gbCd1bnBpbm5pbmcgZGkgdW5hIGNvbG9ubmEgaW4gbWFuaWVyYSBwcm9ncmFtbWF0aWNhIHNlbXBsaWNlbWVudGUgZXNlZ3VlbmRvIHVuYSBwZXIgdW5hIGxlIG9wZXJhemlvbmkgY2hlIHZlcnJlYmJlcm8gZXNlZ3VpdGUgYWx0cmltZW50aVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBDb2RpY2UgZGVsbGEgY29sb25uYSBkYSBzcGlubmFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdW5waW5Db2x1bW4oaWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMucmVzZXRDb2x1bW5WaXNTZWxlY3Rpb24oKTtcclxuICAgICAgICB0aGlzLnBpbk9yVW5waW5Db2x1bW4odGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZmluZCh0ID0+IHQuaWQgPT0gaWQpKTtcclxuICAgICAgICB0aGlzLmNvbmZpcm1Db2x1bW5WaXNpYmlsaXR5U2VsZWN0aW9uKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFN1bCBjbGljayBuZWxsYSBjaGVja2JveCBkaSBzZWxlemlvbmUgZ2xvYmFsZSBzaSBzY29ycm9ubyB0dXR0ZSBsZSBjb2xvbm5lIGUgc2kgaW1wb3N0YW5vIGFsIHZhbG9yZSBkZWxsYSBjaGVjayBnbG9iYWxlICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ29sVmlzQ2hlY2tDaGFuZ2VkKCkge1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZvckVhY2godCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdC5maXhlZClcclxuICAgICAgICAgICAgICAgIHQudmlzaWJsZSA9IHRoaXMuZXN0Lmdsb2JhbENvbFZpc0NoZWNrO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==