@esfaenza/extensions 12.2.13 → 13.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/esfaenza-extensions.d.ts +1 -2
  2. package/esm2020/esfaenza-extensions.mjs +5 -0
  3. package/{esm2015/lib/models/CallResult.js → esm2020/lib/models/CallResult.mjs} +0 -0
  4. package/{esm2015/lib/models/CsvHeaders.js → esm2020/lib/models/CsvHeaders.mjs} +1 -1
  5. package/{esm2015/lib/models/ExportConsts.js → esm2020/lib/models/ExportConsts.mjs} +0 -0
  6. package/{esm2015/lib/models/ExtensionsModuleConfig.js → esm2020/lib/models/ExtensionsModuleConfig.mjs} +0 -0
  7. package/{esm2015/lib/models/GenericItem.js → esm2020/lib/models/GenericItem.mjs} +0 -0
  8. package/{esm2015/lib/models/TypeCode.js → esm2020/lib/models/TypeCode.mjs} +0 -0
  9. package/{esm2015/lib/models/providers/base/BaseStorageProvider.js → esm2020/lib/models/providers/base/BaseStorageProvider.mjs} +0 -0
  10. package/esm2020/lib/models/providers/implementation/DefaultStorageProvider.mjs +79 -0
  11. package/{esm2015/lib/models/session/base/BaseSessionRetriever.js → esm2020/lib/models/session/base/BaseSessionRetriever.mjs} +0 -0
  12. package/esm2020/lib/models/session/implementation/DefaultSessionRetriever.mjs +28 -0
  13. package/esm2020/lib/modules/extensions.full.module.mjs +58 -0
  14. package/esm2020/lib/modules/extensions.module.mjs +28 -0
  15. package/esm2020/lib/services/extensions.clipboard.service.mjs +165 -0
  16. package/esm2020/lib/services/extensions.dates.service.mjs +232 -0
  17. package/{esm2015/lib/services/extensions.exports.service.js → esm2020/lib/services/extensions.exports.service.mjs} +24 -17
  18. package/esm2020/lib/services/extensions.hashing.service.mjs +309 -0
  19. package/esm2020/lib/services/extensions.messages.service.mjs +323 -0
  20. package/esm2020/lib/services/extensions.storage.service.mjs +103 -0
  21. package/esm2020/lib/services/extensions.utilities.service.mjs +188 -0
  22. package/{esm2015/lib/tokens.js → esm2020/lib/tokens.mjs} +0 -0
  23. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  24. package/fesm2015/{esfaenza-extensions.js → esfaenza-extensions.mjs} +120 -75
  25. package/fesm2015/esfaenza-extensions.mjs.map +1 -0
  26. package/fesm2020/esfaenza-extensions.mjs +2055 -0
  27. package/fesm2020/esfaenza-extensions.mjs.map +1 -0
  28. package/lib/models/CsvHeaders.d.ts +4 -0
  29. package/lib/models/providers/implementation/DefaultStorageProvider.d.ts +3 -0
  30. package/lib/models/session/implementation/DefaultSessionRetriever.d.ts +3 -0
  31. package/lib/modules/extensions.full.module.d.ts +4 -0
  32. package/lib/modules/extensions.module.d.ts +4 -0
  33. package/lib/services/extensions.clipboard.service.d.ts +3 -0
  34. package/lib/services/extensions.dates.service.d.ts +3 -0
  35. package/lib/services/extensions.exports.service.d.ts +3 -0
  36. package/lib/services/extensions.hashing.service.d.ts +3 -0
  37. package/lib/services/extensions.messages.service.d.ts +3 -0
  38. package/lib/services/extensions.storage.service.d.ts +3 -0
  39. package/lib/services/extensions.utilities.service.d.ts +3 -0
  40. package/package.json +22 -10
  41. package/bundles/esfaenza-extensions.umd.js +0 -2435
  42. package/bundles/esfaenza-extensions.umd.js.map +0 -1
  43. package/esfaenza-extensions.metadata.json +0 -1
  44. package/esm2015/esfaenza-extensions.js +0 -7
  45. package/esm2015/lib/models/providers/implementation/DefaultStorageProvider.js +0 -79
  46. package/esm2015/lib/models/session/implementation/DefaultSessionRetriever.js +0 -26
  47. package/esm2015/lib/modules/extensions.full.module.js +0 -54
  48. package/esm2015/lib/modules/extensions.module.js +0 -24
  49. package/esm2015/lib/services/extensions.clipboard.service.js +0 -165
  50. package/esm2015/lib/services/extensions.dates.service.js +0 -224
  51. package/esm2015/lib/services/extensions.hashing.service.js +0 -306
  52. package/esm2015/lib/services/extensions.messages.service.js +0 -317
  53. package/esm2015/lib/services/extensions.storage.service.js +0 -100
  54. package/esm2015/lib/services/extensions.utilities.service.js +0 -185
  55. package/fesm2015/esfaenza-extensions.js.map +0 -1
