@esfaenza/extensions 12.2.14 → 13.1.2
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/esfaenza-extensions.d.ts +1 -2
- package/esm2020/esfaenza-extensions.mjs +5 -0
- package/{esm2015/lib/models/CallResult.js → esm2020/lib/models/CallResult.mjs} +0 -0
- package/{esm2015/lib/models/CsvHeaders.js → esm2020/lib/models/CsvHeaders.mjs} +0 -0
- package/{esm2015/lib/models/ExportConsts.js → esm2020/lib/models/ExportConsts.mjs} +0 -0
- package/{esm2015/lib/models/ExtensionsModuleConfig.js → esm2020/lib/models/ExtensionsModuleConfig.mjs} +0 -0
- package/{esm2015/lib/models/GenericItem.js → esm2020/lib/models/GenericItem.mjs} +0 -0
- package/{esm2015/lib/models/TypeCode.js → esm2020/lib/models/TypeCode.mjs} +0 -0
- package/{esm2015/lib/models/providers/base/BaseStorageProvider.js → esm2020/lib/models/providers/base/BaseStorageProvider.mjs} +0 -0
- package/esm2020/lib/models/providers/implementation/DefaultStorageProvider.mjs +79 -0
- package/{esm2015/lib/models/session/base/BaseSessionRetriever.js → esm2020/lib/models/session/base/BaseSessionRetriever.mjs} +0 -0
- package/esm2020/lib/models/session/implementation/DefaultSessionRetriever.mjs +28 -0
- package/esm2020/lib/modules/extensions.full.module.mjs +58 -0
- package/esm2020/lib/modules/extensions.module.mjs +28 -0
- package/esm2020/lib/services/extensions.clipboard.service.mjs +165 -0
- package/esm2020/lib/services/extensions.dates.service.mjs +232 -0
- package/esm2020/lib/services/extensions.exports.service.mjs +453 -0
- package/esm2020/lib/services/extensions.hashing.service.mjs +309 -0
- package/esm2020/lib/services/extensions.messages.service.mjs +323 -0
- package/esm2020/lib/services/extensions.storage.service.mjs +103 -0
- package/esm2020/lib/services/extensions.utilities.service.mjs +188 -0
- package/{esm2015/lib/tokens.js → esm2020/lib/tokens.mjs} +0 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
- package/fesm2015/{esfaenza-extensions.js → esfaenza-extensions.mjs} +105 -67
- package/fesm2015/esfaenza-extensions.mjs.map +1 -0
- package/fesm2020/esfaenza-extensions.mjs +2055 -0
- package/fesm2020/esfaenza-extensions.mjs.map +1 -0
- package/lib/models/providers/implementation/DefaultStorageProvider.d.ts +3 -0
- package/lib/models/session/implementation/DefaultSessionRetriever.d.ts +3 -0
- package/lib/modules/extensions.full.module.d.ts +4 -0
- package/lib/modules/extensions.module.d.ts +4 -0
- package/lib/services/extensions.clipboard.service.d.ts +3 -0
- package/lib/services/extensions.dates.service.d.ts +3 -0
- package/lib/services/extensions.exports.service.d.ts +3 -0
- package/lib/services/extensions.hashing.service.d.ts +3 -0
- package/lib/services/extensions.messages.service.d.ts +3 -0
- package/lib/services/extensions.storage.service.d.ts +3 -0
- package/lib/services/extensions.utilities.service.d.ts +3 -0
- package/package.json +22 -10
- package/bundles/esfaenza-extensions.umd.js +0 -2442
- package/bundles/esfaenza-extensions.umd.js.map +0 -1
- package/esfaenza-extensions.metadata.json +0 -1
- package/esm2015/esfaenza-extensions.js +0 -7
- package/esm2015/lib/models/providers/implementation/DefaultStorageProvider.js +0 -79
- package/esm2015/lib/models/session/implementation/DefaultSessionRetriever.js +0 -26
- package/esm2015/lib/modules/extensions.full.module.js +0 -54
- package/esm2015/lib/modules/extensions.module.js +0 -24
- package/esm2015/lib/services/extensions.clipboard.service.js +0 -165
- package/esm2015/lib/services/extensions.dates.service.js +0 -224
- package/esm2015/lib/services/extensions.exports.service.js +0 -453
- package/esm2015/lib/services/extensions.hashing.service.js +0 -306
- package/esm2015/lib/services/extensions.messages.service.js +0 -317
- package/esm2015/lib/services/extensions.storage.service.js +0 -100
- package/esm2015/lib/services/extensions.utilities.service.js +0 -185
- package/fesm2015/esfaenza-extensions.js.map +0 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Angular
|
|
2
|
+
import { Injectable, Inject, Optional } from "@angular/core";
|
|
3
|
+
// Modelli
|
|
4
|
+
import { EXT_ALLOW_UTC, EXT_LOCALE } from "../tokens";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
|
|
8
|
+
*/
|
|
9
|
+
export class DateService {
|
|
10
|
+
/**
|
|
11
|
+
* Costruttore
|
|
12
|
+
*
|
|
13
|
+
* @ignore
|
|
14
|
+
*/
|
|
15
|
+
constructor(LOCALE, allowUtc) {
|
|
16
|
+
this.LOCALE = LOCALE;
|
|
17
|
+
this.allowUtc = allowUtc;
|
|
18
|
+
/**
|
|
19
|
+
* Oggetto statico di localizzazione per i messaggi di questa Service
|
|
20
|
+
*/
|
|
21
|
+
this.loc = {
|
|
22
|
+
"SMALL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY", 'it-IT': "DD/MM/YYYY" },
|
|
23
|
+
"FULL_DATE_FORMAT": { 'en-US': "MM/DD/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
|
|
24
|
+
"FULL_DATE_FORMAT_NO_SS": { 'en-US': "MM/DD/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
|
|
25
|
+
"SMALL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY", 'it-IT': "DD/MM/YYYY" },
|
|
26
|
+
"SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR": { 'en-US': "DD/MM/YYYY HH", 'it-IT': "DD/MM/YYYY HH" },
|
|
27
|
+
"SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" },
|
|
28
|
+
"FULL_DATE_DISPLAY_FORMAT": { 'en-US': "DD/MM/YYYY HH:mm:ss", 'it-IT': "DD/MM/YYYY HH:mm:ss" },
|
|
29
|
+
"FULL_DATE_DISPLAY_FORMAT_NO_SS": { 'en-US': "DD/MM/YYYY HH:mm", 'it-IT': "DD/MM/YYYY HH:mm" }
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Oggetto di configurazione per tenere da conto le informazioni sui formati
|
|
33
|
+
*/
|
|
34
|
+
this.cfg = {
|
|
35
|
+
fulldate: "",
|
|
36
|
+
fulldateDisplay: "",
|
|
37
|
+
smallDate: "",
|
|
38
|
+
fulldateNoSS: "",
|
|
39
|
+
smallDateWithH: "",
|
|
40
|
+
smallDateWithM: "",
|
|
41
|
+
fulldateDisplayNoSS: ""
|
|
42
|
+
};
|
|
43
|
+
this.cfg.smallDate = this.loc["SMALL_DATE_FORMAT"][this.LOCALE ?? 'it-IT'];
|
|
44
|
+
this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][this.LOCALE ?? 'it-IT'];
|
|
45
|
+
this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][this.LOCALE ?? 'it-IT'];
|
|
46
|
+
this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][this.LOCALE ?? 'it-IT'];
|
|
47
|
+
this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][this.LOCALE ?? 'it-IT'];
|
|
48
|
+
this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][this.LOCALE ?? 'it-IT'];
|
|
49
|
+
this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][this.LOCALE ?? 'it-IT'];
|
|
50
|
+
this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][this.LOCALE ?? 'it-IT'];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Aggiusta una data in "istante finale" in base a qual è la parte di data significativa.
|
|
54
|
+
*
|
|
55
|
+
* Es. Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
|
|
56
|
+
*
|
|
57
|
+
* @param {any} date Data qualsiasi (Date, stringa, dayjs...), verrà ricondotta ad un oggetto dayJs
|
|
58
|
+
* @param {'day' | 'hour' | 'minute'} timepart Parte significativa della data
|
|
59
|
+
* @param {boolean} printSeconds Indica se effettuare la stampa dei secondi o no
|
|
60
|
+
*/
|
|
61
|
+
adjustDateToFinalInstant(date, timepart, printSeconds = true) {
|
|
62
|
+
let mydt = this.getDateConvertion(date);
|
|
63
|
+
if (mydt == null)
|
|
64
|
+
return "FE: Not a Date";
|
|
65
|
+
let isZeroTime = mydt.startOf(timepart).valueOf() === mydt.valueOf();
|
|
66
|
+
if (!isZeroTime)
|
|
67
|
+
return printSeconds ? mydt.format(this.cfg.fulldateDisplay) : mydt.format(this.cfg.fulldateDisplayNoSS);
|
|
68
|
+
let tmpValue = mydt.subtract(1, timepart);
|
|
69
|
+
let value = "";
|
|
70
|
+
// Istante finale delle ore: 05/10/1992 --> 04/10/1992 24:00(:00)
|
|
71
|
+
if (timepart == 'day')
|
|
72
|
+
value = tmpValue.format(this.cfg.smallDate) + " 24:00" + (printSeconds ? ':00' : '');
|
|
73
|
+
// Istante finale dei minuti: giorno 05/10/1992 04:00:00 --> 05/10/1992 03:60(:00)
|
|
74
|
+
else if (timepart == 'hour')
|
|
75
|
+
value = tmpValue.format(this.cfg.smallDateWithH) + ":60" + (printSeconds ? ':00' : '');
|
|
76
|
+
// Istante finale dei secondi: giorno 05/10/1992 04:10:00 --> 05/10/1992 04:09:60
|
|
77
|
+
else if (timepart == 'minute')
|
|
78
|
+
value = tmpValue.format(this.cfg.smallDateWithM) + ":60";
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Funzione che effettua l'ordinamento fra 2 date in base alla direzione specificata
|
|
83
|
+
*
|
|
84
|
+
* @param {any} a Prima data per il confronto
|
|
85
|
+
* @param {any} b Seconda data per il confronto
|
|
86
|
+
* @param {'asc' | 'desc'} direction Direzione rispetto a cui ordinare le due date
|
|
87
|
+
*
|
|
88
|
+
* @returns {number} 0 se le date sono uguali, 1 se la data A deve venire logicamente prima della data B, -1 altrimenti
|
|
89
|
+
*/
|
|
90
|
+
dateSort(a, b, direction) {
|
|
91
|
+
if (a < b)
|
|
92
|
+
return direction == 'asc' ? 1 : -1;
|
|
93
|
+
else if (a > b)
|
|
94
|
+
return direction == 'asc' ? -1 : 1;
|
|
95
|
+
// con a uguale a b
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Effettua il trim dei secondi da una data espressa come stringa
|
|
100
|
+
*
|
|
101
|
+
* @param {string} value Data espressa come stringa
|
|
102
|
+
*
|
|
103
|
+
* @returns {string} Data senza i secondi
|
|
104
|
+
*/
|
|
105
|
+
trimSeconds(value) {
|
|
106
|
+
//I numeri mangiati da dayjs spesso vengono ricondotti a date vere. Mi assicuro che se ci sono solo numeri proseguo
|
|
107
|
+
if (!isNaN(value))
|
|
108
|
+
return value;
|
|
109
|
+
//Se non ho qualcosa del tipo XX/YY/ZZZZ aa:bb:cc di sicuro non è una data che mi interessa
|
|
110
|
+
if (!/^\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d$/g.test(value))
|
|
111
|
+
return value;
|
|
112
|
+
//In questo caso mi arrivano valori che devono essere stampati as-is, solo tagliando i secondi
|
|
113
|
+
return "'" + value.substr(0, value.length - 3);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Data una lista di date Da e una lista di date A restituisce un oggetto rappresentante il range che include tutte le date passate
|
|
117
|
+
*
|
|
118
|
+
* @param {any[]} fromDates Lista dei Da
|
|
119
|
+
* @param {any[]} toDates Lista dei A
|
|
120
|
+
*
|
|
121
|
+
* @returns {{ from: any, to: any }} Range di date Da - A che include tutti i valori di **fromDates** e **toDates**
|
|
122
|
+
*/
|
|
123
|
+
getMinMaxDatesRange(fromDates, toDates) {
|
|
124
|
+
let datesFroms = [];
|
|
125
|
+
let datesTo = [];
|
|
126
|
+
for (let i = 0; i < fromDates.length; i++) {
|
|
127
|
+
let d = fromDates[i];
|
|
128
|
+
var convertion = this.getDateConvertion(d);
|
|
129
|
+
if (convertion)
|
|
130
|
+
datesFroms.push(convertion);
|
|
131
|
+
}
|
|
132
|
+
for (let i = 0; i < toDates.length; i++) {
|
|
133
|
+
let d = toDates[i];
|
|
134
|
+
var convertion = this.getDateConvertion(d);
|
|
135
|
+
if (convertion)
|
|
136
|
+
datesTo.push(convertion);
|
|
137
|
+
}
|
|
138
|
+
return { from: dayjs.min(datesFroms), to: dayjs.max(datesTo) };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Ottiene la conversione di una data in qualsiasi formato al formato standard DayJs
|
|
142
|
+
*
|
|
143
|
+
* @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
|
|
144
|
+
* @param {boolean} useUtc Indica se usare l'estensione utc di Dayjs per parsare la data o no
|
|
145
|
+
*
|
|
146
|
+
* @returns {any} Data in modalità DayJs
|
|
147
|
+
*/
|
|
148
|
+
getDateConvertion(date, useUtc = false) {
|
|
149
|
+
if (!date)
|
|
150
|
+
return null;
|
|
151
|
+
if (this.isDayJs(date))
|
|
152
|
+
return date;
|
|
153
|
+
if (this.isJsDate(date))
|
|
154
|
+
return useUtc ? dayjs.utc(date) : dayjs(date);
|
|
155
|
+
// Se non c'è la proprietà length vuol dire che non è una stringa e a questo punto non ho idea di che minchia sia
|
|
156
|
+
let length = date.length;
|
|
157
|
+
if (!length)
|
|
158
|
+
return null;
|
|
159
|
+
if (useUtc && !this.allowUtc)
|
|
160
|
+
throw "@esfaenza/extensions: Richiesta data UTC ma da configurazione la libreria non lo supporta";
|
|
161
|
+
// Per risparmiare chiamate a tentoni, in base alla lunghezza della stringa chiamo direttamente il metodo giusto,
|
|
162
|
+
// controllando poi che mi generi una data come me la aspetto io
|
|
163
|
+
let tryThis = null;
|
|
164
|
+
let toCall = useUtc ? dayjs.utc : dayjs;
|
|
165
|
+
// Se la data contiene la lettera "T" vuol dire che è una data del tipo 2020-10-15T00:00:00, direttamente parsabile dal dayjs col locale corretto.
|
|
166
|
+
// Per il resto mi baso sulla lunghezza della stringa
|
|
167
|
+
if (date.includes("T"))
|
|
168
|
+
tryThis = toCall(date);
|
|
169
|
+
else if (length == this.cfg.fulldate.length)
|
|
170
|
+
tryThis = toCall(date, this.cfg.fulldate);
|
|
171
|
+
else if (length == this.cfg.smallDate.length)
|
|
172
|
+
tryThis = toCall(date, this.cfg.smallDate);
|
|
173
|
+
else if (length == this.cfg.fulldateNoSS.length)
|
|
174
|
+
tryThis = toCall(date, this.cfg.fulldateNoSS);
|
|
175
|
+
if (tryThis.isValid())
|
|
176
|
+
return tryThis;
|
|
177
|
+
// Se niente funziona, null.
|
|
178
|
+
// Ricondurre l'Input ad una data non è possibile.
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Helper che restituisce **true** qualora l'oggetto passato fosse una data vera e propria, **false** altrimenti
|
|
183
|
+
*
|
|
184
|
+
* @param {any} check Oggetto da controllare
|
|
185
|
+
*
|
|
186
|
+
* @returns {boolean} Indicazione se l'oggetto è un vero Date di Javascript o no
|
|
187
|
+
*/
|
|
188
|
+
isJsDate(check) {
|
|
189
|
+
return check && Object.prototype.toString.call(check) === "[object Date]" && !isNaN(check);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Helper che restituisce **true** qualora l'oggetto passato fosse un DayJs vero e proprio, **false** altrimenti
|
|
193
|
+
*
|
|
194
|
+
* @param {any} check Oggetto da controllare
|
|
195
|
+
* @returns {boolean} Indicazione se l'oggetto è un vero DayJs o no
|
|
196
|
+
*/
|
|
197
|
+
isDayJs(check) {
|
|
198
|
+
// Non uso instanceof perché sarebbe estremamente più lento
|
|
199
|
+
// Non uso nemmeno isDayjs() della libreria Dayjs dato che ha lo stesso problema: https://github.com/iamkun/dayjs/blob/06f88f425828b1ce96b737332d25145a95a4ee9d/src/index.js#L9
|
|
200
|
+
return check.$D !== undefined && check.$M !== undefined && check.$y !== undefined;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Ottiene la formattazione di una data in base alla versione richiesta "small" o "long" e a se stampare o meno i secondi
|
|
204
|
+
*
|
|
205
|
+
* @param {any} date Oggetto rappresentante una data. Potrebbe essere una stringa, un Date o già un DayJs
|
|
206
|
+
* @param {boolean} small Indica se formattarla con un formato breve (se **true**) o un formato più lungo (se **false**)
|
|
207
|
+
*
|
|
208
|
+
* @returns {string} Data formattata nel formato richiesto
|
|
209
|
+
*/
|
|
210
|
+
getFormatted(date, small, seconds) {
|
|
211
|
+
var date = this.getDateConvertion(date);
|
|
212
|
+
if (!date)
|
|
213
|
+
return null;
|
|
214
|
+
return date.format(small ? this.cfg.smallDate : seconds ? this.cfg.fulldateDisplay : this.cfg.fulldateDisplayNoSS);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
DateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DateService, deps: [{ token: EXT_LOCALE, optional: true }, { token: EXT_ALLOW_UTC, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
218
|
+
DateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DateService });
|
|
219
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DateService, decorators: [{
|
|
220
|
+
type: Injectable
|
|
221
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
222
|
+
type: Optional
|
|
223
|
+
}, {
|
|
224
|
+
type: Inject,
|
|
225
|
+
args: [EXT_LOCALE]
|
|
226
|
+
}] }, { type: undefined, decorators: [{
|
|
227
|
+
type: Optional
|
|
228
|
+
}, {
|
|
229
|
+
type: Inject,
|
|
230
|
+
args: [EXT_ALLOW_UTC]
|
|
231
|
+
}] }]; } });
|
|
232
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5kYXRlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zcmMvbGliL3NlcnZpY2VzL2V4dGVuc2lvbnMuZGF0ZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdELFVBQVU7QUFDVixPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7QUFRckQ7O0VBRUU7QUFFSCxNQUFNLE9BQU8sV0FBVztJQTZCcEI7Ozs7T0FJRztJQUNILFlBQTJELE1BQWMsRUFBNkMsUUFBaUI7UUFBNUUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUE2QyxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBaEN2STs7V0FFRztRQUNLLFFBQUcsR0FBRztZQUNWLG1CQUFtQixFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFO1lBQ3JFLGtCQUFrQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtZQUN0Rix3QkFBd0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUU7WUFDdEYsMkJBQTJCLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUU7WUFDN0UscUNBQXFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUU7WUFDN0YsdUNBQXVDLEVBQUUsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFO1lBQ3JHLDBCQUEwQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixF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bUIsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7O3dHQXpPUSxXQUFXLGtCQWtDbUIsVUFBVSw2QkFBOEMsYUFBYTs0R0FsQ25HLFdBQVc7MkZBQVgsV0FBVztrQkFEdkIsVUFBVTs7MEJBbUNhLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVTs7MEJBQTJCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuZ3VsYXJcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0LCBPcHRpb25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG4vLyBNb2RlbGxpXHJcbmltcG9ydCB7IEVYVF9BTExPV19VVEMsIEVYVF9MT0NBTEUgfSBmcm9tIFwiLi4vdG9rZW5zXCI7XHJcblxyXG4vKipcclxuICogRGljaGlhcmF6aW9uZSBkZWxsYSB2YXJpYWJpbGUgZ2xvYmFsZSBkYXlqcy4gTCdvbmVyZSBkaSBcImNyZWFybGFcIiDDqCBhZmZpZGF0byBhbGwnYXBwbGljYXppb25lIGNoZSB1dGlsaXp6YSBxdWVzdGEgbGlicmVyaWEsIFxyXG4gKiBjaGUgZG92csOgIGltcG9ydGFyZSBsbyBzY3JpcHQgZ2xvYmFsZSBkaSBkYXlqcyBuZWxsYSBDTElcclxuICovXHJcbiBkZWNsYXJlIHZhciBkYXlqczogYW55O1xyXG5cclxuIC8qKlxyXG4gKiBTZXJ2aWNlIGNoZSBmb3JuaXNjZSBkZWkgbWV0b2RpIGRpIGVzdGVuc2lvbmUgcGVyIGxhIGdlc3Rpb25lL21hbmlwb2xhemlvbmUgZGVsbGUgZGF0ZVxyXG4gKi9cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRGF0ZVNlcnZpY2Uge1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIE9nZ2V0dG8gc3RhdGljbyBkaSBsb2NhbGl6emF6aW9uZSBwZXIgaSBtZXNzYWdnaSBkaSBxdWVzdGEgU2VydmljZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGxvYyA9IHtcclxuICAgICAgICBcIlNNQUxMX0RBVEVfRk9STUFUXCI6IHsgJ2VuLVVTJzogXCJNTS9ERC9ZWVlZXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWVwiIH0sXHJcbiAgICAgICAgXCJGVUxMX0RBVEVfRk9STUFUXCI6IHsgJ2VuLVVTJzogXCJNTS9ERC9ZWVlZIEhIOm1tOnNzXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISDptbTpzc1wiIH0sXHJcbiAgICAgICAgXCJGVUxMX0RBVEVfRk9STUFUX05PX1NTXCI6IHsgJ2VuLVVTJzogXCJNTS9ERC9ZWVlZIEhIOm1tXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISDptbVwiIH0sXHJcbiAgICAgICAgXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWVwiIH0sXHJcbiAgICAgICAgXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfSE9VUlwiOiB7ICdlbi1VUyc6IFwiREQvTU0vWVlZWSBISFwiLCAnaXQtSVQnOiBcIkREL01NL1lZWVkgSEhcIiB9LFxyXG4gICAgICAgIFwiU01BTExfREFURV9ESVNQTEFZX0ZPUk1BVF9XSVRIX01JTlVURVwiOiB7ICdlbi1VUyc6IFwiREQvTU0vWVlZWSBISDptbVwiLCAnaXQtSVQnOiBcIkREL01NL1lZWVkgSEg6bW1cIiB9LFxyXG4gICAgICAgIFwiRlVMTF9EQVRFX0RJU1BMQVlfRk9STUFUXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZIEhIOm1tOnNzXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISDptbTpzc1wiIH0sXHJcbiAgICAgICAgXCJGVUxMX0RBVEVfRElTUExBWV9GT1JNQVRfTk9fU1NcIjogeyAnZW4tVVMnOiBcIkREL01NL1lZWVkgSEg6bW1cIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tXCIgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9nZ2V0dG8gZGkgY29uZmlndXJhemlvbmUgcGVyIHRlbmVyZSBkYSBjb250byBsZSBpbmZvcm1hemlvbmkgc3VpIGZvcm1hdGlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBjZmcgPSB7XHJcbiAgICAgICAgZnVsbGRhdGU6IFwiXCIsXHJcbiAgICAgICAgZnVsbGRhdGVEaXNwbGF5OiBcIlwiLFxyXG4gICAgICAgIHNtYWxsRGF0ZTogXCJcIixcclxuICAgICAgICBmdWxsZGF0ZU5vU1M6IFwiXCIsXHJcbiAgICAgICAgc21hbGxEYXRlV2l0aEg6IFwiXCIsXHJcbiAgICAgICAgc21hbGxEYXRlV2l0aE06IFwiXCIsXHJcbiAgICAgICAgZnVsbGRhdGVEaXNwbGF5Tm9TUzogXCJcIlxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29zdHJ1dHRvcmVcclxuICAgICAqIFxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoQE9wdGlvbmFsKCkgQEluamVjdChFWFRfTE9DQUxFKSBwcml2YXRlIExPQ0FMRTogc3RyaW5nLCBAT3B0aW9uYWwoKSBASW5qZWN0KEVYVF9BTExPV19VVEMpIHByaXZhdGUgYWxsb3dVdGM6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmNmZy5zbWFsbERhdGUgPSB0aGlzLmxvY1tcIlNNQUxMX0RBVEVfRk9STUFUXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlID0gdGhpcy5sb2NbXCJGVUxMX0RBVEVfRk9STUFUXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlTm9TUyA9IHRoaXMubG9jW1wiRlVMTF9EQVRFX0ZPUk1BVF9OT19TU1wiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgICAgICB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXkgPSB0aGlzLmxvY1tcIkZVTExfREFURV9ESVNQTEFZX0ZPUk1BVFwiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgICAgICB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXlOb1NTICA9dGhpcy5sb2NbXCJGVUxMX0RBVEVfRElTUExBWV9GT1JNQVRfTk9fU1NcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuc21hbGxEYXRlID0gdGhpcy5sb2NbXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhIID0gdGhpcy5sb2NbXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfSE9VUlwiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgICAgICB0aGlzLmNmZy5zbWFsbERhdGVXaXRoTSA9IHRoaXMubG9jW1wiU01BTExfREFURV9ESVNQTEFZX0ZPUk1BVF9XSVRIX01JTlVURVwiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFnZ2l1c3RhIHVuYSBkYXRhIGluIFwiaXN0YW50ZSBmaW5hbGVcIiBpbiBiYXNlIGEgcXVhbCDDqCBsYSBwYXJ0ZSBkaSBkYXRhIHNpZ25pZmljYXRpdmEuXHJcbiAgICAgKiBcclxuICAgICAqIEVzLiBJc3RhbnRlIGZpbmFsZSBkZWxsZSBvcmU6IDA1LzEwLzE5OTIgLS0+IDA0LzEwLzE5OTIgMjQ6MDAoOjAwKVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZGF0ZSBEYXRhIHF1YWxzaWFzaSAoRGF0ZSwgc3RyaW5nYSwgZGF5anMuLi4pLCB2ZXJyw6Agcmljb25kb3R0YSBhZCB1biBvZ2dldHRvIGRheUpzXHJcbiAgICAgKiBAcGFyYW0geydkYXknIHwgJ2hvdXInIHwgJ21pbnV0ZSd9IHRpbWVwYXJ0IFBhcnRlIHNpZ25pZmljYXRpdmEgZGVsbGEgZGF0YVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBwcmludFNlY29uZHMgSW5kaWNhIHNlIGVmZmV0dHVhcmUgbGEgc3RhbXBhIGRlaSBzZWNvbmRpIG8gbm9cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFkanVzdERhdGVUb0ZpbmFsSW5zdGFudChkYXRlOiBhbnksIHRpbWVwYXJ0OiAnZGF5JyB8ICdob3VyJyB8ICdtaW51dGUnLCBwcmludFNlY29uZHM6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgbXlkdCA9IHRoaXMuZ2V0RGF0ZUNvbnZlcnRpb24oZGF0ZSk7XHJcbiAgICAgICAgaWYgKG15ZHQgPT0gbnVsbCkgcmV0dXJuIFwiRkU6IE5vdCBhIERhdGVcIjtcclxuXHJcbiAgICAgICAgbGV0IGlzWmVyb1RpbWUgPSBteWR0LnN0YXJ0T2YodGltZXBhcnQpLnZhbHVlT2YoKSA9PT0gbXlkdC52YWx1ZU9mKCk7XHJcbiAgICAgICAgaWYgKCFpc1plcm9UaW1lKSByZXR1cm4gcHJpbnRTZWNvbmRzID8gbXlkdC5mb3JtYXQodGhpcy5jZmcuZnVsbGRhdGVEaXNwbGF5KSA6IG15ZHQuZm9ybWF0KHRoaXMuY2ZnLmZ1bGxkYXRlRGlzcGxheU5vU1MpO1xyXG5cclxuICAgICAgICBsZXQgdG1wVmFsdWUgPSBteWR0LnN1YnRyYWN0KDEsIHRpbWVwYXJ0KTtcclxuICAgICAgICBsZXQgdmFsdWUgPSBcIlwiO1xyXG5cclxuICAgICAgICAvLyBJc3RhbnRlIGZpbmFsZSBkZWxsZSBvcmU6IDA1LzEwLzE5OTIgLS0+IDA0LzEwLzE5OTIgMjQ6MDAoOjAwKVxyXG4gICAgICAgIGlmICh0aW1lcGFydCA9PSAnZGF5JylcclxuICAgICAgICAgICAgdmFsdWUgPSB0bXBWYWx1ZS5mb3JtYXQodGhpcy5jZmcuc21hbGxEYXRlKSArIFwiIDI0OjAwXCIgKyAocHJpbnRTZWNvbmRzID8gJzowMCcgOiAnJyk7XHJcblxyXG4gICAgICAgIC8vIElzdGFudGUgZmluYWxlIGRlaSBtaW51dGk6IGdpb3JubyAwNS8xMC8xOTkyIDA0OjAwOjAwIC0tPiAwNS8xMC8xOTkyIDAzOjYwKDowMClcclxuICAgICAgICBlbHNlIGlmICh0aW1lcGFydCA9PSAnaG91cicpXHJcbiAgICAgICAgICAgIHZhbHVlID0gdG1wVmFsdWUuZm9ybWF0KHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhIKSArIFwiOjYwXCIgKyAocHJpbnRTZWNvbmRzID8gJzowMCcgOiAnJyk7XHJcblxyXG4gICAgICAgIC8vIElzdGFudGUgZmluYWxlIGRlaSBzZWNvbmRpOiBnaW9ybm8gMDUvMTAvMTk5MiAwNDoxMDowMCAtLT4gMDUvMTAvMTk5MiAwNDowOTo2MFxyXG4gICAgICAgIGVsc2UgaWYgKHRpbWVwYXJ0ID09ICdtaW51dGUnKVxyXG4gICAgICAgICAgICB2YWx1ZSA9IHRtcFZhbHVlLmZvcm1hdCh0aGlzLmNmZy5zbWFsbERhdGVXaXRoTSkgKyBcIjo2MFwiO1xyXG5cclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGdW56aW9uZSBjaGUgZWZmZXR0dWEgbCdvcmRpbmFtZW50byBmcmEgMiBkYXRlIGluIGJhc2UgYWxsYSBkaXJlemlvbmUgc3BlY2lmaWNhdGFcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGEgUHJpbWEgZGF0YSBwZXIgaWwgY29uZnJvbnRvXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gYiBTZWNvbmRhIGRhdGEgcGVyIGlsIGNvbmZyb250b1xyXG4gICAgICogQHBhcmFtIHsnYXNjJyB8ICdkZXNjJ30gZGlyZWN0aW9uIERpcmV6aW9uZSByaXNwZXR0byBhIGN1aSBvcmRpbmFyZSBsZSBkdWUgZGF0ZVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSAwIHNlIGxlIGRhdGUgc29ubyB1Z3VhbGksIDEgc2UgbGEgZGF0YSBBIGRldmUgdmVuaXJlIGxvZ2ljYW1lbnRlIHByaW1hIGRlbGxhIGRhdGEgQiwgLTEgYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGF0ZVNvcnQoYTogYW55LCBiOiBhbnksIGRpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycpOiBudW1iZXIge1xyXG4gICAgICAgIGlmIChhIDwgYikgcmV0dXJuIGRpcmVjdGlvbiA9PSAnYXNjJyA/IDEgOiAtMTtcclxuICAgICAgICBlbHNlIGlmIChhID4gYikgcmV0dXJuIGRpcmVjdGlvbiA9PSAnYXNjJyA/IC0xIDogMTtcclxuXHJcbiAgICAgICAgLy8gY29uIGEgdWd1YWxlIGEgYlxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgaWwgdHJpbSBkZWkgc2Vjb25kaSBkYSB1bmEgZGF0YSBlc3ByZXNzYSBjb21lIHN0cmluZ2FcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIERhdGEgZXNwcmVzc2EgY29tZSBzdHJpbmdhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IERhdGEgc2VuemEgaSBzZWNvbmRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0cmltU2Vjb25kcyh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICAvL0kgbnVtZXJpIG1hbmdpYXRpIGRhIGRheWpzIHNwZXNzbyB2ZW5nb25vIHJpY29uZG90dGkgYSBkYXRlIHZlcmUuIE1pIGFzc2ljdXJvIGNoZSBzZSBjaSBzb25vIHNvbG8gbnVtZXJpIHByb3NlZ3VvXHJcbiAgICAgICAgaWYgKCFpc05hTig8YW55PnZhbHVlKSlcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICAvL1NlIG5vbiBobyBxdWFsY29zYSBkZWwgdGlwbyBYWC9ZWS9aWlpaIGFhOmJiOmNjIGRpIHNpY3VybyBub24gw6ggdW5hIGRhdGEgY2hlIG1pIGludGVyZXNzYVxyXG4gICAgICAgIGlmICghL15cXGRcXGRcXC9cXGRcXGRcXC9cXGRcXGRcXGRcXGQgXFxkXFxkOlxcZFxcZDpcXGRcXGQkL2cudGVzdCh2YWx1ZSkpXHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuXHJcbiAgICAgICAgLy9JbiBxdWVzdG8gY2FzbyBtaSBhcnJpdmFubyB2YWxvcmkgY2hlIGRldm9ubyBlc3NlcmUgc3RhbXBhdGkgYXMtaXMsIHNvbG8gdGFnbGlhbmRvIGkgc2Vjb25kaVxyXG4gICAgICAgIHJldHVybiBcIidcIiArIHZhbHVlLnN1YnN0cigwLCB2YWx1ZS5sZW5ndGggLSAzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGEgdW5hIGxpc3RhIGRpIGRhdGUgRGEgZSB1bmEgbGlzdGEgZGkgZGF0ZSBBIHJlc3RpdHVpc2NlIHVuIG9nZ2V0dG8gcmFwcHJlc2VudGFudGUgaWwgcmFuZ2UgY2hlIGluY2x1ZGUgdHV0dGUgbGUgZGF0ZSBwYXNzYXRlXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55W119IGZyb21EYXRlcyBMaXN0YSBkZWkgRGFcclxuICAgICAqIEBwYXJhbSB7YW55W119IHRvRGF0ZXMgTGlzdGEgZGVpIEFcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge3sgZnJvbTogYW55LCB0bzogYW55IH19IFJhbmdlIGRpIGRhdGUgRGEgLSBBIGNoZSBpbmNsdWRlIHR1dHRpIGkgdmFsb3JpIGRpICoqZnJvbURhdGVzKiogZSAqKnRvRGF0ZXMqKlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0TWluTWF4RGF0ZXNSYW5nZShmcm9tRGF0ZXM6IGFueVtdLCB0b0RhdGVzOiBhbnlbXSk6IHsgZnJvbTogYW55LCB0bzogYW55IH0ge1xyXG4gICAgICAgIGxldCBkYXRlc0Zyb21zOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIGxldCBkYXRlc1RvOiBhbnlbXSA9IFtdO1xyXG5cclxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgZnJvbURhdGVzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgbGV0IGQgPSBmcm9tRGF0ZXNbaV07XHJcbiAgICAgICAgICAgIHZhciBjb252ZXJ0aW9uID0gdGhpcy5nZXREYXRlQ29udmVydGlvbihkKTtcclxuICAgICAgICAgICAgaWYgKGNvbnZlcnRpb24pXHJcbiAgICAgICAgICAgICAgICBkYXRlc0Zyb21zLnB1c2goY29udmVydGlvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdG9EYXRlcy5sZW5ndGg7IGkrKylcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIGxldCBkID0gdG9EYXRlc1tpXTtcclxuICAgICAgICAgICAgdmFyIGNvbnZlcnRpb24gPSB0aGlzLmdldERhdGVDb252ZXJ0aW9uKGQpO1xyXG4gICAgICAgICAgICBpZiAoY29udmVydGlvbilcclxuICAgICAgICAgICAgICAgIGRhdGVzVG8ucHVzaChjb252ZXJ0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7IGZyb206IGRheWpzLm1pbihkYXRlc0Zyb21zKSwgdG86IGRheWpzLm1heChkYXRlc1RvKSB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3R0aWVuZSBsYSBjb252ZXJzaW9uZSBkaSB1bmEgZGF0YSBpbiBxdWFsc2lhc2kgZm9ybWF0byBhbCBmb3JtYXRvIHN0YW5kYXJkIERheUpzXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBkYXRlIE9nZ2V0dG8gcmFwcHJlc2VudGFudGUgdW5hIGRhdGEuIFBvdHJlYmJlIGVzc2VyZSB1bmEgc3RyaW5nYSwgdW4gRGF0ZSBvIGdpw6AgdW4gRGF5SnNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlVXRjIEluZGljYSBzZSB1c2FyZSBsJ2VzdGVuc2lvbmUgdXRjIGRpIERheWpzIHBlciBwYXJzYXJlIGxhIGRhdGEgbyBub1xyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7YW55fSBEYXRhIGluIG1vZGFsaXTDoCBEYXlKc1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0RGF0ZUNvbnZlcnRpb24oZGF0ZTogYW55LCB1c2VVdGM6IGJvb2xlYW4gPSBmYWxzZSk6IGFueSB7XHJcbiAgICAgICAgaWYgKCFkYXRlKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNEYXlKcyhkYXRlKSlcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XHJcblxyXG4gICAgICAgIGlmKHRoaXMuaXNKc0RhdGUoZGF0ZSkpXHJcbiAgICAgICAgICAgIHJldHVybiB1c2VVdGMgPyBkYXlqcy51dGMoZGF0ZSk6IGRheWpzKGRhdGUpO1xyXG5cclxuICAgICAgICAvLyBTZSBub24gYyfDqCBsYSBwcm9wcmlldMOgIGxlbmd0aCB2dW9sIGRpcmUgY2hlIG5vbiDDqCB1bmEgc3RyaW5nYSBlIGEgcXVlc3RvIHB1bnRvIG5vbiBobyBpZGVhIGRpIGNoZSBtaW5jaGlhIHNpYVxyXG4gICAgICAgIGxldCBsZW5ndGggPSBkYXRlLmxlbmd0aDtcclxuICAgICAgICBpZiAoIWxlbmd0aClcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIGlmICh1c2VVdGMgJiYgIXRoaXMuYWxsb3dVdGMpXHJcbiAgICAgICAgICAgIHRocm93IFwiQGVzZmFlbnphL2V4dGVuc2lvbnM6IFJpY2hpZXN0YSBkYXRhIFVUQyBtYSBkYSBjb25maWd1cmF6aW9uZSBsYSBsaWJyZXJpYSBub24gbG8gc3VwcG9ydGFcIjtcclxuXHJcbiAgICAgICAgLy8gUGVyIHJpc3Bhcm1pYXJlIGNoaWFtYXRlIGEgdGVudG9uaSwgaW4gYmFzZSBhbGxhIGx1bmdoZXp6YSBkZWxsYSBzdHJpbmdhIGNoaWFtbyBkaXJldHRhbWVudGUgaWwgbWV0b2RvIGdpdXN0bywgXHJcbiAgICAgICAgLy8gY29udHJvbGxhbmRvIHBvaSBjaGUgbWkgZ2VuZXJpIHVuYSBkYXRhIGNvbWUgbWUgbGEgYXNwZXR0byBpb1xyXG4gICAgICAgIGxldCB0cnlUaGlzID0gbnVsbDtcclxuICAgICAgICBsZXQgdG9DYWxsID0gdXNlVXRjID8gZGF5anMudXRjIDogZGF5anM7XHJcblxyXG4gICAgICAgIC8vIFNlIGxhIGRhdGEgY29udGllbmUgbGEgbGV0dGVyYSBcIlRcIiB2dW9sIGRpcmUgY2hlIMOoIHVuYSBkYXRhIGRlbCB0aXBvIDIwMjAtMTAtMTVUMDA6MDA6MDAsIGRpcmV0dGFtZW50ZSBwYXJzYWJpbGUgZGFsIGRheWpzIGNvbCBsb2NhbGUgY29ycmV0dG8uXHJcbiAgICAgICAgLy8gUGVyIGlsIHJlc3RvIG1pIGJhc28gc3VsbGEgbHVuZ2hlenphIGRlbGxhIHN0cmluZ2FcclxuICAgICAgICBpZiAoKDxzdHJpbmc+ZGF0ZSkuaW5jbHVkZXMoXCJUXCIpKVxyXG4gICAgICAgICAgICB0cnlUaGlzID0gdG9DYWxsKGRhdGUpO1xyXG4gICAgICAgIGVsc2UgaWYgKGxlbmd0aCA9PSB0aGlzLmNmZy5mdWxsZGF0ZS5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSwgdGhpcy5jZmcuZnVsbGRhdGUpO1xyXG4gICAgICAgIGVsc2UgaWYgKGxlbmd0aCA9PSB0aGlzLmNmZy5zbWFsbERhdGUubGVuZ3RoKVxyXG4gICAgICAgICAgICB0cnlUaGlzID0gdG9DYWxsKGRhdGUsIHRoaXMuY2ZnLnNtYWxsRGF0ZSk7XHJcbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IHRoaXMuY2ZnLmZ1bGxkYXRlTm9TUy5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSwgdGhpcy5jZmcuZnVsbGRhdGVOb1NTKVxyXG5cclxuICAgICAgICBpZiAodHJ5VGhpcy5pc1ZhbGlkKCkpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnlUaGlzO1xyXG5cclxuICAgICAgICAvLyBTZSBuaWVudGUgZnVuemlvbmEsIG51bGwuIFxyXG4gICAgICAgIC8vIFJpY29uZHVycmUgbCdJbnB1dCBhZCB1bmEgZGF0YSBub24gw6ggcG9zc2liaWxlLlxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIGNoZSByZXN0aXR1aXNjZSAqKnRydWUqKiBxdWFsb3JhIGwnb2dnZXR0byBwYXNzYXRvIGZvc3NlIHVuYSBkYXRhIHZlcmEgZSBwcm9wcmlhLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gY2hlY2sgT2dnZXR0byBkYSBjb250cm9sbGFyZVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gSW5kaWNhemlvbmUgc2UgbCdvZ2dldHRvIMOoIHVuIHZlcm8gRGF0ZSBkaSBKYXZhc2NyaXB0IG8gbm9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpc0pzRGF0ZShjaGVjazogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGNoZWNrICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChjaGVjaykgPT09IFwiW29iamVjdCBEYXRlXVwiICYmICFpc05hTihjaGVjayk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgY2hlIHJlc3RpdHVpc2NlICoqdHJ1ZSoqIHF1YWxvcmEgbCdvZ2dldHRvIHBhc3NhdG8gZm9zc2UgdW4gRGF5SnMgdmVybyBlIHByb3ByaW8sICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBjaGVjayBPZ2dldHRvIGRhIGNvbnRyb2xsYXJlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gSW5kaWNhemlvbmUgc2UgbCdvZ2dldHRvIMOoIHVuIHZlcm8gRGF5SnMgbyBub1xyXG4gICAgICovXHJcbiAgICAgcHJpdmF0ZSBpc0RheUpzKGNoZWNrOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBOb24gdXNvIGluc3RhbmNlb2YgcGVyY2jDqSBzYXJlYmJlIGVzdHJlbWFtZW50ZSBwacO5IGxlbnRvXHJcbiAgICAgICAgLy8gTm9uIHVzbyBuZW1tZW5vIGlzRGF5anMoKSBkZWxsYSBsaWJyZXJpYSBEYXlqcyBkYXRvIGNoZSBoYSBsbyBzdGVzc28gcHJvYmxlbWE6IGh0dHBzOi8vZ2l0aHViLmNvbS9pYW1rdW4vZGF5anMvYmxvYi8wNmY4OGY0MjU4MjhiMWNlOTZiNzM3MzMyZDI1MTQ1YTk1YTRlZTlkL3NyYy9pbmRleC5qcyNMOVxyXG4gICAgICAgIHJldHVybiBjaGVjay4kRCAhPT0gdW5kZWZpbmVkICYmIGNoZWNrLiRNICE9PSB1bmRlZmluZWQgJiYgY2hlY2suJHkgIT09IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE90dGllbmUgbGEgZm9ybWF0dGF6aW9uZSBkaSB1bmEgZGF0YSBpbiBiYXNlIGFsbGEgdmVyc2lvbmUgcmljaGllc3RhIFwic21hbGxcIiBvIFwibG9uZ1wiIGUgYSBzZSBzdGFtcGFyZSBvIG1lbm8gaSBzZWNvbmRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBkYXRlIE9nZ2V0dG8gcmFwcHJlc2VudGFudGUgdW5hIGRhdGEuIFBvdHJlYmJlIGVzc2VyZSB1bmEgc3RyaW5nYSwgdW4gRGF0ZSBvIGdpw6AgdW4gRGF5SnNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gc21hbGwgSW5kaWNhIHNlIGZvcm1hdHRhcmxhIGNvbiB1biBmb3JtYXRvIGJyZXZlIChzZSAqKnRydWUqKikgbyB1biBmb3JtYXRvIHBpw7kgbHVuZ28gKHNlICoqZmFsc2UqKilcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRGF0YSBmb3JtYXR0YXRhIG5lbCBmb3JtYXRvIHJpY2hpZXN0b1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0Rm9ybWF0dGVkKGRhdGU6IGFueSwgc21hbGw6IGJvb2xlYW4sIHNlY29uZHM6IGJvb2xlYW4pOiBzdHJpbmcge1xyXG4gICAgICAgIHZhciBkYXRlID0gdGhpcy5nZXREYXRlQ29udmVydGlvbihkYXRlKTtcclxuICAgICAgICBpZiAoIWRhdGUpIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoc21hbGwgPyB0aGlzLmNmZy5zbWFsbERhdGUgOiBzZWNvbmRzID8gdGhpcy5jZmcuZnVsbGRhdGVEaXNwbGF5IDogdGhpcy5jZmcuZnVsbGRhdGVEaXNwbGF5Tm9TUyk7XHJcbiAgICB9XHJcbn0iXX0=
|