@esfaenza/es-table 11.2.21 → 11.2.22-beta12
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 +3430 -1575
- 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 +7 -6
- package/esfaenza-es-table.metadata.json +1 -1
- package/esm2015/esfaenza-es-table.js +8 -7
- package/esm2015/lib/components/es-table/es_table.component.js +1293 -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 +100 -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 +121 -0
- package/esm2015/lib/core/handlers/classes/ReportModeHandler.js +70 -0
- package/esm2015/lib/core/handlers/classes/RowGroupingHandler.js +475 -0
- package/esm2015/lib/core/handlers/classes/SelectionHandler.js +527 -0
- package/esm2015/lib/core/handlers/classes/UtilitiesHandler.js +169 -0
- package/esm2015/lib/core/handlers/index.js +10 -0
- package/esm2015/lib/directives/es_td.directive.js +2 -4
- package/esm2015/lib/directives/es_th.directive.js +23 -7
- package/esm2015/lib/domain/configuration/EsTableDefaultable.js +4 -0
- package/esm2015/lib/domain/configuration/EsTableModuleConfig.js +4 -0
- package/esm2015/lib/domain/externals/classes/CornerMenuOption.js +4 -0
- package/esm2015/lib/domain/externals/classes/EsTableColumnsDefinition.js +31 -0
- package/esm2015/lib/domain/externals/classes/EsTableOperationDefinition.js +22 -0
- package/esm2015/lib/domain/externals/classes/appsearch/AppOrdering.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/AppSearch.js +35 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GenericItem.js +11 -0
- package/esm2015/lib/domain/externals/classes/appsearch/Group.js +17 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupAggregation.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupFilter.js +14 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupOrAggregation.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/ItemsSelection.js +23 -0
- package/esm2015/lib/domain/externals/classes/report/ReportColumn.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportDefinition.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportOrder.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportParam.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportResult.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportRow.js +4 -0
- package/esm2015/lib/domain/externals/index.js +18 -0
- package/esm2015/lib/domain/index.js +3 -16
- package/esm2015/lib/domain/internals/classes/CacheTriptic.js +16 -0
- package/esm2015/lib/domain/internals/classes/EsTableColumn.js +24 -0
- package/esm2015/lib/domain/internals/classes/GroupPager.js +21 -0
- package/esm2015/lib/domain/internals/classes/GroupRouteFragment.js +17 -0
- package/esm2015/lib/domain/internals/classes/ThAggregation.js +16 -0
- package/esm2015/lib/domain/internals/classes/ThElement.js +2 -0
- package/esm2015/lib/domain/internals/index.js +7 -0
- package/esm2015/lib/es-table.module.js +13 -8
- package/esm2015/lib/tokens.js +6 -4
- package/esm2015/public-api.js +7 -6
- package/fesm2015/esfaenza-es-table.js +3416 -1692
- package/fesm2015/esfaenza-es-table.js.map +1 -1
- package/lib/{es_table.component.d.ts → components/es-table/es_table.component.d.ts} +163 -331
- package/lib/{es_table.component.loc.d.ts → components/es-table/es_table.component.loc.d.ts} +2 -6
- package/lib/{es_td.component.d.ts → components/es-td/es_td.component.d.ts} +14 -36
- package/lib/{es_th.component.d.ts → components/es-th/es_th.component.d.ts} +27 -61
- package/lib/components/pager/table_pager.component.d.ts +50 -0
- package/lib/{pager → components/pager}/table_pager.component.loc.d.ts +2 -6
- package/lib/core/handlers/classes/ColumnMetadataHandler.d.ts +159 -0
- package/lib/core/handlers/classes/DynamicModeHandler.d.ts +32 -0
- package/lib/core/handlers/classes/ExportHandler.d.ts +22 -0
- package/lib/core/handlers/classes/HierarchyModeHandler.d.ts +40 -0
- package/lib/core/handlers/classes/ItemsHandler.d.ts +41 -0
- package/lib/core/handlers/classes/ReportModeHandler.d.ts +21 -0
- package/lib/core/handlers/classes/RowGroupingHandler.d.ts +114 -0
- package/lib/core/handlers/classes/SelectionHandler.d.ts +149 -0
- package/lib/core/handlers/classes/UtilitiesHandler.d.ts +67 -0
- package/lib/core/handlers/index.d.ts +9 -0
- package/lib/directives/es_td.directive.d.ts +1 -3
- package/lib/directives/es_th.directive.d.ts +18 -5
- package/lib/domain/configuration/EsTableDefaultable.d.ts +19 -0
- package/lib/domain/configuration/EsTableModuleConfig.d.ts +10 -0
- package/lib/domain/externals/classes/CornerMenuOption.d.ts +7 -0
- package/lib/domain/{classes → externals/classes}/EsTableColumnsDefinition.d.ts +5 -7
- package/lib/domain/{classes → externals/classes}/EsTableOperationDefinition.d.ts +1 -3
- package/lib/domain/{classes → externals/classes/appsearch}/AppOrdering.d.ts +0 -0
- package/lib/domain/externals/classes/appsearch/AppSearch.d.ts +67 -0
- package/lib/domain/externals/classes/appsearch/GenericItem.d.ts +13 -0
- package/lib/domain/externals/classes/appsearch/Group.d.ts +17 -0
- package/lib/domain/externals/classes/appsearch/GroupAggregation.d.ts +14 -0
- package/lib/domain/externals/classes/appsearch/GroupFilter.d.ts +12 -0
- package/lib/domain/externals/classes/appsearch/GroupOrAggregation.d.ts +14 -0
- package/lib/domain/externals/classes/appsearch/ItemsSelection.d.ts +22 -0
- package/lib/domain/externals/classes/report/ReportColumn.d.ts +15 -0
- package/lib/domain/externals/classes/report/ReportDefinition.d.ts +24 -0
- package/lib/domain/externals/classes/report/ReportOrder.d.ts +7 -0
- package/lib/domain/externals/classes/report/ReportParam.d.ts +40 -0
- package/lib/domain/externals/classes/report/ReportResult.d.ts +12 -0
- package/lib/domain/externals/classes/report/ReportRow.d.ts +5 -0
- package/lib/domain/externals/index.d.ts +17 -0
- package/lib/domain/index.d.ts +2 -15
- package/lib/domain/internals/classes/CacheTriptic.d.ts +14 -0
- package/lib/domain/{classes → internals/classes}/EsTableColumn.d.ts +8 -4
- package/lib/domain/internals/classes/GroupPager.d.ts +22 -0
- package/lib/domain/internals/classes/GroupRouteFragment.d.ts +15 -0
- package/lib/domain/internals/classes/ThAggregation.d.ts +14 -0
- package/lib/domain/internals/classes/ThElement.d.ts +13 -0
- package/lib/domain/internals/index.d.ts +6 -0
- package/lib/es-table.module.d.ts +1 -1
- package/lib/tokens.d.ts +6 -3
- package/package.json +2 -1
- package/public-api.d.ts +6 -5
- package/esm2015/lib/domain/classes/AppOrdering.js +0 -16
- package/esm2015/lib/domain/classes/AppSearch.js +0 -35
- package/esm2015/lib/domain/classes/CornerMenuOption.js +0 -6
- package/esm2015/lib/domain/classes/EsTableColumn.js +0 -22
- package/esm2015/lib/domain/classes/EsTableColumnsDefinition.js +0 -31
- package/esm2015/lib/domain/classes/EsTableOperationDefinition.js +0 -24
- package/esm2015/lib/domain/classes/GenericItem.js +0 -15
- package/esm2015/lib/domain/classes/IAppSearch.js +0 -2
- package/esm2015/lib/domain/classes/ItemsSelection.js +0 -25
- package/esm2015/lib/domain/classes/ReportColumn.js +0 -6
- package/esm2015/lib/domain/classes/ReportDefinition.js +0 -6
- package/esm2015/lib/domain/classes/ReportOrder.js +0 -6
- package/esm2015/lib/domain/classes/ReportParam.js +0 -6
- package/esm2015/lib/domain/classes/ReportResult.js +0 -6
- package/esm2015/lib/domain/classes/ReportRow.js +0 -6
- package/esm2015/lib/es_table.component.js +0 -1958
- package/esm2015/lib/es_table.component.loc.js +0 -36
- package/esm2015/lib/es_td.component.js +0 -121
- package/esm2015/lib/es_th.component.js +0 -178
- package/esm2015/lib/models/EsTableModuleConfig.js +0 -6
- package/esm2015/lib/pager/table_pager.component.js +0 -70
- package/esm2015/lib/pager/table_pager.component.loc.js +0 -24
- package/lib/domain/classes/AppSearch.d.ts +0 -76
- package/lib/domain/classes/CornerMenuOption.d.ts +0 -13
- package/lib/domain/classes/GenericItem.d.ts +0 -25
- package/lib/domain/classes/IAppSearch.d.ts +0 -67
- package/lib/domain/classes/ItemsSelection.d.ts +0 -27
- package/lib/domain/classes/ReportColumn.d.ts +0 -29
- package/lib/domain/classes/ReportDefinition.d.ts +0 -46
- package/lib/domain/classes/ReportOrder.d.ts +0 -13
- package/lib/domain/classes/ReportParam.d.ts +0 -76
- package/lib/domain/classes/ReportResult.d.ts +0 -22
- package/lib/domain/classes/ReportRow.d.ts +0 -9
- package/lib/models/EsTableModuleConfig.d.ts +0 -9
- package/lib/pager/table_pager.component.d.ts +0 -50
|
@@ -0,0 +1,1293 @@
|
|
|
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 se nascondere o mostrare il componente di paginazione */
|
|
178
|
+
this.HidePaging = null;
|
|
179
|
+
/** Indica se nascondere o mostrare il conteggio degli elementi trovati */
|
|
180
|
+
this.HidePagingCount = null;
|
|
181
|
+
/** Indica se nascondere o mostrare i pulsanti di paginazione */
|
|
182
|
+
this.HidePagingButtons = null;
|
|
183
|
+
/** Riferimento al ContextMenu (ngx-contextmenu) associato al click destro di uno o più elementi selezionati nella tabella */
|
|
184
|
+
this.ContextMenu = null;
|
|
185
|
+
/** Nome dell'esportazione generata da questa tabella */
|
|
186
|
+
this.ExportFileName = 'Export.csv';
|
|
187
|
+
/** Classe (HTML) di default della tabella */
|
|
188
|
+
this.TableClass = null;
|
|
189
|
+
/** @deprecated Indica la presenza di raggruppamenti a livello di header */
|
|
190
|
+
this.HasHeaderGroup = null;
|
|
191
|
+
/** @deprecated Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
|
|
192
|
+
this.HasSecondaryHeaderGroup = null;
|
|
193
|
+
/** Utilizzato per dividere la sorgente in modalità EndlessScroll */
|
|
194
|
+
this.SliceSize = 100;
|
|
195
|
+
/** Decide se utilizzare la modalità di EndlessScroll */
|
|
196
|
+
this.EndlessScroll = null;
|
|
197
|
+
/** Qualora **EndlessScroll** fosse true, indica se utilizzare questa modalità solo quando si cerca per "Tutti" o in generale */
|
|
198
|
+
this.EndlessScrollOnlyForAll = true;
|
|
199
|
+
/** Indica se nascondere gli Header della tabella */
|
|
200
|
+
this.HeaderHidden = null;
|
|
201
|
+
/** Indica se nascondere il Body della tabella */
|
|
202
|
+
this.BodyHidden = null;
|
|
203
|
+
/**
|
|
204
|
+
* Indica se la selezione è temporaneamente disabilitata. Rispetto all'Input **Selection** che visivamente gestisce se ci sono o no gli input di selezione,
|
|
205
|
+
* questo Input gestisce se questi input sono abilitati o meno
|
|
206
|
+
*/
|
|
207
|
+
this.SelectionDisabled = null;
|
|
208
|
+
/**
|
|
209
|
+
* Indica se forzare il sistema di selezione a gestire un elemento per volta.
|
|
210
|
+
* Selezionare un'altra riga con una già selezionata applicherà la selezione alla nuova riga, rimuovendola dall'attuale
|
|
211
|
+
*/
|
|
212
|
+
this.SingleSelection = null;
|
|
213
|
+
/** Callback che dato un oggetto resituisce l'eventuale classe da applicare alla riga collegata all'oggetto */
|
|
214
|
+
this.RowClassAssigner = null;
|
|
215
|
+
/** Permette di ordinare i dati in maniera discendente o ascendente */
|
|
216
|
+
this.OrderByColumn = null;
|
|
217
|
+
/** Permette di avere più direttive di ordinamento dei dati */
|
|
218
|
+
this.MultipleOrderingDirectives = true;
|
|
219
|
+
/** Permette di nascondere le colonne in base alle selezioni effettuate dal Menù contestuale in alto a destra */
|
|
220
|
+
this.HiddenColumns = null;
|
|
221
|
+
/** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
|
|
222
|
+
this.ColumnsOrdering = null;
|
|
223
|
+
/** Eventuale supporto alle ricerche applicate alla modalità Array */
|
|
224
|
+
this.SearchView = null;
|
|
225
|
+
/** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
|
|
226
|
+
this.SelectAll = null;
|
|
227
|
+
/** Simula la paginazione anche per le tabelle che funzionano in modalità Array */
|
|
228
|
+
this.UseArrayModePaging = true;
|
|
229
|
+
/** Definizione di colonne dinamche per la modalità, appunto, dinamica */
|
|
230
|
+
this.DynamicRowColumnsDefinition = null;
|
|
231
|
+
/** Indica operazioni dinamiche generiche che possono essere effettuate per riga. Appaiono come colonne extra sul lato sinistro della tabella */
|
|
232
|
+
this.DynamicOperations = [];
|
|
233
|
+
/** Indica se visualizzare i dati in maniera gerarchica */
|
|
234
|
+
this.Hierarchy = null;
|
|
235
|
+
/** Nome della proprietà che contiene l'ID del padre. Da utilizzare se **Hierarchy** è impostato */
|
|
236
|
+
this.ParentKey = '';
|
|
237
|
+
/** Nome della proprietà che contiene l'ID dell'oggetto attuale. Da utilizzare se **Hierarchy** è impostato */
|
|
238
|
+
this.OwnKey = '';
|
|
239
|
+
/** Indica se partire con un albero espanso. Da utilizzare se **Hierarchy** è impostato */
|
|
240
|
+
this.StartsExpanded = true;
|
|
241
|
+
/** Indica se effettuare il salvataggio delle preferenze di ricerca */
|
|
242
|
+
this.SavePreferences = null;
|
|
243
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
244
|
+
this.PagingStyle = null;
|
|
245
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
246
|
+
this.RowGroupingPagingStyle = null;
|
|
247
|
+
/**
|
|
248
|
+
* Sorgente dati secondaria
|
|
249
|
+
*
|
|
250
|
+
* @deprecated Utilizzato solo per un caso particolare del Metering
|
|
251
|
+
*/
|
|
252
|
+
this.SecondarySource = null;
|
|
253
|
+
/**
|
|
254
|
+
* Sorgente dati secondaria
|
|
255
|
+
*
|
|
256
|
+
* @deprecated Utilizzato solo per un caso particolare del Metering
|
|
257
|
+
*/
|
|
258
|
+
this.TertiarySource = null;
|
|
259
|
+
/** Indica se utilizzare la cache di selezione che permette di mantenere gli stati di selezione dei vari oggetti navigando da una pagina all'altra */
|
|
260
|
+
this.UseSelectionCache = null;
|
|
261
|
+
/** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
|
|
262
|
+
this.ShowItemGroupsColumns = null;
|
|
263
|
+
/** Evento che viene richiamato al cambio di oridnamento di una colonna */
|
|
264
|
+
this.onOrderChanged = new EventEmitter();
|
|
265
|
+
/**
|
|
266
|
+
* Evento che viene richiamato quando l'es-table ritiene sia necessario ri-effettuare la ricerca.
|
|
267
|
+
* Il booleano dell'evento indica se viene suggerito di resettare la pagina o meno.
|
|
268
|
+
*
|
|
269
|
+
* 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,
|
|
270
|
+
* in quel caso l'applicazione ricevente dovrà onorare la richiesta spedendo al backand l'oggetto di ricerca AS-IS
|
|
271
|
+
*
|
|
272
|
+
* il tipo dell'Emitter invece di essere [boolean | AppSearch<any>] è stato impostato a "any" per evitare problemi di retrocompatibilità
|
|
273
|
+
*/
|
|
274
|
+
this.onSearchRequest = new EventEmitter();
|
|
275
|
+
/** Evento che parte ad ogni modifica di "checkaggio" in forma di comodo array. Espone l'oggetto con lo stato di check attuale */
|
|
276
|
+
this.onSelectionChanged = new EventEmitter();
|
|
277
|
+
/** Evento richiamato all'eliminazione di un oggetto */
|
|
278
|
+
this.onRemoval = new EventEmitter();
|
|
279
|
+
/** Evento richiamato all'annullamento di un'eliminazione */
|
|
280
|
+
this.onAbortRemoval = new EventEmitter();
|
|
281
|
+
/** Evento richiamato al click su una cella quando **UseCustomCellActions** è attivo
|
|
282
|
+
*
|
|
283
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
284
|
+
*/
|
|
285
|
+
this.onCellClick = new EventEmitter();
|
|
286
|
+
/** Evento richiamato quando si clicca su un opzione definita nelle **CornerMenuOptions** */
|
|
287
|
+
this.onCornerAction = new EventEmitter();
|
|
288
|
+
/** Evento richiamato quando si clicca su un opzione definita nelle **DynamicOperations** */
|
|
289
|
+
this.onDynamicOperation = new EventEmitter();
|
|
290
|
+
/** Pagina in visualizzazione (durante la paginazione in modalità Array) */
|
|
291
|
+
this.arraymodePage = 1;
|
|
292
|
+
/** Numero di pagine (durante la paginazione in modalità Array) */
|
|
293
|
+
this.arraymodePages = 1;
|
|
294
|
+
/** Oggetti per ogni pagina (durante la paginazione in modalità Array) */
|
|
295
|
+
this.ArraymodeItemsPerPage = null;
|
|
296
|
+
/** Colonne da visualizzare in modalità array */
|
|
297
|
+
this.arrayColumns = [];
|
|
298
|
+
/** Ordine delle colonne da visualizzare in modalità array */
|
|
299
|
+
this.arrayColumnOrdering = [];
|
|
300
|
+
/** Ordinamenti ASC-DESC sulle colonne in modalità array */
|
|
301
|
+
this.arrayOrders = [];
|
|
302
|
+
/**
|
|
303
|
+
* Variabile che serve a gestire il momento in cui l'es-table aggiorna la paginazione (pulsanti ecc).
|
|
304
|
+
* Essendo operazioni comunque costose le effettuo solo su binding esterni, non su rewrite generati internamente
|
|
305
|
+
*/
|
|
306
|
+
this.internalWriteCall = false;
|
|
307
|
+
/**
|
|
308
|
+
* Cache che conterrà tutte le ricerche effettuate su gruppi diversi dal primo e su elementi contenuti nei gruppi.
|
|
309
|
+
* 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:
|
|
310
|
+
*
|
|
311
|
+
*
|
|
312
|
+
* **Cambio ordinamento sul primo gruppo**: reload completo, non mi occupo di ripulire gli elementi bindati in alcun modo
|
|
313
|
+
*
|
|
314
|
+
* **Cambio ordinamento sulla colonna relativa all'N-esimo gruppo**: reload completo del contenuto dei gruppi precedenti, ripulendo precedentemente
|
|
315
|
+
* tutti gli elementi con **_grouplevel** = N
|
|
316
|
+
*
|
|
317
|
+
* **Cambio ordinamento su una colonna non raggruppata**: reload completo per tutti i gruppi finali aperti, devo precedentemente ripulire tutti gli elementi con **_item** = true
|
|
318
|
+
*
|
|
319
|
+
* Altri eventi non dovrebbero rappresentare problemi:
|
|
320
|
+
* - Selezione: non cambia nulla
|
|
321
|
+
* - Paginazione: cambia a livello root quindi viene ricaricato tutto comunque, stesso vale per le paginazioni interne
|
|
322
|
+
*/
|
|
323
|
+
this.groupSearchRequestsCache = [];
|
|
324
|
+
/** Variabile d'appoggio per capire se c'è bisogno di ri-effettuare una ricerca o meno */
|
|
325
|
+
this.ResearchNeeded = false;
|
|
326
|
+
/** Colonne visibili della vista attuale. Valorizzato di default al numero massimo di colonne supportate dalla tabella per le casistiche in assenza di custom cells */
|
|
327
|
+
this.Columns = { Visibile: 100, VisibleUnpinned: 100, Global: 100 };
|
|
328
|
+
/** In caso di Row Grouping qui viene salvata la vista principale dei gruppi base */
|
|
329
|
+
this.MainGroupView = null;
|
|
330
|
+
/** 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" */
|
|
331
|
+
this.BaseItemsCount = null;
|
|
332
|
+
/** 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 */
|
|
333
|
+
this.ArrayGrouping = false;
|
|
334
|
+
/** Opzioni di paginazione */
|
|
335
|
+
this.PagerOptions = { PagerCount: null, ShowCount: true, ShowPaging: true, UsesView: true, View: null, Ready: false, Searches: 'items' };
|
|
336
|
+
/** @ignore */
|
|
337
|
+
this.propagateChange = (_) => { };
|
|
338
|
+
this.export_H = new ExportHandler(this, this.expExts, this.msgExts);
|
|
339
|
+
this.rowGrouping_H = new RowGroupingHandler(this, this.utilities_H, this.dateExts);
|
|
340
|
+
this.columnMetadata_H = new ColumnMetadataHandler(this, this.utilities_H, this.utiExts, this.prefService, this.rowGrouping_H);
|
|
341
|
+
this.dynamicMode_H = new DynamicModeHandler(this);
|
|
342
|
+
this.hierarchyMode_H = new HierarchyModeHandler(this);
|
|
343
|
+
this.items_H = new ItemsHandler(this, this.utilities_H);
|
|
344
|
+
this.reportMode_H = new ReportModeHandler(this, this.utilities_H);
|
|
345
|
+
this.selection_H = new SelectionHandler(this, this.rowGrouping_H);
|
|
346
|
+
if (ngControl)
|
|
347
|
+
ngControl.valueAccessor = this;
|
|
348
|
+
// Assegnazione per tutti gli Input di default
|
|
349
|
+
this.ColumnsResizable = this.utilities_H.InputOrDefault(this.ColumnsResizable, (_a = this.deafults) === null || _a === void 0 ? void 0 : _a.ColumnsResizable);
|
|
350
|
+
this.AutoUpdate = this.utilities_H.InputOrDefault(this.AutoUpdate, (_b = this.deafults) === null || _b === void 0 ? void 0 : _b.AutoUpdate);
|
|
351
|
+
this.AllSearch = this.utilities_H.InputOrDefault(this.AllSearch, (_c = this.deafults) === null || _c === void 0 ? void 0 : _c.AllSearch, true);
|
|
352
|
+
this.Export = this.utilities_H.InputOrDefault(this.Export, (_d = this.deafults) === null || _d === void 0 ? void 0 : _d.Export);
|
|
353
|
+
this.HidePaging = this.utilities_H.InputOrDefault(this.HidePaging, (_e = this.deafults) === null || _e === void 0 ? void 0 : _e.HidePaging, false);
|
|
354
|
+
this.HidePagingCount = this.utilities_H.InputOrDefault(this.HidePagingCount, (_f = this.deafults) === null || _f === void 0 ? void 0 : _f.HidePagingCount);
|
|
355
|
+
this.HidePagingButtons = this.utilities_H.InputOrDefault(this.HidePagingButtons, (_g = this.deafults) === null || _g === void 0 ? void 0 : _g.HidePagingButtons);
|
|
356
|
+
this.ContainerClass = this.utilities_H.InputOrDefault(this.ContainerClass, (_h = this.deafults) === null || _h === void 0 ? void 0 : _h.ContainerClass, '');
|
|
357
|
+
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');
|
|
358
|
+
this.Selection = this.utilities_H.InputOrDefault(this.Selection, (_k = this.deafults) === null || _k === void 0 ? void 0 : _k.Selection);
|
|
359
|
+
this.SavePreferences = this.utilities_H.InputOrDefault(this.SavePreferences, (_l = this.deafults) === null || _l === void 0 ? void 0 : _l.SavePreferences);
|
|
360
|
+
this.PagingStyle = this.utilities_H.InputOrDefault(this.PagingStyle, (_m = this.deafults) === null || _m === void 0 ? void 0 : _m.PagingStyle, 'bottom');
|
|
361
|
+
this.RowGroupingPagingStyle = this.utilities_H.InputOrDefault(this.RowGroupingPagingStyle, (_o = this.deafults) === null || _o === void 0 ? void 0 : _o.RowGroupingPagingStyle, 'left');
|
|
362
|
+
this.UseSelectionCache = this.utilities_H.InputOrDefault(this.UseSelectionCache, (_p = this.deafults) === null || _p === void 0 ? void 0 : _p.UseSelectionCache, true);
|
|
363
|
+
this.ShowItemGroupsColumns = this.utilities_H.InputOrDefault(this.ShowItemGroupsColumns, (_q = this.deafults) === null || _q === void 0 ? void 0 : _q.ShowItemGroupsColumns, false);
|
|
364
|
+
this.ArraymodeItemsPerPage = this.utilities_H.InputOrDefault(this.ArraymodeItemsPerPage, (_r = this.deafults) === null || _r === void 0 ? void 0 : _r.ArraymodeItemsPerPage, 15);
|
|
365
|
+
}
|
|
366
|
+
/** @ignore */
|
|
367
|
+
ngOnInit() {
|
|
368
|
+
//Per poter cambiare il layout in base al livello gerarchico il componente deva avere il pieno controllo di ogni cella,
|
|
369
|
+
//che con solo la proiezione (senza celle cusotm) non è disponibile
|
|
370
|
+
if (this.Hierarchy && !this.UseCustomCells)
|
|
371
|
+
throw "Es-table error: Per poter utilizzare l'es-table con [Hierarchy]=\"true\" è richiesto anche [UseCustomCells]=\"true\"";
|
|
372
|
+
// click destro su una riga con selezione attiva: Tiro fuori il context menu e selezione l'elemento corrente
|
|
373
|
+
this.ctxMenuSubscription = (this.ContextMenu || this.tableEmptyMenu).open.subscribe(t => {
|
|
374
|
+
// Gruppi va bene, oggetti pure, ma separatori fra gruppi proprio no...
|
|
375
|
+
if (t.item._sep)
|
|
376
|
+
return;
|
|
377
|
+
let shouldEmit = !t.item._selected;
|
|
378
|
+
t.item._selected = true;
|
|
379
|
+
var itemSelection = this.selection_H.handleItemsSelection([t.item]);
|
|
380
|
+
this.changed();
|
|
381
|
+
if (shouldEmit)
|
|
382
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/** @ignore */
|
|
386
|
+
ngAfterViewInit() {
|
|
387
|
+
// Se utilizzo la new spicy mode deduco tutti i parametri di lavoro possibili al caricamento della tabella
|
|
388
|
+
// Vengono sovrascritte solo le proprietà non impostate dall'utente
|
|
389
|
+
if (this.EsTdsDirective && this.EsTdsDirective.length > 0 && this.EsThsDirective && this.EsThsDirective.length > 0) {
|
|
390
|
+
if (this.UseCustomCells == null)
|
|
391
|
+
this.UseCustomCells = true;
|
|
392
|
+
if (this.HiddenColumns == null && this.UseCustomCells)
|
|
393
|
+
this.HiddenColumns = true;
|
|
394
|
+
if (this.ColumnsOrdering == null && this.UseCustomCells)
|
|
395
|
+
this.ColumnsOrdering = true;
|
|
396
|
+
if (this.OrderByColumn == null && this.UseCustomCells)
|
|
397
|
+
this.OrderByColumn = true;
|
|
398
|
+
if (this.SelectAll == null && this.Selection)
|
|
399
|
+
this.SelectAll = true;
|
|
400
|
+
if (this.ShiftClick == null && this.Selection)
|
|
401
|
+
this.ShiftClick = true;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/** @ignore */
|
|
405
|
+
ngOnDestroy() {
|
|
406
|
+
if (this.ctxMenuSubscription)
|
|
407
|
+
this.ctxMenuSubscription.unsubscribe();
|
|
408
|
+
}
|
|
409
|
+
/** @ignore */
|
|
410
|
+
ngOnChanges(changes) {
|
|
411
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
412
|
+
let newSearchView = changes['SearchView'];
|
|
413
|
+
if (newSearchView && this.SearchView)
|
|
414
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/** @ignore */
|
|
418
|
+
registerOnChange(fn) { this.propagateChange = fn; }
|
|
419
|
+
/** @ignore */
|
|
420
|
+
registerOnTouched(fn) { }
|
|
421
|
+
/** @ignore */
|
|
422
|
+
changed() { this.propagateChange(this.View); }
|
|
423
|
+
/** @ignore */
|
|
424
|
+
writeValue(obj) {
|
|
425
|
+
var _a;
|
|
426
|
+
this.View = obj ? obj : null;
|
|
427
|
+
// Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
|
|
428
|
+
this.researchInProgress = false;
|
|
429
|
+
if (!this.View && !this.SearchView) {
|
|
430
|
+
// Su view nulla evito di fare pressoché qualsiasi cosa. Se arriva un null devo anche assicurarmi di non mostrare nulla
|
|
431
|
+
this.boundSource = this.TMPBoundSource || [];
|
|
432
|
+
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
433
|
+
this.cdr.markForCheck();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
// Se per sbaglio l'oggetto che mi arriva non è tipizzato (instanceof AppSearch restituisce false anche se è del tipo giusto)
|
|
437
|
+
// lo correggo--------------------------------------------------------------------------------------------------------------
|
|
438
|
+
if (this.View && typeof this.View.result != 'undefined' && !(this.View instanceof ReportDefinition))
|
|
439
|
+
this.View.__proto__ = new ReportDefinition();
|
|
440
|
+
else if (this.View && typeof this.View.itemsperpageoverride != 'undefined' && !(this.View instanceof AppSearch))
|
|
441
|
+
this.View.__proto__ = new AppSearch();
|
|
442
|
+
else if (this.SearchView && typeof this.SearchView.itemsperpageoverride != 'undefined' && !(this.SearchView instanceof AppSearch))
|
|
443
|
+
this.SearchView.__proto__ = new AppSearch();
|
|
444
|
+
// -------------------------------------------------------------------------------------------------------------------------
|
|
445
|
+
if (this.View && this.View instanceof ReportDefinition) {
|
|
446
|
+
// Se mi arriva una report definition vuol dire che potrei avere dei risultati da visualizzare
|
|
447
|
+
this.setMode('report');
|
|
448
|
+
this.ReportValues = this.View.result;
|
|
449
|
+
if (this.ReportValues)
|
|
450
|
+
this.reportMode_H.reviewReportBindings();
|
|
451
|
+
}
|
|
452
|
+
else if (this.View && this.View instanceof AppSearch) {
|
|
453
|
+
// Se cambia l'oggetto intero significa che ho rimandato la ricerca
|
|
454
|
+
this.setMode('view');
|
|
455
|
+
let firstItemGroupOrNoGrouping = (((_a = this.View.requestedgroups) === null || _a === void 0 ? void 0 : _a.length) || 0) == 0;
|
|
456
|
+
// Se vengo da una ricerca interna mantengo lo stato di selezione precedente (quindi su cambio pagina, cambio ipp, ecc...)
|
|
457
|
+
// se invece l'utente ha fatto una ricerca lui (quindi cambiando filtri), secco le info di selezione
|
|
458
|
+
if (!this.View.selection || (!this.View.internalsearchrequest && firstItemGroupOrNoGrouping) || !this.UseSelectionCache) {
|
|
459
|
+
this.selection_H.clearSelectionCaches();
|
|
460
|
+
this.View.selection = new ItemsSelection([]);
|
|
461
|
+
this.onSelectionChanged.emit(this.View.selection);
|
|
462
|
+
}
|
|
463
|
+
this.View.internalsearchrequest = false;
|
|
464
|
+
// Recupero Preference
|
|
465
|
+
if (this.SavePreferences) {
|
|
466
|
+
if (!this.ngControl.name)
|
|
467
|
+
console.error("Non posso utilizzare le preference senza avere un 'name' per questa tabella");
|
|
468
|
+
else if (!this.prefService)
|
|
469
|
+
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
470
|
+
else {
|
|
471
|
+
this.prefService.retrieve(this.ngControl.name).subscribe(prefs => {
|
|
472
|
+
if (prefs) {
|
|
473
|
+
this.View.columns = prefs.columns;
|
|
474
|
+
this.View.column_ordering = prefs.column_ordering;
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
// 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)
|
|
480
|
+
if (firstItemGroupOrNoGrouping)
|
|
481
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.View.page, this.View.pages || 1, this.View.items.length, this.View.itemsperpageoverride);
|
|
482
|
+
}
|
|
483
|
+
else if (this.View && (this.View.length != null && this.View.length != undefined)) {
|
|
484
|
+
this.setMode('array');
|
|
485
|
+
if (!this.UseSelectionCache || !this.arraymodeSelection) {
|
|
486
|
+
this.selection_H.clearSelectionCaches();
|
|
487
|
+
this.arraymodeSelection = new ItemsSelection([]);
|
|
488
|
+
;
|
|
489
|
+
this.onSelectionChanged.emit(this.arraymodeSelection);
|
|
490
|
+
}
|
|
491
|
+
// Recupero Preference
|
|
492
|
+
if (this.SavePreferences) {
|
|
493
|
+
if (!this.ngControl.name)
|
|
494
|
+
console.error("Non posso utilizzare le preference senza avere un 'name' per questa tabella");
|
|
495
|
+
else if (!this.prefService)
|
|
496
|
+
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
497
|
+
else {
|
|
498
|
+
this.prefService.retrieve(this.ngControl.name).subscribe(prefs => {
|
|
499
|
+
if (prefs) {
|
|
500
|
+
this.arrayColumns = prefs.columns;
|
|
501
|
+
this.arrayColumnOrdering = prefs.column_ordering;
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (this.SearchView)
|
|
507
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1, this.SearchView.items.length, this.SearchView.itemsperpageoverride);
|
|
508
|
+
}
|
|
509
|
+
if (this.View && !(this.View instanceof ReportDefinition))
|
|
510
|
+
this.finalizeContext();
|
|
511
|
+
this.postBoundSourceCalculation();
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Successivamente al bind del nuovo input questa funzione si occupa di finalizzare tutti i parametri di funzionamento dell'es-table
|
|
515
|
+
* in base a Input - Modello, e qualsiasi altra cosa possa servire
|
|
516
|
+
*/
|
|
517
|
+
finalizeContext() {
|
|
518
|
+
let viewCasted = this.View;
|
|
519
|
+
/*
|
|
520
|
+
*Uso la tecnica di EndlessScroll se la variabile relativa è attiva e se
|
|
521
|
+
* 1) Ho un Array, oppure
|
|
522
|
+
* 2) Ho un AppSearch che sta cercando con paginazione "Tutto", oppure
|
|
523
|
+
* 3) Ho un AppSearch che sta cercando con paginazione diversa da "Tutto" ma con la variabile EndlessScrollOnlyForAll a false
|
|
524
|
+
*/
|
|
525
|
+
let isAppSearchWithIppMax = this.viewMode && viewCasted.itemsperpageoverride == this.defaultAllPageOverride;
|
|
526
|
+
let isAppSearchNoMaxIpp = this.viewMode && viewCasted.itemsperpageoverride != this.defaultAllPageOverride;
|
|
527
|
+
this.UseEndlessscroll = this.EndlessScroll && (this.arrayMode || isAppSearchWithIppMax || (isAppSearchNoMaxIpp && !this.EndlessScrollOnlyForAll));
|
|
528
|
+
let hasRowGroups = (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
|
|
529
|
+
// Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
|
|
530
|
+
if (this.arrayMode && hasRowGroups)
|
|
531
|
+
this.UseArrayModePaging = false;
|
|
532
|
+
// Riempimento della TMPBoundSource con gli oggetti che verranno poi mostrati ad interfaccia
|
|
533
|
+
if (this.UseEndlessscroll && !hasRowGroups) {
|
|
534
|
+
this.addedSlices = [];
|
|
535
|
+
this.boundSubSources = this.items_H.getItemSlices();
|
|
536
|
+
let firstSub = this.boundSubSources[0];
|
|
537
|
+
this.TMPBoundSource = firstSub ? firstSub : [];
|
|
538
|
+
if (firstSub)
|
|
539
|
+
this.addedSlices.push(0);
|
|
540
|
+
}
|
|
541
|
+
else
|
|
542
|
+
this.TMPBoundSource = this.items_H.getItemsByMode(false, !this.internalWriteCall);
|
|
543
|
+
// Se ho una gerarchia, assegno i livelli gerarchici alla TMPBoundSource
|
|
544
|
+
if (this.Hierarchy && !hasRowGroups)
|
|
545
|
+
this.hierarchyMode_H.assignHierarchyLevels(this.TMPBoundSource);
|
|
546
|
+
// L'hashing degli oggetti lo faccio a prescindere
|
|
547
|
+
this.utilities_H.calculateHash(this.TMPBoundSource);
|
|
548
|
+
// Assegno a una variabile mia l'eventuale override per la classe della riga
|
|
549
|
+
// Se poi sono in modalità gerarchica inietto anche la classe per la configurazione del livello della riga
|
|
550
|
+
if ((this.TMPBoundSource && this.RowClassAssigner) || this.Hierarchy) {
|
|
551
|
+
for (let i = 0; i < this.TMPBoundSource.length; i++) {
|
|
552
|
+
let item = this.TMPBoundSource[i];
|
|
553
|
+
item._rowClass = this.RowClassAssigner ? this.RowClassAssigner(item) : "";
|
|
554
|
+
item._rowClass += this.Hierarchy ? " est-row-lvl-" + item._level : "";
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
/** Genera le informzioni di paginazione per la vista globale dell'es-table */
|
|
559
|
+
setupPagingInformations() {
|
|
560
|
+
this.PagerOptions.ShowCount = !this.HidePagingCount;
|
|
561
|
+
if (this.arrayMode && this.UseArrayModePaging && !this.SearchView) {
|
|
562
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
563
|
+
this.PagerOptions.ShowPaging = !this.HidePaging && this.View.length > 10;
|
|
564
|
+
this.PagerOptions.View = this.View;
|
|
565
|
+
this.PagerOptions.UsesView = false;
|
|
566
|
+
}
|
|
567
|
+
else if (this.arrayMode && (!this.UseArrayModePaging || this.SearchView)) {
|
|
568
|
+
if (this.SearchView) {
|
|
569
|
+
this.PagerOptions.View = this.SearchView;
|
|
570
|
+
this.PagerOptions.PagerCount = this.SearchView.objectcount || 0;
|
|
571
|
+
}
|
|
572
|
+
else
|
|
573
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
574
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
|
|
575
|
+
}
|
|
576
|
+
else if (this.viewMode) {
|
|
577
|
+
let tmpView = this.MainGroupView || this.View;
|
|
578
|
+
let count = (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) || (tmpView === null || tmpView === void 0 ? void 0 : tmpView.objectcount);
|
|
579
|
+
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';
|
|
580
|
+
this.PagerOptions.PagerCount = count || 0;
|
|
581
|
+
this.PagerOptions.View = tmpView;
|
|
582
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (tmpView && count && count != -1);
|
|
583
|
+
this.PagerOptions.ShowPaging = !this.HidePaging;
|
|
584
|
+
}
|
|
585
|
+
else if (this.reportMode) {
|
|
586
|
+
let rvc = this.ReportValues.count;
|
|
587
|
+
this.PagerOptions.View = this.View;
|
|
588
|
+
this.PagerOptions.PagerCount = rvc && rvc == -1 ? this.ReportValues.rows.length : rvc && rvc > 0 ? this.ReportValues.count : 0;
|
|
589
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.objectcount && this.View.objectcount != -1);
|
|
590
|
+
this.PagerOptions.ShowPaging = !this.HidePaging && this.View.pagingavailable;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Metodo che gestisce l'endless scroll e in base a quanto la tabella è stata scrollata aggiunge degli elementi extra a **TMPBoundSource**
|
|
595
|
+
*
|
|
596
|
+
* @param {any} e Evento di scroll del browser
|
|
597
|
+
*/
|
|
598
|
+
onScroll(e) {
|
|
599
|
+
let tableViewHeight = e.target.offsetHeight;
|
|
600
|
+
let tableScrollHeight = e.target.scrollHeight;
|
|
601
|
+
let scrollLocation = e.target.scrollTop;
|
|
602
|
+
let buffer = 200;
|
|
603
|
+
let limit = tableScrollHeight - tableViewHeight - buffer;
|
|
604
|
+
if (scrollLocation > limit) {
|
|
605
|
+
let indexToAdd = Math.floor(this.TMPBoundSource.length / 100);
|
|
606
|
+
if (this.boundSubSources[indexToAdd] && this.addedSlices.indexOf(indexToAdd) == -1) {
|
|
607
|
+
// Devo ricordarmi di fare l'hash del nuovo pezzo
|
|
608
|
+
this.utilities_H.calculateHash(this.boundSubSources[indexToAdd]);
|
|
609
|
+
this.TMPBoundSource = this.TMPBoundSource.concat(this.boundSubSources[indexToAdd]);
|
|
610
|
+
this.addedSlices.push(indexToAdd);
|
|
611
|
+
setTimeout(() => { this.postBoundSourceCalculation(); });
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Metodo lanciato dopo che la sorgente dati è stata correttamente bindata, si occupa di ricalcolare tutto ciò che serve
|
|
617
|
+
* all'es-table per renderizzare i valori da mostrare
|
|
618
|
+
*/
|
|
619
|
+
postBoundSourceCalculation() {
|
|
620
|
+
// Resetto tutto tranne RowTDs e RowTHs per evitare flickering. RowTDs e RowTHs saranno modificate all'interno del prossimo ciclo di CD
|
|
621
|
+
this.RowContexts = [];
|
|
622
|
+
this.OrderDirectives = [];
|
|
623
|
+
this.lastSelectedItemID = null;
|
|
624
|
+
if (this.EsThsDirective && this.EsThsDirective.length > 0 && this.EsTdsDirective && this.EsTdsDirective.length > 0)
|
|
625
|
+
this.internalPostBoundSource();
|
|
626
|
+
else {
|
|
627
|
+
this.cdr.detectChanges();
|
|
628
|
+
setTimeout(() => { this.internalPostBoundSource(); });
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/** 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 */
|
|
632
|
+
internalPostBoundSource() {
|
|
633
|
+
let View = this.View;
|
|
634
|
+
let ths = this.EsThs && this.EsThs.length > 0 ? this.EsThs.toArray() : this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
|
|
635
|
+
let tds = this.EsTds && this.EsTds.length > 0 ? this.EsTds.toArray() : this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
|
|
636
|
+
// Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
|
|
637
|
+
this.dynamicMode_H.eventuallyReviewDynamicColumns();
|
|
638
|
+
this.bindDisplayToLoadedItemsOrGroups(View);
|
|
639
|
+
// Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
|
|
640
|
+
this.setupPagingInformations();
|
|
641
|
+
// Molte cose sono ovviamente disponibili solo in modalità View
|
|
642
|
+
if ((this.viewMode || this.arrayMode) && this.UseCustomCells) {
|
|
643
|
+
let view = this.viewMode ? View : null;
|
|
644
|
+
let itemsAndGroups = this.viewMode ? [...(view.items || []), ...(view.groups || [])] : View;
|
|
645
|
+
let si = this.viewMode ? view.selection : this.arraymodeSelection;
|
|
646
|
+
// N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
|
|
647
|
+
// ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
|
|
648
|
+
// Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
|
|
649
|
+
let hI = this.columnMetadata_H.evaluateHeadersGroupingInfos(ths);
|
|
650
|
+
if (this.arrayMode) { // In modalità array non ho un backend...
|
|
651
|
+
this.items_H.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
|
|
652
|
+
this.rowGrouping_H.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
|
|
653
|
+
}
|
|
654
|
+
this.columnMetadata_H.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
|
|
655
|
+
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)
|
|
656
|
+
this.columnMetadata_H.alignHeadersOrdering(hI.leafs, view); // Allineo gli ordinamenti agli header
|
|
657
|
+
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.
|
|
658
|
+
this.columnMetadata_H.refreshColumnsVisibility(hI.leafs, tds, view); // Lavoro sui TH ed eventualmente modifico la visibilità anche dei TD.
|
|
659
|
+
this.columnMetadata_H.evaluatePinnedColumnsWidth(); // Se sono presenti colonne pinnate valuta la dimensione del contenitore
|
|
660
|
+
this.columnMetadata_H.generateDefaultOrder(hI.leafs, view); // Genero le direttive di ordinamento, che siano default o derivanti dalla AppSearch
|
|
661
|
+
this.columnMetadata_H.evaluateHeaderGroups(hI); // Valuto i raggruppamenti degli header se presenti
|
|
662
|
+
// ************************************* Generazione binding per righe e colonne *************************************
|
|
663
|
+
this.evaluateRowThs(hI.leafs); // Raccolgo i TH
|
|
664
|
+
this.evaluateRowTds(hI.leafs, tds); // Raccolgo i TD in contesti separati, un contesto per ogni item o gruppo
|
|
665
|
+
// ************************************* Ultimi aggiustmaenti dei binding *************************************
|
|
666
|
+
this.columnMetadata_H.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
|
|
667
|
+
this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
|
|
668
|
+
this.selection_H.evaluateSelection(itemsAndGroups, si); // Riallineo le info di selezione degli elementi della View
|
|
669
|
+
if (this.ResearchNeeded) {
|
|
670
|
+
this.changed();
|
|
671
|
+
this.emitSearchRequest(false);
|
|
672
|
+
this.ResearchNeeded = false;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if ((this.viewMode || this.arrayMode) && !this.UseCustomCells) {
|
|
676
|
+
// Riallineo le info di selezione degli elementi della View
|
|
677
|
+
let items = this.viewMode ? View.items : View;
|
|
678
|
+
let si = this.viewMode ? View.selection : this.arraymodeSelection;
|
|
679
|
+
this.selection_H.evaluateSelection(items, si);
|
|
680
|
+
}
|
|
681
|
+
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
682
|
+
this.cdr.markForCheck();
|
|
683
|
+
this.FirstBind = false;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Effettua il binding degli oggetti pervenuti da questa chiamata con gli oggetti effettivamente da graficare
|
|
687
|
+
*
|
|
688
|
+
* @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**
|
|
689
|
+
*/
|
|
690
|
+
bindDisplayToLoadedItemsOrGroups(view) {
|
|
691
|
+
var _a, _b;
|
|
692
|
+
if (this.TMPBoundSource.length == 0) {
|
|
693
|
+
this.BaseItemsCount = 0;
|
|
694
|
+
this.boundSource = this.TMPBoundSource;
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
if (this.arrayMode || !this.UseCustomCells) {
|
|
698
|
+
this.boundSource = this.TMPBoundSource;
|
|
699
|
+
this.BaseItemsCount = (view === null || view === void 0 ? void 0 : view.objectcount) || view.length;
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
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;
|
|
703
|
+
if (groupingKeys == 0) {
|
|
704
|
+
this.boundSource = this.TMPBoundSource;
|
|
705
|
+
this.BaseItemsCount = view.objectcount;
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
this.rowGrouping_H.handleNewDataOnRowGrouping(view, groupingKeys);
|
|
709
|
+
}
|
|
710
|
+
/** Metodo richiamato solo quando **TMPRowTDs** e **TMPRowTHs** sono completamente generati ed aggiustati. Serve per collegarli alle variabili usate lato binding HTML */
|
|
711
|
+
MoveTemporaryVariablesToRealOnes() {
|
|
712
|
+
this.RowTDs = this.TMPRowTDs;
|
|
713
|
+
this.RowTHs = this.TMPRowTHs;
|
|
714
|
+
this.RowThGroups = this.TMPRowThGroups ? this.TMPRowThGroups.reverse() : null;
|
|
715
|
+
this.Columns.Visibile = this.RowTHs.filter(t => t.Visible).length;
|
|
716
|
+
this.Columns.VisibleUnpinned = this.RowTHs.filter(t => t.Visible && !t.Pinned).length;
|
|
717
|
+
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);
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Permette di selezionare o deselezionare in maniera arbitraria degli oggetti
|
|
721
|
+
*
|
|
722
|
+
* @param {any[]} items Oggetti da selezionare o deselezionare
|
|
723
|
+
* @param {boolean} select **true** per selezionarli, **false** per non toccarli
|
|
724
|
+
*/
|
|
725
|
+
setSelectionStatus(items, select) {
|
|
726
|
+
this.selection_H.handleItemsSelection(items, select);
|
|
727
|
+
this.cdr.markForCheck();
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Metodo che gestisce il cambio di Ordinamento di una colonna
|
|
731
|
+
*
|
|
732
|
+
* @param {string} id ID della colonna il cui oridnamento è cambiato
|
|
733
|
+
* @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
|
|
734
|
+
*/
|
|
735
|
+
thOrderChanged(id, order) {
|
|
736
|
+
if (!this.viewMode && !this.arrayMode) {
|
|
737
|
+
console.warn('Order changed on a table not in viewMode or Array mode. Operation not supported');
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
if (!this.OrderByColumn)
|
|
741
|
+
return;
|
|
742
|
+
this.columnMetadata_H.handleTHOrderChange(id, order);
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Metodo da chiamare ogni volta che si vuole dare evidenza all'esterno del bisogno di rieffettuare la ricerca
|
|
746
|
+
*
|
|
747
|
+
* @param {boolean} resetsPage Indica al listener che deve resettare il numero di pagina
|
|
748
|
+
* @param {AppSearch<any>} viewOverride Override della view da emettere per questa ricerca
|
|
749
|
+
*/
|
|
750
|
+
emitSearchRequest(resetsPage, viewOverride) {
|
|
751
|
+
if (this.viewMode && !viewOverride) {
|
|
752
|
+
this.View.internalsearchrequest = true;
|
|
753
|
+
this.changed();
|
|
754
|
+
}
|
|
755
|
+
if (viewOverride) {
|
|
756
|
+
if (resetsPage)
|
|
757
|
+
viewOverride.page = 1;
|
|
758
|
+
viewOverride.internalsearchrequest = true;
|
|
759
|
+
}
|
|
760
|
+
this.researchInProgress = true;
|
|
761
|
+
this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
|
|
765
|
+
*
|
|
766
|
+
* Vengono esclusi i TD "Interni" in quanto vengono generati dagli originali quindi includerli vorrebbe dire rieffettuare le operazioni due volte
|
|
767
|
+
*
|
|
768
|
+
* Costo: 2 scan EsThs, 1 scan EsTds
|
|
769
|
+
*
|
|
770
|
+
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
771
|
+
* @param {EsTd[] | EsTdDirective[]} tds Celle della tabella
|
|
772
|
+
*/
|
|
773
|
+
evaluateRowTds(ths, tds) {
|
|
774
|
+
if (tds.length == 0)
|
|
775
|
+
return;
|
|
776
|
+
let thsCache = {};
|
|
777
|
+
let columnsCache = {};
|
|
778
|
+
for (let coli = 0; coli < this.ColumnsList.length; coli++) {
|
|
779
|
+
let col = this.ColumnsList[coli];
|
|
780
|
+
columnsCache[col.id] = col;
|
|
781
|
+
}
|
|
782
|
+
for (let i = 0; i < ths.length; i++) {
|
|
783
|
+
let th = ths[i];
|
|
784
|
+
thsCache[this.utilities_H.isEsTh(th) ? th.ID : th.th] = th;
|
|
785
|
+
}
|
|
786
|
+
this.TMPRowTDs = {};
|
|
787
|
+
// Variabile d'appoggio per permettermi di inserire tutte le colonne "Fixed" davanti
|
|
788
|
+
let contextFixeds = {};
|
|
789
|
+
for (let i = 0; i < tds.length; i++) {
|
|
790
|
+
let td = tds[i];
|
|
791
|
+
if (this.utilities_H.isEsTd(td)) {
|
|
792
|
+
let th = thsCache[td.ID];
|
|
793
|
+
if (!!th)
|
|
794
|
+
th._referenced = true;
|
|
795
|
+
else
|
|
796
|
+
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.ID;
|
|
797
|
+
let isFixed = (this.utilities_H.isEsTh(th) && th.Fixed) || (!this.utilities_H.isEsTh(th) && (th.thFixed || th.thGroup));
|
|
798
|
+
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 };
|
|
799
|
+
let ctx = td.Context;
|
|
800
|
+
if (this.TMPRowTDs[ctx]) {
|
|
801
|
+
if (isFixed)
|
|
802
|
+
this.TMPRowTDs[ctx].splice(0 + (contextFixeds[ctx]++), 0, itemToAdd);
|
|
803
|
+
else
|
|
804
|
+
this.TMPRowTDs[ctx].push(itemToAdd);
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
this.RowContexts.push(ctx);
|
|
808
|
+
this.TMPRowTDs[ctx] = [itemToAdd];
|
|
809
|
+
contextFixeds[ctx] = isFixed ? 1 : 0;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
for (let i = 0; i < this.boundSource.length; i++) {
|
|
814
|
+
let item = this.boundSource[i];
|
|
815
|
+
let ctx = item._hash;
|
|
816
|
+
let key = td.td;
|
|
817
|
+
let th = thsCache[td.td];
|
|
818
|
+
if (!!th)
|
|
819
|
+
th._referenced = true;
|
|
820
|
+
else
|
|
821
|
+
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.td;
|
|
822
|
+
if (td.tdIf || (!this.utilities_H.isEsTh(th) && th.thGroup)) {
|
|
823
|
+
let thCasted = th;
|
|
824
|
+
let isFixed = (this.utilities_H.isEsTh(th) && th.Fixed) || (!this.utilities_H.isEsTh(th) && (th.thFixed || th.thGroup || th.thPinned));
|
|
825
|
+
let itemToAdd = item._item ?
|
|
826
|
+
{ 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 } :
|
|
827
|
+
{ 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) };
|
|
828
|
+
if (this.TMPRowTDs[ctx]) {
|
|
829
|
+
this.TMPRowTDs[ctx].push(itemToAdd);
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
this.RowContexts.push(ctx);
|
|
833
|
+
this.TMPRowTDs[ctx] = [itemToAdd];
|
|
834
|
+
contextFixeds[ctx] = isFixed ? 1 : 0;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
// 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
|
|
841
|
+
if (this.TMPBoundSource.length == 0)
|
|
842
|
+
return;
|
|
843
|
+
var errs = [];
|
|
844
|
+
for (let i = 0; i < ths.length; i++) {
|
|
845
|
+
let th = ths[i];
|
|
846
|
+
if (!th._referenced)
|
|
847
|
+
errs.push(this.utilities_H.isEsTh(th) ? th.ID : th.th);
|
|
848
|
+
}
|
|
849
|
+
if (errs.length > 0) {
|
|
850
|
+
var errIds = errs.join(', ');
|
|
851
|
+
throw "L'ID di uno o più EsTh non hanno alcun EsTd associato: " + errIds;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Partendo dagli **EsThs** bindati genera, all'interno del dizionario **TMPRowTHs** tutti i contesti dei vari oggetti.
|
|
856
|
+
*
|
|
857
|
+
* Vengono esclusi i TH "Interni" in quanto vengono generati dagli originali quindi includerli vorrebbe dire rieffettuare le operazioni due volte
|
|
858
|
+
*
|
|
859
|
+
* Costo: 1 scan EsThs
|
|
860
|
+
*
|
|
861
|
+
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
862
|
+
*/
|
|
863
|
+
evaluateRowThs(ths) {
|
|
864
|
+
if (ths.length == 0)
|
|
865
|
+
return;
|
|
866
|
+
let columnsListCache = {};
|
|
867
|
+
let castedView = this.View;
|
|
868
|
+
let groupingsUndefined = this.viewMode && (castedView && !castedView.groupings || castedView.groupings.length == 0);
|
|
869
|
+
for (let i = 0; i < this.ColumnsList.length; i++) {
|
|
870
|
+
let itm = this.ColumnsList[i];
|
|
871
|
+
columnsListCache[itm.id] = itm;
|
|
872
|
+
}
|
|
873
|
+
this.TMPRowTHs = [];
|
|
874
|
+
let fixed = 0;
|
|
875
|
+
for (let i = 0; i < ths.length; i++) {
|
|
876
|
+
let th = ths[i];
|
|
877
|
+
let toAdd;
|
|
878
|
+
if (this.utilities_H.isEsTh(th)) {
|
|
879
|
+
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 };
|
|
880
|
+
if (th.Fixed)
|
|
881
|
+
this.TMPRowTHs.splice(0 + (fixed++), 0, toAdd);
|
|
882
|
+
else
|
|
883
|
+
this.TMPRowTHs.push(toAdd);
|
|
884
|
+
}
|
|
885
|
+
else if (th.thIf || th.thGroup) {
|
|
886
|
+
let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
|
|
887
|
+
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 };
|
|
888
|
+
this.TMPRowTHs.push(toAdd);
|
|
889
|
+
// Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
|
|
890
|
+
// li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
|
|
891
|
+
if (groupingsUndefined && (th.thAggregation || th.thGroup)) {
|
|
892
|
+
let groupAggregations = this.rowGrouping_H.getGroupAggregations(th);
|
|
893
|
+
if (!castedView.groupings)
|
|
894
|
+
castedView.groupings = groupAggregations;
|
|
895
|
+
else
|
|
896
|
+
castedView.groupings.push(...groupAggregations);
|
|
897
|
+
this.ResearchNeeded = true;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Sposta la ricerca di una pagina in avanti (o indietro)
|
|
904
|
+
*
|
|
905
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
906
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
907
|
+
*/
|
|
908
|
+
addToPageGroup(page, pager) {
|
|
909
|
+
this.goToPageGroup(pager.view.page + page, pager);
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Sposta la ricerca alla pagina specificata
|
|
913
|
+
*
|
|
914
|
+
* @param {number} page Pagina a cui navigare
|
|
915
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
916
|
+
*/
|
|
917
|
+
goToPageGroup(page, pager) {
|
|
918
|
+
let appSearchElement = pager.view;
|
|
919
|
+
if (page === 0 || (page > appSearchElement.pages && appSearchElement.pages > 0))
|
|
920
|
+
return;
|
|
921
|
+
appSearchElement.page = page;
|
|
922
|
+
pager.buttons = this.utilities_H.getPagesArray(6, appSearchElement.page, appSearchElement.pages);
|
|
923
|
+
this.emitSearchRequest(false, appSearchElement);
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Gestisce i click sulla tabella solo per le righe a gruppo.
|
|
927
|
+
* O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
|
|
928
|
+
*
|
|
929
|
+
* @param {any} group Gruppo bindato su cui si è effettuato il click
|
|
930
|
+
*
|
|
931
|
+
* @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
|
|
932
|
+
*/
|
|
933
|
+
handleGroupClick(group) {
|
|
934
|
+
let casted = this.View;
|
|
935
|
+
let anyG = group;
|
|
936
|
+
anyG._expanded = !anyG._expanded;
|
|
937
|
+
// Sono in modalità raggruppamento virtuale da array: Espandere significa rendere visibili tutti gli oggetti relativi a questo gruppo, viceversa il contrarre
|
|
938
|
+
if (this.ArrayGrouping) {
|
|
939
|
+
let allRelatives = this.boundSource.filter(t => (t._group && ((anyG._expanded && t._parent == anyG._thisKey) || (!anyG._expanded && t._parent && t._parent.startsWith(anyG._thisKey)))) ||
|
|
940
|
+
(t._item && ((anyG._expanded && t._thisKey == anyG._thisKey) || (!anyG._expanded && t._thisKey.startsWith(anyG._thisKey)))));
|
|
941
|
+
allRelatives.forEach(t => { t._visible = anyG._expanded; if (t._group)
|
|
942
|
+
t._expanded = false; });
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
if (anyG._expanded) {
|
|
946
|
+
// Resetto ipp
|
|
947
|
+
casted.itemsperpageoverride = 15;
|
|
948
|
+
if (!casted.requestedgroups)
|
|
949
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
950
|
+
else {
|
|
951
|
+
let level = anyG._grouplevel;
|
|
952
|
+
// se il gruppo cliccato non ha un livello è il primo gruppo, quindi ordinamento unico
|
|
953
|
+
// altrimenti devo rimuovere tutti i filtri su livelli superiori al level cliccato e aggiungere il level cliccato
|
|
954
|
+
if (!level)
|
|
955
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
956
|
+
else {
|
|
957
|
+
casted.requestedgroups = [];
|
|
958
|
+
anyG._parentRoute.forEach((step) => {
|
|
959
|
+
casted.requestedgroups.push(new GroupFilter(step.column, step.value));
|
|
960
|
+
});
|
|
961
|
+
casted.requestedgroups.push(new GroupFilter(group.column, group.value));
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
this.changed();
|
|
965
|
+
this.emitSearchRequest(true);
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
968
|
+
let path = (anyG._parent || '') + group.value;
|
|
969
|
+
// Se ho chiuso un gruppo non mi serve rieffettuare ricerce, mi basta eliminare dagli oggetti bindati tutti gli elementi sottostanti a quel gruppo
|
|
970
|
+
this.boundSource = this.boundSource.filter(t => !t._parent || !t._parent.startsWith(path));
|
|
971
|
+
// devo però anche rimuovere eventuali cache relative
|
|
972
|
+
this.groupSearchRequestsCache = this.groupSearchRequestsCache.filter(t => t.path != path);
|
|
973
|
+
}
|
|
974
|
+
return true;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Gestisce la selezione globale degli oggetti, sia per pagina che a livello di **SelectAll**
|
|
978
|
+
*
|
|
979
|
+
* @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
|
|
980
|
+
*/
|
|
981
|
+
globalCheckChanged(forcedVal = null) {
|
|
982
|
+
// 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
|
|
983
|
+
let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
|
|
984
|
+
var itemSelection = this.selection_H.handleItemsSelection(items, forcedVal, this.globalCheck);
|
|
985
|
+
this.changed();
|
|
986
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
|
|
990
|
+
*
|
|
991
|
+
* @param {any} event Evento nativo HTML del click
|
|
992
|
+
* @param {any} item Oggetto bindato su cui si è effettuato il click
|
|
993
|
+
*
|
|
994
|
+
* @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
|
|
995
|
+
*/
|
|
996
|
+
handleClick(event, item) {
|
|
997
|
+
// Seleziono del testo ma non ho shift premuto -> ignoro la selezione
|
|
998
|
+
if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && !event.shiftKey)
|
|
999
|
+
return false;
|
|
1000
|
+
// Seleziono del testo e ho shift premuto -> annullo la selezione del testo
|
|
1001
|
+
if ((event.view.getSelection().type == 'Range' || event.view.getSelection().toString().length > 0) && event.shiftKey)
|
|
1002
|
+
this.utiExts.clearTextSelection();
|
|
1003
|
+
let selecteditems = [];
|
|
1004
|
+
if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
|
|
1005
|
+
let startSelecting = false;
|
|
1006
|
+
let items = this.boundSource.filter(t => !t._group && !t._sep);
|
|
1007
|
+
for (let i = 0; i < items.length; i++) {
|
|
1008
|
+
let t = items[i];
|
|
1009
|
+
if (startSelecting) {
|
|
1010
|
+
t._selected = true;
|
|
1011
|
+
selecteditems.push(t);
|
|
1012
|
+
}
|
|
1013
|
+
if ((t == item || t == this.lastSelected) && !startSelecting) {
|
|
1014
|
+
startSelecting = true;
|
|
1015
|
+
t._selected = true;
|
|
1016
|
+
selecteditems.push(t);
|
|
1017
|
+
}
|
|
1018
|
+
else if ((t == item || t == this.lastSelected) && startSelecting)
|
|
1019
|
+
startSelecting = false;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
else {
|
|
1023
|
+
item._selected = !item._selected;
|
|
1024
|
+
this.lastSelected = item;
|
|
1025
|
+
selecteditems.push(item);
|
|
1026
|
+
}
|
|
1027
|
+
var itemSelection = this.selection_H.handleItemsSelection(selecteditems);
|
|
1028
|
+
this.changed();
|
|
1029
|
+
this.onSelectionChanged.emit(itemSelection);
|
|
1030
|
+
return true;
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Sposta la ricerca di una pagina in avanti (o indeitro)
|
|
1034
|
+
*
|
|
1035
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1036
|
+
*/
|
|
1037
|
+
addToPage(page) {
|
|
1038
|
+
var _a;
|
|
1039
|
+
let view = this.MainGroupView ? this.MainGroupView : this.View;
|
|
1040
|
+
this.goToPage((((_a = (this.SearchView || view)) === null || _a === void 0 ? void 0 : _a.page) || 0) + page);
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Sposta la ricerca alla pagina specificata
|
|
1044
|
+
*
|
|
1045
|
+
* @param {number} page Pagina a cui navigare
|
|
1046
|
+
*/
|
|
1047
|
+
goToPage(page) {
|
|
1048
|
+
var _a;
|
|
1049
|
+
let view = this.MainGroupView ? this.MainGroupView : this.View;
|
|
1050
|
+
if (!view.page || !view.pages)
|
|
1051
|
+
return;
|
|
1052
|
+
let appSearchElement = this.SearchView || view;
|
|
1053
|
+
if (page === 0 || (page > appSearchElement.pages && appSearchElement.pages > 0))
|
|
1054
|
+
return;
|
|
1055
|
+
appSearchElement.page = page;
|
|
1056
|
+
this.arrayPulsanti = this.utilities_H.getPagesArray(6, appSearchElement.page, appSearchElement.pages, view.items.length || ((_a = view.groups) === null || _a === void 0 ? void 0 : _a.length) || 0, view.itemsperpageoverride);
|
|
1057
|
+
let hasGroupings = !!this.MainGroupView;
|
|
1058
|
+
this.emitSearchRequest(false, hasGroupings ? view : null);
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest**
|
|
1062
|
+
* per comunicare al componente che utilizza questa tabella che i dati sono da aggiornare
|
|
1063
|
+
*/
|
|
1064
|
+
onItemsPerPageChanged(newIpp) {
|
|
1065
|
+
this.PagerOptions.View.itemsperpageoverride = newIpp;
|
|
1066
|
+
this.changed();
|
|
1067
|
+
if (this.MainGroupView)
|
|
1068
|
+
this.emitSearchRequest(true, this.MainGroupView);
|
|
1069
|
+
else
|
|
1070
|
+
this.emitSearchRequest(true);
|
|
1071
|
+
}
|
|
1072
|
+
/** Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest** con la vista del separatore */
|
|
1073
|
+
onGroupItemsPerPageChanged(pager, newIpp) {
|
|
1074
|
+
pager.view.itemsperpageoverride = newIpp;
|
|
1075
|
+
this.emitSearchRequest(true, pager.view);
|
|
1076
|
+
}
|
|
1077
|
+
/** Metodo che gestisce la modifica del tempo specificato per l'aggiornamento automatico */
|
|
1078
|
+
autoUpdateChanged() {
|
|
1079
|
+
if (!/^[1-9]\d*$/.test(this.seconds))
|
|
1080
|
+
this.seconds = '10';
|
|
1081
|
+
let secondsInMs = parseInt(this.seconds, null) * 1000;
|
|
1082
|
+
if (this.autoUpdate)
|
|
1083
|
+
this.updateTimer = setInterval(() => { this.emitSearchRequest(false); }, secondsInMs);
|
|
1084
|
+
else
|
|
1085
|
+
clearInterval(this.updateTimer);
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Metodo chiamato dal click su una delle colonne generate dall'Input **DynamicOperations**
|
|
1089
|
+
*
|
|
1090
|
+
* @param {any} item L'oggetto su cui va effettuata l'operazione
|
|
1091
|
+
* @param {string} opid Codice identificativo dell'operazione da effettuarsi
|
|
1092
|
+
*/
|
|
1093
|
+
dynamicOperation(item, opid) {
|
|
1094
|
+
this.onDynamicOperation.emit({ id: opid, item: item });
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Ottiene il contenuto dell'EsTd da utilizzare per la colonna specificata
|
|
1098
|
+
*
|
|
1099
|
+
* @param {string} column Colonna per cui cercare la cella
|
|
1100
|
+
*
|
|
1101
|
+
* @returns {TemplateRef<any>} Template da usare per la colonna
|
|
1102
|
+
*/
|
|
1103
|
+
findEsTd(column) {
|
|
1104
|
+
var EsTd = this.EsTdsDirective.find((item) => item.td === column);
|
|
1105
|
+
return EsTd ? EsTd.Template : null;
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Equivalente del metodo **addToPage** riadattato per la modalità array
|
|
1109
|
+
*
|
|
1110
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1111
|
+
*/
|
|
1112
|
+
arrayAddToPage(page) {
|
|
1113
|
+
this.arrayGoToPage(this.arraymodePage + page);
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Equivalente del metodo **goToPage** riadattato per la modalità array
|
|
1117
|
+
*
|
|
1118
|
+
* @param {number} page Pagina a cui navigare
|
|
1119
|
+
*/
|
|
1120
|
+
arrayGoToPage(page) {
|
|
1121
|
+
if (page === 0 || page > this.arraymodePages)
|
|
1122
|
+
return;
|
|
1123
|
+
this.arraymodePage = page;
|
|
1124
|
+
// Riforzo il writevalue in modo che il codice passi dalla gestione come se fosse fatta ripartire una ricerca
|
|
1125
|
+
this.internalWriteValue();
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Gestore dei click sulle celle per le quali era impostata una azione custom da **CustomCellActionsOn**
|
|
1129
|
+
*
|
|
1130
|
+
* @param {string} name Nome della cella su cui si è fatto click
|
|
1131
|
+
* @param {any} model Modello relativo alla cella cliccata
|
|
1132
|
+
*
|
|
1133
|
+
* @returns {boolean} **true** se il click è stato fatto su una cella cliccabile, **false** altrimenti
|
|
1134
|
+
*/
|
|
1135
|
+
cellClicked(name, model) {
|
|
1136
|
+
if (this.UseCustomCellActions && this.CustomCellActionsOn.split('$').indexOf(name) != -1) {
|
|
1137
|
+
this.onCellClick.emit({ column: name, model: model });
|
|
1138
|
+
return true;
|
|
1139
|
+
}
|
|
1140
|
+
return false;
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Gestione dei click sulle opzioni del menù contestuale in alto a destra generato dall'Input **CornerMenuOptions**
|
|
1144
|
+
*
|
|
1145
|
+
* @param {string} cornerid Codice dell'operazione selezionata
|
|
1146
|
+
*/
|
|
1147
|
+
cornerActionClicked(cornerid) {
|
|
1148
|
+
this.onCornerAction.emit({ id: cornerid, estable: this });
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Impostazione modalità dell'EsTable
|
|
1152
|
+
*
|
|
1153
|
+
* @param {'array' | 'view' | 'report'} mode Modalità da impostare
|
|
1154
|
+
**/
|
|
1155
|
+
setMode(mode) {
|
|
1156
|
+
this.viewMode = mode == 'view';
|
|
1157
|
+
this.arrayMode = mode == 'array';
|
|
1158
|
+
this.reportMode = mode == 'report';
|
|
1159
|
+
if (this.reportMode) {
|
|
1160
|
+
// In modalità report ho di sicuro queste due
|
|
1161
|
+
this.XLSXExport = true;
|
|
1162
|
+
this.CSVExport = false;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Helper per effettuare chiamate interne di allineamento alla funzione **writeValue**,
|
|
1167
|
+
* impostando prima **internalWriteCall** in modo da non effettuare operazioni inutili
|
|
1168
|
+
*/
|
|
1169
|
+
internalWriteValue() {
|
|
1170
|
+
this.internalWriteCall = true;
|
|
1171
|
+
this.writeValue(this.View);
|
|
1172
|
+
this.internalWriteCall = false;
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Metodo eventualmente richiamabile anche dal componente esterno che permette di forzare un refresh della tabella
|
|
1176
|
+
*/
|
|
1177
|
+
forceRefresh() {
|
|
1178
|
+
// 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
|
|
1179
|
+
let arrayPage;
|
|
1180
|
+
let arrayIpp;
|
|
1181
|
+
if (this.arrayMode) {
|
|
1182
|
+
arrayPage = this.arraymodePage;
|
|
1183
|
+
arrayIpp = this.ArraymodeItemsPerPage;
|
|
1184
|
+
}
|
|
1185
|
+
this.writeValue(this.View);
|
|
1186
|
+
this.cdr.detectChanges();
|
|
1187
|
+
if (this.arrayMode) {
|
|
1188
|
+
this.ArraymodeItemsPerPage = arrayIpp;
|
|
1189
|
+
this.arrayGoToPage(arrayPage);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
EsTableComponent.decorators = [
|
|
1194
|
+
{ type: Component, args: [{
|
|
1195
|
+
selector: 'es-table',
|
|
1196
|
+
viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }],
|
|
1197
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1198
|
+
encapsulation: ViewEncapsulation.None,
|
|
1199
|
+
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>\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=\"headerGroupRef\">\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=\"secondaryHeaderGroupRef\">\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\">\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 *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-10]=\"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 && !HidePagingButtons && (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 m-t-min-3\">\r\n <div *ngIf=\"PagerOptions.ShowPaging && !HidePagingCount\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"items_H.refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [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;\">\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 [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\" [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-10' : ''}}\" *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-10' : ''}}\" *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-10' : ''}}\" *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-10' : ''}}\" *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-10' : ''}}\" *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>",
|
|
1200
|
+
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-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-10{right:10px!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-right-10{right:10px}.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:3px 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-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}"]
|
|
1201
|
+
},] }
|
|
1202
|
+
];
|
|
1203
|
+
EsTableComponent.ctorParameters = () => [
|
|
1204
|
+
{ type: NgControl, decorators: [{ type: Self }, { type: Optional }] },
|
|
1205
|
+
{ type: PreferencesService, decorators: [{ type: Optional }] },
|
|
1206
|
+
{ type: EsTableDefaultable, decorators: [{ type: Optional }, { type: Inject, args: [EST_DEFAULTS,] }] },
|
|
1207
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [EST_LOCALE,] }] },
|
|
1208
|
+
{ type: LocalizationService },
|
|
1209
|
+
{ type: ChangeDetectorRef },
|
|
1210
|
+
{ type: UtilitiesHandler },
|
|
1211
|
+
{ type: UtilityService },
|
|
1212
|
+
{ type: ExportService },
|
|
1213
|
+
{ type: DateService },
|
|
1214
|
+
{ type: MessageService }
|
|
1215
|
+
];
|
|
1216
|
+
EsTableComponent.propDecorators = {
|
|
1217
|
+
EsTdsDirective: [{ type: ContentChildren, args: [EsTdDirective,] }],
|
|
1218
|
+
EsThsDirective: [{ type: ContentChildren, args: [EsThDirective,] }],
|
|
1219
|
+
EsThs: [{ type: ContentChildren, args: [forwardRef(() => EsTh),] }],
|
|
1220
|
+
EsTds: [{ type: ContentChildren, args: [forwardRef(() => EsTd),] }],
|
|
1221
|
+
bodyRef: [{ type: ContentChild, args: ['body', { static: false },] }],
|
|
1222
|
+
headerRef: [{ type: ContentChild, args: ['header', { static: false },] }],
|
|
1223
|
+
headerGroupRef: [{ type: ContentChild, args: ['headerGroup', { static: false },] }],
|
|
1224
|
+
secondaryHeaderGroupRef: [{ type: ContentChild, args: ['secondaryHeaderGroup', { static: false },] }],
|
|
1225
|
+
CornerMenuOptions: [{ type: Input }],
|
|
1226
|
+
ColumnsResizable: [{ type: Input }],
|
|
1227
|
+
AutoUpdate: [{ type: Input }],
|
|
1228
|
+
UseCustomCellActions: [{ type: Input }],
|
|
1229
|
+
CustomCellActionsOn: [{ type: Input }],
|
|
1230
|
+
CellActionPropagates: [{ type: Input }],
|
|
1231
|
+
UseCustomCells: [{ type: Input }],
|
|
1232
|
+
MaxHeight: [{ type: Input }],
|
|
1233
|
+
ContainerClass: [{ type: Input }],
|
|
1234
|
+
XLSXExport: [{ type: Input }],
|
|
1235
|
+
CSVExport: [{ type: Input }],
|
|
1236
|
+
AllSearch: [{ type: Input }],
|
|
1237
|
+
HighCellDensity: [{ type: Input }],
|
|
1238
|
+
Selection: [{ type: Input }],
|
|
1239
|
+
ShowLoadingOnBootstrap: [{ type: Input }],
|
|
1240
|
+
Removal: [{ type: Input }],
|
|
1241
|
+
RemovalCondition: [{ type: Input }],
|
|
1242
|
+
Export: [{ type: Input }],
|
|
1243
|
+
ShiftClick: [{ type: Input }],
|
|
1244
|
+
HidePaging: [{ type: Input }],
|
|
1245
|
+
HidePagingCount: [{ type: Input }],
|
|
1246
|
+
HidePagingButtons: [{ type: Input }],
|
|
1247
|
+
ContextMenu: [{ type: Input }],
|
|
1248
|
+
ExportFileName: [{ type: Input }],
|
|
1249
|
+
TableClass: [{ type: Input }],
|
|
1250
|
+
ExportFunction: [{ type: Input }],
|
|
1251
|
+
HasHeaderGroup: [{ type: Input }],
|
|
1252
|
+
HasSecondaryHeaderGroup: [{ type: Input }],
|
|
1253
|
+
SliceSize: [{ type: Input }],
|
|
1254
|
+
EndlessScroll: [{ type: Input }],
|
|
1255
|
+
EndlessScrollOnlyForAll: [{ type: Input }],
|
|
1256
|
+
HeaderHidden: [{ type: Input }],
|
|
1257
|
+
BodyHidden: [{ type: Input }],
|
|
1258
|
+
SelectionDisabled: [{ type: Input }],
|
|
1259
|
+
SingleSelection: [{ type: Input }],
|
|
1260
|
+
RowClassAssigner: [{ type: Input }],
|
|
1261
|
+
OrderByColumn: [{ type: Input }],
|
|
1262
|
+
MultipleOrderingDirectives: [{ type: Input }],
|
|
1263
|
+
HiddenColumns: [{ type: Input }],
|
|
1264
|
+
ColumnsOrdering: [{ type: Input }],
|
|
1265
|
+
SearchView: [{ type: Input }],
|
|
1266
|
+
SelectAll: [{ type: Input }],
|
|
1267
|
+
UseArrayModePaging: [{ type: Input }],
|
|
1268
|
+
DynamicRowColumnsDefinition: [{ type: Input }],
|
|
1269
|
+
DynamicOperations: [{ type: Input }],
|
|
1270
|
+
Hierarchy: [{ type: Input }],
|
|
1271
|
+
ParentKey: [{ type: Input }],
|
|
1272
|
+
OwnKey: [{ type: Input }],
|
|
1273
|
+
StartsExpanded: [{ type: Input }],
|
|
1274
|
+
SavePreferences: [{ type: Input }],
|
|
1275
|
+
PagingStyle: [{ type: Input }],
|
|
1276
|
+
RowGroupingPagingStyle: [{ type: Input }],
|
|
1277
|
+
SecondarySource: [{ type: Input }],
|
|
1278
|
+
TertiarySource: [{ type: Input }],
|
|
1279
|
+
UseSelectionCache: [{ type: Input }],
|
|
1280
|
+
ShowItemGroupsColumns: [{ type: Input }],
|
|
1281
|
+
onOrderChanged: [{ type: Output }],
|
|
1282
|
+
onSearchRequest: [{ type: Output }],
|
|
1283
|
+
onSelectionChanged: [{ type: Output }],
|
|
1284
|
+
onRemoval: [{ type: Output }],
|
|
1285
|
+
onAbortRemoval: [{ type: Output }],
|
|
1286
|
+
onCellClick: [{ type: Output }],
|
|
1287
|
+
onCornerAction: [{ type: Output }],
|
|
1288
|
+
onDynamicOperation: [{ type: Output }],
|
|
1289
|
+
exportDownloader: [{ type: ViewChild, args: ['exportDownloader', { static: false },] }],
|
|
1290
|
+
tableEmptyMenu: [{ type: ViewChild, args: ['emptyMenu', { static: true },] }],
|
|
1291
|
+
ArraymodeItemsPerPage: [{ type: Input }]
|
|
1292
|
+
};
|
|
1293
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNfdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9jb21wb25lbnRzL2VzLXRhYmxlL2VzX3RhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsVUFBVTtBQUNWLE9BQU8sRUFDSCxTQUFTLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBYSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxLQUFLLEVBQ3BHLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUE0QixTQUFTLEVBQWMsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBZSxNQUFNLEVBQzlJLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakUsaUJBQWlCO0FBQ2pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUszRCxVQUFVO0FBQ1YsT0FBTyxFQUNILFNBQVMsRUFBMkQsZ0JBQWdCLEVBRXZGLE1BQU0sY0FBYyxDQUFDO0FBRXRCLDhCQUE4QjtBQUM5QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFB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dkksSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUNuQixFQUFFLFVBQVUsRUFBUSxRQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBUSxRQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDOzRCQUNuVyxFQUFFLFVBQVUsRUFBUSxRQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBUSxRQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsWUFBWSxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBUSxJQUFJLEVBQUUs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SzttQ0FPTCxLQUFLOzZCQWFMLEtBQUs7d0JBRUwsS0FBSzs2QkFFTCxLQUFLO3lCQUVMLEtBQUs7d0JBRUwsS0FBSzt3QkFFTCxLQUFLOzhCQUVMLEtBQUs7d0JBRUwsS0FBSztxQ0FFTCxLQUFLO3NCQUVMLEtBQUs7K0JBT0wsS0FBSztxQkFFTCxLQUFLO3lCQUVMLEtBQUs7eUJBRUwsS0FBSzs4QkFFTCxLQUFLO2dDQUVMLEtBQUs7MEJBRUwsS0FBSzs2QkFFTCxLQUFLO3lCQUVMLEtBQUs7NkJBT0wsS0FBSzs2QkFFTCxLQUFLO3NDQUVMLEtBQUs7d0JBRUwsS0FBSzs0QkFFTCxLQUFLO3NDQUVMLEtBQUs7MkJBRUwsS0FBSzt5QkFFTCxLQUFLO2dDQU1MLEtBQUs7OEJBTUwsS0FBSzsrQkFFTCxLQUFLOzRCQUVMLEtBQUs7eUNBRUwsS0FBSzs0QkFFTCxLQUFLOzhCQUVMLEtBQUs7eUJBRUwsS0FBSzt3QkFFTCxLQUFLO2lDQUVMLEtBQUs7MENBRUwsS0FBSztnQ0FFTCxLQUFLO3dCQUVMLEtBQUs7d0JBRUwsS0FBSztxQkFFTCxLQUFLOzZCQUVMLEtBQUs7OEJBRUwsS0FBSzswQkFHTCxLQUFLO3FDQUVMLEtBQUs7OEJBT0wsS0FBSzs2QkFPTCxLQUFLO2dDQUVMLEtBQUs7b0NBRUwsS0FBSzs2QkFFTCxNQUFNOzhCQVdOLE1BQU07aUNBRU4sTUFBTTt3QkFFTixNQUFNOzZCQUVOLE1BQU07MEJBTU4sTUFBTTs2QkFFTixNQUFNO2lDQUVOLE1BQU07K0JBT04sU0FBUyxTQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTs2QkFFL0MsU0FBUyxTQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0NBVXZDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBbmd1bGFyXHJcbmltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsIGZvcndhcmRSZWYsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIElucHV0LFxyXG4gICAgRXZlbnRFbWl0dGVyLCBPdXRwdXQsIENvbnRlbnRDaGlsZCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIFZpZXdFbmNhcHN1bGF0aW9uLCBPcHRpb25hbCwgU2VsZiwgVGVtcGxhdGVSZWYsIEluamVjdFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTmdDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuLy8gQ29uZmlndXJhemlvbmlcclxuaW1wb3J0IHsgVXRpbGl0eVNlcnZpY2UsIEV4cG9ydFNlcnZpY2UsIE1lc3NhZ2VTZXJ2aWNlLCBEYXRlU2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9leHRlbnNpb25zJztcclxuaW1wb3J0IHsgTG9jYWxpemF0aW9uU2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9sb2NhbGl6YXRpb25zJztcclxuaW1wb3J0IHsgUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnQGVzZmFlbnphL3ByZWZlcmVuY2VzJztcclxuXHJcbi8vIFBsdWdpbnNcclxuaW1wb3J0IHsgQ29udGV4dE1lbnVDb21wb25lbnQgfSBmcm9tICdAZXNmYWVuemEvbmd4LWNvbnRleHRtZW51JztcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHtcclxuICAgIEFwcFNlYXJjaCwgQXBwT3JkZXJpbmcsIEVzVGFibGVDb2x1bW5zRGVmaW5pdGlvbiwgQ29ybmVyTWVudU9wdGlvbiwgUmVwb3J0RGVmaW5pdGlvbiwgUmVwb3J0UmVzdWx0LFxyXG4gICAgRXNUYWJsZU9wZXJhdGlvbkRlZmluaXRpb24sIEVzVGFibGVDb2x1bW4sIEdyb3VwUGFnZXIsIEdyb3VwUm91dGVGcmFnbWVudCwgVGhFbGVtZW50XHJcbn0gZnJvbSAnLi4vLi4vZG9tYWluJztcclxuXHJcbi8vIENvbXBvbmVudGkgZSBMb2NhbGl6emF6aW9uZVxyXG5pbXBvcnQgeyBFc1RkIH0gZnJvbSAnLi4vZXMtdGQvZXNfdGQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRXNUaCB9IGZyb20gJy4uL2VzLXRoL2VzX3RoLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2VzX3RkLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEVzVGhEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2VzX3RoLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEVzVGFibGVMb2MgfSBmcm9tICcuL2VzX3RhYmxlLmNvbXBvbmVudC5sb2MnO1xyXG5pbXBvcnQgeyBJdGVtc1NlbGVjdGlvbiB9IGZyb20gJy4uLy4uL2RvbWFpbi9leHRlcm5hbHMvY2xhc3Nlcy9hcHBzZWFyY2gvSXRlbXNTZWxlY3Rpb24nO1xyXG5pbXBvcnQgeyBHcm91cE9yQWdncmVnYXRpb24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9jbGFzc2VzL2FwcHNlYXJjaC9Hcm91cE9yQWdncmVnYXRpb25cIjtcclxuaW1wb3J0IHsgR3JvdXBGaWx0ZXIgfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9jbGFzc2VzL2FwcHNlYXJjaC9Hcm91cEZpbHRlclwiO1xyXG5pbXBvcnQgeyBHcm91cCB9IGZyb20gXCIuLi8uLi9kb21haW4vZXh0ZXJuYWxzL2NsYXNzZXMvYXBwc2VhcmNoL0dyb3VwXCI7XHJcbmltcG9ydCB7IEVzVGFibGVEZWZhdWx0YWJsZSB9IGZyb20gJy4uLy4uL2RvbWFpbi9jb25maWd1cmF0aW9uL0VzVGFibGVEZWZhdWx0YWJsZSc7XHJcblxyXG5pbXBvcnQgeyBFU1RfREVGQVVMVFMsIEVTVF9MT0NBTEUgfSBmcm9tICcuLi8uLi90b2tlbnMnO1xyXG5cclxuaW1wb3J0IHsgRXhwb3J0SGFuZGxlciwgQ29sdW1uTWV0YWRhdGFIYW5kbGVyLCBEeW5hbWljTW9kZUhhbmRsZXIsIEhpZXJhcmNoeU1vZGVIYW5kbGVyLCBJdGVtc0hhbmRsZXIsIFJlcG9ydE1vZGVIYW5kbGVyLCBSb3dHcm91cGluZ0hhbmRsZXIsIFNlbGVjdGlvbkhhbmRsZXIsIFV0aWxpdGllc0hhbmRsZXIgfSBmcm9tICcuLi8uLi9jb3JlL2hhbmRsZXJzJztcclxuXHJcbi8qKiBDb21wb25lbnRlIGNoZSBwZXJtZXR0ZSBkaSByYXBwcmVzZW50YXJlIHVuYSBncmlnbGlhIGRpIHZhbG9yaSAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnZXMtdGFibGUnLFxyXG4gICAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogTG9jYWxpemF0aW9uU2VydmljZSwgdXNlQ2xhc3M6IEVzVGFibGVMb2MgfV0sXHJcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9lc190YWJsZS5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2VzX3RhYmxlLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRXNUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xyXG5cclxuICAgIGV4cG9ydF9IOiBFeHBvcnRIYW5kbGVyO1xyXG4gICAgY29sdW1uTWV0YWRhdGFfSDogQ29sdW1uTWV0YWRhdGFIYW5kbGVyO1xyXG4gICAgZHluYW1pY01vZGVfSDogRHluYW1pY01vZGVIYW5kbGVyO1xyXG4gICAgaGllcmFyY2h5TW9kZV9IOiBIaWVyYXJjaHlNb2RlSGFuZGxlcjtcclxuICAgIGl0ZW1zX0g6IEl0ZW1zSGFuZGxlcjtcclxuICAgIHJlcG9ydE1vZGVfSDogUmVwb3J0TW9kZUhhbmRsZXI7XHJcbiAgICByb3dHcm91cGluZ19IOiBSb3dHcm91cGluZ0hhbmRsZXJcclxuICAgIHNlbGVjdGlvbl9IOiBTZWxlY3Rpb25IYW5kbGVyO1xyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBAU2VsZigpIEBPcHRpb25hbCgpIHB1YmxpYyBuZ0NvbnRyb2w6IE5nQ29udHJvbCwgXHJcbiAgICAgICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBwcmVmU2VydmljZTogUHJlZmVyZW5jZXNTZXJ2aWNlLCBcclxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEVTVF9ERUZBVUxUUykgcHJpdmF0ZSBkZWFmdWx0czogRXNUYWJsZURlZmF1bHRhYmxlLCBcclxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEVTVF9MT0NBTEUpIHB1YmxpYyBsb2NhbGU6IHN0cmluZywgXHJcbiAgICAgICAgcHVibGljIGxjOiBMb2NhbGl6YXRpb25TZXJ2aWNlLFxyXG4gICAgICAgIHB1YmxpYyBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBcclxuICAgICAgICBwcml2YXRlIHV0aWxpdGllc19IOiBVdGlsaXRpZXNIYW5kbGVyLCBcclxuICAgICAgICBwcml2YXRlIHV0aUV4dHM6IFV0aWxpdHlTZXJ2aWNlLCBcclxuICAgICAgICBwcml2YXRlIGV4cEV4dHM6IEV4cG9ydFNlcnZpY2UsIFxyXG4gICAgICAgIHByaXZhdGUgZGF0ZUV4dHM6IERhdGVTZXJ2aWNlLCBcclxuICAgICAgICBwcml2YXRlIG1zZ0V4dHM6IE1lc3NhZ2VTZXJ2aWNlKSB7XHJcblxyXG4gICAgICAgIHRoaXMuZXhwb3J0X0ggPSBuZXcgRXhwb3J0SGFuZGxlcih0aGlzLCB0aGlzLmV4cEV4dHMsIHRoaXMubXNnRXh0cyk7XHJcbiAgICAgICAgdGhpcy5yb3dHcm91cGluZ19IID0gbmV3IFJvd0dyb3VwaW5nSGFuZGxlcih0aGlzLCB0aGlzLnV0aWxpdGllc19ILCB0aGlzLmRhdGVFeHRzKTtcclxuICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0ggPSBuZXcgQ29sdW1uTWV0YWRhdGFIYW5kbGVyKHRoaXMsIHRoaXMudXRpbGl0aWVzX0gsIHRoaXMudXRpRXh0cywgdGhpcy5wcmVmU2VydmljZSwgdGhpcy5yb3dHcm91cGluZ19IKTtcclxuICAgICAgICB0aGlzLmR5bmFtaWNNb2RlX0ggPSBuZXcgRHluYW1pY01vZGVIYW5kbGVyKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TW9kZV9IID0gbmV3IEhpZXJhcmNoeU1vZGVIYW5kbGVyKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuaXRlbXNfSCA9IG5ldyBJdGVtc0hhbmRsZXIodGhpcywgdGhpcy51dGlsaXRpZXNfSCk7XHJcbiAgICAgICAgdGhpcy5yZXBvcnRNb2RlX0ggPSBuZXcgUmVwb3J0TW9kZUhhbmRsZXIodGhpcywgdGhpcy51dGlsaXRpZXNfSCk7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25fSCA9IG5ldyBTZWxlY3Rpb25IYW5kbGVyKHRoaXMsIHRoaXMucm93R3JvdXBpbmdfSCk7XHJcblxyXG4gICAgICAgIGlmIChuZ0NvbnRyb2wpXHJcbiAgICAgICAgICAgIG5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcclxuXHJcbiAgICAgICAgLy8gQXNzZWduYXppb25lIHBlciB0dXR0aSBnbGkgSW5wdXQgZGkgZGVmYXVsdFxyXG4gICAgICAgIHRoaXMuQ29sdW1uc1Jlc2l6YWJsZSA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5Db2x1bW5zUmVzaXphYmxlLCB0aGlzLmRlYWZ1bHRzPy5Db2x1bW5zUmVzaXphYmxlKTtcclxuICAgICAgICB0aGlzLkF1dG9VcGRhdGUgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuQXV0b1VwZGF0ZSwgdGhpcy5kZWFmdWx0cz8uQXV0b1VwZGF0ZSk7XHJcbiAgICAgICAgdGhpcy5BbGxTZWFyY2ggPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuQWxsU2VhcmNoLCB0aGlzLmRlYWZ1bHRzPy5BbGxTZWFyY2gsIHRydWUpO1xyXG4gICAgICAgIHRoaXMuRXhwb3J0ID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkV4cG9ydCwgdGhpcy5kZWFmdWx0cz8uRXhwb3J0KTtcclxuICAgICAgICB0aGlzLkhpZGVQYWdpbmcgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuSGlkZVBhZ2luZywgdGhpcy5kZWFmdWx0cz8uSGlkZVBhZ2luZywgZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuSGlkZVBhZ2luZ0NvdW50ID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkhpZGVQYWdpbmdDb3VudCwgdGhpcy5kZWFmdWx0cz8uSGlkZVBhZ2luZ0NvdW50KTtcclxuICAgICAgICB0aGlzLkhpZGVQYWdpbmdCdXR0b25zID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLkhpZGVQYWdpbmdCdXR0b25zLCB0aGlzLmRlYWZ1bHRzPy5IaWRlUGFnaW5nQnV0dG9ucyk7XHJcbiAgICAgICAgdGhpcy5Db250YWluZXJDbGFzcyA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5Db250YWluZXJDbGFzcywgdGhpcy5kZWFmdWx0cz8uQ29udGFpbmVyQ2xhc3MsICcnKTtcclxuICAgICAgICB0aGlzLlRhYmxlQ2xhc3MgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuVGFibGVDbGFzcywgdGhpcy5kZWFmdWx0cz8uVGFibGVDbGFzcywgJ3RhYmxlIHRhYmxlLXN0cmlwZWQgdGFibGUtaG92ZXIgdGFibGUtc20nKTtcclxuICAgICAgICB0aGlzLlNlbGVjdGlvbiA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5TZWxlY3Rpb24sIHRoaXMuZGVhZnVsdHM/LlNlbGVjdGlvbik7XHJcbiAgICAgICAgdGhpcy5TYXZlUHJlZmVyZW5jZXMgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuU2F2ZVByZWZlcmVuY2VzLCB0aGlzLmRlYWZ1bHRzPy5TYXZlUHJlZmVyZW5jZXMpO1xyXG4gICAgICAgIHRoaXMuUGFnaW5nU3R5bGUgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuUGFnaW5nU3R5bGUsIHRoaXMuZGVhZnVsdHM/LlBhZ2luZ1N0eWxlLCAnYm90dG9tJyk7XHJcbiAgICAgICAgdGhpcy5Sb3dHcm91cGluZ1BhZ2luZ1N0eWxlID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLlJvd0dyb3VwaW5nUGFnaW5nU3R5bGUsIHRoaXMuZGVhZnVsdHM/LlJvd0dyb3VwaW5nUGFnaW5nU3R5bGUsICdsZWZ0Jyk7XHJcbiAgICAgICAgdGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSA9IHRoaXMudXRpbGl0aWVzX0guSW5wdXRPckRlZmF1bHQodGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSwgdGhpcy5kZWFmdWx0cz8uVXNlU2VsZWN0aW9uQ2FjaGUsIHRydWUpO1xyXG4gICAgICAgIHRoaXMuU2hvd0l0ZW1Hcm91cHNDb2x1bW5zID0gdGhpcy51dGlsaXRpZXNfSC5JbnB1dE9yRGVmYXVsdCh0aGlzLlNob3dJdGVtR3JvdXBzQ29sdW1ucywgdGhpcy5kZWFmdWx0cz8uU2hvd0l0ZW1Hcm91cHNDb2x1bW5zLCBmYWxzZSk7XHJcbiAgICAgICAgdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UgPSB0aGlzLnV0aWxpdGllc19ILklucHV0T3JEZWZhdWx0KHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlLCB0aGlzLmRlYWZ1bHRzPy5BcnJheW1vZGVJdGVtc1BlclBhZ2UsIDE1KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogVmlldyBmaW5hbGUgc3UgY3VpIGJpbmRhcnNpIGxhdG8gRnJvbnRlbmQsIGlsIHRpcG8gcHXDsiBlc3NlcmUgSUFwcFNlYXJjaDxhbnk+IChwZXIgbGEgKip2aWV3TW9kZSoqKSwgYW55W10gKHBlciBsJyoqYXJyYXlNb2RlKiopIGUgUmVwb3J0RGVmaW5pdGlvbiBwZXIgbGEgKipyZXBvcnRNb2RlKiogKi9cclxuICAgIHB1YmxpYyBWaWV3OiBhbnkgPSBudWxsO1xyXG4gICAgLyoqIE1vZGVsbG8gZGEgY3VpIGwnZXMtdGFibGUgbW9zdHJhIGkgcHVsc2FudGkgZGkgcGFnaW5hemlvbmUgaW4gYmFzc28gYSBkZXN0cmEgKi9cclxuICAgIHB1YmxpYyBhcnJheVB1bHNhbnRpOiBhbnk7XHJcbiAgICAvKiogSW5kaWNhIHNlIGwnZXMtdGFibGUgZGV2ZSBtb3N0cmFyZSBpbCBjaGVjayBnbG9iYWxlIG5lbGwnaGVhZGVyIHBlciBmYXJlIGlsIFwic2VsZXppb25hIHR1dHRvXCIgKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDaGVjayA9IGZhbHNlO1xyXG4gICAgLyoqIFRpZW5lIGRhIGNvbnRvIGwndWx0aW1vIGVsZW1lbnRvIHNlbGV6aW9uYXRvIGluIG1vZG8gZGEgcG90ZXIgZWZmZXR0dWFyZSBpbCBTSElGVCtDTElDSyAqL1xyXG4gICAgcHJpdmF0ZSBsYXN0U2VsZWN0ZWQ6IGFueSA9IG51bGw7XHJcbiAgICAvKiogQ29udGVnZ2lvIGludGVybm8gcGVyIGlsIG51bWVybyBkaSBlbGVtZW50aSBzZWxlemlvbmF0aSAqL1xyXG4gICAgcHVibGljIHNlbGVjdGVkT2JqZWN0cyA9IDA7XHJcbiAgICAvKiogSW5kaWNhIHNlIMOoIHBvc3NpYmlsZSBlZmZldHR1YXJlIHVuYSBzZWxlemlvbmUgbWFzc2l2YSAqL1xyXG4gICAgcHVibGljIGNhblNlbGVjdEFsbCA9IGZhbHNlO1xyXG4gICAgLyoqIEluZGljYSBzZSBpbCBjb21wb25lbnRlIHN0YSBnZXN0ZW5kbyB1biBJQXBwU2VhcmNoPGFueT4gKi9cclxuICAgIHB1YmxpYyB2aWV3TW9kZSA9IGZhbHNlO1xyXG4gICAgLyoqIEluZGljYSBzZSBpbCBjb21wb25lbnRlIHN0YSBnZXN0ZW5kbyB1biBhbnlbXSAqL1xyXG4gICAgcHVibGljIGFycmF5TW9kZSA9IGZhbHNlO1xyXG4gICAgLyoqIEluZGljYSBzZSBpbCBjb21wb25lbnRlIHN0YSBnZXN0ZW5kbyB1biBSZXBvcnREZWZpbml0aW9uICovXHJcbiAgICBwdWJsaWMgcmVwb3J0TW9kZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udGVuaXRvcmUgZGVnbGkgZWxlbWVudGkgZGEgbGlzdGFyZSBsYXRvIGludGVyZmFjY2lhIGRvcG8gdHV0dGUgbGUgZWxhYm9yYXppb25pIGRlbCBjYXNvLFxyXG4gICAgICogZ2VuZXJhbG1lbnRlIG5vbiBzb25vIGFsdHJvIGNoZSB0dXR0aSBnbGkgb2dnZXR0aSBkYSBwcmVzZW50YXJlIGNvbiBpbiBwacO5IGwnaGFzaCBjYWxjb2xhdG8gcGVyIGlkZW50aWZpY2FyZSAxIG9nZ2V0dG8gY29uIGxhIHByb3ByaWEgcmlnYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYm91bmRTb3VyY2U6IGFueVtdID0gW107XHJcbiAgICAvKiogU3Rlc3NhIGNvc2EgZGVsbGEgKipib3VuZFNvdXJjZSoqLCB1dGlsaXp6YXRhIGNvbWUgYXBwb2dnaW8gdGVtcG9yYW5lbyBpbnRlcm5vICovXHJcbiAgICBwdWJsaWMgVE1QQm91bmRTb3VyY2U6IGFueVtdID0gW107XHJcbiAgICAvKiogXCJGZXR0YVwiIGRpIG9nZ2V0dGkgdXRpbGl6emF0YSBuZWxsJ2VuZGxlc3Mgc2Nyb2xsLCBvZ25pIGVsZW1lbnRvIGRpIHF1ZXN0byBhcnJheSDDqCB1biBibG9jY2hldHRvIGRpIDEwMCBlbGVtZW50aSAqL1xyXG4gICAgcHVibGljIGJvdW5kU3ViU291cmNlczogYW55W10gPSBbXTtcclxuICAgIC8qKiBRdWVzdGEgZnVuZ2UgZGEgaW5kaWNhdG9yZSBwZXIgZ2xpIHNsaWNlIGluc2VyaXRpLCBsYSBsdW5naGV6emEgZG92cmViYmUgZXNzZXJlIGNvcnJpc3BvbmRlbnRlIGEgKipib3VuZFN1YlNvdXJjZXMqKiAqL1xyXG4gICAgcHVibGljIGFkZGVkU2xpY2VzOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgLyoqIFZhcmlhYmlsZSBjaGUgaWRlbnRpZmljYSBpbCB2YWxvcmUgZGVsIFwic2VsZXppb25hIFR1dHRvXCIgbmVsbGEgcGFnaW5hemlvbmUgKi9cclxuICAgIHB1YmxpYyBkZWZhdWx0QWxsUGFnZU92ZXJyaWRlID0gOTk5OTk5O1xyXG4gICAgLyoqIEluZGljYSBzZSB1dGlsaXp6YXJlIGlsIHNpc3RlbWEgZGkgRW5kbGVzcyBTY3JvbGwgKi9cclxuICAgIHB1YmxpYyBVc2VFbmRsZXNzc2Nyb2xsOiBib29sZWFuO1xyXG4gICAgLyoqIFZhbG9yaSBkZWxsJ2V2ZW50dWFsZSByZXBvcnQgaW4gdmlzdWFsaXp6YXppb25lICovXHJcbiAgICBwdWJsaWMgUmVwb3J0VmFsdWVzOiBSZXBvcnRSZXN1bHQ7XHJcbiAgICAvKiogU2VydmUgcGVyIHRlbmVyZSBpbiBtZW1vcmlhIGlsIGNvbnRlZ2dpbyBwcmVjZWRlbnRlIGUgcmVjdXBlcmFybG8gaW4gY2FzbyBkaXZlbnRpIC0yICh2ZXJpZmljYXJlIGNvbiBBbGUgcGVyY2jDqSBsYSBsb2dpY2EgZGVsIC0yKSAqL1xyXG4gICAgcHVibGljIHByZXZpb3VzQ291bnQ6IG51bWJlcjtcclxuICAgIC8qKiBJbmRpY2Egc2UgdXRpbGl6emFyZSBpbCBzaXN0ZW1hIGRpIGF1dG91cGRhdGUsIGNpb8OoIHVuIHRyaWdnZXIgdGltZS1penphdG8gaW4gYWx0byBhIGRlc3RyYSBkZWxsYSB0YWJlbGxhIGNoZSByaXBldGUgbGUgcmljZXJjaGUgb2duaSBYICoqc2Vjb25kcyoqICovXHJcbiAgICBwdWJsaWMgYXV0b1VwZGF0ZSA9IGZhbHNlO1xyXG4gICAgLyoqIE51bWVybyBkaSBzZWNvbmRpIGRhIGZhcmUgdHJhc2NvcnJlcmUgZnJhIHVuYSByaWNlcmNhIGUgbCdhbHRyYSAqL1xyXG4gICAgcHVibGljIHNlY29uZHMgPSAnMTAnO1xyXG4gICAgLyoqIFJpZmVyaW1lbnRvIGFsbCdJbnRlcnZhbCBjaGUgdmllbmUgZ2VuZXJhdG8gc2UgKiphdXRvVXBkYXRlKiogw6ggaW1wb3N0YXRhIGEgdHJ1ZSBpbiBtb2RvIGRhIHBvdGVybG8gcmlwdWxpcmUgKi9cclxuICAgIHB1YmxpYyB1cGRhdGVUaW1lcjogYW55O1xyXG4gICAgLyoqIEltcG9zdGF0YSBhIHRydWUgb2duaSB2b2x0YSBjaGUgdmllbmUgYXZ2aWF0YSB1bmEgcmljZXJjYSwgZSBhIGZhbHNlIG9nbmkgdm9sdGEgY2hlIHVuIG51b3ZvIHZhbG9yZSB2aWVuZSByaWNldnV0byAqL1xyXG4gICAgcHVibGljIHJlc2VhcmNoSW5Qcm9ncmVzczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgLyoqIE1vZGVsbG8gcmFwcHJlc2VudGFudGUgdW4gc2luZ29sbyB0ZCBkZWxsYSB0YWJlbGxhLCBnZW5lcmF0byBpbiBiYXNlIGFsbGUgY29uZmlndXJhemlvbmkgZSBhZ2xpIG9nZ2V0dGkgcmljZXZ1dGkgKi9cclxuICAgIHB1YmxpYyBSb3dURHM6IHsgW2NvbnRleHQ6IHN0cmluZ106IEVzVGRbXSB9ID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRpIGFwcG9nZ2lvIHRlbXBvcmFuZW8gcGVyIGkgKipSb3dURHMqKiAqL1xyXG4gICAgcHVibGljIFRNUFJvd1REczogeyBbY29udGV4dDogc3RyaW5nXTogRXNUZFtdIH0gPSBudWxsO1xyXG4gICAgLyoqIE1vZGVsbG8gcmFwcHJlc2VudGFudGUgdW4gc2luZ29sbyB0aCBkZWxsYSB0YWJlbGxhLCBnZW5lcmF0byBpbiBiYXNlIGFsbGUgY29uZmlndXJhemlvbmkgZSBhZ2xpIG9nZ2V0dGkgcmljZXZ1dGkgKi9cclxuICAgIHB1YmxpYyBSb3dUSHM6IFRoRWxlbWVudFtdID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRpIGFwcG9nZ2lvIHRlbXBvcmFuZW8gcGVyIGkgKipSb3dUSHMqKiAqL1xyXG4gICAgcHVibGljIFRNUFJvd1RIczogVGhFbGVtZW50W10gPSBudWxsO1xyXG4gICAgLyoqIE1vZGVsbG8gZGkgYXBwb2dnaW8gdGVtcG9yYW5lbyBwZXIgaSAqKlJvd1RoR3JvdXBzKiogKi9cclxuICAgIHB1YmxpYyBUTVBSb3dUaEdyb3VwczogeyBTcGFuOiBudW1iZXIsIFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IH1bXVtdID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIHJhcHByZXNlbnRhbnRlIHVuIHNpbmdvbG8gaGVhZGVyIGdyb3VwIGRlbGxhIHRhYmVsbGEuIFF1ZXN0YSBsaXN0YSDDqCBnacOgIG9yZGluYXRhIGUgcHJvbnRhIHBlciBlc3NlcmUgdXRpbGl6emF0YSBpbiBuZ0ZvciAqL1xyXG4gICAgcHVibGljIFJvd1RoR3JvdXBzOiB7IFNwYW46IG51bWJlciwgVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfVtdW10gPSBudWxsO1xyXG4gICAgLyoqIENhY2hlIHBlciBpIHJvdXRlckxpbmsgZ2VuZXJhdGkgbmVsbGUgdGFiZWxsZSBkaW5hbWljaGUgKi9cclxuICAgIHB1YmxpYyBEeW5hbWljVGFibGVSb3V0ZXJMaW5rQ2FjaGU6IHt9ID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMaXN0YSBkZWkgY29udGVzdGkuIFVuIGNvbnRlc3RvIG5vbiDDqCBhbHRybyBjaGUgdW4gaGFzaCBwYXJ0aWNvbGFyZSBjYWxjb2xhdG8gc3UgdW4gb2dnZXR0byBjaGUgaWRlbnRpZmljYSB1bml2b2NhbWVudGUgdGFsZSBvZ2dldHRvLlxyXG4gICAgICpcclxuICAgICAqIE9nbnVubyBkaSBxdWVzdGkgY29udGVzdGkgcmFwcHJlc2VudGVyw6AgYSBzdWEgdm9sdGEsIHVuaXZvY2FtZW50ZSwgdW5hIHJpZ2EgYWxsJ2ludGVybm8gZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgUm93Q29udGV4dHM6IGFueVtdID0gW107XHJcbiAgICAvKiogRGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvIGRlbGxlIGNvbG9ubmUgKG5vbiBvcmRpbmFtZW50byBkZWkgZGF0aSBtYSBkZWxsZSBjb2xvbm5lIGluIHNlKSAqL1xyXG4gICAgcHVibGljIE9yZGVyRGlyZWN0aXZlczogc3RyaW5nW10gPSBbXTtcclxuICAgIC8qKiBDb2RpY2UgZGVsbCd1bHRpbW8gb2dnZXR0byBzb2xlemlvbmF0byAqL1xyXG4gICAgcHVibGljIGxhc3RTZWxlY3RlZEl0ZW1JRCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2Egc2Ugb2x0cmUgYWxsZSBjb2xvbm5lIGRpbmFtaWNoZSBzcGVjaWZpY2hlIGRpIHVuIHRpcG8gZGkgb2dnZXR0byBjaSBzb25vIGFuY2hlIGNvbG9ubmUgZGluYW1pY2hlIGFnZ2l1bnRlIGRhbGwndXRlbnRlXHJcbiAgICAgKlxyXG4gICAgICogRXMuIHVuYSBjb2xvbm5hIGluIGN1aSBtb3N0cmFyZSBzZW1wcmUgdW4gaWNvbmNpbmFcclxuICAgICAqL1xyXG4gICAgcHVibGljIFVzZXJEZWZpbmVkRHluYW1pY0NvbHM6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIC8qKiBJbmRpY2EgY2hlIHF1ZXN0byDDqCBpbCBwcmltbyBCaW5kIGRlbGxhIHRhYmVsbGEsIHZpZW5lIHNldHRhdG8gYSBmYWxzZSBub24gYXBwZW5hIGlsIHByaW1vIGJpbmQgdmllbmUgdGVybWluYXRvIGNvbiBzdWNjZXNzbyAqL1xyXG4gICAgcHVibGljIEZpcnN0QmluZDogYm9vbGVhbiA9IHRydWU7XHJcbiAgICAvKiogTGlzdGEgZGkgY29sb25uZSBjaGUgc2kgcG9zc29ubyB2aXN1YWxpenphcmUvb3JkaW5hcmUgZnJhIGRpIGxvcm8gKi9cclxuICAgIHB1YmxpYyBDb2x1bW5zTGlzdDogRXNUYWJsZUNvbHVtbltdID0gW107XHJcbiAgICAvKiogVmFyaWFiaWxlIGQnYXBwb2dnaW8gdXNhdGEgZGFsbGEgZGlhbG9nIGRpIHNlbGV6aW9uZS9uYXNjb25kaW1lbnRvLCBwZXIgZXZpdGFyZSBkaSBkYW5uZWdnaWFyZSAqKkNvbHVtbnNMaXN0KiogaW4gY2FzbyBkaSBtb2RpZmljaGUgcG9pIGFubnVsbGF0ZSAqL1xyXG4gICAgcHVibGljIFRNUENvbHVtbnNMaXN0OiBFc1RhYmxlQ29sdW1uW10gPSBbXTtcclxuICAgIC8qKiBWYWxvcmUgZGVsIGNoZWNrIGdsb2JhbGUgZGkgdmlzaWJpbGl0w6AgdmFsaWRvIHBlciB0dXR0ZSBsZSBjb2xvbm5lIGluICoqQ29sdW1uc0xpc3QqKiAqL1xyXG4gICAgcHVibGljIGdsb2JhbENvbFZpc0NoZWNrID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRlIGxlIG51b3ZlIGRpcmV0dGl2ZSAgYXNzZWduYXRpIGEgZGlyZXR0aXZhIChQZXIgbGEgbW9kYWxpdMOgIGRpbmFtaWNhIGRlbGwnZXMtdGFibGUpICovXHJcbiAgICBAQ29udGVudENoaWxkcmVuKEVzVGREaXJlY3RpdmUpIEVzVGRzRGlyZWN0aXZlOiBRdWVyeUxpc3Q8RXNUZERpcmVjdGl2ZT47XHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgdHV0dGkgZ2xpIGVzLXRkIGFzc2VnbmF0aSBhIGRpcmV0dGl2YSAoUGVyIGxhIG1vZGFsaXTDoCBkaW5hbWljYSBkZWxsJ2VzLXRhYmxlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihFc1RoRGlyZWN0aXZlKSBFc1Roc0RpcmVjdGl2ZTogUXVlcnlMaXN0PEVzVGhEaXJlY3RpdmU+O1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRpIGdsaSBlcy10aCAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IEVzVGgpKSBwcml2YXRlIEVzVGhzOiBRdWVyeUxpc3Q8RXNUaD47XHJcbiAgICAvKiogQGRlcHJlY2F0ZWQgUXVlcnkgcGVyIHJlY3VwZXJhcmUgdHV0dGkgZ2xpIGVzLXRkICovXHJcbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gRXNUZCkpIHByaXZhdGUgRXNUZHM6IFF1ZXJ5TGlzdDxFc1RkPjtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgZGVsIGJvZHkgKHB1bnRvIGRlbGxhIHRhYmVsbGEgZG92ZSB2ZW5nb25vIG1vc3RyYXRlIGxlIHJpZ2hlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnYm9keScsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgYm9keVJlZjogYW55O1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIFF1ZXJ5IHBlciByZWN1cGVyYXJlIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciAocHVudG8gZGVsbGEgdGFiZWxsYSBkb3ZlIHZlbmdvbm8gbW9zdHJhdGUgbGUgaW50ZXN0YXppb25pIGRlbGxlIHJpZ2hlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnaGVhZGVyJywgeyBzdGF0aWM6IGZhbHNlIH0pIHB1YmxpYyBoZWFkZXJSZWY6IGFueTtcclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgc3VsIHJhZ2dydXBwYW1lbnRvIGRlZ2xpIGhlYWRlciAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnaGVhZGVyR3JvdXAnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGhlYWRlckdyb3VwUmVmOiBhbnk7XHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIHN1bCByYWdncnVwcGFtZW50byBkaSBzZWNvbmRvIGxpdmVsbG8gZGVnbGkgaGVhZGVyICovXHJcbiAgICBAQ29udGVudENoaWxkKCdzZWNvbmRhcnlIZWFkZXJHcm91cCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgc2Vjb25kYXJ5SGVhZGVyR3JvdXBSZWY6IGFueTtcclxuICAgIC8qKiBPcHppb25pIGV4dHJhIGNoZSBkZXZvbm8gYXBwYXJpcmUgbmVsIE1lbsO5IGNvbnRlc3R1YWxlIGluIGFsdG8gYSBkZXN0cmEsIHJpY2hpYW1hdG8gZGFpIDMgcGFsbGluaSB2ZXJ0aWNhbGkgKi9cclxuICAgIEBJbnB1dCgpIENvcm5lck1lbnVPcHRpb25zOiBDb3JuZXJNZW51T3B0aW9uW10gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBkZXYnZXNzZXJlIHBvc3NpYmlsZSBlZmZldHR1YXJlIGlsIHJlc2l6ZSBkZWxsZSBjb2xvbm5lICovXHJcbiAgICBASW5wdXQoKSBDb2x1bW5zUmVzaXphYmxlOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgZGV2J2Vzc2VyZSBkaXNwb25pYmlsZSBpbCBzaXN0ZW1hIGRpIGFnZ2lvcm5hbWVudG8gYXV0b21hdGljbyAqL1xyXG4gICAgQElucHV0KCkgQXV0b1VwZGF0ZTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBsYSB0YWJlbGxhIChjb25maWd1cmF0YSBjb24gKipVc2VDdXN0b21DZWxscyoqKSBkZXZlIG1ldHRlcnNpIGluIGFzY29sdG8gcGVyIGkgY2xpY2sgc3VsbGUgY2VsbGUgZGVzaWRlcmF0ZVxyXG4gICAgICogXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXJlIGwnSW5wdXQgKipUZW1wbGF0ZSoqIGRlbGxlIGVzLXRkIGUgYXNzZWduYXJlIHVuIHRlbXBsYXRlIGNvbiB0dXR0aSBpIGJpbmRpbmcgY2hlIHNpIHZ1b2xlIGFpIGNsaWNrXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFVzZUN1c3RvbUNlbGxBY3Rpb25zOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBsZSBjZWxsZSBkZXNpZGVyYXRlIHN1IGN1aSBpbnRlcmNldHRhcmUgaSBjbGljay4gQXR0aXZhIHNvbG8gcXVhbmRvICoqVXNlQ3VzdG9tQ2VsbEFjdGlvbnMqKiDDqCB0cnVlLlxyXG4gICAgICogT2duaSBjZWxsYSBkZXYnZXNzZXJlIHNlcGFyYXRhIGRhbGxhIHN1Y2Nlc3NpdmEgZGFsIGNhcmF0dGVyZSBkZWwgU2ltb2xlb246XHJcbiAgICAgKlxyXG4gICAgICogRXMsIFwiTWlhQ2VsbGExwqdNaWFDZWxsYTJcIlxyXG4gICAgICogXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXJlIGwnSW5wdXQgKipUZW1wbGF0ZSoqIGRlbGxlIGVzLXRkIGUgYXNzZWduYXJlIHVuIHRlbXBsYXRlIGNvbiB0dXR0aSBpIGJpbmRpbmcgY2hlIHNpIHZ1b2xlIGFpIGNsaWNrXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIEN1c3RvbUNlbGxBY3Rpb25zT24gPSAnJztcclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBTZXJ2ZSBwZXIgZGVjaWRlcmUgZGkgbGFuY2lhcmUgbyBtZW5vIGlsICoqZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCkqKiBhbCB0ZXJtaW5lIGRlbGxhIGdlc3Rpb25lIGRlbGwnZXZlbnRvIFxyXG4gICAgICogXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXJlIGwnSW5wdXQgKipUZW1wbGF0ZSoqIGRlbGxlIGVzLXRkIGUgYXNzZWduYXJlIHVuIHRlbXBsYXRlIGNvbiB0dXR0aSBpIGJpbmRpbmcgY2hlIHNpIHZ1b2xlIGFpIGNsaWNrXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIENlbGxBY3Rpb25Qcm9wYWdhdGVzID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY2lkZSBzZSB1dGlsaXp6YXJlIG8gbWVubyBsZSBDdXN0b21DZWxscy4gSW1wb3N0YW5kb2xvIGEgKip0cnVlKiogbCdlcy10YWJsZSBkaXZlbnRhIGluIGdyYWRvIGRpIGdlc3RpcmUgbmF0aXZhbWVudGU6XHJcbiAgICAgKlxyXG4gICAgICogMSkgT3JkaW5hbWVudG8gZSB2aXNpYmlsaXTDoCBkZWxsZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogMikgT3JkaW5hbWVudG8gZGVpIGRhdGlcclxuICAgICAqXHJcbiAgICAgKiAzKSBNb2RhbGl0w6AgR2VyYXJjaGljYVxyXG4gICAgICpcclxuICAgICAqIGVjYy4uLlxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBVc2VDdXN0b21DZWxsczogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgaW1wb3N0YXJlIGwnYWx0ZXp6YSBtYXNzaW1hIGRlbGxhIHRhYmVsbGEuIFNlIG51bGwgbGEgZGltZW5zaW9uZSBzaSBhZGF0dGEgYWwgbnVtZXJvIGRpIGVsZW1lbnRpIGF0dHVhbG1lbnRlIGluIHZpc3VhbGl6emF6aW9uZSAqL1xyXG4gICAgQElucHV0KCkgTWF4SGVpZ2h0OiBudW1iZXIgPSBudWxsO1xyXG4gICAgLyoqIENsYXNzaSBkYSBhcHBsaWNhcmUgYWwgY29udGVuaXRvcmUgZGVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgQ29udGFpbmVyQ2xhc3MgPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIG8gbWVubyBsJ2V4cG9ydCBpbiBmb3JtYXRvIFhMU1ggKi9cclxuICAgIEBJbnB1dCgpIFhMU1hFeHBvcnQ6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIG8gbWVubyBsJ2V4cG9ydCBpbiBmb3JtYXRvIENTViAqL1xyXG4gICAgQElucHV0KCkgQ1NWRXhwb3J0ID0gdHJ1ZTtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSB2aXN1YWxpenphcmUgbyBtZW5vIGwnb3B6aW9uZSBkaSBwYWdpbmF6aW9uZSBcIlR1dHRpXCIgKi9cclxuICAgIEBJbnB1dCgpIEFsbFNlYXJjaCA9IG51bGw7XHJcbiAgICAvKiogRGltaW51aXNjZSBnbGkgc3BhemkgZnJhIHVuYSBjZWxsYSBlIGwnYWx0cmEsIGUgaW50ZXJuYW1lbnRlIGlsIHBhZGRpbmcgZGVsIGZvbnQgaW4gbW9kbyBkYSBwcmVzZW50YXJlIG1vbHRpIHBpw7kgZGF0aSBpbiB1bid1bmljYSBwYWdpbmEgKi9cclxuICAgIEBJbnB1dCgpIEhpZ2hDZWxsRGVuc2l0eTogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogQWJpbGl0YSBvIG1lbm8gbGEgcG9zc2liaWxpdMOgIGRpIHNlbGV6aW9uYXJlIG9nZ2V0dGkgKi9cclxuICAgIEBJbnB1dCgpIFNlbGVjdGlvbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogTW9zdHJhIG8gbWVubyB1biBtZXNzYWdnaW8gZGkgTG9hZGluZyBhbCBwcmltbyBjYXJpY2FtZW50byBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBTaG93TG9hZGluZ09uQm9vdHN0cmFwOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBTZSBpbXBvc3RhdG8gYSAqKnRydWUqKiBhZ2dpdW5nZSB1bmEgY29sb25uYSBjb24gcHVsc2FudGUgZGkgZWxpbWluYXppb25lIHBlciBlZmZldHR1YXJlIGwnZWxpbWluYSBkZWxsJ29nZ2V0dG8gcmVsYXRpdm8gKi9cclxuICAgIEBJbnB1dCgpIFJlbW92YWw6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uZGl6aW9uZSBjaGUgbmFzY29uZGUgbCdpY29uYSBkaSBlbGltaW5hemlvbmUgaW5zZXJpdGEgaW1wb3N0YW5kbyAqKlJlbW92YWwqKiBhIHRydWUgcXVhbG9yYSBsYSBjb25kaXppb25lIG5vbiB2ZW5pc3NlIHJpc3BldHRhdGFcclxuICAgICAqXHJcbiAgICAgKiBDb21lIGNvbmRpemlvbmUgc2kgY29uc2lkZXJhIHVuIHNlbXBsaWNlIGNhbXBvIHN1IGN1aSBlZmZldHR1YXJlIHVuIGNvbnRyb2xsbyBib29sZWFubywgY29tZSBhZCBlc2VtcGlvIFwiY2FucmVtb3ZlXCJcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgUmVtb3ZhbENvbmRpdGlvbiA9ICcnO1xyXG4gICAgLyoqIEluZGljYSBzZSBhYmlsaXRhcmUgbGEgcG9zc2liaWxpdMOgIGRpIGVzcG9ydGFyZSBsYSB2aXN0YSBkYXRpIGF0dHVhbGUgKi9cclxuICAgIEBJbnB1dCgpIEV4cG9ydDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIHBlcm1ldHRlcmUgbGEgc2VsZXppb25lIG11bHRpcGxhIFdpbmRvd3MtbGlrZSBjbGljY2FuZG8gdW4gb2dnZXR0byBlIGZhY2VuZG8gcG9pIFNoaWZ0ICsgY2xpY2sgc3UgdW4gb2dnZXR0byBzdWNjZXNzaXZvICovXHJcbiAgICBASW5wdXQoKSBTaGlmdENsaWNrOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgbmFzY29uZGVyZSBvIG1vc3RyYXJlIGlsIGNvbXBvbmVudGUgZGkgcGFnaW5hemlvbmUgKi9cclxuICAgIEBJbnB1dCgpIEhpZGVQYWdpbmc6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaWwgY29udGVnZ2lvIGRlZ2xpIGVsZW1lbnRpIHRyb3ZhdGkgKi9cclxuICAgIEBJbnB1dCgpIEhpZGVQYWdpbmdDb3VudDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgbyBtb3N0cmFyZSBpIHB1bHNhbnRpIGRpIHBhZ2luYXppb25lICovXHJcbiAgICBASW5wdXQoKSBIaWRlUGFnaW5nQnV0dG9uczogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUmlmZXJpbWVudG8gYWwgQ29udGV4dE1lbnUgKG5neC1jb250ZXh0bWVudSkgYXNzb2NpYXRvIGFsIGNsaWNrIGRlc3RybyBkaSB1bm8gbyBwacO5IGVsZW1lbnRpIHNlbGV6aW9uYXRpIG5lbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIENvbnRleHRNZW51OiBDb250ZXh0TWVudUNvbXBvbmVudCA9IG51bGw7XHJcbiAgICAvKiogTm9tZSBkZWxsJ2VzcG9ydGF6aW9uZSBnZW5lcmF0YSBkYSBxdWVzdGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgRXhwb3J0RmlsZU5hbWUgPSAnRXhwb3J0LmNzdic7XHJcbiAgICAvKiogQ2xhc3NlIChIVE1MKSBkaSBkZWZhdWx0IGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIFRhYmxlQ2xhc3MgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgZGEgdXRpbGl6emFyZSBpbiBlc3BvcnRhemlvbmUuIE5lbCBmb3JtYXRvIFwiUmVwb3J0XCIgYXZyw6AgdW4gdW5pY28gcGFyYW1ldHJvIFwiRm9ybWF0b1wiIGUgbmVzc3VuIHZhbG9yZSBkaSByaXRvcm5vLlxyXG4gICAgICpcclxuICAgICAqIE5lbCBmb3JtYXRvIFwiVmlld1wiIGhhIGNvbWUgcGFyYW1ldHJvIHVuYSBjYWxsYmFjayBjb24gaSBkYXRpIGNvbXBsZXRpIGRhIGVzcG9ydGFyZSAoZGF0byBjaGUgZGkgZGVmYXVsdCBsYSByaWNlcmNhIMOoIHBhZ2luYXRhKVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBFeHBvcnRGdW5jdGlvbjogYW55O1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIEluZGljYSBsYSBwcmVzZW56YSBkaSByYWdncnVwcGFtZW50aSBhIGxpdmVsbG8gZGkgaGVhZGVyICovXHJcbiAgICBASW5wdXQoKSBIYXNIZWFkZXJHcm91cDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogQGRlcHJlY2F0ZWQgSW5kaWNhIGxhIHByZXNlbnphIGRpIHJhZ2dydXBwYW1lbnRpIGEgbGl2ZWxsbyBkZWwgcmFnZ3J1cHBhbWVudG8gcHJlY2VkZW50ZW1lbnRlIGVzaXN0ZW50ZSwgY2hpYXJhbWVudGUgw6ggaW5zZW5zYXRhIHNlbnphICoqSGFzSGVhZGVyR3JvdXAqKiAqL1xyXG4gICAgQElucHV0KCkgSGFzU2Vjb25kYXJ5SGVhZGVyR3JvdXA6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFV0aWxpenphdG8gcGVyIGRpdmlkZXJlIGxhIHNvcmdlbnRlIGluIG1vZGFsaXTDoCBFbmRsZXNzU2Nyb2xsICovXHJcbiAgICBASW5wdXQoKSBTbGljZVNpemUgPSAxMDA7XHJcbiAgICAvKiogRGVjaWRlIHNlIHV0aWxpenphcmUgbGEgbW9kYWxpdMOgIGRpIEVuZGxlc3NTY3JvbGwgKi9cclxuICAgIEBJbnB1dCgpIEVuZGxlc3NTY3JvbGw6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFF1YWxvcmEgKipFbmRsZXNzU2Nyb2xsKiogZm9zc2UgdHJ1ZSwgaW5kaWNhIHNlIHV0aWxpenphcmUgcXVlc3RhIG1vZGFsaXTDoCBzb2xvIHF1YW5kbyBzaSBjZXJjYSBwZXIgXCJUdXR0aVwiIG8gaW4gZ2VuZXJhbGUgKi9cclxuICAgIEBJbnB1dCgpIEVuZGxlc3NTY3JvbGxPbmx5Rm9yQWxsID0gdHJ1ZTtcclxuICAgIC8qKiBJbmRpY2Egc2UgbmFzY29uZGVyZSBnbGkgSGVhZGVyIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIEhlYWRlckhpZGRlbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgaWwgQm9keSBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBCb2R5SGlkZGVuOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBzZSBsYSBzZWxlemlvbmUgw6ggdGVtcG9yYW5lYW1lbnRlIGRpc2FiaWxpdGF0YS4gUmlzcGV0dG8gYWxsJ0lucHV0ICoqU2VsZWN0aW9uKiogY2hlIHZpc2l2YW1lbnRlIGdlc3Rpc2NlIHNlIGNpIHNvbm8gbyBubyBnbGkgaW5wdXQgZGkgc2VsZXppb25lLFxyXG4gICAgICogcXVlc3RvIElucHV0IGdlc3Rpc2NlIHNlIHF1ZXN0aSBpbnB1dCBzb25vIGFiaWxpdGF0aSBvIG1lbm9cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2VsZWN0aW9uRGlzYWJsZWQ6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIGZvcnphcmUgaWwgc2lzdGVtYSBkaSBzZWxlemlvbmUgYSBnZXN0aXJlIHVuIGVsZW1lbnRvIHBlciB2b2x0YS5cclxuICAgICAqIFNlbGV6aW9uYXJlIHVuJ2FsdHJhIHJpZ2EgY29uIHVuYSBnacOgIHNlbGV6aW9uYXRhIGFwcGxpY2hlcsOgIGxhIHNlbGV6aW9uZSBhbGxhIG51b3ZhIHJpZ2EsIHJpbXVvdmVuZG9sYSBkYWxsJ2F0dHVhbGVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2luZ2xlU2VsZWN0aW9uOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBDYWxsYmFjayBjaGUgZGF0byB1biBvZ2dldHRvIHJlc2l0dWlzY2UgbCdldmVudHVhbGUgY2xhc3NlIGRhIGFwcGxpY2FyZSBhbGxhIHJpZ2EgY29sbGVnYXRhIGFsbCdvZ2dldHRvICovXHJcbiAgICBASW5wdXQoKSBSb3dDbGFzc0Fzc2lnbmVyOiBhbnkgPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIGRpIG9yZGluYXJlIGkgZGF0aSBpbiBtYW5pZXJhIGRpc2NlbmRlbnRlIG8gYXNjZW5kZW50ZSAqL1xyXG4gICAgQElucHV0KCkgT3JkZXJCeUNvbHVtbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgYXZlcmUgcGnDuSBkaXJldHRpdmUgZGkgb3JkaW5hbWVudG8gZGVpIGRhdGkgKi9cclxuICAgIEBJbnB1dCgpIE11bHRpcGxlT3JkZXJpbmdEaXJlY3RpdmVzID0gdHJ1ZTtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSBuYXNjb25kZXJlIGxlIGNvbG9ubmUgaW4gYmFzZSBhbGxlIHNlbGV6aW9uaSBlZmZldHR1YXRlIGRhbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhICovXHJcbiAgICBASW5wdXQoKSBIaWRkZW5Db2x1bW5zOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSByaW9yZGluYXJlIGxlIGNvbG9ubmUgaW4gYmFzZSBhbGxlIGltcG9zdGF6aW9uaSBlZmZldHR1YXRlIGRhbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhICovXHJcbiAgICBASW5wdXQoKSBDb2x1bW5zT3JkZXJpbmc6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEV2ZW50dWFsZSBzdXBwb3J0byBhbGxlIHJpY2VyY2hlIGFwcGxpY2F0ZSBhbGxhIG1vZGFsaXTDoCBBcnJheSAqL1xyXG4gICAgQElucHV0KCkgU2VhcmNoVmlldyA9IG51bGwgYXMgQXBwU2VhcmNoPGFueT47XHJcbiAgICAvKiogQWJpbGl0YSBvIGRpc2FiaWxpdGEgaWwgc2lzdGVtYSBjaGUgcGVybWV0dGUgZGkgc2VsZXppb25hcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIG5lbGxhIHZpc3RhICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3RBbGw6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFNpbXVsYSBsYSBwYWdpbmF6aW9uZSBhbmNoZSBwZXIgbGUgdGFiZWxsZSBjaGUgZnVuemlvbmFubyBpbiBtb2RhbGl0w6AgQXJyYXkgKi9cclxuICAgIEBJbnB1dCgpIFVzZUFycmF5TW9kZVBhZ2luZyA9IHRydWU7XHJcbiAgICAvKiogRGVmaW5pemlvbmUgZGkgY29sb25uZSBkaW5hbWNoZSBwZXIgbGEgbW9kYWxpdMOgLCBhcHB1bnRvLCBkaW5hbWljYSAqL1xyXG4gICAgQElucHV0KCkgRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uOiBFc1RhYmxlQ29sdW1uc0RlZmluaXRpb25bXSA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIG9wZXJhemlvbmkgZGluYW1pY2hlIGdlbmVyaWNoZSBjaGUgcG9zc29ubyBlc3NlcmUgZWZmZXR0dWF0ZSBwZXIgcmlnYS4gQXBwYWlvbm8gY29tZSBjb2xvbm5lIGV4dHJhIHN1bCBsYXRvIHNpbmlzdHJvIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIER5bmFtaWNPcGVyYXRpb25zOiBFc1RhYmxlT3BlcmF0aW9uRGVmaW5pdGlvbltdID0gW107XHJcbiAgICAvKiogSW5kaWNhIHNlIHZpc3VhbGl6emFyZSBpIGRhdGkgaW4gbWFuaWVyYSBnZXJhcmNoaWNhICovXHJcbiAgICBASW5wdXQoKSBIaWVyYXJjaHk6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIE5vbWUgZGVsbGEgcHJvcHJpZXTDoCBjaGUgY29udGllbmUgbCdJRCBkZWwgcGFkcmUuIERhIHV0aWxpenphcmUgc2UgKipIaWVyYXJjaHkqKiDDqCBpbXBvc3RhdG8gKi9cclxuICAgIEBJbnB1dCgpIFBhcmVudEtleSA9ICcnO1xyXG4gICAgLyoqIE5vbWUgZGVsbGEgcHJvcHJpZXTDoCBjaGUgY29udGllbmUgbCdJRCBkZWxsJ29nZ2V0dG8gYXR0dWFsZS4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgT3duS2V5ID0gJyc7XHJcbiAgICAvKiogSW5kaWNhIHNlIHBhcnRpcmUgY29uIHVuIGFsYmVybyBlc3BhbnNvLiBEYSB1dGlsaXp6YXJlIHNlICoqSGllcmFyY2h5Kiogw6ggaW1wb3N0YXRvICovXHJcbiAgICBASW5wdXQoKSBTdGFydHNFeHBhbmRlZCA9IHRydWU7XHJcbiAgICAvKiogSW5kaWNhIHNlIGVmZmV0dHVhcmUgaWwgc2FsdmF0YWdnaW8gZGVsbGUgcHJlZmVyZW56ZSBkaSByaWNlcmNhICovXHJcbiAgICBASW5wdXQoKSBTYXZlUHJlZmVyZW5jZXM6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2EgZG92ZSB2aXN1YWxpenphcmUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lLCBzZSBzb3ByYSwgc290dG8gbyBpbiBlbnRyYW1iaSAqL1xyXG4gICAgQElucHV0KCkgUGFnaW5nU3R5bGU6ICdib3RoJyB8ICd0b3AnIHwgJ2JvdHRvbScgPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBkb3ZlIHZpc3VhbGl6emFyZSBsZSBpbmZvcm1hemlvbmkgZGkgcGFnaW5hemlvbmUsIHNlIHNvcHJhLCBzb3R0byBvIGluIGVudHJhbWJpICovXHJcbiAgICBASW5wdXQoKSBSb3dHcm91cGluZ1BhZ2luZ1N0eWxlOiAnbGVmdCcgfCAncmlnaHQnID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNvcmdlbnRlIGRhdGkgc2Vjb25kYXJpYVxyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphdG8gc29sbyBwZXIgdW4gY2FzbyBwYXJ0aWNvbGFyZSBkZWwgTWV0ZXJpbmdcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2Vjb25kYXJ5U291cmNlOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNvcmdlbnRlIGRhdGkgc2Vjb25kYXJpYVxyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphdG8gc29sbyBwZXIgdW4gY2FzbyBwYXJ0aWNvbGFyZSBkZWwgTWV0ZXJpbmdcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgVGVydGlhcnlTb3VyY2U6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSB1dGlsaXp6YXJlIGxhIGNhY2hlIGRpIHNlbGV6aW9uZSBjaGUgcGVybWV0dGUgZGkgbWFudGVuZXJlIGdsaSBzdGF0aSBkaSBzZWxlemlvbmUgZGVpIHZhcmkgb2dnZXR0aSBuYXZpZ2FuZG8gZGEgdW5hIHBhZ2luYSBhbGwnYWx0cmEgKi9cclxuICAgIEBJbnB1dCgpIFVzZVNlbGVjdGlvbkNhY2hlID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSBkZWNpZGVyZSBzZSwgaW4gbW9kYWxpdMOgIHJhZ2dydXBwYW1lbnRvLCBtb3N0cmFyZSBvIG1lbm8gaWwgdmFsb3JlIGRlbGxlIGNvbG9ubmUgZGkgZ3J1cHBvIG5lZ2xpIG9nZ2V0dGkgZmluYWxpLiBEaSBkZWZhdWx0IHNvbm8gbmFzY29zdGkgKi9cclxuICAgIEBJbnB1dCgpIFNob3dJdGVtR3JvdXBzQ29sdW1ucyA9IG51bGw7XHJcbiAgICAvKiogRXZlbnRvIGNoZSB2aWVuZSByaWNoaWFtYXRvIGFsIGNhbWJpbyBkaSBvcmlkbmFtZW50byBkaSB1bmEgY29sb25uYSAqL1xyXG4gICAgQE91dHB1dCgpIG9uT3JkZXJDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8QXBwT3JkZXJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxBcHBPcmRlcmluZz4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEV2ZW50byBjaGUgdmllbmUgcmljaGlhbWF0byBxdWFuZG8gbCdlcy10YWJsZSByaXRpZW5lIHNpYSBuZWNlc3NhcmlvIHJpLWVmZmV0dHVhcmUgbGEgcmljZXJjYS5cclxuICAgICAqIElsIGJvb2xlYW5vIGRlbGwnZXZlbnRvIGluZGljYSBzZSB2aWVuZSBzdWdnZXJpdG8gZGkgcmVzZXR0YXJlIGxhIHBhZ2luYSBvIG1lbm8uXHJcbiAgICAgKiBcclxuICAgICAqIFNvbG8gaW4gY2FzbyB2ZW5nYSB1dGlsaXp6YXRhIGxhIG1vZGFsaXTDoCBhIHJhZ2dydXBwYW1lbnRpIGRpIHJpZ2hlIHB1w7Igc3VjY2VkZXJlIGNoZSBsJ2VzLXRhYmxlIHBhc3NpIHVuIGludGVybyBBcHBTZWFyY2ggY29tZSBwYXJhbWV0cm8gZGkgcmljZXJjYSxcclxuICAgICAqIGluIHF1ZWwgY2FzbyBsJ2FwcGxpY2F6aW9uZSByaWNldmVudGUgZG92csOgIG9ub3JhcmUgbGEgcmljaGllc3RhIHNwZWRlbmRvIGFsIGJhY2thbmQgbCdvZ2dldHRvIGRpIHJpY2VyY2EgQVMtSVNcclxuICAgICAqIFxyXG4gICAgICogaWwgdGlwbyBkZWxsJ0VtaXR0ZXIgaW52ZWNlIGRpIGVzc2VyZSBbYm9vbGVhbiB8IEFwcFNlYXJjaDxhbnk+XSDDqCBzdGF0byBpbXBvc3RhdG8gYSBcImFueVwiIHBlciBldml0YXJlIHByb2JsZW1pIGRpIHJldHJvY29tcGF0aWJpbGl0w6BcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpIG9uU2VhcmNoUmVxdWVzdDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIC8qKiBFdmVudG8gY2hlIHBhcnRlIGFkIG9nbmkgbW9kaWZpY2EgZGkgXCJjaGVja2FnZ2lvXCIgaW4gZm9ybWEgZGkgY29tb2RvIGFycmF5LiBFc3BvbmUgbCdvZ2dldHRvIGNvbiBsbyBzdGF0byBkaSBjaGVjayBhdHR1YWxlICovXHJcbiAgICBAT3V0cHV0KCkgb25TZWxlY3Rpb25DaGFuZ2VkOiBFdmVudEVtaXR0ZXI8SXRlbXNTZWxlY3Rpb248YW55Pj4gPSBuZXcgRXZlbnRFbWl0dGVyPEl0ZW1zU2VsZWN0aW9uPGFueT4+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gYWxsJ2VsaW1pbmF6aW9uZSBkaSB1biBvZ2dldHRvICovXHJcbiAgICBAT3V0cHV0KCkgb25SZW1vdmFsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIGFsbCdhbm51bGxhbWVudG8gZGkgdW4nZWxpbWluYXppb25lICovXHJcbiAgICBAT3V0cHV0KCkgb25BYm9ydFJlbW92YWw6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIGFsIGNsaWNrIHN1IHVuYSBjZWxsYSBxdWFuZG8gKipVc2VDdXN0b21DZWxsQWN0aW9ucyoqIMOoIGF0dGl2byBcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBAT3V0cHV0KCkgb25DZWxsQ2xpY2s6IEV2ZW50RW1pdHRlcjx7IGNvbHVtbjogc3RyaW5nLCBtb2RlbDogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGNvbHVtbjogc3RyaW5nLCBtb2RlbDogYW55IH0+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gcXVhbmRvIHNpIGNsaWNjYSBzdSB1biBvcHppb25lIGRlZmluaXRhIG5lbGxlICoqQ29ybmVyTWVudU9wdGlvbnMqKiAqL1xyXG4gICAgQE91dHB1dCgpIG9uQ29ybmVyQWN0aW9uOiBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nLCBlc3RhYmxlOiBhbnkgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgZXN0YWJsZTogYW55IH0+KCk7XHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gcXVhbmRvIHNpIGNsaWNjYSBzdSB1biBvcHppb25lIGRlZmluaXRhIG5lbGxlICoqRHluYW1pY09wZXJhdGlvbnMqKiAqL1xyXG4gICAgQE91dHB1dCgpIG9uRHluYW1pY09wZXJhdGlvbjogRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgaXRlbTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGl0ZW06IGFueSB9PigpO1xyXG5cclxuICAgIC8qKiBEYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgZGF0YTogYW55W107XHJcbiAgICAvKiogSGVhZGVyIGRlaSBkYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgaGVhZGVyczogYW55W107XHJcbiAgICAvKiogRWxlbWVudG8gSFRNTCBkYSBjbGljY2FyZSBwZXIgbCdlc3BvcnRhemlvbmUgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2V4cG9ydERvd25sb2FkZXInLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGV4cG9ydERvd25sb2FkZXI6IEVsZW1lbnRSZWY7XHJcbiAgICAvKiogUGxhY2Vob2xkZXIgZGkgbWVuw7kgY29udGVzdHVhbGUgcGVyIHF1YW5kbyBub24gY2kgc29ubyBvcHppb25pIG5lbCBwbGFjZWhvbGRlciBcIlZlcm9cIiAgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2VtcHR5TWVudScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyB0YWJsZUVtcHR5TWVudTogQ29udGV4dE1lbnVDb21wb25lbnQ7XHJcblxyXG4gICAgLyoqIFN1YnNjcmlwdGlvbiBzdWxsJ2FwZXJ0dXJhIGRlbCBjb250ZXh0IG1lbnUgZGEgcmlwdWxpcmUgYWwgZGVzdHJveSBkZWxsYSBjbGFzc2UgKi9cclxuICAgIHByaXZhdGUgY3R4TWVudVN1YnNjcmlwdGlvbjogYW55O1xyXG5cclxuICAgIC8qKiBQYWdpbmEgaW4gdmlzdWFsaXp6YXppb25lIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIHB1YmxpYyBhcnJheW1vZGVQYWdlID0gMTtcclxuICAgIC8qKiBOdW1lcm8gZGkgcGFnaW5lIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIHB1YmxpYyBhcnJheW1vZGVQYWdlcyA9IDE7XHJcbiAgICAvKiogT2dnZXR0aSBwZXIgb2duaSBwYWdpbmEgKGR1cmFudGUgbGEgcGFnaW5hemlvbmUgaW4gbW9kYWxpdMOgIEFycmF5KSAqL1xyXG4gICAgQElucHV0KCkgQXJyYXltb2RlSXRlbXNQZXJQYWdlID0gbnVsbDtcclxuICAgIC8qKiBPZ2dldHRvIGRpIHNlbGV6aW9uZSBwZXIgbGEgbW9kYWxpdMOgIEFycmF5LCBjaGUgZGV2ZSBjb21wb3J0YXJzaSBjb21lIGxhIGNvbnRyb3BhcnRlIGluIG1vZGFsaXTDoCBWaWV3ICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlU2VsZWN0aW9uOiBJdGVtc1NlbGVjdGlvbjxhbnk+O1xyXG4gICAgLyoqIENvbG9ubmUgZGEgdmlzdWFsaXp6YXJlIGluIG1vZGFsaXTDoCBhcnJheSAqL1xyXG4gICAgcHVibGljIGFycmF5Q29sdW1uczogc3RyaW5nW10gPSBbXTtcclxuICAgIC8qKiBPcmRpbmUgZGVsbGUgY29sb25uZSBkYSB2aXN1YWxpenphcmUgaW4gbW9kYWxpdMOgIGFycmF5ICovXHJcbiAgICBwdWJsaWMgYXJyYXlDb2x1bW5PcmRlcmluZzogc3RyaW5nW10gPSBbXTtcclxuICAgIC8qKiBPcmRpbmFtZW50aSBBU0MtREVTQyBzdWxsZSBjb2xvbm5lIGluIG1vZGFsaXTDoCBhcnJheSAqL1xyXG4gICAgcHVibGljIGFycmF5T3JkZXJzOiBBcHBPcmRlcmluZ1tdID0gW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBWYXJpYWJpbGUgY2hlIHNlcnZlIGEgZ2VzdGlyZSBpbCBtb21lbnRvIGluIGN1aSBsJ2VzLXRhYmxlIGFnZ2lvcm5hIGxhIHBhZ2luYXppb25lIChwdWxzYW50aSBlY2MpLlxyXG4gICAgICogRXNzZW5kbyBvcGVyYXppb25pIGNvbXVucXVlIGNvc3Rvc2UgbGUgZWZmZXR0dW8gc29sbyBzdSBiaW5kaW5nIGVzdGVybmksIG5vbiBzdSByZXdyaXRlIGdlbmVyYXRpIGludGVybmFtZW50ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGludGVybmFsV3JpdGVDYWxsID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWNoZSBjaGUgY29udGVycsOgIHR1dHRlIGxlIHJpY2VyY2hlIGVmZmV0dHVhdGUgc3UgZ3J1cHBpIGRpdmVyc2kgZGFsIHByaW1vIGUgc3UgZWxlbWVudGkgY29udGVudXRpIG5laSBncnVwcGkuXHJcbiAgICAgKiBJbiBjYXNvIGRpIGNhbWJpIGRpIG9yZGluYW1lbnRvIGRlbGxlIGNvbG9ubmUgZGl2ZXJzZSBkYWxsYSBwcmltYSB0dXR0ZSBsZSBjaGlhbWF0ZSBmYXR0ZSBkYWwgc2Vjb25kbyBsaXZlbGxvIGluIHBvaSBkZXZvbm8gZXNzZXJlIHJpZXNlZ3VpdGUgc2Vjb25kbyBsYSBzZWd1ZW50ZSBsb2dpY2E6XHJcbiAgICAgKiBcclxuICAgICAqIFxyXG4gICAgICogKipDYW1iaW8gb3JkaW5hbWVudG8gc3VsIHByaW1vIGdydXBwbyoqOiByZWxvYWQgY29tcGxldG8sIG5vbiBtaSBvY2N1cG8gZGkgcmlwdWxpcmUgZ2xpIGVsZW1lbnRpIGJpbmRhdGkgaW4gYWxjdW4gbW9kb1xyXG4gICAgICogXHJcbiAgICAgKiAqKkNhbWJpbyBvcmRpbmFtZW50byBzdWxsYSBjb2xvbm5hIHJlbGF0aXZhIGFsbCdOLWVzaW1vIGdydXBwbyoqOiByZWxvYWQgY29tcGxldG8gZGVsIGNvbnRlbnV0byBkZWkgZ3J1cHBpIHByZWNlZGVudGksIHJpcHVsZW5kbyBwcmVjZWRlbnRlbWVudGUgXHJcbiAgICAgKiB0dXR0aSBnbGkgZWxlbWVudGkgY29uICoqX2dyb3VwbGV2ZWwqKiA9IE5cclxuICAgICAqIFxyXG4gICAgICogKipDYW1iaW8gb3JkaW5hbWVudG8gc3UgdW5hIGNvbG9ubmEgbm9uIHJhZ2dydXBwYXRhKio6IHJlbG9hZCBjb21wbGV0byBwZXIgdHV0dGkgaSBncnVwcGkgZmluYWxpIGFwZXJ0aSwgZGV2byBwcmVjZWRlbnRlbWVudGUgcmlwdWxpcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIGNvbiAqKl9pdGVtKiogPSB0cnVlXHJcbiAgICAgKiBcclxuICAgICAqIEFsdHJpIGV2ZW50aSBub24gZG92cmViYmVybyByYXBwcmVzZW50YXJlIHByb2JsZW1pOlxyXG4gICAgICogLSBTZWxlemlvbmU6IG5vbiBjYW1iaWEgbnVsbGFcclxuICAgICAqIC0gUGFnaW5hemlvbmU6IGNhbWJpYSBhIGxpdmVsbG8gcm9vdCBxdWluZGkgdmllbmUgcmljYXJpY2F0byB0dXR0byBjb211bnF1ZSwgc3Rlc3NvIHZhbGUgcGVyIGxlIHBhZ2luYXppb25pIGludGVybmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZTogeyBwYXRoOiBzdHJpbmcsIHJvdXRlOiBHcm91cFJvdXRlRnJhZ21lbnRbXSwgdmlldzogQXBwU2VhcmNoPGFueT4sIGdyb3VwX2NvbHVtbjogc3RyaW5nIH1bXSA9IFtdO1xyXG5cclxuICAgIC8qKiBWYXJpYWJpbGUgZCdhcHBvZ2dpbyBwZXIgY2FwaXJlIHNlIGMnw6ggYmlzb2dubyBkaSByaS1lZmZldHR1YXJlIHVuYSByaWNlcmNhIG8gbWVubyAqL1xyXG4gICAgcHJpdmF0ZSBSZXNlYXJjaE5lZWRlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgLyoqIENvbG9ubmUgdmlzaWJpbGkgZGVsbGEgdmlzdGEgYXR0dWFsZS4gVmFsb3JpenphdG8gZGkgZGVmYXVsdCBhbCBudW1lcm8gbWFzc2ltbyBkaSBjb2xvbm5lIHN1cHBvcnRhdGUgZGFsbGEgdGFiZWxsYSBwZXIgbGUgY2FzaXN0aWNoZSBpbiBhc3NlbnphIGRpIGN1c3RvbSBjZWxscyAqL1xyXG4gICAgcHVibGljIENvbHVtbnM6IHsgVmlzaWJpbGU6IG51bWJlciwgVmlzaWJsZVVucGlubmVkOiBudW1iZXIsIEdsb2JhbDogbnVtYmVyIH0gPSB7IFZpc2liaWxlOiAxMDAsIFZpc2libGVVbnBpbm5lZDogMTAwLCBHbG9iYWw6IDEwMCB9O1xyXG4gICAgLyoqIEluIGNhc28gZGkgUm93IEdyb3VwaW5nIHF1aSB2aWVuZSBzYWx2YXRhIGxhIHZpc3RhIHByaW5jaXBhbGUgZGVpIGdydXBwaSBiYXNlICovXHJcbiAgICBwdWJsaWMgTWFpbkdyb3VwVmlldzogQXBwU2VhcmNoPGFueT4gPSBudWxsO1xyXG4gICBcclxuICAgIC8qKiBDb250ZWdnaW8gYmFzZSBkZWdsaSBvZ2dldHRpLiBJbiBtb2RhbGl0w6Agbm9ybWFsZSB2aWVuZSByZXNldHRhdG8gYWQgb2duaSBudW92YSBWaWV3IGluc2VyaXRhLCBpbiBtb2RhbGl0w6AgUm93R3JvdXBpbmcgdmllbmUgcmVzZXR0YXRvIHNvbG8gYWQgdW5hIG51b3ZhIFZpZXcgZGkgbGl2ZWxsbyBcIjBcIiAqL1xyXG4gICAgcHVibGljIEJhc2VJdGVtc0NvdW50ID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIGNpIHNvbm8gZGVsbGUgY29sb25uZSBwaW5uYXRlIGUgdmlzaWJpbGkuIFNlcnZlIHBlciBwb3RlciBzZXR0YXJlIHR1dHRlIGxlIGNvbG9ubmUgcHJpbWEgY2hlIGFycml2aW5vIGRhdGkgYSBwaW5uZWQqL1xyXG4gICAgcHVibGljIEhhc1Bpbm5lZENvbHVtbnM6IGJvb2xlYW5cclxuICAgIC8qKiBMYXJnaGV6emEgY2FsY29sYXRhIGRlbCBjb250YWluZXIgZGVsbGUgY29sb25uZSBwaW5uYXRlICovXHJcbiAgICBwdWJsaWMgUGlubmVkQ29udGFpbmVyV2lkdGg6IG51bWJlcjtcclxuICAgIC8qKiBJbmRpY2Egc2Ugbm9ub3N0YW50ZSBzaWFtbyBpbiBtb2RhbGl0w6AgYXJyYXkgc29ubyBzdGF0aSBpbmRpdmlkdWF0aSBkZWkgZ3J1cHBpLiBJbiB0YWwgY2FzbyBlcy10YWJsZSBzaSBjb21wb3J0YSBkYSBwc2V1ZG8gYmFja2VuZCBlZCBlZmZldHR1YSBsZSBhZ2dyZWdhemlvbmkgZSByYWdncnVwcGFtZW50aSBjb21wbGV0YW1lbnRlIGxhdG8gY2xpZW50ICovXHJcbiAgICBwdWJsaWMgQXJyYXlHcm91cGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBPcHppb25pIGRpIHBhZ2luYXppb25lICovXHJcbiAgICBwdWJsaWMgUGFnZXJPcHRpb25zOiB7IFBhZ2VyQ291bnQ6IG51bWJlciwgU2hvd0NvdW50OiBib29sZWFuLCBTaG93UGFnaW5nOiBib29sZWFuLCBVc2VzVmlldzogYm9vbGVhbiwgVmlldzogYW55LCBSZWFkeTogYm9vbGVhbiwgU2VhcmNoZXM6ICdpdGVtcycgfCAnZ3JvdXBzJyB9ID1cclxuICAgICAgICB7IFBhZ2VyQ291bnQ6IG51bGwsIFNob3dDb3VudDogdHJ1ZSwgU2hvd1BhZ2luZzogdHJ1ZSwgVXNlc1ZpZXc6IHRydWUsIFZpZXc6IG51bGwsIFJlYWR5OiBmYWxzZSwgU2VhcmNoZXM6ICdpdGVtcycgfTtcclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIG5nT25Jbml0KCkge1xyXG4gICAgICAgIC8vUGVyIHBvdGVyIGNhbWJpYXJlIGlsIGxheW91dCBpbiBiYXNlIGFsIGxpdmVsbG8gZ2VyYXJjaGljbyBpbCBjb21wb25lbnRlIGRldmEgYXZlcmUgaWwgcGllbm8gY29udHJvbGxvIGRpIG9nbmkgY2VsbGEsXHJcbiAgICAgICAgLy9jaGUgY29uIHNvbG8gbGEgcHJvaWV6aW9uZSAoc2VuemEgY2VsbGUgY3Vzb3RtKSBub24gw6ggZGlzcG9uaWJpbGVcclxuICAgICAgICBpZiAodGhpcy5IaWVyYXJjaHkgJiYgIXRoaXMuVXNlQ3VzdG9tQ2VsbHMpXHJcbiAgICAgICAgICAgIHRocm93IFwiRXMtdGFibGUgZXJyb3I6IFBlciBwb3RlciB1dGlsaXp6YXJlIGwnZXMtdGFibGUgY29uIFtIaWVyYXJjaHldPVxcXCJ0cnVlXFxcIiDDqCByaWNoaWVzdG8gYW5jaGUgW1VzZUN1c3RvbUNlbGxzXT1cXFwidHJ1ZVxcXCJcIjtcclxuXHJcbiAgICAgICAgLy8gY2xpY2sgZGVzdHJvIHN1IHVuYSByaWdhIGNvbiBzZWxlemlvbmUgYXR0aXZhOiBUaXJvIGZ1b3JpIGlsIGNvbnRleHQgbWVudSBlIHNlbGV6aW9uZSBsJ2VsZW1lbnRvIGNvcnJlbnRlXHJcbiAgICAgICAgdGhpcy5jdHhNZW51U3Vic2NyaXB0aW9uID0gKHRoaXMuQ29udGV4dE1lbnUgfHwgdGhpcy50YWJsZUVtcHR5TWVudSkub3Blbi5zdWJzY3JpYmUodCA9PiB7XHJcbiAgICAgICAgICAgIC8vIEdydXBwaSB2YSBiZW5lLCBvZ2dldHRpIHB1cmUsIG1hIHNlcGFyYXRvcmkgZnJhIGdydXBwaSBwcm9wcmlvIG5vLi4uXHJcbiAgICAgICAgICAgIGlmICh0Lml0ZW0uX3NlcCkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgbGV0IHNob3VsZEVtaXQgPSAhdC5pdGVtLl9zZWxlY3RlZDtcclxuXHJcbiAgICAgICAgICAgIHQuaXRlbS5fc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB2YXIgaXRlbVNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uX0guaGFuZGxlSXRlbXNTZWxlY3Rpb24oW3QuaXRlbV0pO1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzaG91bGRFbWl0KVxyXG4gICAgICAgICAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICAvLyBTZSB1dGlsaXp6byBsYSBuZXcgc3BpY3kgbW9kZSBkZWR1Y28gdHV0dGkgaSBwYXJhbWV0cmkgZGkgbGF2b3JvIHBvc3NpYmlsaSBhbCBjYXJpY2FtZW50byBkZWxsYSB0YWJlbGxhXHJcbiAgICAgICAgLy8gVmVuZ29ubyBzb3ZyYXNjcml0dGUgc29sbyBsZSBwcm9wcmlldMOgIG5vbiBpbXBvc3RhdGUgZGFsbCd1dGVudGVcclxuICAgICAgICBpZiAodGhpcy5Fc1Rkc0RpcmVjdGl2ZSAmJiB0aGlzLkVzVGRzRGlyZWN0aXZlLmxlbmd0aCA+IDAgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZSAmJiB0aGlzLkVzVGhzRGlyZWN0aXZlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuVXNlQ3VzdG9tQ2VsbHMgPT0gbnVsbCkgdGhpcy5Vc2VDdXN0b21DZWxscyA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLkhpZGRlbkNvbHVtbnMgPT0gbnVsbCAmJiB0aGlzLlVzZUN1c3RvbUNlbGxzKSB0aGlzLkhpZGRlbkNvbHVtbnMgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5Db2x1bW5zT3JkZXJpbmcgPT0gbnVsbCAmJiB0aGlzLlVzZUN1c3RvbUNlbGxzKSB0aGlzLkNvbHVtbnNPcmRlcmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLk9yZGVyQnlDb2x1bW4gPT0gbnVsbCAmJiB0aGlzLlVzZUN1c3RvbUNlbGxzKSB0aGlzLk9yZGVyQnlDb2x1bW4gPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5TZWxlY3RBbGwgPT0gbnVsbCAmJiB0aGlzLlNlbGVjdGlvbikgdGhpcy5TZWxlY3RBbGwgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5TaGlmdENsaWNrID09IG51bGwgJiYgdGhpcy5TZWxlY3Rpb24pIHRoaXMuU2hpZnRDbGljayA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3R4TWVudVN1YnNjcmlwdGlvbilcclxuICAgICAgICAgICAgdGhpcy5jdHhNZW51U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBhc3luYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgbGV0IG5ld1NlYXJjaFZpZXcgPSBjaGFuZ2VzWydTZWFyY2hWaWV3J107XHJcbiAgICAgICAgaWYgKG5ld1NlYXJjaFZpZXcgJiYgdGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLnV0aWxpdGllc19ILmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5TZWFyY2hWaWV3LnBhZ2UsIHRoaXMuU2VhcmNoVmlldy5wYWdlcyB8fCAxLCB0aGlzLlNlYXJjaFZpZXcuaXRlbXMubGVuZ3RoLCB0aGlzLlNlYXJjaFZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbik6IHZvaWQgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuKTogdm9pZCB7IH1cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjaGFuZ2VkKCkgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLlZpZXcpOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHJvcGFnYXRlQ2hhbmdlID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgd3JpdGVWYWx1ZShvYmopOiB2b2lkIHtcclxuICAgICAgICB0aGlzLlZpZXcgPSBvYmogPyBvYmogOiBudWxsO1xyXG5cclxuICAgICAgICAvLyBNaSDDqCBhcnJpdmF0YSBsJ0FwcFNlYXJjaCBxdWluZGkgZGkgc2ljdXJvIG5vbiBobyB1bmEgcmljZXJjYSBpbiBwcm9ncmVzc1xyXG4gICAgICAgIHRoaXMucmVzZWFyY2hJblByb2dyZXNzID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5WaWV3ICYmICF0aGlzLlNlYXJjaFZpZXcpIHtcclxuICAgICAgICAgICAgLy8gU3UgdmlldyBudWxsYSBldml0byBkaSBmYXJlIHByZXNzb2Now6kgcXVhbHNpYXNpIGNvc2EuIFNlIGFycml2YSB1biBudWxsIGRldm8gYW5jaGUgYXNzaWN1cmFybWkgZGkgbm9uIG1vc3RyYXJlIG51bGxhXHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLlRNUEJvdW5kU291cmNlIHx8IFtdO1xyXG5cclxuICAgICAgICAgICAgLy8gUGVyIGVzc2VyZSBzaWN1cm8gY2hlIGRvcG8gdW4gYmluZCBkaSBvZ2dldHRpIGxhIGVzLXRhYmxlIGFnZ2lvcm5pIGxhIGdyYWZpY2FcclxuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIHBlciBzYmFnbGlvIGwnb2dnZXR0byBjaGUgbWkgYXJyaXZhIG5vbiDDqCB0aXBpenphdG8gKGluc3RhbmNlb2YgQXBwU2VhcmNoIHJlc3RpdHVpc2NlIGZhbHNlIGFuY2hlIHNlIMOoIGRlbCB0aXBvIGdpdXN0bylcclxuICAgICAgICAvLyBsbyBjb3JyZWdnby0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAgICAgaWYgKHRoaXMuVmlldyAmJiB0eXBlb2YgKHRoaXMuVmlldyBhcyBhbnkpLnJlc3VsdCAhPSAndW5kZWZpbmVkJyAmJiAhKHRoaXMuVmlldyBpbnN0YW5jZW9mIFJlcG9ydERlZmluaXRpb24pKSBcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBSZXBvcnREZWZpbml0aW9uKCk7XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHR5cGVvZiAodGhpcy5WaWV3IGFzIGFueSkuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgIT0gJ3VuZGVmaW5lZCcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpKSBcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBBcHBTZWFyY2goKTtcclxuICAgICAgICBlbHNlIGlmICh0aGlzLlNlYXJjaFZpZXcgJiYgdHlwZW9mICh0aGlzLlNlYXJjaFZpZXcgYXMgYW55KS5pdGVtc3BlcnBhZ2VvdmVycmlkZSAhPSAndW5kZWZpbmVkJyAmJiAhKHRoaXMuU2VhcmNoVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkpIFxyXG4gICAgICAgICAgICAodGhpcy5TZWFyY2hWaWV3IGFzIGFueSkuX19wcm90b19fID0gbmV3IEFwcFNlYXJjaCgpO1xyXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuVmlldyAmJiB0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSB7XHJcbiAgICAgICAgICAgIC8vIFNlIG1pIGFycml2YSB1bmEgcmVwb3J0IGRlZmluaXRpb24gdnVvbCBkaXJlIGNoZSBwb3RyZWkgYXZlcmUgZGVpIHJpc3VsdGF0aSBkYSB2aXN1YWxpenphcmVcclxuICAgICAgICAgICAgdGhpcy5zZXRNb2RlKCdyZXBvcnQnKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuUmVwb3J0VmFsdWVzID0gdGhpcy5WaWV3LnJlc3VsdDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuUmVwb3J0VmFsdWVzKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXBvcnRNb2RlX0gucmV2aWV3UmVwb3J0QmluZGluZ3MoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHRoaXMuVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkge1xyXG4gICAgICAgICAgICAvLyBTZSBjYW1iaWEgbCdvZ2dldHRvIGludGVybyBzaWduaWZpY2EgY2hlIGhvIHJpbWFuZGF0byBsYSByaWNlcmNhXHJcbiAgICAgICAgICAgIHRoaXMuc2V0TW9kZSgndmlldycpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nID0gKHRoaXMuVmlldy5yZXF1ZXN0ZWRncm91cHM/Lmxlbmd0aCB8fCAwKSA9PSAwO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgdmVuZ28gZGEgdW5hIHJpY2VyY2EgaW50ZXJuYSBtYW50ZW5nbyBsbyBzdGF0byBkaSBzZWxlemlvbmUgcHJlY2VkZW50ZSAocXVpbmRpIHN1IGNhbWJpbyBwYWdpbmEsIGNhbWJpbyBpcHAsIGVjYy4uLilcclxuICAgICAgICAgICAgLy8gc2UgaW52ZWNlIGwndXRlbnRlIGhhIGZhdHRvIHVuYSByaWNlcmNhIGx1aSAocXVpbmRpIGNhbWJpYW5kbyBmaWx0cmkpLCBzZWNjbyBsZSBpbmZvIGRpIHNlbGV6aW9uZVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuVmlldy5zZWxlY3Rpb24gfHwgKCF0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ICYmIGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nKSB8fCAhdGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25fSC5jbGVhclNlbGVjdGlvbkNhY2hlcygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3LnNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuVmlldy5zZWxlY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvLyBSZWN1cGVybyBQcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm5nQ29udHJvbC5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgcXVlc3RhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5wcmVmU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZlNlcnZpY2UucmV0cmlldmU8eyBjb2x1bW5zOiBzdHJpbmdbXSwgY29sdW1uX29yZGVyaW5nOiBzdHJpbmdbXSB9Pig8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUpLnN1YnNjcmliZShwcmVmcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5WaWV3LmNvbHVtbnMgPSBwcmVmcy5jb2x1bW5zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5WaWV3LmNvbHVtbl9vcmRlcmluZyA9IHByZWZzLmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBMYSBwYWdpbmF6aW9uZSBkZXZvIGZhcmxhIHNvbGFtZW50ZSBxdWFuZG8gcmljaGllZG8gbyB1biBncnVwcG8gcHJpbmNpcGFsZSAoc2Ugc29ubyBpbiByb3cgZ3JvdXBpbmcpIG8gc2Ugbm9uIHJpY2hpZWRvIGdydXBwaSAoaW4gdHV0dGkgbGdpIGFsdHJpIGNhc2kpXHJcbiAgICAgICAgICAgIGlmIChmaXJzdEl0ZW1Hcm91cE9yTm9Hcm91cGluZylcclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMudXRpbGl0aWVzX0guZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlZpZXcucGFnZSwgdGhpcy5WaWV3LnBhZ2VzIHx8IDEsIHRoaXMuVmlldy5pdGVtcy5sZW5ndGgsIHRoaXMuVmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuVmlldyAmJiAodGhpcy5WaWV3Lmxlbmd0aCAhPSBudWxsICYmIHRoaXMuVmlldy5sZW5ndGggIT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldE1vZGUoJ2FycmF5Jyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuVXNlU2VsZWN0aW9uQ2FjaGUgfHwgIXRoaXMuYXJyYXltb2RlU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbl9ILmNsZWFyU2VsZWN0aW9uQ2FjaGVzKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdCh0aGlzLmFycmF5bW9kZVNlbGVjdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFJlY3VwZXJvIFByZWZlcmVuY2VcclxuICAgICAgICAgICAgaWYgKHRoaXMuU2F2ZVByZWZlcmVuY2VzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubmdDb250cm9sLm5hbWUpXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgYXZlcmUgdW4gJ25hbWUnIHBlciBxdWVzdGEgdGFiZWxsYVwiKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCF0aGlzLnByZWZTZXJ2aWNlKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGNoZSBpbCBwYWNjaGV0dG8gQGVzZmFlbnphL3ByZWZlcmVuY2VzIHNpYSBpbnN0YWxsYXRvXCIpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmU2VydmljZS5yZXRyaWV2ZTx7IGNvbHVtbnM6IHN0cmluZ1tdLCBjb2x1bW5fb3JkZXJpbmc6IHN0cmluZ1tdIH0+KDxzdHJpbmc+dGhpcy5uZ0NvbnRyb2wubmFtZSkuc3Vic2NyaWJlKHByZWZzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFycmF5Q29sdW1ucyA9IHByZWZzLmNvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFycmF5Q29sdW1uT3JkZXJpbmcgPSBwcmVmcy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuU2VhcmNoVmlldylcclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMudXRpbGl0aWVzX0guZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlNlYXJjaFZpZXcucGFnZSwgdGhpcy5TZWFyY2hWaWV3LnBhZ2VzIHx8IDEsIHRoaXMuU2VhcmNoVmlldy5pdGVtcy5sZW5ndGgsIHRoaXMuU2VhcmNoVmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5WaWV3ICYmICEodGhpcy5WaWV3IGluc3RhbmNlb2YgUmVwb3J0RGVmaW5pdGlvbikpXHJcbiAgICAgICAgICAgIHRoaXMuZmluYWxpemVDb250ZXh0KCk7XHJcblxyXG4gICAgICAgIHRoaXMucG9zdEJvdW5kU291cmNlQ2FsY3VsYXRpb24oKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN1Y2Nlc3NpdmFtZW50ZSBhbCBiaW5kIGRlbCBudW92byBpbnB1dCBxdWVzdGEgZnVuemlvbmUgc2kgb2NjdXBhIGRpIGZpbmFsaXp6YXJlIHR1dHRpIGkgcGFyYW1ldHJpIGRpIGZ1bnppb25hbWVudG8gZGVsbCdlcy10YWJsZSBcclxuICAgICAqIGluIGJhc2UgYSBJbnB1dCAtIE1vZGVsbG8sIGUgcXVhbHNpYXNpIGFsdHJhIGNvc2EgcG9zc2Egc2VydmlyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGZpbmFsaXplQ29udGV4dCgpIHtcclxuICAgICAgICBsZXQgdmlld0Nhc3RlZCA9IHRoaXMuVmlldyBhcyBBcHBTZWFyY2g8YW55PjtcclxuXHJcbiAgICAgICAgLypcclxuICAgICAgICAgKlVzbyBsYSB0ZWNuaWNhIGRpIEVuZGxlc3NTY3JvbGwgc2UgbGEgdmFyaWFiaWxlIHJlbGF0aXZhIMOoIGF0dGl2YSBlIHNlXHJcbiAgICAgICAgICogMSkgSG8gdW4gQXJyYXksIG9wcHVyZVxyXG4gICAgICAgICAqIDIpIEhvIHVuIEFwcFNlYXJjaCBjaGUgc3RhIGNlcmNhbmRvIGNvbiBwYWdpbmF6aW9uZSBcIlR1dHRvXCIsIG9wcHVyZVxyXG4gICAgICAgICAqIDMpIEhvIHVuIEFwcFNlYXJjaCBjaGUgc3RhIGNlcmNhbmRvIGNvbiBwYWdpbmF6aW9uZSBkaXZlcnNhIGRhIFwiVHV0dG9cIiBtYSBjb24gbGEgdmFyaWFiaWxlIEVuZGxlc3NTY3JvbGxPbmx5Rm9yQWxsIGEgZmFsc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBsZXQgaXNBcHBTZWFyY2hXaXRoSXBwTWF4ID0gdGhpcy52aWV3TW9kZSAmJiB2aWV3Q2FzdGVkLml0ZW1zcGVycGFnZW92ZXJyaWRlID09IHRoaXMuZGVmYXVsdEFsbFBhZ2VPdmVycmlkZTtcclxuICAgICAgICBsZXQgaXNBcHBTZWFyY2hOb01heElwcCA9IHRoaXMudmlld01vZGUgJiYgdmlld0Nhc3RlZC5pdGVtc3BlcnBhZ2VvdmVycmlkZSAhPSB0aGlzLmRlZmF1bHRBbGxQYWdlT3ZlcnJpZGU7XHJcbiAgICAgICAgdGhpcy5Vc2VFbmRsZXNzc2Nyb2xsID0gdGhpcy5FbmRsZXNzU2Nyb2xsICYmICh0aGlzLmFycmF5TW9kZSB8fCBpc0FwcFNlYXJjaFdpdGhJcHBNYXggfHwgKGlzQXBwU2VhcmNoTm9NYXhJcHAgJiYgIXRoaXMuRW5kbGVzc1Njcm9sbE9ubHlGb3JBbGwpKTtcclxuXHJcbiAgICAgICAgbGV0IGhhc1Jvd0dyb3VwcyA9ICh2aWV3Q2FzdGVkLmdyb3VwaW5ncyAmJiB2aWV3Q2FzdGVkLmdyb3VwaW5ncy5maWx0ZXIodCA9PiAhdC5hZ2dyZWdhdGlvbikubGVuZ3RoID4gMCkgfHwgKHRoaXMuYXJyYXlNb2RlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUuc29tZSh0ID0+IHQudGhHcm91cCkpO1xyXG5cclxuICAgICAgICAvLyBTZSBobyBkZWkgZ3J1cHBpIGluIG1vZGFsaXTDoCBhcnJheSBkZXZvIHNpc3RlbWFyZSB1biBwbycgZGkgdmFyaWFiaWxpIGNoZSBkaXZlbnRhbm8gaW5zZW5zYXRlXHJcbiAgICAgICAgaWYgKHRoaXMuYXJyYXlNb2RlICYmIGhhc1Jvd0dyb3VwcylcclxuICAgICAgICAgICAgdGhpcy5Vc2VBcnJheU1vZGVQYWdpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gUmllbXBpbWVudG8gZGVsbGEgVE1QQm91bmRTb3VyY2UgY29uIGdsaSBvZ2dldHRpIGNoZSB2ZXJyYW5ubyBwb2kgbW9zdHJhdGkgYWQgaW50ZXJmYWNjaWFcclxuICAgICAgICBpZiAodGhpcy5Vc2VFbmRsZXNzc2Nyb2xsICYmICFoYXNSb3dHcm91cHMpIHtcclxuICAgICAgICAgICAgdGhpcy5hZGRlZFNsaWNlcyA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU3ViU291cmNlcyA9IHRoaXMuaXRlbXNfSC5nZXRJdGVtU2xpY2VzKCk7XHJcbiAgICAgICAgICAgIGxldCBmaXJzdFN1YiA9IHRoaXMuYm91bmRTdWJTb3VyY2VzWzBdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZSA9IGZpcnN0U3ViID8gZmlyc3RTdWIgOiBbXTtcclxuICAgICAgICAgICAgaWYgKGZpcnN0U3ViKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZFNsaWNlcy5wdXNoKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuVE1QQm91bmRTb3VyY2UgPSB0aGlzLml0ZW1zX0guZ2V0SXRlbXNCeU1vZGUoZmFsc2UsICF0aGlzLmludGVybmFsV3JpdGVDYWxsKTtcclxuXHJcbiAgICAgICAgLy8gU2UgaG8gdW5hIGdlcmFyY2hpYSwgYXNzZWdubyBpIGxpdmVsbGkgZ2VyYXJjaGljaSBhbGxhIFRNUEJvdW5kU291cmNlXHJcbiAgICAgICAgaWYgKHRoaXMuSGllcmFyY2h5ICYmICFoYXNSb3dHcm91cHMpXHJcbiAgICAgICAgICAgIHRoaXMuaGllcmFyY2h5TW9kZV9ILmFzc2lnbkhpZXJhcmNoeUxldmVscyh0aGlzLlRNUEJvdW5kU291cmNlKTtcclxuXHJcbiAgICAgICAgLy8gTCdoYXNoaW5nIGRlZ2xpIG9nZ2V0dGkgbG8gZmFjY2lvIGEgcHJlc2NpbmRlcmVcclxuICAgICAgICB0aGlzLnV0aWxpdGllc19ILmNhbGN1bGF0ZUhhc2godGhpcy5UTVBCb3VuZFNvdXJjZSk7XHJcblxyXG4gICAgICAgIC8vIEFzc2Vnbm8gYSB1bmEgdmFyaWFiaWxlIG1pYSBsJ2V2ZW50dWFsZSBvdmVycmlkZSBwZXIgbGEgY2xhc3NlIGRlbGxhIHJpZ2FcclxuICAgICAgICAvLyBTZSBwb2kgc29ubyBpbiBtb2RhbGl0w6AgZ2VyYXJjaGljYSBpbmlldHRvIGFuY2hlIGxhIGNsYXNzZSBwZXIgbGEgY29uZmlndXJhemlvbmUgZGVsIGxpdmVsbG8gZGVsbGEgcmlnYVxyXG4gICAgICAgIGlmICgodGhpcy5UTVBCb3VuZFNvdXJjZSAmJiB0aGlzLlJvd0NsYXNzQXNzaWduZXIpIHx8IHRoaXMuSGllcmFyY2h5KSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLlRNUEJvdW5kU291cmNlW2ldO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5fcm93Q2xhc3MgPSB0aGlzLlJvd0NsYXNzQXNzaWduZXIgPyB0aGlzLlJvd0NsYXNzQXNzaWduZXIoaXRlbSkgOiBcIlwiO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5fcm93Q2xhc3MgKz0gdGhpcy5IaWVyYXJjaHkgPyBcIiBlc3Qtcm93LWx2bC1cIiArIGl0ZW0uX2xldmVsIDogXCJcIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogR2VuZXJhIGxlIGluZm9ybXppb25pIGRpIHBhZ2luYXppb25lIHBlciBsYSB2aXN0YSBnbG9iYWxlIGRlbGwnZXMtdGFibGUgKi9cclxuICAgIHByaXZhdGUgc2V0dXBQYWdpbmdJbmZvcm1hdGlvbnMoKSB7XHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gIXRoaXMuSGlkZVBhZ2luZ0NvdW50O1xyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSAmJiB0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyAmJiAhdGhpcy5TZWFyY2hWaWV3KSB7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSAoPGFueVtdPnRoaXMuVmlldykubGVuZ3RoIHx8IDA7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dQYWdpbmcgPSAhdGhpcy5IaWRlUGFnaW5nICYmIHRoaXMuVmlldy5sZW5ndGggPiAxMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldyA9IHRoaXMuVmlldztcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVXNlc1ZpZXcgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5hcnJheU1vZGUgJiYgKCF0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyB8fCB0aGlzLlNlYXJjaFZpZXcpKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcgPSB0aGlzLlNlYXJjaFZpZXdcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSB0aGlzLlNlYXJjaFZpZXcub2JqZWN0Y291bnQgfHwgMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5QYWdlckNvdW50ID0gKDxhbnlbXT50aGlzLlZpZXcpLmxlbmd0aCB8fCAwXHJcblxyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93Q291bnQgPSB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93Q291bnQgfHwgKHRoaXMuVmlldyAmJiB0aGlzLlZpZXcubGVuZ3RoKSB8fCAodGhpcy5TZWFyY2hWaWV3ICYmIHRoaXMuU2VhcmNoVmlldy5vYmplY3Rjb3VudCAmJiB0aGlzLlNlYXJjaFZpZXcub2JqZWN0Y291bnQgIT0gLTEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIGxldCB0bXBWaWV3ID0gdGhpcy5NYWluR3JvdXBWaWV3IHx8IHRoaXMuVmlldztcclxuICAgICAgICAgICAgbGV0IGNvdW50ID0gdG1wVmlldz8uZ3JvdXBjb3VudCB8fCB0bXBWaWV3Py5vYmplY3Rjb3VudDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2VhcmNoZXMgPSB0bXBWaWV3Py5ncm91cGNvdW50ICE9IG51bGwgJiYgdG1wVmlldz8uZ3JvdXBjb3VudCAhPSB1bmRlZmluZWQgPyAnZ3JvdXBzJyA6ICdpdGVtcyc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSBjb3VudCB8fCAwO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5WaWV3ID0gdG1wVmlldztcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0bXBWaWV3ICYmIGNvdW50ICYmIGNvdW50ICE9IC0xKTtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd1BhZ2luZyA9ICF0aGlzLkhpZGVQYWdpbmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmVwb3J0TW9kZSkge1xyXG4gICAgICAgICAgICBsZXQgcnZjID0gdGhpcy5SZXBvcnRWYWx1ZXMuY291bnQ7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcgPSB0aGlzLlZpZXc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSBydmMgJiYgcnZjID09IC0xID8gdGhpcy5SZXBvcnRWYWx1ZXMucm93cy5sZW5ndGggOiBydmMgJiYgcnZjID4gMCA/IHRoaXMuUmVwb3J0VmFsdWVzLmNvdW50IDogMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0aGlzLlZpZXcgJiYgdGhpcy5WaWV3Lm9iamVjdGNvdW50ICYmIHRoaXMuVmlldy5vYmplY3Rjb3VudCAhPSAtMSk7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dQYWdpbmcgPSAhdGhpcy5IaWRlUGFnaW5nICYmIHRoaXMuVmlldy5wYWdpbmdhdmFpbGFibGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZXN0aXNjZSBsJ2VuZGxlc3Mgc2Nyb2xsIGUgaW4gYmFzZSBhIHF1YW50byBsYSB0YWJlbGxhIMOoIHN0YXRhIHNjcm9sbGF0YSBhZ2dpdW5nZSBkZWdsaSBlbGVtZW50aSBleHRyYSBhICoqVE1QQm91bmRTb3VyY2UqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBlIEV2ZW50byBkaSBzY3JvbGwgZGVsIGJyb3dzZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uU2Nyb2xsKGU6IGFueSkge1xyXG4gICAgICAgIGxldCB0YWJsZVZpZXdIZWlnaHQgPSBlLnRhcmdldC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgbGV0IHRhYmxlU2Nyb2xsSGVpZ2h0ID0gZS50YXJnZXQuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgICAgIGxldCBzY3JvbGxMb2NhdGlvbiA9IGUudGFyZ2V0LnNjcm9sbFRvcDtcclxuICAgICAgICBsZXQgYnVmZmVyID0gMjAwO1xyXG5cclxuICAgICAgICBsZXQgbGltaXQgPSB0YWJsZVNjcm9sbEhlaWdodCAtIHRhYmxlVmlld0hlaWdodCAtIGJ1ZmZlcjtcclxuICAgICAgICBpZiAoc2Nyb2xsTG9jYXRpb24gPiBsaW1pdCkge1xyXG4gICAgICAgICAgICBsZXQgaW5kZXhUb0FkZCA9IE1hdGguZmxvb3IodGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGggLyAxMDApO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ib3VuZFN1YlNvdXJjZXNbaW5kZXhUb0FkZF0gJiYgdGhpcy5hZGRlZFNsaWNlcy5pbmRleE9mKGluZGV4VG9BZGQpID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEZXZvIHJpY29yZGFybWkgZGkgZmFyZSBsJ2hhc2ggZGVsIG51b3ZvIHBlenpvXHJcbiAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllc19ILmNhbGN1bGF0ZUhhc2godGhpcy5ib3VuZFN1YlNvdXJjZXNbaW5kZXhUb0FkZF0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2UuY29uY2F0KHRoaXMuYm91bmRTdWJTb3VyY2VzW2luZGV4VG9BZGRdKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkZWRTbGljZXMucHVzaChpbmRleFRvQWRkKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5wb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpOyB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBsYW5jaWF0byBkb3BvIGNoZSBsYSBzb3JnZW50ZSBkYXRpIMOoIHN0YXRhIGNvcnJldHRhbWVudGUgYmluZGF0YSwgc2kgb2NjdXBhIGRpIHJpY2FsY29sYXJlIHR1dHRvIGNpw7IgY2hlIHNlcnZlXHJcbiAgICAgKiBhbGwnZXMtdGFibGUgcGVyIHJlbmRlcml6emFyZSBpIHZhbG9yaSBkYSBtb3N0cmFyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHBvc3RCb3VuZFNvdXJjZUNhbGN1bGF0aW9uKCkge1xyXG4gICAgICAgIC8vIFJlc2V0dG8gdHV0dG8gdHJhbm5lIFJvd1REcyBlIFJvd1RIcyBwZXIgZXZpdGFyZSBmbGlja2VyaW5nLiBSb3dURHMgZSBSb3dUSHMgc2FyYW5ubyBtb2RpZmljYXRlIGFsbCdpbnRlcm5vIGRlbCBwcm9zc2ltbyBjaWNsbyBkaSBDRFxyXG4gICAgICAgIHRoaXMuUm93Q29udGV4dHMgPSBbXTtcclxuICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuRXNUaHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZS5sZW5ndGggPiAwICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Rkc0RpcmVjdGl2ZS5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICB0aGlzLmludGVybmFsUG9zdEJvdW5kU291cmNlKCk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuaW50ZXJuYWxQb3N0Qm91bmRTb3VyY2UoKTsgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBQZXIgcG90ZXIgZGlzdGluZ3VlcmUgbGUgY2hpYW1hdGUgYSBxdWVzdG8gbWV0b2RvOiBEb3BvIGlsIHNldFRpbWVvdXQgc2UgdXNvIGdsaSBFc1RkL0VzVGggdmVjY2hpLCBzZW56YSBpbCBzZXRUaW1lb3V0IHNlIHVzbyBsZSBudW92ZSBkaXJldHRpdmUgKi9cclxuICAgIHByaXZhdGUgaW50ZXJuYWxQb3N0Qm91bmRTb3VyY2UoKSB7XHJcbiAgICAgICAgbGV0IFZpZXcgPSB0aGlzLlZpZXc7XHJcbiAgICAgICAgbGV0IHRocyA9IHRoaXMuRXNUaHMgJiYgdGhpcy5Fc1Rocy5sZW5ndGggPiAwID8gdGhpcy5Fc1Rocy50b0FycmF5KCkgOiB0aGlzLkVzVGhzRGlyZWN0aXZlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUubGVuZ3RoID4gMCA/IHRoaXMuRXNUaHNEaXJlY3RpdmUudG9BcnJheSgpIDogW107XHJcbiAgICAgICAgbGV0IHRkcyA9IHRoaXMuRXNUZHMgJiYgdGhpcy5Fc1Rkcy5sZW5ndGggPiAwID8gdGhpcy5Fc1Rkcy50b0FycmF5KCkgOiB0aGlzLkVzVGRzRGlyZWN0aXZlICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUubGVuZ3RoID4gMCA/IHRoaXMuRXNUZHNEaXJlY3RpdmUudG9BcnJheSgpIDogW107XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBobyBjb2xvbm5lIGRpbmFtaWNoZSBtYSBzb25vIGluIG1vZGFsaXTDoCBkaW5hbWljYSAobG8gY2FwaXNjbyBwZXJjaMOpIGMnw6ggdW5hIHZpZXcgcGllbmEgZGkgZ2VuZXJpY2l0ZW0pIG1ldHRvIGlsIGRlZmF1bHQgZGVsbGUgY29sb25uZVxyXG4gICAgICAgIHRoaXMuZHluYW1pY01vZGVfSC5ldmVudHVhbGx5UmV2aWV3RHluYW1pY0NvbHVtbnMoKTtcclxuICAgICAgICB0aGlzLmJpbmREaXNwbGF5VG9Mb2FkZWRJdGVtc09yR3JvdXBzKFZpZXcpO1xyXG5cclxuICAgICAgICAvLyBRdWVzdG8gZGV2J2Vzc2VyZSBwZXIgZm9yemEgbGFuY2lhdG8gZG9wbyAqKmJpbmREaXNwbGF5VG9Mb2FkZWRJdGVtc09yR3JvdXBzKiogZGF0byBjaGUgw6ggbMOsIGNoZSBhbGN1bmUgY29zZSB2ZW5nb25vIHZhbG9yaXp6YXRlXHJcbiAgICAgICAgdGhpcy5zZXR1cFBhZ2luZ0luZm9ybWF0aW9ucygpO1xyXG5cclxuICAgICAgICAvLyBNb2x0ZSBjb3NlIHNvbm8gb3Z2aWFtZW50ZSBkaXNwb25pYmlsaSBzb2xvIGluIG1vZGFsaXTDoCBWaWV3XHJcbiAgICAgICAgaWYgKCh0aGlzLnZpZXdNb2RlIHx8IHRoaXMuYXJyYXlNb2RlKSAmJiB0aGlzLlVzZUN1c3RvbUNlbGxzKSB7XHJcbiAgICAgICAgICAgIGxldCB2aWV3ID0gdGhpcy52aWV3TW9kZSA/IFZpZXcgYXMgQXBwU2VhcmNoPGFueT4gOiBudWxsO1xyXG4gICAgICAgICAgICBsZXQgaXRlbXNBbmRHcm91cHMgPSB0aGlzLnZpZXdNb2RlID8gWy4uLih2aWV3Lml0ZW1zIHx8IFtdKSwgLi4uKHZpZXcuZ3JvdXBzIHx8IFtdKV0gOiBWaWV3IGFzIGFueVtdO1xyXG4gICAgICAgICAgICBsZXQgc2kgPSB0aGlzLnZpZXdNb2RlID8gdmlldy5zZWxlY3Rpb24gOiB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbjtcclxuICAgICAgICAgICAgLy8gTi5COiBSaXNwZXR0YXJlIGwnb3JkaW5lIGRpIHF1ZXN0ZSAzIG1hY3JvY2F0ZWdvcmllIMOoIFZJVEFMRVxyXG5cclxuICAgICAgICAgICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAgICAgICAgU2lzdGVtYXppb25pIGRpIFRILCBURCwgZSB2aXNpYmlsaXTDoCB2YXJpZSAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgIC8vIFByZXBhc3NhZ2dpbyBwZXIgdGlyYXJlIGZ1b3JpIHR1dHRlIGxlIGluZm8gdXRpbGkgc3VnbGkgaGVhZGVycyBpbiBtb2RvIGRhIG5vbiByaWNhY29sYXJzZWxpIHNlbXByZSBkb3BvXHJcbiAgICAgICAgICAgIGxldCBoSSA9IHRoaXMuY29sdW1uTWV0YWRhdGFfSC5ldmFsdWF0ZUhlYWRlcnNHcm91cGluZ0luZm9zKHRocyk7ICAgICAgICBcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIG1vZGFsaXTDoCBhcnJheSBub24gaG8gdW4gYmFja2VuZC4uLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc19ILmFycmF5TW9kZVJldmlld09yZGVyaW5ncygpICAgICAgICAgICAgICAgICAvLyAuLi4gcXVpbmRpIGdsaSBvcmRpbmFtZW50aSBsaSBkZXZvIGZhcmUgbGF0byBjbGllbnQsIGUgLi4uXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvd0dyb3VwaW5nX0guYXJyYXlNb2RlUmV2aWV3R3JvdXBpbmdzKGhJLmxlYWZzKTsgIC8vIC4uLiBpIHJhZ2dydXBwYW1lbnRpIGxpIGRldm8gZmFyZSBsYXRvIGNsaWVudFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0gucmV2aWV3Q29sdW1uc0xpc3QoaEkubGVhZnMpOyAgICAgICAgICAgICAgICAgICAgICAgLy8gQWdnaW9ybmEgbGEgbGlzdGEgZGVsbGUgY29sb25uZSBkYSBtb3N0cmFyZSBuZWxsYSBkaWFsb2cgcGVyIG9yZGluYW1lbnRvIGVjY1xyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0gubW92ZUZpeGVkQ29sdW1uc0F0VGhlQmVnaW5uaW5nKGhJLmxlYWZzLCB0ZHMpOyAgICAgLy8gU3Bvc3RvIHR1dHRlIGxlIGNvc2UgZml4ZWQgYWxsJ2luaXppbyBpbiBtb2RvIGNoZSBsYSBjcmVhemlvbmUgZGkgdGggZSB0ZCBzaWEgcGnDuSBzbmVsbGEgKFV0aWxpenphIGxlIENvbHVtbnNMaXN0LCBxdWluZGkgZGV2J2Vzc2VyZSByaWNoaWFtYXRhIFBJUk1BIGRpIHJldmlld0NvbHVtbnNMaXN0KVxyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0guYWxpZ25IZWFkZXJzT3JkZXJpbmcoaEkubGVhZnMsIHZpZXcpOyAgICAgICAgICAgICAgLy8gQWxsaW5lbyBnbGkgb3JkaW5hbWVudGkgYWdsaSBoZWFkZXJcclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmFsaWduQ29sdW1uc0lmTG9hZGVkVmlldyh2aWV3KTsgICAgICAgICAgICAgICAgICAgIC8vIFNlIHN0byBjYXJpY2FuZG8gdW5hIFZpZXcgZGEgaG90cG90YXRvIChxdWluZGkgY29uIHNhdmVkc3RhdGUgPSB0cnVlKSByaWFsbGluZW8gbGEgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZSBlIGlsIGxvcm8gb3JkaW5lLlxyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0gucmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KGhJLmxlYWZzLCB0ZHMsIHZpZXcpOyAgICAgLy8gTGF2b3JvIHN1aSBUSCBlZCBldmVudHVhbG1lbnRlIG1vZGlmaWNvIGxhIHZpc2liaWxpdMOgIGFuY2hlIGRlaSBURC5cclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmV2YWx1YXRlUGlubmVkQ29sdW1uc1dpZHRoKCk7ICAgICAgICAgICAgICAgICAgICAgIC8vIFNlIHNvbm8gcHJlc2VudGkgY29sb25uZSBwaW5uYXRlIHZhbHV0YSBsYSBkaW1lbnNpb25lIGRlbCBjb250ZW5pdG9yZVxyXG4gICAgICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0guZ2VuZXJhdGVEZWZhdWx0T3JkZXIoaEkubGVhZnMsIHZpZXcpOyAgICAgICAgICAgICAgLy8gR2VuZXJvIGxlIGRpcmV0dGl2ZSBkaSBvcmRpbmFtZW50bywgY2hlIHNpYW5vIGRlZmF1bHQgbyBkZXJpdmFudGkgZGFsbGEgQXBwU2VhcmNoXHJcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTWV0YWRhdGFfSC5ldmFsdWF0ZUhlYWRlckdyb3VwcyhoSSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYWx1dG8gaSByYWdncnVwcGFtZW50aSBkZWdsaSBoZWFkZXIgc2UgcHJlc2VudGlcclxuXHJcbiAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIEdlbmVyYXppb25lIGJpbmRpbmcgcGVyIHJpZ2hlIGUgY29sb25uZSAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVSb3dUaHMoaEkubGVhZnMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhY2NvbGdvIGkgVEhcclxuICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVJvd1RkcyhoSS5sZWFmcywgdGRzKTsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmFjY29sZ28gaSBURCBpbiBjb250ZXN0aSBzZXBhcmF0aSwgdW4gY29udGVzdG8gcGVyIG9nbmkgaXRlbSBvIGdydXBwb1xyXG5cclxuICAgICAgICAgICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAgICAgICAgVWx0aW1pIGFnZ2l1c3RtYWVudGkgZGVpIGJpbmRpbmcgICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5cclxuICAgICAgICAgICAgdGhpcy5jb2x1bW5NZXRhZGF0YV9ILmFwcGx5T3JkZXJpbmcodmlldywgdHJ1ZSk7ICAgICAgICAgICAgLy8gQXBwbGljbyBsJ29yZGluYW1lbnRvIHN1bGxlIGNvbG9ubmUgKG5vbiBBU0MgREVTQywgbWEgXCJwcmltYSBxdWVzdGEgbyBxdWVsbGEgY29sb25uYVwiKVxyXG4gICAgICAgICAgICB0aGlzLk1vdmVUZW1wb3JhcnlWYXJpYWJsZXNUb1JlYWxPbmVzKCk7ICAgICAgICAgICAgICAgICAgICAvLyBDb2xsZWdvIFRIIGUgVEQgYWdnaXVzdGF0aSBmaW5vIGFkIG9yYSBhbGxlIHZhcmlhYmlsaSBkaSBCaW5kaW5nIEhUTUxcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25fSC5ldmFsdWF0ZVNlbGVjdGlvbihpdGVtc0FuZEdyb3Vwcywgc2kpOyAgICAgLy8gUmlhbGxpbmVvIGxlIGluZm8gZGkgc2VsZXppb25lIGRlZ2xpIGVsZW1lbnRpIGRlbGxhIFZpZXdcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlJlc2VhcmNoTmVlZGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5SZXNlYXJjaE5lZWRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKCh0aGlzLnZpZXdNb2RlIHx8IHRoaXMuYXJyYXlNb2RlKSAmJiAhdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICAvLyBSaWFsbGluZW8gbGUgaW5mbyBkaSBzZWxlemlvbmUgZGVnbGkgZWxlbWVudGkgZGVsbGEgVmlld1xyXG4gICAgICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLnZpZXdNb2RlID8gKFZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLml0ZW1zIDogVmlldyBhcyBhbnlbXTtcclxuICAgICAgICAgICAgbGV0IHNpID0gdGhpcy52aWV3TW9kZSA/IChWaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5zZWxlY3Rpb24gOiB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbjtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25fSC5ldmFsdWF0ZVNlbGVjdGlvbihpdGVtcywgc2kpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGVyIGVzc2VyZSBzaWN1cm8gY2hlIGRvcG8gdW4gYmluZCBkaSBvZ2dldHRpIGxhIGVzLXRhYmxlIGFnZ2lvcm5pIGxhIGdyYWZpY2FcclxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICB0aGlzLkZpcnN0QmluZCA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgaWwgYmluZGluZyBkZWdsaSBvZ2dldHRpIHBlcnZlbnV0aSBkYSBxdWVzdGEgY2hpYW1hdGEgY29uIGdsaSBvZ2dldHRpIGVmZmV0dGl2YW1lbnRlIGRhIGdyYWZpY2FyZVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gdmlldyBWaWV3IGRhIGN1aSBzb25vIGFycml2YXRpIGdsaSBvZ2dldHRpLiBQdcOyIGVzc2VyZSBvIHVuIGFycmF5IHNlIHNvbm8gaW4gKiphcnJheU1vZGUqKiBvIHVuYSBBcHBTZWFyY2g8VD4gc2Ugc29ubyBpbiAqKnZpZXdNb2RlKipcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBiaW5kRGlzcGxheVRvTG9hZGVkSXRlbXNPckdyb3Vwcyh2aWV3OiBhbnkpIHtcclxuICAgICAgICBpZiAodGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLkJhc2VJdGVtc0NvdW50ID0gMDtcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSB8fCAhdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5CYXNlSXRlbXNDb3VudCA9IHZpZXc/Lm9iamVjdGNvdW50IHx8IHZpZXcubGVuZ3RoO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgZ3JvdXBpbmdLZXlzID0gdmlldy5ncm91cGluZ3M/LmZpbHRlcih0ID0+ICF0LmFnZ3JlZ2F0aW9uKT8ubGVuZ3RoIHx8IDA7XHJcbiAgICAgICAgaWYgKGdyb3VwaW5nS2V5cyA9PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLlRNUEJvdW5kU291cmNlO1xyXG4gICAgICAgICAgICB0aGlzLkJhc2VJdGVtc0NvdW50ID0gdmlldy5vYmplY3Rjb3VudDtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5yb3dHcm91cGluZ19ILmhhbmRsZU5ld0RhdGFPblJvd0dyb3VwaW5nKHZpZXcsIGdyb3VwaW5nS2V5cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIE1ldG9kbyByaWNoaWFtYXRvIHNvbG8gcXVhbmRvICoqVE1QUm93VERzKiogZSAqKlRNUFJvd1RIcyoqIHNvbm8gY29tcGxldGFtZW50ZSBnZW5lcmF0aSBlZCBhZ2dpdXN0YXRpLiBTZXJ2ZSBwZXIgY29sbGVnYXJsaSBhbGxlIHZhcmlhYmlsaSB1c2F0ZSBsYXRvIGJpbmRpbmcgSFRNTCAqL1xyXG4gICAgcHJpdmF0ZSBNb3ZlVGVtcG9yYXJ5VmFyaWFibGVzVG9SZWFsT25lcygpIHtcclxuICAgICAgICB0aGlzLlJvd1REcyA9IHRoaXMuVE1QUm93VERzO1xyXG4gICAgICAgIHRoaXMuUm93VEhzID0gdGhpcy5UTVBSb3dUSHM7XHJcbiAgICAgICAgdGhpcy5Sb3dUaEdyb3VwcyA9IHRoaXMuVE1QUm93VGhHcm91cHMgPyB0aGlzLlRNUFJvd1RoR3JvdXBzLnJldmVyc2UoKSA6IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMuQ29sdW1ucy5WaXNpYmlsZSA9IHRoaXMuUm93VEhzLmZpbHRlcih0ID0+IHQuVmlzaWJsZSkubGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuQ29sdW1ucy5WaXNpYmxlVW5waW5uZWQgPSB0aGlzLlJvd1RIcy5maWx0ZXIodCA9PiB0LlZpc2libGUgJiYgIXQuUGlubmVkKS5sZW5ndGg7XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zLkdsb2JhbCA9IHRoaXMuQ29sdW1ucy5WaXNpYmxlVW5waW5uZWQgKyAodGhpcy5IYXNQaW5uZWRDb2x1bW5zID8gMSA6IDApICsgKHRoaXMuU2VsZWN0aW9uID8gMSA6IDApICsgKHRoaXMuUmVtb3ZhbCA/IDEgOiAwKSArICh0aGlzLkV4cG9ydCB8fCB0aGlzLkhpZGRlbkNvbHVtbnMgfHwgdGhpcy5Db2x1bW5zT3JkZXJpbmcgfHwgdGhpcy5Db3JuZXJNZW51T3B0aW9ucyA/IDEgOiAwKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVybWV0dGUgZGkgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlIGluIG1hbmllcmEgYXJiaXRyYXJpYSBkZWdsaSBvZ2dldHRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNlbGVjdCAqKnRydWUqKiBwZXIgc2VsZXppb25hcmxpLCAqKmZhbHNlKiogcGVyIG5vbiB0b2NjYXJsaVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0U2VsZWN0aW9uU3RhdHVzKGl0ZW1zOiBhbnlbXSwgc2VsZWN0OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25fSC5oYW5kbGVJdGVtc1NlbGVjdGlvbihpdGVtcywgc2VsZWN0KTtcclxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZ2VzdGlzY2UgaWwgY2FtYmlvIGRpIE9yZGluYW1lbnRvIGRpIHVuYSBjb2xvbm5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIGRlbGxhIGNvbG9ubmEgaWwgY3VpIG9yaWRuYW1lbnRvIMOoIGNhbWJpYXRvXHJcbiAgICAgKiBAcGFyYW0geydERVNDJyB8ICdBU0MnfSBvcmRlciBOdW92byBvcmRpbmUgc2VsZXppb25hdG8gcGVyIGxhIGNvbG9ubmFcclxuICAgICAqL1xyXG4gICAgcHVibGljIHRoT3JkZXJDaGFuZ2VkKGlkOiBzdHJpbmcsIG9yZGVyPzogJ0RFU0MnIHwgJ0FTQycpIHtcclxuICAgICAgICBpZiAoIXRoaXMudmlld01vZGUgJiYgIXRoaXMuYXJyYXlNb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignT3JkZXIgY2hhbmdlZCBvbiBhIHRhYmxlIG5vdCBpbiB2aWV3TW9kZSBvciBBcnJheSBtb2RlLiBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMuT3JkZXJCeUNvbHVtbilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLmNvbHVtbk1ldGFkYXRhX0guaGFuZGxlVEhPcmRlckNoYW5nZShpZCwgb3JkZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGRhIGNoaWFtYXJlIG9nbmkgdm9sdGEgY2hlIHNpIHZ1b2xlIGRhcmUgZXZpZGVuemEgYWxsJ2VzdGVybm8gZGVsIGJpc29nbm8gZGkgcmllZmZldHR1YXJlIGxhIHJpY2VyY2FcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZXNldHNQYWdlIEluZGljYSBhbCBsaXN0ZW5lciBjaGUgZGV2ZSByZXNldHRhcmUgaWwgbnVtZXJvIGRpIHBhZ2luYVxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlld092ZXJyaWRlIE92ZXJyaWRlIGRlbGxhIHZpZXcgZGEgZW1ldHRlcmUgcGVyIHF1ZXN0YSByaWNlcmNhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbWl0U2VhcmNoUmVxdWVzdChyZXNldHNQYWdlOiBib29sZWFuLCB2aWV3T3ZlcnJpZGU/OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlICYmICF2aWV3T3ZlcnJpZGUpIHtcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBBcHBTZWFyY2g8YW55PikuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmlld092ZXJyaWRlKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNldHNQYWdlKVxyXG4gICAgICAgICAgICAgICAgdmlld092ZXJyaWRlLnBhZ2UgPSAxO1xyXG4gICAgICAgICAgICB2aWV3T3ZlcnJpZGUuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gdHJ1ZVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5yZXNlYXJjaEluUHJvZ3Jlc3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMub25TZWFyY2hSZXF1ZXN0LmVtaXQodmlld092ZXJyaWRlID8gdmlld092ZXJyaWRlIDogcmVzZXRzUGFnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJ0ZW5kbyBkYWdsaSAqKkVzVGRzKiogYmluZGF0aSBnZW5lcmEsIGFsbCdpbnRlcm5vIGRlbCBkaXppb25hcmlvICoqVE1QUm93VERzKiogdHV0dGkgaSBjb250ZXN0aSBkZWkgdmFyaSBvZ2dldHRpLlxyXG4gICAgICpcclxuICAgICAqIFZlbmdvbm8gZXNjbHVzaSBpIFREIFwiSW50ZXJuaVwiIGluIHF1YW50byB2ZW5nb25vIGdlbmVyYXRpIGRhZ2xpIG9yaWdpbmFsaSBxdWluZGkgaW5jbHVkZXJsaSB2b3JyZWJiZSBkaXJlIHJpZWZmZXR0dWFyZSBsZSBvcGVyYXppb25pIGR1ZSB2b2x0ZVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAyIHNjYW4gRXNUaHMsIDEgc2NhbiBFc1Rkc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0VzVGRbXSB8IEVzVGREaXJlY3RpdmVbXX0gdGRzIENlbGxlIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBldmFsdWF0ZVJvd1Rkcyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdGRzOiBFc1RkW10gfCBFc1RkRGlyZWN0aXZlW10pIHtcclxuICAgICAgICBpZiAodGRzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCB0aHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGggfCBFc1RoRGlyZWN0aXZlIH0gPSB7fTtcclxuICAgICAgICBsZXQgY29sdW1uc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUYWJsZUNvbHVtbiB9ID0ge307XHJcblxyXG4gICAgICAgIGZvciAobGV0IGNvbGkgPSAwOyBjb2xpIDwgdGhpcy5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5Db2x1bW5zTGlzdFtjb2xpXTtcclxuICAgICAgICAgICAgY29sdW1uc0NhY2hlW2NvbC5pZF0gPSBjb2w7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIHRoc0NhY2hlW3RoaXMudXRpbGl0aWVzX0guaXNFc1RoKHRoKSA/IHRoLklEIDogdGgudGhdID0gdGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLlRNUFJvd1REcyA9IHt9O1xyXG4gICAgICAgIC8vIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHBlciBwZXJtZXR0ZXJtaSBkaSBpbnNlcmlyZSB0dXR0ZSBsZSBjb2xvbm5lIFwiRml4ZWRcIiBkYXZhbnRpXHJcbiAgICAgICAgbGV0IGNvbnRleHRGaXhlZHM6IHsgW2NvbnRleHQ6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMudXRpbGl0aWVzX0guaXNFc1RkKHRkKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQuSURdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCEhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgdGguX3JlZmVyZW5jZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwiSUQgZGVsbCdvZ2dldG8gRXNUZCBub24gY29tcGF0aWJpbGUgY29uIGdsaSBJRCBkaWNoYXJhdGkgbmVnbGkgRXNUaDogXCIgKyB0ZC5JRDtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgaXNGaXhlZCA9ICh0aGlzLnV0aWxpdGllc19ILmlzRXNUaCh0aCkgJiYgdGguRml4ZWQpIHx8ICghdGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpICYmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApKTtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtVG9BZGQgPSA8YW55PnsgR3JvdXBBZ2dyZWdhdGlvbjogZmFsc2UsIEdyb3VwSGVhZGVyOiBmYWxzZSwgV3JhcHM6IHRydWUsIElEOiB0ZC5JRCwgVmlzaWJsZTogdGQuVmlzaWJsZSwgQ2xhc3M6IHRkLkNsYXNzLCBDb250ZW50OiB0ZC5Db250ZW50LCBSb3V0ZXJMaW5rOiB0ZC5Sb3V0ZXJMaW5rLCBUZW1wbGF0ZTogdGQuVGVtcGxhdGUgfTtcclxuICAgICAgICAgICAgICAgIGxldCBjdHggPSB0ZC5Db250ZXh0O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXhlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dURHNbY3R4XS5zcGxpY2UoMCArIChjb250ZXh0Rml4ZWRzW2N0eF0rKyksIDAsIGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdLnB1c2goaXRlbVRvQWRkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuUm93Q29udGV4dHMucHVzaChjdHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0gPSBbaXRlbVRvQWRkXTtcclxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBpdGVtID0gdGhpcy5ib3VuZFNvdXJjZVtpXTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY3R4ID0gaXRlbS5faGFzaDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQga2V5ID0gdGQudGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQudGRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aC5fcmVmZXJlbmNlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBcIklEIGRlbGwnb2dnZXRvIEVzVGQgbm9uIGNvbXBhdGliaWxlIGNvbiBnbGkgSUQgZGljaGFyYXRpIG5lZ2xpIEVzVGg6IFwiICsgdGQudGQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZC50ZElmIHx8ICghdGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpICYmIHRoLnRoR3JvdXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0aENhc3RlZCA9IDxFc1RoRGlyZWN0aXZlPnRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgaXNGaXhlZCA9ICh0aGlzLnV0aWxpdGllc19ILmlzRXNUaCh0aCkgJiYgdGguRml4ZWQpIHx8ICghdGhpcy51dGlsaXRpZXNfSC5pc0VzVGgodGgpICYmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXAgfHwgdGgudGhQaW5uZWQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGl0ZW1Ub0FkZCA9IGl0ZW0uX2l0ZW0gP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGFueT57IExlZnRCb3JkZXI6ICg8YW55PnRoQ2FzdGVkKS5fbGJvcmQsIFJpZ2h0Qm9yZGVyOiAoPGFueT50aENhc3RlZCkuX3Jib3JkLCBJRDoga2V5LCBQaW5uZWQ6IGNvbHVtbnNDYWNoZVt0ZC50ZF0ucGlubmVkLCBQaW5uZWRXaWR0aDogdGhDYXN0ZWQudGhQaW5uZWRXaWR0aCwgR3JvdXBIZWFkZXI6IGZhbHNlLCBHcm91cEFnZ3JlZ2F0aW9uOiBmYWxzZSwgVmlzaWJsZTogY29sdW1uc0NhY2hlW3RkLnRkXS52aXNpYmxlLCBXcmFwczogZmFsc2UsIENsYXNzOiB0ZC50ZENsYXNzLCBUZW1wbGF0ZTogdGhDYXN0ZWQudGhHcm91cCAmJiAhdGhpcy5TaG93SXRlbUdyb3Vwc0NvbHVtbnMgPyBudWxsIDogdGQuVGVtcGxhdGUgfSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YW55PnsgTGVmdEJvcmRlcjogKDxhbnk+dGhDYXN0ZWQpLl9sYm9yZCwgUmlnaHRCb3JkZXI6ICg8YW55PnRoQ2FzdGVkKS5fcmJvcmQsIElEOiBrZXksIFBpbm5lZDogY29sdW1uc0NhY2hlW3RkLnRkXS5waW5uZWQsIFBpbm5lZFdpZHRoOiB0aENhc3RlZC50aFBpbm5lZFdpZHRoLCBHcm91cEhlYWRlcjogdGhDYXN0ZWQudGhHcm91cCwgR3JvdXBBZ2dyZWdhdGlvbjogISF0aENhc3RlZC50aEFnZ3JlZ2F0aW9uLCBWaXNpYmxlOiBjb2x1bW5zQ2FjaGVbdGQudGRdLnZpc2libGUsIFdyYXBzOiBmYWxzZSwgQ2xhc3M6IHRoQ2FzdGVkLnRoR3JvdXBDbGFzcyB8fCAnJywgQ29udGVudDogdGhpcy5yb3dHcm91cGluZ19ILmdldEdyb3VwQ2VsbERpc3BsYXkoPEdyb3VwPml0ZW0sIGtleSwgPEVzVGhEaXJlY3RpdmU+dGgpIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5UTVBSb3dURHNbY3R4XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dURHNbY3R4XS5wdXNoKGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlJvd0NvbnRleHRzLnB1c2goY3R4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0gPSBbaXRlbVRvQWRkXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRGaXhlZHNbY3R4XSA9IGlzRml4ZWQgPyAxIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2Ugbm9uIGhvIG9nZ2V0dGkgw6ggaW51dGlsZSBjaGUgY29udHJvbGxvIGdsaSBlcnJvcmksIGRhdG8gY2hlIGdsaSBlcy10ZCBub24gZXNpc3RlcmFubm8gZGkgY2VydG8gZSBkaSBjb25zZWd1ZW56YSBnbGkgZXMtdGggbm9uIHNhcmFubm8gcmVmZXJlbnppYXRpXHJcbiAgICAgICAgaWYgKHRoaXMuVE1QQm91bmRTb3VyY2UubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdmFyIGVycnM6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXRoLl9yZWZlcmVuY2VkKVxyXG4gICAgICAgICAgICAgICAgZXJycy5wdXNoKHRoaXMudXRpbGl0aWVzX0guaXNFc1RoKHRoKSA/IHRoLklEIDogdGgudGgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB2YXIgZXJySWRzID0gZXJycy5qb2luKCcsICcpO1xyXG4gICAgICAgICAgICB0aHJvdyBcIkwnSUQgZGkgdW5vIG8gcGnDuSBFc1RoIG5vbiBoYW5ubyBhbGN1biBFc1RkIGFzc29jaWF0bzogXCIgKyBlcnJJZHM7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGFydGVuZG8gZGFnbGkgKipFc1RocyoqIGJpbmRhdGkgZ2VuZXJhLCBhbGwnaW50ZXJubyBkZWwgZGl6aW9uYXJpbyAqKlRNUFJvd1RIcyoqIHR1dHRpIGkgY29udGVzdGkgZGVpIHZhcmkgb2dnZXR0aS5cclxuICAgICAqXHJcbiAgICAgKiBWZW5nb25vIGVzY2x1c2kgaSBUSCBcIkludGVybmlcIiBpbiBxdWFudG8gdmVuZ29ubyBnZW5lcmF0aSBkYWdsaSBvcmlnaW5hbGkgcXVpbmRpIGluY2x1ZGVybGkgdm9ycmViYmUgZGlyZSByaWVmZmV0dHVhcmUgbGUgb3BlcmF6aW9uaSBkdWUgdm9sdGVcclxuICAgICAqXHJcbiAgICAgKiBDb3N0bzogMSBzY2FuIEVzVGhzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBldmFsdWF0ZVJvd1Rocyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSkge1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnNMaXN0Q2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uIH0gPSB7fTtcclxuICAgICAgICBsZXQgY2FzdGVkVmlldyA9IDxBcHBTZWFyY2g8YW55Pj50aGlzLlZpZXc7XHJcbiAgICAgICAgbGV0IGdyb3VwaW5nc1VuZGVmaW5lZCA9IHRoaXMudmlld01vZGUgJiYgKGNhc3RlZFZpZXcgJiYgIWNhc3RlZFZpZXcuZ3JvdXBpbmdzIHx8IGNhc3RlZFZpZXcuZ3JvdXBpbmdzLmxlbmd0aCA9PSAwKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpdG0gPSB0aGlzLkNvbHVtbnNMaXN0W2ldO1xyXG4gICAgICAgICAgICBjb2x1bW5zTGlzdENhY2hlW2l0bS5pZF0gPSBpdG1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuVE1QUm93VEhzID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGxldCB0b0FkZDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnV0aWxpdGllc19ILmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRvQWRkID0geyBQaW5uZWQ6IGZhbHNlLCBJRDogdGguSUQsIFZpc2libGU6IHRoLlZpc2libGUsIENsYXNzOiB0aC5DbGFzcywgT3JkZXI6IHRoLk9yZGVyLCBPcmRlcmFibGU6IHRoLk9yZGVyYWJsZSwgVGVtcGxhdGU6IG51bGwsIENvbnRlbnQ6IHRoLkRlc2NyaXB0aW9uLCBXcmFwOiB0aC5XcmFwIH07XHJcbiAgICAgICAgICAgICAgICBpZiAodGguRml4ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMuc3BsaWNlKDAgKyAoZml4ZWQrKyksIDAsIHRvQWRkKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1RIcy5wdXNoKHRvQWRkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0aC50aElmIHx8IHRoLnRoR3JvdXApIHtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgdGhDbGFzcyA9ICh0aC50aENsYXNzIHx8ICcnKSArICh0aC50aEdyb3VwID8gXCIgZXN0LWNvbC1taW5cIiA6IFwiXCIpO1xyXG4gICAgICAgICAgICAgICAgdG9BZGQgPSB7IFBpbm5lZDogY29sdW1uc0xpc3RDYWNoZVt0aC50aF0ucGlubmVkLCBQaW5uZWRXaWR0aDogdGgudGhQaW5uZWRXaWR0aCwgSUQ6IHRoLnRoLCBWaXNpYmxlOiB0aC50aFZpc2libGUsIENsYXNzOiB0aENsYXNzLCBPcmRlcjogdGgudGhPcmRlciwgT3JkZXJhYmxlOiB0aC50aE9yZGVyYWJsZSwgVGVtcGxhdGU6IHRoLlRlbXBsYXRlLCBDb250ZW50OiBudWxsLCBXcmFwOiB0aC50aFdyYXAsIExlZnRCb3JkZXI6ICg8YW55PnRoKS5fbGJvcmQsIFJpZ2h0Qm9yZGVyOiAoPGFueT50aCkuX3Jib3JkIH07XHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1RIcy5wdXNoKHRvQWRkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZSBobyB1biBtb2RlbGxvIGNoZSBkZXZlIGZ1bnppb25hcmUgYSByb3dncm91cGluZyBtYSBub24gw6ggYW5jb3JhIHN0YXRhIGVmZmV0dHVhdGEgbmVzc3VuYSByaWNlcmNhIHN1aSBncnVwcGkgcHJpbmNpcGFsaSAoZ3JvdXBpbmdzVW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgLy8gbGkgZ2VuZXJvIGUgbWFuZG8gbGEgcHJpbWEgcmljZXJjYSBjaGUgZGV2J2Vzc2VyZSBzcGVkaXRhIGFsIGJhY2tlbmQgcGVyIGlsIHByaW1vIGNhcmljYW1lbnRvIGRlaSBncnVwcGlcclxuICAgICAgICAgICAgICAgIGlmIChncm91cGluZ3NVbmRlZmluZWQgJiYgKHRoLnRoQWdncmVnYXRpb24gfHwgdGgudGhHcm91cCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZ3JvdXBBZ2dyZWdhdGlvbnM6IEdyb3VwT3JBZ2dyZWdhdGlvbltdID0gdGhpcy5yb3dHcm91cGluZ19ILmdldEdyb3VwQWdncmVnYXRpb25zKHRoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWNhc3RlZFZpZXcuZ3JvdXBpbmdzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXN0ZWRWaWV3Lmdyb3VwaW5ncyA9IGdyb3VwQWdncmVnYXRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdGVkVmlldy5ncm91cGluZ3MucHVzaCguLi5ncm91cEFnZ3JlZ2F0aW9ucyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuUmVzZWFyY2hOZWVkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3Bvc3RhIGxhIHJpY2VyY2EgZGkgdW5hIHBhZ2luYSBpbiBhdmFudGkgKG8gaW5kaWV0cm8pXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgTnVtZXJvIGRpIHBhZ2luZSBkYSBhZ2dpdW5nZXJlIChvIHNvdHRyYXJyZSwgc2UgbmVnYXRpdm8pIGFsbGEgcGFnaW5hIGF0dHVhbGVcclxuICAgICAqIEBwYXJhbSB7YW55fSBwYWdlciBFbGVtZW50byBkaSBzZXBhcmF6aW9uZSBzdSBjdWkgw6ggZWZmZXR0dWF0YSBsYSByaWNlcmNhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRUb1BhZ2VHcm91cChwYWdlOiBudW1iZXIsIHBhZ2VyOiBHcm91cFBhZ2VyKSB7XHJcbiAgICAgICAgdGhpcy5nb1RvUGFnZUdyb3VwKHBhZ2VyLnZpZXcucGFnZSArIHBhZ2UsIHBhZ2VyKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGFsbGEgcGFnaW5hIHNwZWNpZmljYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gcGFnZXIgRWxlbWVudG8gZGkgc2VwYXJhemlvbmUgc3UgY3VpIMOoIGVmZmV0dHVhdGEgbGEgcmljZXJjYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ29Ub1BhZ2VHcm91cChwYWdlOiBudW1iZXIsIHBhZ2VyOiBHcm91cFBhZ2VyKSB7XHJcblxyXG4gICAgICAgIGxldCBhcHBTZWFyY2hFbGVtZW50ID0gcGFnZXIudmlldztcclxuICAgICAgICBpZiAocGFnZSA9PT0gMCB8fCAocGFnZSA+IGFwcFNlYXJjaEVsZW1lbnQucGFnZXMgJiYgYXBwU2VhcmNoRWxlbWVudC5wYWdlcyA+IDApKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGFwcFNlYXJjaEVsZW1lbnQucGFnZSA9IHBhZ2U7XHJcbiAgICAgICAgcGFnZXIuYnV0dG9ucyA9IHRoaXMudXRpbGl0aWVzX0guZ2V0UGFnZXNBcnJheSg2LCBhcHBTZWFyY2hFbGVtZW50LnBhZ2UsIGFwcFNlYXJjaEVsZW1lbnQucGFnZXMpO1xyXG5cclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlLCBhcHBTZWFyY2hFbGVtZW50KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBpIGNsaWNrIHN1bGxhIHRhYmVsbGEgc29sbyBwZXIgbGUgcmlnaGUgYSBncnVwcG8uIFxyXG4gICAgICogTyByaW11b3ZlIGdsaSBlbGVtZW50aSBhdHR1YWxtZW50ZSBwcmVzZW50aSBvIGNhcmljYSBpbCBjb250ZW51dG8gZGVsIGdydXBwb1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBncm91cCBHcnVwcG8gYmluZGF0byBzdSBjdWkgc2kgw6ggZWZmZXR0dWF0byBpbCBjbGlja1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAqKnRydWUqKiBzZSBsJ29wZXJhaXpvbmUgw6ggYW5kYXRhIGEgYnVvbiBmaW5lLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlR3JvdXBDbGljayhncm91cDogR3JvdXApOiBib29sZWFuIHtcclxuICAgICAgICBsZXQgY2FzdGVkID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgICAgIGxldCBhbnlHID0gKDxhbnk+Z3JvdXApO1xyXG4gICAgICAgIGFueUcuX2V4cGFuZGVkID0gIWFueUcuX2V4cGFuZGVkO1xyXG5cclxuICAgICAgICAvLyBTb25vIGluIG1vZGFsaXTDoCByYWdncnVwcGFtZW50byB2aXJ0dWFsZSBkYSBhcnJheTogRXNwYW5kZXJlIHNpZ25pZmljYSByZW5kZXJlIHZpc2liaWxpIHR1dHRpIGdsaSBvZ2dldHRpIHJlbGF0aXZpIGEgcXVlc3RvIGdydXBwbywgdmljZXZlcnNhIGlsIGNvbnRyYXJyZVxyXG4gICAgICAgIGlmICh0aGlzLkFycmF5R3JvdXBpbmcpIHtcclxuICAgICAgICAgICAgbGV0IGFsbFJlbGF0aXZlcyA9IHRoaXMuYm91bmRTb3VyY2UuZmlsdGVyKHQgPT5cclxuICAgICAgICAgICAgICAgICh0Ll9ncm91cCAmJiAoKGFueUcuX2V4cGFuZGVkICYmIHQuX3BhcmVudCA9PSBhbnlHLl90aGlzS2V5KSB8fCAoIWFueUcuX2V4cGFuZGVkICYmIHQuX3BhcmVudCAmJiB0Ll9wYXJlbnQuc3RhcnRzV2l0aChhbnlHLl90aGlzS2V5KSkpKSB8fFxyXG4gICAgICAgICAgICAgICAgKHQuX2l0ZW0gJiYgKChhbnlHLl9leHBhbmRlZCAmJiB0Ll90aGlzS2V5ID09IGFueUcuX3RoaXNLZXkpIHx8ICghYW55Ry5fZXhwYW5kZWQgJiYgdC5fdGhpc0tleS5zdGFydHNXaXRoKGFueUcuX3RoaXNLZXkpKSkpKVxyXG4gICAgICAgICAgICBhbGxSZWxhdGl2ZXMuZm9yRWFjaCh0ID0+IHsgdC5fdmlzaWJsZSA9IGFueUcuX2V4cGFuZGVkOyBpZiAodC5fZ3JvdXApIHQuX2V4cGFuZGVkID0gZmFsc2UgfSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChhbnlHLl9leHBhbmRlZCkge1xyXG4gICAgICAgICAgICAvLyBSZXNldHRvIGlwcFxyXG4gICAgICAgICAgICBjYXN0ZWQuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPSAxNTtcclxuICAgICAgICAgICAgaWYgKCFjYXN0ZWQucmVxdWVzdGVkZ3JvdXBzKVxyXG4gICAgICAgICAgICAgICAgY2FzdGVkLnJlcXVlc3RlZGdyb3VwcyA9IFtuZXcgR3JvdXBGaWx0ZXIoZ3JvdXAuY29sdW1uLCBncm91cC52YWx1ZSldO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCBsZXZlbCA9IGFueUcuX2dyb3VwbGV2ZWw7XHJcbiAgICAgICAgICAgICAgICAvLyBzZSBpbCBncnVwcG8gY2xpY2NhdG8gbm9uIGhhIHVuIGxpdmVsbG8gw6ggaWwgcHJpbW8gZ3J1cHBvLCBxdWluZGkgb3JkaW5hbWVudG8gdW5pY29cclxuICAgICAgICAgICAgICAgIC8vIGFsdHJpbWVudGkgZGV2byByaW11b3ZlcmUgdHV0dGkgaSBmaWx0cmkgc3UgbGl2ZWxsaSBzdXBlcmlvcmkgYWwgbGV2ZWwgY2xpY2NhdG8gZSBhZ2dpdW5nZXJlIGlsIGxldmVsIGNsaWNjYXRvXHJcbiAgICAgICAgICAgICAgICBpZiAoIWxldmVsKVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMgPSBbbmV3IEdyb3VwRmlsdGVyKGdyb3VwLmNvbHVtbiwgZ3JvdXAudmFsdWUpXTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBhbnlHLl9wYXJlbnRSb3V0ZS5mb3JFYWNoKChzdGVwOiBHcm91cFJvdXRlRnJhZ21lbnQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdGVkLnJlcXVlc3RlZGdyb3Vwcy5wdXNoKG5ldyBHcm91cEZpbHRlcihzdGVwLmNvbHVtbiwgc3RlcC52YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMucHVzaChuZXcgR3JvdXBGaWx0ZXIoZ3JvdXAuY29sdW1uLCBncm91cC52YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBwYXRoID0gKGFueUcuX3BhcmVudCB8fCAnJykgKyBncm91cC52YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGhvIGNoaXVzbyB1biBncnVwcG8gbm9uIG1pIHNlcnZlIHJpZWZmZXR0dWFyZSByaWNlcmNlLCBtaSBiYXN0YSBlbGltaW5hcmUgZGFnbGkgb2dnZXR0aSBiaW5kYXRpIHR1dHRpIGdsaSBlbGVtZW50aSBzb3R0b3N0YW50aSBhIHF1ZWwgZ3J1cHBvXHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLmJvdW5kU291cmNlLmZpbHRlcih0ID0+ICF0Ll9wYXJlbnQgfHwgIXQuX3BhcmVudC5zdGFydHNXaXRoKHBhdGgpKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGRldm8gcGVyw7IgYW5jaGUgcmltdW92ZXJlIGV2ZW50dWFsaSBjYWNoZSByZWxhdGl2ZVxyXG4gICAgICAgICAgICB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZSA9IHRoaXMuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmZpbHRlcih0ID0+IHQucGF0aCAhPSBwYXRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlc3Rpc2NlIGxhIHNlbGV6aW9uZSBnbG9iYWxlIGRlZ2xpIG9nZ2V0dGksIHNpYSBwZXIgcGFnaW5hIGNoZSBhIGxpdmVsbG8gZGkgKipTZWxlY3RBbGwqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZm9yY2VkVmFsIFZhbG9yZSBmb3J6YXRvIGRpIGNoZWNrIGRhIGFzc2VnbmFyZSBhZ2xpIG9nZ2V0dGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdsb2JhbENoZWNrQ2hhbmdlZChmb3JjZWRWYWw6IGJvb2xlYW4gPSBudWxsKSB7XHJcblxyXG4gICAgICAgIC8vIFByZW5kbyB0dXR0aSBnbGkgZWxlbWVudGkgcHJlc2VudGkgaW4gcXVlc3RhIHZpc3RhLiBTZSBobyBncnVwcGkgcHJlbmRvIHNvbG8gaSBncnVwcGkgYSBsaXZlbGxvIDAsIGFsdHJpbWVudGkgcHJlbmRvIHR1dHRpIGdsaSBvZ2dldHRpIHBlciBzZWxlemlvbmFybGlcclxuICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLmJvdW5kU291cmNlLmZpbmQodCA9PiB0Ll9ncm91cCkgPyB0aGlzLmJvdW5kU291cmNlLmZpbHRlcih0ID0+IHQuX2dyb3VwICYmICF0Ll9wYXJlbnQpIDogdGhpcy5ib3VuZFNvdXJjZTtcclxuICAgICAgICB2YXIgaXRlbVNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uX0guaGFuZGxlSXRlbXNTZWxlY3Rpb24oaXRlbXMsIGZvcmNlZFZhbCwgdGhpcy5nbG9iYWxDaGVjayk7XHJcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcblxyXG4gICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkLmVtaXQoaXRlbVNlbGVjdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBpIGNsaWNrIHN1bGxhIHRhYmVsbGEsIGdlc3RlbmRvIGV2ZW50dWFsbWVudGUgYW5jaGUgZ2xpIFNoaWZ0ICsgQ2xpY2sgcGVyIHNlbGV6aW9uYXJlIHVuIHJhbmdlIGRpIG9nZ2V0dGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZXZlbnQgRXZlbnRvIG5hdGl2byBIVE1MIGRlbCBjbGlja1xyXG4gICAgICogQHBhcmFtIHthbnl9IGl0ZW0gT2dnZXR0byBiaW5kYXRvIHN1IGN1aSBzaSDDqCBlZmZldHR1YXRvIGlsIGNsaWNrXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGwnb3BlcmFpem9uZSDDqCBhbmRhdGEgYSBidW9uIGZpbmUsICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYW5kbGVDbGljayhldmVudDogYW55LCBpdGVtOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBTZWxlemlvbm8gZGVsIHRlc3RvIG1hIG5vbiBobyBzaGlmdCBwcmVtdXRvIC0+IGlnbm9ybyBsYSBzZWxlemlvbmVcclxuICAgICAgICBpZiAoKGV2ZW50LnZpZXcuZ2V0U2VsZWN0aW9uKCkudHlwZSA9PSAnUmFuZ2UnIHx8IGV2ZW50LnZpZXcuZ2V0U2VsZWN0aW9uKCkudG9TdHJpbmcoKS5sZW5ndGggPiAwKSAmJiAhZXZlbnQuc2hpZnRLZXkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gU2VsZXppb25vIGRlbCB0ZXN0byBlIGhvIHNoaWZ0IHByZW11dG8gLT4gYW5udWxsbyBsYSBzZWxlemlvbmUgZGVsIHRlc3RvXHJcbiAgICAgICAgaWYgKChldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnR5cGUgPT0gJ1JhbmdlJyB8fCBldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCkubGVuZ3RoID4gMCkgJiYgZXZlbnQuc2hpZnRLZXkpXHJcbiAgICAgICAgICAgIHRoaXMudXRpRXh0cy5jbGVhclRleHRTZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgICAgbGV0IHNlbGVjdGVkaXRlbXM6IGFueVtdID0gW107XHJcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5ICYmIHRoaXMuU2hpZnRDbGljayAmJiAhdGhpcy5TaW5nbGVTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgbGV0IHN0YXJ0U2VsZWN0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLmJvdW5kU291cmNlLmZpbHRlcih0ID0+ICF0Ll9ncm91cCAmJiAhdC5fc2VwKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHQgPSBpdGVtc1tpXTtcclxuICAgICAgICAgICAgICAgIGlmIChzdGFydFNlbGVjdGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIHQuX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZGl0ZW1zLnB1c2godCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoKHQgPT0gaXRlbSB8fCB0ID09IHRoaXMubGFzdFNlbGVjdGVkKSAmJiAhc3RhcnRTZWxlY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydFNlbGVjdGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5fc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkaXRlbXMucHVzaCh0KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHQgPT0gaXRlbSB8fCB0ID09IHRoaXMubGFzdFNlbGVjdGVkKSAmJiBzdGFydFNlbGVjdGluZylcclxuICAgICAgICAgICAgICAgICAgICBzdGFydFNlbGVjdGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaXRlbS5fc2VsZWN0ZWQgPSAhaXRlbS5fc2VsZWN0ZWQ7XHJcbiAgICAgICAgICAgIHRoaXMubGFzdFNlbGVjdGVkID0gaXRlbTtcclxuICAgICAgICAgICAgc2VsZWN0ZWRpdGVtcy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGl0ZW1TZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbl9ILmhhbmRsZUl0ZW1zU2VsZWN0aW9uKHNlbGVjdGVkaXRlbXMpO1xyXG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG5cclxuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KGl0ZW1TZWxlY3Rpb24pO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGRpIHVuYSBwYWdpbmEgaW4gYXZhbnRpIChvIGluZGVpdHJvKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIE51bWVybyBkaSBwYWdpbmUgZGEgYWdnaXVuZ2VyZSAobyBzb3R0cmFycmUsIHNlIG5lZ2F0aXZvKSBhbGxhIHBhZ2luYSBhdHR1YWxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRUb1BhZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICAgICAgbGV0IHZpZXcgPSB0aGlzLk1haW5Hcm91cFZpZXcgPyB0aGlzLk1haW5Hcm91cFZpZXcgOiB0aGlzLlZpZXc7XHJcblxyXG4gICAgICAgIHRoaXMuZ29Ub1BhZ2UoKCh0aGlzLlNlYXJjaFZpZXcgfHwgdmlldyk/LnBhZ2UgfHwgMCkgKyBwYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGFsbGEgcGFnaW5hIHNwZWNpZmljYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnb1RvUGFnZShwYWdlOiBudW1iZXIpIHtcclxuICAgICAgICBsZXQgdmlldyA9IHRoaXMuTWFpbkdyb3VwVmlldyA/IHRoaXMuTWFpbkdyb3VwVmlldyA6IHRoaXMuVmlldztcclxuICAgICAgICBpZiAoIXZpZXcucGFnZSB8fCAhdmlldy5wYWdlcylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgYXBwU2VhcmNoRWxlbWVudCA9IHRoaXMuU2VhcmNoVmlldyB8fCB2aWV3O1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IChwYWdlID4gYXBwU2VhcmNoRWxlbWVudC5wYWdlcyAmJiBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzID4gMCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgYXBwU2VhcmNoRWxlbWVudC5wYWdlID0gcGFnZTtcclxuICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLnV0aWxpdGllc19ILmdldFBhZ2VzQXJyYXkoNiwgYXBwU2VhcmNoRWxlbWVudC5wYWdlLCBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzLCB2aWV3Lml0ZW1zLmxlbmd0aCB8fCB2aWV3Lmdyb3Vwcz8ubGVuZ3RoIHx8IDAsIHZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUpO1xyXG5cclxuICAgICAgICBsZXQgaGFzR3JvdXBpbmdzID0gISF0aGlzLk1haW5Hcm91cFZpZXc7XHJcbiAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSwgaGFzR3JvdXBpbmdzID8gdmlldyA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnRvIHJpY2hpYW1hdG8gc3VsIGNhbWJpbyBkZWxsYSBwYWdpbmF6aW9uZS4gVmVycsOgIHJpY2hpYW1hdG8gbCdldmVudG8gKiplbWl0U2VhcmNoUmVxdWVzdCoqXHJcbiAgICAgKiBwZXIgY29tdW5pY2FyZSBhbCBjb21wb25lbnRlIGNoZSB1dGlsaXp6YSBxdWVzdGEgdGFiZWxsYSBjaGUgaSBkYXRpIHNvbm8gZGEgYWdnaW9ybmFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25JdGVtc1BlclBhZ2VDaGFuZ2VkKG5ld0lwcCkge1xyXG4gICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPSBuZXdJcHA7XHJcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICAgICAgaWYgKHRoaXMuTWFpbkdyb3VwVmlldylcclxuICAgICAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlLCB0aGlzLk1haW5Hcm91cFZpZXcpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gc3VsIGNhbWJpbyBkZWxsYSBwYWdpbmF6aW9uZS4gVmVycsOgIHJpY2hpYW1hdG8gbCdldmVudG8gKiplbWl0U2VhcmNoUmVxdWVzdCoqIGNvbiBsYSB2aXN0YSBkZWwgc2VwYXJhdG9yZSAqL1xyXG4gICAgcHVibGljIG9uR3JvdXBJdGVtc1BlclBhZ2VDaGFuZ2VkKHBhZ2VyOiBHcm91cFBhZ2VyLCBuZXdJcHA6IG51bWJlcikge1xyXG4gICAgICAgIHBhZ2VyLnZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPSBuZXdJcHA7XHJcbiAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlLCBwYWdlci52aWV3KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqIE1ldG9kbyBjaGUgZ2VzdGlzY2UgbGEgbW9kaWZpY2EgZGVsIHRlbXBvIHNwZWNpZmljYXRvIHBlciBsJ2FnZ2lvcm5hbWVudG8gYXV0b21hdGljbyAqL1xyXG4gICAgcHVibGljIGF1dG9VcGRhdGVDaGFuZ2VkKCkge1xyXG4gICAgICAgIGlmICghL15bMS05XVxcZCokLy50ZXN0KHRoaXMuc2Vjb25kcykpXHJcbiAgICAgICAgICAgIHRoaXMuc2Vjb25kcyA9ICcxMCc7XHJcblxyXG4gICAgICAgIGxldCBzZWNvbmRzSW5NcyA9IHBhcnNlSW50KHRoaXMuc2Vjb25kcywgbnVsbCkgKiAxMDAwO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hdXRvVXBkYXRlKVxyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4geyB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlKTsgfSwgc2Vjb25kc0luTXMpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnVwZGF0ZVRpbWVyKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGlhbWF0byBkYWwgY2xpY2sgc3UgdW5hIGRlbGxlIGNvbG9ubmUgZ2VuZXJhdGUgZGFsbCdJbnB1dCAqKkR5bmFtaWNPcGVyYXRpb25zKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gaXRlbSBMJ29nZ2V0dG8gc3UgY3VpIHZhIGVmZmV0dHVhdGEgbCdvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb3BpZCBDb2RpY2UgaWRlbnRpZmljYXRpdm8gZGVsbCdvcGVyYXppb25lIGRhIGVmZmV0dHVhcnNpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkeW5hbWljT3BlcmF0aW9uKGl0ZW06IGFueSwgb3BpZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5vbkR5bmFtaWNPcGVyYXRpb24uZW1pdCh7IGlkOiBvcGlkLCBpdGVtOiBpdGVtIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3R0aWVuZSBpbCBjb250ZW51dG8gZGVsbCdFc1RkIGRhIHV0aWxpenphcmUgcGVyIGxhIGNvbG9ubmEgc3BlY2lmaWNhdGFcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbHVtbiBDb2xvbm5hIHBlciBjdWkgY2VyY2FyZSBsYSBjZWxsYVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7VGVtcGxhdGVSZWY8YW55Pn0gVGVtcGxhdGUgZGEgdXNhcmUgcGVyIGxhIGNvbG9ubmFcclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpbmRFc1RkKGNvbHVtbjogc3RyaW5nKTogVGVtcGxhdGVSZWY8YW55PiB7XHJcbiAgICAgICAgdmFyIEVzVGQgPSB0aGlzLkVzVGRzRGlyZWN0aXZlLmZpbmQoKGl0ZW0pID0+IGl0ZW0udGQgPT09IGNvbHVtbik7XHJcbiAgICAgICAgcmV0dXJuIEVzVGQgPyBFc1RkLlRlbXBsYXRlIDogbnVsbDtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcXVpdmFsZW50ZSBkZWwgbWV0b2RvICoqYWRkVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgTnVtZXJvIGRpIHBhZ2luZSBkYSBhZ2dpdW5nZXJlIChvIHNvdHRyYXJyZSwgc2UgbmVnYXRpdm8pIGFsbGEgcGFnaW5hIGF0dHVhbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFycmF5QWRkVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuYXJyYXlHb1RvUGFnZSh0aGlzLmFycmF5bW9kZVBhZ2UgKyBwYWdlKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXF1aXZhbGVudGUgZGVsIG1ldG9kbyAqKmdvVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhcnJheUdvVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IHBhZ2UgPiB0aGlzLmFycmF5bW9kZVBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy5hcnJheW1vZGVQYWdlID0gcGFnZTtcclxuXHJcbiAgICAgICAgLy8gUmlmb3J6byBpbCB3cml0ZXZhbHVlIGluIG1vZG8gY2hlIGlsIGNvZGljZSBwYXNzaSBkYWxsYSBnZXN0aW9uZSBjb21lIHNlIGZvc3NlIGZhdHRhIHJpcGFydGlyZSB1bmEgcmljZXJjYVxyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZVZhbHVlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0b3JlIGRlaSBjbGljayBzdWxsZSBjZWxsZSBwZXIgbGUgcXVhbGkgZXJhIGltcG9zdGF0YSB1bmEgYXppb25lIGN1c3RvbSBkYSAqKkN1c3RvbUNlbGxBY3Rpb25zT24qKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5vbWUgZGVsbGEgY2VsbGEgc3UgY3VpIHNpIMOoIGZhdHRvIGNsaWNrXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gbW9kZWwgTW9kZWxsbyByZWxhdGl2byBhbGxhIGNlbGxhIGNsaWNjYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGlsIGNsaWNrIMOoIHN0YXRvIGZhdHRvIHN1IHVuYSBjZWxsYSBjbGljY2FiaWxlLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2VsbENsaWNrZWQobmFtZTogc3RyaW5nLCBtb2RlbDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKHRoaXMuVXNlQ3VzdG9tQ2VsbEFjdGlvbnMgJiYgdGhpcy5DdXN0b21DZWxsQWN0aW9uc09uLnNwbGl0KCckJykuaW5kZXhPZihuYW1lKSAhPSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2VsbENsaWNrLmVtaXQoeyBjb2x1bW46IG5hbWUsIG1vZGVsOiBtb2RlbCB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aW9uZSBkZWkgY2xpY2sgc3VsbGUgb3B6aW9uaSBkZWwgbWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSBnZW5lcmF0byBkYWxsJ0lucHV0ICoqQ29ybmVyTWVudU9wdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb3JuZXJpZCBDb2RpY2UgZGVsbCdvcGVyYXppb25lIHNlbGV6aW9uYXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb3JuZXJBY3Rpb25DbGlja2VkKGNvcm5lcmlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uQ29ybmVyQWN0aW9uLmVtaXQoeyBpZDogY29ybmVyaWQsIGVzdGFibGU6IHRoaXMgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogSW1wb3N0YXppb25lIG1vZGFsaXTDoCBkZWxsJ0VzVGFibGUgXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7J2FycmF5JyB8ICd2aWV3JyB8ICdyZXBvcnQnfSBtb2RlIE1vZGFsaXTDoCBkYSBpbXBvc3RhcmVcclxuICAgICAqKi9cclxuICAgIHByaXZhdGUgc2V0TW9kZShtb2RlOiAnYXJyYXknIHwgJ3ZpZXcnIHwgJ3JlcG9ydCcpIHtcclxuICAgICAgICB0aGlzLnZpZXdNb2RlID0gbW9kZSA9PSAndmlldyc7XHJcbiAgICAgICAgdGhpcy5hcnJheU1vZGUgPSBtb2RlID09ICdhcnJheSc7XHJcbiAgICAgICAgdGhpcy5yZXBvcnRNb2RlID0gbW9kZSA9PSAncmVwb3J0JztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucmVwb3J0TW9kZSkge1xyXG4gICAgICAgICAgICAvLyBJbiBtb2RhbGl0w6AgcmVwb3J0IGhvIGRpIHNpY3VybyBxdWVzdGUgZHVlXHJcbiAgICAgICAgICAgIHRoaXMuWExTWEV4cG9ydCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuQ1NWRXhwb3J0ID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHBlciBlZmZldHR1YXJlIGNoaWFtYXRlIGludGVybmUgZGkgYWxsaW5lYW1lbnRvIGFsbGEgZnVuemlvbmUgKip3cml0ZVZhbHVlKiosIFxyXG4gICAgICogaW1wb3N0YW5kbyBwcmltYSAqKmludGVybmFsV3JpdGVDYWxsKiogaW4gbW9kbyBkYSBub24gZWZmZXR0dWFyZSBvcGVyYXppb25pIGludXRpbGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGludGVybmFsV3JpdGVWYWx1ZSgpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsV3JpdGVDYWxsID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5WaWV3KTtcclxuICAgICAgICB0aGlzLmludGVybmFsV3JpdGVDYWxsID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gZXZlbnR1YWxtZW50ZSByaWNoaWFtYWJpbGUgYW5jaGUgZGFsIGNvbXBvbmVudGUgZXN0ZXJubyBjaGUgcGVybWV0dGUgZGkgZm9yemFyZSB1biByZWZyZXNoIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIGZvcmNlUmVmcmVzaCgpIHtcclxuXHJcbiAgICAgICAgLy8gU2Ugc29ubyBpbiBtb2RhbGl0w6AgVmlldyB2aWVuZSBtYW50ZW51dG8gaW4gYXV0b21hdGljbyBpbCBudW1lcm8gZGkgcGFnaW5hLCBtYSBwZXIgbGEgbW9kYWxpdMOgIGFycmF5IGRldm8gcHJlbmRlcmUgbGUgaW5mbyBkaSBwYWdpbmF6aW9uZSBwcmltYSBlIHJpYXBwbGljYXJsZSBkb3BvXHJcbiAgICAgICAgbGV0IGFycmF5UGFnZTogbnVtYmVyO1xyXG4gICAgICAgIGxldCBhcnJheUlwcDogbnVtYmVyO1xyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSkge1xyXG4gICAgICAgICAgICBhcnJheVBhZ2UgPSB0aGlzLmFycmF5bW9kZVBhZ2U7XHJcbiAgICAgICAgICAgIGFycmF5SXBwID0gdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5WaWV3KTtcclxuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IGFycmF5SXBwO1xyXG4gICAgICAgICAgICB0aGlzLmFycmF5R29Ub1BhZ2UoYXJyYXlQYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn0iXX0=
|