@@ -0,0 +1,323 @@
1
+ // Angular
2
+ import { Injectable, Inject, Optional } from "@angular/core";
3
+ import swal from "sweetalert2";
4
+ // Modelli
5
+ import { EXT_LOCALE, EXT_FANCY_ALERTS } from "../tokens";
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "ngx-toastr";
8
+ /**
9
+ * Service che fornisce funzionalità di alert nei tipi fondamentali: success, info, warning e danger
10
+ */
11
+ export class MessageService {
12
+ /**
13
+ * Costruttore
14
+ *
15
+ * @ignore
16
+ */
17
+ constructor(toastr, FANCY_ALERTS, LOCALE) {
18
+ this.toastr = toastr;
19
+ this.FANCY_ALERTS = FANCY_ALERTS;
20
+ this.LOCALE = LOCALE;
21
+ /**
22
+ * Oggetto statico in supporto alla localizzazione
23
+ */
24
+ this.loc = {
25
+ 'Confirm': { 'en-US': "Confirm", 'it-IT': "Conferma", },
26
+ 'Cancel': { 'en-US': "Cancel", 'it-IT': "Annulla", },
27
+ 'Close': { 'en-US': "Close", 'it-IT': "Chiudi", },
28
+ 'Error': { 'en-US': "Error", 'it-IT': "Errore", },
29
+ 'Info': { 'en-US': "Info", 'it-IT': "Informazione", },
30
+ 'Success': { 'en-US': "Success", 'it-IT': "Successo", },
31
+ 'Warning': { 'en-US': "Warning", 'it-IT': "Attenzione", }
32
+ };
33
+ this.expiredSessionSwal = swal.mixin({
34
+ showCancelButton: false,
35
+ confirmButtonText: 'Login',
36
+ customClass: {
37
+ confirmButton: "btn btn-primary",
38
+ container: "app-wrap",
39
+ },
40
+ buttonsStyling: false,
41
+ reverseButtons: false,
42
+ allowOutsideClick: false,
43
+ icon: "warning"
44
+ });
45
+ this.warningSwalWithCancel = swal.mixin({
46
+ title: this.loc["Warning"][this.LOCALE ?? 'it-IT'],
47
+ customClass: {
48
+ confirmButton: "btn btn-primary",
49
+ cancelButton: "btn btn-secondary app-margin-right-10",
50
+ container: "app-wrap",
51
+ },
52
+ buttonsStyling: false,
53
+ reverseButtons: true,
54
+ showCancelButton: true,
55
+ confirmButtonText: this.loc["Confirm"][this.LOCALE ?? 'it-IT'],
56
+ cancelButtonText: this.loc["Cancel"][this.LOCALE ?? 'it-IT'],
57
+ icon: "warning"
58
+ });
59
+ this.warningSwal = swal.mixin({
60
+ title: this.loc["Warning"][this.LOCALE ?? 'it-IT'],
61
+ customClass: {
62
+ confirmButton: "btn btn-primary",
63
+ container: "app-wrap",
64
+ },
65
+ buttonsStyling: false,
66
+ reverseButtons: true,
67
+ showCancelButton: false,
68
+ confirmButtonText: this.loc["Close"][this.LOCALE ?? 'it-IT'],
69
+ icon: "warning"
70
+ });
71
+ this.successSwal = swal.mixin({
72
+ title: this.loc["Success"][this.LOCALE ?? 'it-IT'],
73
+ customClass: {
74
+ confirmButton: "btn btn-primary",
75
+ container: "app-wrap",
76
+ },
77
+ buttonsStyling: false,
78
+ reverseButtons: true,
79
+ showCancelButton: false,
80
+ confirmButtonText: this.loc["Close"][this.LOCALE ?? 'it-IT'],
81
+ icon: "success"
82
+ });
83
+ this.errorSwal = swal.mixin({
84
+ title: this.loc["Error"][this.LOCALE ?? 'it-IT'],
85
+ customClass: {
86
+ confirmButton: "btn btn-primary",
87
+ container: "app-wrap",
88
+ },
89
+ buttonsStyling: false,
90
+ reverseButtons: true,
91
+ showCancelButton: false,
92
+ confirmButtonText: this.loc["Close"][this.LOCALE ?? 'it-IT'],
93
+ icon: "error"
94
+ });
95
+ this.infoSwal = swal.mixin({
96
+ title: this.loc["Info"][this.LOCALE ?? 'it-IT'],
97
+ customClass: {
98
+ confirmButton: "btn btn-primary",
99
+ container: "app-wrap",
100
+ },
101
+ buttonsStyling: false,
102
+ reverseButtons: true,
103
+ showCancelButton: false,
104
+ confirmButtonText: this.loc["Close"][this.LOCALE ?? 'it-IT'],
105
+ icon: "info"
106
+ });
107
+ }
108
+ /**
109
+ * Presentazione di un semplice messaggio di successo
110
+ *
111
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
112
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
113
+ *
114
+ * @param {string} text Testo da mostrare
115
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
116
+ */
117
+ simpleSuccess(text, secondaryNotificationType = null) {
118
+ let tos = this.toastrOrSwal(secondaryNotificationType);
119
+ if (tos == "swal")
120
+ this.successSwal.fire("", text);
121
+ else
122
+ this.toastr.success(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: tos == "toastr" ? 0 : 5000, extendedTimeOut: tos == "toastr" ? 0 : 1000 });
123
+ }
124
+ /**
125
+ * Presentazione di un semplice messaggio di informazione
126
+ *
127
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
128
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
129
+ *
130
+ * @param {string} text Testo da mostrare
131
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
132
+ */
133
+ simpleInfo(text, secondaryNotificationType = null) {
134
+ let tos = this.toastrOrSwal(secondaryNotificationType);
135
+ if (tos == "swal")
136
+ this.infoSwal.fire("", text);
137
+ else
138
+ this.toastr.info(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: tos == "toastr" ? 0 : 5000, extendedTimeOut: tos == "toastr" ? 0 : 1000 });
139
+ }
140
+ /**
141
+ * Presentazione di un semplice messaggio di errore
142
+ *
143
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
144
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
145
+ *
146
+ * @param {string} text Testo da mostrare
147
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
148
+ */
149
+ simpleError(text, secondaryNotificationType = null) {
150
+ let tos = this.toastrOrSwal(secondaryNotificationType);
151
+ if (tos == "swal")
152
+ this.errorSwal.fire("", text);
153
+ else
154
+ this.toastr.error(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: tos == "toastr" ? 0 : 5000, extendedTimeOut: tos == "toastr" ? 0 : 1000 });
155
+ }
156
+ /**
157
+ * Presentazione di un semplice messaggio di avviso
158
+ *
159
+ * Se viene chiamato con le impostazioni di default e toastr è abilitato, viene mostrato al centro
160
+ * Se viene chiamato con override su toastr vuol dire che è una notifica secondaria e appare in alto a destra
161
+ *
162
+ * @param {string} text Testo da mostrare
163
+ * @param {"toastr" | "swal" | null} secondaryNotificationType Qualora sia una notifica secondaria, ne indica il tipo
164
+ */
165
+ simpleWarning(text, secondaryNotificationType = null) {
166
+ let tos = this.toastrOrSwal(secondaryNotificationType);
167
+ if (tos == "swal")
168
+ this.warningSwal.fire("", text);
169
+ else
170
+ this.toastr.warning(text, null, { positionClass: tos == "toastr" ? "toast-top-right" : "toast-top-center", timeOut: tos == "toastr" ? 0 : 5000, extendedTimeOut: tos == "toastr" ? 0 : 1000 });
171
+ }
172
+ /**
173
+ * Ripulisce tutti i messaggi presenti in un dato momento sullo schermo
174
+ */
175
+ clearMessages() {
176
+ this.toastr.clear();
177
+ swal.close();
178
+ }
179
+ /**
180
+ * Mostra un messaggio di avviso con richiesta di conferma
181
+ *
182
+ * @param {string} title Titolo del messaggio
183
+ * @param {string} text Contenuto del messaggio
184
+ *
185
+ * @returns {Promise} Restituisce una Promise col risultato scelto dall'utente (conferma o no)
186
+ */
187
+ promiseWarningWithChoice(title, text) {
188
+ return this.warningSwalWithCancel.fire(title, text);
189
+ }
190
+ /**
191
+ * In base alla configurazione attuale e all'eventuale override per la chiamata del caso indica se bisogna utilizzare toastr o sweetalert
192
+ *
193
+ * @param {"toastr" | "swal" | null} providerOverride Override alla modalità configurata
194
+ *
195
+ * @returns {"toastr" | "swal"} Indicazione su che provider di messaggi di avviso debba essere utilizzato
196
+ */
197
+ toastrOrSwal(providerOverride) {
198
+ if (providerOverride != null)
199
+ return providerOverride;
200
+ return this.FANCY_ALERTS == null ? "swal" : this.FANCY_ALERTS ? "swal" : "toastr";
201
+ }
202
+ /**
203
+ * Mostra un messaggio di avviso con richiesta di conferma e gestisce il risultato chiamato i callback **onsuccess** o **onerror**
204
+ *
205
+ * @param {string} title Titolo del messaggio
206
+ * @param {string} text Contenuto del messaggio
207
+ * @param {Function} onsuccess Callback da chimare su conferma
208
+ * @param {Function} onerror Callback da chimare su errori
209
+ */
210
+ simpleWarningWithChoice(title, text, onsuccess = null, onerror = null) {
211
+ this.warningSwalWithCancel.fire(title, text).then((result) => {
212
+ if (result.value && onsuccess)
213
+ onsuccess();
214
+ else if (onerror)
215
+ onerror();
216
+ });
217
+ }
218
+ /**
219
+ * Mostra un messaggio di avviso che la sessione corrente è scaduta e propone all'utente di navigare al login. Qualora l'utente decidesse di farlo
220
+ * verrà chiamata la funzione di callback **onnavigate
221
+ *
222
+ * @param {string} title Titolo del messaggio
223
+ * @param {string} text Contenuto del messaggio
224
+ * @param {Function} onnavigate Callback da chimare su navigazione in corso
225
+ */
226
+ expiredSessionMessage(title, text, onnavigate = null) {
227
+ this.expiredSessionSwal.fire(title, text).then((result) => {
228
+ if (result.value && onnavigate)
229
+ onnavigate();
230
+ });
231
+ }
232
+ /**
233
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **CallResult**
234
+ *
235
+ * @param {CallResult} response Risposta ricevuta dal server
236
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
237
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
238
+ * @param {Function} postSuccess Callback da chimare in caso di successo
239
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
240
+ */
241
+ manageCallResultResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
242
+ if (response.success) {
243
+ if (successMsg)
244
+ this.simpleSuccess(successMsg);
245
+ if (postSuccess)
246
+ postSuccess();
247
+ }
248
+ else if (response.haserror) {
249
+ this.simpleError((errorMsg ? errorMsg + ": " : "") + response.error);
250
+ if (postFailure)
251
+ postFailure();
252
+ }
253
+ else if (response.haswarning) {
254
+ this.simpleWarning(response.warning);
255
+ }
256
+ }
257
+ /**
258
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **string**, considerando che:
259
+ *
260
+ * Stringa vuota --> Tutto bene
261
+ *
262
+ * Stringa piena --> Questo è il messaggio d'errore per cui la chiamata è fallita
263
+ *
264
+ * @param {string} response Risposta ricevuta dal server
265
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
266
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
267
+ * @param {Function} postSuccess Callback da chimare in caso di successo
268
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
269
+ */
270
+ manageStringResponse(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
271
+ if (!response) {
272
+ if (successMsg)
273
+ this.simpleSuccess(successMsg);
274
+ if (postSuccess)
275
+ postSuccess();
276
+ }
277
+ else {
278
+ if (errorMsg)
279
+ this.simpleError(errorMsg + ": " + response);
280
+ if (postFailure)
281
+ postFailure();
282
+ }
283
+ }
284
+ /**
285
+ * Metodo helper per gestire in maniera standardizzata una risposta di tipo **boolean**
286
+ *
287
+ * @param {string} response Risposta ricevuta dal server
288
+ * @param {string} successMsg Messaggio da visualizzare in caso di successo
289
+ * @param {string} errorMsg Messaggio da visualizzare in caso di fallimento
290
+ * @param {Function} postSuccess Callback da chimare in caso di successo
291
+ * @param {Function} postFailure Callback da chimare in caso di fallimento
292
+ */
293
+ manageStringResponseBool(response, successMsg, errorMsg, postSuccess = null, postFailure = null) {
294
+ if (response) {
295
+ if (successMsg)
296
+ this.simpleSuccess(successMsg);
297
+ if (postSuccess)
298
+ postSuccess();
299
+ }
300
+ else {
301
+ if (errorMsg)
302
+ this.simpleError(errorMsg);
303
+ if (postFailure)
304
+ postFailure();
305
+ }
306
+ }
307
+ }
308
+ MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: MessageService, deps: [{ token: i1.ToastrService }, { token: EXT_FANCY_ALERTS, optional: true }, { token: EXT_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
309
+ MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: MessageService });
310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: MessageService, decorators: [{
311
+ type: Injectable
312
+ }], ctorParameters: function () { return [{ type: i1.ToastrService }, { type: undefined, decorators: [{
313
+ type: Optional
314
+ }, {
315
+ type: Inject,
316
+ args: [EXT_FANCY_ALERTS]
317
+ }] }, { type: undefined, decorators: [{
318
+ type: Optional
319
+ }, {
320
+ type: Inject,
321
+ args: [EXT_LOCALE]
322
+ }] }]; } });
323
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5tZXNzYWdlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zcmMvbGliL3NlcnZpY2VzL2V4dGVuc2lvbnMubWVzc2FnZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTdELE9BQU8sSUFBSSxNQUFNLGFBQWEsQ0FBQztBQUUvQixVQUFVO0FBQ1YsT0FBTyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7O0FBR3pEOztHQUVHO0FBRUgsTUFBTSxPQUFPLGNBQWM7SUE2Q3ZCOzs7O09BSUc7SUFDSCxZQUEyQixNQUFxQixFQUFnRCxZQUFxQixFQUEwQyxNQUFjO1FBQWxKLFdBQU0sR0FBTixNQUFNLENBQWU7UUFBZ0QsaUJBQVksR0FBWixZQUFZLENBQVM7UUFBMEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQWhEN0s7O1dBRUc7UUFDSyxRQUFHLEdBQUc7WUFDVixTQUFTLEVBQUUsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxVQUFVLEdBQUc7WUFDdkQsUUFBUSxFQUFFLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxHQUFHO1lBQ3BELE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsR0FBRztZQUNqRCxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEdBQUc7WUFDakQsTUFBTSxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxHQUFHO1lBQ3JELFNBQVMsRUFBRSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFVBQVUsR0FBRztZQUN2RCxTQUFTLEVBQUUsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxZQUFZLEdBQUc7U0FDNUQsQ0FBQztRQXNDRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUNqQyxnQkFBZ0IsRUFBRSxLQUFLO1lBQ3ZCLGlCQUFpQixFQUFFLE9BQU87WUFDMUIsV0FBVyxFQUFFO2dCQUNULGFBQWEsRUFBRSxpQkFBaUI7Z0JBQ2hDLFNBQVMsRUFBRSxVQUFVO2FBQ3hCO1lBQ0QsY0FBYyxFQUFFLEtBQUs7WUFDckIsY0FBYyxFQUFFLEtBQUs7WUFDckIsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixJQUFJLEVBQUUsU0FBUztTQUNsQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUNwQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQztZQUNsRCxXQUFXLEVBQUU7Z0JBQ1QsYUFBYSxFQUFFLGlCQUFpQjtnQkFDaEMsWUFBWSxFQUFFLHVDQUF1QztnQkFDckQsU0FBUyxFQUFFLFVBQVU7YUFDeEI7WUFDRCxjQUFjLEVBQUUsS0FBSztZQUNyQixjQUFjLEVBQUUsSUFBSTtZQUNwQixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLGlCQUFpQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7WUFDOUQsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQztZQUM1RCxJQUFJLEVBQUUsU0FBUztTQUNsQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDMUIsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7WUFDbEQsV0FBVyxFQUFFO2dCQUNULGFBQWEsRUFBRSxpQkFBaUI7Z0JBQ2hDLFNBQVMsRUFBRSxVQUFVO2FBQ3hCO1lBQ0QsY0FBYyxFQUFFLEtBQUs7WUFDckIsY0FBYyxFQUFFLElBQUk7WUFDcEIsZ0JBQWdCLEVBQUUsS0FBSztZQUN2QixpQkFBaUIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDO1lBQzVELElBQUksRUFBRSxTQUFTO1NBQ2xCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUMxQixLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQztZQUNsRCxXQUFXLEVBQUU7Z0JBQ1QsYUFBYSxFQUFFLGlCQUFpQjtnQkFDaEMsU0FBUyxFQUFFLFVBQVU7YUFDeEI7WUFDRCxjQUFjLEVBQUUsS0FBSztZQUNyQixjQUFjLEVBQUUsSUFBSTtZQUNwQixnQkFBZ0IsRUFBRSxLQUFLO1lBQ3ZCLGlCQUFpQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7WUFDNUQsSUFBSSxFQUFFLFNBQVM7U0FDbEIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3hCLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDO1lBQ2hELFdBQVcsRUFBRTtnQkFDVCxhQUFhLEVBQUUsaUJBQWlCO2dCQUNoQyxTQUFTLEVBQUUsVUFBVTthQUN4QjtZQUNELGNBQWMsRUFBRSxLQUFLO1lBQ3JCLGNBQWMsRUFBRSxJQUFJO1lBQ3BCLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQztZQUM1RCxJQUFJLEVBQUUsT0FBTztTQUNoQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDdkIsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7WUFDL0MsV0FBVyxFQUFFO2dCQUNULGFBQWEsRUFBRSxpQkFBaUI7Z0JBQ2hDLFNBQVMsRUFBRSxVQUFVO2FBQ3hCO1lBQ0QsY0FBYyxFQUFFLEtBQUs7WUFDckIsY0FBYyxFQUFFLElBQUk7WUFDcEIsZ0JBQWdCLEVBQUUsS0FBSztZQUN2QixpQkFBaUIsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDO1lBQzVELElBQUksRUFBRSxNQUFNO1NBQ2YsQ0FBQyxDQUFDO0lBRVAsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksYUFBYSxDQUFDLElBQVksRUFBRSw0QkFBc0QsSUFBSTtRQUN6RixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFdkQsSUFBSSxHQUFHLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzs7WUFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxFQUFHLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRyxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBQyxDQUFDLENBQUM7SUFDek0sQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksVUFBVSxDQUFDLElBQVksRUFBRSw0QkFBc0QsSUFBSTtRQUN0RixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFdkQsSUFBSSxHQUFHLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzs7WUFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxFQUFHLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRyxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdk0sQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksV0FBVyxDQUFDLElBQVksRUFBRSw0QkFBc0QsSUFBSTtRQUN2RixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFdkQsSUFBSSxHQUFHLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzs7WUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxFQUFHLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRyxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDeE0sQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksYUFBYSxDQUFDLElBQVksRUFBRSw0QkFBc0QsSUFBSTtRQUN6RixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFdkQsSUFBSSxHQUFHLElBQUksTUFBTTtZQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzs7WUFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxFQUFHLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRyxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDMU0sQ0FBQztJQUVEOztPQUVHO0lBQ0ksYUFBYTtRQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLHdCQUF3QixDQUFDLEtBQWEsRUFBRSxJQUFZO1FBQ3ZELE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLFlBQVksQ0FBQyxnQkFBMEM7UUFDM0QsSUFBSSxnQkFBZ0IsSUFBSSxJQUFJO1lBQ3hCLE9BQU8sZ0JBQWdCLENBQUM7UUFDNUIsT0FBTyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztJQUN0RixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLHVCQUF1QixDQUFDLEtBQWEsRUFBRSxJQUFZLEVBQUUsWUFBc0IsSUFBSSxFQUFFLFVBQW9CLElBQUk7UUFDNUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDekQsSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLFNBQVM7Z0JBQ3pCLFNBQVMsRUFBRSxDQUFDO2lCQUNYLElBQUksT0FBTztnQkFDWixPQUFPLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0kscUJBQXFCLENBQUMsS0FBYSxFQUFFLElBQVksRUFBRSxhQUF1QixJQUFJO1FBQ2pGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3RELElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxVQUFVO2dCQUMxQixVQUFVLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNJLHdCQUF3QixDQUFDLFFBQW9CLEVBQUUsVUFBa0IsRUFBRSxRQUFnQixFQUFFLGNBQXdCLElBQUksRUFBRSxjQUF3QixJQUFJO1FBQ2xKLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRTtZQUNsQixJQUFJLFVBQVU7Z0JBQ1YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVuQyxJQUFJLFdBQVc7Z0JBQUUsV0FBVyxFQUFFLENBQUM7U0FDbEM7YUFBTSxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXJFLElBQUksV0FBVztnQkFBRSxXQUFXLEVBQUUsQ0FBQztTQUNsQzthQUNJLElBQUksUUFBUSxDQUFDLFVBQVUsRUFBRTtZQUMxQixJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN4QztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxvQkFBb0IsQ0FBQyxRQUFnQixFQUFFLFVBQWtCLEVBQUUsUUFBZ0IsRUFBRSxjQUF3QixJQUFJLEVBQUUsY0FBd0IsSUFBSTtRQUMxSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ1gsSUFBSSxVQUFVO2dCQUNWLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFbkMsSUFBSSxXQUFXO2dCQUFFLFdBQVcsRUFBRSxDQUFDO1NBQ2xDO2FBQU07WUFDSCxJQUFJLFFBQVE7Z0JBQ1IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDO1lBRWpELElBQUksV0FBVztnQkFBRSxXQUFXLEVBQUUsQ0FBQztTQUNsQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNJLHdCQUF3QixDQUFDLFFBQWlCLEVBQUUsVUFBa0IsRUFBRSxRQUFnQixFQUFFLGNBQXdCLElBQUksRUFBRSxjQUF3QixJQUFJO1FBQy9JLElBQUksUUFBUSxFQUFFO1lBQ1YsSUFBSSxVQUFVO2dCQUNWLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFbkMsSUFBSSxXQUFXO2dCQUFFLFdBQVcsRUFBRSxDQUFDO1NBQ2xDO2FBQU07WUFDSCxJQUFJLFFBQVE7Z0JBQ1IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUvQixJQUFJLFdBQVc7Z0JBQUUsV0FBVyxFQUFFLENBQUM7U0FDbEM7SUFDTCxDQUFDOzsyR0EvVVEsY0FBYywrQ0FrRCtDLGdCQUFnQiw2QkFBcUQsVUFBVTsrR0FsRDVJLGNBQWM7MkZBQWQsY0FBYztrQkFEMUIsVUFBVTs7MEJBbUQ0QyxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGdCQUFnQjs7MEJBQWtDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuZ3VsYXJcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0LCBPcHRpb25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG4vLyBDb25maWd1cmF6aW9uaVxyXG5pbXBvcnQgeyBUb2FzdHJTZXJ2aWNlIH0gZnJvbSBcIm5neC10b2FzdHJcIjtcclxuaW1wb3J0IHN3YWwgZnJvbSBcInN3ZWV0YWxlcnQyXCI7XHJcblxyXG4vLyBNb2RlbGxpXHJcbmltcG9ydCB7IEVYVF9MT0NBTEUsIEVYVF9GQU5DWV9BTEVSVFMgfSBmcm9tIFwiLi4vdG9rZW5zXCI7XHJcbmltcG9ydCB7IENhbGxSZXN1bHQgfSBmcm9tIFwiLi4vbW9kZWxzL0NhbGxSZXN1bHRcIjtcclxuXHJcbi8qKlxyXG4gKiBTZXJ2aWNlIGNoZSBmb3JuaXNjZSBmdW56aW9uYWxpdMOgIGRpIGFsZXJ0IG5laSB0aXBpIGZvbmRhbWVudGFsaTogc3VjY2VzcywgaW5mbywgd2FybmluZyBlIGRhbmdlclxyXG4gKi9cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTWVzc2FnZVNlcnZpY2Uge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2dnZXR0byBzdGF0aWNvIGluIHN1cHBvcnRvIGFsbGEgbG9jYWxpenphemlvbmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBsb2MgPSB7XHJcbiAgICAgICAgJ0NvbmZpcm0nOiB7ICdlbi1VUyc6IFwiQ29uZmlybVwiLCAnaXQtSVQnOiBcIkNvbmZlcm1hXCIsIH0sXHJcbiAgICAgICAgJ0NhbmNlbCc6IHsgJ2VuLVVTJzogXCJDYW5jZWxcIiwgJ2l0LUlUJzogXCJBbm51bGxhXCIsIH0sXHJcbiAgICAgICAgJ0Nsb3NlJzogeyAnZW4tVVMnOiBcIkNsb3NlXCIsICdpdC1JVCc6IFwiQ2hpdWRpXCIsIH0sXHJcbiAgICAgICAgJ0Vycm9yJzogeyAnZW4tVVMnOiBcIkVycm9yXCIsICdpdC1JVCc6IFwiRXJyb3JlXCIsIH0sXHJcbiAgICAgICAgJ0luZm8nOiB7ICdlbi1VUyc6IFwiSW5mb1wiLCAnaXQtSVQnOiBcIkluZm9ybWF6aW9uZVwiLCB9LFxyXG4gICAgICAgICdTdWNjZXNzJzogeyAnZW4tVVMnOiBcIlN1Y2Nlc3NcIiwgJ2l0LUlUJzogXCJTdWNjZXNzb1wiLCB9LFxyXG4gICAgICAgICdXYXJuaW5nJzogeyAnZW4tVVMnOiBcIldhcm5pbmdcIiwgJ2l0LUlUJzogXCJBdHRlbnppb25lXCIsIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSBkaSB1biB3YXJuaW5nIGNvbiByaWNoaWVzdGEgZGkgY29uZmVybWFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSB3YXJuaW5nU3dhbFdpdGhDYW5jZWw6IGFueTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIGRpIHVuIGVycm9yZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGVycm9yU3dhbDogYW55O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVtcGxhdGUgZGkgdW4gbWVzc2FnZ2lvIGRpIHN1Y2Nlc3NvXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3VjY2Vzc1N3YWw6IGFueTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlbXBsYXRlIGRpIHVuIGF2dmlzb1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHdhcm5pbmdTd2FsOiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZW1wbGF0ZSBkaSB1biBtZXNzYWdnaW8gaW5mb3JtYXRpdm9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbmZvU3dhbDogYW55O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVtcGxhdGUgZGkgdW4gd2FybmluZyBwZXIgbGEgc2Vzc2lvbmUgc2NhZHV0YVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV4cGlyZWRTZXNzaW9uU3dhbDogYW55O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29zdHJ1dHRvcmUgXHJcbiAgICAgKiBcclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgdG9hc3RyOiBUb2FzdHJTZXJ2aWNlLCBAT3B0aW9uYWwoKSBASW5qZWN0KEVYVF9GQU5DWV9BTEVSVFMpIHByaXZhdGUgRkFOQ1lfQUxFUlRTOiBib29sZWFuLCBAT3B0aW9uYWwoKSBASW5qZWN0KEVYVF9MT0NBTEUpIHByaXZhdGUgTE9DQUxFOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmV4cGlyZWRTZXNzaW9uU3dhbCA9IHN3YWwubWl4aW4oe1xyXG4gICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiBmYWxzZSxcclxuICAgICAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6ICdMb2dpbicsXHJcbiAgICAgICAgICAgIGN1c3RvbUNsYXNzOiB7XHJcbiAgICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiBcImJ0biBidG4tcHJpbWFyeVwiLFxyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBcImFwcC13cmFwXCIsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGJ1dHRvbnNTdHlsaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgcmV2ZXJzZUJ1dHRvbnM6IGZhbHNlLFxyXG4gICAgICAgICAgICBhbGxvd091dHNpZGVDbGljazogZmFsc2UsXHJcbiAgICAgICAgICAgIGljb246IFwid2FybmluZ1wiXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMud2FybmluZ1N3YWxXaXRoQ2FuY2VsID0gc3dhbC5taXhpbih7XHJcbiAgICAgICAgICAgIHRpdGxlOiB0aGlzLmxvY1tcIldhcm5pbmdcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ10sXHJcbiAgICAgICAgICAgIGN1c3RvbUNsYXNzOiB7XHJcbiAgICAgICAgICAgICAgICBjb25maXJtQnV0dG9uOiBcImJ0biBidG4tcHJpbWFyeVwiLFxyXG4gICAgICAgICAgICAgICAgY2FuY2VsQnV0dG9uOiBcImJ0biBidG4tc2Vjb25kYXJ5IGFwcC1tYXJnaW4tcmlnaHQtMTBcIixcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogXCJhcHAtd3JhcFwiLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBidXR0b25zU3R5bGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgIHJldmVyc2VCdXR0b25zOiB0cnVlLFxyXG4gICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maXJtQnV0dG9uVGV4dDogdGhpcy5sb2NbXCJDb25maXJtXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddLFxyXG4gICAgICAgICAgICBjYW5jZWxCdXR0b25UZXh0OiB0aGlzLmxvY1tcIkNhbmNlbFwiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXSxcclxuICAgICAgICAgICAgaWNvbjogXCJ3YXJuaW5nXCJcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy53YXJuaW5nU3dhbCA9IHN3YWwubWl4aW4oe1xyXG4gICAgICAgICAgICB0aXRsZTogdGhpcy5sb2NbXCJXYXJuaW5nXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddLFxyXG4gICAgICAgICAgICBjdXN0b21DbGFzczoge1xyXG4gICAgICAgICAgICAgICAgY29uZmlybUJ1dHRvbjogXCJidG4gYnRuLXByaW1hcnlcIixcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogXCJhcHAtd3JhcFwiLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBidXR0b25zU3R5bGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgIHJldmVyc2VCdXR0b25zOiB0cnVlLFxyXG4gICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiBmYWxzZSxcclxuICAgICAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6IHRoaXMubG9jW1wiQ2xvc2VcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ10sXHJcbiAgICAgICAgICAgIGljb246IFwid2FybmluZ1wiXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuc3VjY2Vzc1N3YWwgPSBzd2FsLm1peGluKHtcclxuICAgICAgICAgICAgdGl0bGU6IHRoaXMubG9jW1wiU3VjY2Vzc1wiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXSxcclxuICAgICAgICAgICAgY3VzdG9tQ2xhc3M6IHtcclxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b246IFwiYnRuIGJ0bi1wcmltYXJ5XCIsXHJcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IFwiYXBwLXdyYXBcIixcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgYnV0dG9uc1N0eWxpbmc6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXZlcnNlQnV0dG9uczogdHJ1ZSxcclxuICAgICAgICAgICAgc2hvd0NhbmNlbEJ1dHRvbjogZmFsc2UsXHJcbiAgICAgICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiB0aGlzLmxvY1tcIkNsb3NlXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddLFxyXG4gICAgICAgICAgICBpY29uOiBcInN1Y2Nlc3NcIlxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yU3dhbCA9IHN3YWwubWl4aW4oe1xyXG4gICAgICAgICAgICB0aXRsZTogdGhpcy5sb2NbXCJFcnJvclwiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXSxcclxuICAgICAgICAgICAgY3VzdG9tQ2xhc3M6IHtcclxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b246IFwiYnRuIGJ0bi1wcmltYXJ5XCIsXHJcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IFwiYXBwLXdyYXBcIixcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgYnV0dG9uc1N0eWxpbmc6IGZhbHNlLFxyXG4gICAgICAgICAgICByZXZlcnNlQnV0dG9uczogdHJ1ZSxcclxuICAgICAgICAgICAgc2hvd0NhbmNlbEJ1dHRvbjogZmFsc2UsXHJcbiAgICAgICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiB0aGlzLmxvY1tcIkNsb3NlXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddLFxyXG4gICAgICAgICAgICBpY29uOiBcImVycm9yXCJcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbmZvU3dhbCA9IHN3YWwubWl4aW4oe1xyXG4gICAgICAgICAgICB0aXRsZTogdGhpcy5sb2NbXCJJbmZvXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddLFxyXG4gICAgICAgICAgICBjdXN0b21DbGFzczoge1xyXG4gICAgICAgICAgICAgICAgY29uZmlybUJ1dHRvbjogXCJidG4gYnRuLXByaW1hcnlcIixcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogXCJhcHAtd3JhcFwiLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBidXR0b25zU3R5bGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgIHJldmVyc2VCdXR0b25zOiB0cnVlLFxyXG4gICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiBmYWxzZSxcclxuICAgICAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6IHRoaXMubG9jW1wiQ2xvc2VcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ10sXHJcbiAgICAgICAgICAgIGljb246IFwiaW5mb1wiXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlc2VudGF6aW9uZSBkaSB1biBzZW1wbGljZSBtZXNzYWdnaW8gZGkgc3VjY2Vzc29cclxuICAgICAqIFxyXG4gICAgICogU2UgdmllbmUgY2hpYW1hdG8gY29uIGxlIGltcG9zdGF6aW9uaSBkaSBkZWZhdWx0IGUgdG9hc3RyIMOoIGFiaWxpdGF0bywgdmllbmUgbW9zdHJhdG8gYWwgY2VudHJvXHJcbiAgICAgKiBTZSB2aWVuZSBjaGlhbWF0byBjb24gb3ZlcnJpZGUgc3UgdG9hc3RyIHZ1b2wgZGlyZSBjaGUgw6ggdW5hIG5vdGlmaWNhIHNlY29uZGFyaWEgZSBhcHBhcmUgaW4gYWx0byBhIGRlc3RyYVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXN0byBkYSBtb3N0cmFyZVxyXG4gICAgICogQHBhcmFtIHtcInRvYXN0clwiIHwgXCJzd2FsXCIgfCBudWxsfSBzZWNvbmRhcnlOb3RpZmljYXRpb25UeXBlIFF1YWxvcmEgc2lhIHVuYSBub3RpZmljYSBzZWNvbmRhcmlhLCBuZSBpbmRpY2EgaWwgdGlwb1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2ltcGxlU3VjY2Vzcyh0ZXh0OiBzdHJpbmcsIHNlY29uZGFyeU5vdGlmaWNhdGlvblR5cGU6IFwidG9hc3RyXCIgfCBcInN3YWxcIiB8IG51bGwgPSBudWxsKSB7XHJcbiAgICAgICAgbGV0IHRvcyA9IHRoaXMudG9hc3RyT3JTd2FsKHNlY29uZGFyeU5vdGlmaWNhdGlvblR5cGUpO1xyXG5cclxuICAgICAgICBpZiAodG9zID09IFwic3dhbFwiKSB0aGlzLnN1Y2Nlc3NTd2FsLmZpcmUoXCJcIiwgdGV4dCk7XHJcbiAgICAgICAgZWxzZSB0aGlzLnRvYXN0ci5zdWNjZXNzKHRleHQsIG51bGwsIHsgcG9zaXRpb25DbGFzczogdG9zID09IFwidG9hc3RyXCIgPyBcInRvYXN0LXRvcC1yaWdodFwiIDogXCJ0b2FzdC10b3AtY2VudGVyXCIsIHRpbWVPdXQ6ICB0b3MgPT0gXCJ0b2FzdHJcIiA/IDAgOiA1MDAwLCBleHRlbmRlZFRpbWVPdXQ6ICB0b3MgPT0gXCJ0b2FzdHJcIiA/IDAgOiAxMDAwfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVzZW50YXppb25lIGRpIHVuIHNlbXBsaWNlIG1lc3NhZ2dpbyBkaSBpbmZvcm1hemlvbmVcclxuICAgICAqIFxyXG4gICAgICogU2UgdmllbmUgY2hpYW1hdG8gY29uIGxlIGltcG9zdGF6aW9uaSBkaSBkZWZhdWx0IGUgdG9hc3RyIMOoIGFiaWxpdGF0bywgdmllbmUgbW9zdHJhdG8gYWwgY2VudHJvXHJcbiAgICAgKiBTZSB2aWVuZSBjaGlhbWF0byBjb24gb3ZlcnJpZGUgc3UgdG9hc3RyIHZ1b2wgZGlyZSBjaGUgw6ggdW5hIG5vdGlmaWNhIHNlY29uZGFyaWEgZSBhcHBhcmUgaW4gYWx0byBhIGRlc3RyYVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXN0byBkYSBtb3N0cmFyZVxyXG4gICAgICogQHBhcmFtIHtcInRvYXN0clwiIHwgXCJzd2FsXCIgfCBudWxsfSBzZWNvbmRhcnlOb3RpZmljYXRpb25UeXBlIFF1YWxvcmEgc2lhIHVuYSBub3RpZmljYSBzZWNvbmRhcmlhLCBuZSBpbmRpY2EgaWwgdGlwb1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2ltcGxlSW5mbyh0ZXh0OiBzdHJpbmcsIHNlY29uZGFyeU5vdGlmaWNhdGlvblR5cGU6IFwidG9hc3RyXCIgfCBcInN3YWxcIiB8IG51bGwgPSBudWxsKSB7XHJcbiAgICAgICAgbGV0IHRvcyA9IHRoaXMudG9hc3RyT3JTd2FsKHNlY29uZGFyeU5vdGlmaWNhdGlvblR5cGUpO1xyXG5cclxuICAgICAgICBpZiAodG9zID09IFwic3dhbFwiKSB0aGlzLmluZm9Td2FsLmZpcmUoXCJcIiwgdGV4dCk7XHJcbiAgICAgICAgZWxzZSB0aGlzLnRvYXN0ci5pbmZvKHRleHQsIG51bGwsIHsgcG9zaXRpb25DbGFzczogdG9zID09IFwidG9hc3RyXCIgPyBcInRvYXN0LXRvcC1yaWdodFwiIDogXCJ0b2FzdC10b3AtY2VudGVyXCIsIHRpbWVPdXQ6ICB0b3MgPT0gXCJ0b2FzdHJcIiA/IDAgOiA1MDAwLCBleHRlbmRlZFRpbWVPdXQ6ICB0b3MgPT0gXCJ0b2FzdHJcIiA/IDAgOiAxMDAwIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlc2VudGF6aW9uZSBkaSB1biBzZW1wbGljZSBtZXNzYWdnaW8gZGkgZXJyb3JlXHJcbiAgICAgKiBcclxuICAgICAqIFNlIHZpZW5lIGNoaWFtYXRvIGNvbiBsZSBpbXBvc3RhemlvbmkgZGkgZGVmYXVsdCBlIHRvYXN0ciDDqCBhYmlsaXRhdG8sIHZpZW5lIG1vc3RyYXRvIGFsIGNlbnRyb1xyXG4gICAgICogU2UgdmllbmUgY2hpYW1hdG8gY29uIG92ZXJyaWRlIHN1IHRvYXN0ciB2dW9sIGRpcmUgY2hlIMOoIHVuYSBub3RpZmljYSBzZWNvbmRhcmlhIGUgYXBwYXJlIGluIGFsdG8gYSBkZXN0cmFcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGVzdG8gZGEgbW9zdHJhcmVcclxuICAgICAqIEBwYXJhbSB7XCJ0b2FzdHJcIiB8IFwic3dhbFwiIHwgbnVsbH0gc2Vjb25kYXJ5Tm90aWZpY2F0aW9uVHlwZSBRdWFsb3JhIHNpYSB1bmEgbm90aWZpY2Egc2Vjb25kYXJpYSwgbmUgaW5kaWNhIGlsIHRpcG9cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNpbXBsZUVycm9yKHRleHQ6IHN0cmluZywgc2Vjb25kYXJ5Tm90aWZpY2F0aW9uVHlwZTogXCJ0b2FzdHJcIiB8IFwic3dhbFwiIHwgbnVsbCA9IG51bGwpIHtcclxuICAgICAgICBsZXQgdG9zID0gdGhpcy50b2FzdHJPclN3YWwoc2Vjb25kYXJ5Tm90aWZpY2F0aW9uVHlwZSk7XHJcblxyXG4gICAgICAgIGlmICh0b3MgPT0gXCJzd2FsXCIpIHRoaXMuZXJyb3JTd2FsLmZpcmUoXCJcIiwgdGV4dCk7XHJcbiAgICAgICAgZWxzZSB0aGlzLnRvYXN0ci5lcnJvcih0ZXh0LCBudWxsLCB7IHBvc2l0aW9uQ2xhc3M6IHRvcyA9PSBcInRvYXN0clwiID8gXCJ0b2FzdC10b3AtcmlnaHRcIiA6IFwidG9hc3QtdG9wLWNlbnRlclwiLCB0aW1lT3V0OiAgdG9zID09IFwidG9hc3RyXCIgPyAwIDogNTAwMCwgZXh0ZW5kZWRUaW1lT3V0OiAgdG9zID09IFwidG9hc3RyXCIgPyAwIDogMTAwMCB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFByZXNlbnRhemlvbmUgZGkgdW4gc2VtcGxpY2UgbWVzc2FnZ2lvIGRpIGF2dmlzb1xyXG4gICAgICogXHJcbiAgICAgKiBTZSB2aWVuZSBjaGlhbWF0byBjb24gbGUgaW1wb3N0YXppb25pIGRpIGRlZmF1bHQgZSB0b2FzdHIgw6ggYWJpbGl0YXRvLCB2aWVuZSBtb3N0cmF0byBhbCBjZW50cm9cclxuICAgICAqIFNlIHZpZW5lIGNoaWFtYXRvIGNvbiBvdmVycmlkZSBzdSB0b2FzdHIgdnVvbCBkaXJlIGNoZSDDqCB1bmEgbm90aWZpY2Egc2Vjb25kYXJpYSBlIGFwcGFyZSBpbiBhbHRvIGEgZGVzdHJhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRlc3RvIGRhIG1vc3RyYXJlXHJcbiAgICAgKiBAcGFyYW0ge1widG9hc3RyXCIgfCBcInN3YWxcIiB8IG51bGx9IHNlY29uZGFyeU5vdGlmaWNhdGlvblR5cGUgUXVhbG9yYSBzaWEgdW5hIG5vdGlmaWNhIHNlY29uZGFyaWEsIG5lIGluZGljYSBpbCB0aXBvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzaW1wbGVXYXJuaW5nKHRleHQ6IHN0cmluZywgc2Vjb25kYXJ5Tm90aWZpY2F0aW9uVHlwZTogXCJ0b2FzdHJcIiB8IFwic3dhbFwiIHwgbnVsbCA9IG51bGwpIHtcclxuICAgICAgICBsZXQgdG9zID0gdGhpcy50b2FzdHJPclN3YWwoc2Vjb25kYXJ5Tm90aWZpY2F0aW9uVHlwZSk7XHJcblxyXG4gICAgICAgIGlmICh0b3MgPT0gXCJzd2FsXCIpIHRoaXMud2FybmluZ1N3YWwuZmlyZShcIlwiLCB0ZXh0KTtcclxuICAgICAgICBlbHNlIHRoaXMudG9hc3RyLndhcm5pbmcodGV4dCwgbnVsbCwgeyBwb3NpdGlvbkNsYXNzOiB0b3MgPT0gXCJ0b2FzdHJcIiA/IFwidG9hc3QtdG9wLXJpZ2h0XCIgOiBcInRvYXN0LXRvcC1jZW50ZXJcIiwgdGltZU91dDogIHRvcyA9PSBcInRvYXN0clwiID8gMCA6IDUwMDAsIGV4dGVuZGVkVGltZU91dDogIHRvcyA9PSBcInRvYXN0clwiID8gMCA6IDEwMDAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSaXB1bGlzY2UgdHV0dGkgaSBtZXNzYWdnaSBwcmVzZW50aSBpbiB1biBkYXRvIG1vbWVudG8gc3VsbG8gc2NoZXJtb1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2xlYXJNZXNzYWdlcygpIHtcclxuICAgICAgICB0aGlzLnRvYXN0ci5jbGVhcigpO1xyXG4gICAgICAgIHN3YWwuY2xvc2UoKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgLyoqXHJcbiAgICAgKiBNb3N0cmEgdW4gbWVzc2FnZ2lvIGRpIGF2dmlzbyBjb24gcmljaGllc3RhIGRpIGNvbmZlcm1hXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSBUaXRvbG8gZGVsIG1lc3NhZ2dpb1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgQ29udGVudXRvIGRlbCBtZXNzYWdnaW9cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlc3RpdHVpc2NlIHVuYSBQcm9taXNlIGNvbCByaXN1bHRhdG8gc2NlbHRvIGRhbGwndXRlbnRlIChjb25mZXJtYSBvIG5vKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcHJvbWlzZVdhcm5pbmdXaXRoQ2hvaWNlKHRpdGxlOiBzdHJpbmcsIHRleHQ6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud2FybmluZ1N3YWxXaXRoQ2FuY2VsLmZpcmUodGl0bGUsIHRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW4gYmFzZSBhbGxhIGNvbmZpZ3VyYXppb25lIGF0dHVhbGUgZSBhbGwnZXZlbnR1YWxlIG92ZXJyaWRlIHBlciBsYSBjaGlhbWF0YSBkZWwgY2FzbyBpbmRpY2Egc2UgYmlzb2duYSB1dGlsaXp6YXJlIHRvYXN0ciBvIHN3ZWV0YWxlcnRcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtcInRvYXN0clwiIHwgXCJzd2FsXCIgfCBudWxsfSBwcm92aWRlck92ZXJyaWRlIE92ZXJyaWRlIGFsbGEgbW9kYWxpdMOgIGNvbmZpZ3VyYXRhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtcInRvYXN0clwiIHwgXCJzd2FsXCJ9IEluZGljYXppb25lIHN1IGNoZSBwcm92aWRlciBkaSBtZXNzYWdnaSBkaSBhdnZpc28gZGViYmEgZXNzZXJlIHV0aWxpenphdG9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSB0b2FzdHJPclN3YWwocHJvdmlkZXJPdmVycmlkZTogXCJ0b2FzdHJcIiB8IFwic3dhbFwiIHwgbnVsbCk6IFwidG9hc3RyXCIgfCBcInN3YWxcIiB7XHJcbiAgICAgICAgaWYgKHByb3ZpZGVyT3ZlcnJpZGUgIT0gbnVsbClcclxuICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVyT3ZlcnJpZGU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuRkFOQ1lfQUxFUlRTID09IG51bGwgPyBcInN3YWxcIiA6IHRoaXMuRkFOQ1lfQUxFUlRTID8gXCJzd2FsXCIgOiBcInRvYXN0clwiO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTW9zdHJhIHVuIG1lc3NhZ2dpbyBkaSBhdnZpc28gY29uIHJpY2hpZXN0YSBkaSBjb25mZXJtYSBlIGdlc3Rpc2NlIGlsIHJpc3VsdGF0byBjaGlhbWF0byBpIGNhbGxiYWNrICoqb25zdWNjZXNzKiogbyAqKm9uZXJyb3IqKlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGUgVGl0b2xvIGRlbCBtZXNzYWdnaW9cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IENvbnRlbnV0byBkZWwgbWVzc2FnZ2lvXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvbnN1Y2Nlc3MgQ2FsbGJhY2sgZGEgY2hpbWFyZSBzdSBjb25mZXJtYVxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb25lcnJvciBDYWxsYmFjayBkYSBjaGltYXJlIHN1IGVycm9yaVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2ltcGxlV2FybmluZ1dpdGhDaG9pY2UodGl0bGU6IHN0cmluZywgdGV4dDogc3RyaW5nLCBvbnN1Y2Nlc3M6IEZ1bmN0aW9uID0gbnVsbCwgb25lcnJvcjogRnVuY3Rpb24gPSBudWxsKSB7XHJcbiAgICAgICAgdGhpcy53YXJuaW5nU3dhbFdpdGhDYW5jZWwuZmlyZSh0aXRsZSwgdGV4dCkudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQudmFsdWUgJiYgb25zdWNjZXNzKVxyXG4gICAgICAgICAgICAgICAgb25zdWNjZXNzKCk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG9uZXJyb3IpXHJcbiAgICAgICAgICAgICAgICBvbmVycm9yKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNb3N0cmEgdW4gbWVzc2FnZ2lvIGRpIGF2dmlzbyBjaGUgbGEgc2Vzc2lvbmUgY29ycmVudGUgw6ggc2NhZHV0YSBlIHByb3BvbmUgYWxsJ3V0ZW50ZSBkaSBuYXZpZ2FyZSBhbCBsb2dpbi4gUXVhbG9yYSBsJ3V0ZW50ZSBkZWNpZGVzc2UgZGkgZmFybG8gXHJcbiAgICAgKiB2ZXJyw6AgY2hpYW1hdGEgbGEgZnVuemlvbmUgZGkgY2FsbGJhY2sgKipvbm5hdmlnYXRlXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSBUaXRvbG8gZGVsIG1lc3NhZ2dpb1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgQ29udGVudXRvIGRlbCBtZXNzYWdnaW9cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9ubmF2aWdhdGUgQ2FsbGJhY2sgZGEgY2hpbWFyZSBzdSBuYXZpZ2F6aW9uZSBpbiBjb3Jzb1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXhwaXJlZFNlc3Npb25NZXNzYWdlKHRpdGxlOiBzdHJpbmcsIHRleHQ6IHN0cmluZywgb25uYXZpZ2F0ZTogRnVuY3Rpb24gPSBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5leHBpcmVkU2Vzc2lvblN3YWwuZmlyZSh0aXRsZSwgdGV4dCkudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQudmFsdWUgJiYgb25uYXZpZ2F0ZSlcclxuICAgICAgICAgICAgICAgIG9ubmF2aWdhdGUoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBoZWxwZXIgcGVyIGdlc3RpcmUgaW4gbWFuaWVyYSBzdGFuZGFyZGl6emF0YSB1bmEgcmlzcG9zdGEgZGkgdGlwbyAqKkNhbGxSZXN1bHQqKlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0NhbGxSZXN1bHR9IHJlc3BvbnNlIFJpc3Bvc3RhIHJpY2V2dXRhIGRhbCBzZXJ2ZXJcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdWNjZXNzTXNnIE1lc3NhZ2dpbyBkYSB2aXN1YWxpenphcmUgaW4gY2FzbyBkaSBzdWNjZXNzb1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yTXNnIE1lc3NhZ2dpbyBkYSB2aXN1YWxpenphcmUgaW4gY2FzbyBkaSBmYWxsaW1lbnRvXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwb3N0U3VjY2VzcyBDYWxsYmFjayBkYSBjaGltYXJlIGluIGNhc28gZGkgc3VjY2Vzc29cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHBvc3RGYWlsdXJlIENhbGxiYWNrIGRhIGNoaW1hcmUgaW4gY2FzbyBkaSBmYWxsaW1lbnRvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBtYW5hZ2VDYWxsUmVzdWx0UmVzcG9uc2UocmVzcG9uc2U6IENhbGxSZXN1bHQsIHN1Y2Nlc3NNc2c6IHN0cmluZywgZXJyb3JNc2c6IHN0cmluZywgcG9zdFN1Y2Nlc3M6IEZ1bmN0aW9uID0gbnVsbCwgcG9zdEZhaWx1cmU6IEZ1bmN0aW9uID0gbnVsbCkge1xyXG4gICAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICAgIGlmIChzdWNjZXNzTXNnKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zaW1wbGVTdWNjZXNzKHN1Y2Nlc3NNc2cpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHBvc3RTdWNjZXNzKSBwb3N0U3VjY2VzcygpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UuaGFzZXJyb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5zaW1wbGVFcnJvcigoZXJyb3JNc2cgPyBlcnJvck1zZyArIFwiOiBcIiA6IFwiXCIpICsgcmVzcG9uc2UuZXJyb3IpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHBvc3RGYWlsdXJlKSBwb3N0RmFpbHVyZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChyZXNwb25zZS5oYXN3YXJuaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2ltcGxlV2FybmluZyhyZXNwb25zZS53YXJuaW5nKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gaGVscGVyIHBlciBnZXN0aXJlIGluIG1hbmllcmEgc3RhbmRhcmRpenphdGEgdW5hIHJpc3Bvc3RhIGRpIHRpcG8gKipzdHJpbmcqKiwgY29uc2lkZXJhbmRvIGNoZTpcclxuICAgICAqIFxyXG4gICAgICogU3RyaW5nYSB2dW90YSAtLT4gVHV0dG8gYmVuZVxyXG4gICAgICogXHJcbiAgICAgKiBTdHJpbmdhIHBpZW5hIC0tPiBRdWVzdG8gw6ggaWwgbWVzc2FnZ2lvIGQnZXJyb3JlIHBlciBjdWkgbGEgY2hpYW1hdGEgw6ggZmFsbGl0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcmVzcG9uc2UgUmlzcG9zdGEgcmljZXZ1dGEgZGFsIHNlcnZlclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN1Y2Nlc3NNc2cgTWVzc2FnZ2lvIGRhIHZpc3VhbGl6emFyZSBpbiBjYXNvIGRpIHN1Y2Nlc3NvXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JNc2cgTWVzc2FnZ2lvIGRhIHZpc3VhbGl6emFyZSBpbiBjYXNvIGRpIGZhbGxpbWVudG9cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHBvc3RTdWNjZXNzIENhbGxiYWNrIGRhIGNoaW1hcmUgaW4gY2FzbyBkaSBzdWNjZXNzb1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcG9zdEZhaWx1cmUgQ2FsbGJhY2sgZGEgY2hpbWFyZSBpbiBjYXNvIGRpIGZhbGxpbWVudG9cclxuICAgICAqL1xyXG4gICAgcHVibGljIG1hbmFnZVN0cmluZ1Jlc3BvbnNlKHJlc3BvbnNlOiBzdHJpbmcsIHN1Y2Nlc3NNc2c6IHN0cmluZywgZXJyb3JNc2c6IHN0cmluZywgcG9zdFN1Y2Nlc3M6IEZ1bmN0aW9uID0gbnVsbCwgcG9zdEZhaWx1cmU6IEZ1bmN0aW9uID0gbnVsbCkge1xyXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgaWYgKHN1Y2Nlc3NNc2cpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNpbXBsZVN1Y2Nlc3Moc3VjY2Vzc01zZyk7XHJcblxyXG4gICAgICAgICAgICBpZiAocG9zdFN1Y2Nlc3MpIHBvc3RTdWNjZXNzKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGVycm9yTXNnKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zaW1wbGVFcnJvcihlcnJvck1zZyArIFwiOiBcIiArIHJlc3BvbnNlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChwb3N0RmFpbHVyZSkgcG9zdEZhaWx1cmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gaGVscGVyIHBlciBnZXN0aXJlIGluIG1hbmllcmEgc3RhbmRhcmRpenphdGEgdW5hIHJpc3Bvc3RhIGRpIHRpcG8gKipib29sZWFuKipcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHJlc3BvbnNlIFJpc3Bvc3RhIHJpY2V2dXRhIGRhbCBzZXJ2ZXJcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdWNjZXNzTXNnIE1lc3NhZ2dpbyBkYSB2aXN1YWxpenphcmUgaW4gY2FzbyBkaSBzdWNjZXNzb1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yTXNnIE1lc3NhZ2dpbyBkYSB2aXN1YWxpenphcmUgaW4gY2FzbyBkaSBmYWxsaW1lbnRvXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwb3N0U3VjY2VzcyBDYWxsYmFjayBkYSBjaGltYXJlIGluIGNhc28gZGkgc3VjY2Vzc29cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHBvc3RGYWlsdXJlIENhbGxiYWNrIGRhIGNoaW1hcmUgaW4gY2FzbyBkaSBmYWxsaW1lbnRvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBtYW5hZ2VTdHJpbmdSZXNwb25zZUJvb2wocmVzcG9uc2U6IGJvb2xlYW4sIHN1Y2Nlc3NNc2c6IHN0cmluZywgZXJyb3JNc2c6IHN0cmluZywgcG9zdFN1Y2Nlc3M6IEZ1bmN0aW9uID0gbnVsbCwgcG9zdEZhaWx1cmU6IEZ1bmN0aW9uID0gbnVsbCkge1xyXG4gICAgICAgIGlmIChyZXNwb25zZSkge1xyXG4gICAgICAgICAgICBpZiAoc3VjY2Vzc01zZylcclxuICAgICAgICAgICAgICAgIHRoaXMuc2ltcGxlU3VjY2VzcyhzdWNjZXNzTXNnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChwb3N0U3VjY2VzcykgcG9zdFN1Y2Nlc3MoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoZXJyb3JNc2cpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNpbXBsZUVycm9yKGVycm9yTXNnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChwb3N0RmFpbHVyZSkgcG9zdEZhaWx1cmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn0iXX0=
@@ -0,0 +1,103 @@
1
+ // Angular
2
+ import { Injectable, Inject, Optional } from "@angular/core";
3
+ // Modelli
4
+ import { APPSEARCH_PREFIX } from '../tokens';
5
+ import { tap, first } from "rxjs/operators";
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "../models/session/base/BaseSessionRetriever";
8
+ import * as i2 from "../models/providers/base/BaseStorageProvider";
9
+ /**
10
+ * Service che fornisce funzionalità di base per storicizzazione e recupero oggetti dallo Storage Locale
11
+ *
12
+ * N.B: In ogni chiamata è presente l'operatore rxjs **first()** per far sì che a prescindere dall'implementazione utente/default gli
13
+ * observable effettuino l'unsubscribe automaticamente terminata la prima operazine
14
+ */
15
+ export class StorageService {
16
+ /**
17
+ * Costruttore
18
+ *
19
+ * @ignore
20
+ */
21
+ constructor(APPSEARCH_PREFIX, _session, _storage) {
22
+ this.APPSEARCH_PREFIX = APPSEARCH_PREFIX;
23
+ this._session = _session;
24
+ this._storage = _storage;
25
+ }
26
+ /**
27
+ * Inserisce un oggetto che funga da contenitore di oggetti nel local storage, ripulendone gli oggetti (supponendo che sia una view di ricerca) e marcandolo come
28
+ * salvato, in modo che quando viene recuperato il sistema non pensi che sia un oggetto vuoto ma che sappia che gli oggetti son stati ripuliti per risparmiare spazio
29
+ *
30
+ * @param {string} storeName Chiave del localStorage in cui storicizzare l'oggetto **itemsContainer**
31
+ * @param {{ items: any[] }} itemsContainer Oggetto da storicizzare
32
+ */
33
+ setItem(storeName, item) {
34
+ var finalItem;
35
+ //Se sto salvando un oggetto con "items" e "page" vuol dire che è un appsearch, la ripulisco
36
+ if (item.items && item.page) {
37
+ finalItem = JSON.parse(JSON.stringify(item));
38
+ finalItem.items = [];
39
+ finalItem.savedstate = true;
40
+ finalItem.savedprefix = this.APPSEARCH_PREFIX || 'Hot';
41
+ }
42
+ else
43
+ finalItem = item;
44
+ return this._storage.setItem(storeName, finalItem).pipe(first(), tap(res => {
45
+ if (res == false)
46
+ console.error("Impossibile effettuare il salvataggio dell'oggetto all'interno dello Storage Locale per la chiave " + storeName);
47
+ }));
48
+ }
49
+ /**
50
+ * Recupera un oggetto dallo Storage Locale
51
+ *
52
+ * @param {string} storeName Chiave del localStorage da cui recuperare l'oggetto
53
+ *
54
+ * @returns {any} Oggetto recuperato e deserializzato
55
+ */
56
+ getItem(storeName) {
57
+ return this._storage.getItem(storeName).pipe(first(), tap(res => {
58
+ if (res == null)
59
+ console.warn("Impossibile ottenere l'oggetto salvato con chiave " + storeName);
60
+ }));
61
+ }
62
+ /**
63
+ * Ripulisce lo Storage Locale
64
+ *
65
+ * @param {string} storeName Chiave del localStorage da ripulire
66
+ */
67
+ removeItem(storeName) {
68
+ return this._storage.removeItem(storeName).pipe(first(), tap(res => {
69
+ if (res == false)
70
+ console.warn("Impossibile rimuovere l'oggetto salvato con chiave " + storeName);
71
+ }));
72
+ }
73
+ /**
74
+ * Ripulisce lo Storage Locale di ogni cosa salvata
75
+ *
76
+ * @param {string} storeName Chiave del localStorage da ripulire
77
+ */
78
+ clear() {
79
+ return this._storage.clear().pipe(first(), tap(res => {
80
+ if (res == false)
81
+ console.warn("Impossibile ripulire lo Storage Locale");
82
+ }));
83
+ }
84
+ /**
85
+ * Restituisce tutte le chiavi-valore associate alla sessione corrente
86
+ *
87
+ * @returns {Observable<{ [index: string]: string; }>} Risultato della query
88
+ */
89
+ getAll() {
90
+ return this._storage.getAll().pipe(first());
91
+ }
92
+ }
93
+ StorageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: StorageService, deps: [{ token: APPSEARCH_PREFIX, optional: true }, { token: i1.BaseSessionRetriever }, { token: i2.BaseStorageProvider }], target: i0.ɵɵFactoryTarget.Injectable });
94
+ StorageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: StorageService });
95
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: StorageService, decorators: [{
96
+ type: Injectable
97
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
98
+ type: Optional
99
+ }, {
100
+ type: Inject,
101
+ args: [APPSEARCH_PREFIX]
102
+ }] }, { type: i1.BaseSessionRetriever }, { type: i2.BaseStorageProvider }]; } });
103
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5zdG9yYWdlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9leHRlbnNpb25zL3NyYy9saWIvc2VydmljZXMvZXh0ZW5zaW9ucy5zdG9yYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFBVTtBQUNWLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUk3RCxVQUFVO0FBQ1YsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBSTdDLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7QUFFNUM7Ozs7O0dBS0c7QUFFSCxNQUFNLE9BQU8sY0FBYztJQUV2Qjs7OztPQUlHO0lBQ0gsWUFBMEQsZ0JBQXdCLEVBQVUsUUFBOEIsRUFBVSxRQUE2QjtRQUF2RyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQVE7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFzQjtRQUFVLGFBQVEsR0FBUixRQUFRLENBQXFCO0lBQUksQ0FBQztJQUV0Szs7Ozs7O09BTUc7SUFDSSxPQUFPLENBQUksU0FBaUIsRUFBRSxJQUFPO1FBQ3hDLElBQUksU0FBYyxDQUFDO1FBQ25CLDRGQUE0RjtRQUM1RixJQUFVLElBQUssQ0FBQyxLQUFLLElBQVUsSUFBSyxDQUFDLElBQUksRUFBRTtZQUN2QyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDN0MsU0FBUyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDckIsU0FBUyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDdEIsU0FBVSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDO1NBQ2pFOztZQUVHLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFFckIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN2RSxJQUFJLEdBQUcsSUFBSSxLQUFLO2dCQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0dBQW9HLEdBQUcsU0FBUyxDQUFDLENBQUM7UUFDeEksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxPQUFPLENBQUksU0FBaUI7UUFDL0IsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBSSxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQy9ELElBQUksR0FBRyxJQUFJLElBQUk7Z0JBQ1gsT0FBTyxDQUFDLElBQUksQ0FBQyxvREFBb0QsR0FBRyxTQUFTLENBQUMsQ0FBQztRQUN2RixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxVQUFVLENBQUMsU0FBaUI7UUFDL0IsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQy9ELElBQUksR0FBRyxJQUFJLEtBQUs7Z0JBQ1osT0FBTyxDQUFDLElBQUksQ0FBQyxxREFBcUQsR0FBRyxTQUFTLENBQUMsQ0FBQztRQUN4RixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLO1FBQ1IsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDakQsSUFBSSxHQUFHLElBQUksS0FBSztnQkFDWixPQUFPLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTTtRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNoRCxDQUFDOzsyR0EvRVEsY0FBYyxrQkFPUyxnQkFBZ0I7K0dBUHZDLGNBQWM7MkZBQWQsY0FBYztrQkFEMUIsVUFBVTs7MEJBUU0sUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBbmd1bGFyXHJcbmltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCwgT3B0aW9uYWwgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBCYXNlU3RvcmFnZVByb3ZpZGVyIH0gZnJvbSBcIi4uL21vZGVscy9wcm92aWRlcnMvYmFzZS9CYXNlU3RvcmFnZVByb3ZpZGVyXCI7XHJcbmltcG9ydCB7IEJhc2VTZXNzaW9uUmV0cmlldmVyIH0gZnJvbSBcIi4uL21vZGVscy9zZXNzaW9uL2Jhc2UvQmFzZVNlc3Npb25SZXRyaWV2ZXJcIjtcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHsgQVBQU0VBUkNIX1BSRUZJWCB9IGZyb20gJy4uL3Rva2Vucyc7XHJcblxyXG4vLyBSWEpTXHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyB0YXAsIGZpcnN0IH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XHJcblxyXG4vKipcclxuICogU2VydmljZSBjaGUgZm9ybmlzY2UgZnVuemlvbmFsaXTDoCBkaSBiYXNlIHBlciBzdG9yaWNpenphemlvbmUgZSByZWN1cGVybyBvZ2dldHRpIGRhbGxvIFN0b3JhZ2UgTG9jYWxlXHJcbiAqIFxyXG4gKiBOLkI6IEluIG9nbmkgY2hpYW1hdGEgw6ggcHJlc2VudGUgbCdvcGVyYXRvcmUgcnhqcyAqKmZpcnN0KCkqKiBwZXIgZmFyIHPDrCBjaGUgYSBwcmVzY2luZGVyZSBkYWxsJ2ltcGxlbWVudGF6aW9uZSB1dGVudGUvZGVmYXVsdCBnbGkgXHJcbiAqIG9ic2VydmFibGUgZWZmZXR0dWlubyBsJ3Vuc3Vic2NyaWJlIGF1dG9tYXRpY2FtZW50ZSB0ZXJtaW5hdGEgbGEgcHJpbWEgb3BlcmF6aW5lXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBTdG9yYWdlU2VydmljZSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3N0cnV0dG9yZVxyXG4gICAgICogXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBJbmplY3QoQVBQU0VBUkNIX1BSRUZJWCkgcHJpdmF0ZSBBUFBTRUFSQ0hfUFJFRklYOiBzdHJpbmcsIHByaXZhdGUgX3Nlc3Npb246IEJhc2VTZXNzaW9uUmV0cmlldmVyLCBwcml2YXRlIF9zdG9yYWdlOiBCYXNlU3RvcmFnZVByb3ZpZGVyKSB7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluc2VyaXNjZSB1biBvZ2dldHRvIGNoZSBmdW5nYSBkYSBjb250ZW5pdG9yZSBkaSBvZ2dldHRpIG5lbCBsb2NhbCBzdG9yYWdlLCByaXB1bGVuZG9uZSBnbGkgb2dnZXR0aSAoc3VwcG9uZW5kbyBjaGUgc2lhIHVuYSB2aWV3IGRpIHJpY2VyY2EpIGUgbWFyY2FuZG9sbyBjb21lIFxyXG4gICAgICogc2FsdmF0bywgaW4gbW9kbyBjaGUgcXVhbmRvIHZpZW5lIHJlY3VwZXJhdG8gaWwgc2lzdGVtYSBub24gcGVuc2kgY2hlIHNpYSB1biBvZ2dldHRvIHZ1b3RvIG1hIGNoZSBzYXBwaWEgY2hlIGdsaSBvZ2dldHRpIHNvbiBzdGF0aSByaXB1bGl0aSBwZXIgcmlzcGFybWlhcmUgc3BhemlvXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdG9yZU5hbWUgQ2hpYXZlIGRlbCBsb2NhbFN0b3JhZ2UgaW4gY3VpIHN0b3JpY2l6emFyZSBsJ29nZ2V0dG8gKippdGVtc0NvbnRhaW5lcioqXHJcbiAgICAgKiBAcGFyYW0ge3sgaXRlbXM6IGFueVtdIH19IGl0ZW1zQ29udGFpbmVyIE9nZ2V0dG8gZGEgc3RvcmljaXp6YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRJdGVtPFQ+KHN0b3JlTmFtZTogc3RyaW5nLCBpdGVtOiBUKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICAgICAgdmFyIGZpbmFsSXRlbTogYW55O1xyXG4gICAgICAgIC8vU2Ugc3RvIHNhbHZhbmRvIHVuIG9nZ2V0dG8gY29uIFwiaXRlbXNcIiBlIFwicGFnZVwiIHZ1b2wgZGlyZSBjaGUgw6ggdW4gYXBwc2VhcmNoLCBsYSByaXB1bGlzY29cclxuICAgICAgICBpZiAoKDxhbnk+aXRlbSkuaXRlbXMgJiYgKDxhbnk+aXRlbSkucGFnZSkge1xyXG4gICAgICAgICAgICBmaW5hbEl0ZW0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGl0ZW0pKTtcclxuICAgICAgICAgICAgZmluYWxJdGVtLml0ZW1zID0gW107XHJcbiAgICAgICAgICAgIGZpbmFsSXRlbS5zYXZlZHN0YXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgKDxhbnk+ZmluYWxJdGVtKS5zYXZlZHByZWZpeCA9IHRoaXMuQVBQU0VBUkNIX1BSRUZJWCB8fCAnSG90JztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICBmaW5hbEl0ZW0gPSBpdGVtO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcmFnZS5zZXRJdGVtKHN0b3JlTmFtZSwgZmluYWxJdGVtKS5waXBlKGZpcnN0KCksIHRhcChyZXMgPT4ge1xyXG4gICAgICAgICAgICBpZiAocmVzID09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkltcG9zc2liaWxlIGVmZmV0dHVhcmUgaWwgc2FsdmF0YWdnaW8gZGVsbCdvZ2dldHRvIGFsbCdpbnRlcm5vIGRlbGxvIFN0b3JhZ2UgTG9jYWxlIHBlciBsYSBjaGlhdmUgXCIgKyBzdG9yZU5hbWUpO1xyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlY3VwZXJhIHVuIG9nZ2V0dG8gZGFsbG8gU3RvcmFnZSBMb2NhbGVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0b3JlTmFtZSBDaGlhdmUgZGVsIGxvY2FsU3RvcmFnZSBkYSBjdWkgcmVjdXBlcmFyZSBsJ29nZ2V0dG9cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge2FueX0gT2dnZXR0byByZWN1cGVyYXRvIGUgZGVzZXJpYWxpenphdG9cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldEl0ZW08VD4oc3RvcmVOYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcmFnZS5nZXRJdGVtPFQ+KHN0b3JlTmFtZSkucGlwZShmaXJzdCgpLCB0YXAocmVzID0+IHtcclxuICAgICAgICAgICAgaWYgKHJlcyA9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiSW1wb3NzaWJpbGUgb3R0ZW5lcmUgbCdvZ2dldHRvIHNhbHZhdG8gY29uIGNoaWF2ZSBcIiArIHN0b3JlTmFtZSk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmlwdWxpc2NlIGxvIFN0b3JhZ2UgTG9jYWxlIFxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RvcmVOYW1lIENoaWF2ZSBkZWwgbG9jYWxTdG9yYWdlIGRhIHJpcHVsaXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZW1vdmVJdGVtKHN0b3JlTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2UucmVtb3ZlSXRlbShzdG9yZU5hbWUpLnBpcGUoZmlyc3QoKSwgdGFwKHJlcyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChyZXMgPT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJJbXBvc3NpYmlsZSByaW11b3ZlcmUgbCdvZ2dldHRvIHNhbHZhdG8gY29uIGNoaWF2ZSBcIiArIHN0b3JlTmFtZSk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmlwdWxpc2NlIGxvIFN0b3JhZ2UgTG9jYWxlIGRpIG9nbmkgY29zYSBzYWx2YXRhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdG9yZU5hbWUgQ2hpYXZlIGRlbCBsb2NhbFN0b3JhZ2UgZGEgcmlwdWxpcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNsZWFyKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdG9yYWdlLmNsZWFyKCkucGlwZShmaXJzdCgpLCB0YXAocmVzID0+IHtcclxuICAgICAgICAgICAgaWYgKHJlcyA9PSBmYWxzZSlcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkltcG9zc2liaWxlIHJpcHVsaXJlIGxvIFN0b3JhZ2UgTG9jYWxlXCIpO1xyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc3RpdHVpc2NlIHR1dHRlIGxlIGNoaWF2aS12YWxvcmUgYXNzb2NpYXRlIGFsbGEgc2Vzc2lvbmUgY29ycmVudGVcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGU8eyBbaW5kZXg6IHN0cmluZ106IHN0cmluZzsgfT59IFJpc3VsdGF0byBkZWxsYSBxdWVyeVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0QWxsKCk6IE9ic2VydmFibGU8eyBbaW5kZXg6IHN0cmluZ106IHN0cmluZzsgfT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdG9yYWdlLmdldEFsbCgpLnBpcGUoZmlyc3QoKSk7XHJcbiAgICB9XHJcbn0iXX0=