@esfaenza/es-table 11.2.22-beta3 → 11.2.22-beta33
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 +3181 -3000
- package/bundles/esfaenza-es-table.umd.js.map +1 -1
- package/bundles/esfaenza-es-table.umd.min.js +1 -15
- package/bundles/esfaenza-es-table.umd.min.js.map +1 -1
- package/esfaenza-es-table.d.ts +6 -5
- package/esfaenza-es-table.metadata.json +1 -1
- package/esm2015/esfaenza-es-table.js +7 -6
- package/esm2015/lib/components/es-table/es_table.component.js +1313 -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 +667 -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/domain/configuration/EsTableDefaultable.js +4 -0
- package/esm2015/lib/domain/configuration/EsTableModuleConfig.js +4 -0
- package/esm2015/lib/domain/internals/classes/EsTableColumn.js +1 -1
- package/esm2015/lib/domain/internals/classes/ThElement.js +2 -0
- package/esm2015/lib/domain/internals/index.js +2 -1
- package/esm2015/lib/es-table.module.js +6 -6
- package/esm2015/lib/tokens.js +1 -1
- package/esm2015/public-api.js +6 -6
- package/fesm2015/esfaenza-es-table.js +2863 -2705
- package/fesm2015/esfaenza-es-table.js.map +1 -1
- package/lib/components/es-table/es_table.component.d.ts +630 -0
- package/lib/{es_table.component.loc.d.ts → components/es-table/es_table.component.loc.d.ts} +0 -0
- package/lib/{es_td.component.d.ts → components/es-td/es_td.component.d.ts} +0 -0
- package/lib/{es_th.component.d.ts → components/es-th/es_th.component.d.ts} +6 -0
- package/lib/{pager → components/pager}/table_pager.component.d.ts +8 -1
- package/lib/{pager → components/pager}/table_pager.component.loc.d.ts +0 -0
- 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/{models → domain/configuration}/EsTableDefaultable.d.ts +0 -0
- package/lib/{models → domain/configuration}/EsTableModuleConfig.d.ts +0 -0
- package/lib/domain/internals/classes/EsTableColumn.d.ts +2 -0
- package/lib/domain/internals/classes/ThElement.d.ts +13 -0
- package/lib/domain/internals/index.d.ts +1 -0
- package/lib/es-table.module.d.ts +1 -1
- package/lib/tokens.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +5 -5
- package/esm2015/lib/es_table.component.js +0 -3453
- package/esm2015/lib/es_table.component.loc.js +0 -35
- package/esm2015/lib/es_td.component.js +0 -106
- package/esm2015/lib/es_th.component.js +0 -150
- package/esm2015/lib/models/EsTableDefaultable.js +0 -4
- package/esm2015/lib/models/EsTableModuleConfig.js +0 -4
- package/esm2015/lib/pager/table_pager.component.js +0 -92
- package/esm2015/lib/pager/table_pager.component.loc.js +0 -22
- package/lib/es_table.component.d.ts +0 -1192
|
@@ -0,0 +1,1313 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
// Angular
|
|
3
|
+
import { Component, forwardRef, ContentChildren, ChangeDetectorRef, ChangeDetectionStrategy, Input, EventEmitter, Output, ContentChild, ViewChild, ViewEncapsulation, Optional, Self, Inject } from '@angular/core';
|
|
4
|
+
import { NgControl } from '@angular/forms';
|
|
5
|
+
// Configurazioni
|
|
6
|
+
import { UtilityService, ExportService, MessageService, DateService } from '@esfaenza/extensions';
|
|
7
|
+
import { LocalizationService } from '@esfaenza/localizations';
|
|
8
|
+
import { PreferencesService } from '@esfaenza/preferences';
|
|
9
|
+
// Modelli
|
|
10
|
+
import { AppSearch, ReportDefinition } from '../../domain';
|
|
11
|
+
// Componenti e Localizzazione
|
|
12
|
+
import { EsTd } from '../es-td/es_td.component';
|
|
13
|
+
import { EsTh } from '../es-th/es_th.component';
|
|
14
|
+
import { EsTdDirective } from '../../directives/es_td.directive';
|
|
15
|
+
import { EsThDirective } from '../../directives/es_th.directive';
|
|
16
|
+
import { EsTableLoc } from './es_table.component.loc';
|
|
17
|
+
import { ItemsSelection } from '../../domain/externals/classes/appsearch/ItemsSelection';
|
|
18
|
+
import { GroupFilter } from "../../domain/externals/classes/appsearch/GroupFilter";
|
|
19
|
+
import { EsTableDefaultable } from '../../domain/configuration/EsTableDefaultable';
|
|
20
|
+
import { EST_DEFAULTS, EST_LOCALE } from '../../tokens';
|
|
21
|
+
import { ExportHandler, ColumnMetadataHandler, DynamicModeHandler, HierarchyModeHandler, ItemsHandler, ReportModeHandler, RowGroupingHandler, SelectionHandler, UtilitiesHandler } from '../../core/handlers';
|
|
22
|
+
/** Componente che permette di rappresentare una griglia di valori */
|
|
23
|
+
export class EsTableComponent {
|
|
24
|
+
/** @ignore */
|
|
25
|
+
constructor(ngControl, prefService, deafults, locale, lc, cdr, utilities_H, utiExts, expExts, dateExts, msgExts) {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
27
|
+
this.ngControl = ngControl;
|
|
28
|
+
this.prefService = prefService;
|
|
29
|
+
this.deafults = deafults;
|
|
30
|
+
this.locale = locale;
|
|
31
|
+
this.lc = lc;
|
|
32
|
+
this.cdr = cdr;
|
|
33
|
+
this.utilities_H = utilities_H;
|
|
34
|
+
this.utiExts = utiExts;
|
|
35
|
+
this.expExts = expExts;
|
|
36
|
+
this.dateExts = dateExts;
|
|
37
|
+
this.msgExts = msgExts;
|
|
38
|
+
/** View finale su cui bindarsi lato Frontend, il tipo può essere IAppSearch<any> (per la **viewMode**), any[] (per l'**arrayMode**) e ReportDefinition per la **reportMode** */
|
|
39
|
+
this.View = null;
|
|
40
|
+
/** Indica se l'es-table deve mostrare il check globale nell'header per fare il "seleziona tutto" */
|
|
41
|
+
this.globalCheck = false;
|
|
42
|
+
/** Tiene da conto l'ultimo elemento selezionato in modo da poter effettuare il SHIFT+CLICK */
|
|
43
|
+
this.lastSelected = null;
|
|
44
|
+
/** Conteggio interno per il numero di elementi selezionati */
|
|
45
|
+
this.selectedObjects = 0;
|
|
46
|
+
/** Indica se è possibile effettuare una selezione massiva */
|
|
47
|
+
this.canSelectAll = false;
|
|
48
|
+
/** Indica se il componente sta gestendo un IAppSearch<any> */
|
|
49
|
+
this.viewMode = false;
|
|
50
|
+
/** Indica se il componente sta gestendo un any[] */
|
|
51
|
+
this.arrayMode = false;
|
|
52
|
+
/** Indica se il componente sta gestendo un ReportDefinition */
|
|
53
|
+
this.reportMode = false;
|
|
54
|
+
/**
|
|
55
|
+
* Contenitore degli elementi da listare lato interfaccia dopo tutte le elaborazioni del caso,
|
|
56
|
+
* generalmente non sono altro che tutti gli oggetti da presentare con in più l'hash calcolato per identificare 1 oggetto con la propria riga
|
|
57
|
+
*/
|
|
58
|
+
this.boundSource = [];
|
|
59
|
+
/** Stessa cosa della **boundSource**, utilizzata come appoggio temporaneo interno */
|
|
60
|
+
this.TMPBoundSource = [];
|
|
61
|
+
/** "Fetta" di oggetti utilizzata nell'endless scroll, ogni elemento di questo array è un blocchetto di 100 elementi */
|
|
62
|
+
this.boundSubSources = [];
|
|
63
|
+
/** Questa funge da indicatore per gli slice inseriti, la lunghezza dovrebbe essere corrispondente a **boundSubSources** */
|
|
64
|
+
this.addedSlices = [];
|
|
65
|
+
/** Variabile che identifica il valore del "seleziona Tutto" nella paginazione */
|
|
66
|
+
this.defaultAllPageOverride = 999999;
|
|
67
|
+
/** Indica se utilizzare il sistema di autoupdate, cioè un trigger time-izzato in alto a destra della tabella che ripete le ricerche ogni X **seconds** */
|
|
68
|
+
this.autoUpdate = false;
|
|
69
|
+
/** Numero di secondi da fare trascorrere fra una ricerca e l'altra */
|
|
70
|
+
this.seconds = '10';
|
|
71
|
+
/** Impostata a true ogni volta che viene avviata una ricerca, e a false ogni volta che un nuovo valore viene ricevuto */
|
|
72
|
+
this.researchInProgress = false;
|
|
73
|
+
/** Modello rappresentante un singolo td della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
|
|
74
|
+
this.RowTDs = null;
|
|
75
|
+
/** Modello di appoggio temporaneo per i **RowTDs** */
|
|
76
|
+
this.TMPRowTDs = null;
|
|
77
|
+
/** Modello rappresentante un singolo th della tabella, generato in base alle configurazioni e agli oggetti ricevuti */
|
|
78
|
+
this.RowTHs = null;
|
|
79
|
+
/** Modello di appoggio temporaneo per i **RowTHs** */
|
|
80
|
+
this.TMPRowTHs = null;
|
|
81
|
+
/** Modello di appoggio temporaneo per i **RowThGroups** */
|
|
82
|
+
this.TMPRowThGroups = null;
|
|
83
|
+
/** Modello rappresentante un singolo header group della tabella. Questa lista è già ordinata e pronta per essere utilizzata in ngFor */
|
|
84
|
+
this.RowThGroups = null;
|
|
85
|
+
/** Cache per i routerLink generati nelle tabelle dinamiche */
|
|
86
|
+
this.DynamicTableRouterLinkCache = {};
|
|
87
|
+
/**
|
|
88
|
+
* Lista dei contesti. Un contesto non è altro che un hash particolare calcolato su un oggetto che identifica univocamente tale oggetto.
|
|
89
|
+
*
|
|
90
|
+
* Ognuno di questi contesti rappresenterà a sua volta, univocamente, una riga all'interno della tabella
|
|
91
|
+
*/
|
|
92
|
+
this.RowContexts = [];
|
|
93
|
+
/** Direttive di ordinamento delle colonne (non ordinamento dei dati ma delle colonne in se) */
|
|
94
|
+
this.OrderDirectives = [];
|
|
95
|
+
/** Codice dell'ultimo oggetto solezionato */
|
|
96
|
+
this.lastSelectedItemID = null;
|
|
97
|
+
/**
|
|
98
|
+
* Indica se oltre alle colonne dinamiche specifiche di un tipo di oggetto ci sono anche colonne dinamiche aggiunte dall'utente
|
|
99
|
+
*
|
|
100
|
+
* Es. una colonna in cui mostrare sempre un iconcina
|
|
101
|
+
*/
|
|
102
|
+
this.UserDefinedDynamicCols = false;
|
|
103
|
+
/** Indica che questo è il primo Bind della tabella, viene settato a false non appena il primo bind viene terminato con successo */
|
|
104
|
+
this.FirstBind = true;
|
|
105
|
+
/** Lista di colonne che si possono visualizzare/ordinare fra di loro */
|
|
106
|
+
this.ColumnsList = [];
|
|
107
|
+
/** Variabile d'appoggio usata dalla dialog di selezione/nascondimento, per evitare di danneggiare **ColumnsList** in caso di modifiche poi annullate */
|
|
108
|
+
this.TMPColumnsList = [];
|
|
109
|
+
/** Valore del check globale di visibilità valido per tutte le colonne in **ColumnsList** */
|
|
110
|
+
this.globalColVisCheck = false;
|
|
111
|
+
/** Opzioni extra che devono apparire nel Menù contestuale in alto a destra, richiamato dai 3 pallini verticali */
|
|
112
|
+
this.CornerMenuOptions = null;
|
|
113
|
+
/** Indica se dev'essere possibile effettuare il resize delle colonne */
|
|
114
|
+
this.ColumnsResizable = null;
|
|
115
|
+
/** Indica se dev'essere disponibile il sistema di aggiornamento automatico */
|
|
116
|
+
this.AutoUpdate = null;
|
|
117
|
+
/** Indica se la tabella (configurata con **UseCustomCells**) deve mettersi in ascolto per i click sulle celle desiderate
|
|
118
|
+
*
|
|
119
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
120
|
+
*/
|
|
121
|
+
this.UseCustomCellActions = null;
|
|
122
|
+
/**
|
|
123
|
+
* Indica le celle desiderate su cui intercettare i click. Attiva solo quando **UseCustomCellActions** è true.
|
|
124
|
+
* Ogni cella dev'essere separata dalla successiva dal carattere del Simoleon:
|
|
125
|
+
*
|
|
126
|
+
* Es, "MiaCella1§MiaCella2"
|
|
127
|
+
*
|
|
128
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
129
|
+
*/
|
|
130
|
+
this.CustomCellActionsOn = '';
|
|
131
|
+
/**
|
|
132
|
+
* Serve per decidere di lanciare o meno il **event.stopPropagation()** al termine della gestione dell'evento
|
|
133
|
+
*
|
|
134
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
135
|
+
*/
|
|
136
|
+
this.CellActionPropagates = true;
|
|
137
|
+
/**
|
|
138
|
+
* Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
|
|
139
|
+
*
|
|
140
|
+
* 1) Ordinamento e visibilità delle colonne
|
|
141
|
+
*
|
|
142
|
+
* 2) Ordinamento dei dati
|
|
143
|
+
*
|
|
144
|
+
* 3) Modalità Gerarchica
|
|
145
|
+
*
|
|
146
|
+
* ecc...
|
|
147
|
+
*/
|
|
148
|
+
this.UseCustomCells = null;
|
|
149
|
+
/** Permette di impostare l'altezza massima della tabella. Se null la dimensione si adatta al numero di elementi attualmente in visualizzazione */
|
|
150
|
+
this.MaxHeight = null;
|
|
151
|
+
/** Classi da applicare al contenitore della tabella */
|
|
152
|
+
this.ContainerClass = null;
|
|
153
|
+
/** Permette o meno l'export in formato XLSX */
|
|
154
|
+
this.XLSXExport = null;
|
|
155
|
+
/** Permette o meno l'export in formato CSV */
|
|
156
|
+
this.CSVExport = true;
|
|
157
|
+
/** Permette di visualizzare o meno l'opzione di paginazione "Tutti" */
|
|
158
|
+
this.AllSearch = null;
|
|
159
|
+
/** Diminuisce gli spazi fra una cella e l'altra, e internamente il padding del font in modo da presentare molti più dati in un'unica pagina */
|
|
160
|
+
this.HighCellDensity = null;
|
|
161
|
+
/** Abilita o meno la possibilità di selezionare oggetti */
|
|
162
|
+
this.Selection = null;
|
|
163
|
+
/** Mostra o meno un messaggio di Loading al primo caricamento della tabella */
|
|
164
|
+
this.ShowLoadingOnBootstrap = null;
|
|
165
|
+
/** Se impostato a **true** aggiunge una colonna con pulsante di eliminazione per effettuare l'elimina dell'oggetto relativo */
|
|
166
|
+
this.Removal = null;
|
|
167
|
+
/**
|
|
168
|
+
* Condizione che nasconde l'icona di eliminazione inserita impostando **Removal** a true qualora la condizione non venisse rispettata
|
|
169
|
+
*
|
|
170
|
+
* Come condizione si considera un semplice campo su cui effettuare un controllo booleano, come ad esempio "canremove"
|
|
171
|
+
*/
|
|
172
|
+
this.RemovalCondition = '';
|
|
173
|
+
/** Indica se abilitare la possibilità di esportare la vista dati attuale */
|
|
174
|
+
this.Export = null;
|
|
175
|
+
/** Indica se permettere la selezione multipla Windows-like cliccando un oggetto e facendo poi Shift + click su un oggetto successivo */
|
|
176
|
+
this.ShiftClick = null;
|
|
177
|
+
/** Indica il testo che va a sostituire "Oggetti Visualizzati" in caso si stia facendo qualcosa di custom */
|
|
178
|
+
this.CountLabel = null;
|
|
179
|
+
/** Indica se nascondere o mostrare il componente di paginazione */
|
|
180
|
+
this.HidePaging = null;
|
|
181
|
+
/** Indica se nascondere o mostrare il conteggio degli elementi trovati */
|
|
182
|
+
this.HidePagingCount = null;
|
|
183
|
+
/** Indica se nascondere o mostrare i pulsanti di paginazione */
|
|
184
|
+
this.HidePagingButtons = null;
|
|
185
|
+
/** Riferimento al ContextMenu (ngx-contextmenu) associato al click destro di uno o più elementi selezionati nella tabella */
|
|
186
|
+
this.ContextMenu = null;
|
|
187
|
+
/** Nome dell'esportazione generata da questa tabella */
|
|
188
|
+
this.ExportFileName = 'Export.csv';
|
|
189
|
+
/** Classe (HTML) di default della tabella */
|
|
190
|
+
this.TableClass = null;
|
|
191
|
+
/** Indica la presenza di raggruppamenti a livello di header */
|
|
192
|
+
this.HasHeaderGroup = null;
|
|
193
|
+
/** Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
|
|
194
|
+
this.HasSecondaryHeaderGroup = null;
|
|
195
|
+
/** Utilizzato per dividere la sorgente in modalità EndlessScroll */
|
|
196
|
+
this.SliceSize = 100;
|
|
197
|
+
/** Decide se utilizzare la modalità di EndlessScroll */
|
|
198
|
+
this.EndlessScroll = null;
|
|
199
|
+
/** Qualora **EndlessScroll** fosse true, indica se utilizzare questa modalità solo quando si cerca per "Tutti" o in generale */
|
|
200
|
+
this.EndlessScrollOnlyForAll = true;
|
|
201
|
+
/** Indica se nascondere gli Header della tabella */
|
|
202
|
+
this.HeaderHidden = null;
|
|
203
|
+
/** Indica se nascondere il Body della tabella */
|
|
204
|
+
this.BodyHidden = null;
|
|
205
|
+
/**
|
|
206
|
+
* Indica se la selezione è temporaneamente disabilitata. Rispetto all'Input **Selection** che visivamente gestisce se ci sono o no gli input di selezione,
|
|
207
|
+
* questo Input gestisce se questi input sono abilitati o meno
|
|
208
|
+
*/
|
|
209
|
+
this.SelectionDisabled = null;
|
|
210
|
+
/**
|
|
211
|
+
* Indica se forzare il sistema di selezione a gestire un elemento per volta.
|
|
212
|
+
* Selezionare un'altra riga con una già selezionata applicherà la selezione alla nuova riga, rimuovendola dall'attuale
|
|
213
|
+
*/
|
|
214
|
+
this.SingleSelection = null;
|
|
215
|
+
/** Callback che dato un oggetto resituisce l'eventuale classe da applicare alla riga collegata all'oggetto */
|
|
216
|
+
this.RowClassAssigner = null;
|
|
217
|
+
/** Permette di ordinare i dati in maniera discendente o ascendente */
|
|
218
|
+
this.OrderByColumn = null;
|
|
219
|
+
/** Permette di avere più direttive di ordinamento dei dati */
|
|
220
|
+
this.MultipleOrderingDirectives = true;
|
|
221
|
+
/** Permette di nascondere le colonne in base alle selezioni effettuate dal Menù contestuale in alto a destra */
|
|
222
|
+
this.HiddenColumns = null;
|
|
223
|
+
/** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
|
|
224
|
+
this.ColumnsOrdering = null;
|
|
225
|
+
/** Eventuale supporto alle ricerche applicate alla modalità Array */
|
|
226
|
+
this.SearchView = null;
|
|
227
|
+
/** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
|
|
228
|
+
this.SelectAll = null;
|
|
229
|
+
/** Simula la paginazione anche per le tabelle che funzionano in modalità Array */
|
|
230
|
+
this.UseArrayModePaging = true;
|
|
231
|
+
/** Definizione di colonne dinamche per la modalità, appunto, dinamica */
|
|
232
|
+
this.DynamicRowColumnsDefinition = null;
|
|
233
|
+
/** Indica operazioni dinamiche generiche che possono essere effettuate per riga. Appaiono come colonne extra sul lato sinistro della tabella */
|
|
234
|
+
this.DynamicOperations = [];
|
|
235
|
+
/** Indica se visualizzare i dati in maniera gerarchica */
|
|
236
|
+
this.Hierarchy = null;
|
|
237
|
+
/** Nome della proprietà che contiene l'ID del padre. Da utilizzare se **Hierarchy** è impostato */
|
|
238
|
+
this.ParentKey = '';
|
|
239
|
+
/** Nome della proprietà che contiene l'ID dell'oggetto attuale. Da utilizzare se **Hierarchy** è impostato */
|
|
240
|
+
this.OwnKey = '';
|
|
241
|
+
/** Indica se partire con un albero espanso. Da utilizzare se **Hierarchy** è impostato */
|
|
242
|
+
this.StartsExpanded = true;
|
|
243
|
+
/** Indica se effettuare il salvataggio delle preferenze di ricerca */
|
|
244
|
+
this.SavePreferences = null;
|
|
245
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
246
|
+
this.PagingStyle = null;
|
|
247
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
248
|
+
this.RowGroupingPagingStyle = null;
|
|
249
|
+
/**
|
|
250
|
+
* Sorgente dati secondaria
|
|
251
|
+
*
|
|
252
|
+
* @deprecated Utilizzato solo per un caso particolare del Metering
|
|
253
|
+
*/
|
|
254
|
+
this.SecondarySource = null;
|
|
255
|
+
/**
|
|
256
|
+
* Sorgente dati secondaria
|
|
257
|
+
*
|
|
258
|
+
* @deprecated Utilizzato solo per un caso particolare del Metering
|
|
259
|
+
*/
|
|
260
|
+
this.TertiarySource = null;
|
|
261
|
+
/** Indica se utilizzare la cache di selezione che permette di mantenere gli stati di selezione dei vari oggetti navigando da una pagina all'altra */
|
|
262
|
+
this.UseSelectionCache = null;
|
|
263
|
+
/** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
|
|
264
|
+
this.ShowItemGroupsColumns = null;
|
|
265
|
+
/** Evento che viene richiamato al cambio di oridnamento di una colonna */
|
|
266
|
+
this.onOrderChanged = new EventEmitter();
|
|
267
|
+
/**
|
|
268
|
+
* Evento che viene richiamato quando l'es-table ritiene sia necessario ri-effettuare la ricerca.
|
|
269
|
+
* Il booleano dell'evento indica se viene suggerito di resettare la pagina o meno.
|
|
270
|
+
*
|
|
271
|
+
* Solo in caso venga utilizzata la modalità a raggruppamenti di righe può succedere che l'es-table passi un intero AppSearch come parametro di ricerca,
|
|
272
|
+
* in quel caso l'applicazione ricevente dovrà onorare la richiesta spedendo al backand l'oggetto di ricerca AS-IS
|
|
273
|
+
*
|
|
274
|
+
* il tipo dell'Emitter invece di essere [boolean | AppSearch<any>] è stato impostato a "any" per evitare problemi di retrocompatibilità
|
|
275
|
+
*/
|
|
276
|
+
this.onSearchRequest = new EventEmitter();
|
|
277
|
+
/** Evento che parte ad ogni modifica di "checkaggio" in forma di comodo array. Espone l'oggetto con lo stato di check attuale */
|
|
278
|
+
this.onSelectionChanged = new EventEmitter();
|
|
279
|
+
/** Evento richiamato all'eliminazione di un oggetto */
|
|
280
|
+
this.onRemoval = new EventEmitter();
|
|
281
|
+
/** Evento richiamato all'annullamento di un'eliminazione */
|
|
282
|
+
this.onAbortRemoval = new EventEmitter();
|
|
283
|
+
/** Evento richiamato al click su una cella quando **UseCustomCellActions** è attivo
|
|
284
|
+
*
|
|
285
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
286
|
+
*/
|
|
287
|
+
this.onCellClick = new EventEmitter();
|
|
288
|
+
/** Evento richiamato quando si clicca su un opzione definita nelle **CornerMenuOptions** */
|
|
289
|
+
this.onCornerAction = new EventEmitter();
|
|
290
|
+
/** Evento richiamato quando si clicca su un opzione definita nelle **DynamicOperations** */
|
|
291
|
+
this.onDynamicOperation = new EventEmitter();
|
|
292
|
+
/** Pagina in visualizzazione (durante la paginazione in modalità Array) */
|
|
293
|
+
this.arraymodePage = 1;
|
|
294
|
+
/** Numero di pagine (durante la paginazione in modalità Array) */
|
|
295
|
+
this.arraymodePages = 1;
|
|
296
|
+
/** Oggetti per ogni pagina (durante la paginazione in modalità Array) */
|
|
297
|
+
this.ArraymodeItemsPerPage = null;
|
|
298
|
+
/** Colonne da visualizzare in modalità array */
|
|
299
|
+
this.arrayColumns = [];
|
|
300
|
+
/** Ordine delle colonne da visualizzare in modalità array */
|
|
301
|
+
this.arrayColumnOrdering = [];
|
|
302
|
+
/** Ordinamenti ASC-DESC sulle colonne in modalità array */
|
|
303
|
+
this.arrayOrders = [];
|
|
304
|
+
/**
|
|
305
|
+
* Variabile che serve a gestire il momento in cui l'es-table aggiorna la paginazione (pulsanti ecc).
|
|
306
|
+
* Essendo operazioni comunque costose le effettuo solo su binding esterni, non su rewrite generati internamente
|
|
307
|
+
*/
|
|
308
|
+
this.internalWriteCall = false;
|
|
309
|
+
/**
|
|
310
|
+
* Cache che conterrà tutte le ricerche effettuate su gruppi diversi dal primo e su elementi contenuti nei gruppi.
|
|
311
|
+
* In caso di cambi di ordinamento delle colonne diverse dalla prima tutte le chiamate fatte dal secondo livello in poi devono essere rieseguite secondo la seguente logica:
|
|
312
|
+
*
|
|
313
|
+
*
|
|
314
|
+
* **Cambio ordinamento sul primo gruppo**: reload completo, non mi occupo di ripulire gli elementi bindati in alcun modo
|
|
315
|
+
*
|
|
316
|
+
* **Cambio ordinamento sulla colonna relativa all'N-esimo gruppo**: reload completo del contenuto dei gruppi precedenti, ripulendo precedentemente
|
|
317
|
+
* tutti gli elementi con **_grouplevel** = N
|
|
318
|
+
*
|
|
319
|
+
* **Cambio ordinamento su una colonna non raggruppata**: reload completo per tutti i gruppi finali aperti, devo precedentemente ripulire tutti gli elementi con **_item** = true
|
|
320
|
+
*
|
|
321
|
+
* Altri eventi non dovrebbero rappresentare problemi:
|
|
322
|
+
* - Selezione: non cambia nulla
|
|
323
|
+
* - Paginazione: cambia a livello root quindi viene ricaricato tutto comunque, stesso vale per le paginazioni interne
|
|
324
|
+
*/
|
|
325
|
+
this.groupSearchRequestsCache = [];
|
|
326
|
+
/** Variabile d'appoggio per capire se c'è bisogno di ri-effettuare una ricerca o meno */
|
|
327
|
+
this.ResearchNeeded = false;
|
|
328
|
+
/** Colonne visibili della vista attuale. Valorizzato di default al numero massimo di colonne supportate dalla tabella per le casistiche in assenza di custom cells */
|
|
329
|
+
this.Columns = { Visibile: 100, VisibleUnpinned: 100, Global: 100 };
|
|
330
|
+
/** In caso di Row Grouping qui viene salvata la vista principale dei gruppi base */
|
|
331
|
+
this.MainGroupView = null;
|
|
332
|
+
/** Conteggio base degli oggetti. In modalità normale viene resettato ad ogni nuova View inserita, in modalità RowGrouping viene resettato solo ad una nuova View di livello "0" */
|
|
333
|
+
this.BaseItemsCount = null;
|
|
334
|
+
/** Indica se nonostante siamo in modalità array sono stati individuati dei gruppi. In tal caso es-table si comporta da pseudo backend ed effettua le aggregazioni e raggruppamenti completamente lato client */
|
|
335
|
+
this.ArrayGrouping = false;
|
|
336
|
+
/** Opzioni di paginazione */
|
|
337
|
+
this.PagerOptions = { PagerCount: null, ShowCount: true, ShowPaging: true, ShowButtons: true, ShowPagingOptions: true, UsesView: true, View: null, Ready: false, Searches: 'items' };
|
|
338
|
+
/** @ignore */
|
|
339
|
+
this.propagateChange = (_) => { };
|
|
340
|
+
/** Funzione di trackby per il body che dovrebbe evitare il 90% delle change detection */
|
|
341
|
+
this.bodyTrackBy = (index, item) => item._hash;
|
|
342
|
+
this.export_H = new ExportHandler(this, this.expExts, this.msgExts);
|
|
343
|
+
this.rowGrouping_H = new RowGroupingHandler(this, this.utilities_H, this.dateExts);
|
|
344
|
+
this.columnMetadata_H = new ColumnMetadataHandler(this, this.utilities_H, this.utiExts, this.prefService, this.rowGrouping_H);
|
|
345
|
+
this.dynamicMode_H = new DynamicModeHandler(this);
|
|
346
|
+
this.hierarchyMode_H = new HierarchyModeHandler(this);
|
|
347
|
+
this.items_H = new ItemsHandler(this, this.utilities_H);
|
|
348
|
+
this.reportMode_H = new ReportModeHandler(this, this.utilities_H);
|
|
349
|
+
this.selection_H = new SelectionHandler(this, this.rowGrouping_H);
|
|
350
|
+
if (ngControl)
|
|
351
|
+
ngControl.valueAccessor = this;
|
|
352
|
+
// Assegnazione per tutti gli Input di default
|
|
353
|
+
this.ColumnsResizable = this.utilities_H.InputOrDefault(this.ColumnsResizable, (_a = this.deafults) === null || _a === void 0 ? void 0 : _a.ColumnsResizable);
|
|
354
|
+
this.AutoUpdate = this.utilities_H.InputOrDefault(this.AutoUpdate, (_b = this.deafults) === null || _b === void 0 ? void 0 : _b.AutoUpdate);
|
|
355
|
+
this.AllSearch = this.utilities_H.InputOrDefault(this.AllSearch, (_c = this.deafults) === null || _c === void 0 ? void 0 : _c.AllSearch, true);
|
|
356
|
+
this.Export = this.utilities_H.InputOrDefault(this.Export, (_d = this.deafults) === null || _d === void 0 ? void 0 : _d.Export);
|
|
357
|
+
this.HidePaging = this.utilities_H.InputOrDefault(this.HidePaging, (_e = this.deafults) === null || _e === void 0 ? void 0 : _e.HidePaging, false);
|
|
358
|
+
this.HidePagingCount = this.utilities_H.InputOrDefault(this.HidePagingCount, (_f = this.deafults) === null || _f === void 0 ? void 0 : _f.HidePagingCount);
|
|
359
|
+
this.HidePagingButtons = this.utilities_H.InputOrDefault(this.HidePagingButtons, (_g = this.deafults) === null || _g === void 0 ? void 0 : _g.HidePagingButtons);
|
|
360
|
+
this.ContainerClass = this.utilities_H.InputOrDefault(this.ContainerClass, (_h = this.deafults) === null || _h === void 0 ? void 0 : _h.ContainerClass, '');
|
|
361
|
+
this.TableClass = this.utilities_H.InputOrDefault(this.TableClass, (_j = this.deafults) === null || _j === void 0 ? void 0 : _j.TableClass, 'table table-striped table-hover table-sm');
|
|
362
|
+
this.Selection = this.utilities_H.InputOrDefault(this.Selection, (_k = this.deafults) === null || _k === void 0 ? void 0 : _k.Selection);
|
|
363
|
+
this.SavePreferences = this.utilities_H.InputOrDefault(this.SavePreferences, (_l = this.deafults) === null || _l === void 0 ? void 0 : _l.SavePreferences);
|
|
364
|
+
this.PagingStyle = this.utilities_H.InputOrDefault(this.PagingStyle, (_m = this.deafults) === null || _m === void 0 ? void 0 : _m.PagingStyle, 'bottom');
|
|
365
|
+
this.RowGroupingPagingStyle = this.utilities_H.InputOrDefault(this.RowGroupingPagingStyle, (_o = this.deafults) === null || _o === void 0 ? void 0 : _o.RowGroupingPagingStyle, 'left');
|
|
366
|
+
this.UseSelectionCache = this.utilities_H.InputOrDefault(this.UseSelectionCache, (_p = this.deafults) === null || _p === void 0 ? void 0 : _p.UseSelectionCache, true);
|
|
367
|
+
this.ShowItemGroupsColumns = this.utilities_H.InputOrDefault(this.ShowItemGroupsColumns, (_q = this.deafults) === null || _q === void 0 ? void 0 : _q.ShowItemGroupsColumns, false);
|
|
368
|
+
this.ArraymodeItemsPerPage = this.utilities_H.InputOrDefault(this.ArraymodeItemsPerPage, (_r = this.deafults) === null || _r === void 0 ? void 0 : _r.ArraymodeItemsPerPage, 15);
|
|
369
|
+
}
|
|
370
|
+
/** @ignore */
|
|
371
|
+
ngOnInit() {
|
|
372
|
+
//Per poter cambiare il layout in base al livello gerarchico il componente deva avere il pieno controllo di ogni cella,
|
|
373
|
+
//che con solo la proiezione (senza celle cusotm) non è disponibile
|
|
374
|
+
if (this.Hierarchy && !this.UseCustomCells)
|
|
375
|
+
throw "Es-table error: Per poter utilizzare l'es-table con [Hierarchy]=\"true\" è richiesto anche [UseCustomCells]=\"true\"";
|
|
376
|
+
// click destro su una riga con selezione attiva: Tiro fuori il context menu e selezione l'elemento corrente
|
|
377
|
+
this.ctxMenuSubscription = (this.ContextMenu || this.tableEmptyMenu).open.subscribe(t => {
|
|
378
|
+
// Gruppi va bene, oggetti pure, ma separatori fra gruppi proprio no...
|
|
379
|
+
if (t.item._sep)
|
|
380
|
+
return;
|
|
381
|
+
let shouldEmit = !t.item._selected;
|
|
382
|
+
t.item._selected = true;
|
|
383
|
+
var itemSelection = this.selection_H.handleItemsSelection([t.item]);
|
|
384
|
+
this.changed();
|
|
385
|
+
if (shouldEmit)
|
|
386
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
/** @ignore */
|
|
390
|
+
ngAfterViewInit() {
|
|
391
|
+
// Se utilizzo la new spicy mode deduco tutti i parametri di lavoro possibili al caricamento della tabella
|
|
392
|
+
// Vengono sovrascritte solo le proprietà non impostate dall'utente
|
|
393
|
+
if (this.EsTdsDirective && this.EsTdsDirective.length > 0 && this.EsThsDirective && this.EsThsDirective.length > 0) {
|
|
394
|
+
if (this.UseCustomCells == null)
|
|
395
|
+
this.UseCustomCells = true;
|
|
396
|
+
if (this.HiddenColumns == null && this.UseCustomCells)
|
|
397
|
+
this.HiddenColumns = true;
|
|
398
|
+
if (this.ColumnsOrdering == null && this.UseCustomCells)
|
|
399
|
+
this.ColumnsOrdering = true;
|
|
400
|
+
if (this.OrderByColumn == null && this.UseCustomCells)
|
|
401
|
+
this.OrderByColumn = true;
|
|
402
|
+
if (this.SelectAll == null && this.Selection)
|
|
403
|
+
this.SelectAll = true;
|
|
404
|
+
if (this.ShiftClick == null && this.Selection)
|
|
405
|
+
this.ShiftClick = true;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/** @ignore */
|
|
409
|
+
ngOnDestroy() {
|
|
410
|
+
if (this.ctxMenuSubscription)
|
|
411
|
+
this.ctxMenuSubscription.unsubscribe();
|
|
412
|
+
}
|
|
413
|
+
/** @ignore */
|
|
414
|
+
ngOnChanges(changes) {
|
|
415
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
416
|
+
let newSearchView = changes['SearchView'];
|
|
417
|
+
if (newSearchView && this.SearchView)
|
|
418
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
/** @ignore */
|
|
422
|
+
registerOnChange(fn) { this.propagateChange = fn; }
|
|
423
|
+
/** @ignore */
|
|
424
|
+
registerOnTouched(fn) { }
|
|
425
|
+
/** @ignore */
|
|
426
|
+
changed() { this.propagateChange(this.View); }
|
|
427
|
+
/** @ignore */
|
|
428
|
+
writeValue(obj) {
|
|
429
|
+
var _a;
|
|
430
|
+
this.View = obj ? obj : null;
|
|
431
|
+
// Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
|
|
432
|
+
this.researchInProgress = false;
|
|
433
|
+
if (!this.View && !this.SearchView) {
|
|
434
|
+
// Su view nulla evito di fare pressoché qualsiasi cosa. Se arriva un null devo anche assicurarmi di non mostrare nulla
|
|
435
|
+
this.boundSource = this.TMPBoundSource || [];
|
|
436
|
+
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
437
|
+
this.cdr.markForCheck();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
// Se per sbaglio l'oggetto che mi arriva non è tipizzato (instanceof AppSearch restituisce false anche se è del tipo giusto)
|
|
441
|
+
// lo correggo--------------------------------------------------------------------------------------------------------------
|
|
442
|
+
if (this.View && typeof this.View.result != 'undefined' && !(this.View instanceof ReportDefinition))
|
|
443
|
+
this.View.__proto__ = new ReportDefinition();
|
|
444
|
+
else if (this.View && typeof this.View.itemsperpageoverride != 'undefined' && !(this.View instanceof AppSearch))
|
|
445
|
+
this.View.__proto__ = new AppSearch();
|
|
446
|
+
else if (this.SearchView && typeof this.SearchView.itemsperpageoverride != 'undefined' && !(this.SearchView instanceof AppSearch))
|
|
447
|
+
this.SearchView.__proto__ = new AppSearch();
|
|
448
|
+
// -------------------------------------------------------------------------------------------------------------------------
|
|
449
|
+
if (this.View && this.View instanceof ReportDefinition) {
|
|
450
|
+
// Se mi arriva una report definition vuol dire che potrei avere dei risultati da visualizzare
|
|
451
|
+
this.setMode('report');
|
|
452
|
+
this.ReportValues = this.View.result;
|
|
453
|
+
if (this.ReportValues)
|
|
454
|
+
this.reportMode_H.reviewReportBindings();
|
|
455
|
+
}
|
|
456
|
+
else if (this.View && this.View instanceof AppSearch) {
|
|
457
|
+
// Se cambia l'oggetto intero significa che ho rimandato la ricerca
|
|
458
|
+
this.setMode('view');
|
|
459
|
+
let firstItemGroupOrNoGrouping = (((_a = this.View.requestedgroups) === null || _a === void 0 ? void 0 : _a.length) || 0) == 0;
|
|
460
|
+
// Se vengo da una ricerca interna mantengo lo stato di selezione precedente (quindi su cambio pagina, cambio ipp, ecc...)
|
|
461
|
+
// se invece l'utente ha fatto una ricerca lui (quindi cambiando filtri), secco le info di selezione
|
|
462
|
+
if (!this.View.selection || (!this.View.internalsearchrequest && firstItemGroupOrNoGrouping) || !this.UseSelectionCache) {
|
|
463
|
+
this.selection_H.clearSelectionCaches();
|
|
464
|
+
this.View.selection = new ItemsSelection([]);
|
|
465
|
+
this.onSelectionChanged.emit(this.View.selection);
|
|
466
|
+
}
|
|
467
|
+
this.View.internalsearchrequest = false;
|
|
468
|
+
// Recupero Preference
|
|
469
|
+
if (this.SavePreferences) {
|
|
470
|
+
if (!this.ngControl.name)
|
|
471
|
+
console.error("Non posso utilizzare le preference senza avere un 'name' per questa tabella");
|
|
472
|
+
else if (!this.prefService)
|
|
473
|
+
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
474
|
+
else {
|
|
475
|
+
this.prefService.retrieve(this.ngControl.name).subscribe(prefs => {
|
|
476
|
+
if (prefs) {
|
|
477
|
+
this.View.columns = prefs.columns;
|
|
478
|
+
this.View.column_ordering = prefs.column_ordering;
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
// La paginazione devo farla solamente quando richiedo o un gruppo principale (se sono in row grouping) o se non richiedo gruppi (in tutti lgi altri casi)
|
|
484
|
+
if (firstItemGroupOrNoGrouping)
|
|
485
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.View.page, this.View.pages || 1, this.View.items.length, this.View.itemsperpageoverride);
|
|
486
|
+
}
|
|
487
|
+
else if (this.View && (this.View.length != null && this.View.length != undefined)) {
|
|
488
|
+
this.setMode('array');
|
|
489
|
+
if (!this.UseSelectionCache || !this.arraymodeSelection) {
|
|
490
|
+
this.selection_H.clearSelectionCaches();
|
|
491
|
+
this.arraymodeSelection = new ItemsSelection([]);
|
|
492
|
+
this.onSelectionChanged.emit(this.arraymodeSelection);
|
|
493
|
+
}
|
|
494
|
+
// Recupero Preference
|
|
495
|
+
if (this.SavePreferences) {
|
|
496
|
+
if (!this.ngControl.name)
|
|
497
|
+
console.error("Non posso utilizzare le preference senza avere un 'name' per questa tabella");
|
|
498
|
+
else if (!this.prefService)
|
|
499
|
+
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
500
|
+
else {
|
|
501
|
+
this.prefService.retrieve(this.ngControl.name).subscribe(prefs => {
|
|
502
|
+
if (prefs) {
|
|
503
|
+
this.arrayColumns = prefs.columns;
|
|
504
|
+
this.arrayColumnOrdering = prefs.column_ordering;
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if (this.SearchView)
|
|
510
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
|
|
511
|
+
}
|
|
512
|
+
if (this.View && !(this.View instanceof ReportDefinition))
|
|
513
|
+
this.finalizeContext();
|
|
514
|
+
this.postBoundSourceCalculation();
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Successivamente al bind del nuovo input questa funzione si occupa di finalizzare tutti i parametri di funzionamento dell'es-table
|
|
518
|
+
* in base a Input - Modello, e qualsiasi altra cosa possa servire
|
|
519
|
+
*/
|
|
520
|
+
finalizeContext() {
|
|
521
|
+
let viewCasted = this.View;
|
|
522
|
+
/*
|
|
523
|
+
*Uso la tecnica di EndlessScroll se la variabile relativa è attiva e se
|
|
524
|
+
* 1) Ho un Array, oppure
|
|
525
|
+
* 2) Ho un AppSearch che sta cercando con paginazione "Tutto", oppure
|
|
526
|
+
* 3) Ho un AppSearch che sta cercando con paginazione diversa da "Tutto" ma con la variabile EndlessScrollOnlyForAll a false
|
|
527
|
+
*/
|
|
528
|
+
let isAppSearchWithIppMax = this.viewMode && viewCasted.itemsperpageoverride == this.defaultAllPageOverride;
|
|
529
|
+
let isAppSearchNoMaxIpp = this.viewMode && viewCasted.itemsperpageoverride != this.defaultAllPageOverride;
|
|
530
|
+
this.UseEndlessscroll = this.EndlessScroll && (this.arrayMode || isAppSearchWithIppMax || (isAppSearchNoMaxIpp && !this.EndlessScrollOnlyForAll));
|
|
531
|
+
let hasRowGroups = (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
|
|
532
|
+
// Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
|
|
533
|
+
if (this.arrayMode && hasRowGroups)
|
|
534
|
+
this.UseArrayModePaging = false;
|
|
535
|
+
// Riempimento della TMPBoundSource con gli oggetti che verranno poi mostrati ad interfaccia
|
|
536
|
+
if (this.UseEndlessscroll && !hasRowGroups) {
|
|
537
|
+
this.addedSlices = [];
|
|
538
|
+
this.boundSubSources = this.items_H.getItemSlices();
|
|
539
|
+
let firstSub = this.boundSubSources[0];
|
|
540
|
+
this.TMPBoundSource = firstSub ? firstSub : [];
|
|
541
|
+
if (firstSub)
|
|
542
|
+
this.addedSlices.push(0);
|
|
543
|
+
}
|
|
544
|
+
else
|
|
545
|
+
this.TMPBoundSource = this.items_H.getItemsByMode(false, !this.internalWriteCall);
|
|
546
|
+
// Se ho una gerarchia, assegno i livelli gerarchici alla TMPBoundSource
|
|
547
|
+
if (this.Hierarchy && !hasRowGroups)
|
|
548
|
+
this.hierarchyMode_H.assignHierarchyLevels(this.TMPBoundSource);
|
|
549
|
+
// L'hashing degli oggetti lo faccio a prescindere
|
|
550
|
+
this.utilities_H.calculateHash(this.TMPBoundSource);
|
|
551
|
+
// Assegno a una variabile mia l'eventuale override per la classe della riga
|
|
552
|
+
// Se poi sono in modalità gerarchica inietto anche la classe per la configurazione del livello della riga
|
|
553
|
+
if ((this.TMPBoundSource && this.RowClassAssigner) || this.Hierarchy) {
|
|
554
|
+
for (let i = 0; i < this.TMPBoundSource.length; i++) {
|
|
555
|
+
let item = this.TMPBoundSource[i];
|
|
556
|
+
item._rowClass = this.RowClassAssigner ? this.RowClassAssigner(item) : "";
|
|
557
|
+
item._rowClass += this.Hierarchy ? " est-row-lvl-" + item._level : "";
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/** Genera le informzioni di paginazione per la vista globale dell'es-table */
|
|
562
|
+
setupPagingInformations() {
|
|
563
|
+
var _a;
|
|
564
|
+
// Default che valgono di base, poi eventualmente moddati dalle funzioni sotto
|
|
565
|
+
this.PagerOptions.ShowCount = !this.HidePagingCount;
|
|
566
|
+
this.PagerOptions.ShowButtons = !this.HidePagingButtons;
|
|
567
|
+
this.PagerOptions.ShowPaging = !this.HidePaging;
|
|
568
|
+
this.PagerOptions.UsesView = true;
|
|
569
|
+
if (this.arrayMode && this.UseArrayModePaging && !this.SearchView) {
|
|
570
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
571
|
+
this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && this.View.length > 10;
|
|
572
|
+
this.PagerOptions.View = this.View;
|
|
573
|
+
this.PagerOptions.UsesView = false;
|
|
574
|
+
this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
|
|
575
|
+
}
|
|
576
|
+
else if (this.arrayMode && (!this.UseArrayModePaging || this.SearchView)) {
|
|
577
|
+
if (this.SearchView) {
|
|
578
|
+
this.PagerOptions.View = this.SearchView;
|
|
579
|
+
this.PagerOptions.PagerCount = this.SearchView.objectcount || 0;
|
|
580
|
+
}
|
|
581
|
+
else
|
|
582
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
583
|
+
this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && (this.View.length > 10 || (((_a = this.SearchView) === null || _a === void 0 ? void 0 : _a.objectcount) || 0) > 10);
|
|
584
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
|
|
585
|
+
this.PagerOptions.ShowPaging = this.PagerOptions.ShowButtons || this.PagerOptions.ShowCount;
|
|
586
|
+
this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
|
|
587
|
+
}
|
|
588
|
+
else if (this.viewMode) {
|
|
589
|
+
let tmpView = this.MainGroupView || this.View;
|
|
590
|
+
let count = (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) || (tmpView === null || tmpView === void 0 ? void 0 : tmpView.objectcount);
|
|
591
|
+
this.PagerOptions.Searches = (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) != null && (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) != undefined ? 'groups' : 'items';
|
|
592
|
+
this.PagerOptions.PagerCount = count || 0;
|
|
593
|
+
this.PagerOptions.View = tmpView;
|
|
594
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (tmpView && count && count != -1);
|
|
595
|
+
}
|
|
596
|
+
else if (this.reportMode) {
|
|
597
|
+
let rvc = this.ReportValues.count;
|
|
598
|
+
this.PagerOptions.View = this.View;
|
|
599
|
+
this.PagerOptions.PagerCount = rvc && rvc == -1 ? this.ReportValues.rows.length : rvc && rvc > 0 ? this.ReportValues.count : 0;
|
|
600
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.result.count != -1);
|
|
601
|
+
this.PagerOptions.ShowButtons = this.PagerOptions.ShowButtons && (this.View.pagingavailable || this.PagerOptions.ShowCount);
|
|
602
|
+
this.PagerOptions.ShowPagingOptions = this.PagerOptions.ShowButtons;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Metodo che gestisce l'endless scroll e in base a quanto la tabella è stata scrollata aggiunge degli elementi extra a **TMPBoundSource**
|
|
607
|
+
*
|
|
608
|
+
* @param {any} e Evento di scroll del browser
|
|
609
|
+
*/
|
|
610
|
+
onScroll(e) {
|
|
611
|
+
let tableViewHeight = e.target.offsetHeight;
|
|
612
|
+
let tableScrollHeight = e.target.scrollHeight;
|
|
613
|
+
let scrollLocation = e.target.scrollTop;
|
|
614
|
+
let buffer = 200;
|
|
615
|
+
let limit = tableScrollHeight - tableViewHeight - buffer;
|
|
616
|
+
if (scrollLocation > limit) {
|
|
617
|
+
let indexToAdd = Math.floor(this.TMPBoundSource.length / 100);
|
|
618
|
+
if (this.boundSubSources[indexToAdd] && this.addedSlices.indexOf(indexToAdd) == -1) {
|
|
619
|
+
// Devo ricordarmi di fare l'hash del nuovo pezzo
|
|
620
|
+
this.utilities_H.calculateHash(this.boundSubSources[indexToAdd]);
|
|
621
|
+
this.TMPBoundSource = this.TMPBoundSource.concat(this.boundSubSources[indexToAdd]);
|
|
622
|
+
this.addedSlices.push(indexToAdd);
|
|
623
|
+
setTimeout(() => { this.postBoundSourceCalculation(); });
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Metodo lanciato dopo che la sorgente dati è stata correttamente bindata, si occupa di ricalcolare tutto ciò che serve
|
|
629
|
+
* all'es-table per renderizzare i valori da mostrare
|
|
630
|
+
*/
|
|
631
|
+
postBoundSourceCalculation() {
|
|
632
|
+
// Resetto tutto tranne RowTDs e RowTHs per evitare flickering. RowTDs e RowTHs saranno modificate all'interno del prossimo ciclo di CD
|
|
633
|
+
this.RowContexts = [];
|
|
634
|
+
this.OrderDirectives = [];
|
|
635
|
+
this.lastSelectedItemID = null;
|
|
636
|
+
if (this.EsThsDirective && this.EsThsDirective.length > 0 && this.EsTdsDirective && this.EsTdsDirective.length > 0)
|
|
637
|
+
this.internalPostBoundSource();
|
|
638
|
+
else {
|
|
639
|
+
this.cdr.detectChanges();
|
|
640
|
+
setTimeout(() => { this.internalPostBoundSource(); });
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/** Per poter distinguere le chiamate a questo metodo: Dopo il setTimeout se uso gli EsTd/EsTh vecchi, senza il setTimeout se uso le nuove direttive */
|
|
644
|
+
internalPostBoundSource() {
|
|
645
|
+
let View = this.View;
|
|
646
|
+
let ths = this.EsThs && this.EsThs.length > 0 ? this.EsThs.toArray() : this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
|
|
647
|
+
let tds = this.EsTds && this.EsTds.length > 0 ? this.EsTds.toArray() : this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
|
|
648
|
+
// Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
|
|
649
|
+
this.dynamicMode_H.eventuallyReviewDynamicColumns();
|
|
650
|
+
this.bindDisplayToLoadedItemsOrGroups(View);
|
|
651
|
+
// Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
|
|
652
|
+
this.setupPagingInformations();
|
|
653
|
+
// Molte cose sono ovviamente disponibili solo in modalità View
|
|
654
|
+
if ((this.viewMode || this.arrayMode) && this.UseCustomCells) {
|
|
655
|
+
let view = this.viewMode ? View : null;
|
|
656
|
+
let itemsAndGroups = this.viewMode ? [...(view.items || []), ...(view.groups || [])] : View;
|
|
657
|
+
let si = this.viewMode ? view.selection : this.arraymodeSelection;
|
|
658
|
+
// N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
|
|
659
|
+
// ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
|
|
660
|
+
// Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
|
|
661
|
+
let hI = this.columnMetadata_H.evaluateHeadersGroupingInfos(ths);
|
|
662
|
+
if (this.arrayMode) { // In modalità array non ho un backend...
|
|
663
|
+
this.items_H.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
|
|
664
|
+
this.rowGrouping_H.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
|
|
665
|
+
}
|
|
666
|
+
this.columnMetadata_H.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
|
|
667
|
+
this.columnMetadata_H.moveFixedColumnsAtTheBeginning(hI.leafs, tds); // Sposto tutte le cose fixed all'inizio in modo che la creazione di th e td sia più snella (Utilizza le ColumnsList, quindi dev'essere richiamata PIRMA di reviewColumnsList)
|
|
668
|
+
this.columnMetadata_H.alignHeadersOrdering(hI.leafs, view); // Allineo gli ordinamenti agli header
|
|
669
|
+
this.columnMetadata_H.alignColumnsIfLoadedView(view); // Se sto caricando una View da hotpotato (quindi con savedstate = true) riallineo la visibilità delle colonne e il loro ordine.
|
|
670
|
+
this.columnMetadata_H.refreshColumnsVisibility(hI.leafs, tds, view); // Lavoro sui TH ed eventualmente modifico la visibilità anche dei TD.
|
|
671
|
+
this.columnMetadata_H.evaluatePinnedColumnsWidth(); // Se sono presenti colonne pinnate valuta la dimensione del contenitore
|
|
672
|
+
this.columnMetadata_H.generateDefaultOrder(hI.leafs, view); // Genero le direttive di ordinamento, che siano default o derivanti dalla AppSearch
|
|
673
|
+
this.columnMetadata_H.evaluateHeaderGroups(hI); // Valuto i raggruppamenti degli header se presenti
|
|
674
|
+
// ************************************* Generazione binding per righe e colonne *************************************
|
|
675
|
+
this.evaluateRowThs(hI.leafs); // Raccolgo i TH
|
|
676
|
+
this.evaluateRowTds(hI.leafs, tds); // Raccolgo i TD in contesti separati, un contesto per ogni item o gruppo
|
|
677
|
+
// ************************************* Ultimi aggiustmaenti dei binding *************************************
|
|
678
|
+
this.columnMetadata_H.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
|
|
679
|
+
this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
|
|
680
|
+
this.selection_H.evaluateSelection(itemsAndGroups, si); // Riallineo le info di selezione degli elementi della View
|
|
681
|
+
if (this.ResearchNeeded) {
|
|
682
|
+
this.changed();
|
|
683
|
+
this.emitSearchRequest(false);
|
|
684
|
+
this.ResearchNeeded = false;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
else if ((this.viewMode || this.arrayMode) && !this.UseCustomCells) {
|
|
688
|
+
// Riallineo le info di selezione degli elementi della View
|
|
689
|
+
let items = this.viewMode ? View.items : View;
|
|
690
|
+
let si = this.viewMode ? View.selection : this.arraymodeSelection;
|
|
691
|
+
this.selection_H.evaluateSelection(items, si);
|
|
692
|
+
}
|
|
693
|
+
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
694
|
+
this.cdr.markForCheck();
|
|
695
|
+
this.FirstBind = false;
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Effettua il binding degli oggetti pervenuti da questa chiamata con gli oggetti effettivamente da graficare
|
|
699
|
+
*
|
|
700
|
+
* @param {any} view View da cui sono arrivati gli oggetti. Può essere o un array se sono in **arrayMode** o una AppSearch<T> se sono in **viewMode**
|
|
701
|
+
*/
|
|
702
|
+
bindDisplayToLoadedItemsOrGroups(view) {
|
|
703
|
+
var _a, _b;
|
|
704
|
+
if (this.TMPBoundSource.length == 0) {
|
|
705
|
+
this.BaseItemsCount = 0;
|
|
706
|
+
this.boundSource = this.TMPBoundSource;
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (this.arrayMode || !this.UseCustomCells) {
|
|
710
|
+
this.boundSource = this.TMPBoundSource;
|
|
711
|
+
this.BaseItemsCount = (view === null || view === void 0 ? void 0 : view.objectcount) || view.length;
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
let groupingKeys = ((_b = (_a = view.groupings) === null || _a === void 0 ? void 0 : _a.filter(t => !t.aggregation)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
715
|
+
if (groupingKeys == 0) {
|
|
716
|
+
this.boundSource = this.TMPBoundSource;
|
|
717
|
+
this.BaseItemsCount = view.objectcount;
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
this.rowGrouping_H.handleNewDataOnRowGrouping(view, groupingKeys);
|
|
721
|
+
}
|
|
722
|
+
/** Metodo richiamato solo quando **TMPRowTDs** e **TMPRowTHs** sono completamente generati ed aggiustati. Serve per collegarli alle variabili usate lato binding HTML */
|
|
723
|
+
MoveTemporaryVariablesToRealOnes() {
|
|
724
|
+
this.RowTDs = this.TMPRowTDs;
|
|
725
|
+
this.RowTHs = this.TMPRowTHs;
|
|
726
|
+
this.RowThGroups = this.TMPRowThGroups ? this.TMPRowThGroups.reverse() : null;
|
|
727
|
+
this.Columns.Visibile = this.RowTHs.filter(t => t.Visible).length;
|
|
728
|
+
this.Columns.VisibleUnpinned = this.RowTHs.filter(t => t.Visible && !t.Pinned).length;
|
|
729
|
+
this.Columns.Global = this.Columns.VisibleUnpinned + (this.HasPinnedColumns ? 1 : 0) + (this.Selection ? 1 : 0) + (this.Removal ? 1 : 0) + (this.Export || this.HiddenColumns || this.ColumnsOrdering || this.CornerMenuOptions ? 1 : 0);
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Permette di selezionare o deselezionare in maniera arbitraria degli oggetti
|
|
733
|
+
*
|
|
734
|
+
* @param {any[]} items Oggetti da selezionare o deselezionare
|
|
735
|
+
* @param {boolean} select **true** per selezionarli, **false** per non toccarli
|
|
736
|
+
*/
|
|
737
|
+
setSelectionStatus(items, select) {
|
|
738
|
+
this.selection_H.handleItemsSelection(items, select);
|
|
739
|
+
this.cdr.markForCheck();
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Metodo che gestisce il cambio di Ordinamento di una colonna
|
|
743
|
+
*
|
|
744
|
+
* @param {string} id ID della colonna il cui oridnamento è cambiato
|
|
745
|
+
* @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
|
|
746
|
+
*/
|
|
747
|
+
thOrderChanged(id, order) {
|
|
748
|
+
if (!this.viewMode && !this.arrayMode) {
|
|
749
|
+
console.warn('Order changed on a table not in viewMode or Array mode. Operation not supported');
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if (!this.OrderByColumn)
|
|
753
|
+
return;
|
|
754
|
+
this.columnMetadata_H.handleTHOrderChange(id, order);
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Metodo da chiamare ogni volta che si vuole dare evidenza all'esterno del bisogno di rieffettuare la ricerca
|
|
758
|
+
*
|
|
759
|
+
* @param {boolean} resetsPage Indica al listener che deve resettare il numero di pagina
|
|
760
|
+
* @param {AppSearch<any>} viewOverride Override della view da emettere per questa ricerca
|
|
761
|
+
*/
|
|
762
|
+
emitSearchRequest(resetsPage, viewOverride) {
|
|
763
|
+
if (this.viewMode && !viewOverride) {
|
|
764
|
+
this.View.internalsearchrequest = true;
|
|
765
|
+
this.changed();
|
|
766
|
+
}
|
|
767
|
+
if (viewOverride) {
|
|
768
|
+
if (resetsPage)
|
|
769
|
+
viewOverride.page = 1;
|
|
770
|
+
viewOverride.internalsearchrequest = true;
|
|
771
|
+
}
|
|
772
|
+
this.researchInProgress = true;
|
|
773
|
+
this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
|
|
777
|
+
*
|
|
778
|
+
* Vengono esclusi i TD "Interni" in quanto vengono generati dagli originali quindi includerli vorrebbe dire rieffettuare le operazioni due volte
|
|
779
|
+
*
|
|
780
|
+
* Costo: 2 scan EsThs, 1 scan EsTds
|
|
781
|
+
*
|
|
782
|
+
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
783
|
+
* @param {EsTd[] | EsTdDirective[]} tds Celle della tabella
|
|
784
|
+
*/
|
|
785
|
+
evaluateRowTds(ths, tds) {
|
|
786
|
+
if (tds.length == 0)
|
|
787
|
+
return;
|
|
788
|
+
let thsCache = {};
|
|
789
|
+
let columnsCache = {};
|
|
790
|
+
for (let coli = 0; coli < this.ColumnsList.length; coli++) {
|
|
791
|
+
let col = this.ColumnsList[coli];
|
|
792
|
+
columnsCache[col.id] = col;
|
|
793
|
+
}
|
|
794
|
+
for (let i = 0; i < ths.length; i++) {
|
|
795
|
+
let th = ths[i];
|
|
796
|
+
thsCache[this.utilities_H.isEsTh(th) ? th.ID : th.th] = th;
|
|
797
|
+
}
|
|
798
|
+
this.TMPRowTDs = {};
|
|
799
|
+
// Variabile d'appoggio per permettermi di inserire tutte le colonne "Fixed" davanti
|
|
800
|
+
let contextFixeds = {};
|
|
801
|
+
for (let i = 0; i < tds.length; i++) {
|
|
802
|
+
let td = tds[i];
|
|
803
|
+
if (this.utilities_H.isEsTd(td)) {
|
|
804
|
+
let th = thsCache[td.ID];
|
|
805
|
+
if (!!th)
|
|
806
|
+
th._referenced = true;
|
|
807
|
+
else
|
|
808
|
+
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.ID;
|
|
809
|
+
let isFixed = (this.utilities_H.isEsTh(th) && th.Fixed) || (!this.utilities_H.isEsTh(th) && (th.thFixed || th.thGroup));
|
|
810
|
+
let itemToAdd = { GroupAggregation: false, GroupHeader: false, Wraps: true, ID: td.ID, Visible: td.Visible, Class: td.Class, Content: td.Content, RouterLink: td.RouterLink, Template: td.Template };
|
|
811
|
+
let ctx = td.Context;
|
|
812
|
+
if (this.TMPRowTDs[ctx]) {
|
|
813
|
+
if (isFixed)
|
|
814
|
+
this.TMPRowTDs[ctx].splice(0 + (contextFixeds[ctx]++), 0, itemToAdd);
|
|
815
|
+
else
|
|
816
|
+
this.TMPRowTDs[ctx].push(itemToAdd);
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
819
|
+
this.RowContexts.push(ctx);
|
|
820
|
+
this.TMPRowTDs[ctx] = [itemToAdd];
|
|
821
|
+
contextFixeds[ctx] = isFixed ? 1 : 0;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
for (let i = 0; i < this.boundSource.length; i++) {
|
|
826
|
+
let item = this.boundSource[i];
|
|
827
|
+
let ctx = item._hash;
|
|
828
|
+
let key = td.td;
|
|
829
|
+
let th = thsCache[td.td];
|
|
830
|
+
if (!!th)
|
|
831
|
+
th._referenced = true;
|
|
832
|
+
else
|
|
833
|
+
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.td;
|
|
834
|
+
if (td.tdIf || (!this.utilities_H.isEsTh(th) && th.thGroup)) {
|
|
835
|
+
let thCasted = th;
|
|
836
|
+
let isFixed = (this.utilities_H.isEsTh(th) && th.Fixed) || (!this.utilities_H.isEsTh(th) && (th.thFixed || th.thGroup || th.thPinned));
|
|
837
|
+
let itemToAdd = item._item ?
|
|
838
|
+
{ LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: false, GroupAggregation: false, Visible: columnsCache[td.td].visible, Wraps: false, Class: td.tdClass, Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template } :
|
|
839
|
+
{ LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: thCasted.thGroup, GroupAggregation: !!thCasted.thAggregation, Visible: columnsCache[td.td].visible, Wraps: false, Class: thCasted.thGroupClass || '', Content: this.rowGrouping_H.getGroupCellDisplay(item, key, th) };
|
|
840
|
+
if (this.TMPRowTDs[ctx]) {
|
|
841
|
+
this.TMPRowTDs[ctx].push(itemToAdd);
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
this.RowContexts.push(ctx);
|
|
845
|
+
this.TMPRowTDs[ctx] = [itemToAdd];
|
|
846
|
+
contextFixeds[ctx] = isFixed ? 1 : 0;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
// Se non ho oggetti è inutile che controllo gli errori, dato che gli es-td non esisteranno di certo e di conseguenza gli es-th non saranno referenziati
|
|
853
|
+
if (this.TMPBoundSource.length == 0)
|
|
854
|
+
return;
|
|
855
|
+
var errs = [];
|
|
856
|
+
for (let i = 0; i < ths.length; i++) {
|
|
857
|
+
let th = ths[i];
|
|
858
|
+
if (!th._referenced)
|
|
859
|
+
errs.push(this.utilities_H.isEsTh(th) ? th.ID : th.th);
|
|
860
|
+
}
|
|
861
|
+
if (errs.length > 0) {
|
|
862
|
+
var errIds = errs.join(', ');
|
|
863
|
+
throw "L'ID di uno o più EsTh non hanno alcun EsTd associato: " + errIds;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Partendo dagli **EsThs** bindati genera, all'interno del dizionario **TMPRowTHs** tutti i contesti dei vari oggetti.
|
|
868
|
+
*
|
|
869
|
+
* Vengono esclusi i TH "Interni" in quanto vengono generati dagli originali quindi includerli vorrebbe dire rieffettuare le operazioni due volte
|
|
870
|
+
*
|
|
871
|
+
* Costo: 1 scan EsThs
|
|
872
|
+
*
|
|
873
|
+
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
874
|
+
*/
|
|
875
|
+
evaluateRowThs(ths) {
|
|
876
|
+
if (ths.length == 0)
|
|
877
|
+
return;
|
|
878
|
+
let columnsListCache = {};
|
|
879
|
+
let castedView = this.View;
|
|
880
|
+
let groupingsUndefined = this.viewMode && (castedView && !castedView.groupings || castedView.groupings.length == 0);
|
|
881
|
+
for (let i = 0; i < this.ColumnsList.length; i++) {
|
|
882
|
+
let itm = this.ColumnsList[i];
|
|
883
|
+
columnsListCache[itm.id] = itm;
|
|
884
|
+
}
|
|
885
|
+
this.TMPRowTHs = [];
|
|
886
|
+
let fixed = 0;
|
|
887
|
+
for (let i = 0; i < ths.length; i++) {
|
|
888
|
+
let th = ths[i];
|
|
889
|
+
let toAdd;
|
|
890
|
+
if (this.utilities_H.isEsTh(th)) {
|
|
891
|
+
toAdd = { Pinned: false, ID: th.ID, Visible: th.Visible, Class: th.Class, Order: th.Order, Orderable: th.Orderable, Template: null, Content: th.Description, Wrap: th.Wrap };
|
|
892
|
+
if (th.Fixed)
|
|
893
|
+
this.TMPRowTHs.splice(0 + (fixed++), 0, toAdd);
|
|
894
|
+
else
|
|
895
|
+
this.TMPRowTHs.push(toAdd);
|
|
896
|
+
}
|
|
897
|
+
else if (th.thIf || th.thGroup) {
|
|
898
|
+
let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
|
|
899
|
+
toAdd = { Pinned: columnsListCache[th.th].pinned, PinnedWidth: th.thPinnedWidth, ID: th.th, Visible: th.thVisible, Class: thClass, Order: th.thOrder, Orderable: th.thOrderable, Template: th.Template, Content: null, Wrap: th.thWrap, LeftBorder: th._lbord, RightBorder: th._rbord };
|
|
900
|
+
this.TMPRowTHs.push(toAdd);
|
|
901
|
+
// Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
|
|
902
|
+
// li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
|
|
903
|
+
if (groupingsUndefined && (th.thAggregation || th.thGroup)) {
|
|
904
|
+
let groupAggregations = this.rowGrouping_H.getGroupAggregations(th);
|
|
905
|
+
if (!castedView.groupings)
|
|
906
|
+
castedView.groupings = groupAggregations;
|
|
907
|
+
else
|
|
908
|
+
castedView.groupings.push(...groupAggregations);
|
|
909
|
+
this.ResearchNeeded = true;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Sposta la ricerca di una pagina in avanti (o indietro)
|
|
916
|
+
*
|
|
917
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
918
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
919
|
+
*/
|
|
920
|
+
addToPageGroup(page, pager) {
|
|
921
|
+
this.goToPageGroup(pager.view.page + page, pager);
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Sposta la ricerca alla pagina specificata
|
|
925
|
+
*
|
|
926
|
+
* @param {number} page Pagina a cui navigare
|
|
927
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
928
|
+
*/
|
|
929
|
+
goToPageGroup(page, pager) {
|
|
930
|
+
let appSearchElement = pager.view;
|
|
931
|
+
if (page === 0 || (page > appSearchElement.pages && appSearchElement.pages > 0))
|
|
932
|
+
return;
|
|
933
|
+
appSearchElement.page = page;
|
|
934
|
+
pager.buttons = this.utilities_H.getPagesArray(6, appSearchElement.page, appSearchElement.pages);
|
|
935
|
+
this.emitSearchRequest(false, appSearchElement);
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Gestisce i click sulla tabella solo per le righe a gruppo.
|
|
939
|
+
* O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
|
|
940
|
+
*
|
|
941
|
+
* @param {any} group Gruppo bindato su cui si è effettuato il click
|
|
942
|
+
*
|
|
943
|
+
* @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
|
|
944
|
+
*/
|
|
945
|
+
handleGroupClick(group) {
|
|
946
|
+
let casted = this.View;
|
|
947
|
+
let anyG = group;
|
|
948
|
+
anyG._expanded = !anyG._expanded;
|
|
949
|
+
// Sono in modalità raggruppamento virtuale da array: Espandere significa rendere visibili tutti gli oggetti relativi a questo gruppo, viceversa il contrarre
|
|
950
|
+
if (this.ArrayGrouping) {
|
|
951
|
+
let allRelatives = this.boundSource.filter(t => (t._group && ((anyG._expanded && t._parent == anyG._thisKey) || (!anyG._expanded && t._parent && t._parent.startsWith(anyG._thisKey)))) ||
|
|
952
|
+
(t._item && ((anyG._expanded && t._thisKey == anyG._thisKey) || (!anyG._expanded && t._thisKey.startsWith(anyG._thisKey)))));
|
|
953
|
+
allRelatives.forEach(t => { t._visible = anyG._expanded; if (t._group)
|
|
954
|
+
t._expanded = false; });
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
if (anyG._expanded) {
|
|
958
|
+
// Resetto ipp
|
|
959
|
+
casted.itemsperpageoverride = 15;
|
|
960
|
+
if (!casted.requestedgroups)
|
|
961
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
962
|
+
else {
|
|
963
|
+
let level = anyG._grouplevel;
|
|
964
|
+
// se il gruppo cliccato non ha un livello è il primo gruppo, quindi ordinamento unico
|
|
965
|
+
// altrimenti devo rimuovere tutti i filtri su livelli superiori al level cliccato e aggiungere il level cliccato
|
|
966
|
+
if (!level)
|
|
967
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
968
|
+
else {
|
|
969
|
+
casted.requestedgroups = [];
|
|
970
|
+
anyG._parentRoute.forEach((step) => {
|
|
971
|
+
casted.requestedgroups.push(new GroupFilter(step.column, step.value));
|
|
972
|
+
});
|
|
973
|
+
casted.requestedgroups.push(new GroupFilter(group.column, group.value));
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
this.changed();
|
|
977
|
+
this.emitSearchRequest(true);
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
let path = (anyG._parent || '') + group.value;
|
|
981
|
+
// Se ho chiuso un gruppo non mi serve rieffettuare ricerce, mi basta eliminare dagli oggetti bindati tutti gli elementi sottostanti a quel gruppo
|
|
982
|
+
this.boundSource = this.boundSource.filter(t => !t._parent || !t._parent.startsWith(path));
|
|
983
|
+
// devo però anche rimuovere eventuali cache relative
|
|
984
|
+
this.groupSearchRequestsCache = this.groupSearchRequestsCache.filter(t => t.path != path);
|
|
985
|
+
}
|
|
986
|
+
return true;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Gestisce la selezione globale degli oggetti, sia per pagina che a livello di **SelectAll**
|
|
990
|
+
*
|
|
991
|
+
* @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
|
|
992
|
+
*/
|
|
993
|
+
globalCheckChanged(forcedVal = null) {
|
|
994
|
+
// Prendo tutti gli elementi presenti in questa vista. Se ho gruppi prendo solo i gruppi a livello 0, altrimenti prendo tutti gli oggetti per selezionarli
|
|
995
|
+
let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
|
|
996
|
+
var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
|
|
997
|
+
this.changed();
|
|
998
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
|
|
1002
|
+
*
|
|
1003
|
+
* @param {any} event Evento nativo HTML del click
|
|
1004
|
+
* @param {any} item Oggetto bindato su cui si è effettuato il click
|
|
1005
|
+
*
|
|
1006
|
+
* @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
|
|
1007
|
+
*/
|
|
1008
|
+
handleClick(event, item) {
|
|
1009
|
+
// Seleziono del testo ma non ho shift premuto -> ignoro la selezione
|
|
1010
|
+
if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
|
|
1011
|
+
return false;
|
|
1012
|
+
// Seleziono del testo e ho shift premuto -> annullo la selezione del testo
|
|
1013
|
+
if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
|
|
1014
|
+
this.utiExts.clearTextSelection();
|
|
1015
|
+
let selecteditems = [];
|
|
1016
|
+
if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
|
|
1017
|
+
let startSelecting = false;
|
|
1018
|
+
let items = this.boundSource.filter(t => !t._group && !t._sep);
|
|
1019
|
+
for (let i = 0; i < items.length; i++) {
|
|
1020
|
+
let t = items[i];
|
|
1021
|
+
if (startSelecting) {
|
|
1022
|
+
t._selected = true;
|
|
1023
|
+
selecteditems.push(t);
|
|
1024
|
+
}
|
|
1025
|
+
if ((t == item || t == this.lastSelected) && !startSelecting) {
|
|
1026
|
+
startSelecting = true;
|
|
1027
|
+
t._selected = true;
|
|
1028
|
+
selecteditems.push(t);
|
|
1029
|
+
}
|
|
1030
|
+
else if ((t == item || t == this.lastSelected) && startSelecting)
|
|
1031
|
+
startSelecting = false;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
else {
|
|
1035
|
+
item._selected = !item._selected;
|
|
1036
|
+
this.lastSelected = item;
|
|
1037
|
+
selecteditems.push(item);
|
|
1038
|
+
}
|
|
1039
|
+
var itemSelection = this.selection_H.handleItemsSelection(selecteditems);
|
|
1040
|
+
this.changed();
|
|
1041
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
1042
|
+
return true;
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Sposta la ricerca di una pagina in avanti (o indeitro)
|
|
1046
|
+
*
|
|
1047
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1048
|
+
*/
|
|
1049
|
+
addToPage(page) {
|
|
1050
|
+
var _a;
|
|
1051
|
+
let view = this.MainGroupView ? this.MainGroupView : this.View;
|
|
1052
|
+
this.goToPage((((_a = (this.SearchView || view)) === null || _a === void 0 ? void 0 : _a.page) || 0) + page);
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Sposta la ricerca alla pagina specificata
|
|
1056
|
+
*
|
|
1057
|
+
* @param {number} page Pagina a cui navigare
|
|
1058
|
+
*/
|
|
1059
|
+
goToPage(page) {
|
|
1060
|
+
var _a, _b;
|
|
1061
|
+
let view = this.MainGroupView ? this.MainGroupView : (this.arrayMode ? this.SearchView : this.View);
|
|
1062
|
+
if (!view.page || !view.pages)
|
|
1063
|
+
return;
|
|
1064
|
+
let appSearchElement = this.SearchView || view;
|
|
1065
|
+
if (page === 0 || (page > appSearchElement.pages && appSearchElement.pages > 0))
|
|
1066
|
+
return;
|
|
1067
|
+
appSearchElement.page = page;
|
|
1068
|
+
let count = this.reportMode ? (((_a = view.result) === null || _a === void 0 ? void 0 : _a.count) || 0) : (view.items.length || ((_b = view.groups) === null || _b === void 0 ? void 0 : _b.length) || 0);
|
|
1069
|
+
let ipp = this.reportMode ? (view.itemsperpageoverride || 15) : view.itemsperpageoverride || 15;
|
|
1070
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, appSearchElement.page, appSearchElement.pages, count, ipp);
|
|
1071
|
+
let hasGroupings = !!this.MainGroupView;
|
|
1072
|
+
this.emitSearchRequest(false, hasGroupings ? view : this.SearchView ? this.SearchView : null);
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest**
|
|
1076
|
+
* per comunicare al componente che utilizza questa tabella che i dati sono da aggiornare
|
|
1077
|
+
*/
|
|
1078
|
+
onItemsPerPageChanged(newIpp) {
|
|
1079
|
+
this.PagerOptions.View.itemsperpageoverride = newIpp;
|
|
1080
|
+
this.changed();
|
|
1081
|
+
if (this.MainGroupView)
|
|
1082
|
+
this.emitSearchRequest(true, this.MainGroupView);
|
|
1083
|
+
else if (this.SearchView) {
|
|
1084
|
+
// Questo secondo me si può portare a livello un po' più alto
|
|
1085
|
+
this.SearchView.page = 1;
|
|
1086
|
+
this.emitSearchRequest(true, this.SearchView);
|
|
1087
|
+
}
|
|
1088
|
+
else
|
|
1089
|
+
this.emitSearchRequest(true);
|
|
1090
|
+
}
|
|
1091
|
+
/** Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest** con la vista del separatore */
|
|
1092
|
+
onGroupItemsPerPageChanged(pager, newIpp) {
|
|
1093
|
+
pager.view.itemsperpageoverride = newIpp;
|
|
1094
|
+
this.emitSearchRequest(true, pager.view);
|
|
1095
|
+
}
|
|
1096
|
+
/** Metodo che gestisce la modifica del tempo specificato per l'aggiornamento automatico */
|
|
1097
|
+
autoUpdateChanged() {
|
|
1098
|
+
if (!/^[1-9]\d*$/.test(this.seconds))
|
|
1099
|
+
this.seconds = '10';
|
|
1100
|
+
let secondsInMs = parseInt(this.seconds, null) * 1000;
|
|
1101
|
+
if (this.autoUpdate)
|
|
1102
|
+
this.updateTimer = setInterval(() => { this.emitSearchRequest(false); }, secondsInMs);
|
|
1103
|
+
else
|
|
1104
|
+
clearInterval(this.updateTimer);
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Metodo chiamato dal click su una delle colonne generate dall'Input **DynamicOperations**
|
|
1108
|
+
*
|
|
1109
|
+
* @param {any} item L'oggetto su cui va effettuata l'operazione
|
|
1110
|
+
* @param {string} opid Codice identificativo dell'operazione da effettuarsi
|
|
1111
|
+
*/
|
|
1112
|
+
dynamicOperation(item, opid) {
|
|
1113
|
+
this.onDynamicOperation.emit({ id: opid, item: item });
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Ottiene il contenuto dell'EsTd da utilizzare per la colonna specificata
|
|
1117
|
+
*
|
|
1118
|
+
* @param {string} column Colonna per cui cercare la cella
|
|
1119
|
+
*
|
|
1120
|
+
* @returns {TemplateRef<any>} Template da usare per la colonna
|
|
1121
|
+
*/
|
|
1122
|
+
findEsTd(column) {
|
|
1123
|
+
var EsTd = this.EsTdsDirective.find((item) => item.td === column);
|
|
1124
|
+
return EsTd ? EsTd.Template : null;
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Equivalente del metodo **addToPage** riadattato per la modalità array
|
|
1128
|
+
*
|
|
1129
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1130
|
+
*/
|
|
1131
|
+
arrayAddToPage(page) {
|
|
1132
|
+
this.arrayGoToPage(this.arraymodePage + page);
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Equivalente del metodo **goToPage** riadattato per la modalità array
|
|
1136
|
+
*
|
|
1137
|
+
* @param {number} page Pagina a cui navigare
|
|
1138
|
+
*/
|
|
1139
|
+
arrayGoToPage(page) {
|
|
1140
|
+
if (page === 0 || page > this.arraymodePages)
|
|
1141
|
+
return;
|
|
1142
|
+
this.arraymodePage = page;
|
|
1143
|
+
// Riforzo il writevalue in modo che il codice passi dalla gestione come se fosse fatta ripartire una ricerca
|
|
1144
|
+
this.internalWriteValue();
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Gestore dei click sulle celle per le quali era impostata una azione custom da **CustomCellActionsOn**
|
|
1148
|
+
*
|
|
1149
|
+
* @param {string} name Nome della cella su cui si è fatto click
|
|
1150
|
+
* @param {any} model Modello relativo alla cella cliccata
|
|
1151
|
+
*
|
|
1152
|
+
* @returns {boolean} **true** se il click è stato fatto su una cella cliccabile, **false** altrimenti
|
|
1153
|
+
*/
|
|
1154
|
+
cellClicked(name, model) {
|
|
1155
|
+
if (this.UseCustomCellActions && this.CustomCellActionsOn.split('$').indexOf(name) != -1) {
|
|
1156
|
+
this.onCellClick.emit({ column: name, model: model });
|
|
1157
|
+
return true;
|
|
1158
|
+
}
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Gestione dei click sulle opzioni del menù contestuale in alto a destra generato dall'Input **CornerMenuOptions**
|
|
1163
|
+
*
|
|
1164
|
+
* @param {string} cornerid Codice dell'operazione selezionata
|
|
1165
|
+
*/
|
|
1166
|
+
cornerActionClicked(cornerid) {
|
|
1167
|
+
this.onCornerAction.emit({ id: cornerid, estable: this });
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Impostazione modalità dell'EsTable
|
|
1171
|
+
*
|
|
1172
|
+
* @param {'array' | 'view' | 'report'} mode Modalità da impostare
|
|
1173
|
+
**/
|
|
1174
|
+
setMode(mode) {
|
|
1175
|
+
this.viewMode = mode == 'view';
|
|
1176
|
+
this.arrayMode = mode == 'array';
|
|
1177
|
+
this.reportMode = mode == 'report';
|
|
1178
|
+
if (this.reportMode) {
|
|
1179
|
+
// In modalità report ho di sicuro queste due
|
|
1180
|
+
this.XLSXExport = true;
|
|
1181
|
+
this.CSVExport = false;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Helper per effettuare chiamate interne di allineamento alla funzione **writeValue**,
|
|
1186
|
+
* impostando prima **internalWriteCall** in modo da non effettuare operazioni inutili
|
|
1187
|
+
*/
|
|
1188
|
+
internalWriteValue() {
|
|
1189
|
+
this.internalWriteCall = true;
|
|
1190
|
+
this.writeValue(this.View);
|
|
1191
|
+
this.internalWriteCall = false;
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Metodo eventualmente richiamabile anche dal componente esterno che permette di forzare un refresh della tabella
|
|
1195
|
+
*/
|
|
1196
|
+
forceRefresh() {
|
|
1197
|
+
// Se sono in modalità View viene mantenuto in automatico il numero di pagina, ma per la modalità array devo prendere le info di paginazione prima e riapplicarle dopo
|
|
1198
|
+
let arrayPage;
|
|
1199
|
+
let arrayIpp;
|
|
1200
|
+
if (this.arrayMode) {
|
|
1201
|
+
arrayPage = this.arraymodePage;
|
|
1202
|
+
arrayIpp = this.ArraymodeItemsPerPage;
|
|
1203
|
+
}
|
|
1204
|
+
this.writeValue(this.View);
|
|
1205
|
+
this.cdr.detectChanges();
|
|
1206
|
+
if (this.arrayMode) {
|
|
1207
|
+
this.ArraymodeItemsPerPage = arrayIpp;
|
|
1208
|
+
this.arrayGoToPage(arrayPage);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
EsTableComponent.decorators = [
|
|
1213
|
+
{ type: Component, args: [{
|
|
1214
|
+
selector: 'es-table',
|
|
1215
|
+
viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }],
|
|
1216
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1217
|
+
encapsulation: ViewEncapsulation.None,
|
|
1218
|
+
template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}} <input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" /> {{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n</div>\r\n\r\n<!--\r\nI TH sono contenuto statico, questo significa che senza condizione per RowTHs arriverebbero sia qui sia nell ng-container dell'header in fase non inizializzata, duplicando fisicamente le colonne.\r\nPer ovviare al problema, questo pezzo lo faccio apparire solo se ci sono gi\u00E0 dei RowTHs, quindi su valorizzazione della View succeder\u00E0:\r\n1) appaiono i th nell' ng-container dell'header, e NON qui\r\n2) i TH vengono presi, elaborati e trasformati in RowTHs\r\n3) l'ng-container dell'header sparisce (per la condizione !UseCustomCells || !RowTHs) e qui appaiono i nuovi TH (che poi sono gli stessi di prima che girano)\r\n4) Vengono presi i nuovi TH da qui e trasformati a loro volta in RowTHs\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && RowTHs\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Qui invece ci sono tutti i TH-->\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<!--\r\nQuesta parte \u00E8 un po' pi\u00F9 semplice del sopra. Infatti i TD vengono s\u00EC bindati in entrambi i punti (qui e nell'ng-container del body), ma avr\u00F2 le TD statiche prima di generare la TMPBoundSource.\r\nQuesto significa che il workflow di binding sar\u00E0:\r\n1) Appaiono i TD statici nel body e NON qui, perch\u00E9 i TMPBoundSource non sono ancora stati emessi\r\n2) Contemporaneamente all'emissione dei TMPBoundSource vengono anche emessi i RowTds\r\n3) Considerando il punto 2, al giro dopo appariranno i TD qui, perch\u00E9 \u00E8 stata generata la TMPBoundSource, e spariranno contemporaneamente dall'ng-container del body (per la condizione !UseCustomCells || !RowTDs)\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && bodyRef\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Tutti i TD che dopo verranno presi ed elaborati internamente-->\r\n <ng-container *ngFor=\"let item of TMPBoundSource\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<div *ngIf=\"View\" class=\"est-relative\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span> {{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"est-top-pager\" *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"est-top-allselect\" *ngIf=\"canSelectAll || (!reportMode && (View?.selection || arraymodeSelection).all)\">\r\n <span>{{ (selectedObjects == -1 ? ('All the' | localize : lc) : ((selectedObjects || 0) | number : '0.0-0' : locale)) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span> \r\n <span class=\"est-link est-inline\" (click)=\"selection_H.selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection).all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [class.est-scrollable]=\"UseEndlessscroll\" (scroll)=\"UseEndlessscroll && onScroll($event)\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"SelectAll || PagingStyle != 'bottom'\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden-view]=\"!canSelectAll && (reportMode || !(View?.selection || arraymodeSelection).all) && PagingStyle == 'bottom'\">\r\n <p class=\"est-hidden-view app-margin-bottom-0\">\u00A7</p>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned; Else: cell.Template\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"(viewMode || arrayMode)\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border est-simple-border-bottom\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th class=\"est-pinned-internal-header\" *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" [class.est-no-border]=\"true\" [class.est-nowrap]=\"!rowHeader.Wrap\" class=\"{{rowHeader.Class || ''}}\" [Pinned]=\"true\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onUnpinning)=\"columnMetadata_H.unpinColumn($event)\" (onOrderChange)=\"OrderByColumn && thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template;\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class || ''}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"OrderByColumn && thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template;\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Casistica in cui ho il setup proveniente da un report. Gli header sono definiti da come \u00E8 fatto il report-->\r\n <ng-container *ngIf=\"reportMode\">\r\n <th [style.color]=\"clm.color\" *ngFor=\"let clm of ReportValues.columns\" class=\"est-no-selection est-pointer est-nowrap\" (click)=\"reportMode_H.setupNextOrderAndSearch(clm)\">\r\n {{clm.description}}<span class=\"fa\" [class.fa-chevron-down]=\"clm.order == 'DESC'\" [class.fa-chevron-up]=\"clm.order == 'ASC'\"></span>\r\n </th>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-9]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"columnMetadata_H.resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"export_H.tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"export_H.tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n \r\n <!-- Valido per modalit\u00E0 View o Array. Se sono in report mode il body \u00E8 creato in altro modo -->\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" *ngIf=\"(arrayMode || viewMode)\">\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n\r\n <!-- Per la modalit\u00E0 a report c'\u00E8 un body particolare semi-dinamico -->\r\n <tbody [hidden]=\"BodyHidden\" *ngIf=\"reportMode\">\r\n <tr *ngFor=\"let row of ReportValues.rows; let even = even;\">\r\n <td class=\"est-nowrap\" *ngFor=\"let val of row.values\">{{val}}</td>\r\n <td class=\"est-sticky-last-column{{even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && PagerOptions.ShowButtons && (PagerOptions.PagerCount > 10 || PagerOptions.PagerCount == -1)\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"(!reportMode || View?.pagingavailable) && (!arrayMode || SearchView)\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { Margin: true, ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right\" *ngIf=\"PagerOptions.ShowCount || PagerOptions.ShowPagingOptions\">\r\n <div class=\"est-mt-min-5\" *ngIf=\"PagerOptions.ShowPaging\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [CountLabel]=\"CountLabel\" [ShowPaging]=\"PagerOptions.ShowPagingOptions\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n <div *ngIf=\"reportMode && !PagerOptions.ShowPaging\"><em>{{'Paging options are not available for this report' | localize: lc}}</em></div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <div class=\"est-flex\" [class.est-margin-left-50]=\"options.Margin\">\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\"><a *ngFor=\"let p of options.Array\" class=\"btn est-page-sel {{p.cssClass}}\" (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a></div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index; trackBy: bodyTrackBy\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"(!item.locked && !item._sep && !item._group && handleClick($event, item)) || item._group && handleGroupClick(item)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"item._group && handleGroupClick(item)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td class=\"est-pinned-body \" *ngIf=\"HasPinnedColumns\"><div class=\"est-pinned-border est-cell-group-padding\"></div></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><app-paging [CountLabel]=\"CountLabel\" [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [CountLabel]=\"CountLabel\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\" *ngIf=\"(item.searches == 'groups' ? item.view.groupcount : item.view.objectcount) > 10\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"dynamicMode_H.generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\"\r\n [class.est-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + rowItem.propertyName + '$') != -1\"\r\n (click)=\"cellClicked(rowItem.propertyName, item) && !CellActionPropagates && $event.stopPropagation()\"\r\n [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && RowTDs\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowItem.Template\">{{rowItem.Content}}</span>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowItem.Template\">{{rowItem.Content}}</span>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [class.est-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + $any(rowItem).ID + '$') != -1\" (click)=\"cellClicked(rowItem.ID, item) && !CellActionPropagates && $event.stopPropagation()\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"hierarchyMode_H.collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"hierarchyMode_H.expandParent(item[this.OwnKey])\"></span>\r\n \r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-9' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">×</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"columnMetadata_H.globalColVisCheckChanged();\">\r\n </th>\r\n <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th>\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" class=\"est-pointer\" [class.est-white-selected]=\"lastSelectedItemID == item.id\" [class.est-no-selection]=\"!item.visible\">\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"columnMetadata_H.updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap\" *ngIf=\"ColumnsOrdering\">\r\n <span class=\"fa fa-arrow-up\" [class.est-hidden-view]=\"item.fixed || item.pinned\" (click)=\"lastSelectedItemID = item.id; i != 0 && !item.fixed && columnMetadata_H.sendUp(item); $event.stopPropagation();\"></span>\r\n <span class=\"fa fa-arrow-down\" [class.est-hidden-view]=\"item.fixed || item.pinned\" (click)=\"lastSelectedItemID = item.id; !last && !item.fixed && columnMetadata_H.sendDown(item); $event.stopPropagation();\"></span>\r\n </td>\r\n <td class=\"est-nowrap\" (click)=\"columnMetadata_H.columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <ng-container *ngTemplateOutlet=\"item.template\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnMetadata_H.columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td><span *ngIf=\"!item.fixed\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"columnMetadata_H.pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"columnMetadata_H.confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>",
|
|
1219
|
+
styles: [".est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-pointer{cursor:pointer}.est-high-density td,.est-high-density th{padding:0 .2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-mt-min-5{margin-top:-5px}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-9{right:9px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14{font-size:14px}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.est-slider,.est-slider:before{position:absolute;transition:.4s}.est-slider:before{content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translateX(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-relative{position:relative}.est-top-pager{position:absolute;right:0;top:5px}.est-top-allselect{position:absolute;left:0;top:5px;font-weight:700}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-margin-left-50{margin-left:50px}.est-quick-unpin{color:#000;margin-left:8px;font-size:14px;transform:rotate(45deg)}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit;border:none;border-radius:15px}.est-page-next,.est-page-prev{color:#000;font-size:inherit;padding:2px 0 0}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-simple-border-bottom{border-bottom:1px solid #dee2e6}.est-pinned-internal-header{border-top:0;border-bottom:0 solid #dee2e6}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-flex{display:flex}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:hsla(0,0%,46.7%,.4666666666666667)!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:hsla(0,0%,73.3%,.7333333333333333)!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}"]
|
|
1220
|
+
},] }
|
|
1221
|
+
];
|
|
1222
|
+
EsTableComponent.ctorParameters = () => [
|
|
1223
|
+
{ type: NgControl, decorators: [{ type: Self }, { type: Optional }] },
|
|
1224
|
+
{ type: PreferencesService, decorators: [{ type: Optional }] },
|
|
1225
|
+
{ type: EsTableDefaultable, decorators: [{ type: Optional }, { type: Inject, args: [EST_DEFAULTS,] }] },
|
|
1226
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [EST_LOCALE,] }] },
|
|
1227
|
+
{ type: LocalizationService },
|
|
1228
|
+
{ type: ChangeDetectorRef },
|
|
1229
|
+
{ type: UtilitiesHandler },
|
|
1230
|
+
{ type: UtilityService },
|
|
1231
|
+
{ type: ExportService },
|
|
1232
|
+
{ type: DateService },
|
|
1233
|
+
{ type: MessageService }
|
|
1234
|
+
];
|
|
1235
|
+
EsTableComponent.propDecorators = {
|
|
1236
|
+
EsTdsDirective: [{ type: ContentChildren, args: [EsTdDirective,] }],
|
|
1237
|
+
EsThsDirective: [{ type: ContentChildren, args: [EsThDirective,] }],
|
|
1238
|
+
EsThs: [{ type: ContentChildren, args: [forwardRef(() => EsTh),] }],
|
|
1239
|
+
EsTds: [{ type: ContentChildren, args: [forwardRef(() => EsTd),] }],
|
|
1240
|
+
bodyRef: [{ type: ContentChild, args: ['body', { static: false },] }],
|
|
1241
|
+
headerRef: [{ type: ContentChild, args: ['header', { static: false },] }],
|
|
1242
|
+
headerGroupRef: [{ type: ContentChild, args: ['headerGroup', { static: false },] }],
|
|
1243
|
+
secondaryHeaderGroupRef: [{ type: ContentChild, args: ['secondaryHeaderGroup', { static: false },] }],
|
|
1244
|
+
CornerMenuOptions: [{ type: Input }],
|
|
1245
|
+
ColumnsResizable: [{ type: Input }],
|
|
1246
|
+
AutoUpdate: [{ type: Input }],
|
|
1247
|
+
UseCustomCellActions: [{ type: Input }],
|
|
1248
|
+
CustomCellActionsOn: [{ type: Input }],
|
|
1249
|
+
CellActionPropagates: [{ type: Input }],
|
|
1250
|
+
UseCustomCells: [{ type: Input }],
|
|
1251
|
+
MaxHeight: [{ type: Input }],
|
|
1252
|
+
ContainerClass: [{ type: Input }],
|
|
1253
|
+
XLSXExport: [{ type: Input }],
|
|
1254
|
+
CSVExport: [{ type: Input }],
|
|
1255
|
+
AllSearch: [{ type: Input }],
|
|
1256
|
+
HighCellDensity: [{ type: Input }],
|
|
1257
|
+
Selection: [{ type: Input }],
|
|
1258
|
+
ShowLoadingOnBootstrap: [{ type: Input }],
|
|
1259
|
+
Removal: [{ type: Input }],
|
|
1260
|
+
RemovalCondition: [{ type: Input }],
|
|
1261
|
+
Export: [{ type: Input }],
|
|
1262
|
+
ShiftClick: [{ type: Input }],
|
|
1263
|
+
CountLabel: [{ type: Input }],
|
|
1264
|
+
HidePaging: [{ type: Input }],
|
|
1265
|
+
HidePagingCount: [{ type: Input }],
|
|
1266
|
+
HidePagingButtons: [{ type: Input }],
|
|
1267
|
+
ContextMenu: [{ type: Input }],
|
|
1268
|
+
ExportFileName: [{ type: Input }],
|
|
1269
|
+
TableClass: [{ type: Input }],
|
|
1270
|
+
ExportFunction: [{ type: Input }],
|
|
1271
|
+
HasHeaderGroup: [{ type: Input }],
|
|
1272
|
+
HasSecondaryHeaderGroup: [{ type: Input }],
|
|
1273
|
+
SliceSize: [{ type: Input }],
|
|
1274
|
+
EndlessScroll: [{ type: Input }],
|
|
1275
|
+
EndlessScrollOnlyForAll: [{ type: Input }],
|
|
1276
|
+
HeaderHidden: [{ type: Input }],
|
|
1277
|
+
BodyHidden: [{ type: Input }],
|
|
1278
|
+
SelectionDisabled: [{ type: Input }],
|
|
1279
|
+
SingleSelection: [{ type: Input }],
|
|
1280
|
+
RowClassAssigner: [{ type: Input }],
|
|
1281
|
+
OrderByColumn: [{ type: Input }],
|
|
1282
|
+
MultipleOrderingDirectives: [{ type: Input }],
|
|
1283
|
+
HiddenColumns: [{ type: Input }],
|
|
1284
|
+
ColumnsOrdering: [{ type: Input }],
|
|
1285
|
+
SearchView: [{ type: Input }],
|
|
1286
|
+
SelectAll: [{ type: Input }],
|
|
1287
|
+
UseArrayModePaging: [{ type: Input }],
|
|
1288
|
+
DynamicRowColumnsDefinition: [{ type: Input }],
|
|
1289
|
+
DynamicOperations: [{ type: Input }],
|
|
1290
|
+
Hierarchy: [{ type: Input }],
|
|
1291
|
+
ParentKey: [{ type: Input }],
|
|
1292
|
+
OwnKey: [{ type: Input }],
|
|
1293
|
+
StartsExpanded: [{ type: Input }],
|
|
1294
|
+
SavePreferences: [{ type: Input }],
|
|
1295
|
+
PagingStyle: [{ type: Input }],
|
|
1296
|
+
RowGroupingPagingStyle: [{ type: Input }],
|
|
1297
|
+
SecondarySource: [{ type: Input }],
|
|
1298
|
+
TertiarySource: [{ type: Input }],
|
|
1299
|
+
UseSelectionCache: [{ type: Input }],
|
|
1300
|
+
ShowItemGroupsColumns: [{ type: Input }],
|
|
1301
|
+
onOrderChanged: [{ type: Output }],
|
|
1302
|
+
onSearchRequest: [{ type: Output }],
|
|
1303
|
+
onSelectionChanged: [{ type: Output }],
|
|
1304
|
+
onRemoval: [{ type: Output }],
|
|
1305
|
+
onAbortRemoval: [{ type: Output }],
|
|
1306
|
+
onCellClick: [{ type: Output }],
|
|
1307
|
+
onCornerAction: [{ type: Output }],
|
|
1308
|
+
onDynamicOperation: [{ type: Output }],
|
|
1309
|
+
exportDownloader: [{ type: ViewChild, args: ['exportDownloader', { static: false },] }],
|
|
1310
|
+
tableEmptyMenu: [{ type: ViewChild, args: ['emptyMenu', { static: true },] }],
|
|
1311
|
+
ArraymodeItemsPerPage: [{ type: Input }]
|
|
1312
|
+
};
|
|
1313
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNfdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9jb21wb25lbnRzL2VzLXRhYmxlL2VzX3RhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsVUFBVTtBQUNWLE9BQU8sRUFDSCxTQUFTLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBYSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxLQUFLLEVBQ3BHLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUE0QixTQUFTLEVBQWMsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBZSxNQUFNLEVBQzlJLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakUsaUJBQWlCO0FBQ2pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUszRCxVQUFVO0FBQ1YsT0FBTyxFQUNILFNBQVMsRUFBMkQsZ0JBQWdCLEVBRXZGLE1BQU0sY0FBYyxDQUFDO0FBRXRCLDhCQUE4QjtBQUM5QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFB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QUMsT0FBTyxDQUFDO1lBQ2xILElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxHQUFHLEtBQUssSUFBSSxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxJQUFJLENBQUMsT0FBTyxJQUFJLEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRzthQUNJLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUN0QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztZQUNsQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0gsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUF1QixJQUFJLENBQUMsSUFBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3SCxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDNUgsSUFBSSxD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TCxLQUFLO3dCQUVMLEtBQUs7cUJBRUwsS0FBSzs2QkFFTCxLQUFLOzhCQUVMLEtBQUs7MEJBR0wsS0FBSztxQ0FFTCxLQUFLOzhCQU9MLEtBQUs7NkJBT0wsS0FBSztnQ0FFTCxLQUFLO29DQUVMLEtBQUs7NkJBRUwsTUFBTTs4QkFXTixNQUFNO2lDQUVOLE1BQU07d0JBRU4sTUFBTTs2QkFFTixNQUFNOzBCQU1OLE1BQU07NkJBRU4sTUFBTTtpQ0FFTixNQUFNOytCQU9OLFNBQVMsU0FBQyxrQkFBa0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7NkJBRS9DLFNBQVMsU0FBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO29DQVV2QyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhclxyXG5pbXBvcnQge1xyXG4gICAgQ29tcG9uZW50LCBmb3J3YXJkUmVmLCBDb250ZW50Q2hpbGRyZW4sIFF1ZXJ5TGlzdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBJbnB1dCxcclxuICAgIEV2ZW50RW1pdHRlciwgT3V0cHV0LCBDb250ZW50Q2hpbGQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBWaWV3RW5jYXBzdWxhdGlvbiwgT3B0aW9uYWwsIFNlbGYsIFRlbXBsYXRlUmVmLCBJbmplY3RcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5nQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbi8vIENvbmZpZ3VyYXppb25pXHJcbmltcG9ydCB7IFV0aWxpdHlTZXJ2aWNlLCBFeHBvcnRTZXJ2aWNlLCBNZXNzYWdlU2VydmljZSwgRGF0ZVNlcnZpY2UgfSBmcm9tICdAZXNmYWVuemEvZXh0ZW5zaW9ucyc7XHJcbmltcG9ydCB7IExvY2FsaXphdGlvblNlcnZpY2UgfSBmcm9tICdAZXNmYWVuemEvbG9jYWxpemF0aW9ucyc7XHJcbmltcG9ydCB7IFByZWZlcmVuY2VzU2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9wcmVmZXJlbmNlcyc7XHJcblxyXG4vLyBQbHVnaW5zXHJcbmltcG9ydCB7IENvbnRleHRNZW51Q29tcG9uZW50IH0gZnJvbSAnQGVzZmFlbnphL25neC1jb250ZXh0bWVudSc7XHJcblxyXG4vLyBNb2RlbGxpXHJcbmltcG9ydCB7XHJcbiAgICBBcHBTZWFyY2gsIEFwcE9yZGVyaW5nLCBFc1RhYmxlQ29sdW1uc0RlZmluaXRpb24sIENvcm5lck1lbnVPcHRpb24sIFJlcG9ydERlZmluaXRpb24sIFJlcG9ydFJlc3VsdCxcclxuICAgIEVzVGFibGVPcGVyYXRpb25EZWZpbml0aW9uLCBFc1RhYmxlQ29sdW1uLCBHcm91cFBhZ2VyLCBHcm91cFJvdXRlRnJhZ21lbnQsIFRoRWxlbWVudFxyXG59IGZyb20gJy4uLy4uL2RvbWFpbic7XHJcblxyXG4vLyBDb21wb25lbnRpIGUgTG9jYWxpenphemlvbmVcclxuaW1wb3J0IHsgRXNUZCB9IGZyb20gJy4uL2VzLXRkL2VzX3RkLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGggfSBmcm9tICcuLi9lcy10aC9lc190aC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBFc1RkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9lc190ZC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBFc1RoRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9lc190aC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBFc1RhYmxlTG9jIH0gZnJvbSAnLi9lc190YWJsZS5jb21wb25lbnQubG9jJztcclxuaW1wb3J0IHsgSXRlbXNTZWxlY3Rpb24gfSBmcm9tICcuLi8uLi9kb21haW4vZXh0ZXJuYWxzL2NsYXNzZXMvYXBwc2VhcmNoL0l0ZW1zU2VsZWN0aW9uJztcclxuaW1wb3J0IHsgR3JvdXBPckFnZ3JlZ2F0aW9uIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9leHRlcm5hbHMvY2xhc3Nlcy9hcHBzZWFyY2gvR3JvdXBPckFnZ3JlZ2F0aW9uXCI7XHJcbmltcG9ydCB7IEdyb3VwRmlsdGVyIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9leHRlcm5hbHMvY2xhc3Nlcy9hcHBzZWFyY2gvR3JvdXBGaWx0ZXJcIjtcclxuaW1wb3J0IHsgR3JvdXAgfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9jbGFzc2VzL2FwcHNlYXJjaC9Hcm91cFwiO1xyXG5pbXBvcnQgeyBFc1RhYmxlRGVmYXVsdGFibGUgfSBmcm9tICcuLi8uLi9kb21haW4vY29uZmlndXJhdGlvbi9Fc1RhYmxlRGVmYXVsdGFibGUnO1xyXG5cclxuaW1wb3J0IHsgRVNUX0RFRkFVTFRTLCBFU1RfTE9DQUxFIH0gZnJvbSAnLi4vLi4vdG9rZW5zJztcclxuXHJcbmltcG9ydCB7IEV4cG9ydEhhbmRsZXIsIENvbHVtbk1ldGFkYXRhSGFuZGxlciwgRHluYW1pY01vZGVIYW5kbGVyLCBIaWVyYXJjaHlNb2RlSGFuZGxlciwgSXRlbXNIYW5kbGVyLCBSZXBvcnRNb2RlSGFuZGxlciwgUm93R3JvdXBpbmdIYW5kbGVyLCBTZWxlY3Rpb25IYW5kbGVyLCBVdGlsaXRpZXNIYW5kbGVyIH0gZnJvbSAnLi4vLi4vY29yZS9oYW5kbGVycyc7XHJcblxyXG4vKiogQ29tcG9uZW50ZSBjaGUgcGVybWV0dGUgZGkgcmFwcHJlc2VudGFyZSB1bmEgZ3JpZ2xpYSBkaSB2YWxvcmkgKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2VzLXRhYmxlJyxcclxuICAgIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IExvY2FsaXphdGlvblNlcnZpY2UsIHVzZUNsYXNzOiBFc1RhYmxlTG9jIH1dLFxyXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vZXNfdGFibGUuY29tcG9uZW50LnNjc3MnXSxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9lc190YWJsZS5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIEVzVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzIHtcclxuXHJcbiAgICBleHBvcnRfSDogRXhwb3J0SGFuZGxlcjtcclxuICAgIGNvbHVtbk1ldGFkYXRhX0g6IENvbHVtbk1ldGFkYXRhSGFuZGxlcjtcclxuICAgIGR5bmFtaWNNb2RlX0g6IER5bmFtaWNNb2RlSGFuZGxlcjtcclxuICAgIGhpZXJhcmNoeU1vZGVfSDogSGllcmFyY2h5TW9kZUhhbmRsZXI7XHJcbiAgICBpdGVtc19IOiBJdGVtc0hhbmRsZXI7XHJcbiAgICByZXBvcnRNb2RlX0g6IFJlcG9ydE1vZGVIYW5kbGVyO1xyXG4gICAgcm93R3JvdXBpbmdfSDogUm93R3JvdXBpbmdIYW5kbGVyXHJcbiAgICBzZWxlY3Rpb25fSDogU2VsZWN0aW9uSGFuZGxlcjtcclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgQFNlbGYoKSBAT3B0aW9uYWwoKSBwdWJsaWMgbmdDb250cm9sOiBOZ0NvbnRyb2wsIFxyXG4gICAgICAgIEBPcHRpb25hbCgpIHByaXZhdGUgcHJlZlNlcnZpY2U6IFByZWZlcmVuY2VzU2VydmljZSwgXHJcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChFU1RfREVGQVVMVFMpIHByaXZhdGUgZGVhZnVsdHM6IEVzVGFibGVEZWZhdWx0YWJsZSwgXHJcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChFU1RfTE9DQUxFKSBwdWJsaWMgbG9jYWxlOiBzdHJpbmcsIFxyXG4gICAgICAgIHB1YmxpYyBsYzogTG9jYWxpemF0aW9uU2VydmljZSxcclxuICAgICAgICBwdWJsaWMgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgXHJcbiAgICAgICAgcHJpdmF0ZSB1dGlsaXRpZXNfSDogVXRpbGl0aWVzSGFuZGxlciwgXHJcbiAgICAgICAgcHJpdmF0ZSB1dGlFeHRzOiBVdGlsaXR5U2VydmljZSwgXHJcbiAgICAgICAgcHJpdmF0ZSBleHBFeHRzOiBFeHBvcnRTZXJ2aWNlLCBcclxuICAgICAgICBwcml2YXRlIGRhdGVFeHRzOiBEYXRlU2VydmljZSwgXHJcbiAgICAgICAgcHJpdmF0ZSBtc2dFeHRzOiBNZXNzYWdlU2VydmljZSkge1xyXG5cclxuICAgICAgICB0aGlzLmV4cG9ydF9IID0gbmV3IEV4cG9ydEhhbmRsZXIodGhpcywgdGhpcy5leHBFeHRzLCB0aGlzLm1zZ0V4dHMpO1xyXG4gICAgICAgIHRoaXMucm93R3JvdXBpbmdfSCA9IG5ldyBSb3dHcm91cGluZ0hhbmRsZXIodGhpcywgdGhpcy51dGlsaXRpZXNfSCwgdGhpcy5kYXRlRXh0cyk7XHJcbiAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9IID0gbmV3IENvbHVtbk1ldGFkYXRhSGFuZGxlcih0aGlzLCB0aGlzLnV0aWxpdGllc19ILCB0aGlzLnV0aUV4dHMsIHRoaXMucHJlZlNlcnZpY2UsIHRoaXMucm93R3JvdXBpbmdfSCk7XHJcbiAgICAgICAgdGhpcy5keW5hbWljTW9kZV9IID0gbmV3IER5bmFtaWNNb2RlSGFuZGxlcih0aGlzKTtcclxuICAgICAgICB0aGlzLmhpZXJhcmNoeU1vZGVfSCA9IG5ldyBIaWVyYXJjaHlNb2RlSGFuZGxlcih0aGlzKTtcclxuICAgICAgICB0aGlzLml0ZW1zX0ggPSBuZXcgSXRlbXNIYW5kbGVyKHRoaXMsIHRoaXMudXRpbGl0aWVzX0gpO1xyXG4gICAgICAgIHRoaXMucmVwb3J0TW9kZV9IID0gbmV3IFJlcG9ydE1vZGVIYW5kbGVyKHRoaXMsIHRoaXMudXRpbGl0aWVzX0gpO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uX0ggPSBuZXcgU2VsZWN0aW9uSGFuZGxlcih0aGlzLCB0aGlzLnJvd0dyb3VwaW5nX0gpO1xyXG5cclxuICAgICAgICBpZiAobmdDb250cm9sKVxyXG4gICAgICAgICAgICBuZ0NvbnRyb2wudmFsdWVBY2Nlc3NvciA9IHRoaXM7XHJcblxyXG4gICAgICAgIC8vIEFzc2VnbmF6aW9uZSBwZXIgdHV0dGkgZ2xpIElucHV0IGRpIGRlZmF1bHRcclxuICAgICAgICB0aGlzLkNvbHVtbnNSZXNpemFibGUgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuQ29sdW1uc1Jlc2l6YWJsZSwgdGhpcy5kZWFmdWx0cz8uQ29sdW1uc1Jlc2l6YWJsZSk7XHJcbiAgICAgICAgdGhpcy5BdXRvVXBkYXRlID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkF1dG9VcGRhdGUsIHRoaXMuZGVhZnVsdHM/LkF1dG9VcGRhdGUpO1xyXG4gICAgICAgIHRoaXMuQWxsU2VhcmNoID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkFsbFNlYXJjaCwgdGhpcy5kZWFmdWx0cz8uQWxsU2VhcmNoLCB0cnVlKTtcclxuICAgICAgICB0aGlzLkV4cG9ydCA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5FeHBvcnQsIHRoaXMuZGVhZnVsdHM/LkV4cG9ydCk7XHJcbiAgICAgICAgdGhpcy5IaWRlUGFnaW5nID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkhpZGVQYWdpbmcsIHRoaXMuZGVhZnVsdHM/LkhpZGVQYWdpbmcsIGZhbHNlKTtcclxuICAgICAgICB0aGlzLkhpZGVQYWdpbmdDb3VudCA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5IaWRlUGFnaW5nQ291bnQsIHRoaXMuZGVhZnVsdHM/LkhpZGVQYWdpbmdDb3VudCk7XHJcbiAgICAgICAgdGhpcy5IaWRlUGFnaW5nQnV0dG9ucyA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5IaWRlUGFnaW5nQnV0dG9ucywgdGhpcy5kZWFmdWx0cz8uSGlkZVBhZ2luZ0J1dHRvbnMpO1xyXG4gICAgICAgIHRoaXMuQ29udGFpbmVyQ2xhc3MgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuQ29udGFpbmVyQ2xhc3MsIHRoaXMuZGVhZnVsdHM/LkNvbnRhaW5lckNsYXNzLCAnJyk7XHJcbiAgICAgICAgdGhpcy5UYWJsZUNsYXNzID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLlRhYmxlQ2xhc3MsIHRoaXMuZGVhZnVsdHM/LlRhYmxlQ2xhc3MsICd0YWJsZSB0YWJsZS1zdHJpcGVkIHRhYmxlLWhvdmVyIHRhYmxlLXNtJyk7XHJcbiAgICAgICAgdGhpcy5TZWxlY3Rpb24gPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuU2VsZWN0aW9uLCB0aGlzLmRlYWZ1bHRzPy5TZWxlY3Rpb24pO1xyXG4gICAgICAgIHRoaXMuU2F2ZVByZWZlcmVuY2VzID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLlNhdmVQcmVmZXJlbmNlcywgdGhpcy5kZWFmdWx0cz8uU2F2ZVByZWZlcmVuY2VzKTtcclxuICAgICAgICB0aGlzLlBhZ2luZ1N0eWxlID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLlBhZ2luZ1N0eWxlLCB0aGlzLmRlYWZ1bHRzPy5QYWdpbmdTdHlsZSwgJ2JvdHRvbScpO1xyXG4gICAgICAgIHRoaXMuUm93R3JvdXBpbmdQYWdpbmdTdHlsZSA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5Sb3dHcm91cGluZ1BhZ2luZ1N0eWxlLCB0aGlzLmRlYWZ1bHRzPy5Sb3dHcm91cGluZ1BhZ2luZ1N0eWxlLCAnbGVmdCcpO1xyXG4gICAgICAgIHRoaXMuVXNlU2VsZWN0aW9uQ2FjaGUgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuVXNlU2VsZWN0aW9uQ2FjaGUsIHRoaXMuZGVhZnVsdHM/LlVzZVNlbGVjdGlvbkNhY2hlLCB0cnVlKTtcclxuICAgICAgICB0aGlzLlNob3dJdGVtR3JvdXBzQ29sdW1ucyA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5TaG93SXRlbUdyb3Vwc0NvbHVtbnMsIHRoaXMuZGVhZnVsdHM/LlNob3dJdGVtR3JvdXBzQ29sdW1ucywgZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSwgdGhpcy5kZWFmdWx0cz8uQXJyYXltb2RlSXRlbXNQZXJQYWdlLCAxNSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFZpZXcgZmluYWxlIHN1IGN1aSBiaW5kYXJzaSBsYXRvIEZyb250ZW5kLCBpbCB0aXBvIHB1w7IgZXNzZXJlIElBcHBTZWFyY2g8YW55PiAocGVyIGxhICoqdmlld01vZGUqKiksIGFueVtdIChwZXIgbCcqKmFycmF5TW9kZSoqKSBlIFJlcG9ydERlZmluaXRpb24gcGVyIGxhICoqcmVwb3J0TW9kZSoqICovXHJcbiAgICBwdWJsaWMgVmlldzogYW55ID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRhIGN1aSBsJ2VzLXRhYmxlIG1vc3RyYSBpIHB1bHNhbnRpIGRpIHBhZ2luYXppb25lIGluIGJhc3NvIGEgZGVzdHJhICovXHJcbiAgICBwdWJsaWMgYXJyYXlQdWxzYW50aTogYW55O1xyXG4gICAgLyoqIEluZGljYSBzZSBsJ2VzLXRhYmxlIGRldmUgbW9zdHJhcmUgaWwgY2hlY2sgZ2xvYmFsZSBuZWxsJ2hlYWRlciBwZXIgZmFyZSBpbCBcInNlbGV6aW9uYSB0dXR0b1wiICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ2hlY2sgPSBmYWxzZTtcclxuICAgIC8qKiBUaWVuZSBkYSBjb250byBsJ3VsdGltbyBlbGVtZW50byBzZWxlemlvbmF0byBpbiBtb2RvIGRhIHBvdGVyIGVmZmV0dHVhcmUgaWwgU0hJRlQrQ0xJQ0sgKi9cclxuICAgIHByaXZhdGUgbGFzdFNlbGVjdGVkOiBhbnkgPSBudWxsO1xyXG4gICAgLyoqIENvbnRlZ2dpbyBpbnRlcm5vIHBlciBpbCBudW1lcm8gZGkgZWxlbWVudGkgc2VsZXppb25hdGkgKi9cclxuICAgIHB1YmxpYyBzZWxlY3RlZE9iamVjdHMgPSAwO1xyXG4gICAgLyoqIEluZGljYSBzZSDDqCBwb3NzaWJpbGUgZWZmZXR0dWFyZSB1bmEgc2VsZXppb25lIG1hc3NpdmEgKi9cclxuICAgIHB1YmxpYyBjYW5TZWxlY3RBbGwgPSBmYWxzZTtcclxuICAgIC8qKiBJbmRpY2Egc2UgaWwgY29tcG9uZW50ZSBzdGEgZ2VzdGVuZG8gdW4gSUFwcFNlYXJjaDxhbnk+ICovXHJcbiAgICBwdWJsaWMgdmlld01vZGUgPSBmYWxzZTtcclxuICAgIC8qKiBJbmRpY2Egc2UgaWwgY29tcG9uZW50ZSBzdGEgZ2VzdGVuZG8gdW4gYW55W10gKi9cclxuICAgIHB1YmxpYyBhcnJheU1vZGUgPSBmYWxzZTtcclxuICAgIC8qKiBJbmRpY2Egc2UgaWwgY29tcG9uZW50ZSBzdGEgZ2VzdGVuZG8gdW4gUmVwb3J0RGVmaW5pdGlvbiAqL1xyXG4gICAgcHVibGljIHJlcG9ydE1vZGUgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnRlbml0b3JlIGRlZ2xpIGVsZW1lbnRpIGRhIGxpc3RhcmUgbGF0byBpbnRlcmZhY2NpYSBkb3BvIHR1dHRlIGxlIGVsYWJvcmF6aW9uaSBkZWwgY2FzbyxcclxuICAgICAqIGdlbmVyYWxtZW50ZSBub24gc29ubyBhbHRybyBjaGUgdHV0dGkgZ2xpIG9nZ2V0dGkgZGEgcHJlc2VudGFyZSBjb24gaW4gcGnDuSBsJ2hhc2ggY2FsY29sYXRvIHBlciBpZGVudGlmaWNhcmUgMSBvZ2dldHRvIGNvbiBsYSBwcm9wcmlhIHJpZ2FcclxuICAgICAqL1xyXG4gICAgcHVibGljIGJvdW5kU291cmNlOiBhbnlbXSA9IFtdO1xyXG4gICAgLyoqIFN0ZXNzYSBjb3NhIGRlbGxhICoqYm91bmRTb3VyY2UqKiwgdXRpbGl6emF0YSBjb21lIGFwcG9nZ2lvIHRlbXBvcmFuZW8gaW50ZXJubyAqL1xyXG4gICAgcHVibGljIFRNUEJvdW5kU291cmNlOiBhbnlbXSA9IFtdO1xyXG4gICAgLyoqIFwiRmV0dGFcIiBkaSBvZ2dldHRpIHV0aWxpenphdGEgbmVsbCdlbmRsZXNzIHNjcm9sbCwgb2duaSBlbGVtZW50byBkaSBxdWVzdG8gYXJyYXkgw6ggdW4gYmxvY2NoZXR0byBkaSAxMDAgZWxlbWVudGkgKi9cclxuICAgIHB1YmxpYyBib3VuZFN1YlNvdXJjZXM6IGFueVtdID0gW107XHJcbiAgICAvKiogUXVlc3RhIGZ1bmdlIGRhIGluZGljYXRvcmUgcGVyIGdsaSBzbGljZSBpbnNlcml0aSwgbGEgbHVuZ2hlenphIGRvdnJlYmJlIGVzc2VyZSBjb3JyaXNwb25kZW50ZSBhICoqYm91bmRTdWJTb3VyY2VzKiogKi9cclxuICAgIHB1YmxpYyBhZGRlZFNsaWNlczogbnVtYmVyW10gPSBbXTtcclxuICAgIC8qKiBWYXJpYWJpbGUgY2hlIGlkZW50aWZpY2EgaWwgdmFsb3JlIGRlbCBcInNlbGV6aW9uYSBUdXR0b1wiIG5lbGxhIHBhZ2luYXppb25lICovXHJcbiAgICBwdWJsaWMgZGVmYXVsdEFsbFBhZ2VPdmVycmlkZSA9IDk5OTk5OTtcclxuICAgIC8qKiBJbmRpY2Egc2UgdXRpbGl6emFyZSBpbCBzaXN0ZW1hIGRpIEVuZGxlc3MgU2Nyb2xsICovXHJcbiAgICBwdWJsaWMgVXNlRW5kbGVzc3Njcm9sbDogYm9vbGVhbjtcclxuICAgIC8qKiBWYWxvcmkgZGVsbCdldmVudHVhbGUgcmVwb3J0IGluIHZpc3VhbGl6emF6aW9uZSAqL1xyXG4gICAgcHVibGljIFJlcG9ydFZhbHVlczogUmVwb3J0UmVzdWx0O1xyXG4gICAgLyoqIFNlcnZlIHBlciB0ZW5lcmUgaW4gbWVtb3JpYSBpbCBjb250ZWdnaW8gcHJlY2VkZW50ZSBlIHJlY3VwZXJhcmxvIGluIGNhc28gZGl2ZW50aSAtMiAodmVyaWZpY2FyZSBjb24gQWxlIHBlcmNow6kgbGEgbG9naWNhIGRlbCAtMikgKi9cclxuICAgIHB1YmxpYyBwcmV2aW91c0NvdW50OiBudW1iZXI7XHJcbiAgICAvKiogSW5kaWNhIHNlIHV0aWxpenphcmUgaWwgc2lzdGVtYSBkaSBhdXRvdXBkYXRlLCBjaW/DqCB1biB0cmlnZ2VyIHRpbWUtaXp6YXRvIGluIGFsdG8gYSBkZXN0cmEgZGVsbGEgdGFiZWxsYSBjaGUgcmlwZXRlIGxlIHJpY2VyY2hlIG9nbmkgWCAqKnNlY29uZHMqKiAqL1xyXG4gICAgcHVibGljIGF1dG9VcGRhdGUgPSBmYWxzZTtcclxuICAgIC8qKiBOdW1lcm8gZGkgc2Vjb25kaSBkYSBmYXJlIHRyYXNjb3JyZXJlIGZyYSB1bmEgcmljZXJjYSBlIGwnYWx0cmEgKi9cclxuICAgIHB1YmxpYyBzZWNvbmRzID0gJzEwJztcclxuICAgIC8qKiBSaWZlcmltZW50byBhbGwnSW50ZXJ2YWwgY2hlIHZpZW5lIGdlbmVyYXRvIHNlICoqYXV0b1VwZGF0ZSoqIMOoIGltcG9zdGF0YSBhIHRydWUgaW4gbW9kbyBkYSBwb3RlcmxvIHJpcHVsaXJlICovXHJcbiAgICBwdWJsaWMgdXBkYXRlVGltZXI6IGFueTtcclxuICAgIC8qKiBJbXBvc3RhdGEgYSB0cnVlIG9nbmkgdm9sdGEgY2hlIHZpZW5lIGF2dmlhdGEgdW5hIHJpY2VyY2EsIGUgYSBmYWxzZSBvZ25pIHZvbHRhIGNoZSB1biBudW92byB2YWxvcmUgdmllbmUgcmljZXZ1dG8gKi9cclxuICAgIHB1YmxpYyByZXNlYXJjaEluUHJvZ3Jlc3M6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIC8qKiBNb2RlbGxvIHJhcHByZXNlbnRhbnRlIHVuIHNpbmdvbG8gdGQgZGVsbGEgdGFiZWxsYSwgZ2VuZXJhdG8gaW4gYmFzZSBhbGxlIGNvbmZpZ3VyYXppb25pIGUgYWdsaSBvZ2dldHRpIHJpY2V2dXRpICovXHJcbiAgICBwdWJsaWMgUm93VERzOiB7IFtjb250ZXh0OiBzdHJpbmddOiBFc1RkW10gfSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyBkaSBhcHBvZ2dpbyB0ZW1wb3JhbmVvIHBlciBpICoqUm93VERzKiogKi9cclxuICAgIHB1YmxpYyBUTVBSb3dURHM6IHsgW2NvbnRleHQ6IHN0cmluZ106IEVzVGRbXSB9ID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIHJhcHByZXNlbnRhbnRlIHVuIHNpbmdvbG8gdGggZGVsbGEgdGFiZWxsYSwgZ2VuZXJhdG8gaW4gYmFzZSBhbGxlIGNvbmZpZ3VyYXppb25pIGUgYWdsaSBvZ2dldHRpIHJpY2V2dXRpICovXHJcbiAgICBwdWJsaWMgUm93VEhzOiBUaEVsZW1lbnRbXSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyBkaSBhcHBvZ2dpbyB0ZW1wb3JhbmVvIHBlciBpICoqUm93VEhzKiogKi9cclxuICAgIHB1YmxpYyBUTVBSb3dUSHM6IFRoRWxlbWVudFtdID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRpIGFwcG9nZ2lvIHRlbXBvcmFuZW8gcGVyIGkgKipSb3dUaEdyb3VwcyoqICovXHJcbiAgICBwdWJsaWMgVE1QUm93VGhHcm91cHM6IHsgU3BhbjogbnVtYmVyLCBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB9W11bXSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyByYXBwcmVzZW50YW50ZSB1biBzaW5nb2xvIGhlYWRlciBncm91cCBkZWxsYSB0YWJlbGxhLiBRdWVzdGEgbGlzdGEgw6ggZ2nDoCBvcmRpbmF0YSBlIHByb250YSBwZXIgZXNzZXJlIHV0aWxpenphdGEgaW4gbmdGb3IgKi9cclxuICAgIHB1YmxpYyBSb3dUaEdyb3VwczogeyBTcGFuOiBudW1iZXIsIFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IH1bXVtdID0gbnVsbDtcclxuICAgIC8qKiBDYWNoZSBwZXIgaSByb3V0ZXJMaW5rIGdlbmVyYXRpIG5lbGxlIHRhYmVsbGUgZGluYW1pY2hlICovXHJcbiAgICBwdWJsaWMgRHluYW1pY1RhYmxlUm91dGVyTGlua0NhY2hlOiB7fSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGlzdGEgZGVpIGNvbnRlc3RpLiBVbiBjb250ZXN0byBub24gw6ggYWx0cm8gY2hlIHVuIGhhc2ggcGFydGljb2xhcmUgY2FsY29sYXRvIHN1IHVuIG9nZ2V0dG8gY2hlIGlkZW50aWZpY2EgdW5pdm9jYW1lbnRlIHRhbGUgb2dnZXR0by5cclxuICAgICAqXHJcbiAgICAgKiBPZ251bm8gZGkgcXVlc3RpIGNvbnRlc3RpIHJhcHByZXNlbnRlcsOgIGEgc3VhIHZvbHRhLCB1bml2b2NhbWVudGUsIHVuYSByaWdhIGFsbCdpbnRlcm5vIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIFJvd0NvbnRleHRzOiBhbnlbXSA9IFtdO1xyXG4gICAgLyoqIERpcmV0dGl2ZSBkaSBvcmRpbmFtZW50byBkZWxsZSBjb2xvbm5lIChub24gb3JkaW5hbWVudG8gZGVpIGRhdGkgbWEgZGVsbGUgY29sb25uZSBpbiBzZSkgKi9cclxuICAgIHB1YmxpYyBPcmRlckRpcmVjdGl2ZXM6IHN0cmluZ1tdID0gW107XHJcbiAgICAvKiogQ29kaWNlIGRlbGwndWx0aW1vIG9nZ2V0dG8gc29sZXppb25hdG8gKi9cclxuICAgIHB1YmxpYyBsYXN0U2VsZWN0ZWRJdGVtSUQgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIG9sdHJlIGFsbGUgY29sb25uZSBkaW5hbWljaGUgc3BlY2lmaWNoZSBkaSB1biB0aXBvIGRpIG9nZ2V0dG8gY2kgc29ubyBhbmNoZSBjb2xvbm5lIGRpbmFtaWNoZSBhZ2dpdW50ZSBkYWxsJ3V0ZW50ZVxyXG4gICAgICpcclxuICAgICAqIEVzLiB1bmEgY29sb25uYSBpbiBjdWkgbW9zdHJhcmUgc2VtcHJlIHVuIGljb25jaW5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBVc2VyRGVmaW5lZER5bmFtaWNDb2xzOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAvKiogSW5kaWNhIGNoZSBxdWVzdG8gw6ggaWwgcHJpbW8gQmluZCBkZWxsYSB0YWJlbGxhLCB2aWVuZSBzZXR0YXRvIGEgZmFsc2Ugbm9uIGFwcGVuYSBpbCBwcmltbyBiaW5kIHZpZW5lIHRlcm1pbmF0byBjb24gc3VjY2Vzc28gKi9cclxuICAgIHB1YmxpYyBGaXJzdEJpbmQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLyoqIExpc3RhIGRpIGNvbG9ubmUgY2hlIHNpIHBvc3Nvbm8gdmlzdWFsaXp6YXJlL29yZGluYXJlIGZyYSBkaSBsb3JvICovXHJcbiAgICBwdWJsaWMgQ29sdW1uc0xpc3Q6IEVzVGFibGVDb2x1bW5bXSA9IFtdO1xyXG4gICAgLyoqIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHVzYXRhIGRhbGxhIGRpYWxvZyBkaSBzZWxlemlvbmUvbmFzY29uZGltZW50bywgcGVyIGV2aXRhcmUgZGkgZGFubmVnZ2lhcmUgKipDb2x1bW5zTGlzdCoqIGluIGNhc28gZGkgbW9kaWZpY2hlIHBvaSBhbm51bGxhdGUgKi9cclxuICAgIHB1YmxpYyBUTVBDb2x1bW5zTGlzdDogRXNUYWJsZUNvbHVtbltdID0gW107XHJcbiAgICAvKiogVmFsb3JlIGRlbCBjaGVjayBnbG9iYWxlIGRpIHZpc2liaWxpdMOgIHZhbGlkbyBwZXIgdHV0dGUgbGUgY29sb25uZSBpbiAqKkNvbHVtbnNMaXN0KiogKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDb2xWaXNDaGVjayA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0ZSBsZSBudW92ZSBkaXJldHRpdmUgIGFzc2VnbmF0aSBhIGRpcmV0dGl2YSAoUGVyIGxhIG1vZGFsaXTDoCBkaW5hbWljYSBkZWxsJ2VzLXRhYmxlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihFc1RkRGlyZWN0aXZlKSBFc1Rkc0RpcmVjdGl2ZTogUXVlcnlMaXN0PEVzVGREaXJlY3RpdmU+O1xyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRpIGdsaSBlcy10ZCBhc3NlZ25hdGkgYSBkaXJldHRpdmEgKFBlciBsYSBtb2RhbGl0w6AgZGluYW1pY2EgZGVsbCdlcy10YWJsZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oRXNUaERpcmVjdGl2ZSkgRXNUaHNEaXJlY3RpdmU6IFF1ZXJ5TGlzdDxFc1RoRGlyZWN0aXZlPjtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0aSBnbGkgZXMtdGggKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBFc1RoKSkgcHJpdmF0ZSBFc1RoczogUXVlcnlMaXN0PEVzVGg+O1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRpIGdsaSBlcy10ZCAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IEVzVGQpKSBwcml2YXRlIEVzVGRzOiBRdWVyeUxpc3Q8RXNUZD47XHJcbiAgICAvKiogQGRlcHJlY2F0ZWQgUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIGRlbCBib2R5IChwdW50byBkZWxsYSB0YWJlbGxhIGRvdmUgdmVuZ29ubyBtb3N0cmF0ZSBsZSByaWdoZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2JvZHknLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGJvZHlSZWY6IGFueTtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgZGVsbCdoZWFkZXIgKHB1bnRvIGRlbGxhIHRhYmVsbGEgZG92ZSB2ZW5nb25vIG1vc3RyYXRlIGxlIGludGVzdGF6aW9uaSBkZWxsZSByaWdoZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2hlYWRlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgaGVhZGVyUmVmOiBhbnk7XHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIHN1bCByYWdncnVwcGFtZW50byBkZWdsaSBoZWFkZXIgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2hlYWRlckdyb3VwJywgeyBzdGF0aWM6IGZhbHNlIH0pIHB1YmxpYyBoZWFkZXJHcm91cFJlZjogYW55O1xyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIGxlIGluZm9ybWF6aW9uaSBzdWwgcmFnZ3J1cHBhbWVudG8gZGkgc2Vjb25kbyBsaXZlbGxvIGRlZ2xpIGhlYWRlciAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnc2Vjb25kYXJ5SGVhZGVyR3JvdXAnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIHNlY29uZGFyeUhlYWRlckdyb3VwUmVmOiBhbnk7XHJcbiAgICAvKiogT3B6aW9uaSBleHRyYSBjaGUgZGV2b25vIGFwcGFyaXJlIG5lbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhLCByaWNoaWFtYXRvIGRhaSAzIHBhbGxpbmkgdmVydGljYWxpICovXHJcbiAgICBASW5wdXQoKSBDb3JuZXJNZW51T3B0aW9uczogQ29ybmVyTWVudU9wdGlvbltdID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgZGV2J2Vzc2VyZSBwb3NzaWJpbGUgZWZmZXR0dWFyZSBpbCByZXNpemUgZGVsbGUgY29sb25uZSAqL1xyXG4gICAgQElucHV0KCkgQ29sdW1uc1Jlc2l6YWJsZTogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIGRldidlc3NlcmUgZGlzcG9uaWJpbGUgaWwgc2lzdGVtYSBkaSBhZ2dpb3JuYW1lbnRvIGF1dG9tYXRpY28gKi9cclxuICAgIEBJbnB1dCgpIEF1dG9VcGRhdGU6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgbGEgdGFiZWxsYSAoY29uZmlndXJhdGEgY29uICoqVXNlQ3VzdG9tQ2VsbHMqKikgZGV2ZSBtZXR0ZXJzaSBpbiBhc2NvbHRvIHBlciBpIGNsaWNrIHN1bGxlIGNlbGxlIGRlc2lkZXJhdGVcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBVc2VDdXN0b21DZWxsQWN0aW9uczogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2EgbGUgY2VsbGUgZGVzaWRlcmF0ZSBzdSBjdWkgaW50ZXJjZXR0YXJlIGkgY2xpY2suIEF0dGl2YSBzb2xvIHF1YW5kbyAqKlVzZUN1c3RvbUNlbGxBY3Rpb25zKiogw6ggdHJ1ZS5cclxuICAgICAqIE9nbmkgY2VsbGEgZGV2J2Vzc2VyZSBzZXBhcmF0YSBkYWxsYSBzdWNjZXNzaXZhIGRhbCBjYXJhdHRlcmUgZGVsIFNpbW9sZW9uOlxyXG4gICAgICpcclxuICAgICAqIEVzLCBcIk1pYUNlbGxhMcKnTWlhQ2VsbGEyXCJcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBDdXN0b21DZWxsQWN0aW9uc09uID0gJyc7XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogU2VydmUgcGVyIGRlY2lkZXJlIGRpIGxhbmNpYXJlIG8gbWVubyBpbCAqKmV2ZW50LnN0b3BQcm9wYWdhdGlvbigpKiogYWwgdGVybWluZSBkZWxsYSBnZXN0aW9uZSBkZWxsJ2V2ZW50byBcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBDZWxsQWN0aW9uUHJvcGFnYXRlcyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNpZGUgc2UgdXRpbGl6emFyZSBvIG1lbm8gbGUgQ3VzdG9tQ2VsbHMuIEltcG9zdGFuZG9sbyBhICoqdHJ1ZSoqIGwnZXMtdGFibGUgZGl2ZW50YSBpbiBncmFkbyBkaSBnZXN0aXJlIG5hdGl2YW1lbnRlOlxyXG4gICAgICpcclxuICAgICAqIDEpIE9yZGluYW1lbnRvIGUgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIDIpIE9yZGluYW1lbnRvIGRlaSBkYXRpXHJcbiAgICAgKlxyXG4gICAgICogMykgTW9kYWxpdMOgIEdlcmFyY2hpY2FcclxuICAgICAqXHJcbiAgICAgKiBlY2MuLi5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgVXNlQ3VzdG9tQ2VsbHM6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIGRpIGltcG9zdGFyZSBsJ2FsdGV6emEgbWFzc2ltYSBkZWxsYSB0YWJlbGxhLiBTZSBudWxsIGxhIGRpbWVuc2lvbmUgc2kgYWRhdHRhIGFsIG51bWVybyBkaSBlbGVtZW50aSBhdHR1YWxtZW50ZSBpbiB2aXN1YWxpenphemlvbmUgKi9cclxuICAgIEBJbnB1dCgpIE1heEhlaWdodDogbnVtYmVyID0gbnVsbDtcclxuICAgIC8qKiBDbGFzc2kgZGEgYXBwbGljYXJlIGFsIGNvbnRlbml0b3JlIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIENvbnRhaW5lckNsYXNzID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBvIG1lbm8gbCdleHBvcnQgaW4gZm9ybWF0byBYTFNYICovXHJcbiAgICBASW5wdXQoKSBYTFNYRXhwb3J0OiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBvIG1lbm8gbCdleHBvcnQgaW4gZm9ybWF0byBDU1YgKi9cclxuICAgIEBJbnB1dCgpIENTVkV4cG9ydCA9IHRydWU7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgdmlzdWFsaXp6YXJlIG8gbWVubyBsJ29wemlvbmUgZGkgcGFnaW5hemlvbmUgXCJUdXR0aVwiICovXHJcbiAgICBASW5wdXQoKSBBbGxTZWFyY2ggPSBudWxsO1xyXG4gICAgLyoqIERpbWludWlzY2UgZ2xpIHNwYXppIGZyYSB1bmEgY2VsbGEgZSBsJ2FsdHJhLCBlIGludGVybmFtZW50ZSBpbCBwYWRkaW5nIGRlbCBmb250IGluIG1vZG8gZGEgcHJlc2VudGFyZSBtb2x0aSBwacO5IGRhdGkgaW4gdW4ndW5pY2EgcGFnaW5hICovXHJcbiAgICBASW5wdXQoKSBIaWdoQ2VsbERlbnNpdHk6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEFiaWxpdGEgbyBtZW5vIGxhIHBvc3NpYmlsaXTDoCBkaSBzZWxlemlvbmFyZSBvZ2dldHRpICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3Rpb246IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIE1vc3RyYSBvIG1lbm8gdW4gbWVzc2FnZ2lvIGRpIExvYWRpbmcgYWwgcHJpbW8gY2FyaWNhbWVudG8gZGVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgU2hvd0xvYWRpbmdPbkJvb3RzdHJhcDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogU2UgaW1wb3N0YXRvIGEgKip0cnVlKiogYWdnaXVuZ2UgdW5hIGNvbG9ubmEgY29uIHB1bHNhbnRlIGRpIGVsaW1pbmF6aW9uZSBwZXIgZWZmZXR0dWFyZSBsJ2VsaW1pbmEgZGVsbCdvZ2dldHRvIHJlbGF0aXZvICovXHJcbiAgICBASW5wdXQoKSBSZW1vdmFsOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbmRpemlvbmUgY2hlIG5hc2NvbmRlIGwnaWNvbmEgZGkgZWxpbWluYXppb25lIGluc2VyaXRhIGltcG9zdGFuZG8gKipSZW1vdmFsKiogYSB0cnVlIHF1YWxvcmEgbGEgY29uZGl6aW9uZSBub24gdmVuaXNzZSByaXNwZXR0YXRhXHJcbiAgICAgKlxyXG4gICAgICogQ29tZSBjb25kaXppb25lIHNpIGNvbnNpZGVyYSB1biBzZW1wbGljZSBjYW1wbyBzdSBjdWkgZWZmZXR0dWFyZSB1biBjb250cm9sbG8gYm9vbGVhbm8sIGNvbWUgYWQgZXNlbXBpbyBcImNhbnJlbW92ZVwiXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFJlbW92YWxDb25kaXRpb24gPSAnJztcclxuICAgIC8qKiBJbmRpY2Egc2UgYWJpbGl0YXJlIGxhIHBvc3NpYmlsaXTDoCBkaSBlc3BvcnRhcmUgbGEgdmlzdGEgZGF0aSBhdHR1YWxlICovXHJcbiAgICBASW5wdXQoKSBFeHBvcnQ6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBwZXJtZXR0ZXJlIGxhIHNlbGV6aW9uZSBtdWx0aXBsYSBXaW5kb3dzLWxpa2UgY2xpY2NhbmRvIHVuIG9nZ2V0dG8gZSBmYWNlbmRvIHBvaSBTaGlmdCArIGNsaWNrIHN1IHVuIG9nZ2V0dG8gc3VjY2Vzc2l2byAqL1xyXG4gICAgQElucHV0KCkgU2hpZnRDbGljazogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIGlsIHRlc3RvIGNoZSB2YSBhIHNvc3RpdHVpcmUgXCJPZ2dldHRpIFZpc3VhbGl6emF0aVwiIGluIGNhc28gc2kgc3RpYSBmYWNlbmRvIHF1YWxjb3NhIGRpIGN1c3RvbSAqL1xyXG4gICAgQElucHV0KCkgQ291bnRMYWJlbDogc3RyaW5nID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgbmFzY29uZGVyZSBvIG1vc3RyYXJlIGlsIGNvbXBvbmVudGUgZGkgcGFnaW5hemlvbmUgKi9cclxuICAgIEBJbnB1dCgpIEhpZGVQYWdpbmc6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaWwgY29udGVnZ2lvIGRlZ2xpIGVsZW1lbnRpIHRyb3ZhdGkgKi9cclxuICAgIEBJbnB1dCgpIEhpZGVQYWdpbmdDb3VudDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgbyBtb3N0cmFyZSBpIHB1bHNhbnRpIGRpIHBhZ2luYXppb25lICovXHJcbiAgICBASW5wdXQoKSBIaWRlUGFnaW5nQnV0dG9uczogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUmlmZXJpbWVudG8gYWwgQ29udGV4dE1lbnUgKG5neC1jb250ZXh0bWVudSkgYXNzb2NpYXRvIGFsIGNsaWNrIGRlc3RybyBkaSB1bm8gbyBwacO5IGVsZW1lbnRpIHNlbGV6aW9uYXRpIG5lbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIENvbnRleHRNZW51OiBDb250ZXh0TWVudUNvbXBvbmVudCA9IG51bGw7XHJcbiAgICAvKiogTm9tZSBkZWxsJ2VzcG9ydGF6aW9uZSBnZW5lcmF0YSBkYSBxdWVzdGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgRXhwb3J0RmlsZU5hbWUgPSAnRXhwb3J0LmNzdic7XHJcbiAgICAvKiogQ2xhc3NlIChIVE1MKSBkaSBkZWZhdWx0IGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIFRhYmxlQ2xhc3MgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgZGEgdXRpbGl6emFyZSBpbiBlc3BvcnRhemlvbmUuIE5lbCBmb3JtYXRvIFwiUmVwb3J0XCIgYXZyw6AgdW4gdW5pY28gcGFyYW1ldHJvIFwiRm9ybWF0b1wiIGUgbmVzc3VuIHZhbG9yZSBkaSByaXRvcm5vLlxyXG4gICAgICpcclxuICAgICAqIE5lbCBmb3JtYXRvIFwiVmlld1wiIGhhIGNvbWUgcGFyYW1ldHJvIHVuYSBjYWxsYmFjayBjb24gaSBkYXRpIGNvbXBsZXRpIGRhIGVzcG9ydGFyZSAoZGF0byBjaGUgZGkgZGVmYXVsdCBsYSByaWNlcmNhIMOoIHBhZ2luYXRhKVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBFeHBvcnRGdW5jdGlvbjogYW55O1xyXG4gICAgLyoqIEluZGljYSBsYSBwcmVzZW56YSBkaSByYWdncnVwcGFtZW50aSBhIGxpdmVsbG8gZGkgaGVhZGVyICovXHJcbiAgICBASW5wdXQoKSBIYXNIZWFkZXJHcm91cDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIGxhIHByZXNlbnphIGRpIHJhZ2dydXBwYW1lbnRpIGEgbGl2ZWxsbyBkZWwgcmFnZ3J1cHBhbWVudG8gcHJlY2VkZW50ZW1lbnRlIGVzaXN0ZW50ZSwgY2hpYXJhbWVudGUgw6ggaW5zZW5zYXRhIHNlbnphICoqSGFzSGVhZGVyR3JvdXAqKiAqL1xyXG4gICAgQElucHV0KCkgSGFzU2Vjb25kYXJ5SGVhZGVyR3JvdXA6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFV0aWxpenphdG8gcGVyIGRpdmlkZXJlIGxhIHNvcmdlbnRlIGluIG1vZGFsaXTDoCBFbmRsZXNzU2Nyb2xsICovXHJcbiAgICBASW5wdXQoKSBTbGljZVNpemUgPSAxMDA7XHJcbiAgICAvKiogRGVjaWRlIHNlIHV0aWxpenphcmUgbGEgbW9kYWxpdMOgIGRpIEVuZGxlc3NTY3JvbGwgKi9cclxuICAgIEBJbnB1dCgpIEVuZGxlc3NTY3JvbGw6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFF1YWxvcmEgKipFbmRsZXNzU2Nyb2xsKiogZm9zc2UgdHJ1ZSwgaW5kaWNhIHNlIHV0aWxpenphcmUgcXVlc3RhIG1vZGFsaXTDoCBzb2xvIHF1YW5kbyBzaSBjZXJjYSBwZXIgXCJUdXR0aVwiIG8gaW4gZ2VuZXJhbGUgKi9cclxuICAgIEBJbnB1dCgpIEVuZGxlc3NTY3JvbGxPbmx5Rm9yQWxsID0gdHJ1ZTtcclxuICAgIC8qKiBJbmRpY2Egc2UgbmFzY29uZGVyZSBnbGkgSGVhZGVyIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIEhlYWRlckhpZGRlbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgaWwgQm9keSBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBCb2R5SGlkZGVuOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBzZSBsYSBzZWxlemlvbmUgw6ggdGVtcG9yYW5lYW1lbnRlIGRpc2FiaWxpdGF0YS4gUmlzcGV0dG8gYWxsJ0lucHV0ICoqU2VsZWN0aW9uKiogY2hlIHZpc2l2YW1lbnRlIGdlc3Rpc2NlIHNlIGNpIHNvbm8gbyBubyBnbGkgaW5wdXQgZGkgc2VsZXppb25lLFxyXG4gICAgICogcXVlc3RvIElucHV0IGdlc3Rpc2NlIHNlIHF1ZXN0aSBpbnB1dCBzb25vIGFiaWxpdGF0aSBvIG1lbm9cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2VsZWN0aW9uRGlzYWJsZWQ6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIGZvcnphcmUgaWwgc2lzdGVtYSBkaSBzZWxlemlvbmUgYSBnZXN0aXJlIHVuIGVsZW1lbnRvIHBlciB2b2x0YS5cclxuICAgICAqIFNlbGV6aW9uYXJlIHVuJ2FsdHJhIHJpZ2EgY29uIHVuYSBnacOgIHNlbGV6aW9uYXRhIGFwcGxpY2hlcsOgIGxhIHNlbGV6aW9uZSBhbGxhIG51b3ZhIHJpZ2EsIHJpbXVvdmVuZG9sYSBkYWxsJ2F0dHVhbGVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2luZ2xlU2VsZWN0aW9uOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBDYWxsYmFjayBjaGUgZGF0byB1biBvZ2dldHRvIHJlc2l0dWlzY2UgbCdldmVudHVhbGUgY2xhc3NlIGRhIGFwcGxpY2FyZSBhbGxhIHJpZ2EgY29sbGVnYXRhIGFsbCdvZ2dldHRvICovXHJcbiAgICBASW5wdXQoKSBSb3dDbGFzc0Fzc2lnbmVyOiBhbnkgPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIGRpIG9yZGluYXJlIGkgZGF0aSBpbiBtYW5pZXJhIGRpc2NlbmRlbnRlIG8gYXNjZW5kZW50ZSAqL1xyXG4gICAgQElucHV0KCkgT3JkZXJCeUNvbHVtbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgYXZlcmUgcGnDuSBkaXJldHRpdmUgZGkgb3JkaW5hbWVudG8gZGVpIGRhdGkgKi9cclxuICAgIEBJbnB1dCgpIE11bHRpcGxlT3JkZXJpbmdEaXJlY3RpdmVzID0gdHJ1ZTtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSBuYXNjb25kZXJlIGxlIGNvbG9ubmUgaW4gYmFzZSBhbGxlIHNlbGV6aW9uaSBlZmZldHR1YXRlIGRhbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhICovXHJcbiAgICBASW5wdXQoKSBIaWRkZW5Db2x1bW5zOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSByaW9yZGluYXJlIGxlIGNvbG9ubmUgaW4gYmFzZSBhbGxlIGltcG9zdGF6aW9uaSBlZmZldHR1YXRlIGRhbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhICovXHJcbiAgICBASW5wdXQoKSBDb2x1bW5zT3JkZXJpbmc6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEV2ZW50dWFsZSBzdXBwb3J0byBhbGxlIHJpY2VyY2hlIGFwcGxpY2F0ZSBhbGxhIG1vZGFsaXTDoCBBcnJheSAqL1xyXG4gICAgQElucHV0KCkgU2VhcmNoVmlldyA9IG51bGwgYXMgQXBwU2VhcmNoPGFueT47XHJcbiAgICAvKiogQWJpbGl0YSBvIGRpc2FiaWxpdGEgaWwgc2lzdGVtYSBjaGUgcGVybWV0dGUgZGkgc2VsZXppb25hcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIG5lbGxhIHZpc3RhICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3RBbGw6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFNpbXVsYSBsYSBwYWdpbmF6aW9uZSBhbmNoZSBwZXIgbGUgdGFiZWxsZSBjaGUgZnVuemlvbmFubyBpbiBtb2RhbGl0w6AgQXJyYXkgKi9cclxuICAgIEBJbnB1dCgpIFVzZUFycmF5TW9kZVBhZ2luZyA9IHRydWU7XHJcbiAgICAvKiogRGVmaW5pemlvbmUgZGkgY29sb25uZSBkaW5hbWNoZSBwZXIgbGEgbW9kYWxpdMOgLCBhcHB1bnRvLCBkaW5hbWljYSAqL1xyXG4gICAgQElucHV0KCkgRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uOiBFc1RhYmxlQ29sdW1uc0RlZmluaXRpb25bXSA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIG9wZXJhemlvbmkgZGluYW1pY2hlIGdlbmVyaWNoZSBjaGUgcG9zc29ubyBlc3NlcmUgZWZmZXR0dWF0ZSBwZXIgcmlnYS4gQXBwYWlvbm8gY29tZSBjb2xvbm5lIGV4dHJhIHN1bCBsYXRvIHNpbmlzdHJvIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIER5bmFtaWNPcGVyYXRpb25zOiBFc1RhYmxlT3BlcmF0aW9uRGVmaW5pdGlvbltdID0gW107XHJcbiAgICAvKiogSW5kaWNhIHNlIHZpc3VhbGl6emFyZSBpIGRhdGkgaW4gbWFuaWVyYSBnZXJhcmNoaWNhICovXHJcbiAgICBASW5wdXQoKSBIaWVyYXJjaHk6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIE5vbWUgZGVsbGEgcHJvcHJpZXTDoCBjaGUgY29udGllbmUgbCdJRCBkZWwgcGFkcmUuIERhIHV0aWxpenphcmUgc2UgKipIaWVyYXJjaHkqKiDDqCBpbXBvc3RhdG8gKi9cclxuICAgIEBJbnB1dCgpIFBhcmVudEtleSA9ICcnO1xyXG4gICAgLyoqIE5vbWUgZGVsbGEgcHJvcHJpZXTDoCBjaGUgY29udGllbmUgbCdJRCBkZWxsJ29nZ2V0dG8gYXR0dWFsZS4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgT3duS2V5ID0gJyc7XHJcbiAgICAvKiogSW5kaWNhIHNlIHBhcnRpcmUgY29uIHVuIGFsYmVybyBlc3BhbnNvLiBEYSB1dGlsaXp6YXJlIHNlICoqSGllcmFyY2h5Kiogw6ggaW1wb3N0YXRvICovXHJcbiAgICBASW5wdXQoKSBTdGFydHNFeHBhbmRlZCA9IHRydWU7XHJcbiAgICAvKiogSW5kaWNhIHNlIGVmZmV0dHVhcmUgaWwgc2FsdmF0YWdnaW8gZGVsbGUgcHJlZmVyZW56ZSBkaSByaWNlcmNhICovXHJcbiAgICBASW5wdXQoKSBTYXZlUHJlZmVyZW5jZXM6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2EgZG92ZSB2aXN1YWxpenphcmUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lLCBzZSBzb3ByYSwgc290dG8gbyBpbiBlbnRyYW1iaSAqL1xyXG4gICAgQElucHV0KCkgUGFnaW5nU3R5bGU6ICdib3RoJyB8ICd0b3AnIHwgJ2JvdHRvbScgPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBkb3ZlIHZpc3VhbGl6emFyZSBsZSBpbmZvcm1hemlvbmkgZGkgcGFnaW5hemlvbmUsIHNlIHNvcHJhLCBzb3R0byBvIGluIGVudHJhbWJpICovXHJcbiAgICBASW5wdXQoKSBSb3dHcm91cGluZ1BhZ2luZ1N0eWxlOiAnbGVmdCcgfCAncmlnaHQnID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNvcmdlbnRlIGRhdGkgc2Vjb25kYXJpYVxyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphdG8gc29sbyBwZXIgdW4gY2FzbyBwYXJ0aWNvbGFyZSBkZWwgTWV0ZXJpbmdcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2Vjb25kYXJ5U291cmNlOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNvcmdlbnRlIGRhdGkgc2Vjb25kYXJpYVxyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphdG8gc29sbyBwZXIgdW4gY2FzbyBwYXJ0aWNvbGFyZSBkZWwgTWV0ZXJpbmdcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgVGVydGlhcnlTb3VyY2U6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSB1dGlsaXp6YXJlIGxhIGNhY2hlIGRpIHNlbGV6aW9uZSBjaGUgcGVybWV0dGUgZGkgbWFudGVuZXJlIGdsaSBzdGF0aSBkaSBzZWxlemlvbmUgZGVpIHZhcmkgb2dnZXR0aSBuYXZpZ2FuZG8gZGEgdW5hIHBhZ2luYSBhbGwnYWx0cmEgKi9cclxuICAgIEBJbnB1dCgpIFVzZVNlbGVjdGlvbkNhY2hlID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSBkZWNpZGVyZSBzZSwgaW4gbW9kYWxpdMOgIHJhZ2dydXBwYW1lbnRvLCBtb3N0cmFyZSBvIG1lbm8gaWwgdmFsb3JlIGRlbGxlIGNvbG9ubmUgZGkgZ3J1cHBvIG5lZ2xpIG9nZ2V0dGkgZmluYWxpLiBEaSBkZWZhdWx0IHNvbm8gbmFzY29zdGkgKi9cclxuICAgIEBJbnB1dCgpIFNob3dJdGVtR3JvdXBzQ29sdW1ucyA9IG51bGw7XHJcbiAgICAvKiogRXZlbnRvIGNoZSB2aWVuZSByaWNoaWFtYXRvIGFsIGNhbWJpbyBkaSBvcmlkbmFtZW50byBkaSB1bmEgY29sb25uYSAqL1xyXG4gICAgQE91dHB1dCgpIG9uT3JkZXJDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8QXBwT3JkZXJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxBcHBPcmRlcmluZz4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEV2ZW50byBjaGUgdmllbmUgcmljaGlhbWF0byBxdWFuZG8gbCdlcy10YWJsZSByaXRpZW5lIHNpYSBuZWNlc3NhcmlvIHJpLWVmZmV0dHVhcmUgbGEgcmljZXJjYS5cclxuICAgICAqIElsIGJvb2xlYW5vIGRlbGwnZXZlbnRvIGluZGljYSBzZSB2aWVuZSBzdWdnZXJpdG8gZGkgcmVzZXR0YXJlIGxhIHBhZ2luYSBvIG1lbm8uXHJcbiAgICAgKiBcclxuICAgICAqIFNvbG8gaW4gY2FzbyB2ZW5nYSB1dGlsaXp6YXRhIGxhIG1vZGFsaXTDoCBhIHJhZ2dydXBwYW1lbnRpIGRpIHJpZ2hlIHB1w7Igc3VjY2VkZXJlIGNoZSBsJ2VzLXRhYmxlIHBhc3NpIHVuIGludGVybyBBcHBTZWFyY2ggY29tZSBwYXJhbWV0cm8gZGkgcmljZXJjYSxcclxuICAgICAqIGluIHF1ZWwgY2FzbyBsJ2FwcGxpY2F6aW9uZSByaWNldmVudGUgZG92csOgIG9ub3JhcmUgbGEgcmljaGllc3RhIHNwZWRlbmRvIGFsIGJhY2thbmQgbCdvZ2dldHRvIGRpIHJpY2VyY2EgQVMtSVNcclxuICAgICAqIFxyXG4gICAgICogaWwgdGlwbyBkZWxsJ0VtaXR0ZXIgaW52ZWNlIGRpIGVzc2VyZSBbYm9vbGVhbiB8IEFwcFNlYXJjaDxhbnk+XSDDqCBzdGF0byBpbXBvc3RhdG8gYSBcImFueVwiIHBlciBldml0YXJlIHByb2JsZW1pIGRpIHJldHJvY29tcGF0aWJpbGl0w6BcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpIG9uU2VhcmNoUmVxdWVzdDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIC8qKiBFdmVudG8gY2hlIHBhcnRlIGFkIG9nbmkgbW9kaWZpY2EgZGkgXCJjaGVja2FnZ2lvXCIgaW4gZm9ybWEgZGkgY29tb2RvIGFycmF5LiBFc3BvbmUgbCdvZ2dldHRvIGNvbiBsbyBzdGF0byBkaSBjaGVjayBhdHR1YWxlICovXHJcbiAgICBAT3V0cHV0KCkgb25TZWxlY3Rpb25DaGFuZ2VkOiBFdmVudEVtaXR0ZXI8SXRlbXNTZWxlY3Rpb248YW55Pj4gPSBuZXcgRXZlbnRFbWl0dGVyPEl0ZW1zU2VsZWN0aW9uPGFueT4+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gYWxsJ2VsaW1pbmF6aW9uZSBkaSB1biBvZ2dldHRvICovXHJcbiAgICBAT3V0cHV0KCkgb25SZW1vdmFsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIGFsbCdhbm51bGxhbWVudG8gZGkgdW4nZWxpbWluYXppb25lICovXHJcbiAgICBAT3V0cHV0KCkgb25BYm9ydFJlbW92YWw6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIGFsIGNsaWNrIHN1IHVuYSBjZWxsYSBxdWFuZG8gKipVc2VDdXN0b21DZWxsQWN0aW9ucyoqIMOoIGF0dGl2byBcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBAT3V0cHV0KCkgb25DZWxsQ2xpY2s6IEV2ZW50RW1pdHRlcjx7IGNvbHVtbjogc3RyaW5nLCBtb2RlbDogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGNvbHVtbjogc3RyaW5nLCBtb2RlbDogYW55IH0+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gcXVhbmRvIHNpIGNsaWNjYSBzdSB1biBvcHppb25lIGRlZmluaXRhIG5lbGxlICoqQ29ybmVyTWVudU9wdGlvbnMqKiAqL1xyXG4gICAgQE91dHB1dCgpIG9uQ29ybmVyQWN0aW9uOiBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nLCBlc3RhYmxlOiBhbnkgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgZXN0YWJsZTogYW55IH0+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gcXVhbmRvIHNpIGNsaWNjYSBzdSB1biBvcHppb25lIGRlZmluaXRhIG5lbGxlICoqRHluYW1pY09wZXJhdGlvbnMqKiAqL1xyXG4gICAgQE91dHB1dCgpIG9uRHluYW1pY09wZXJhdGlvbjogRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgaXRlbTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGl0ZW06IGFueSB9PigpO1xyXG5cclxuICAgIC8qKiBEYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgZGF0YTogYW55W107XHJcbiAgICAvKiogSGVhZGVyIGRlaSBkYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgaGVhZGVyczogYW55W107XHJcbiAgICAvKiogRWxlbWVudG8gSFRNTCBkYSBjbGljY2FyZSBwZXIgbCdlc3BvcnRhemlvbmUgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2V4cG9ydERvd25sb2FkZXInLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGV4cG9ydERvd25sb2FkZXI6IEVsZW1lbnRSZWY7XHJcbiAgICAvKiogUGxhY2Vob2xkZXIgZGkgbWVuw7kgY29udGVzdHVhbGUgcGVyIHF1YW5kbyBub24gY2kgc29ubyBvcHppb25pIG5lbCBwbGFjZWhvbGRlciBcIlZlcm9cIiAgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2VtcHR5TWVudScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyB0YWJsZUVtcHR5TWVudTogQ29udGV4dE1lbnVDb21wb25lbnQ7XHJcblxyXG4gICAgLyoqIFN1YnNjcmlwdGlvbiBzdWxsJ2FwZXJ0dXJhIGRlbCBjb250ZXh0IG1lbnUgZGEgcmlwdWxpcmUgYWwgZGVzdHJveSBkZWxsYSBjbGFzc2UgKi9cclxuICAgIHByaXZhdGUgY3R4TWVudVN1YnNjcmlwdGlvbjogYW55O1xyXG5cclxuICAgIC8qKiBQYWdpbmEgaW4gdmlzdWFsaXp6YXppb25lIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIHB1YmxpYyBhcnJheW1vZGVQYWdlID0gMTtcclxuICAgIC8qKiBOdW1lcm8gZGkgcGFnaW5lIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIHB1YmxpYyBhcnJheW1vZGVQYWdlcyA9IDE7XHJcbiAgICAvKiogT2dnZXR0aSBwZXIgb2duaSBwYWdpbmEgKGR1cmFudGUgbGEgcGFnaW5hemlvbmUgaW4gbW9kYWxpdMOgIEFycmF5KSAqL1xyXG4gICAgQElucHV0KCkgQXJyYXltb2RlSXRlbXNQZXJQYWdlID0gbnVsbDtcclxuICAgIC8qKiBPZ2dldHRvIGRpIHNlbGV6aW9uZSBwZXIgbGEgbW9kYWxpdMOgIEFycmF5LCBjaGUgZGV2ZSBjb21wb3J0YXJzaSBjb21lIGxhIGNvbnRyb3BhcnRlIGluIG1vZGFsaXTDoCBWaWV3ICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlU2VsZWN0aW9uOiBJdGVtc1NlbGVjdGlvbjxhbnk+O1xyXG4gICAgLyoqIENvbG9ubmUgZGEgdmlzdWFsaXp6YXJlIGluIG1vZGFsaXTDoCBhcnJheSAqL1xyXG4gICAgcHVibGljIGFycmF5Q29sdW1uczogc3RyaW5nW10gPSBbXTtcclxuICAgIC8qKiBPcmRpbmUgZGVsbGUgY29sb25uZSBkYSB2aXN1YWxpenphcmUgaW4gbW9kYWxpdMOgIGFycmF5ICovXHJcbiAgICBwdWJsaWMgYXJyYXlDb2x1bW5PcmRlcmluZzogc3RyaW5nW10gPSBbXTtcclxuICAgIC8qKiBPcmRpbmFtZW50aSBBU0MtREVTQyBzdWxsZSBjb2xvbm5lIGluIG1vZGFsaXTDoCBhcnJheSAqL1xyXG4gICAgcHVibGljIGFycmF5T3JkZXJzOiBBcHBPcmRlcmluZ1tdID0gW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBWYXJpYWJpbGUgY2hlIHNlcnZlIGEgZ2VzdGlyZSBpbCBtb21lbnRvIGluIGN1aSBsJ2VzLXRhYmxlIGFnZ2lvcm5hIGxhIHBhZ2luYXppb25lIChwdWxzYW50aSBlY2MpLlxyXG4gICAgICogRXNzZW5kbyBvcGVyYXppb25pIGNvbXVucXVlIGNvc3Rvc2UgbGUgZWZmZXR0dW8gc29sbyBzdSBiaW5kaW5nIGVzdGVybmksIG5vbiBzdSByZXdyaXRlIGdlbmVyYXRpIGludGVybmFtZW50ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGludGVybmFsV3JpdGVDYWxsID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWNoZSBjaGUgY29udGVycsOgIHR1dHRlIGxlIHJpY2VyY2hlIGVmZmV0dHVhdGUgc3UgZ3J1cHBpIGRpdmVyc2kgZGFsIHByaW1vIGUgc3UgZWxlbWVudGkgY29udGVudXRpIG5laSBncnVwcGkuXHJcbiAgICAgKiBJbiBjYXNvIGRpIGNhbWJpIGRpIG9yZGluYW1lbnRvIGRlbGxlIGNvbG9ubmUgZGl2ZXJzZSBkYWxsYSBwcmltYSB0dXR0ZSBsZSBjaGlhbWF0ZSBmYXR0ZSBkYWwgc2Vjb25kbyBsaXZlbGxvIGluIHBvaSBkZXZvbm8gZXNzZXJlIHJpZXNlZ3VpdGUgc2Vjb25kbyBsYSBzZWd1ZW50ZSBsb2dpY2E6XHJcbiAgICAgKiBcclxuICAgICAqIFxyXG4gICAgICogKipDYW1iaW8gb3JkaW5hbWVudG8gc3VsIHByaW1vIGdydXBwbyoqOiByZWxvYWQgY29tcGxldG8sIG5vbiBtaSBvY2N1cG8gZGkgcmlwdWxpcmUgZ2xpIGVsZW1lbnRpIGJpbmRhdGkgaW4gYWxjdW4gbW9kb1xyXG4gICAgICogXHJcbiAgICAgKiAqKkNhbWJpbyBvcmRpbmFtZW50byBzdWxsYSBjb2xvbm5hIHJlbGF0aXZhIGFsbCdOLWVzaW1vIGdydXBwbyoqOiByZWxvYWQgY29tcGxldG8gZGVsIGNvbnRlbnV0byBkZWkgZ3J1cHBpIHByZWNlZGVudGksIHJpcHVsZW5kbyBwcmVjZWRlbnRlbWVudGUgXHJcbiAgICAgKiB0dXR0aSBnbGkgZWxlbWVudGkgY29uICoqX2dyb3VwbGV2ZWwqKiA9IE5cclxuICAgICAqIFxyXG4gICAgICogKipDYW1iaW8gb3JkaW5hbWVudG8gc3UgdW5hIGNvbG9ubmEgbm9uIHJhZ2dydXBwYXRhKio6IHJlbG9hZCBjb21wbGV0byBwZXIgdHV0dGkgaSBncnVwcGkgZmluYWxpIGFwZXJ0aSwgZGV2byBwcmVjZWRlbnRlbWVudGUgcmlwdWxpcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIGNvbiAqKl9pdGVtKiogPSB0cnVlXHJcbiAgICAgKiBcclxuICAgICAqIEFsdHJpIGV2ZW50aSBub24gZG92cmViYmVybyByYXBwcmVzZW50YXJlIHByb2JsZW1pOlxyXG4gICAgICogLSBTZWxlemlvbmU6IG5vbiBjYW1iaWEgbnVsbGFcclxuICAgICAqIC0gUGFnaW5hemlvbmU6IGNhbWJpYSBhIGxpdmVsbG8gcm9vdCBxdWluZGkgdmllbmUgcmljYXJpY2F0byB0dXR0byBjb211bnF1ZSwgc3Rlc3NvIHZhbGUgcGVyIGxlIHBhZ2luYXppb25pIGludGVybmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZTogeyBwYXRoOiBzdHJpbmcsIHJvdXRlOiBHcm91cFJvdXRlRnJhZ21lbnRbXSwgdmlldzogQXBwU2VhcmNoPGFueT4sIGdyb3VwX2NvbHVtbjogc3RyaW5nIH1bXSA9IFtdO1xyXG5cclxuICAgIC8qKiBWYXJpYWJpbGUgZCdhcHBvZ2dpbyBwZXIgY2FwaXJlIHNlIGMnw6ggYmlzb2dubyBkaSByaS1lZmZldHR1YXJlIHVuYSByaWNlcmNhIG8gbWVubyAqL1xyXG4gICAgcHJpdmF0ZSBSZXNlYXJjaE5lZWRlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgLyoqIENvbG9ubmUgdmlzaWJpbGkgZGVsbGEgdmlzdGEgYXR0dWFsZS4gVmFsb3JpenphdG8gZGkgZGVmYXVsdCBhbCBudW1lcm8gbWFzc2ltbyBkaSBjb2xvbm5lIHN1cHBvcnRhdGUgZGFsbGEgdGFiZWxsYSBwZXIgbGUgY2FzaXN0aWNoZSBpbiBhc3NlbnphIGRpIGN1c3RvbSBjZWxscyAqL1xyXG4gICAgcHVibGljIENvbHVtbnM6IHsgVmlzaWJpbGU6IG51bWJlciwgVmlzaWJsZVVucGlubmVkOiBudW1iZXIsIEdsb2JhbDogbnVtYmVyIH0gPSB7IFZpc2liaWxlOiAxMDAsIFZpc2libGVVbnBpbm5lZDogMTAwLCBHbG9iYWw6IDEwMCB9O1xyXG4gICAgLyoqIEluIGNhc28gZGkgUm93IEdyb3VwaW5nIHF1aSB2aWVuZSBzYWx2YXRhIGxhIHZpc3RhIHByaW5jaXBhbGUgZGVpIGdydXBwaSBiYXNlICovXHJcbiAgICBwdWJsaWMgTWFpbkdyb3VwVmlldzogQXBwU2VhcmNoPGFueT4gPSBudWxsO1xyXG4gICBcclxuICAgIC8qKiBDb250ZWdnaW8gYmFzZSBkZWdsaSBvZ2dldHRpLiBJbiBtb2RhbGl0w6Agbm9ybWFsZSB2aWVuZSByZXNldHRhdG8gYWQgb2duaSBudW92YSBWaWV3IGluc2VyaXRhLCBpbiBtb2RhbGl0w6AgUm93R3JvdXBpbmcgdmllbmUgcmVzZXR0YXRvIHNvbG8gYWQgdW5hIG51b3ZhIFZpZXcgZGkgbGl2ZWxsbyBcIjBcIiAqL1xyXG4gICAgcHVibGljIEJhc2VJdGVtc0NvdW50ID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIGNpIHNvbm8gZGVsbGUgY29sb25uZSBwaW5uYXRlIGUgdmlzaWJpbGkuIFNlcnZlIHBlciBwb3RlciBzZXR0YXJlIHR1dHRlIGxlIGNvbG9ubmUgcHJpbWEgY2hlIGFycml2aW5vIGRhdGkgYSBwaW5uZWQqL1xyXG4gICAgcHVibGljIEhhc1Bpbm5lZENvbHVtbnM6IGJvb2xlYW5cclxuICAgIC8qKiBMYXJnaGV6emEgY2FsY29sYXRhIGRlbCBjb250YWluZXIgZGVsbGUgY29sb25uZSBwaW5uYXRlICovXHJcbiAgICBwdWJsaWMgUGlubmVkQ29udGFpbmVyV2lkdGg6IG51bWJlcjtcclxuICAgIC8qKiBJbmRpY2Egc2Ugbm9ub3N0YW50ZSBzaWFtbyBpbiBtb2RhbGl0w6AgYXJyYXkgc29ubyBzdGF0aSBpbmRpdmlkdWF0aSBkZWkgZ3J1cHBpLiBJbiB0YWwgY2FzbyBlcy10YWJsZSBzaSBjb21wb3J0YSBkYSBwc2V1ZG8gYmFja2VuZCBlZCBlZmZldHR1YSBsZSBhZ2dyZWdhemlvbmkgZSByYWdncnVwcGFtZW50aSBjb21wbGV0YW1lbnRlIGxhdG8gY2xpZW50ICovXHJcbiAgICBwdWJsaWMgQXJyYXlHcm91cGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBPcHppb25pIGRpIHBhZ2luYXppb25lICovXHJcbiAgICBwdWJsaWMgUGFnZXJPcHRpb25zOiB7IFBhZ2VyQ291bnQ6IG51bWJlciwgU2hvd0NvdW50OiBib29sZWFuLCBTaG93UGFnaW5nOiBib29sZWFuLCBVc2VzVmlldzogYm9vbGVhbiwgU2hvd0J1dHRvbnM6IGJvb2xlYW4sIFNob3dQYWdpbmdPcHRpb25zOiBib29sZWFuLCBWaWV3OiBhbnksIFJlYWR5OiBib29sZWFuLCBTZWFyY2hlczogJ2l0ZW1zJyB8ICdncm91cHMnIH0gPVxyXG4gICAgICAgIHsgUGFnZXJDb3VudDogbnVsbCwgU2hvd0NvdW50OiB0cnVlLCBTaG93UGFnaW5nOiB0cnVlLCBTaG93QnV0dG9uczogdHJ1ZSwgU2hvd1BhZ2luZ09wdGlvbnM6IHRydWUsIFVzZXNWaWV3OiB0cnVlLCBWaWV3OiBudWxsLCBSZWFkeTogZmFsc2UsIFNlYXJjaGVzOiAnaXRlbXMnIH07XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcclxuICAgICAgICAvL1BlciBwb3RlciBjYW1iaWFyZSBpbCBsYXlvdXQgaW4gYmFzZSBhbCBsaXZlbGxvIGdlcmFyY2hpY28gaWwgY29tcG9uZW50ZSBkZXZhIGF2ZXJlIGlsIHBpZW5vIGNvbnRyb2xsbyBkaSBvZ25pIGNlbGxhLFxyXG4gICAgICAgIC8vY2hlIGNvbiBzb2xvIGxhIHByb2llemlvbmUgKHNlbnphIGNlbGxlIGN1c290bSkgbm9uIMOoIGRpc3BvbmliaWxlXHJcbiAgICAgICAgaWYgKHRoaXMuSGllcmFyY2h5ICYmICF0aGlzLlVzZUN1c3RvbUNlbGxzKVxyXG4gICAgICAgICAgICB0aHJvdyBcIkVzLXRhYmxlIGVycm9yOiBQZXIgcG90ZXIgdXRpbGl6emFyZSBsJ2VzLXRhYmxlIGNvbiBbSGllcmFyY2h5XT1cXFwidHJ1ZVxcXCIgw6ggcmljaGllc3RvIGFuY2hlIFtVc2VDdXN0b21DZWxsc109XFxcInRydWVcXFwiXCI7XHJcblxyXG4gICAgICAgIC8vIGNsaWNrIGRlc3RybyBzdSB1bmEgcmlnYSBjb24gc2VsZXppb25lIGF0dGl2YTogVGlybyBmdW9yaSBpbCBjb250ZXh0IG1lbnUgZSBzZWxlemlvbmUgbCdlbGVtZW50byBjb3JyZW50ZVxyXG4gICAgICAgIHRoaXMuY3R4TWVudVN1YnNjcmlwdGlvbiA9ICh0aGlzLkNvbnRleHRNZW51IHx8IHRoaXMudGFibGVFbXB0eU1lbnUpLm9wZW4uc3Vic2NyaWJlKHQgPT4ge1xyXG4gICAgICAgICAgICAvLyBHcnVwcGkgdmEgYmVuZSwgb2dnZXR0aSBwdXJlLCBtYSBzZXBhcmF0b3JpIGZyYSBncnVwcGkgcHJvcHJpbyBuby4uLlxyXG4gICAgICAgICAgICBpZiAodC5pdGVtLl9zZXApIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGxldCBzaG91bGRFbWl0ID0gIXQuaXRlbS5fc2VsZWN0ZWQ7XHJcblxyXG4gICAgICAgICAgICB0Lml0ZW0uX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdmFyIGl0ZW1TZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbl9ILmhhbmRsZUl0ZW1zU2VsZWN0aW9uKFt0Lml0ZW1dKTtcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2hvdWxkRW1pdClcclxuICAgICAgICAgICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkLmVtaXQoaXRlbVNlbGVjdGlvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAgICAgLy8gU2UgdXRpbGl6em8gbGEgbmV3IHNwaWN5IG1vZGUgZGVkdWNvIHR1dHRpIGkgcGFyYW1ldHJpIGRpIGxhdm9ybyBwb3NzaWJpbGkgYWwgY2FyaWNhbWVudG8gZGVsbGEgdGFiZWxsYVxyXG4gICAgICAgIC8vIFZlbmdvbm8gc292cmFzY3JpdHRlIHNvbG8gbGUgcHJvcHJpZXTDoCBub24gaW1wb3N0YXRlIGRhbGwndXRlbnRlXHJcbiAgICAgICAgaWYgKHRoaXMuRXNUZHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Rkc0RpcmVjdGl2ZS5sZW5ndGggPiAwICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlVzZUN1c3RvbUNlbGxzID09IG51bGwpIHRoaXMuVXNlQ3VzdG9tQ2VsbHMgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5IaWRkZW5Db2x1bW5zID09IG51bGwgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykgdGhpcy5IaWRkZW5Db2x1bW5zID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuQ29sdW1uc09yZGVyaW5nID09IG51bGwgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykgdGhpcy5Db2x1bW5zT3JkZXJpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5PcmRlckJ5Q29sdW1uID09IG51bGwgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykgdGhpcy5PcmRlckJ5Q29sdW1uID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuU2VsZWN0QWxsID09IG51bGwgJiYgdGhpcy5TZWxlY3Rpb24pIHRoaXMuU2VsZWN0QWxsID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuU2hpZnRDbGljayA9PSBudWxsICYmIHRoaXMuU2VsZWN0aW9uKSB0aGlzLlNoaWZ0Q2xpY2sgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIGlmICh0aGlzLmN0eE1lbnVTdWJzY3JpcHRpb24pXHJcbiAgICAgICAgICAgIHRoaXMuY3R4TWVudVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG5cclxuICAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgIHB1YmxpYyBhc3luYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgbGV0IG5ld1NlYXJjaFZpZXcgPSBjaGFuZ2VzWydTZWFyY2hWaWV3J107XHJcbiAgICAgICAgaWYgKG5ld1NlYXJjaFZpZXcgJiYgdGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLnV0aWxpdGllc19ILmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5TZWFyY2hWaWV3LnBhZ2UsIHRoaXMuU2VhcmNoVmlldy5wYWdlcyB8fCAxLCB0aGlzLlNlYXJjaFZpZXcuaXRlbXMubGVuZ3RoLCB0aGlzLlNlYXJjaFZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbik6IHZvaWQgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuKTogdm9pZCB7IH1cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjaGFuZ2VkKCkgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLlZpZXcpOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHJvcGFnYXRlQ2hhbmdlID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgd3JpdGVWYWx1ZShvYmopOiB2b2lkIHtcclxuICAgICAgICB0aGlzLlZpZXcgPSBvYmogPyBvYmogOiBudWxsO1xyXG5cclxuICAgICAgICAvLyBNaSDDqCBhcnJpdmF0YSBsJ0FwcFNlYXJjaCBxdWluZGkgZGkgc2ljdXJvIG5vbiBobyB1bmEgcmljZXJjYSBpbiBwcm9ncmVzc1xyXG4gICAgICAgIHRoaXMucmVzZWFyY2hJblByb2dyZXNzID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5WaWV3ICYmICF0aGlzLlNlYXJjaFZpZXcpIHtcclxuICAgICAgICAgICAgLy8gU3UgdmlldyBudWxsYSBldml0byBkaSBmYXJlIHByZXNzb2Now6kgcXVhbHNpYXNpIGNvc2EuIFNlIGFycml2YSB1biBudWxsIGRldm8gYW5jaGUgYXNzaWN1cmFybWkgZGkgbm9uIG1vc3RyYXJlIG51bGxhXHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLlRNUEJvdW5kU291cmNlIHx8IFtdO1xyXG5cclxuICAgICAgICAgICAgLy8gUGVyIGVzc2VyZSBzaWN1cm8gY2hlIGRvcG8gdW4gYmluZCBkaSBvZ2dldHRpIGxhIGVzLXRhYmxlIGFnZ2lvcm5pIGxhIGdyYWZpY2FcclxuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIHBlciBzYmFnbGlvIGwnb2dnZXR0byBjaGUgbWkgYXJyaXZhIG5vbiDDqCB0aXBpenphdG8gKGluc3RhbmNlb2YgQXBwU2VhcmNoIHJlc3RpdHVpc2NlIGZhbHNlIGFuY2hlIHNlIMOoIGRlbCB0aXBvIGdpdXN0bylcclxuICAgICAgICAvLyBsbyBjb3JyZWdnby0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAgICAgaWYgKHRoaXMuVmlldyAmJiB0eXBlb2YgKHRoaXMuVmlldyBhcyBhbnkpLnJlc3VsdCAhPSAndW5kZWZpbmVkJyAmJiAhKHRoaXMuVmlldyBpbnN0YW5jZW9mIFJlcG9ydERlZmluaXRpb24pKSBcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBSZXBvcnREZWZpbml0aW9uKCk7XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHR5cGVvZiAodGhpcy5WaWV3IGFzIGFueSkuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgIT0gJ3VuZGVmaW5lZCcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpKSBcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBBcHBTZWFyY2goKTtcclxuICAgICAgICBlbHNlIGlmICh0aGlzLlNlYXJjaFZpZXcgJiYgdHlwZW9mICh0aGlzLlNlYXJjaFZpZXcgYXMgYW55KS5pdGVtc3BlcnBhZ2VvdmVycmlkZSAhPSAndW5kZWZpbmVkJyAmJiAhKHRoaXMuU2VhcmNoVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkpIFxyXG4gICAgICAgICAgICAodGhpcy5TZWFyY2hWaWV3IGFzIGFueSkuX19wcm90b19fID0gbmV3IEFwcFNlYXJjaCgpO1xyXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuVmlldyAmJiB0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSB7XHJcbiAgICAgICAgICAgIC8vIFNlIG1pIGFycml2YSB1bmEgcmVwb3J0IGRlZmluaXRpb24gdnVvbCBkaXJlIGNoZSBwb3RyZWkgYXZlcmUgZGVpIHJpc3VsdGF0aSBkYSB2aXN1YWxpenphcmVcclxuICAgICAgICAgICAgdGhpcy5zZXRNb2RlKCdyZXBvcnQnKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuUmVwb3J0VmFsdWVzID0gdGhpcy5WaWV3LnJlc3VsdDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuUmVwb3J0VmFsdWVzKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXBvcnRNb2RlX0gucmV2aWV3UmVwb3J0QmluZGluZ3MoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHRoaXMuVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkge1xyXG4gICAgICAgICAgICAvLyBTZSBjYW1iaWEgbCdvZ2dldHRvIGludGVybyBzaWduaWZpY2EgY2hlIGhvIHJpbWFuZGF0byBsYSByaWNlcmNhXHJcbiAgICAgICAgICAgIHRoaXMuc2V0TW9kZSgndmlldycpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nID0gKHRoaXMuVmlldy5yZXF1ZXN0ZWRncm91cHM/Lmxlbmd0aCB8fCAwKSA9PSAwO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgdmVuZ28gZGEgdW5hIHJpY2VyY2EgaW50ZXJuYSBtYW50ZW5nbyBsbyBzdGF0byBkaSBzZWxlemlvbmUgcHJlY2VkZW50ZSAocXVpbmRpIHN1IGNhbWJpbyBwYWdpbmEsIGNhbWJpbyBpcHAsIGVjYy4uLilcclxuICAgICAgICAgICAgLy8gc2UgaW52ZWNlIGwndXRlbnRlIGhhIGZhdHRvIHVuYSByaWNlcmNhIGx1aSAocXVpbmRpIGNhbWJpYW5kbyBmaWx0cmkpLCBzZWNjbyBsZSBpbmZvIGRpIHNlbGV6aW9uZVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuVmlldy5zZWxlY3Rpb24gfHwgKCF0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ICYmIGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nKSB8fCAhdGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25fSC5jbGVhclNlbGVjdGlvbkNhY2hlcygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3LnNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuVmlldy5zZWxlY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvLyBSZWN1cGVybyBQcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm5nQ29udHJvbC5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgcXVlc3RhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5wcmVmU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZlNlcnZpY2UucmV0cmlldmU8eyBjb2x1bW5zOiBzdHJpbmdbXSwgY29sdW1uX29yZGVyaW5nOiBzdHJpbmdbXSB9Pig8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUpLnN1YnNjcmliZShwcmVmcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5WaWV3LmNvbHVtbnMgPSBwcmVmcy5jb2x1bW5zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5WaWV3LmNvbHVtbl9vcmRlcmluZyA9IHByZWZzLmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBMYSBwYWdpbmF6aW9uZSBkZXZvIGZhcmxhIHNvbGFtZW50ZSBxdWFuZG8gcmljaGllZG8gbyB1biBncnVwcG8gcHJpbmNpcGFsZSAoc2Ugc29ubyBpbiByb3cgZ3JvdXBpbmcpIG8gc2Ugbm9uIHJpY2hpZWRvIGdydXBwaSAoaW4gdHV0dGkgbGdpIGFsdHJpIGNhc2kpXHJcbiAgICAgICAgICAgIGlmIChmaXJzdEl0ZW1Hcm91cE9yTm9Hcm91cGluZylcclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMudXRpbGl0aWVzX0guZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlZpZXcucGFnZSwgdGhpcy5WaWV3LnBhZ2VzIHx8IDEsIHRoaXMuVmlldy5pdGVtcy5sZW5ndGgsIHRoaXMuVmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuVmlldyAmJiAodGhpcy5WaWV3Lmxlbmd0aCAhPSBudWxsICYmIHRoaXMuVmlldy5sZW5ndGggIT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldE1vZGUoJ2FycmF5Jyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuVXNlU2VsZWN0aW9uQ2FjaGUgfHwgIXRoaXMuYXJyYXltb2RlU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbl9ILmNsZWFyU2VsZWN0aW9uQ2FjaGVzKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gUmVjdXBlcm8gUHJlZmVyZW5jZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5TYXZlUHJlZmVyZW5jZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5uZ0NvbnRyb2wubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBhdmVyZSB1biAnbmFtZScgcGVyIHF1ZXN0YSB0YWJlbGxhXCIpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIXRoaXMucHJlZlNlcnZpY2UpXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgY2hlIGlsIHBhY2NoZXR0byBAZXNmYWVuemEvcHJlZmVyZW5jZXMgc2lhIGluc3RhbGxhdG9cIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZTZXJ2aWNlLnJldHJpZXZlPHsgY29sdW1uczogc3RyaW5nW10sIGNvbHVtbl9vcmRlcmluZzogc3RyaW5nW10gfT4oPHN0cmluZz50aGlzLm5nQ29udHJvbC5uYW1lKS5zdWJzY3JpYmUocHJlZnMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlDb2x1bW5zID0gcHJlZnMuY29sdW1ucztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlDb2x1bW5PcmRlcmluZyA9IHByZWZzLmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hcnJheVB1bHNhbnRpID0gdGhpcy51dGlsaXRpZXNfSC5nZXRQYWdlc0FycmF5KDYsIHRoaXMuU2VhcmNoVmlldy5wYWdlLCB0aGlzLlNlYXJjaFZpZXcucGFnZXMgfHwgMSwgdGhpcy5TZWFyY2hWaWV3Lml0ZW1zLmxlbmd0aCwgdGhpcy5TZWFyY2hWaWV3Lml0ZW1zcGVycGFnZW92ZXJyaWRlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSlcclxuICAgICAgICAgICAgdGhpcy5maW5hbGl6ZUNvbnRleHQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBGdW56aW9uZSBkaSB0cmFja2J5IHBlciBpbCBib2R5IGNoZSBkb3ZyZWJiZSBldml0YXJlIGlsIDkwJSBkZWxsZSBjaGFuZ2UgZGV0ZWN0aW9uICovXHJcbiAgICBwdWJsaWMgYm9keVRyYWNrQnkgPSAoaW5kZXg6IG51bWJlciwgaXRlbTogYW55KSA9PiBpdGVtLl9oYXNoO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3VjY2Vzc2l2YW1lbnRlIGFsIGJpbmQgZGVsIG51b3ZvIGlucHV0IHF1ZXN0YSBmdW56aW9uZSBzaSBvY2N1cGEgZGkgZmluYWxpenphcmUgdHV0dGkgaSBwYXJhbWV0cmkgZGkgZnVuemlvbmFtZW50byBkZWxsJ2VzLXRhYmxlIFxyXG4gICAgICogaW4gYmFzZSBhIElucHV0IC0gTW9kZWxsbywgZSBxdWFsc2lhc2kgYWx0cmEgY29zYSBwb3NzYSBzZXJ2aXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZmluYWxpemVDb250ZXh0KCkge1xyXG4gICAgICAgIGxldCB2aWV3Q2FzdGVkID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG5cclxuICAgICAgICAvKlxyXG4gICAgICAgICAqVXNvIGxhIHRlY25pY2EgZGkgRW5kbGVzc1Njcm9sbCBzZSBsYSB2YXJpYWJpbGUgcmVsYXRpdmEgw6ggYXR0aXZhIGUgc2VcclxuICAgICAgICAgKiAxKSBIbyB1biBBcnJheSwgb3BwdXJlXHJcbiAgICAgICAgICogMikgSG8gdW4gQXBwU2VhcmNoIGNoZSBzdGEgY2VyY2FuZG8gY29uIHBhZ2luYXppb25lIFwiVHV0dG9cIiwgb3BwdXJlXHJcbiAgICAgICAgICogMykgSG8gdW4gQXBwU2VhcmNoIGNoZSBzdGEgY2VyY2FuZG8gY29uIHBhZ2luYXppb25lIGRpdmVyc2EgZGEgXCJUdXR0b1wiIG1hIGNvbiBsYSB2YXJpYWJpbGUgRW5kbGVzc1Njcm9sbE9ubHlGb3JBbGwgYSBmYWxzZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxldCBpc0FwcFNlYXJjaFdpdGhJcHBNYXggPSB0aGlzLnZpZXdNb2RlICYmIHZpZXdDYXN0ZWQuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPT0gdGhpcy5kZWZhdWx0QWxsUGFnZU92ZXJyaWRlO1xyXG4gICAgICAgIGxldCBpc0FwcFNlYXJjaE5vTWF4SXBwID0gdGhpcy52aWV3TW9kZSAmJiB2aWV3Q2FzdGVkLml0ZW1zcGVycGFnZW92ZXJyaWRlICE9IHRoaXMuZGVmYXVsdEFsbFBhZ2VPdmVycmlkZTtcclxuICAgICAgICB0aGlzLlVzZUVuZGxlc3NzY3JvbGwgPSB0aGlzLkVuZGxlc3NTY3JvbGwgJiYgKHRoaXMuYXJyYXlNb2RlIHx8IGlzQXBwU2VhcmNoV2l0aElwcE1heCB8fCAoaXNBcHBTZWFyY2hOb01heElwcCAmJiAhdGhpcy5FbmRsZXNzU2Nyb2xsT25seUZvckFsbCkpO1xyXG5cclxuICAgICAgICBsZXQgaGFzUm93R3JvdXBzID0gKHZpZXdDYXN0ZWQuZ3JvdXBpbmdzICYmIHZpZXdDYXN0ZWQuZ3JvdXBpbmdzLmZpbHRlcih0ID0+ICF0LmFnZ3JlZ2F0aW9uKS5sZW5ndGggPiAwKSB8fCAodGhpcy5hcnJheU1vZGUgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZS5zb21lKHQgPT4gdC50aEdyb3VwKSk7XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIGRlaSBncnVwcGkgaW4gbW9kYWxpdMOgIGFycmF5IGRldm8gc2lzdGVtYXJlIHVuIHBvJyBkaSB2YXJpYWJpbGkgY2hlIGRpdmVudGFubyBpbnNlbnNhdGVcclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUgJiYgaGFzUm93R3JvdXBzKVxyXG4gICAgICAgICAgICB0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvLyBSaWVtcGltZW50byBkZWxsYSBUTVBCb3VuZFNvdXJjZSBjb24gZ2xpIG9nZ2V0dGkgY2hlIHZlcnJhbm5vIHBvaSBtb3N0cmF0aSBhZCBpbnRlcmZhY2NpYVxyXG4gICAgICAgIGlmICh0aGlzLlVzZUVuZGxlc3NzY3JvbGwgJiYgIWhhc1Jvd0dyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmFkZGVkU2xpY2VzID0gW107XHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTdWJTb3VyY2VzID0gdGhpcy5pdGVtc19ILmdldEl0ZW1TbGljZXMoKTtcclxuICAgICAgICAgICAgbGV0IGZpcnN0U3ViID0gdGhpcy5ib3VuZFN1YlNvdXJjZXNbMF07XHJcblxyXG4gICAgICAgICAgICB0aGlzLlRNUEJvdW5kU291cmNlID0gZmlyc3RTdWIgPyBmaXJzdFN1YiA6IFtdO1xyXG4gICAgICAgICAgICBpZiAoZmlyc3RTdWIpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFkZGVkU2xpY2VzLnB1c2goMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZSA9IHRoaXMuaXRlbXNfSC5nZXRJdGVtc0J5TW9kZShmYWxzZSwgIXRoaXMuaW50ZXJuYWxXcml0ZUNhbGwpO1xyXG5cclxuICAgICAgICAvLyBTZSBobyB1bmEgZ2VyYXJjaGlhLCBhc3NlZ25vIGkgbGl2ZWxsaSBnZXJhcmNoaWNpIGFsbGEgVE1QQm91bmRTb3VyY2VcclxuICAgICAgICBpZiAodGhpcy5IaWVyYXJjaHkgJiYgIWhhc1Jvd0dyb3VwcylcclxuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaHlNb2RlX0guYXNzaWduSGllcmFyY2h5TGV2ZWxzKHRoaXMuVE1QQm91bmRTb3VyY2UpO1xyXG5cclxuICAgICAgICAvLyBMJ2hhc2hpbmcgZGVnbGkgb2dnZXR0aSBsbyBmYWNjaW8gYSBwcmVzY2luZGVyZVxyXG4gICAgICAgIHRoaXMudXRpbGl0aWVzX0guY2FsY3VsYXRlSGFzaCh0aGlzLlRNUEJvdW5kU291cmNlKTtcclxuXHJcbiAgICAgICAgLy8gQXNzZWdubyBhIHVuYSB2YXJpYWJpbGUgbWlhIGwnZXZlbnR1YWxlIG92ZXJyaWRlIHBlciBsYSBjbGFzc2UgZGVsbGEgcmlnYVxyXG4gICAgICAgIC8vIFNlIHBvaSBzb25vIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhIGluaWV0dG8gYW5jaGUgbGEgY2xhc3NlIHBlciBsYSBjb25maWd1cmF6aW9uZSBkZWwgbGl2ZWxsbyBkZWxsYSByaWdhXHJcbiAgICAgICAgaWYgKCh0aGlzLlRNUEJvdW5kU291cmNlICYmIHRoaXMuUm93Q2xhc3NBc3NpZ25lcikgfHwgdGhpcy5IaWVyYXJjaHkpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuVE1QQm91bmRTb3VyY2VbaV07XHJcbiAgICAgICAgICAgICAgICBpdGVtLl9yb3dDbGFzcyA9IHRoaXMuUm93Q2xhc3NBc3NpZ25lciA/IHRoaXMuUm93Q2xhc3NBc3NpZ25lcihpdGVtKSA6IFwiXCI7XHJcbiAgICAgICAgICAgICAgICBpdGVtLl9yb3dDbGFzcyArPSB0aGlzLkhpZXJhcmNoeSA/IFwiIGVzdC1yb3ctbHZsLVwiICsgaXRlbS5fbGV2ZWwgOiBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBHZW5lcmEgbGUgaW5mb3JtemlvbmkgZGkgcGFnaW5hemlvbmUgcGVyIGxhIHZpc3RhIGdsb2JhbGUgZGVsbCdlcy10YWJsZSAqL1xyXG4gICAgcHJpdmF0ZSBzZXR1cFBhZ2luZ0luZm9ybWF0aW9ucygpIHtcclxuXHJcbiAgICAgICAgLy8gRGVmYXVsdCBjaGUgdmFsZ29ubyBkaSBiYXNlLCBwb2kgZXZlbnR1YWxtZW50ZSBtb2RkYXRpIGRhbGxlIGZ1bnppb25pIHNvdHRvXHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gIXRoaXMuSGlkZVBhZ2luZ0NvdW50O1xyXG4gICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zID0gIXRoaXMuSGlkZVBhZ2luZ0J1dHRvbnM7XHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd1BhZ2luZyA9ICF0aGlzLkhpZGVQYWdpbmdcclxuICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5Vc2VzVmlldyA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSAmJiB0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyAmJiAhdGhpcy5TZWFyY2hWaWV3KSB7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSAoPGFueVtdPnRoaXMuVmlldykubGVuZ3RoIHx8IDA7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0J1dHRvbnMgJiYgdGhpcy5WaWV3Lmxlbmd0aCA+IDEwO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5WaWV3ID0gdGhpcy5WaWV3O1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5Vc2VzVmlldyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93UGFnaW5nT3B0aW9ucyA9IHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLmFycmF5TW9kZSAmJiAoIXRoaXMuVXNlQXJyYXlNb2RlUGFnaW5nIHx8IHRoaXMuU2VhcmNoVmlldykpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuU2VhcmNoVmlldykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldyA9IHRoaXMuU2VhcmNoVmlld1xyXG4gICAgICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuUGFnZXJDb3VudCA9IHRoaXMuU2VhcmNoVmlldy5vYmplY3Rjb3VudCB8fCAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSAoPGFueVtdPnRoaXMuVmlldykubGVuZ3RoIHx8IDBcclxuXHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0J1dHRvbnMgJiYgKHRoaXMuVmlldy5sZW5ndGggPiAxMCB8fCAodGhpcy5TZWFyY2hWaWV3Py5vYmplY3Rjb3VudCB8fCAwKSA+IDEwKTtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0aGlzLlZpZXcgJiYgdGhpcy5WaWV3Lmxlbmd0aCkgfHwgKHRoaXMuU2VhcmNoVmlldyAmJiB0aGlzLlNlYXJjaFZpZXcub2JqZWN0Y291bnQgJiYgdGhpcy5TZWFyY2hWaWV3Lm9iamVjdGNvdW50ICE9IC0xKTtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd1BhZ2luZyA9IHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zIHx8IHRoaXMuUGFnZXJPcHRpb25zLlNob3dDb3VudDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd1BhZ2luZ09wdGlvbnMgPSB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93QnV0dG9ucztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy52aWV3TW9kZSkge1xyXG4gICAgICAgICAgICBsZXQgdG1wVmlldyA9IHRoaXMuTWFpbkdyb3VwVmlldyB8fCB0aGlzLlZpZXc7XHJcbiAgICAgICAgICAgIGxldCBjb3VudCA9IHRtcFZpZXc/Lmdyb3VwY291bnQgfHwgdG1wVmlldz8ub2JqZWN0Y291bnQ7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNlYXJjaGVzID0gdG1wVmlldz8uZ3JvdXBjb3VudCAhPSBudWxsICYmIHRtcFZpZXc/Lmdyb3VwY291bnQgIT0gdW5kZWZpbmVkID8gJ2dyb3VwcycgOiAnaXRlbXMnO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5QYWdlckNvdW50ID0gY291bnQgfHwgMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldyA9IHRtcFZpZXc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dDb3VudCA9IHRoaXMuUGFnZXJPcHRpb25zLlNob3dDb3VudCB8fCAodG1wVmlldyAmJiBjb3VudCAmJiBjb3VudCAhPSAtMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmVwb3J0TW9kZSkge1xyXG4gICAgICAgICAgICBsZXQgcnZjID0gdGhpcy5SZXBvcnRWYWx1ZXMuY291bnQ7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcgPSB0aGlzLlZpZXc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSBydmMgJiYgcnZjID09IC0xID8gdGhpcy5SZXBvcnRWYWx1ZXMucm93cy5sZW5ndGggOiBydmMgJiYgcnZjID4gMCA/IHRoaXMuUmVwb3J0VmFsdWVzLmNvdW50IDogMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0aGlzLlZpZXcgJiYgKDxSZXBvcnREZWZpbml0aW9uPnRoaXMuVmlldykucmVzdWx0LmNvdW50ICE9IC0xKTtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0J1dHRvbnMgPSB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93QnV0dG9ucyAmJiAodGhpcy5WaWV3LnBhZ2luZ2F2YWlsYWJsZSB8fCB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93Q291bnQpO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93UGFnaW5nT3B0aW9ucyA9IHRoaXMuUGFnZXJPcHRpb25zLlNob3dCdXR0b25zO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZ2VzdGlzY2UgbCdlbmRsZXNzIHNjcm9sbCBlIGluIGJhc2UgYSBxdWFudG8gbGEgdGFiZWxsYSDDqCBzdGF0YSBzY3JvbGxhdGEgYWdnaXVuZ2UgZGVnbGkgZWxlbWVudGkgZXh0cmEgYSAqKlRNUEJvdW5kU291cmNlKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZSBFdmVudG8gZGkgc2Nyb2xsIGRlbCBicm93c2VyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvblNjcm9sbChlOiBhbnkpIHtcclxuICAgICAgICBsZXQgdGFibGVWaWV3SGVpZ2h0ID0gZS50YXJnZXQub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICAgIGxldCB0YWJsZVNjcm9sbEhlaWdodCA9IGUudGFyZ2V0LnNjcm9sbEhlaWdodDtcclxuICAgICAgICBsZXQgc2Nyb2xsTG9jYXRpb24gPSBlLnRhcmdldC5zY3JvbGxUb3A7XHJcbiAgICAgICAgbGV0IGJ1ZmZlciA9IDIwMDtcclxuXHJcbiAgICAgICAgbGV0IGxpbWl0ID0gdGFibGVTY3JvbGxIZWlnaHQgLSB0YWJsZVZpZXdIZWlnaHQgLSBidWZmZXI7XHJcbiAgICAgICAgaWYgKHNjcm9sbExvY2F0aW9uID4gbGltaXQpIHtcclxuICAgICAgICAgICAgbGV0IGluZGV4VG9BZGQgPSBNYXRoLmZsb29yKHRoaXMuVE1QQm91bmRTb3VyY2UubGVuZ3RoIC8gMTAwKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYm91bmRTdWJTb3VyY2VzW2luZGV4VG9BZGRdICYmIHRoaXMuYWRkZWRTbGljZXMuaW5kZXhPZihpbmRleFRvQWRkKSA9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgLy8gRGV2byByaWNvcmRhcm1pIGRpIGZhcmUgbCdoYXNoIGRlbCBudW92byBwZXp6b1xyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXNfSC5jYWxjdWxhdGVIYXNoKHRoaXMuYm91bmRTdWJTb3VyY2VzW2luZGV4VG9BZGRdKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuVE1QQm91bmRTb3VyY2UgPSB0aGlzLlRNUEJvdW5kU291cmNlLmNvbmNhdCh0aGlzLmJvdW5kU3ViU291cmNlc1tpbmRleFRvQWRkXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFkZGVkU2xpY2VzLnB1c2goaW5kZXhUb0FkZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMucG9zdEJvdW5kU291cmNlQ2FsY3VsYXRpb24oKTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gbGFuY2lhdG8gZG9wbyBjaGUgbGEgc29yZ2VudGUgZGF0aSDDqCBzdGF0YSBjb3JyZXR0YW1lbnRlIGJpbmRhdGEsIHNpIG9jY3VwYSBkaSByaWNhbGNvbGFyZSB0dXR0byBjacOyIGNoZSBzZXJ2ZVxyXG4gICAgICogYWxsJ2VzLXRhYmxlIHBlciByZW5kZXJpenphcmUgaSB2YWxvcmkgZGEgbW9zdHJhcmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBwb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpIHtcclxuICAgICAgICAvLyBSZXNldHRvIHR1dHRvIHRyYW5uZSBSb3dURHMgZSBSb3dUSHMgcGVyIGV2aXRhcmUgZmxpY2tlcmluZy4gUm93VERzIGUgUm93VEhzIHNhcmFubm8gbW9kaWZpY2F0ZSBhbGwnaW50ZXJubyBkZWwgcHJvc3NpbW8gY2ljbG8gZGkgQ0RcclxuICAgICAgICB0aGlzLlJvd0NvbnRleHRzID0gW107XHJcbiAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMgPSBbXTtcclxuICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZEl0ZW1JRCA9IG51bGw7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLkVzVGhzRGlyZWN0aXZlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUubGVuZ3RoID4gMCAmJiB0aGlzLkVzVGRzRGlyZWN0aXZlICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgdGhpcy5pbnRlcm5hbFBvc3RCb3VuZFNvdXJjZSgpO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyB0aGlzLmludGVybmFsUG9zdEJvdW5kU291cmNlKCk7IH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogUGVyIHBvdGVyIGRpc3Rpbmd1ZXJlIGxlIGNoaWFtYXRlIGEgcXVlc3RvIG1ldG9kbzogRG9wbyBpbCBzZXRUaW1lb3V0IHNlIHVzbyBnbGkgRXNUZC9Fc1RoIHZlY2NoaSwgc2VuemEgaWwgc2V0VGltZW91dCBzZSB1c28gbGUgbnVvdmUgZGlyZXR0aXZlICovXHJcbiAgICBwcml2YXRlIGludGVybmFsUG9zdEJvdW5kU291cmNlKCkge1xyXG4gICAgICAgIGxldCBWaWV3ID0gdGhpcy5WaWV3O1xyXG4gICAgICAgIGxldCB0aHMgPSB0aGlzLkVzVGhzICYmIHRoaXMuRXNUaHMubGVuZ3RoID4gMCA/IHRoaXMuRXNUaHMudG9BcnJheSgpIDogdGhpcy5Fc1Roc0RpcmVjdGl2ZSAmJiB0aGlzLkVzVGhzRGlyZWN0aXZlLmxlbmd0aCA+IDAgPyB0aGlzLkVzVGhzRGlyZWN0aXZlLnRvQXJyYXkoKSA6IFtdO1xyXG4gICAgICAgIGxldCB0ZHMgPSB0aGlzLkVzVGRzICYmIHRoaXMuRXNUZHMubGVuZ3RoID4gMCA/IHRoaXMuRXNUZHMudG9BcnJheSgpIDogdGhpcy5Fc1Rkc0RpcmVjdGl2ZSAmJiB0aGlzLkVzVGRzRGlyZWN0aXZlLmxlbmd0aCA+IDAgPyB0aGlzLkVzVGRzRGlyZWN0aXZlLnRvQXJyYXkoKSA6IFtdO1xyXG5cclxuICAgICAgICAvLyBTZSBub24gaG8gY29sb25uZSBkaW5hbWljaGUgbWEgc29ubyBpbiBtb2RhbGl0w6AgZGluYW1pY2EgKGxvIGNhcGlzY28gcGVyY2jDqSBjJ8OoIHVuYSB2aWV3IHBpZW5hIGRpIGdlbmVyaWNpdGVtKSBtZXR0byBpbCBkZWZhdWx0IGRlbGxlIGNvbG9ubmVcclxuICAgICAgICB0aGlzLmR5bmFtaWNNb2RlX0guZXZlbnR1YWxseVJldmlld0R5bmFtaWNDb2x1bW5zKCk7XHJcbiAgICAgICAgdGhpcy5iaW5kRGlzcGxheVRvTG9hZGVkSXRlbXNPckdyb3VwcyhWaWV3KTtcclxuXHJcbiAgICAgICAgLy8gUXVlc3RvIGRldidlc3NlcmUgcGVyIGZvcnphIGxhbmNpYXRvIGRvcG8gKipiaW5kRGlzcGxheVRvTG9hZGVkSXRlbXNPckdyb3VwcyoqIGRhdG8gY2hlIMOoIGzDrCBjaGUgYWxjdW5lIGNvc2UgdmVuZ29ubyB2YWxvcml6emF0ZVxyXG4gICAgICAgIHRoaXMuc2V0dXBQYWdpbmdJbmZvcm1hdGlvbnMoKTtcclxuXHJcbiAgICAgICAgLy8gTW9sdGUgY29zZSBzb25vIG92dmlhbWVudGUgZGlzcG9uaWJpbGkgc29sbyBpbiBtb2RhbGl0w6AgVmlld1xyXG4gICAgICAgIGlmICgodGhpcy52aWV3TW9kZSB8fCB0aGlzLmFycmF5TW9kZSkgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICBsZXQgdmlldyA9IHRoaXMudmlld01vZGUgPyBWaWV3IGFzIEFwcFNlYXJjaDxhbnk+IDogbnVsbDtcclxuICAgICAgICAgICAgbGV0IGl0ZW1zQW5kR3JvdXBzID0gdGhpcy52aWV3TW9kZSA/IFsuLi4odmlldy5pdGVtcyB8fCBbXSksIC4uLih2aWV3Lmdyb3VwcyB8fCBbXSldIDogVmlldyBhcyBhbnlbXTtcclxuICAgICAgICAgICAgbGV0IHNpID0gdGhpcy52aWV3TW9kZSA/IHZpZXcuc2VsZWN0aW9uIDogdGhpcy5hcnJheW1vZGVTZWxlY3Rpb247XHJcbiAgICAgICAgICAgIC8vIE4uQjogUmlzcGV0dGFyZSBsJ29yZGluZSBkaSBxdWVzdGUgMyBtYWNyb2NhdGVnb3JpZSDDqCBWSVRBTEVcclxuXHJcbiAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIFNpc3RlbWF6aW9uaSBkaSBUSCwgVEQsIGUgdmlzaWJpbGl0w6AgdmFyaWUgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICAgICAgICAvLyBQcmVwYXNzYWdnaW8gcGVyIHRpcmFyZSBmdW9yaSB0dXR0ZSBsZSBpbmZvIHV0aWxpIHN1Z2xpIGhlYWRlcnMgaW4gbW9kbyBkYSBub24gcmljYWNvbGFyc2VsaSBzZW1wcmUgZG9wb1xyXG4gICAgICAgICAgICBsZXQgaEkgPSB0aGlzLmNvbHVtbk1ldGFkYXRhX0guZXZhbHVhdGVIZWFkZXJzR3JvdXBpbmdJbmZvcyh0aHMpOyAgICAgICAgXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbiBtb2RhbGl0w6AgYXJyYXkgbm9uIGhvIHVuIGJhY2tlbmQuLi5cclxuICAgICAgICAgICAgICAgIHRoaXMuaXRlbXNfSC5hcnJheU1vZGVSZXZpZXdPcmRlcmluZ3MoKSAgICAgICAgICAgICAgICAgLy8gLi4uIHF1aW5kaSBnbGkgb3JkaW5hbWVudGkgbGkgZGV2byBmYXJlIGxhdG8gY2xpZW50LCBlIC4uLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5yb3dHcm91cGluZ19ILmFycmF5TW9kZVJldmlld0dyb3VwaW5ncyhoSS5sZWFmcyk7ICAvLyAuLi4gaSByYWdncnVwcGFtZW50aSBsaSBkZXZvIGZhcmUgbGF0byBjbGllbnRcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILnJldmlld0NvbHVtbnNMaXN0KGhJLmxlYWZzKTsgICAgICAgICAgICAgICAgICAgICAgIC8vIEFnZ2lvcm5hIGxhIGxpc3RhIGRlbGxlIGNvbG9ubmUgZGEgbW9zdHJhcmUgbmVsbGEgZGlhbG9nIHBlciBvcmRpbmFtZW50byBlY2NcclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILm1vdmVGaXhlZENvbHVtbnNBdFRoZUJlZ2lubmluZyhoSS5sZWFmcywgdGRzKTsgICAgIC8vIFNwb3N0byB0dXR0ZSBsZSBjb3NlIGZpeGVkIGFsbCdpbml6aW8gaW4gbW9kbyBjaGUgbGEgY3JlYXppb25lIGRpIHRoIGUgdGQgc2lhIHBpw7kgc25lbGxhIChVdGlsaXp6YSBsZSBDb2x1bW5zTGlzdCwgcXVpbmRpIGRldidlc3NlcmUgcmljaGlhbWF0YSBQSVJNQSBkaSByZXZpZXdDb2x1bW5zTGlzdClcclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmFsaWduSGVhZGVyc09yZGVyaW5nKGhJLmxlYWZzLCB2aWV3KTsgICAgICAgICAgICAgIC8vIEFsbGluZW8gZ2xpIG9yZGluYW1lbnRpIGFnbGkgaGVhZGVyXHJcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTWV0YWRhdGFfSC5hbGlnbkNvbHVtbnNJZkxvYWRlZFZpZXcodmlldyk7ICAgICAgICAgICAgICAgICAgICAvLyBTZSBzdG8gY2FyaWNhbmRvIHVuYSBWaWV3IGRhIGhvdHBvdGF0byAocXVpbmRpIGNvbiBzYXZlZHN0YXRlID0gdHJ1ZSkgcmlhbGxpbmVvIGxhIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmUgZSBpbCBsb3JvIG9yZGluZS5cclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILnJlZnJlc2hDb2x1bW5zVmlzaWJpbGl0eShoSS5sZWFmcywgdGRzLCB2aWV3KTsgICAgIC8vIExhdm9ybyBzdWkgVEggZWQgZXZlbnR1YWxtZW50ZSBtb2RpZmljbyBsYSB2aXNpYmlsaXTDoCBhbmNoZSBkZWkgVEQuXHJcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTWV0YWRhdGFfSC5ldmFsdWF0ZVBpbm5lZENvbHVtbnNXaWR0aCgpOyAgICAgICAgICAgICAgICAgICAgICAvLyBTZSBzb25vIHByZXNlbnRpIGNvbG9ubmUgcGlubmF0ZSB2YWx1dGEgbGEgZGltZW5zaW9uZSBkZWwgY29udGVuaXRvcmVcclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmdlbmVyYXRlRGVmYXVsdE9yZGVyKGhJLmxlYWZzLCB2aWV3KTsgICAgICAgICAgICAgIC8vIEdlbmVybyBsZSBkaXJldHRpdmUgZGkgb3JkaW5hbWVudG8sIGNoZSBzaWFubyBkZWZhdWx0IG8gZGVyaXZhbnRpIGRhbGxhIEFwcFNlYXJjaFxyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0guZXZhbHVhdGVIZWFkZXJHcm91cHMoaEkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFsdXRvIGkgcmFnZ3J1cHBhbWVudGkgZGVnbGkgaGVhZGVyIHNlIHByZXNlbnRpXHJcblxyXG4gICAgICAgICAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAgICBHZW5lcmF6aW9uZSBiaW5kaW5nIHBlciByaWdoZSBlIGNvbG9ubmUgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICAgICAgICB0aGlzLmV2YWx1YXRlUm93VGhzKGhJLmxlYWZzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSYWNjb2xnbyBpIFRIXHJcbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVSb3dUZHMoaEkubGVhZnMsIHRkcyk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhY2NvbGdvIGkgVEQgaW4gY29udGVzdGkgc2VwYXJhdGksIHVuIGNvbnRlc3RvIHBlciBvZ25pIGl0ZW0gbyBncnVwcG9cclxuXHJcbiAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIFVsdGltaSBhZ2dpdXN0bWFlbnRpIGRlaSBiaW5kaW5nICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTWV0YWRhdGFfSC5hcHBseU9yZGVyaW5nKHZpZXcsIHRydWUpOyAgICAgICAgICAgIC8vIEFwcGxpY28gbCdvcmRpbmFtZW50byBzdWxsZSBjb2xvbm5lIChub24gQVNDIERFU0MsIG1hIFwicHJpbWEgcXVlc3RhIG8gcXVlbGxhIGNvbG9ubmFcIilcclxuICAgICAgICAgICAgdGhpcy5Nb3ZlVGVtcG9yYXJ5VmFyaWFibGVzVG9SZWFsT25lcygpOyAgICAgICAgICAgICAgICAgICAgLy8gQ29sbGVnbyBUSCBlIFREIGFnZ2l1c3RhdGkgZmlubyBhZCBvcmEgYWxsZSB2YXJpYWJpbGkgZGkgQmluZGluZyBIVE1MXHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uX0guZXZhbHVhdGVTZWxlY3Rpb24oaXRlbXNBbmRHcm91cHMsIHNpKTsgICAgIC8vIFJpYWxsaW5lbyBsZSBpbmZvIGRpIHNlbGV6aW9uZSBkZWdsaSBlbGVtZW50aSBkZWxsYSBWaWV3XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5SZXNlYXJjaE5lZWRlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuUmVzZWFyY2hOZWVkZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICgodGhpcy52aWV3TW9kZSB8fCB0aGlzLmFycmF5TW9kZSkgJiYgIXRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHtcclxuICAgICAgICAgICAgLy8gUmlhbGxpbmVvIGxlIGluZm8gZGkgc2VsZXppb25lIGRlZ2xpIGVsZW1lbnRpIGRlbGxhIFZpZXdcclxuICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy52aWV3TW9kZSA/IChWaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5pdGVtcyA6IFZpZXcgYXMgYW55W107XHJcbiAgICAgICAgICAgIGxldCBzaSA9IHRoaXMudmlld01vZGUgPyAoVmlldyBhcyBBcHBTZWFyY2g8YW55Pikuc2VsZWN0aW9uIDogdGhpcy5hcnJheW1vZGVTZWxlY3Rpb247XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uX0guZXZhbHVhdGVTZWxlY3Rpb24oaXRlbXMsIHNpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFBlciBlc3NlcmUgc2ljdXJvIGNoZSBkb3BvIHVuIGJpbmQgZGkgb2dnZXR0aSBsYSBlcy10YWJsZSBhZ2dpb3JuaSBsYSBncmFmaWNhXHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgdGhpcy5GaXJzdEJpbmQgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEVmZmV0dHVhIGlsIGJpbmRpbmcgZGVnbGkgb2dnZXR0aSBwZXJ2ZW51dGkgZGEgcXVlc3RhIGNoaWFtYXRhIGNvbiBnbGkgb2dnZXR0aSBlZmZldHRpdmFtZW50ZSBkYSBncmFmaWNhcmVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IHZpZXcgVmlldyBkYSBjdWkgc29ubyBhcnJpdmF0aSBnbGkgb2dnZXR0aS4gUHXDsiBlc3NlcmUgbyB1biBhcnJheSBzZSBzb25vIGluICoqYXJyYXlNb2RlKiogbyB1bmEgQXBwU2VhcmNoPFQ+IHNlIHNvbm8gaW4gKip2aWV3TW9kZSoqXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYmluZERpc3BsYXlUb0xvYWRlZEl0ZW1zT3JHcm91cHModmlldzogYW55KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuVE1QQm91bmRTb3VyY2UubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5CYXNlSXRlbXNDb3VudCA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLlRNUEJvdW5kU291cmNlO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUgfHwgIXRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHtcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2U7XHJcbiAgICAgICAgICAgIHRoaXMuQmFzZUl0ZW1zQ291bnQgPSB2aWV3Py5vYmplY3Rjb3VudCB8fCB2aWV3Lmxlbmd0aDtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGdyb3VwaW5nS2V5cyA9IHZpZXcuZ3JvdXBpbmdzPy5maWx0ZXIodCA9PiAhdC5hZ2dyZWdhdGlvbik/Lmxlbmd0aCB8fCAwO1xyXG4gICAgICAgIGlmIChncm91cGluZ0tleXMgPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5CYXNlSXRlbXNDb3VudCA9IHZpZXcub2JqZWN0Y291bnQ7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucm93R3JvdXBpbmdfSC5oYW5kbGVOZXdEYXRhT25Sb3dHcm91cGluZyh2aWV3LCBncm91cGluZ0tleXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBNZXRvZG8gcmljaGlhbWF0byBzb2xvIHF1YW5kbyAqKlRNUFJvd1REcyoqIGUgKipUTVBSb3dUSHMqKiBzb25vIGNvbXBsZXRhbWVudGUgZ2VuZXJhdGkgZWQgYWdnaXVzdGF0aS4gU2VydmUgcGVyIGNvbGxlZ2FybGkgYWxsZSB2YXJpYWJpbGkgdXNhdGUgbGF0byBiaW5kaW5nIEhUTUwgKi9cclxuICAgIHByaXZhdGUgTW92ZVRlbXBvcmFyeVZhcmlhYmxlc1RvUmVhbE9uZXMoKSB7XHJcbiAgICAgICAgdGhpcy5Sb3dURHMgPSB0aGlzLlRNUFJvd1REcztcclxuICAgICAgICB0aGlzLlJvd1RIcyA9IHRoaXMuVE1QUm93VEhzO1xyXG4gICAgICAgIHRoaXMuUm93VGhHcm91cHMgPSB0aGlzLlRNUFJvd1RoR3JvdXBzID8gdGhpcy5UTVBSb3dUaEdyb3Vwcy5yZXZlcnNlKCkgOiBudWxsO1xyXG5cclxuICAgICAgICB0aGlzLkNvbHVtbnMuVmlzaWJpbGUgPSB0aGlzLlJvd1RIcy5maWx0ZXIodCA9PiB0LlZpc2libGUpLmxlbmd0aDtcclxuICAgICAgICB0aGlzLkNvbHVtbnMuVmlzaWJsZVVucGlubmVkID0gdGhpcy5Sb3dUSHMuZmlsdGVyKHQgPT4gdC5WaXNpYmxlICYmICF0LlBpbm5lZCkubGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuQ29sdW1ucy5HbG9iYWwgPSB0aGlzLkNvbHVtbnMuVmlzaWJsZVVucGlubmVkICsgKHRoaXMuSGFzUGlubmVkQ29sdW1ucyA/IDEgOiAwKSArICh0aGlzLlNlbGVjdGlvbiA/IDEgOiAwKSArICh0aGlzLlJlbW92YWwgPyAxIDogMCkgKyAodGhpcy5FeHBvcnQgfHwgdGhpcy5IaWRkZW5Db2x1bW5zIHx8IHRoaXMuQ29sdW1uc09yZGVyaW5nIHx8IHRoaXMuQ29ybmVyTWVudU9wdGlvbnMgPyAxIDogMClcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBlcm1ldHRlIGRpIHNlbGV6aW9uYXJlIG8gZGVzZWxlemlvbmFyZSBpbiBtYW5pZXJhIGFyYml0cmFyaWEgZGVnbGkgb2dnZXR0aVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRhIHNlbGV6aW9uYXJlIG8gZGVzZWxlemlvbmFyZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBzZWxlY3QgKip0cnVlKiogcGVyIHNlbGV6aW9uYXJsaSwgKipmYWxzZSoqIHBlciBub24gdG9jY2FybGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldFNlbGVjdGlvblN0YXR1cyhpdGVtczogYW55W10sIHNlbGVjdDogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uX0guaGFuZGxlSXRlbXNTZWxlY3Rpb24oaXRlbXMsIHNlbGVjdCk7XHJcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlc3Rpc2NlIGlsIGNhbWJpbyBkaSBPcmRpbmFtZW50byBkaSB1bmEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBkZWxsYSBjb2xvbm5hIGlsIGN1aSBvcmlkbmFtZW50byDDqCBjYW1iaWF0b1xyXG4gICAgICogQHBhcmFtIHsnREVTQycgfCAnQVNDJ30gb3JkZXIgTnVvdm8gb3JkaW5lIHNlbGV6aW9uYXRvIHBlciBsYSBjb2xvbm5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0aE9yZGVyQ2hhbmdlZChpZDogc3RyaW5nLCBvcmRlcj86ICdERVNDJyB8ICdBU0MnKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlICYmICF0aGlzLmFycmF5TW9kZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ09yZGVyIGNoYW5nZWQgb24gYSB0YWJsZSBub3QgaW4gdmlld01vZGUgb3IgQXJyYXkgbW9kZS4gT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLk9yZGVyQnlDb2x1bW4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmhhbmRsZVRIT3JkZXJDaGFuZ2UoaWQsIG9yZGVyKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBkYSBjaGlhbWFyZSBvZ25pIHZvbHRhIGNoZSBzaSB2dW9sZSBkYXJlIGV2aWRlbnphIGFsbCdlc3Rlcm5vIGRlbCBiaXNvZ25vIGRpIHJpZWZmZXR0dWFyZSBsYSByaWNlcmNhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVzZXRzUGFnZSBJbmRpY2EgYWwgbGlzdGVuZXIgY2hlIGRldmUgcmVzZXR0YXJlIGlsIG51bWVybyBkaSBwYWdpbmFcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXdPdmVycmlkZSBPdmVycmlkZSBkZWxsYSB2aWV3IGRhIGVtZXR0ZXJlIHBlciBxdWVzdGEgcmljZXJjYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW1pdFNlYXJjaFJlcXVlc3QocmVzZXRzUGFnZTogYm9vbGVhbiwgdmlld092ZXJyaWRlPzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBpZiAodGhpcy52aWV3TW9kZSAmJiAhdmlld092ZXJyaWRlKSB7XHJcbiAgICAgICAgICAgICh0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLmludGVybmFsc2VhcmNocmVxdWVzdCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHZpZXdPdmVycmlkZSkge1xyXG4gICAgICAgICAgICBpZiAocmVzZXRzUGFnZSlcclxuICAgICAgICAgICAgICAgIHZpZXdPdmVycmlkZS5wYWdlID0gMTtcclxuICAgICAgICAgICAgdmlld092ZXJyaWRlLmludGVybmFsc2VhcmNocmVxdWVzdCA9IHRydWVcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucmVzZWFyY2hJblByb2dyZXNzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm9uU2VhcmNoUmVxdWVzdC5lbWl0KHZpZXdPdmVycmlkZSA/IHZpZXdPdmVycmlkZSA6IHJlc2V0c1BhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGFydGVuZG8gZGFnbGkgKipFc1RkcyoqIGJpbmRhdGkgZ2VuZXJhLCBhbGwnaW50ZXJubyBkZWwgZGl6aW9uYXJpbyAqKlRNUFJvd1REcyoqIHR1dHRpIGkgY29udGVzdGkgZGVpIHZhcmkgb2dnZXR0aS5cclxuICAgICAqXHJcbiAgICAgKiBWZW5nb25vIGVzY2x1c2kgaSBURCBcIkludGVybmlcIiBpbiBxdWFudG8gdmVuZ29ubyBnZW5lcmF0aSBkYWdsaSBvcmlnaW5hbGkgcXVpbmRpIGluY2x1ZGVybGkgdm9ycmViYmUgZGlyZSByaWVmZmV0dHVhcmUgbGUgb3BlcmF6aW9uaSBkdWUgdm9sdGVcclxuICAgICAqXHJcbiAgICAgKiBDb3N0bzogMiBzY2FuIEVzVGhzLCAxIHNjYW4gRXNUZHNcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICogQHBhcmFtIHtFc1RkW10gfCBFc1RkRGlyZWN0aXZlW119IHRkcyBDZWxsZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVSb3dUZHModGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10sIHRkczogRXNUZFtdIHwgRXNUZERpcmVjdGl2ZVtdKSB7XHJcbiAgICAgICAgaWYgKHRkcy5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgdGhzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RoIHwgRXNUaERpcmVjdGl2ZSB9ID0ge307XHJcbiAgICAgICAgbGV0IGNvbHVtbnNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGFibGVDb2x1bW4gfSA9IHt9O1xyXG5cclxuICAgICAgICBmb3IgKGxldCBjb2xpID0gMDsgY29saSA8IHRoaXMuQ29sdW1uc0xpc3QubGVuZ3RoOyBjb2xpKyspIHtcclxuICAgICAgICAgICAgbGV0IGNvbCA9IHRoaXMuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICB0aHNDYWNoZVt0aGlzLnV0aWxpdGllc19ILmlzRXNUaCh0aCkgPyB0aC5JRCA6IHRoLnRoXSA9IHRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5UTVBSb3dURHMgPSB7fTtcclxuICAgICAgICAvLyBWYXJpYWJpbGUgZCdhcHBvZ2dpbyBwZXIgcGVybWV0dGVybWkgZGkgaW5zZXJpcmUgdHV0dGUgbGUgY29sb25uZSBcIkZpeGVkXCIgZGF2YW50aVxyXG4gICAgICAgIGxldCBjb250ZXh0Rml4ZWRzOiB7IFtjb250ZXh0OiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0ZCA9IHRkc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnV0aWxpdGllc19ILmlzRXNUZCh0ZCkpIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc0NhY2hlW3RkLklEXTtcclxuICAgICAgICAgICAgICAgIGlmICghIXRoKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoLl9yZWZlcmVuY2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBcIklEIGRlbGwnb2dnZXRvIEVzVGQgbm9uIGNvbXBhdGliaWxlIGNvbiBnbGkgSUQgZGljaGFyYXRpIG5lZ2xpIEVzVGg6IFwiICsgdGQuSUQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGlzRml4ZWQgPSAodGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpICYmIHRoLkZpeGVkKSB8fCAoIXRoaXMudXRpbGl0aWVzX0guaXNFc1RoKHRoKSAmJiAodGgudGhGaXhlZCB8fCB0aC50aEdyb3VwKSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXRlbVRvQWRkID0gPGFueT57IEdyb3VwQWdncmVnYXRpb246IGZhbHNlLCBHcm91cEhlYWRlcjogZmFsc2UsIFdyYXBzOiB0cnVlLCBJRDogdGQuSUQsIFZpc2libGU6IHRkLlZpc2libGUsIENsYXNzOiB0ZC5DbGFzcywgQ29udGVudDogdGQuQ29udGVudCwgUm91dGVyTGluazogdGQuUm91dGVyTGluaywgVGVtcGxhdGU6IHRkLlRlbXBsYXRlIH07XHJcbiAgICAgICAgICAgICAgICBsZXQgY3R4ID0gdGQuQ29udGV4dDtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLlRNUFJvd1REc1tjdHhdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRml4ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0uc3BsaWNlKDAgKyAoY29udGV4dEZpeGVkc1tjdHhdKyspLCAwLCBpdGVtVG9BZGQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dURHNbY3R4XS5wdXNoKGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlJvd0NvbnRleHRzLnB1c2goY3R4KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdID0gW2l0ZW1Ub0FkZF07XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dEZpeGVkc1tjdHhdID0gaXNGaXhlZCA/IDEgOiAwXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYm91bmRTb3VyY2UubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuYm91bmRTb3VyY2VbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGN0eCA9IGl0ZW0uX2hhc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGtleSA9IHRkLnRkO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc0NhY2hlW3RkLnRkXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISF0aClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGguX3JlZmVyZW5jZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJJRCBkZWxsJ29nZ2V0byBFc1RkIG5vbiBjb21wYXRpYmlsZSBjb24gZ2xpIElEIGRpY2hhcmF0aSBuZWdsaSBFc1RoOiBcIiArIHRkLnRkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGQudGRJZiB8fCAoIXRoaXMudXRpbGl0aWVzX0guaXNFc1RoKHRoKSAmJiB0aC50aEdyb3VwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGhDYXN0ZWQgPSA8RXNUaERpcmVjdGl2ZT50aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGlzRml4ZWQgPSAodGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpICYmIHRoLkZpeGVkKSB8fCAoIXRoaXMudXRpbGl0aWVzX0guaXNFc1RoKHRoKSAmJiAodGgudGhGaXhlZCB8fCB0aC50aEdyb3VwIHx8IHRoLnRoUGlubmVkKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpdGVtVG9BZGQgPSBpdGVtLl9pdGVtID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhbnk+eyBMZWZ0Qm9yZGVyOiAoPGFueT50aENhc3RlZCkuX2xib3JkLCBSaWdodEJvcmRlcjogKDxhbnk+dGhDYXN0ZWQpLl9yYm9yZCwgSUQ6IGtleSwgUGlubmVkOiBjb2x1bW5zQ2FjaGVbdGQudGRdLnBpbm5lZCwgUGlubmVkV2lkdGg6IHRoQ2FzdGVkLnRoUGlubmVkV2lkdGgsIEdyb3VwSGVhZGVyOiBmYWxzZSwgR3JvdXBBZ2dyZWdhdGlvbjogZmFsc2UsIFZpc2libGU6IGNvbHVtbnNDYWNoZVt0ZC50ZF0udmlzaWJsZSwgV3JhcHM6IGZhbHNlLCBDbGFzczogdGQudGRDbGFzcywgVGVtcGxhdGU6IHRoQ2FzdGVkLnRoR3JvdXAgJiYgIXRoaXMuU2hvd0l0ZW1Hcm91cHNDb2x1bW5zID8gbnVsbCA6IHRkLlRlbXBsYXRlIH0gOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGFueT57IExlZnRCb3JkZXI6ICg8YW55PnRoQ2FzdGVkKS5fbGJvcmQsIFJpZ2h0Qm9yZGVyOiAoPGFueT50aENhc3RlZCkuX3Jib3JkLCBJRDoga2V5LCBQaW5uZWQ6IGNvbHVtbnNDYWNoZVt0ZC50ZF0ucGlubmVkLCBQaW5uZWRXaWR0aDogdGhDYXN0ZWQudGhQaW5uZWRXaWR0aCwgR3JvdXBIZWFkZXI6IHRoQ2FzdGVkLnRoR3JvdXAsIEdyb3VwQWdncmVnYXRpb246ICEhdGhDYXN0ZWQudGhBZ2dyZWdhdGlvbiwgVmlzaWJsZTogY29sdW1uc0NhY2hlW3RkLnRkXS52aXNpYmxlLCBXcmFwczogZmFsc2UsIENsYXNzOiB0aENhc3RlZC50aEdyb3VwQ2xhc3MgfHwgJycsIENvbnRlbnQ6IHRoaXMucm93R3JvdXBpbmdfSC5nZXRHcm91cENlbGxEaXNwbGF5KDxHcm91cD5pdGVtLCBrZXksIDxFc1RoRGlyZWN0aXZlPnRoKSB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0ucHVzaChpdGVtVG9BZGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5Sb3dDb250ZXh0cy5wdXNoKGN0eCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdID0gW2l0ZW1Ub0FkZF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBobyBvZ2dldHRpIMOoIGludXRpbGUgY2hlIGNvbnRyb2xsbyBnbGkgZXJyb3JpLCBkYXRvIGNoZSBnbGkgZXMtdGQgbm9uIGVzaXN0ZXJhbm5vIGRpIGNlcnRvIGUgZGkgY29uc2VndWVuemEgZ2xpIGVzLXRoIG5vbiBzYXJhbm5vIHJlZmVyZW56aWF0aVxyXG4gICAgICAgIGlmICh0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHZhciBlcnJzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgaWYgKCF0aC5fcmVmZXJlbmNlZClcclxuICAgICAgICAgICAgICAgIGVycnMucHVzaCh0aGlzLnV0aWxpdGllc19ILmlzRXNUaCh0aCkgPyB0aC5JRCA6IHRoLnRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChlcnJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgdmFyIGVycklkcyA9IGVycnMuam9pbignLCAnKTtcclxuICAgICAgICAgICAgdGhyb3cgXCJMJ0lEIGRpIHVubyBvIHBpw7kgRXNUaCBub24gaGFubm8gYWxjdW4gRXNUZCBhc3NvY2lhdG86IFwiICsgZXJySWRzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUaHMqKiBiaW5kYXRpIGdlbmVyYSwgYWxsJ2ludGVybm8gZGVsIGRpemlvbmFyaW8gKipUTVBSb3dUSHMqKiB0dXR0aSBpIGNvbnRlc3RpIGRlaSB2YXJpIG9nZ2V0dGkuXHJcbiAgICAgKlxyXG4gICAgICogVmVuZ29ubyBlc2NsdXNpIGkgVEggXCJJbnRlcm5pXCIgaW4gcXVhbnRvIHZlbmdvbm8gZ2VuZXJhdGkgZGFnbGkgb3JpZ2luYWxpIHF1aW5kaSBpbmNsdWRlcmxpIHZvcnJlYmJlIGRpcmUgcmllZmZldHR1YXJlIGxlIG9wZXJhemlvbmkgZHVlIHZvbHRlXHJcbiAgICAgKlxyXG4gICAgICogQ29zdG86IDEgc2NhbiBFc1Roc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVSb3dUaHModGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBjb2x1bW5zTGlzdENhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUYWJsZUNvbHVtbiB9ID0ge307XHJcbiAgICAgICAgbGV0IGNhc3RlZFZpZXcgPSA8QXBwU2VhcmNoPGFueT4+dGhpcy5WaWV3O1xyXG4gICAgICAgIGxldCBncm91cGluZ3NVbmRlZmluZWQgPSB0aGlzLnZpZXdNb2RlICYmIChjYXN0ZWRWaWV3ICYmICFjYXN0ZWRWaWV3Lmdyb3VwaW5ncyB8fCBjYXN0ZWRWaWV3Lmdyb3VwaW5ncy5sZW5ndGggPT0gMCk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5Db2x1bW5zTGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRtID0gdGhpcy5Db2x1bW5zTGlzdFtpXTtcclxuICAgICAgICAgICAgY29sdW1uc0xpc3RDYWNoZVtpdG0uaWRdID0gaXRtXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLlRNUFJvd1RIcyA9IFtdO1xyXG4gICAgICAgIGxldCBmaXhlZCA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBsZXQgdG9BZGQ7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpKSB7XHJcbiAgICAgICAgICAgICAgICB0b0FkZCA9IHsgUGlubmVkOiBmYWxzZSwgSUQ6IHRoLklELCBWaXNpYmxlOiB0aC5WaXNpYmxlLCBDbGFzczogdGguQ2xhc3MsIE9yZGVyOiB0aC5PcmRlciwgT3JkZXJhYmxlOiB0aC5PcmRlcmFibGUsIFRlbXBsYXRlOiBudWxsLCBDb250ZW50OiB0aC5EZXNjcmlwdGlvbiwgV3JhcDogdGguV3JhcCB9O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoLkZpeGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VEhzLnNwbGljZSgwICsgKGZpeGVkKyspLCAwLCB0b0FkZCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMucHVzaCh0b0FkZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGgudGhJZiB8fCB0aC50aEdyb3VwKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHRoQ2xhc3MgPSAodGgudGhDbGFzcyB8fCAnJykgKyAodGgudGhHcm91cCA/IFwiIGVzdC1jb2wtbWluXCIgOiBcIlwiKTtcclxuICAgICAgICAgICAgICAgIHRvQWRkID0geyBQaW5uZWQ6IGNvbHVtbnNMaXN0Q2FjaGVbdGgudGhdLnBpbm5lZCwgUGlubmVkV2lkdGg6IHRoLnRoUGlubmVkV2lkdGgsIElEOiB0aC50aCwgVmlzaWJsZTogdGgudGhWaXNpYmxlLCBDbGFzczogdGhDbGFzcywgT3JkZXI6IHRoLnRoT3JkZXIsIE9yZGVyYWJsZTogdGgudGhPcmRlcmFibGUsIFRlbXBsYXRlOiB0aC5UZW1wbGF0ZSwgQ29udGVudDogbnVsbCwgV3JhcDogdGgudGhXcmFwLCBMZWZ0Qm9yZGVyOiAoPGFueT50aCkuX2xib3JkLCBSaWdodEJvcmRlcjogKDxhbnk+dGgpLl9yYm9yZCB9O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMucHVzaCh0b0FkZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2UgaG8gdW4gbW9kZWxsbyBjaGUgZGV2ZSBmdW56aW9uYXJlIGEgcm93Z3JvdXBpbmcgbWEgbm9uIMOoIGFuY29yYSBzdGF0YSBlZmZldHR1YXRhIG5lc3N1bmEgcmljZXJjYSBzdWkgZ3J1cHBpIHByaW5jaXBhbGkgKGdyb3VwaW5nc1VuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIC8vIGxpIGdlbmVybyBlIG1hbmRvIGxhIHByaW1hIHJpY2VyY2EgY2hlIGRldidlc3NlcmUgc3BlZGl0YSBhbCBiYWNrZW5kIHBlciBpbCBwcmltbyBjYXJpY2FtZW50byBkZWkgZ3J1cHBpXHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXBpbmdzVW5kZWZpbmVkICYmICh0aC50aEFnZ3JlZ2F0aW9uIHx8IHRoLnRoR3JvdXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGdyb3VwQWdncmVnYXRpb25zOiBHcm91cE9yQWdncmVnYXRpb25bXSA9IHRoaXMucm93R3JvdXBpbmdfSC5nZXRHcm91cEFnZ3JlZ2F0aW9ucyh0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYXN0ZWRWaWV3Lmdyb3VwaW5ncylcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdGVkVmlldy5ncm91cGluZ3MgPSBncm91cEFnZ3JlZ2F0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc3RlZFZpZXcuZ3JvdXBpbmdzLnB1c2goLi4uZ3JvdXBBZ2dyZWdhdGlvbnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlJlc2VhcmNoTmVlZGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGRpIHVuYSBwYWdpbmEgaW4gYXZhbnRpIChvIGluZGlldHJvKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIE51bWVybyBkaSBwYWdpbmUgZGEgYWdnaXVuZ2VyZSAobyBzb3R0cmFycmUsIHNlIG5lZ2F0aXZvKSBhbGxhIHBhZ2luYSBhdHR1YWxlXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gcGFnZXIgRWxlbWVudG8gZGkgc2VwYXJhemlvbmUgc3UgY3VpIMOoIGVmZmV0dHVhdGEgbGEgcmljZXJjYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkVG9QYWdlR3JvdXAocGFnZTogbnVtYmVyLCBwYWdlcjogR3JvdXBQYWdlcikge1xyXG4gICAgICAgIHRoaXMuZ29Ub1BhZ2VHcm91cChwYWdlci52aWV3LnBhZ2UgKyBwYWdlLCBwYWdlcik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcG9zdGEgbGEgcmljZXJjYSBhbGxhIHBhZ2luYSBzcGVjaWZpY2F0YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIFBhZ2luYSBhIGN1aSBuYXZpZ2FyZVxyXG4gICAgICogQHBhcmFtIHthbnl9IHBhZ2VyIEVsZW1lbnRvIGRpIHNlcGFyYXppb25lIHN1IGN1aSDDqCBlZmZldHR1YXRhIGxhIHJpY2VyY2FcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdvVG9QYWdlR3JvdXAocGFnZTogbnVtYmVyLCBwYWdlcjogR3JvdXBQYWdlcikge1xyXG5cclxuICAgICAgICBsZXQgYXBwU2VhcmNoRWxlbWVudCA9IHBhZ2VyLnZpZXc7XHJcbiAgICAgICAgaWYgKHBhZ2UgPT09IDAgfHwgKHBhZ2UgPiBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzICYmIGFwcFNlYXJjaEVsZW1lbnQucGFnZXMgPiAwKSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBhcHBTZWFyY2hFbGVtZW50LnBhZ2UgPSBwYWdlO1xyXG4gICAgICAgIHBhZ2VyLmJ1dHRvbnMgPSB0aGlzLnV0aWxpdGllc19ILmdldFBhZ2VzQXJyYXkoNiwgYXBwU2VhcmNoRWxlbWVudC5wYWdlLCBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzKTtcclxuXHJcbiAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSwgYXBwU2VhcmNoRWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VzdGlzY2UgaSBjbGljayBzdWxsYSB0YWJlbGxhIHNvbG8gcGVyIGxlIHJpZ2hlIGEgZ3J1cHBvLiBcclxuICAgICAqIE8gcmltdW92ZSBnbGkgZWxlbWVudGkgYXR0dWFsbWVudGUgcHJlc2VudGkgbyBjYXJpY2EgaWwgY29udGVudXRvIGRlbCBncnVwcG9cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZ3JvdXAgR3J1cHBvIGJpbmRhdG8gc3UgY3VpIHNpIMOoIGVmZmV0dHVhdG8gaWwgY2xpY2tcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gKip0cnVlKiogc2UgbCdvcGVyYWl6b25lIMOoIGFuZGF0YSBhIGJ1b24gZmluZSwgKipmYWxzZSoqIGFsdHJpbWVudGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGhhbmRsZUdyb3VwQ2xpY2soZ3JvdXA6IEdyb3VwKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IGNhc3RlZCA9IHRoaXMuVmlldyBhcyBBcHBTZWFyY2g8YW55PjtcclxuICAgICAgICBsZXQgYW55RyA9ICg8YW55Pmdyb3VwKTtcclxuICAgICAgICBhbnlHLl9leHBhbmRlZCA9ICFhbnlHLl9leHBhbmRlZDtcclxuXHJcbiAgICAgICAgLy8gU29ubyBpbiBtb2RhbGl0w6AgcmFnZ3J1cHBhbWVudG8gdmlydHVhbGUgZGEgYXJyYXk6IEVzcGFuZGVyZSBzaWduaWZpY2EgcmVuZGVyZSB2aXNpYmlsaSB0dXR0aSBnbGkgb2dnZXR0aSByZWxhdGl2aSBhIHF1ZXN0byBncnVwcG8sIHZpY2V2ZXJzYSBpbCBjb250cmFycmVcclxuICAgICAgICBpZiAodGhpcy5BcnJheUdyb3VwaW5nKSB7XHJcbiAgICAgICAgICAgIGxldCBhbGxSZWxhdGl2ZXMgPSB0aGlzLmJvdW5kU291cmNlLmZpbHRlcih0ID0+XHJcbiAgICAgICAgICAgICAgICAodC5fZ3JvdXAgJiYgKChhbnlHLl9leHBhbmRlZCAmJiB0Ll9wYXJlbnQgPT0gYW55Ry5fdGhpc0tleSkgfHwgKCFhbnlHLl9leHBhbmRlZCAmJiB0Ll9wYXJlbnQgJiYgdC5fcGFyZW50LnN0YXJ0c1dpdGgoYW55Ry5fdGhpc0tleSkpKSkgfHxcclxuICAgICAgICAgICAgICAgICh0Ll9pdGVtICYmICgoYW55Ry5fZXhwYW5kZWQgJiYgdC5fdGhpc0tleSA9PSBhbnlHLl90aGlzS2V5KSB8fCAoIWFueUcuX2V4cGFuZGVkICYmIHQuX3RoaXNLZXkuc3RhcnRzV2l0aChhbnlHLl90aGlzS2V5KSkpKSlcclxuICAgICAgICAgICAgYWxsUmVsYXRpdmVzLmZvckVhY2godCA9PiB7IHQuX3Zpc2libGUgPSBhbnlHLl9leHBhbmRlZDsgaWYgKHQuX2dyb3VwKSB0Ll9leHBhbmRlZCA9IGZhbHNlIH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYW55Ry5fZXhwYW5kZWQpIHtcclxuICAgICAgICAgICAgLy8gUmVzZXR0byBpcHBcclxuICAgICAgICAgICAgY2FzdGVkLml0ZW1zcGVycGFnZW92ZXJyaWRlID0gMTU7XHJcbiAgICAgICAgICAgIGlmICghY2FzdGVkLnJlcXVlc3RlZGdyb3VwcylcclxuICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMgPSBbbmV3IEdyb3VwRmlsdGVyKGdyb3VwLmNvbHVtbiwgZ3JvdXAudmFsdWUpXTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbGV2ZWwgPSBhbnlHLl9ncm91cGxldmVsO1xyXG4gICAgICAgICAgICAgICAgLy8gc2UgaWwgZ3J1cHBvIGNsaWNjYXRvIG5vbiBoYSB1biBsaXZlbGxvIMOoIGlsIHByaW1vIGdydXBwbywgcXVpbmRpIG9yZGluYW1lbnRvIHVuaWNvXHJcbiAgICAgICAgICAgICAgICAvLyBhbHRyaW1lbnRpIGRldm8gcmltdW92ZXJlIHR1dHRpIGkgZmlsdHJpIHN1IGxpdmVsbGkgc3VwZXJpb3JpIGFsIGxldmVsIGNsaWNjYXRvIGUgYWdnaXVuZ2VyZSBpbCBsZXZlbCBjbGljY2F0b1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsZXZlbClcclxuICAgICAgICAgICAgICAgICAgICBjYXN0ZWQucmVxdWVzdGVkZ3JvdXBzID0gW25ldyBHcm91cEZpbHRlcihncm91cC5jb2x1bW4sIGdyb3VwLnZhbHVlKV07XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXN0ZWQucmVxdWVzdGVkZ3JvdXBzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgYW55Ry5fcGFyZW50Um91dGUuZm9yRWFjaCgoc3RlcDogR3JvdXBSb3V0ZUZyYWdtZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMucHVzaChuZXcgR3JvdXBGaWx0ZXIoc3RlcC5jb2x1bW4sIHN0ZXAudmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICBjYXN0ZWQucmVxdWVzdGVkZ3JvdXBzLnB1c2gobmV3IEdyb3VwRmlsdGVyKGdyb3VwLmNvbHVtbiwgZ3JvdXAudmFsdWUpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QodHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgcGF0aCA9IChhbnlHLl9wYXJlbnQgfHwgJycpICsgZ3JvdXAudmFsdWU7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBobyBjaGl1c28gdW4gZ3J1cHBvIG5vbiBtaSBzZXJ2ZSByaWVmZmV0dHVhcmUgcmljZXJjZSwgbWkgYmFzdGEgZWxpbWluYXJlIGRhZ2xpIG9nZ2V0dGkgYmluZGF0aSB0dXR0aSBnbGkgZWxlbWVudGkgc290dG9zdGFudGkgYSBxdWVsIGdydXBwb1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhdC5fcGFyZW50IHx8ICF0Ll9wYXJlbnQuc3RhcnRzV2l0aChwYXRoKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBkZXZvIHBlcsOyIGFuY2hlIHJpbXVvdmVyZSBldmVudHVhbGkgY2FjaGUgcmVsYXRpdmVcclxuICAgICAgICAgICAgdGhpcy5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUgPSB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZS5maWx0ZXIodCA9PiB0LnBhdGggIT0gcGF0aCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBsYSBzZWxlemlvbmUgZ2xvYmFsZSBkZWdsaSBvZ2dldHRpLCBzaWEgcGVyIHBhZ2luYSBjaGUgYSBsaXZlbGxvIGRpICoqU2VsZWN0QWxsKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlZFZhbCBWYWxvcmUgZm9yemF0byBkaSBjaGVjayBkYSBhc3NlZ25hcmUgYWdsaSBvZ2dldHRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDaGVja0NoYW5nZWQoZm9yY2VkVmFsOiBib29sZWFuID0gbnVsbCkge1xyXG5cclxuICAgICAgICAvLyBQcmVuZG8gdHV0dGkgZ2xpIGVsZW1lbnRpIHByZXNlbnRpIGluIHF1ZXN0YSB2aXN0YS4gU2UgaG8gZ3J1cHBpIHByZW5kbyBzb2xvIGkgZ3J1cHBpIGEgbGl2ZWxsbyAwLCBhbHRyaW1lbnRpIHByZW5kbyB0dXR0aSBnbGkgb2dnZXR0aSBwZXIgc2VsZXppb25hcmxpXHJcbiAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5ib3VuZFNvdXJjZS5maW5kKHQgPT4gdC5fZ3JvdXApID8gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiB0Ll9ncm91cCAmJiAhdC5fcGFyZW50KSA6IHRoaXMuYm91bmRTb3VyY2U7XHJcbiAgICAgICAgdmFyIGl0ZW1TZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbl9ILmhhbmRsZUl0ZW1zU2VsZWN0aW9uKGl0ZW1zLCBmb3JjZWRWYWwsIHRoaXMuZ2xvYmFsQ2hlY2spO1xyXG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG5cclxuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KGl0ZW1TZWxlY3Rpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VzdGlzY2UgaSBjbGljayBzdWxsYSB0YWJlbGxhLCBnZXN0ZW5kbyBldmVudHVhbG1lbnRlIGFuY2hlIGdsaSBTaGlmdCArIENsaWNrIHBlciBzZWxlemlvbmFyZSB1biByYW5nZSBkaSBvZ2dldHRpXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnl9IGV2ZW50IEV2ZW50byBuYXRpdm8gSFRNTCBkZWwgY2xpY2tcclxuICAgICAqIEBwYXJhbSB7YW55fSBpdGVtIE9nZ2V0dG8gYmluZGF0byBzdSBjdWkgc2kgw6ggZWZmZXR0dWF0byBpbCBjbGlja1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAqKnRydWUqKiBzZSBsJ29wZXJhaXpvbmUgw6ggYW5kYXRhIGEgYnVvbiBmaW5lLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2xpY2soZXZlbnQ6IGFueSwgaXRlbTogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gU2VsZXppb25vIGRlbCB0ZXN0byBtYSBub24gaG8gc2hpZnQgcHJlbXV0byAtPiBpZ25vcm8gbGEgc2VsZXppb25lXHJcbiAgICAgICAgaWYgKChldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnR5cGUgPT0gJ1JhbmdlJyB8fCBldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCkubGVuZ3RoID4gMCkgJiYgIWV2ZW50LnNoaWZ0S2V5KVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIC8vIFNlbGV6aW9ubyBkZWwgdGVzdG8gZSBobyBzaGlmdCBwcmVtdXRvIC0+IGFubnVsbG8gbGEgc2VsZXppb25lIGRlbCB0ZXN0b1xyXG4gICAgICAgIGlmICgoZXZlbnQudmlldy5nZXRTZWxlY3Rpb24oKS50eXBlID09ICdSYW5nZScgfHwgZXZlbnQudmlldy5nZXRTZWxlY3Rpb24oKS50b1N0cmluZygpLmxlbmd0aCA+IDApICYmIGV2ZW50LnNoaWZ0S2V5KVxyXG4gICAgICAgICAgICB0aGlzLnV0aUV4dHMuY2xlYXJUZXh0U2VsZWN0aW9uKCk7XHJcblxyXG4gICAgICAgIGxldCBzZWxlY3RlZGl0ZW1zOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIGlmIChldmVudC5zaGlmdEtleSAmJiB0aGlzLlNoaWZ0Q2xpY2sgJiYgIXRoaXMuU2luZ2xlU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGxldCBzdGFydFNlbGVjdGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhdC5fZ3JvdXAgJiYgIXQuX3NlcCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0ID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnRTZWxlY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICB0Ll9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRpdGVtcy5wdXNoKHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgIXN0YXJ0U2VsZWN0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHQuX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZGl0ZW1zLnB1c2godCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgc3RhcnRTZWxlY3RpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGl0ZW0uX3NlbGVjdGVkID0gIWl0ZW0uX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZCA9IGl0ZW07XHJcbiAgICAgICAgICAgIHNlbGVjdGVkaXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25fSC5oYW5kbGVJdGVtc1NlbGVjdGlvbihzZWxlY3RlZGl0ZW1zKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcG9zdGEgbGEgcmljZXJjYSBkaSB1bmEgcGFnaW5hIGluIGF2YW50aSAobyBpbmRlaXRybylcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBOdW1lcm8gZGkgcGFnaW5lIGRhIGFnZ2l1bmdlcmUgKG8gc290dHJhcnJlLCBzZSBuZWdhdGl2bykgYWxsYSBwYWdpbmEgYXR0dWFsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIGxldCB2aWV3ID0gdGhpcy5NYWluR3JvdXBWaWV3ID8gdGhpcy5NYWluR3JvdXBWaWV3IDogdGhpcy5WaWV3O1xyXG5cclxuICAgICAgICB0aGlzLmdvVG9QYWdlKCgodGhpcy5TZWFyY2hWaWV3IHx8IHZpZXcpPy5wYWdlIHx8IDApICsgcGFnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcG9zdGEgbGEgcmljZXJjYSBhbGxhIHBhZ2luYSBzcGVjaWZpY2F0YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIFBhZ2luYSBhIGN1aSBuYXZpZ2FyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ29Ub1BhZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICAgICAgbGV0IHZpZXcgPSB0aGlzLk1haW5Hcm91cFZpZXcgPyB0aGlzLk1haW5Hcm91cFZpZXcgOiAodGhpcy5hcnJheU1vZGUgPyB0aGlzLlNlYXJjaFZpZXcgOiB0aGlzLlZpZXcpO1xyXG4gICAgICAgIGlmICghdmlldy5wYWdlIHx8ICF2aWV3LnBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBhcHBTZWFyY2hFbGVtZW50ID0gdGhpcy5TZWFyY2hWaWV3IHx8IHZpZXc7XHJcbiAgICAgICAgaWYgKHBhZ2UgPT09IDAgfHwgKHBhZ2UgPiBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzICYmIGFwcFNlYXJjaEVsZW1lbnQucGFnZXMgPiAwKSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBhcHBTZWFyY2hFbGVtZW50LnBhZ2UgPSBwYWdlO1xyXG4gICAgICAgIGxldCBjb3VudCA9IHRoaXMucmVwb3J0TW9kZSA/ICgoPFJlcG9ydERlZmluaXRpb24+dmlldykucmVzdWx0Py5jb3VudCB8fCAwKSA6ICh2aWV3Lml0ZW1zLmxlbmd0aCB8fCB2aWV3Lmdyb3Vwcz8ubGVuZ3RoIHx8IDApO1xyXG4gICAgICAgIGxldCBpcHAgPSB0aGlzLnJlcG9ydE1vZGUgPyAoKDxSZXBvcnREZWZpbml0aW9uPnZpZXcpLml0ZW1zcGVycGFnZW92ZXJyaWRlIHx8IDE1KSA6IHZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgfHwgMTU7XHJcbiAgICAgICAgdGhpcy5hcnJheVB1bHNhbnRpID0gdGhpcy51dGlsaXRpZXNfSC5nZXRQYWdlc0FycmF5KDYsIGFwcFNlYXJjaEVsZW1lbnQucGFnZSwgYXBwU2VhcmNoRWxlbWVudC5wYWdlcywgY291bnQsIGlwcCk7XHJcblxyXG4gICAgICAgIGxldCBoYXNHcm91cGluZ3MgPSAhIXRoaXMuTWFpbkdyb3VwVmlldztcclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlLCBoYXNHcm91cGluZ3MgPyB2aWV3IDogdGhpcy5TZWFyY2hWaWV3ID8gdGhpcy5TZWFyY2hWaWV3IDogbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudG8gcmljaGlhbWF0byBzdWwgY2FtYmlvIGRlbGxhIHBhZ2luYXppb25lLiBWZXJyw6AgcmljaGlhbWF0byBsJ2V2ZW50byAqKmVtaXRTZWFyY2hSZXF1ZXN0KipcclxuICAgICAqIHBlciBjb211bmljYXJlIGFsIGNvbXBvbmVudGUgY2hlIHV0aWxpenphIHF1ZXN0YSB0YWJlbGxhIGNoZSBpIGRhdGkgc29ubyBkYSBhZ2dpb3JuYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkl0ZW1zUGVyUGFnZUNoYW5nZWQobmV3SXBwKSB7XHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSA9IG5ld0lwcDtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICBpZiAodGhpcy5NYWluR3JvdXBWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHRoaXMuTWFpbkdyb3VwVmlldyk7XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5TZWFyY2hWaWV3KSB7XHJcbiAgICAgICAgICAgIC8vIFF1ZXN0byBzZWNvbmRvIG1lIHNpIHB1w7IgcG9ydGFyZSBhIGxpdmVsbG8gdW4gcG8nIHBpw7kgYWx0b1xyXG4gICAgICAgICAgICB0aGlzLlNlYXJjaFZpZXcucGFnZSA9IDE7XHJcbiAgICAgICAgICAgIHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QodHJ1ZSwgdGhpcy5TZWFyY2hWaWV3KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBzdWwgY2FtYmlvIGRlbGxhIHBhZ2luYXppb25lLiBWZXJyw6AgcmljaGlhbWF0byBsJ2V2ZW50byAqKmVtaXRTZWFyY2hSZXF1ZXN0KiogY29uIGxhIHZpc3RhIGRlbCBzZXBhcmF0b3JlICovXHJcbiAgICBwdWJsaWMgb25Hcm91cEl0ZW1zUGVyUGFnZUNoYW5nZWQocGFnZXI6IEdyb3VwUGFnZXIsIG5ld0lwcDogbnVtYmVyKSB7XHJcbiAgICAgICAgcGFnZXIudmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSA9IG5ld0lwcDtcclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHBhZ2VyLnZpZXcpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogTWV0b2RvIGNoZSBnZXN0aXNjZSBsYSBtb2RpZmljYSBkZWwgdGVtcG8gc3BlY2lmaWNhdG8gcGVyIGwnYWdnaW9ybmFtZW50byBhdXRvbWF0aWNvICovXHJcbiAgICBwdWJsaWMgYXV0b1VwZGF0ZUNoYW5nZWQoKSB7XHJcbiAgICAgICAgaWYgKCEvXlsxLTldXFxkKiQvLnRlc3QodGhpcy5zZWNvbmRzKSlcclxuICAgICAgICAgICAgdGhpcy5zZWNvbmRzID0gJzEwJztcclxuXHJcbiAgICAgICAgbGV0IHNlY29uZHNJbk1zID0gcGFyc2VJbnQodGhpcy5zZWNvbmRzLCBudWxsKSAqIDEwMDA7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmF1dG9VcGRhdGUpXHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7IHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpOyB9LCBzZWNvbmRzSW5Ncyk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMudXBkYXRlVGltZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoaWFtYXRvIGRhbCBjbGljayBzdSB1bmEgZGVsbGUgY29sb25uZSBnZW5lcmF0ZSBkYWxsJ0lucHV0ICoqRHluYW1pY09wZXJhdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBpdGVtIEwnb2dnZXR0byBzdSBjdWkgdmEgZWZmZXR0dWF0YSBsJ29wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGlkIENvZGljZSBpZGVudGlmaWNhdGl2byBkZWxsJ29wZXJhemlvbmUgZGEgZWZmZXR0dWFyc2lcclxuICAgICAqL1xyXG4gICAgcHVibGljIGR5bmFtaWNPcGVyYXRpb24oaXRlbTogYW55LCBvcGlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uRHluYW1pY09wZXJhdGlvbi5lbWl0KHsgaWQ6IG9waWQsIGl0ZW06IGl0ZW0gfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIGlsIGNvbnRlbnV0byBkZWxsJ0VzVGQgZGEgdXRpbGl6emFyZSBwZXIgbGEgY29sb25uYSBzcGVjaWZpY2F0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uIENvbG9ubmEgcGVyIGN1aSBjZXJjYXJlIGxhIGNlbGxhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtUZW1wbGF0ZVJlZjxhbnk+fSBUZW1wbGF0ZSBkYSB1c2FyZSBwZXIgbGEgY29sb25uYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmluZEVzVGQoY29sdW1uOiBzdHJpbmcpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcclxuICAgICAgICB2YXIgRXNUZCA9IHRoaXMuRXNUZHNEaXJlY3RpdmUuZmluZCgoaXRlbSkgPT4gaXRlbS50ZCA9PT0gY29sdW1uKTtcclxuICAgICAgICByZXR1cm4gRXNUZCA/IEVzVGQuVGVtcGxhdGUgOiBudWxsO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEVxdWl2YWxlbnRlIGRlbCBtZXRvZG8gKiphZGRUb1BhZ2UqKiByaWFkYXR0YXRvIHBlciBsYSBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBOdW1lcm8gZGkgcGFnaW5lIGRhIGFnZ2l1bmdlcmUgKG8gc290dHJhcnJlLCBzZSBuZWdhdGl2bykgYWxsYSBwYWdpbmEgYXR0dWFsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXJyYXlBZGRUb1BhZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5hcnJheUdvVG9QYWdlKHRoaXMuYXJyYXltb2RlUGFnZSArIHBhZ2UpXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcXVpdmFsZW50ZSBkZWwgbWV0b2RvICoqZ29Ub1BhZ2UqKiByaWFkYXR0YXRvIHBlciBsYSBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBQYWdpbmEgYSBjdWkgbmF2aWdhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFycmF5R29Ub1BhZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHBhZ2UgPT09IDAgfHwgcGFnZSA+IHRoaXMuYXJyYXltb2RlUGFnZXMpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB0aGlzLmFycmF5bW9kZVBhZ2UgPSBwYWdlO1xyXG5cclxuICAgICAgICAvLyBSaWZvcnpvIGlsIHdyaXRldmFsdWUgaW4gbW9kbyBjaGUgaWwgY29kaWNlIHBhc3NpIGRhbGxhIGdlc3Rpb25lIGNvbWUgc2UgZm9zc2UgZmF0dGEgcmlwYXJ0aXJlIHVuYSByaWNlcmNhXHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbFdyaXRlVmFsdWUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlc3RvcmUgZGVpIGNsaWNrIHN1bGxlIGNlbGxlIHBlciBsZSBxdWFsaSBlcmEgaW1wb3N0YXRhIHVuYSBhemlvbmUgY3VzdG9tIGRhICoqQ3VzdG9tQ2VsbEFjdGlvbnNPbioqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgTm9tZSBkZWxsYSBjZWxsYSBzdSBjdWkgc2kgw6ggZmF0dG8gY2xpY2tcclxuICAgICAqIEBwYXJhbSB7YW55fSBtb2RlbCBNb2RlbGxvIHJlbGF0aXZvIGFsbGEgY2VsbGEgY2xpY2NhdGFcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gKip0cnVlKiogc2UgaWwgY2xpY2sgw6ggc3RhdG8gZmF0dG8gc3UgdW5hIGNlbGxhIGNsaWNjYWJpbGUsICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjZWxsQ2xpY2tlZChuYW1lOiBzdHJpbmcsIG1vZGVsOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5Vc2VDdXN0b21DZWxsQWN0aW9ucyAmJiB0aGlzLkN1c3RvbUNlbGxBY3Rpb25zT24uc3BsaXQoJyQnKS5pbmRleE9mKG5hbWUpICE9IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25DZWxsQ2xpY2suZW1pdCh7IGNvbHVtbjogbmFtZSwgbW9kZWw6IG1vZGVsIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlc3Rpb25lIGRlaSBjbGljayBzdWxsZSBvcHppb25pIGRlbCBtZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhIGdlbmVyYXRvIGRhbGwnSW5wdXQgKipDb3JuZXJNZW51T3B0aW9ucyoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvcm5lcmlkIENvZGljZSBkZWxsJ29wZXJhemlvbmUgc2VsZXppb25hdGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvcm5lckFjdGlvbkNsaWNrZWQoY29ybmVyaWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMub25Db3JuZXJBY3Rpb24uZW1pdCh7IGlkOiBjb3JuZXJpZCwgZXN0YWJsZTogdGhpcyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBJbXBvc3RhemlvbmUgbW9kYWxpdMOgIGRlbGwnRXNUYWJsZSBcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHsnYXJyYXknIHwgJ3ZpZXcnIHwgJ3JlcG9ydCd9IG1vZGUgTW9kYWxpdMOgIGRhIGltcG9zdGFyZVxyXG4gICAgICoqL1xyXG4gICAgcHJpdmF0ZSBzZXRNb2RlKG1vZGU6ICdhcnJheScgfCAndmlldycgfCAncmVwb3J0Jykge1xyXG4gICAgICAgIHRoaXMudmlld01vZGUgPSBtb2RlID09ICd2aWV3JztcclxuICAgICAgICB0aGlzLmFycmF5TW9kZSA9IG1vZGUgPT0gJ2FycmF5JztcclxuICAgICAgICB0aGlzLnJlcG9ydE1vZGUgPSBtb2RlID09ICdyZXBvcnQnO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5yZXBvcnRNb2RlKSB7XHJcbiAgICAgICAgICAgIC8vIEluIG1vZGFsaXTDoCByZXBvcnQgaG8gZGkgc2ljdXJvIHF1ZXN0ZSBkdWVcclxuICAgICAgICAgICAgdGhpcy5YTFNYRXhwb3J0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5DU1ZFeHBvcnQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgcGVyIGVmZmV0dHVhcmUgY2hpYW1hdGUgaW50ZXJuZSBkaSBhbGxpbmVhbWVudG8gYWxsYSBmdW56aW9uZSAqKndyaXRlVmFsdWUqKiwgXHJcbiAgICAgKiBpbXBvc3RhbmRvIHByaW1hICoqaW50ZXJuYWxXcml0ZUNhbGwqKiBpbiBtb2RvIGRhIG5vbiBlZmZldHR1YXJlIG9wZXJhemlvbmkgaW51dGlsaVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaW50ZXJuYWxXcml0ZVZhbHVlKCkge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZUNhbGwgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMud3JpdGVWYWx1ZSh0aGlzLlZpZXcpO1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZUNhbGwgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBldmVudHVhbG1lbnRlIHJpY2hpYW1hYmlsZSBhbmNoZSBkYWwgY29tcG9uZW50ZSBlc3Rlcm5vIGNoZSBwZXJtZXR0ZSBkaSBmb3J6YXJlIHVuIHJlZnJlc2ggZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZm9yY2VSZWZyZXNoKCkge1xyXG5cclxuICAgICAgICAvLyBTZSBzb25vIGluIG1vZGFsaXTDoCBWaWV3IHZpZW5lIG1hbnRlbnV0byBpbiBhdXRvbWF0aWNvIGlsIG51bWVybyBkaSBwYWdpbmEsIG1hIHBlciBsYSBtb2RhbGl0w6AgYXJyYXkgZGV2byBwcmVuZGVyZSBsZSBpbmZvIGRpIHBhZ2luYXppb25lIHByaW1hIGUgcmlhcHBsaWNhcmxlIGRvcG9cclxuICAgICAgICBsZXQgYXJyYXlQYWdlOiBudW1iZXI7XHJcbiAgICAgICAgbGV0IGFycmF5SXBwOiBudW1iZXI7XHJcbiAgICAgICAgaWYgKHRoaXMuYXJyYXlNb2RlKSB7XHJcbiAgICAgICAgICAgIGFycmF5UGFnZSA9IHRoaXMuYXJyYXltb2RlUGFnZTtcclxuICAgICAgICAgICAgYXJyYXlJcHAgPSB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMud3JpdGVWYWx1ZSh0aGlzLlZpZXcpO1xyXG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuYXJyYXlNb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlID0gYXJyYXlJcHA7XHJcbiAgICAgICAgICAgIHRoaXMuYXJyYXlHb1RvUGFnZShhcnJheVBhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSJdfQ==
|