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