@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.
- 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} +1 -1
- 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/{esm2015/lib/services/extensions.exports.service.js → esm2020/lib/services/extensions.exports.service.mjs} +24 -17
- 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} +120 -75
- 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/CsvHeaders.d.ts +4 -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 -2435
- 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.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
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
// Angular
|
|
2
|
-
import { Injectable, Inject, Optional } from "@angular/core";
|
|
3
|
-
// Modelli
|
|
4
|
-
import { EXT_ALLOW_UTC, EXT_LOCALE } from "../tokens";
|
|
5
|
-
/**
|
|
6
|
-
* Service che fornisce dei metodi di estensione per la gestione/manipolazione delle date
|
|
7
|
-
*/
|
|
8
|
-
export class DateService {
|
|
9
|
-
/**
|
|
10
|
-
* Costruttore
|
|
11
|
-
*
|
|
12
|
-
* @ignore
|
|
13
|
-
*/
|
|
14
|
-
constructor(LOCALE, allowUtc) {
|
|
15
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
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"][(_a = this.LOCALE) !== null && _a !== void 0 ? _a : 'it-IT'];
|
|
44
|
-
this.cfg.fulldate = this.loc["FULL_DATE_FORMAT"][(_b = this.LOCALE) !== null && _b !== void 0 ? _b : 'it-IT'];
|
|
45
|
-
this.cfg.fulldateNoSS = this.loc["FULL_DATE_FORMAT_NO_SS"][(_c = this.LOCALE) !== null && _c !== void 0 ? _c : 'it-IT'];
|
|
46
|
-
this.cfg.fulldateDisplay = this.loc["FULL_DATE_DISPLAY_FORMAT"][(_d = this.LOCALE) !== null && _d !== void 0 ? _d : 'it-IT'];
|
|
47
|
-
this.cfg.fulldateDisplayNoSS = this.loc["FULL_DATE_DISPLAY_FORMAT_NO_SS"][(_e = this.LOCALE) !== null && _e !== void 0 ? _e : 'it-IT'];
|
|
48
|
-
this.cfg.smallDate = this.loc["SMALL_DATE_DISPLAY_FORMAT"][(_f = this.LOCALE) !== null && _f !== void 0 ? _f : 'it-IT'];
|
|
49
|
-
this.cfg.smallDateWithH = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_HOUR"][(_g = this.LOCALE) !== null && _g !== void 0 ? _g : 'it-IT'];
|
|
50
|
-
this.cfg.smallDateWithM = this.loc["SMALL_DATE_DISPLAY_FORMAT_WITH_MINUTE"][(_h = this.LOCALE) !== null && _h !== void 0 ? _h : '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.decorators = [
|
|
218
|
-
{ type: Injectable }
|
|
219
|
-
];
|
|
220
|
-
DateService.ctorParameters = () => [
|
|
221
|
-
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [EXT_LOCALE,] }] },
|
|
222
|
-
{ type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [EXT_ALLOW_UTC,] }] }
|
|
223
|
-
];
|
|
224
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5kYXRlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zcmMvbGliL3NlcnZpY2VzL2V4dGVuc2lvbnMuZGF0ZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdELFVBQVU7QUFDVixPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQVFyRDs7RUFFRTtBQUVILE1BQU0sT0FBTyxXQUFXO0lBNkJwQjs7OztPQUlHO0lBQ0gsWUFBMkQsTUFBYyxFQUE2QyxRQUFpQjs7UUFBNUUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUE2QyxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBaEN2STs7V0FFRztRQUNLLFFBQUcsR0FBRztZQUNWLG1CQUFtQixFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFO1lBQ3JFLGtCQUFrQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtZQUN0Rix3QkFBd0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUU7WUFDdEYsMkJBQTJCLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUU7WUFDN0UscUNBQXFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUU7WUFDN0YsdUNBQXVDLEVBQUUsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFO1lBQ3JHLDBCQUEwQixFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixF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QUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7OztZQTFPSixVQUFVOzs7eUNBbUNhLFFBQVEsWUFBSSxNQUFNLFNBQUMsVUFBVTswQ0FBMkIsUUFBUSxZQUFJLE1BQU0sU0FBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhclxyXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QsIE9wdGlvbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHsgRVhUX0FMTE9XX1VUQywgRVhUX0xPQ0FMRSB9IGZyb20gXCIuLi90b2tlbnNcIjtcclxuXHJcbi8qKlxyXG4gKiBEaWNoaWFyYXppb25lIGRlbGxhIHZhcmlhYmlsZSBnbG9iYWxlIGRheWpzLiBMJ29uZXJlIGRpIFwiY3JlYXJsYVwiIMOoIGFmZmlkYXRvIGFsbCdhcHBsaWNhemlvbmUgY2hlIHV0aWxpenphIHF1ZXN0YSBsaWJyZXJpYSwgXHJcbiAqIGNoZSBkb3Zyw6AgaW1wb3J0YXJlIGxvIHNjcmlwdCBnbG9iYWxlIGRpIGRheWpzIG5lbGxhIENMSVxyXG4gKi9cclxuIGRlY2xhcmUgdmFyIGRheWpzOiBhbnk7XHJcblxyXG4gLyoqXHJcbiAqIFNlcnZpY2UgY2hlIGZvcm5pc2NlIGRlaSBtZXRvZGkgZGkgZXN0ZW5zaW9uZSBwZXIgbGEgZ2VzdGlvbmUvbWFuaXBvbGF6aW9uZSBkZWxsZSBkYXRlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBEYXRlU2VydmljZSB7XHJcbiAgICBcclxuICAgIC8qKlxyXG4gICAgICogT2dnZXR0byBzdGF0aWNvIGRpIGxvY2FsaXp6YXppb25lIHBlciBpIG1lc3NhZ2dpIGRpIHF1ZXN0YSBTZXJ2aWNlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgbG9jID0ge1xyXG4gICAgICAgIFwiU01BTExfREFURV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVlcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVkgSEg6bW06c3NcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tOnNzXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9GT1JNQVRfTk9fU1NcIjogeyAnZW4tVVMnOiBcIk1NL0REL1lZWVkgSEg6bW1cIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tXCIgfSxcclxuICAgICAgICBcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIkREL01NL1lZWVlcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZXCIgfSxcclxuICAgICAgICBcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRfV0lUSF9IT1VSXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZIEhIXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISFwiIH0sXHJcbiAgICAgICAgXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfTUlOVVRFXCI6IHsgJ2VuLVVTJzogXCJERC9NTS9ZWVlZIEhIOm1tXCIsICdpdC1JVCc6IFwiREQvTU0vWVlZWSBISDptbVwiIH0sXHJcbiAgICAgICAgXCJGVUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIjogeyAnZW4tVVMnOiBcIkREL01NL1lZWVkgSEg6bW06c3NcIiwgJ2l0LUlUJzogXCJERC9NTS9ZWVlZIEhIOm1tOnNzXCIgfSxcclxuICAgICAgICBcIkZVTExfREFURV9ESVNQTEFZX0ZPUk1BVF9OT19TU1wiOiB7ICdlbi1VUyc6IFwiREQvTU0vWVlZWSBISDptbVwiLCAnaXQtSVQnOiBcIkREL01NL1lZWVkgSEg6bW1cIiB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2dnZXR0byBkaSBjb25maWd1cmF6aW9uZSBwZXIgdGVuZXJlIGRhIGNvbnRvIGxlIGluZm9ybWF6aW9uaSBzdWkgZm9ybWF0aVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNmZyA9IHtcclxuICAgICAgICBmdWxsZGF0ZTogXCJcIixcclxuICAgICAgICBmdWxsZGF0ZURpc3BsYXk6IFwiXCIsXHJcbiAgICAgICAgc21hbGxEYXRlOiBcIlwiLFxyXG4gICAgICAgIGZ1bGxkYXRlTm9TUzogXCJcIixcclxuICAgICAgICBzbWFsbERhdGVXaXRoSDogXCJcIixcclxuICAgICAgICBzbWFsbERhdGVXaXRoTTogXCJcIixcclxuICAgICAgICBmdWxsZGF0ZURpc3BsYXlOb1NTOiBcIlwiXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3N0cnV0dG9yZVxyXG4gICAgICogXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KEVYVF9MT0NBTEUpIHByaXZhdGUgTE9DQUxFOiBzdHJpbmcsIEBPcHRpb25hbCgpIEBJbmplY3QoRVhUX0FMTE9XX1VUQykgcHJpdmF0ZSBhbGxvd1V0YzogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuY2ZnLnNtYWxsRGF0ZSA9IHRoaXMubG9jW1wiU01BTExfREFURV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuZnVsbGRhdGUgPSB0aGlzLmxvY1tcIkZVTExfREFURV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuZnVsbGRhdGVOb1NTID0gdGhpcy5sb2NbXCJGVUxMX0RBVEVfRk9STUFUX05PX1NTXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlRGlzcGxheSA9IHRoaXMubG9jW1wiRlVMTF9EQVRFX0RJU1BMQVlfRk9STUFUXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLmZ1bGxkYXRlRGlzcGxheU5vU1MgID10aGlzLmxvY1tcIkZVTExfREFURV9ESVNQTEFZX0ZPUk1BVF9OT19TU1wiXVt0aGlzLkxPQ0FMRSA/PyAnaXQtSVQnXTtcclxuICAgICAgICB0aGlzLmNmZy5zbWFsbERhdGUgPSB0aGlzLmxvY1tcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRcIl1bdGhpcy5MT0NBTEUgPz8gJ2l0LUlUJ107XHJcbiAgICAgICAgdGhpcy5jZmcuc21hbGxEYXRlV2l0aEggPSB0aGlzLmxvY1tcIlNNQUxMX0RBVEVfRElTUExBWV9GT1JNQVRfV0lUSF9IT1VSXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgICAgIHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhNID0gdGhpcy5sb2NbXCJTTUFMTF9EQVRFX0RJU1BMQVlfRk9STUFUX1dJVEhfTUlOVVRFXCJdW3RoaXMuTE9DQUxFID8/ICdpdC1JVCddO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWdnaXVzdGEgdW5hIGRhdGEgaW4gXCJpc3RhbnRlIGZpbmFsZVwiIGluIGJhc2UgYSBxdWFsIMOoIGxhIHBhcnRlIGRpIGRhdGEgc2lnbmlmaWNhdGl2YS5cclxuICAgICAqIFxyXG4gICAgICogRXMuIElzdGFudGUgZmluYWxlIGRlbGxlIG9yZTogMDUvMTAvMTk5MiAtLT4gMDQvMTAvMTk5MiAyNDowMCg6MDApXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBkYXRlIERhdGEgcXVhbHNpYXNpIChEYXRlLCBzdHJpbmdhLCBkYXlqcy4uLiksIHZlcnLDoCByaWNvbmRvdHRhIGFkIHVuIG9nZ2V0dG8gZGF5SnNcclxuICAgICAqIEBwYXJhbSB7J2RheScgfCAnaG91cicgfCAnbWludXRlJ30gdGltZXBhcnQgUGFydGUgc2lnbmlmaWNhdGl2YSBkZWxsYSBkYXRhXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHByaW50U2Vjb25kcyBJbmRpY2Egc2UgZWZmZXR0dWFyZSBsYSBzdGFtcGEgZGVpIHNlY29uZGkgbyBub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRqdXN0RGF0ZVRvRmluYWxJbnN0YW50KGRhdGU6IGFueSwgdGltZXBhcnQ6ICdkYXknIHwgJ2hvdXInIHwgJ21pbnV0ZScsIHByaW50U2Vjb25kczogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcge1xyXG4gICAgICAgIGxldCBteWR0ID0gdGhpcy5nZXREYXRlQ29udmVydGlvbihkYXRlKTtcclxuICAgICAgICBpZiAobXlkdCA9PSBudWxsKSByZXR1cm4gXCJGRTogTm90IGEgRGF0ZVwiO1xyXG5cclxuICAgICAgICBsZXQgaXNaZXJvVGltZSA9IG15ZHQuc3RhcnRPZih0aW1lcGFydCkudmFsdWVPZigpID09PSBteWR0LnZhbHVlT2YoKTtcclxuICAgICAgICBpZiAoIWlzWmVyb1RpbWUpIHJldHVybiBwcmludFNlY29uZHMgPyBteWR0LmZvcm1hdCh0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXkpIDogbXlkdC5mb3JtYXQodGhpcy5jZmcuZnVsbGRhdGVEaXNwbGF5Tm9TUyk7XHJcblxyXG4gICAgICAgIGxldCB0bXBWYWx1ZSA9IG15ZHQuc3VidHJhY3QoMSwgdGltZXBhcnQpO1xyXG4gICAgICAgIGxldCB2YWx1ZSA9IFwiXCI7XHJcblxyXG4gICAgICAgIC8vIElzdGFudGUgZmluYWxlIGRlbGxlIG9yZTogMDUvMTAvMTk5MiAtLT4gMDQvMTAvMTk5MiAyNDowMCg6MDApXHJcbiAgICAgICAgaWYgKHRpbWVwYXJ0ID09ICdkYXknKVxyXG4gICAgICAgICAgICB2YWx1ZSA9IHRtcFZhbHVlLmZvcm1hdCh0aGlzLmNmZy5zbWFsbERhdGUpICsgXCIgMjQ6MDBcIiArIChwcmludFNlY29uZHMgPyAnOjAwJyA6ICcnKTtcclxuXHJcbiAgICAgICAgLy8gSXN0YW50ZSBmaW5hbGUgZGVpIG1pbnV0aTogZ2lvcm5vIDA1LzEwLzE5OTIgMDQ6MDA6MDAgLS0+IDA1LzEwLzE5OTIgMDM6NjAoOjAwKVxyXG4gICAgICAgIGVsc2UgaWYgKHRpbWVwYXJ0ID09ICdob3VyJylcclxuICAgICAgICAgICAgdmFsdWUgPSB0bXBWYWx1ZS5mb3JtYXQodGhpcy5jZmcuc21hbGxEYXRlV2l0aEgpICsgXCI6NjBcIiArIChwcmludFNlY29uZHMgPyAnOjAwJyA6ICcnKTtcclxuXHJcbiAgICAgICAgLy8gSXN0YW50ZSBmaW5hbGUgZGVpIHNlY29uZGk6IGdpb3JubyAwNS8xMC8xOTkyIDA0OjEwOjAwIC0tPiAwNS8xMC8xOTkyIDA0OjA5OjYwXHJcbiAgICAgICAgZWxzZSBpZiAodGltZXBhcnQgPT0gJ21pbnV0ZScpXHJcbiAgICAgICAgICAgIHZhbHVlID0gdG1wVmFsdWUuZm9ybWF0KHRoaXMuY2ZnLnNtYWxsRGF0ZVdpdGhNKSArIFwiOjYwXCI7XHJcblxyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGNoZSBlZmZldHR1YSBsJ29yZGluYW1lbnRvIGZyYSAyIGRhdGUgaW4gYmFzZSBhbGxhIGRpcmV6aW9uZSBzcGVjaWZpY2F0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gYSBQcmltYSBkYXRhIHBlciBpbCBjb25mcm9udG9cclxuICAgICAqIEBwYXJhbSB7YW55fSBiIFNlY29uZGEgZGF0YSBwZXIgaWwgY29uZnJvbnRvXHJcbiAgICAgKiBAcGFyYW0geydhc2MnIHwgJ2Rlc2MnfSBkaXJlY3Rpb24gRGlyZXppb25lIHJpc3BldHRvIGEgY3VpIG9yZGluYXJlIGxlIGR1ZSBkYXRlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgc2UgbGUgZGF0ZSBzb25vIHVndWFsaSwgMSBzZSBsYSBkYXRhIEEgZGV2ZSB2ZW5pcmUgbG9naWNhbWVudGUgcHJpbWEgZGVsbGEgZGF0YSBCLCAtMSBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkYXRlU29ydChhOiBhbnksIGI6IGFueSwgZGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGEgPCBiKSByZXR1cm4gZGlyZWN0aW9uID09ICdhc2MnID8gMSA6IC0xO1xyXG4gICAgICAgIGVsc2UgaWYgKGEgPiBiKSByZXR1cm4gZGlyZWN0aW9uID09ICdhc2MnID8gLTEgOiAxO1xyXG5cclxuICAgICAgICAvLyBjb24gYSB1Z3VhbGUgYSBiXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFZmZldHR1YSBpbCB0cmltIGRlaSBzZWNvbmRpIGRhIHVuYSBkYXRhIGVzcHJlc3NhIGNvbWUgc3RyaW5nYVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgRGF0YSBlc3ByZXNzYSBjb21lIHN0cmluZ2FcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRGF0YSBzZW56YSBpIHNlY29uZGlcclxuICAgICAqL1xyXG4gICAgcHVibGljIHRyaW1TZWNvbmRzKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIC8vSSBudW1lcmkgbWFuZ2lhdGkgZGEgZGF5anMgc3Blc3NvIHZlbmdvbm8gcmljb25kb3R0aSBhIGRhdGUgdmVyZS4gTWkgYXNzaWN1cm8gY2hlIHNlIGNpIHNvbm8gc29sbyBudW1lcmkgcHJvc2VndW9cclxuICAgICAgICBpZiAoIWlzTmFOKDxhbnk+dmFsdWUpKVxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcblxyXG4gICAgICAgIC8vU2Ugbm9uIGhvIHF1YWxjb3NhIGRlbCB0aXBvIFhYL1lZL1paWlogYWE6YmI6Y2MgZGkgc2ljdXJvIG5vbiDDqCB1bmEgZGF0YSBjaGUgbWkgaW50ZXJlc3NhXHJcbiAgICAgICAgaWYgKCEvXlxcZFxcZFxcL1xcZFxcZFxcL1xcZFxcZFxcZFxcZCBcXGRcXGQ6XFxkXFxkOlxcZFxcZCQvZy50ZXN0KHZhbHVlKSlcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICAvL0luIHF1ZXN0byBjYXNvIG1pIGFycml2YW5vIHZhbG9yaSBjaGUgZGV2b25vIGVzc2VyZSBzdGFtcGF0aSBhcy1pcywgc29sbyB0YWdsaWFuZG8gaSBzZWNvbmRpXHJcbiAgICAgICAgcmV0dXJuIFwiJ1wiICsgdmFsdWUuc3Vic3RyKDAsIHZhbHVlLmxlbmd0aCAtIDMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0YSB1bmEgbGlzdGEgZGkgZGF0ZSBEYSBlIHVuYSBsaXN0YSBkaSBkYXRlIEEgcmVzdGl0dWlzY2UgdW4gb2dnZXR0byByYXBwcmVzZW50YW50ZSBpbCByYW5nZSBjaGUgaW5jbHVkZSB0dXR0ZSBsZSBkYXRlIHBhc3NhdGVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gZnJvbURhdGVzIExpc3RhIGRlaSBEYVxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gdG9EYXRlcyBMaXN0YSBkZWkgQVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7eyBmcm9tOiBhbnksIHRvOiBhbnkgfX0gUmFuZ2UgZGkgZGF0ZSBEYSAtIEEgY2hlIGluY2x1ZGUgdHV0dGkgaSB2YWxvcmkgZGkgKipmcm9tRGF0ZXMqKiBlICoqdG9EYXRlcyoqXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRNaW5NYXhEYXRlc1JhbmdlKGZyb21EYXRlczogYW55W10sIHRvRGF0ZXM6IGFueVtdKTogeyBmcm9tOiBhbnksIHRvOiBhbnkgfSB7XHJcbiAgICAgICAgbGV0IGRhdGVzRnJvbXM6IGFueVtdID0gW107XHJcbiAgICAgICAgbGV0IGRhdGVzVG86IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBmcm9tRGF0ZXMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBsZXQgZCA9IGZyb21EYXRlc1tpXTtcclxuICAgICAgICAgICAgdmFyIGNvbnZlcnRpb24gPSB0aGlzLmdldERhdGVDb252ZXJ0aW9uKGQpO1xyXG4gICAgICAgICAgICBpZiAoY29udmVydGlvbilcclxuICAgICAgICAgICAgICAgIGRhdGVzRnJvbXMucHVzaChjb252ZXJ0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0b0RhdGVzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgbGV0IGQgPSB0b0RhdGVzW2ldO1xyXG4gICAgICAgICAgICB2YXIgY29udmVydGlvbiA9IHRoaXMuZ2V0RGF0ZUNvbnZlcnRpb24oZCk7XHJcbiAgICAgICAgICAgIGlmIChjb252ZXJ0aW9uKVxyXG4gICAgICAgICAgICAgICAgZGF0ZXNUby5wdXNoKGNvbnZlcnRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgZnJvbTogZGF5anMubWluKGRhdGVzRnJvbXMpLCB0bzogZGF5anMubWF4KGRhdGVzVG8pIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIGxhIGNvbnZlcnNpb25lIGRpIHVuYSBkYXRhIGluIHF1YWxzaWFzaSBmb3JtYXRvIGFsIGZvcm1hdG8gc3RhbmRhcmQgRGF5SnNcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGRhdGUgT2dnZXR0byByYXBwcmVzZW50YW50ZSB1bmEgZGF0YS4gUG90cmViYmUgZXNzZXJlIHVuYSBzdHJpbmdhLCB1biBEYXRlIG8gZ2nDoCB1biBEYXlKc1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSB1c2VVdGMgSW5kaWNhIHNlIHVzYXJlIGwnZXN0ZW5zaW9uZSB1dGMgZGkgRGF5anMgcGVyIHBhcnNhcmUgbGEgZGF0YSBvIG5vXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnl9IERhdGEgaW4gbW9kYWxpdMOgIERheUpzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXREYXRlQ29udmVydGlvbihkYXRlOiBhbnksIHVzZVV0YzogYm9vbGVhbiA9IGZhbHNlKTogYW55IHtcclxuICAgICAgICBpZiAoIWRhdGUpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc0RheUpzKGRhdGUpKVxyXG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcclxuXHJcbiAgICAgICAgaWYodGhpcy5pc0pzRGF0ZShkYXRlKSlcclxuICAgICAgICAgICAgcmV0dXJuIHVzZVV0YyA/IGRheWpzLnV0YyhkYXRlKTogZGF5anMoZGF0ZSk7XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBjJ8OoIGxhIHByb3ByaWV0w6AgbGVuZ3RoIHZ1b2wgZGlyZSBjaGUgbm9uIMOoIHVuYSBzdHJpbmdhIGUgYSBxdWVzdG8gcHVudG8gbm9uIGhvIGlkZWEgZGkgY2hlIG1pbmNoaWEgc2lhXHJcbiAgICAgICAgbGV0IGxlbmd0aCA9IGRhdGUubGVuZ3RoO1xyXG4gICAgICAgIGlmICghbGVuZ3RoKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHVzZVV0YyAmJiAhdGhpcy5hbGxvd1V0YylcclxuICAgICAgICAgICAgdGhyb3cgXCJAZXNmYWVuemEvZXh0ZW5zaW9uczogUmljaGllc3RhIGRhdGEgVVRDIG1hIGRhIGNvbmZpZ3VyYXppb25lIGxhIGxpYnJlcmlhIG5vbiBsbyBzdXBwb3J0YVwiO1xyXG5cclxuICAgICAgICAvLyBQZXIgcmlzcGFybWlhcmUgY2hpYW1hdGUgYSB0ZW50b25pLCBpbiBiYXNlIGFsbGEgbHVuZ2hlenphIGRlbGxhIHN0cmluZ2EgY2hpYW1vIGRpcmV0dGFtZW50ZSBpbCBtZXRvZG8gZ2l1c3RvLCBcclxuICAgICAgICAvLyBjb250cm9sbGFuZG8gcG9pIGNoZSBtaSBnZW5lcmkgdW5hIGRhdGEgY29tZSBtZSBsYSBhc3BldHRvIGlvXHJcbiAgICAgICAgbGV0IHRyeVRoaXMgPSBudWxsO1xyXG4gICAgICAgIGxldCB0b0NhbGwgPSB1c2VVdGMgPyBkYXlqcy51dGMgOiBkYXlqcztcclxuXHJcbiAgICAgICAgLy8gU2UgbGEgZGF0YSBjb250aWVuZSBsYSBsZXR0ZXJhIFwiVFwiIHZ1b2wgZGlyZSBjaGUgw6ggdW5hIGRhdGEgZGVsIHRpcG8gMjAyMC0xMC0xNVQwMDowMDowMCwgZGlyZXR0YW1lbnRlIHBhcnNhYmlsZSBkYWwgZGF5anMgY29sIGxvY2FsZSBjb3JyZXR0by5cclxuICAgICAgICAvLyBQZXIgaWwgcmVzdG8gbWkgYmFzbyBzdWxsYSBsdW5naGV6emEgZGVsbGEgc3RyaW5nYVxyXG4gICAgICAgIGlmICgoPHN0cmluZz5kYXRlKS5pbmNsdWRlcyhcIlRcIikpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSk7XHJcbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IHRoaXMuY2ZnLmZ1bGxkYXRlLmxlbmd0aClcclxuICAgICAgICAgICAgdHJ5VGhpcyA9IHRvQ2FsbChkYXRlLCB0aGlzLmNmZy5mdWxsZGF0ZSk7XHJcbiAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IHRoaXMuY2ZnLnNtYWxsRGF0ZS5sZW5ndGgpXHJcbiAgICAgICAgICAgIHRyeVRoaXMgPSB0b0NhbGwoZGF0ZSwgdGhpcy5jZmcuc21hbGxEYXRlKTtcclxuICAgICAgICBlbHNlIGlmIChsZW5ndGggPT0gdGhpcy5jZmcuZnVsbGRhdGVOb1NTLmxlbmd0aClcclxuICAgICAgICAgICAgdHJ5VGhpcyA9IHRvQ2FsbChkYXRlLCB0aGlzLmNmZy5mdWxsZGF0ZU5vU1MpXHJcblxyXG4gICAgICAgIGlmICh0cnlUaGlzLmlzVmFsaWQoKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRyeVRoaXM7XHJcblxyXG4gICAgICAgIC8vIFNlIG5pZW50ZSBmdW56aW9uYSwgbnVsbC4gXHJcbiAgICAgICAgLy8gUmljb25kdXJyZSBsJ0lucHV0IGFkIHVuYSBkYXRhIG5vbiDDqCBwb3NzaWJpbGUuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgY2hlIHJlc3RpdHVpc2NlICoqdHJ1ZSoqIHF1YWxvcmEgbCdvZ2dldHRvIHBhc3NhdG8gZm9zc2UgdW5hIGRhdGEgdmVyYSBlIHByb3ByaWEsICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBjaGVjayBPZ2dldHRvIGRhIGNvbnRyb2xsYXJlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBJbmRpY2F6aW9uZSBzZSBsJ29nZ2V0dG8gw6ggdW4gdmVybyBEYXRlIGRpIEphdmFzY3JpcHQgbyBub1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzSnNEYXRlKGNoZWNrOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gY2hlY2sgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGNoZWNrKSA9PT0gXCJbb2JqZWN0IERhdGVdXCIgJiYgIWlzTmFOKGNoZWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBjaGUgcmVzdGl0dWlzY2UgKip0cnVlKiogcXVhbG9yYSBsJ29nZ2V0dG8gcGFzc2F0byBmb3NzZSB1biBEYXlKcyB2ZXJvIGUgcHJvcHJpbywgKipmYWxzZSoqIGFsdHJpbWVudGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGNoZWNrIE9nZ2V0dG8gZGEgY29udHJvbGxhcmVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBJbmRpY2F6aW9uZSBzZSBsJ29nZ2V0dG8gw6ggdW4gdmVybyBEYXlKcyBvIG5vXHJcbiAgICAgKi9cclxuICAgICBwcml2YXRlIGlzRGF5SnMoY2hlY2s6IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIE5vbiB1c28gaW5zdGFuY2VvZiBwZXJjaMOpIHNhcmViYmUgZXN0cmVtYW1lbnRlIHBpw7kgbGVudG9cclxuICAgICAgICAvLyBOb24gdXNvIG5lbW1lbm8gaXNEYXlqcygpIGRlbGxhIGxpYnJlcmlhIERheWpzIGRhdG8gY2hlIGhhIGxvIHN0ZXNzbyBwcm9ibGVtYTogaHR0cHM6Ly9naXRodWIuY29tL2lhbWt1bi9kYXlqcy9ibG9iLzA2Zjg4ZjQyNTgyOGIxY2U5NmI3MzczMzJkMjUxNDVhOTVhNGVlOWQvc3JjL2luZGV4LmpzI0w5XHJcbiAgICAgICAgcmV0dXJuIGNoZWNrLiREICE9PSB1bmRlZmluZWQgJiYgY2hlY2suJE0gIT09IHVuZGVmaW5lZCAmJiBjaGVjay4keSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3R0aWVuZSBsYSBmb3JtYXR0YXppb25lIGRpIHVuYSBkYXRhIGluIGJhc2UgYWxsYSB2ZXJzaW9uZSByaWNoaWVzdGEgXCJzbWFsbFwiIG8gXCJsb25nXCIgZSBhIHNlIHN0YW1wYXJlIG8gbWVubyBpIHNlY29uZGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGRhdGUgT2dnZXR0byByYXBwcmVzZW50YW50ZSB1bmEgZGF0YS4gUG90cmViYmUgZXNzZXJlIHVuYSBzdHJpbmdhLCB1biBEYXRlIG8gZ2nDoCB1biBEYXlKc1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBzbWFsbCBJbmRpY2Egc2UgZm9ybWF0dGFybGEgY29uIHVuIGZvcm1hdG8gYnJldmUgKHNlICoqdHJ1ZSoqKSBvIHVuIGZvcm1hdG8gcGnDuSBsdW5nbyAoc2UgKipmYWxzZSoqKVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBEYXRhIGZvcm1hdHRhdGEgbmVsIGZvcm1hdG8gcmljaGllc3RvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRGb3JtYXR0ZWQoZGF0ZTogYW55LCBzbWFsbDogYm9vbGVhbiwgc2Vjb25kczogYm9vbGVhbik6IHN0cmluZyB7XHJcbiAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmdldERhdGVDb252ZXJ0aW9uKGRhdGUpO1xyXG4gICAgICAgIGlmICghZGF0ZSkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChzbWFsbCA/IHRoaXMuY2ZnLnNtYWxsRGF0ZSA6IHNlY29uZHMgPyB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXkgOiB0aGlzLmNmZy5mdWxsZGF0ZURpc3BsYXlOb1NTKTtcclxuICAgIH1cclxufSJdfQ==
|