@blinkk/root-cms 1.0.0-rc.9 → 1.0.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/LICENSE +22 -0
- package/README.md +66 -0
- package/bin/root-cms.js +5 -23
- package/dist/app.js +67 -14
- package/dist/cli.js +210 -100
- package/dist/client.d.ts +81 -4
- package/dist/client.js +267 -8
- package/dist/core.d.ts +2 -3
- package/dist/core.js +275 -8
- package/dist/functions.d.ts +1 -1
- package/dist/functions.js +553 -98
- package/dist/plugin.d.ts +18 -5
- package/dist/plugin.js +668 -140
- package/dist/project.d.ts +2 -2
- package/dist/richtext.d.ts +73 -0
- package/dist/richtext.js +129 -0
- package/dist/{schema-fad0a59a.d.ts → schema--v3Ho5Lj.d.ts} +27 -39
- package/dist/ui/signin.css +8 -0
- package/dist/ui/signin.js +571 -407
- package/dist/ui/ui.css +1006 -27
- package/dist/ui/ui.js +26228 -8796
- package/package.json +53 -36
package/dist/plugin.js
CHANGED
|
@@ -9,23 +9,527 @@ import {
|
|
|
9
9
|
initializeApp
|
|
10
10
|
} from "firebase-admin/app";
|
|
11
11
|
import { getAuth } from "firebase-admin/auth";
|
|
12
|
+
import * as jsonwebtoken from "jsonwebtoken";
|
|
12
13
|
import sirv from "sirv";
|
|
13
14
|
|
|
14
15
|
// core/api.ts
|
|
15
16
|
import { multipartMiddleware } from "@blinkk/root/middleware";
|
|
16
17
|
|
|
17
|
-
// core/runtime.ts
|
|
18
|
-
import {
|
|
19
|
-
FieldValue as FieldValue2,
|
|
20
|
-
getFirestore as getFirestore2
|
|
21
|
-
} from "firebase-admin/firestore";
|
|
22
|
-
|
|
23
18
|
// core/client.ts
|
|
24
19
|
import crypto from "node:crypto";
|
|
25
20
|
import {
|
|
26
21
|
FieldValue,
|
|
22
|
+
Timestamp,
|
|
27
23
|
getFirestore
|
|
28
24
|
} from "firebase-admin/firestore";
|
|
25
|
+
var RootCMSClient = class {
|
|
26
|
+
constructor(rootConfig) {
|
|
27
|
+
this.rootConfig = rootConfig;
|
|
28
|
+
this.cmsPlugin = getCmsPlugin(this.rootConfig);
|
|
29
|
+
const cmsPluginOptions = this.cmsPlugin.getConfig();
|
|
30
|
+
this.projectId = cmsPluginOptions.id || "default";
|
|
31
|
+
this.app = this.cmsPlugin.getFirebaseApp();
|
|
32
|
+
this.db = getFirestore(this.app);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Retrieves doc data from Root.js CMS.
|
|
36
|
+
*/
|
|
37
|
+
async getDoc(collectionId, slug, options) {
|
|
38
|
+
const rawData = await this.getRawDoc(collectionId, slug, options);
|
|
39
|
+
if (rawData) {
|
|
40
|
+
return unmarshalData(rawData);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Retrieves raw doc data as stored in the database. Only use this if you know
|
|
46
|
+
* what you are doing.
|
|
47
|
+
*/
|
|
48
|
+
async getRawDoc(collectionId, slug, options) {
|
|
49
|
+
const mode = options.mode;
|
|
50
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
51
|
+
slug = slug.replaceAll("/", "--");
|
|
52
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}/${slug}`;
|
|
53
|
+
const docRef = this.db.doc(dbPath);
|
|
54
|
+
const doc = await docRef.get();
|
|
55
|
+
if (doc.exists) {
|
|
56
|
+
return doc.data();
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
async setRawDoc(collectionId, slug, data, options) {
|
|
61
|
+
const mode = options.mode;
|
|
62
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
63
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}/${slug}`;
|
|
64
|
+
const docRef = this.db.doc(dbPath);
|
|
65
|
+
await docRef.set(data);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Lists docs from a Root.js CMS collection.
|
|
69
|
+
*/
|
|
70
|
+
async listDocs(collectionId, options) {
|
|
71
|
+
const mode = options.mode;
|
|
72
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
73
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}`;
|
|
74
|
+
let query = this.db.collection(dbPath);
|
|
75
|
+
if (options.limit) {
|
|
76
|
+
query = query.limit(options.limit);
|
|
77
|
+
}
|
|
78
|
+
if (options.offset) {
|
|
79
|
+
query = query.offset(options.offset);
|
|
80
|
+
}
|
|
81
|
+
if (options.orderBy) {
|
|
82
|
+
query = query.orderBy(options.orderBy, options.orderByDirection);
|
|
83
|
+
}
|
|
84
|
+
if (options.query) {
|
|
85
|
+
query = options.query(query);
|
|
86
|
+
}
|
|
87
|
+
const results = await query.get();
|
|
88
|
+
const docs = [];
|
|
89
|
+
results.forEach((result) => {
|
|
90
|
+
const doc = unmarshalData(result.data());
|
|
91
|
+
docs.push(doc);
|
|
92
|
+
});
|
|
93
|
+
return { docs };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns the number of docs in a Root.js CMS collection.
|
|
97
|
+
*/
|
|
98
|
+
async getDocsCount(collectionId, options) {
|
|
99
|
+
const mode = options.mode;
|
|
100
|
+
const modeCollection = mode === "draft" ? "Drafts" : "Published";
|
|
101
|
+
const dbPath = `Projects/${this.projectId}/Collections/${collectionId}/${modeCollection}`;
|
|
102
|
+
let query = this.db.collection(dbPath);
|
|
103
|
+
if (options.query) {
|
|
104
|
+
query = options.query(query);
|
|
105
|
+
}
|
|
106
|
+
const results = await query.count().get();
|
|
107
|
+
const count = results.data().count;
|
|
108
|
+
return count;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Batch publishes a set of docs by id.
|
|
112
|
+
*/
|
|
113
|
+
async publishDocs(docIds, options) {
|
|
114
|
+
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
|
|
115
|
+
const publishedBy = (options == null ? void 0 : options.publishedBy) || "root-cms-client";
|
|
116
|
+
const docRefs = docIds.map((docId) => {
|
|
117
|
+
const [collection, slug] = docId.split("/");
|
|
118
|
+
if (!collection || !slug) {
|
|
119
|
+
throw new Error(`invalid doc id: ${docId}`);
|
|
120
|
+
}
|
|
121
|
+
const docRef = this.db.doc(
|
|
122
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
123
|
+
);
|
|
124
|
+
return docRef;
|
|
125
|
+
});
|
|
126
|
+
const docSnapshots = await this.db.getAll(...docRefs);
|
|
127
|
+
const docs = docSnapshots.map((snapshot) => snapshot.data()).filter((d) => !!d);
|
|
128
|
+
if (docs.length === 0) {
|
|
129
|
+
console.log("no docs to publish");
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
let batchCount = 0;
|
|
133
|
+
const batch = (options == null ? void 0 : options.batch) || this.db.batch();
|
|
134
|
+
const publishedDocs = [];
|
|
135
|
+
for (const doc of docs) {
|
|
136
|
+
const { id, collection, slug, sys, fields } = doc;
|
|
137
|
+
const draftRef = this.db.doc(
|
|
138
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
139
|
+
);
|
|
140
|
+
const scheduledRef = this.db.doc(
|
|
141
|
+
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
|
|
142
|
+
);
|
|
143
|
+
const publishedRef = this.db.doc(
|
|
144
|
+
`${projectCollectionsPath}/${collection}/Published/${slug}`
|
|
145
|
+
);
|
|
146
|
+
const firstPublishedAt = sys.firstPublishedAt ?? FieldValue.serverTimestamp();
|
|
147
|
+
const firstPublishedBy = sys.firstPublishedBy ?? publishedBy;
|
|
148
|
+
batch.set(publishedRef, {
|
|
149
|
+
id,
|
|
150
|
+
collection,
|
|
151
|
+
slug,
|
|
152
|
+
fields: fields || {},
|
|
153
|
+
sys: {
|
|
154
|
+
...sys,
|
|
155
|
+
firstPublishedAt,
|
|
156
|
+
firstPublishedBy,
|
|
157
|
+
publishedAt: FieldValue.serverTimestamp(),
|
|
158
|
+
publishedBy
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
batchCount += 1;
|
|
162
|
+
batch.delete(scheduledRef);
|
|
163
|
+
batchCount += 1;
|
|
164
|
+
batch.update(draftRef, {
|
|
165
|
+
"sys.scheduledAt": FieldValue.delete(),
|
|
166
|
+
"sys.scheduledBy": FieldValue.delete(),
|
|
167
|
+
"sys.firstPublishedAt": firstPublishedAt,
|
|
168
|
+
"sys.firstPublishedBy": firstPublishedBy,
|
|
169
|
+
"sys.publishedAt": FieldValue.serverTimestamp(),
|
|
170
|
+
"sys.publishedBy": publishedBy
|
|
171
|
+
});
|
|
172
|
+
batchCount += 1;
|
|
173
|
+
publishedDocs.push(doc);
|
|
174
|
+
if (batchCount >= 400) {
|
|
175
|
+
await batch.commit();
|
|
176
|
+
batchCount = 0;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (batchCount > 0) {
|
|
180
|
+
await batch.commit();
|
|
181
|
+
}
|
|
182
|
+
console.log(`published ${publishedDocs.length} docs!`);
|
|
183
|
+
return publishedDocs;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Publishes scheduled docs.
|
|
187
|
+
*/
|
|
188
|
+
async publishScheduledDocs() {
|
|
189
|
+
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
|
|
190
|
+
const now = Math.ceil((/* @__PURE__ */ new Date()).getTime());
|
|
191
|
+
const snapshot = await this.db.collectionGroup("Scheduled").get();
|
|
192
|
+
const docs = snapshot.docs.filter((d) => {
|
|
193
|
+
var _a;
|
|
194
|
+
if (!d.ref.path.startsWith(projectCollectionsPath)) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
const data = d.data() || {};
|
|
198
|
+
const scheduledAt = (_a = data.sys) == null ? void 0 : _a.scheduledAt;
|
|
199
|
+
return scheduledAt && scheduledAt.toMillis && scheduledAt.toMillis() <= now;
|
|
200
|
+
}).map((d) => {
|
|
201
|
+
const dbPath = d.ref.path;
|
|
202
|
+
const segments = dbPath.split("/");
|
|
203
|
+
const slug = segments.at(-1);
|
|
204
|
+
const collection = segments.at(-3);
|
|
205
|
+
const id = `${collection}/${slug}`;
|
|
206
|
+
return {
|
|
207
|
+
data: d.data(),
|
|
208
|
+
id,
|
|
209
|
+
collection,
|
|
210
|
+
slug
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
if (docs.length === 0) {
|
|
214
|
+
console.log("no docs to schedule");
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
let batchCount = 0;
|
|
218
|
+
const batch = this.db.batch();
|
|
219
|
+
const publishedDocs = [];
|
|
220
|
+
for (const doc of docs) {
|
|
221
|
+
const { id, collection, slug, data } = doc;
|
|
222
|
+
const draftRef = this.db.doc(
|
|
223
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
224
|
+
);
|
|
225
|
+
const scheduledRef = this.db.doc(
|
|
226
|
+
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
|
|
227
|
+
);
|
|
228
|
+
const publishedRef = this.db.doc(
|
|
229
|
+
`${projectCollectionsPath}/${collection}/Published/${slug}`
|
|
230
|
+
);
|
|
231
|
+
const { scheduledAt, scheduledBy, ...sys } = data.sys || {};
|
|
232
|
+
const firstPublishedAt = sys.firstPublishedAt ?? scheduledAt;
|
|
233
|
+
const firstPublishedBy = sys.firstPublishedBy ?? (scheduledBy || "root-cms-client");
|
|
234
|
+
batch.set(publishedRef, {
|
|
235
|
+
id,
|
|
236
|
+
collection,
|
|
237
|
+
slug,
|
|
238
|
+
fields: data.fields || {},
|
|
239
|
+
sys: {
|
|
240
|
+
...sys,
|
|
241
|
+
firstPublishedAt,
|
|
242
|
+
firstPublishedBy,
|
|
243
|
+
publishedAt: FieldValue.serverTimestamp(),
|
|
244
|
+
publishedBy: scheduledBy || ""
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
batchCount += 1;
|
|
248
|
+
batch.delete(scheduledRef);
|
|
249
|
+
batchCount += 1;
|
|
250
|
+
batch.update(draftRef, {
|
|
251
|
+
"sys.scheduledAt": FieldValue.delete(),
|
|
252
|
+
"sys.scheduledBy": FieldValue.delete(),
|
|
253
|
+
"sys.firstPublishedAt": firstPublishedAt,
|
|
254
|
+
"sys.firstPublishedBy": firstPublishedBy,
|
|
255
|
+
"sys.publishedAt": FieldValue.serverTimestamp(),
|
|
256
|
+
"sys.publishedBy": scheduledBy || "root-cms-client"
|
|
257
|
+
});
|
|
258
|
+
batchCount += 1;
|
|
259
|
+
publishedDocs.push(doc);
|
|
260
|
+
if (batchCount >= 400) {
|
|
261
|
+
await batch.commit();
|
|
262
|
+
batchCount = 0;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (batchCount > 0) {
|
|
267
|
+
await batch.commit();
|
|
268
|
+
}
|
|
269
|
+
console.log(`published ${publishedDocs.length} docs!`);
|
|
270
|
+
return publishedDocs;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Publishes docs in scheduled releases.
|
|
274
|
+
*/
|
|
275
|
+
async publishScheduledReleases() {
|
|
276
|
+
const releasesPath = `Projects/${this.projectId}/Releases`;
|
|
277
|
+
const now = Math.ceil((/* @__PURE__ */ new Date()).getTime());
|
|
278
|
+
const query = this.db.collection(releasesPath).where("scheduledAt", "<=", Timestamp.fromMillis(now));
|
|
279
|
+
const querySnapshot = await query.get();
|
|
280
|
+
for (const snapshot of querySnapshot.docs) {
|
|
281
|
+
const release = snapshot.data();
|
|
282
|
+
const batch = this.db.batch();
|
|
283
|
+
const publishedBy = release.scheduledBy || "root-cms-client";
|
|
284
|
+
batch.update(snapshot.ref, {
|
|
285
|
+
publishedAt: Timestamp.now(),
|
|
286
|
+
publishedBy,
|
|
287
|
+
scheduledAt: FieldValue.delete(),
|
|
288
|
+
scheduledBy: FieldValue.delete()
|
|
289
|
+
});
|
|
290
|
+
await this.publishDocs(release.docIds || [], { publishedBy, batch });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Loads translations saved in the translations collection, optionally
|
|
295
|
+
* filtered by tag.
|
|
296
|
+
*
|
|
297
|
+
* Returns a map like:
|
|
298
|
+
* ```
|
|
299
|
+
* {
|
|
300
|
+
* "<hash>": {"source": "Hello", "es": "Hola", "fr": "Bonjour"},
|
|
301
|
+
* }
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
async loadTranslations(options) {
|
|
305
|
+
const dbPath = `Projects/${this.projectId}/Translations`;
|
|
306
|
+
let query = this.db.collection(dbPath);
|
|
307
|
+
if (options == null ? void 0 : options.tags) {
|
|
308
|
+
query = query.where("tags", "array-contains-any", options.tags);
|
|
309
|
+
}
|
|
310
|
+
const querySnapshot = await query.get();
|
|
311
|
+
const translationsMap = {};
|
|
312
|
+
querySnapshot.forEach((doc) => {
|
|
313
|
+
const hash = doc.id;
|
|
314
|
+
translationsMap[hash] = doc.data();
|
|
315
|
+
});
|
|
316
|
+
return translationsMap;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Saves a map of translations, e.g.:
|
|
320
|
+
* ```
|
|
321
|
+
* await client.saveTranslations({
|
|
322
|
+
* "Hello": {"es": "Hola", "fr": "Bonjour"},
|
|
323
|
+
* });
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
async saveTranslations(translations, tags) {
|
|
327
|
+
const translationsPath = `Projects/${this.projectId}/Translations`;
|
|
328
|
+
const batch = this.db.batch();
|
|
329
|
+
let batchCount = 0;
|
|
330
|
+
Object.entries(translations).forEach(([source, sourceTranslations]) => {
|
|
331
|
+
const hash = this.getTranslationKey(source);
|
|
332
|
+
const translationRef = this.db.doc(`${translationsPath}/${hash}`);
|
|
333
|
+
const data = {
|
|
334
|
+
...sourceTranslations,
|
|
335
|
+
source: this.normalizeString(source)
|
|
336
|
+
};
|
|
337
|
+
if (tags) {
|
|
338
|
+
data.tags = tags;
|
|
339
|
+
}
|
|
340
|
+
batch.update(translationRef, data);
|
|
341
|
+
batchCount += 1;
|
|
342
|
+
});
|
|
343
|
+
if (batchCount > 500) {
|
|
344
|
+
throw new Error("up to 500 translations can be saved at a time.");
|
|
345
|
+
}
|
|
346
|
+
await batch.commit();
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Returns the "key" used for a translation as stored in the db. Translations
|
|
350
|
+
* are stored under `Projects/<project id>/Translations/<sha1 hash>`.
|
|
351
|
+
*/
|
|
352
|
+
getTranslationKey(source) {
|
|
353
|
+
const sha1 = crypto.createHash("sha1").update(this.normalizeString(source)).digest("hex");
|
|
354
|
+
return sha1;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Cleans a string that's used for translations. Performs the following:
|
|
358
|
+
* - Removes any leading/trailing whitespace
|
|
359
|
+
* - Removes spaces at the end of any line
|
|
360
|
+
*/
|
|
361
|
+
normalizeString(str) {
|
|
362
|
+
const lines = String(str).trim().split("\n").map((line) => line.trimEnd());
|
|
363
|
+
return lines.join("\n");
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Loads translations for a particular locale.
|
|
367
|
+
*
|
|
368
|
+
* Returns a map like:
|
|
369
|
+
* ```
|
|
370
|
+
* {
|
|
371
|
+
* "Hello": "Bonjour",
|
|
372
|
+
* }
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
async loadTranslationsForLocale(locale, options) {
|
|
376
|
+
const translationsMap = await this.loadTranslations(options);
|
|
377
|
+
return translationsForLocale(translationsMap, locale);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Returns a data source configuration object.
|
|
381
|
+
*/
|
|
382
|
+
async getDataSource(dataSourceId) {
|
|
383
|
+
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}`;
|
|
384
|
+
const docRef = this.db.doc(dbPath);
|
|
385
|
+
const doc = await docRef.get();
|
|
386
|
+
if (doc.exists) {
|
|
387
|
+
return doc.data();
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Syncs a data source to draft state.
|
|
393
|
+
*/
|
|
394
|
+
async syncDataSource(dataSourceId, options) {
|
|
395
|
+
const dataSource = await this.getDataSource(dataSourceId);
|
|
396
|
+
if (!dataSource) {
|
|
397
|
+
throw new Error(`data source not found: ${dataSourceId}`);
|
|
398
|
+
}
|
|
399
|
+
const data = await this.fetchData(dataSource);
|
|
400
|
+
const dataSourceDocRef = this.db.doc(
|
|
401
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
402
|
+
);
|
|
403
|
+
const dataDocRef = this.db.doc(
|
|
404
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/draft`
|
|
405
|
+
);
|
|
406
|
+
const syncedBy = (options == null ? void 0 : options.syncedBy) || "root-cms-client";
|
|
407
|
+
const updatedDataSource = {
|
|
408
|
+
...dataSource,
|
|
409
|
+
syncedAt: Timestamp.now(),
|
|
410
|
+
syncedBy
|
|
411
|
+
};
|
|
412
|
+
const batch = this.db.batch();
|
|
413
|
+
batch.set(dataDocRef, {
|
|
414
|
+
dataSource: updatedDataSource,
|
|
415
|
+
data
|
|
416
|
+
});
|
|
417
|
+
batch.update(dataSourceDocRef, {
|
|
418
|
+
syncedAt: Timestamp.now(),
|
|
419
|
+
syncedBy
|
|
420
|
+
});
|
|
421
|
+
await batch.commit();
|
|
422
|
+
console.log(`synced data source: ${dataSourceId}`);
|
|
423
|
+
console.log(`synced by: ${syncedBy}`);
|
|
424
|
+
}
|
|
425
|
+
async publishDataSource(dataSourceId, options) {
|
|
426
|
+
const dataSource = await this.getDataSource(dataSourceId);
|
|
427
|
+
if (!dataSource) {
|
|
428
|
+
throw new Error(`data source not found: ${dataSourceId}`);
|
|
429
|
+
}
|
|
430
|
+
const dataSourceDocRef = this.db.doc(
|
|
431
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
432
|
+
);
|
|
433
|
+
const dataDocRefDraft = this.db.doc(
|
|
434
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}/draft`
|
|
435
|
+
);
|
|
436
|
+
const dataDocRefPublished = this.db.doc(
|
|
437
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}/published`
|
|
438
|
+
);
|
|
439
|
+
const dataRes = await this.getFromDataSource(dataSourceId, { mode: "draft" });
|
|
440
|
+
const publishedBy = (options == null ? void 0 : options.publishedBy) || "root-cms-client";
|
|
441
|
+
const updatedDataSource = {
|
|
442
|
+
...dataSource,
|
|
443
|
+
publishedAt: Timestamp.now(),
|
|
444
|
+
publishedBy
|
|
445
|
+
};
|
|
446
|
+
const batch = this.db.batch();
|
|
447
|
+
batch.set(dataDocRefPublished, {
|
|
448
|
+
dataSource: updatedDataSource,
|
|
449
|
+
data: (dataRes == null ? void 0 : dataRes.data) || null
|
|
450
|
+
});
|
|
451
|
+
batch.update(dataDocRefDraft, {
|
|
452
|
+
dataSource: updatedDataSource
|
|
453
|
+
});
|
|
454
|
+
batch.update(dataSourceDocRef, {
|
|
455
|
+
publishedAt: Timestamp.now(),
|
|
456
|
+
publishedBy
|
|
457
|
+
});
|
|
458
|
+
await batch.commit();
|
|
459
|
+
console.log(`published data ${dataSourceId}`);
|
|
460
|
+
console.log(`published by: ${publishedBy}`);
|
|
461
|
+
}
|
|
462
|
+
async fetchData(dataSource) {
|
|
463
|
+
if (dataSource.type === "http") {
|
|
464
|
+
return await this.fetchHttpData(dataSource);
|
|
465
|
+
}
|
|
466
|
+
throw new Error(`unsupported data source: ${dataSource.type}`);
|
|
467
|
+
}
|
|
468
|
+
async fetchHttpData(dataSource) {
|
|
469
|
+
var _a, _b, _c;
|
|
470
|
+
const url = dataSource.url || "";
|
|
471
|
+
if (!url.startsWith("https://")) {
|
|
472
|
+
throw new Error(`url not supported: ${url}`);
|
|
473
|
+
}
|
|
474
|
+
const res = await fetch(url, {
|
|
475
|
+
method: ((_a = dataSource.httpOptions) == null ? void 0 : _a.method) || "GET",
|
|
476
|
+
headers: ((_b = dataSource.httpOptions) == null ? void 0 : _b.headers) || [],
|
|
477
|
+
body: ((_c = dataSource.httpOptions) == null ? void 0 : _c.body) || void 0
|
|
478
|
+
});
|
|
479
|
+
if (res.status !== 200) {
|
|
480
|
+
const err = await res.text();
|
|
481
|
+
throw new Error(`req failed: ${err}`);
|
|
482
|
+
}
|
|
483
|
+
const contentType = String(res.headers.get("content-type"));
|
|
484
|
+
if (contentType.includes("application/json")) {
|
|
485
|
+
return await res.json();
|
|
486
|
+
}
|
|
487
|
+
return res.text();
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Fetches data from a data source.
|
|
491
|
+
*/
|
|
492
|
+
async getFromDataSource(dataSourceId, options) {
|
|
493
|
+
const mode = (options == null ? void 0 : options.mode) || "published";
|
|
494
|
+
if (!(mode === "draft" || mode === "published")) {
|
|
495
|
+
throw new Error(`invalid mode: ${mode}`);
|
|
496
|
+
}
|
|
497
|
+
if (!dataSourceId || dataSourceId.includes("/")) {
|
|
498
|
+
throw new Error(`invalid data source id: ${dataSourceId}`);
|
|
499
|
+
}
|
|
500
|
+
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}/Data/${mode}`;
|
|
501
|
+
const docRef = this.db.doc(dbPath);
|
|
502
|
+
const doc = await docRef.get();
|
|
503
|
+
if (doc.exists) {
|
|
504
|
+
return doc.data();
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Verifies user exists in the ACL list.
|
|
510
|
+
*/
|
|
511
|
+
async userExistsInAcl(email) {
|
|
512
|
+
if (!email) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
const docRef = this.db.doc(`Projects/${this.projectId}`);
|
|
516
|
+
const snapshot = await docRef.get();
|
|
517
|
+
const data = snapshot.data() || {};
|
|
518
|
+
const acl = data.roles || {};
|
|
519
|
+
if (email in acl) {
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
if (!email.includes("@")) {
|
|
523
|
+
console.warn(`invalid email: ${email}`);
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
const domain = email.split("@").at(-1);
|
|
527
|
+
if (domain && `*@${domain}` in acl) {
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
};
|
|
29
533
|
function getCmsPlugin(rootConfig) {
|
|
30
534
|
const plugins = rootConfig.plugins || [];
|
|
31
535
|
const plugin = plugins.find((plugin2) => plugin2.name === "root-cms");
|
|
@@ -34,98 +538,48 @@ function getCmsPlugin(rootConfig) {
|
|
|
34
538
|
}
|
|
35
539
|
return plugin;
|
|
36
540
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const scheduledAt = (_a = data.sys) == null ? void 0 : _a.scheduledAt;
|
|
55
|
-
return scheduledAt && scheduledAt.toMillis && scheduledAt.toMillis() <= now;
|
|
56
|
-
}).map((d) => {
|
|
57
|
-
const dbPath = d.ref.path;
|
|
58
|
-
const segments = dbPath.split("/");
|
|
59
|
-
const slug = segments.at(-1);
|
|
60
|
-
const collection = segments.at(-3);
|
|
61
|
-
const id = `${collection}/${slug}`;
|
|
62
|
-
return {
|
|
63
|
-
data: d.data(),
|
|
64
|
-
id,
|
|
65
|
-
collection,
|
|
66
|
-
slug
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
if (docs.length === 0) {
|
|
70
|
-
return [];
|
|
71
|
-
}
|
|
72
|
-
let batchCount = 0;
|
|
73
|
-
const batch = db.batch();
|
|
74
|
-
const publishedDocs = [];
|
|
75
|
-
for (const doc of docs) {
|
|
76
|
-
const { id, collection, slug, data } = doc;
|
|
77
|
-
const draftRef = db.doc(
|
|
78
|
-
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
79
|
-
);
|
|
80
|
-
const scheduledRef = db.doc(
|
|
81
|
-
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
|
|
82
|
-
);
|
|
83
|
-
const publishedRef = db.doc(
|
|
84
|
-
`${projectCollectionsPath}/${collection}/Published/${slug}`
|
|
85
|
-
);
|
|
86
|
-
const { scheduledAt, scheduledBy, ...sys } = data.sys || {};
|
|
87
|
-
const firstPublishedAt = sys.firstPublishedAt ?? scheduledAt;
|
|
88
|
-
const firstPublishedBy = sys.firstPublishedBy ?? (scheduledBy || "");
|
|
89
|
-
batch.set(publishedRef, {
|
|
90
|
-
id,
|
|
91
|
-
collection,
|
|
92
|
-
slug,
|
|
93
|
-
fields: data.fields || {},
|
|
94
|
-
sys: {
|
|
95
|
-
...sys,
|
|
96
|
-
firstPublishedAt,
|
|
97
|
-
firstPublishedBy,
|
|
98
|
-
publishedAt: FieldValue2.serverTimestamp(),
|
|
99
|
-
publishedBy: scheduledBy || ""
|
|
541
|
+
function unmarshalData(data) {
|
|
542
|
+
const result = {};
|
|
543
|
+
for (const key in data) {
|
|
544
|
+
const val = data[key];
|
|
545
|
+
if (isObject(val)) {
|
|
546
|
+
if (val.toMillis) {
|
|
547
|
+
result[key] = val.toMillis();
|
|
548
|
+
} else if (Object.hasOwn(val, "_array") && Array.isArray(val._array)) {
|
|
549
|
+
const arr = val._array.map((arrayKey) => {
|
|
550
|
+
return {
|
|
551
|
+
...unmarshalData(val[arrayKey] || {}),
|
|
552
|
+
_arrayKey: arrayKey
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
result[key] = arr;
|
|
556
|
+
} else {
|
|
557
|
+
result[key] = unmarshalData(val);
|
|
100
558
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
batch.delete(scheduledRef);
|
|
104
|
-
batchCount += 1;
|
|
105
|
-
batch.update(draftRef, {
|
|
106
|
-
"sys.scheduledAt": FieldValue2.delete(),
|
|
107
|
-
"sys.scheduledBy": FieldValue2.delete(),
|
|
108
|
-
"sys.firstPublishedAt": firstPublishedAt,
|
|
109
|
-
"sys.firstPublishedBy": firstPublishedBy,
|
|
110
|
-
"sys.publishedAt": FieldValue2.serverTimestamp(),
|
|
111
|
-
"sys.publishedBy": scheduledBy || ""
|
|
112
|
-
});
|
|
113
|
-
batchCount += 1;
|
|
114
|
-
publishedDocs.push(doc);
|
|
115
|
-
if (batchCount >= 498) {
|
|
116
|
-
break;
|
|
559
|
+
} else {
|
|
560
|
+
result[key] = val;
|
|
117
561
|
}
|
|
118
562
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
563
|
+
return result;
|
|
564
|
+
}
|
|
565
|
+
function isObject(data) {
|
|
566
|
+
return typeof data === "object" && !Array.isArray(data) && data !== null;
|
|
567
|
+
}
|
|
568
|
+
function translationsForLocale(translationsMap, locale) {
|
|
569
|
+
const localeTranslations = {};
|
|
570
|
+
Object.values(translationsMap).forEach((string) => {
|
|
571
|
+
const source = string.source;
|
|
572
|
+
const translation = string[locale] || string.en || string.source;
|
|
573
|
+
localeTranslations[source] = translation;
|
|
574
|
+
});
|
|
575
|
+
return localeTranslations;
|
|
122
576
|
}
|
|
123
577
|
|
|
124
578
|
// core/versions.ts
|
|
125
579
|
import path from "node:path";
|
|
126
580
|
import {
|
|
127
|
-
Timestamp as
|
|
128
|
-
getFirestore as
|
|
581
|
+
Timestamp as Timestamp2,
|
|
582
|
+
getFirestore as getFirestore2
|
|
129
583
|
} from "firebase-admin/firestore";
|
|
130
584
|
import glob from "tiny-glob";
|
|
131
585
|
var DOCUMENT_SAVE_OFFSET = 5 * 60 * 1e3;
|
|
@@ -137,7 +591,7 @@ var VersionsService = class {
|
|
|
137
591
|
const projectId = cmsPluginOptions.id || "default";
|
|
138
592
|
this.projectId = projectId;
|
|
139
593
|
const app = cmsPlugin2.getFirebaseApp();
|
|
140
|
-
this.db =
|
|
594
|
+
this.db = getFirestore2(app);
|
|
141
595
|
}
|
|
142
596
|
/**
|
|
143
597
|
* Saves a version of all documents that have been edited since the last run.
|
|
@@ -146,7 +600,7 @@ var VersionsService = class {
|
|
|
146
600
|
const lastRun = await this.getLastRun();
|
|
147
601
|
const lastRunWithOffset = lastRun === 0 ? lastRun : lastRun - DOCUMENT_SAVE_OFFSET;
|
|
148
602
|
const changedDocs = await this.getDocsModifiedAfter(lastRunWithOffset);
|
|
149
|
-
const now =
|
|
603
|
+
const now = Timestamp2.now().toMillis();
|
|
150
604
|
const versions = changedDocs.filter((doc) => {
|
|
151
605
|
const modifiedAt = doc.sys.modifiedAt.toMillis();
|
|
152
606
|
return modifiedAt <= now - DOCUMENT_SAVE_OFFSET;
|
|
@@ -192,7 +646,7 @@ var VersionsService = class {
|
|
|
192
646
|
* Saves {versionLastRun: <timestamp>} to the Projects/<projectId> doc.
|
|
193
647
|
*/
|
|
194
648
|
async saveLastRun(millis) {
|
|
195
|
-
const ts =
|
|
649
|
+
const ts = Timestamp2.fromMillis(millis);
|
|
196
650
|
const projectDocRef = this.db.collection("Projects").doc(this.projectId);
|
|
197
651
|
await projectDocRef.set({ versionsLastRun: ts }, { merge: true });
|
|
198
652
|
}
|
|
@@ -200,7 +654,7 @@ var VersionsService = class {
|
|
|
200
654
|
* Returns a list of all docs that were edited after a certain time.
|
|
201
655
|
*/
|
|
202
656
|
async getDocsModifiedAfter(millis) {
|
|
203
|
-
const ts =
|
|
657
|
+
const ts = Timestamp2.fromMillis(millis);
|
|
204
658
|
const results = [];
|
|
205
659
|
const collectionIds = await this.listCollections();
|
|
206
660
|
for (const collectionId of collectionIds) {
|
|
@@ -245,7 +699,9 @@ async function runCronJob(name, fn, ...args) {
|
|
|
245
699
|
}
|
|
246
700
|
}
|
|
247
701
|
async function runPublishScheduledDocs(rootConfig) {
|
|
248
|
-
|
|
702
|
+
const cmsClient = new RootCMSClient(rootConfig);
|
|
703
|
+
await cmsClient.publishScheduledDocs();
|
|
704
|
+
await cmsClient.publishScheduledReleases();
|
|
249
705
|
}
|
|
250
706
|
async function runSaveVersions(rootConfig) {
|
|
251
707
|
const service = new VersionsService(rootConfig);
|
|
@@ -285,6 +741,7 @@ function api(server) {
|
|
|
285
741
|
server.use("/cms/api/csv.download", (req, res) => {
|
|
286
742
|
if (req.method !== "POST" || !String(req.get("content-type")).startsWith("application/json")) {
|
|
287
743
|
res.status(400).json({ success: false, error: "BAD_REQUEST" });
|
|
744
|
+
return;
|
|
288
745
|
}
|
|
289
746
|
try {
|
|
290
747
|
const body = req.body || {};
|
|
@@ -318,6 +775,30 @@ function api(server) {
|
|
|
318
775
|
}
|
|
319
776
|
}
|
|
320
777
|
);
|
|
778
|
+
server.use("/cms/api/data.sync", async (req, res) => {
|
|
779
|
+
var _a;
|
|
780
|
+
if (req.method !== "POST" || !String(req.get("content-type")).startsWith("application/json")) {
|
|
781
|
+
res.status(400).json({ success: false, error: "BAD_REQUEST" });
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
if (!((_a = req.user) == null ? void 0 : _a.email)) {
|
|
785
|
+
res.status(401).json({ success: false, error: "UNAUTHORIZED" });
|
|
786
|
+
}
|
|
787
|
+
const reqBody = req.body || {};
|
|
788
|
+
const dataSourceId = reqBody.id;
|
|
789
|
+
if (!dataSourceId) {
|
|
790
|
+
res.status(400).json({ success: false, error: "MISSING_ID" });
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
794
|
+
try {
|
|
795
|
+
await cmsClient.syncDataSource(dataSourceId, { syncedBy: req.user.email });
|
|
796
|
+
res.status(200).json({ success: true, id: dataSourceId });
|
|
797
|
+
} catch (err) {
|
|
798
|
+
console.error(err.stack || err);
|
|
799
|
+
res.status(500).json({ success: false, error: "UNKNOWN" });
|
|
800
|
+
}
|
|
801
|
+
});
|
|
321
802
|
}
|
|
322
803
|
|
|
323
804
|
// core/plugin.ts
|
|
@@ -349,12 +830,18 @@ function cmsPlugin(options) {
|
|
|
349
830
|
const app = getFirebaseApp(firebaseConfig.projectId);
|
|
350
831
|
const auth = getAuth(app);
|
|
351
832
|
function loginRequired(req) {
|
|
833
|
+
if (req.originalUrl === "/cms/api/cron.run") {
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
352
836
|
if (req.originalUrl.startsWith("/cms")) {
|
|
353
837
|
return true;
|
|
354
838
|
}
|
|
355
839
|
if (String(req.query.preview) === "true") {
|
|
356
840
|
return true;
|
|
357
841
|
}
|
|
842
|
+
if (options.isLoginRequired && options.isLoginRequired(req)) {
|
|
843
|
+
return true;
|
|
844
|
+
}
|
|
358
845
|
return false;
|
|
359
846
|
}
|
|
360
847
|
async function verifyUserLogin(req) {
|
|
@@ -362,66 +849,108 @@ function cmsPlugin(options) {
|
|
|
362
849
|
const idToken = (_a = req.body) == null ? void 0 : _a.idToken;
|
|
363
850
|
if (!idToken) {
|
|
364
851
|
console.log("login failed: no id token");
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
if (process.env.NODE_ENV === "development") {
|
|
368
|
-
return Boolean(idToken);
|
|
852
|
+
return { authorized: false, reason: "no token" };
|
|
369
853
|
}
|
|
854
|
+
let user;
|
|
370
855
|
try {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
856
|
+
if (process.env.NODE_ENV === "development") {
|
|
857
|
+
const jwt = jsonwebtoken.decode(idToken);
|
|
858
|
+
if (!jwt.email || !jwt.email_verified) {
|
|
859
|
+
console.log("login failed: email unverified");
|
|
860
|
+
return { authorized: false, reason: "login failed" };
|
|
861
|
+
}
|
|
862
|
+
user = { email: jwt.email };
|
|
863
|
+
} else {
|
|
864
|
+
const jwt = await auth.verifyIdToken(idToken, true);
|
|
865
|
+
if (isExpired(jwt)) {
|
|
866
|
+
console.log("login failed: id token is expired");
|
|
867
|
+
return { authorized: false, reason: "login failed" };
|
|
868
|
+
}
|
|
869
|
+
if (!jwt.email || !jwt.email_verified) {
|
|
870
|
+
console.log("login failed: email unverified");
|
|
871
|
+
return { authorized: false, reason: "login failed" };
|
|
872
|
+
}
|
|
873
|
+
user = { email: jwt.email };
|
|
379
874
|
}
|
|
380
875
|
if (options.isUserAuthorized) {
|
|
381
|
-
const authorized = await options.isUserAuthorized(req,
|
|
876
|
+
const authorized = await options.isUserAuthorized(req, {
|
|
877
|
+
email: user.email
|
|
878
|
+
});
|
|
382
879
|
if (!authorized) {
|
|
383
880
|
console.log("login failed: user is not authorized");
|
|
881
|
+
return { authorized: false, reason: "not authorized" };
|
|
384
882
|
}
|
|
385
|
-
|
|
883
|
+
}
|
|
884
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
885
|
+
const userHasAccess = await cmsClient.userExistsInAcl(user.email);
|
|
886
|
+
if (!userHasAccess) {
|
|
887
|
+
console.log("login failed: user is not in the firestore acl list");
|
|
888
|
+
return { authorized: false, reason: "not authorized" };
|
|
386
889
|
}
|
|
387
890
|
} catch (err) {
|
|
388
891
|
console.error("failed to verify jwt token");
|
|
389
892
|
console.error(err);
|
|
390
|
-
return false;
|
|
893
|
+
return { authorized: false, reason: "unknown error" };
|
|
391
894
|
}
|
|
392
|
-
return true;
|
|
895
|
+
return { authorized: true };
|
|
393
896
|
}
|
|
394
|
-
async function
|
|
897
|
+
async function getCurrentUser(req) {
|
|
395
898
|
const sessionCookie = req.session.getItem(SESSION_COOKIE_AUTH);
|
|
396
899
|
if (!sessionCookie) {
|
|
397
|
-
|
|
398
|
-
return false;
|
|
900
|
+
return null;
|
|
399
901
|
}
|
|
400
902
|
if (process.env.NODE_ENV === "development") {
|
|
401
|
-
|
|
903
|
+
const jwt = jsonwebtoken.decode(sessionCookie);
|
|
904
|
+
if (!(jwt == null ? void 0 : jwt.email) || !(jwt == null ? void 0 : jwt.email_verified)) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
if (options.isUserAuthorized) {
|
|
908
|
+
const authorized = await options.isUserAuthorized(req, {
|
|
909
|
+
email: jwt.email
|
|
910
|
+
});
|
|
911
|
+
if (!authorized) {
|
|
912
|
+
console.log("session failed: not authorized");
|
|
913
|
+
return null;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
917
|
+
const userHasAccess = await cmsClient.userExistsInAcl(jwt.email);
|
|
918
|
+
if (!userHasAccess) {
|
|
919
|
+
console.log("session failed: user is not in the firestore acl list");
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
return { email: jwt.email };
|
|
402
923
|
}
|
|
403
924
|
try {
|
|
404
925
|
const jwt = await auth.verifySessionCookie(sessionCookie, true);
|
|
405
926
|
if (isExpired(jwt)) {
|
|
406
927
|
console.log("session failed: token is expired");
|
|
407
|
-
return
|
|
928
|
+
return null;
|
|
408
929
|
}
|
|
409
930
|
if (!jwt.email || !jwt.email_verified) {
|
|
410
931
|
console.log("session failed: email not verified");
|
|
411
|
-
return
|
|
932
|
+
return null;
|
|
412
933
|
}
|
|
413
934
|
if (options.isUserAuthorized) {
|
|
414
|
-
const authorized = await options.isUserAuthorized(req,
|
|
935
|
+
const authorized = await options.isUserAuthorized(req, {
|
|
936
|
+
email: jwt.email
|
|
937
|
+
});
|
|
415
938
|
if (!authorized) {
|
|
416
939
|
console.log("session failed: not authorized");
|
|
940
|
+
return null;
|
|
417
941
|
}
|
|
418
|
-
return authorized;
|
|
419
942
|
}
|
|
420
|
-
|
|
943
|
+
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
944
|
+
const userHasAccess = await cmsClient.userExistsInAcl(jwt.email);
|
|
945
|
+
if (!userHasAccess) {
|
|
946
|
+
console.log("session failed: user is not in the firestore acl list");
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
return { email: jwt.email };
|
|
421
950
|
} catch (err) {
|
|
422
951
|
console.error("failed to verify jwt token");
|
|
423
952
|
console.error(err);
|
|
424
|
-
return
|
|
953
|
+
return null;
|
|
425
954
|
}
|
|
426
955
|
}
|
|
427
956
|
return {
|
|
@@ -474,9 +1003,9 @@ function cmsPlugin(options) {
|
|
|
474
1003
|
server.use("/cms/login", async (req, res) => {
|
|
475
1004
|
if (req.method === "PUT" && req.headers["content-type"] === "application/json") {
|
|
476
1005
|
try {
|
|
477
|
-
const
|
|
478
|
-
if (!
|
|
479
|
-
res.status(401).json({ success: false, error: "NOT_AUTHORIZED" });
|
|
1006
|
+
const { authorized, reason } = await verifyUserLogin(req);
|
|
1007
|
+
if (!authorized) {
|
|
1008
|
+
res.status(401).json({ success: false, error: "NOT_AUTHORIZED", reason });
|
|
480
1009
|
return;
|
|
481
1010
|
}
|
|
482
1011
|
const expiresIn = 60 * 60 * 24 * 5 * 1e3;
|
|
@@ -518,24 +1047,23 @@ function cmsPlugin(options) {
|
|
|
518
1047
|
res.redirect("/cms/login");
|
|
519
1048
|
});
|
|
520
1049
|
server.use(async (req, res, next) => {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
const userIsLoggedIn = await verifyUserSession(req);
|
|
526
|
-
if (userIsLoggedIn) {
|
|
527
|
-
next();
|
|
528
|
-
return;
|
|
1050
|
+
const user = await getCurrentUser(req);
|
|
1051
|
+
if (user) {
|
|
1052
|
+
req.user = user;
|
|
529
1053
|
}
|
|
530
|
-
if (req
|
|
531
|
-
|
|
1054
|
+
if (!user && loginRequired(req)) {
|
|
1055
|
+
if (req.originalUrl.startsWith("/cms/api")) {
|
|
1056
|
+
res.status(401).json({ success: false, error: "NOT_AUTHORIZED" });
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
console.log("redirecting to login page");
|
|
1060
|
+
const params = new URLSearchParams({
|
|
1061
|
+
continue: req.originalUrl
|
|
1062
|
+
});
|
|
1063
|
+
res.redirect(`/cms/login?${params.toString()}`);
|
|
532
1064
|
return;
|
|
533
1065
|
}
|
|
534
|
-
|
|
535
|
-
const params = new URLSearchParams({
|
|
536
|
-
continue: req.originalUrl
|
|
537
|
-
});
|
|
538
|
-
res.redirect(`/cms/login?${params.toString()}`);
|
|
1066
|
+
next();
|
|
539
1067
|
});
|
|
540
1068
|
api(server);
|
|
541
1069
|
server.use("/cms", async (req, res) => {
|
|
@@ -560,4 +1088,4 @@ function fileExists(filepath) {
|
|
|
560
1088
|
export {
|
|
561
1089
|
cmsPlugin
|
|
562
1090
|
};
|
|
563
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9wbHVnaW4udHMiLCAiLi4vY29yZS9hcGkudHMiLCAiLi4vY29yZS9ydW50aW1lLnRzIiwgIi4uL2NvcmUvY2xpZW50LnRzIiwgIi4uL2NvcmUvdmVyc2lvbnMudHMiLCAiLi4vY29yZS9jcm9uLnRzIiwgIi4uL2NvcmUvY3N2LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge3Byb21pc2VzIGFzIGZzfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gJ25vZGU6dXJsJztcblxuaW1wb3J0IHtcbiAgQ29uZmlndXJlU2VydmVyT3B0aW9ucyxcbiAgTmV4dEZ1bmN0aW9uLFxuICBQbHVnaW4sXG4gIFJlcXVlc3QsXG4gIFJlc3BvbnNlLFxuICBTZXJ2ZXIsXG59IGZyb20gJ0BibGlua2svcm9vdCc7XG5pbXBvcnQgYm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQge1xuICBBcHAsXG4gIGFwcGxpY2F0aW9uRGVmYXVsdCxcbiAgZ2V0QXBwLFxuICBpbml0aWFsaXplQXBwLFxufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9hcHAnO1xuaW1wb3J0IHtnZXRBdXRoLCBEZWNvZGVkSWRUb2tlbn0gZnJvbSAnZmlyZWJhc2UtYWRtaW4vYXV0aCc7XG5pbXBvcnQgc2lydiBmcm9tICdzaXJ2JztcbmltcG9ydCB7YXBpfSBmcm9tICcuL2FwaS5qcyc7XG5cbmNvbnN0IF9fZGlybmFtZSA9IHBhdGguZGlybmFtZShmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybCkpO1xuXG50eXBlIEFwcE1vZHVsZSA9IHR5cGVvZiBpbXBvcnQoJy4vYXBwLmpzJyk7XG5cbi8vIFRoZSBzZXNzaW9uIGtleSBuYW1lIHVzZWQgZm9yIFJvb3QgQ01TIGF1dGhlbnRpY2F0aW9uLlxuY29uc3QgU0VTU0lPTl9DT09LSUVfQVVUSCA9ICdyb290LWNtcy1hdXRoJztcblxuZXhwb3J0IHR5cGUgQ01TVXNlciA9IERlY29kZWRJZFRva2VuO1xuXG5leHBvcnQgdHlwZSBDTVNQbHVnaW5PcHRpb25zID0ge1xuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBwcm9qZWN0LiBEYXRhIHdpbGwgYmUgc3RvcmVkIHVuZGVyIHRoZSBuYW1lc3BhY2VcbiAgICogYFByb2plY3RzLyR7aWR9YCBpbiBmaXJlc3RvcmUuXG4gICAqL1xuICBpZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHByb2plY3QuIFVzZWQgaW4gdGhlIGhlYWRlciBvZiB0aGUgQ01TIHRvIGhlbHAgaWRlbnRpZnlcbiAgICogdGhlIHByb2plY3QuXG4gICAqL1xuICBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGaXJlYmFzZSBjb25maWcgb2JqZWN0LCB3aGljaCBjYW4gYmUgb2J0YWluZWQgaW4gdGhlIEZpcmViYXNlIENvbnNvbGUgYnlcbiAgICogZ29pbmcgdG8gXCJQcm9qZWN0IFNldHRpbmdzXCIuXG4gICAqL1xuICBmaXJlYmFzZUNvbmZpZzoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZztcbiAgICBhcGlLZXk6IHN0cmluZztcbiAgICBhdXRoRG9tYWluOiBzdHJpbmc7XG4gICAgcHJvamVjdElkOiBzdHJpbmc7XG4gICAgc3RvcmFnZUJ1Y2tldDogc3RyaW5nO1xuICAgIG1lc3NhZ2luZ1NlbmRlcklkOiBzdHJpbmc7XG4gICAgYXBwSWQ6IHN0cmluZztcbiAgfTtcblxuICAvKipcbiAgICogU2VjcmV0IHZhbHVlKHMpIHVzZWQgZm9yIHNpZ25pbmcgdGhlIHVzZXIgYXV0aGVudGljYXRpb24gY29va2llLlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIGlzIG5vdyBoYW5kbGVkIGRpcmVjdGx5IGJ5IHJvb3QncyBzZXNzaW9uTWlkZGxld2FyZSB1bmRlclxuICAgKiBgc2VydmVyLnNlc3Npb25Db29raWVTZWNyZXRgIGluIHJvb3QuY29uZmlnLnRzLlxuICAgKi9cbiAgY29va2llU2VjcmV0Pzogc3RyaW5nIHwgc3RyaW5nW107XG5cbiAgLyoqIEZ1bmN0aW9uIGNhbGxlZCB0byBjaGVjayBpZiBhIHVzZXIgc2hvdWxkIGhhdmUgYWNjZXNzIHRvIHRoZSBDTVMuICovXG4gIGlzVXNlckF1dGhvcml6ZWQ/OiAoXG4gICAgcmVxOiBSZXF1ZXN0LFxuICAgIHVzZXI6IENNU1VzZXJcbiAgKSA9PiBib29sZWFuIHwgUHJvbWlzZTxib29sZWFuPjtcblxuICAvKipcbiAgICogVVJMIHRvIEdDSSBzZXJ2aWNlIGZvciB0cmFuc2Zvcm1pbmcgdXBsb2FkZWQgR0NTIGltYWdlcyB0byBhIEdvb2dsZSBBcHBcbiAgICogRW5naW5lIEltYWdlcyBBUEkgc2VydmluZyBVUkwuXG4gICAqXG4gICAqIFNldHRpbmcgdGhpcyB0byBgdHJ1ZWAgdXNlcyB0aGUgZGVmYXVsdCBob3N0ZWQgc2VydmljZSBhdFxuICAgKiBodHRwczovL2djaS5yb290anMuZGV2LlxuICAgKlxuICAgKiBUbyBzZXQgdXAgR0NJOlxuICAgKlxuICAgKiAtIENyZWF0ZSBhIEdDUyBidWNrZXQgd2l0aCBmaW5lLWdyYWluZWQgcGVybWlzc2lvbnNcbiAgICogLSBTaGFyZSBvd25lciBhY2Nlc3MgdG8gdGhlIGJ1Y2tldCB3aXRoIHRoZSBzZXJ2aWNlIGFjY291bnQgcmV0dXJuZWQgaW5cbiAgICogICBodHRwczovL2djaS5yb290anMuZGV2L18vc2VydmljZV9hY2NvdW50XG4gICAqXG4gICAqIFRvIGRpc2FibGUgR0NJLCBsZWF2ZSB0aGlzIHZhbHVlIGVtcHR5IG9yIHNldCB0byBgZmFsc2VgLCB3aGljaCB3aGljaCB3aWxsXG4gICAqIHNlcnZlIGltYWdlcyBkaXJlY3RseSBmcm9tIEdDUyBpbnN0ZWFkLlxuICAgKi9cbiAgZ2NpPzogc3RyaW5nIHwgYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIENNU1BsdWdpbiA9IFBsdWdpbiAmIHtcbiAgbmFtZTogJ3Jvb3QtY21zJztcbiAgZ2V0Q29uZmlnOiAoKSA9PiBDTVNQbHVnaW5PcHRpb25zO1xuICBnZXRGaXJlYmFzZUFwcDogKCkgPT4gQXBwO1xufTtcblxuZnVuY3Rpb24gaXNFeHBpcmVkKGRlY29kZWRJZFRva2VuOiBEZWNvZGVkSWRUb2tlbikge1xuICBjb25zdCB0cyA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgcmV0dXJuIHRzID49IGRlY29kZWRJZFRva2VuLmV4cDtcbn1cblxuZnVuY3Rpb24gZ2V0RmlyZWJhc2VBcHAoZ2NwUHJvamVjdElkOiBzdHJpbmcpOiBBcHAge1xuICBjb25zdCBhcHBOYW1lID0gJ3Jvb3QtY21zJztcbiAgdHJ5IHtcbiAgICByZXR1cm4gZ2V0QXBwKGFwcE5hbWUpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBpZiAoZXJyICYmIGVyci5jb2RlID09PSAnYXBwL25vLWFwcCcpIHtcbiAgICAgIHJldHVybiBpbml0aWFsaXplQXBwKFxuICAgICAgICB7XG4gICAgICAgICAgcHJvamVjdElkOiBnY3BQcm9qZWN0SWQsXG4gICAgICAgICAgY3JlZGVudGlhbDogYXBwbGljYXRpb25EZWZhdWx0KCksXG4gICAgICAgIH0sXG4gICAgICAgIGFwcE5hbWVcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IGVycjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY21zUGx1Z2luKG9wdGlvbnM6IENNU1BsdWdpbk9wdGlvbnMpOiBDTVNQbHVnaW4ge1xuICBjb25zdCBmaXJlYmFzZUNvbmZpZyA9IG9wdGlvbnMuZmlyZWJhc2VDb25maWc7XG4gIGNvbnN0IGFwcCA9IGdldEZpcmViYXNlQXBwKGZpcmViYXNlQ29uZmlnLnByb2plY3RJZCk7XG4gIGNvbnN0IGF1dGggPSBnZXRBdXRoKGFwcCk7XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBsb2dpbiBpcyByZXF1aXJlZCBmb3IgdGhlIHJlcXVlc3QuIEN1cnJlbnRseSByZXR1cm5zIGB0cnVlYCBpZlxuICAgKiB0aGUgVVJMIHBhdGggc3RhcnRzIHdpdGggL2NtcyBvciBpZiA/cHJldmlldz10cnVlIGlzIGluIHRoZSBVUkwuXG4gICAqL1xuICBmdW5jdGlvbiBsb2dpblJlcXVpcmVkKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICAgIGlmIChyZXEub3JpZ2luYWxVcmwuc3RhcnRzV2l0aCgnL2NtcycpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKFN0cmluZyhyZXEucXVlcnkucHJldmlldykgPT09ICd0cnVlJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhIG5ldyBsb2dpbiByZXF1ZXN0IGZvciBhIHVzZXIuIFRoZSByZXF1ZXN0IGJvZHkgc2hvdWxkIGNvbnRhaW5cbiAgICogYW4gaWRUb2tlbiwgd2hpY2ggaXMgdmVyaWZpZWQgb24gcHJvZCB1c2luZyBGaXJlYmFzZSBBZG1pbiBhbmQgSWRlbnRpdHlcbiAgICogVG9vbGtpdC4gSWYgYSBgaXNVc2VyQXV0aG9yaXplZCgpYCBjb25maWcgaXMgc2V0LCB0aGlzIGZ1bmN0aW9uIHdpbGwgYWxzb1xuICAgKiB2ZXJpZnkgdmlhIHRoYXQgZnVuY3Rpb24uIFJldHVybnMgdHJ1ZSBpZiB0aGUgbG9naW4gdmVyaWZpY2F0aW9uIHN1Y2NlZWRzLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gdmVyaWZ5VXNlckxvZ2luKHJlcTogUmVxdWVzdCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGlkVG9rZW4gPSByZXEuYm9keT8uaWRUb2tlbjtcbiAgICBpZiAoIWlkVG9rZW4pIHtcbiAgICAgIGNvbnNvbGUubG9nKCdsb2dpbiBmYWlsZWQ6IG5vIGlkIHRva2VuJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gT24gbG9jYWwgZGV2LCBzaW1wbHkgdmVyaWZ5IHRoYXQgYW4gaWRUb2tlbiBpcyBzZXQuIFRoZSBpZGVudGl0eSB0b29sa2l0XG4gICAgLy8gdGhhdCB2ZXJpZmllcyBpZCB0b2tlbnMgcmVxdWlyZXMgYSBzZXJ2aWNlIGFjY291bnQsIHdoaWNoIHdlIHdhbnQgdG9cbiAgICAvLyBhdm9pZCBoYXZpbmcgdG8gc2V0IHVwIHdoZW4gdXNlcnMgYXJlIGRvaW5nIGxvY2FsIGRldmVsb3BtZW50LlxuICAgIC8vIEF1dGhlbnRpY2F0aW9uIGlzIHN0aWxsIHJlcXVpcmVkIGJ5IHRoZSBmcm9udGVuZCB1c2luZyBGaXJlYmFzZSBBdXRoLFxuICAgIC8vIHRoaXMganVzdCBieXBhc3NlcyB0aGUgaW5pdGlhbCBzZXJ2ZXIgY2hlY2sgYmVmb3JlIHRoZSB1aSBpcyByZW5kZXJlZC5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCcpIHtcbiAgICAgIHJldHVybiBCb29sZWFuKGlkVG9rZW4pO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBqd3QgPSBhd2FpdCBhdXRoLnZlcmlmeUlkVG9rZW4oaWRUb2tlbiwgdHJ1ZSk7XG4gICAgICBpZiAoaXNFeHBpcmVkKGp3dCkpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2xvZ2luIGZhaWxlZDogaWQgdG9rZW4gaXMgZXhwaXJlZCcpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIWp3dC5lbWFpbCB8fCAhand0LmVtYWlsX3ZlcmlmaWVkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdsb2dpbiBmYWlsZWQ6IGVtYWlsIHVudmVyaWZpZWQnKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuaXNVc2VyQXV0aG9yaXplZCkge1xuICAgICAgICBjb25zdCBhdXRob3JpemVkID0gYXdhaXQgb3B0aW9ucy5pc1VzZXJBdXRob3JpemVkKHJlcSwgand0KTtcbiAgICAgICAgaWYgKCFhdXRob3JpemVkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ2xvZ2luIGZhaWxlZDogdXNlciBpcyBub3QgYXV0aG9yaXplZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhdXRob3JpemVkO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignZmFpbGVkIHRvIHZlcmlmeSBqd3QgdG9rZW4nKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gVE9ETyhzdGV2ZW5sZSk6IGRlY2lkZSB3aGV0aGVyIHdlIHdhbnQgdG8gZW5mb3JjZSBgaXNVc2VyQXV0aG9yaXplZCgpYC5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB3aGV0aGVyIHRoZSBjdXJyZW50IHVzZXIgc2Vzc2lvbiBzaG91bGQgYmUgYWxsb3dlZCB0byBhY2Nlc3MgdGhlXG4gICAqIENNUy4gUmV0dXJucyB0cnVlIGlmIGFjY2VzcyBpcyBncmFudGVkLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gdmVyaWZ5VXNlclNlc3Npb24ocmVxOiBSZXF1ZXN0KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc2Vzc2lvbkNvb2tpZSA9IHJlcS5zZXNzaW9uLmdldEl0ZW0oU0VTU0lPTl9DT09LSUVfQVVUSCk7XG4gICAgaWYgKCFzZXNzaW9uQ29va2llKSB7XG4gICAgICBjb25zb2xlLmxvZygnc2Vzc2lvbiBmYWlsZWQ6IG5vIHNlc3Npb24gY29va2llJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gT24gbG9jYWwgZGV2LCBzaW1wbHkgdmVyaWZ5IHRoYXQgYW4gc2Vzc2lvbiBjb29raWUgaXMgc2V0LiBTZWUgbm90ZVxuICAgIC8vIGFib3ZlIGluIGB2ZXJpZnlVc2VyTG9naW4oKWAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgICByZXR1cm4gQm9vbGVhbihzZXNzaW9uQ29va2llKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgand0ID0gYXdhaXQgYXV0aC52ZXJpZnlTZXNzaW9uQ29va2llKHNlc3Npb25Db29raWUsIHRydWUpO1xuICAgICAgaWYgKGlzRXhwaXJlZChqd3QpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogdG9rZW4gaXMgZXhwaXJlZCcpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIWp3dC5lbWFpbCB8fCAhand0LmVtYWlsX3ZlcmlmaWVkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogZW1haWwgbm90IHZlcmlmaWVkJyk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmlzVXNlckF1dGhvcml6ZWQpIHtcbiAgICAgICAgY29uc3QgYXV0aG9yaXplZCA9IGF3YWl0IG9wdGlvbnMuaXNVc2VyQXV0aG9yaXplZChyZXEsIGp3dCk7XG4gICAgICAgIGlmICghYXV0aG9yaXplZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogbm90IGF1dGhvcml6ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXV0aG9yaXplZDtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE8oc3RldmVubGUpOiBkZWNpZGUgd2hldGhlciB3ZSB3YW50IHRvIGVuZm9yY2UgYGlzVXNlckF1dGhvcml6ZWQoKWAuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2ZhaWxlZCB0byB2ZXJpZnkgand0IHRva2VuJyk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAncm9vdC1jbXMnLFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlnIG9wdGlvbnMgcGFzc2VkIHRvIHRoZSBwbHVnaW4uXG4gICAgICovXG4gICAgZ2V0Q29uZmlnOiAoKSA9PiB7XG4gICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgRmlyZWJhc2UgQXBwIGluc3RhbmNlIHVzZWQgYnkgdGhlIHBsdWdpbi5cbiAgICAgKi9cbiAgICBnZXRGaXJlYmFzZUFwcDogKCkgPT4ge1xuICAgICAgcmV0dXJuIGFwcDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSBtYXAgb2Ygc3NyIGZpbGVzIHRvIGluY2x1ZGUgd2hlbiBydW5uaW5nIGByb290IGJ1aWxkYC5cbiAgICAgKi9cbiAgICBzc3JJbnB1dDogKCkgPT4gKHtcbiAgICAgIGNtczogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vYXBwLmpzJyksXG4gICAgfSksXG5cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyBDTVMtc3BlY2lmaWMgbWlkZGxld2FyZSB0byB0aGUgUm9vdC5qcyBzZXJ2ZXIuXG4gICAgICovXG4gICAgY29uZmlndXJlU2VydmVyOiBhc3luYyAoXG4gICAgICBzZXJ2ZXI6IFNlcnZlcixcbiAgICAgIHNlcnZlck9wdGlvbnM6IENvbmZpZ3VyZVNlcnZlck9wdGlvbnNcbiAgICApID0+IHtcbiAgICAgIHNlcnZlci51c2UoYm9keVBhcnNlci5qc29uKCkpO1xuXG4gICAgICBhc3luYyBmdW5jdGlvbiBnZXRSZW5kZXJlcihyZXE6IFJlcXVlc3QpOiBQcm9taXNlPEFwcE1vZHVsZT4ge1xuICAgICAgICBpZiAoc2VydmVyT3B0aW9ucy50eXBlID09PSAnZGV2Jykge1xuICAgICAgICAgIGNvbnN0IGFwcEZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vYXBwLmpzJyk7XG4gICAgICAgICAgY29uc3QgYXBwID0gKGF3YWl0IHJlcS52aXRlU2VydmVyIS5zc3JMb2FkTW9kdWxlKFxuICAgICAgICAgICAgYXBwRmlsZVBhdGhcbiAgICAgICAgICApKSBhcyBBcHBNb2R1bGU7XG4gICAgICAgICAgcmV0dXJuIGFwcDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcEltcG9ydFBhdGggPSBwYXRoLnJlc29sdmUoXG4gICAgICAgICAgcmVxLnJvb3RDb25maWchLnJvb3REaXIsXG4gICAgICAgICAgJ2Rpc3Qvc2VydmVyL2Ntcy5qcydcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCEoYXdhaXQgZmlsZUV4aXN0cyhhcHBJbXBvcnRQYXRoKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnZGlzdC9zZXJ2ZXIvY21zLmpzIG5vdCBmb3VuZC4gcnVuIGByb290IGJ1aWxkYCB0byBjcmVhdGUgaXQuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBwID0gKGF3YWl0IGltcG9ydChhcHBJbXBvcnRQYXRoKSkgYXMgQXBwTW9kdWxlO1xuICAgICAgICByZXR1cm4gYXBwO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGF0aWNEaXIgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAndWknKTtcbiAgICAgIHNlcnZlci51c2UoJy9jbXMvc3RhdGljJywgc2lydihzdGF0aWNEaXIsIHtkZXY6IGZhbHNlfSkpO1xuXG4gICAgICAvLyBMb2dpbiBoYW5kbGVyLlxuICAgICAgc2VydmVyLnVzZSgnL2Ntcy9sb2dpbicsIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlcS5tZXRob2QgPT09ICdQVVQnICYmXG4gICAgICAgICAgcmVxLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddID09PSAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlzQXV0aG9yaXplZCA9IGF3YWl0IHZlcmlmeVVzZXJMb2dpbihyZXEpO1xuICAgICAgICAgICAgaWYgKCFpc0F1dGhvcml6ZWQpIHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ05PVF9BVVRIT1JJWkVEJ30pO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCBzZXNzaW9uIGV4cGlyYXRpb24gdG8gNSBkYXlzLlxuICAgICAgICAgICAgY29uc3QgZXhwaXJlc0luID0gNjAgKiA2MCAqIDI0ICogNSAqIDEwMDA7XG4gICAgICAgICAgICBjb25zdCBpZFRva2VuID0gcmVxLmJvZHkuaWRUb2tlbiE7XG5cbiAgICAgICAgICAgIGxldCBzZXNzaW9uQ29va2llOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCcpIHtcbiAgICAgICAgICAgICAgc2Vzc2lvbkNvb2tpZSA9IGlkVG9rZW47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzZXNzaW9uQ29va2llID0gYXdhaXQgYXV0aC5jcmVhdGVTZXNzaW9uQ29va2llKGlkVG9rZW4sIHtcbiAgICAgICAgICAgICAgICBleHBpcmVzSW4sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLnNlc3Npb24uc2V0SXRlbShTRVNTSU9OX0NPT0tJRV9BVVRILCBzZXNzaW9uQ29va2llKTtcbiAgICAgICAgICAgIHJlcy5zYXZlU2Vzc2lvbigpO1xuICAgICAgICAgICAgcmVzLmpzb24oe3N1Y2Nlc3M6IHRydWV9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIuc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzXG4gICAgICAgICAgICAgIC5zdGF0dXMoNTAwKVxuICAgICAgICAgICAgICAuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnVU5LTk9XTl9TRVJWRVJfRVJST1InfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYXBwID0gYXdhaXQgZ2V0UmVuZGVyZXIocmVxKTtcbiAgICAgICAgICBhcHAucmVuZGVyU2lnbkluKHJlcSwgcmVzLCBvcHRpb25zKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyLnN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJ1VOS05PV04gU0VSVkVSIEVSUk9SJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBMb2dvdXQgaGFuZGxlci5cbiAgICAgIHNlcnZlci51c2UoJy9jbXMvbG9nb3V0JywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICByZXMuc2Vzc2lvbi5yZW1vdmVJdGVtKFNFU1NJT05fQ09PS0lFX0FVVEgpO1xuICAgICAgICByZXMuc2F2ZVNlc3Npb24oKTtcbiAgICAgICAgcmVzLnJlZGlyZWN0KCcvY21zL2xvZ2luJyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gU2FmZWd1YXJkIHRvIHZlcmlmeSB1c2VyIGxvZ2luIGJlZm9yZSByZW5kZXJpbmcgYW55IENNUyBwYWdlLlxuICAgICAgc2VydmVyLnVzZShhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICAgICAgaWYgKCFsb2dpblJlcXVpcmVkKHJlcSkpIHtcbiAgICAgICAgICBuZXh0KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVzZXJJc0xvZ2dlZEluID0gYXdhaXQgdmVyaWZ5VXNlclNlc3Npb24ocmVxKTtcbiAgICAgICAgaWYgKHVzZXJJc0xvZ2dlZEluKSB7XG4gICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxLm9yaWdpbmFsVXJsLnN0YXJ0c1dpdGgoJy9jbXMvYXBpJykpIHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwMSkuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnTk9UX0FVVEhPUklaRUQnfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCdyZWRpcmVjdGluZyB0byBsb2dpbiBwYWdlJyk7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgICAgICAgIGNvbnRpbnVlOiByZXEub3JpZ2luYWxVcmwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXMucmVkaXJlY3QoYC9jbXMvbG9naW4/JHtwYXJhbXMudG9TdHJpbmcoKX1gKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBSZWdpc3RlciBBUEkgaGFuZGxlcnMuXG4gICAgICBhcGkoc2VydmVyKTtcblxuICAgICAgLy8gUmVuZGVyIHRoZSBDTVMgU1BBLlxuICAgICAgc2VydmVyLnVzZSgnL2NtcycsIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCBnZXRSZW5kZXJlcihyZXEpO1xuICAgICAgICAgIGF3YWl0IGFwcC5yZW5kZXJBcHAocmVxLCByZXMsIHtcbiAgICAgICAgICAgIHJvb3RDb25maWc6IHJlcS5yb290Q29uZmlnLFxuICAgICAgICAgICAgY21zQ29uZmlnOiBvcHRpb25zLFxuICAgICAgICAgICAgZmlyZWJhc2VDb25maWc6IG9wdGlvbnMuZmlyZWJhc2VDb25maWcsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIC8vIFRPRE8oc3RldmVubGUpOiByZW5kZXIgYSBjdXN0b20gZXJyb3IgcGFnZS5cbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJ1VOS05PV04gU0VSVkVSIEVSUk9SJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbGVFeGlzdHMoZmlsZXBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gZnNcbiAgICAuYWNjZXNzKGZpbGVwYXRoKVxuICAgIC50aGVuKCgpID0+IHRydWUpXG4gICAgLmNhdGNoKCgpID0+IGZhbHNlKTtcbn1cbiIsICJpbXBvcnQge1NlcnZlciwgUmVxdWVzdCwgUmVzcG9uc2V9IGZyb20gJ0BibGlua2svcm9vdCc7XG5pbXBvcnQge211bHRpcGFydE1pZGRsZXdhcmV9IGZyb20gJ0BibGlua2svcm9vdC9taWRkbGV3YXJlJztcbmltcG9ydCB7cnVuQ3JvbkpvYnN9IGZyb20gJy4vY3Jvbi5qcyc7XG5pbXBvcnQge2FycmF5VG9Dc3YsIGNzdlRvQXJyYXl9IGZyb20gJy4vY3N2LmpzJztcblxuLyoqXG4gKiBSZWdpc3RlcnMgQVBJIG1pZGRsZXdhcmUgaGFuZGxlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcGkoc2VydmVyOiBTZXJ2ZXIpIHtcbiAgLyoqXG4gICAqIFJ1bnMgQ01TIGNyb24gam9icy5cbiAgICovXG4gIHNlcnZlci51c2UoJy9jbXMvYXBpL2Nyb24ucnVuJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBydW5Dcm9uSm9icyhyZXEucm9vdENvbmZpZyEpO1xuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWV9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZX0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgYSBKU09OIG9iamVjdCBjb250YWluaW5nIHtoZWFkZXJzOiBbLi4uXSwgcm93czogWy4uLl19IGFuZCBzZW5kc1xuICAgKiBhbiBIVFRQIHJlc3BvbnNlIHdpdGggYSBjb3JyZXNwb25kaW5nIENTViBmaWxlIGFzIGFuIGF0dGFjaG1lbnQuXG4gICAqXG4gICAqIFNhbXBsZSByZXF1ZXN0OlxuICAgKlxuICAgKiBgYGBqc29uXG4gICAqIHtcbiAgICogICBcImhlYWRlcnNcIjogW1wiZm9vXCJdLFxuICAgKiAgIFwicm93c1wiOiBbXG4gICAqICAgICB7XCJmb29cIjogXCJiYXJcIn0sXG4gICAqICAgICB7XCJmb29cIjogXCJiYXpcIn0sXG4gICAqICAgXVxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgc2VydmVyLnVzZSgnL2Ntcy9hcGkvY3N2LmRvd25sb2FkJywgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGlmIChcbiAgICAgIHJlcS5tZXRob2QgIT09ICdQT1NUJyB8fFxuICAgICAgIVN0cmluZyhyZXEuZ2V0KCdjb250ZW50LXR5cGUnKSkuc3RhcnRzV2l0aCgnYXBwbGljYXRpb24vanNvbicpXG4gICAgKSB7XG4gICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnQkFEX1JFUVVFU1QnfSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJvZHkgPSByZXEuYm9keSB8fCB7fTtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBib2R5LmhlYWRlcnMgfHwgW107XG4gICAgICBjb25zdCByb3dzID0gYm9keS5yb3dzIHx8IFtdO1xuICAgICAgY29uc3QgY3N2ID0gYXJyYXlUb0Nzdih7aGVhZGVycywgcm93c30pO1xuICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvY3N2Jyk7XG4gICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uJywgJ2F0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiZGF0YS5jc3ZcIicpO1xuICAgICAgcmVzLnN0YXR1cygyMDApLmVuZChjc3YpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnIuc3RhY2sgfHwgZXJyKTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdVTktOT1dOJ30pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgYSBDU1YgZmlsZSBhbmQgcmV0dXJucyBhIEpTT04gYXJyYXkgb2Ygb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlXG4gICAqIENTVi5cbiAgICpcbiAgICogU2FtcGxlIHJlc3BvbnNlOlxuICAgKlxuICAgKiBgYGBqc29uXG4gICAqIHtcbiAgICogICBcInN1Y2Nlc3NcIjogdHJ1ZSxcbiAgICogICBcImRhdGFcIjogW1xuICAgKiAgICAge1wiZm9vXCI6IFwiYmFyXCJ9LFxuICAgKiAgICAge1wiZm9vXCI6IFwiYmF6XCJ9LFxuICAgKiAgIF1cbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIHNlcnZlci51c2UoXG4gICAgJy9jbXMvYXBpL2Nzdi5pbXBvcnQnLFxuICAgIG11bHRpcGFydE1pZGRsZXdhcmUoKSxcbiAgICAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBpZiAocmVxLm1ldGhvZCAhPT0gJ1BPU1QnIHx8ICFyZXEuZmlsZXMgfHwgIXJlcS5maWxlcy5maWxlKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdCQURfUkVRVUVTVCd9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBmaWxlID0gcmVxLmZpbGVzLmZpbGU7XG4gICAgICAgIGNvbnN0IGNzdlN0cmluZyA9IGZpbGUuYnVmZmVyLnRvU3RyaW5nKCd1dGY4Jyk7XG4gICAgICAgIGNvbnN0IHJvd3MgPSBjc3ZUb0FycmF5KGNzdlN0cmluZyk7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiByb3dzfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIuc3RhY2sgfHwgZXJyKTtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ1VOS05PV04nfSk7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuIiwgIi8qKiBAZGVwcmVjYXRlZCBVc2UgY2xpZW50LnRzIGluc3RlYWQuICovXG5cbmltcG9ydCB7Um9vdENvbmZpZ30gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCB7XG4gIEZpZWxkVmFsdWUsXG4gIFF1ZXJ5LFxuICBUaW1lc3RhbXAsXG4gIGdldEZpcmVzdG9yZSxcbn0gZnJvbSAnZmlyZWJhc2UtYWRtaW4vZmlyZXN0b3JlJztcbmltcG9ydCB7XG4gIExvYWRUcmFuc2xhdGlvbnNPcHRpb25zLFxuICBMb2NhbGVUcmFuc2xhdGlvbnMsXG4gIFRyYW5zbGF0aW9uLFxuICBUcmFuc2xhdGlvbnNNYXAsXG4gIGdldENtc1BsdWdpbixcbiAgdHJhbnNsYXRpb25zRm9yTG9jYWxlLFxuICB1bm1hcnNoYWxEYXRhLFxufSBmcm9tICcuL2NsaWVudC5qcyc7XG5cbi8qKlxuICogUmV0cmlldmVzIGEgZG9jIGZyb20gUm9vdC5qcyBDTVMuXG4gKiBAZGVwcmVjYXRlZCBVc2UgUm9vdENNU0NsaWVudC5nZXREb2MoKSBpbnN0ZWFkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RG9jPFQ+KFxuICByb290Q29uZmlnOiBSb290Q29uZmlnLFxuICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgc2x1Zzogc3RyaW5nLFxuICBvcHRpb25zOiB7XG4gICAgbW9kZTogJ2RyYWZ0JyB8ICdwdWJsaXNoZWQnO1xuICB9XG4pOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gIGNvbnN0IGNtc1BsdWdpbiA9IGdldENtc1BsdWdpbihyb290Q29uZmlnKTtcbiAgY29uc3QgY21zUGx1Z2luT3B0aW9ucyA9IGNtc1BsdWdpbi5nZXRDb25maWcoKTtcbiAgY29uc3QgcHJvamVjdElkID0gY21zUGx1Z2luT3B0aW9ucy5pZCB8fCAnZGVmYXVsdCc7XG4gIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGU7XG4gIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gIGNvbnN0IGFwcCA9IGNtc1BsdWdpbi5nZXRGaXJlYmFzZUFwcCgpO1xuICBjb25zdCBkYiA9IGdldEZpcmVzdG9yZShhcHApO1xuICAvLyBTbHVncyB3aXRoIHNsYXNoZXMgYXJlIGVuY29kZWQgYXMgYC0tYCBpbiB0aGUgREIuXG4gIHNsdWcgPSBzbHVnLnJlcGxhY2VBbGwoJy8nLCAnLS0nKTtcbiAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7cHJvamVjdElkfS9Db2xsZWN0aW9ucy8ke2NvbGxlY3Rpb25JZH0vJHttb2RlQ29sbGVjdGlvbn0vJHtzbHVnfWA7XG4gIGNvbnN0IGRvY1JlZiA9IGRiLmRvYyhkYlBhdGgpO1xuICBjb25zdCBkb2MgPSBhd2FpdCBkb2NSZWYuZ2V0KCk7XG4gIGlmIChkb2MuZXhpc3RzKSB7XG4gICAgY29uc3QgZGF0YSA9IGRvYy5kYXRhKCk7XG4gICAgcmV0dXJuIHVubWFyc2hhbERhdGEoZGF0YSkgYXMgVDtcbiAgfVxuICBjb25zb2xlLmxvZyhgZG9jIG5vdCBmb3VuZDogJHtkYlBhdGh9YCk7XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIExpc3RzIGRvY3MgZnJvbSBhIFJvb3QuanMgQ01TIGNvbGxlY3Rpb24uXG4gKiBAZGVwcmVjYXRlZCBVc2UgUm9vdENNU0NsaWVudC5saXN0RG9jcygpIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0RG9jczxUPihcbiAgcm9vdENvbmZpZzogUm9vdENvbmZpZyxcbiAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gIG9wdGlvbnM6IHtcbiAgICBtb2RlOiAnZHJhZnQnIHwgJ3B1Ymxpc2hlZCc7XG4gICAgb2Zmc2V0PzogbnVtYmVyO1xuICAgIGxpbWl0PzogbnVtYmVyO1xuICAgIG9yZGVyQnk/OiBzdHJpbmc7XG4gICAgb3JkZXJCeURpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xuICAgIHF1ZXJ5PzogKHF1ZXJ5OiBRdWVyeSkgPT4gUXVlcnk7XG4gIH1cbik6IFByb21pc2U8e2RvY3M6IFRbXX0+IHtcbiAgY29uc3QgY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHJvb3RDb25maWcpO1xuICBjb25zdCBjbXNQbHVnaW5PcHRpb25zID0gY21zUGx1Z2luLmdldENvbmZpZygpO1xuICBjb25zdCBwcm9qZWN0SWQgPSBjbXNQbHVnaW5PcHRpb25zLmlkIHx8ICdkZWZhdWx0JztcbiAgY29uc3QgbW9kZSA9IG9wdGlvbnMubW9kZTtcbiAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgY29uc3QgYXBwID0gY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gIGNvbnN0IGRiID0gZ2V0RmlyZXN0b3JlKGFwcCk7XG4gIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3Byb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259YDtcbiAgbGV0IHF1ZXJ5OiBRdWVyeSA9IGRiLmNvbGxlY3Rpb24oZGJQYXRoKTtcbiAgaWYgKG9wdGlvbnMubGltaXQpIHtcbiAgICBxdWVyeSA9IHF1ZXJ5LmxpbWl0KG9wdGlvbnMubGltaXQpO1xuICB9XG4gIGlmIChvcHRpb25zLm9mZnNldCkge1xuICAgIHF1ZXJ5ID0gcXVlcnkub2Zmc2V0KG9wdGlvbnMub2Zmc2V0KTtcbiAgfVxuICBpZiAob3B0aW9ucy5vcmRlckJ5KSB7XG4gICAgcXVlcnkgPSBxdWVyeS5vcmRlckJ5KG9wdGlvbnMub3JkZXJCeSwgb3B0aW9ucy5vcmRlckJ5RGlyZWN0aW9uKTtcbiAgfVxuICBpZiAob3B0aW9ucy5xdWVyeSkge1xuICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeShxdWVyeSk7XG4gIH1cbiAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHF1ZXJ5LmdldCgpO1xuICBjb25zdCBkb2NzOiBUW10gPSBbXTtcbiAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQpID0+IHtcbiAgICBjb25zdCBkb2MgPSB1bm1hcnNoYWxEYXRhKHJlc3VsdC5kYXRhKCkpIGFzIFQ7XG4gICAgZG9jcy5wdXNoKGRvYyk7XG4gIH0pO1xuICByZXR1cm4ge2RvY3N9O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkb2NzIGluIGEgUm9vdC5qcyBDTVMgY29sbGVjdGlvbi5cbiAqIEBkZXByZWNhdGVkIFVzZSBSb290Q01TQ2xpZW50LmdldERvY3NDb3VudCgpIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBudW1Eb2NzKFxuICByb290Q29uZmlnOiBSb290Q29uZmlnLFxuICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgb3B0aW9uczoge1xuICAgIG1vZGU6ICdkcmFmdCcgfCAncHVibGlzaGVkJztcbiAgICBxdWVyeT86IChxdWVyeTogUXVlcnkpID0+IFF1ZXJ5O1xuICB9XG4pIHtcbiAgY29uc3QgY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHJvb3RDb25maWcpO1xuICBjb25zdCBjbXNQbHVnaW5PcHRpb25zID0gY21zUGx1Z2luLmdldENvbmZpZygpO1xuICBjb25zdCBwcm9qZWN0SWQgPSBjbXNQbHVnaW5PcHRpb25zLmlkIHx8ICdkZWZhdWx0JztcbiAgY29uc3QgbW9kZSA9IG9wdGlvbnMubW9kZTtcbiAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgY29uc3QgYXBwID0gY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gIGNvbnN0IGRiID0gZ2V0RmlyZXN0b3JlKGFwcCk7XG4gIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3Byb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259YDtcbiAgbGV0IHF1ZXJ5OiBRdWVyeSA9IGRiLmNvbGxlY3Rpb24oZGJQYXRoKTtcbiAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICBxdWVyeSA9IG9wdGlvbnMucXVlcnkocXVlcnkpO1xuICB9XG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBxdWVyeS5jb3VudCgpLmdldCgpO1xuICBjb25zdCBjb3VudCA9IHJlc3VsdHMuZGF0YSgpLmNvdW50O1xuICByZXR1cm4gY291bnQ7XG59XG5cbi8qKlxuICogUHVibGlzaGVzIHNjaGVkdWxlZCBkb2NzLlxuICogQGRlcHJlY2F0ZWQgVXNlIFJvb3RDTVNDbGllbnQucHVibGlzaFNjaGVkdWxlZERvY3MoKSBpbnN0ZWFkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVibGlzaFNjaGVkdWxlZERvY3Mocm9vdENvbmZpZzogUm9vdENvbmZpZykge1xuICBjb25zdCBjbXNQbHVnaW4gPSBnZXRDbXNQbHVnaW4ocm9vdENvbmZpZyk7XG4gIGNvbnN0IGNtc1BsdWdpbk9wdGlvbnMgPSBjbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gIGNvbnN0IHByb2plY3RJZCA9IGNtc1BsdWdpbk9wdGlvbnMuaWQgfHwgJ2RlZmF1bHQnO1xuICBjb25zdCBhcHAgPSBjbXNQbHVnaW4uZ2V0RmlyZWJhc2VBcHAoKTtcbiAgY29uc3QgZGIgPSBnZXRGaXJlc3RvcmUoYXBwKTtcblxuICBjb25zdCBwcm9qZWN0Q29sbGVjdGlvbnNQYXRoID0gYFByb2plY3RzLyR7cHJvamVjdElkfS9Db2xsZWN0aW9uc2A7XG4gIGNvbnN0IG5vdyA9IE1hdGguY2VpbChuZXcgRGF0ZSgpLmdldFRpbWUoKSk7XG5cbiAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCBkYi5jb2xsZWN0aW9uR3JvdXAoJ1NjaGVkdWxlZCcpLmdldCgpO1xuICBjb25zdCBkb2NzID0gc25hcHNob3QuZG9jc1xuICAgIC5maWx0ZXIoKGQpID0+IHtcbiAgICAgIC8vIEZpbHRlciBkb2NzIGJ5IHByb2plY3QuXG4gICAgICBpZiAoIWQucmVmLnBhdGguc3RhcnRzV2l0aChwcm9qZWN0Q29sbGVjdGlvbnNQYXRoKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBGaWx0ZXIgZG9jcyB3aGVyZSBzY2hlZHVsZWRBdCBpcyBpbiB0aGUgcGFzdC5cbiAgICAgIC8vIE5PVEUoc3RldmVubGUpOiB0aGUgZmlsdGVyaW5nIGlzIGRvbmUgbWFudWFsbHkgaW5zdGVhZCBvZiB1c2luZyBhIHF1ZXJ5XG4gICAgICAvLyB0byBhdm9pZCBoYXZpbmcgdG8gY3JlYXRlIGFuIGluZGV4IGluIGZpcmVzdG9yZS5cbiAgICAgIGNvbnN0IGRhdGEgPSBkLmRhdGEoKSB8fCB7fTtcbiAgICAgIGNvbnN0IHNjaGVkdWxlZEF0OiBUaW1lc3RhbXAgfCB1bmRlZmluZWQgPSBkYXRhLnN5cz8uc2NoZWR1bGVkQXQ7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBzY2hlZHVsZWRBdCAmJiBzY2hlZHVsZWRBdC50b01pbGxpcyAmJiBzY2hlZHVsZWRBdC50b01pbGxpcygpIDw9IG5vd1xuICAgICAgKTtcbiAgICB9KVxuICAgIC5tYXAoKGQpID0+IHtcbiAgICAgIGNvbnN0IGRiUGF0aCA9IGQucmVmLnBhdGg7XG4gICAgICBjb25zdCBzZWdtZW50cyA9IGRiUGF0aC5zcGxpdCgnLycpO1xuICAgICAgY29uc3Qgc2x1ZyA9IHNlZ21lbnRzLmF0KC0xKTtcbiAgICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBzZWdtZW50cy5hdCgtMyk7XG4gICAgICBjb25zdCBpZCA9IGAke2NvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogZC5kYXRhKCksXG4gICAgICAgIGlkLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBzbHVnLFxuICAgICAgfTtcbiAgICB9KTtcblxuICBpZiAoZG9jcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBFYWNoIHRyYW5zYWN0aW9uIG9yIGJhdGNoIGNhbiB3cml0ZSBhIG1heCBvZiA1MDAgb3BzLlxuICAvLyBodHRwczovL2ZpcmViYXNlLmdvb2dsZS5jb20vZG9jcy9maXJlc3RvcmUvbWFuYWdlLWRhdGEvdHJhbnNhY3Rpb25zXG4gIGxldCBiYXRjaENvdW50ID0gMDtcbiAgY29uc3QgYmF0Y2ggPSBkYi5iYXRjaCgpO1xuICBjb25zdCBwdWJsaXNoZWREb2NzOiBhbnlbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGRvYyBvZiBkb2NzKSB7XG4gICAgY29uc3Qge2lkLCBjb2xsZWN0aW9uLCBzbHVnLCBkYXRhfSA9IGRvYztcbiAgICBjb25zdCBkcmFmdFJlZiA9IGRiLmRvYyhcbiAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vRHJhZnRzLyR7c2x1Z31gXG4gICAgKTtcbiAgICBjb25zdCBzY2hlZHVsZWRSZWYgPSBkYi5kb2MoXG4gICAgICBgJHtwcm9qZWN0Q29sbGVjdGlvbnNQYXRofS8ke2NvbGxlY3Rpb259L1NjaGVkdWxlZC8ke3NsdWd9YFxuICAgICk7XG4gICAgY29uc3QgcHVibGlzaGVkUmVmID0gZGIuZG9jKFxuICAgICAgYCR7cHJvamVjdENvbGxlY3Rpb25zUGF0aH0vJHtjb2xsZWN0aW9ufS9QdWJsaXNoZWQvJHtzbHVnfWBcbiAgICApO1xuICAgIGNvbnN0IHtzY2hlZHVsZWRBdCwgc2NoZWR1bGVkQnksIC4uLnN5c30gPSBkYXRhLnN5cyB8fCB7fTtcblxuICAgIC8vIE9ubHkgdXBkYXRlIGBmaXJzdFB1Ymxpc2hlZGAgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LlxuICAgIGNvbnN0IGZpcnN0UHVibGlzaGVkQXQgPSBzeXMuZmlyc3RQdWJsaXNoZWRBdCA/PyBzY2hlZHVsZWRBdDtcbiAgICBjb25zdCBmaXJzdFB1Ymxpc2hlZEJ5ID0gc3lzLmZpcnN0UHVibGlzaGVkQnkgPz8gKHNjaGVkdWxlZEJ5IHx8ICcnKTtcblxuICAgIC8vIFNhdmUgcHVibGlzaGVkIGRvYy5cbiAgICBiYXRjaC5zZXQocHVibGlzaGVkUmVmLCB7XG4gICAgICBpZCxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBzbHVnLFxuICAgICAgZmllbGRzOiBkYXRhLmZpZWxkcyB8fCB7fSxcbiAgICAgIHN5czoge1xuICAgICAgICAuLi5zeXMsXG4gICAgICAgIGZpcnN0UHVibGlzaGVkQXQ6IGZpcnN0UHVibGlzaGVkQXQsXG4gICAgICAgIGZpcnN0UHVibGlzaGVkQnk6IGZpcnN0UHVibGlzaGVkQnksXG4gICAgICAgIHB1Ymxpc2hlZEF0OiBGaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpLFxuICAgICAgICBwdWJsaXNoZWRCeTogc2NoZWR1bGVkQnkgfHwgJycsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgIC8vIFJlbW92ZSBwdWJsaXNoZWQgZG9jLlxuICAgIGJhdGNoLmRlbGV0ZShzY2hlZHVsZWRSZWYpO1xuICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgZHJhZnQgZG9jIHRvIHJlbW92ZSBgc2NoZWR1bGVkQXRgIGFuZCBgc2NoZWR1bGVkQnlgIGZpZWxkc1xuICAgIC8vIGFuZCB1cGRhdGUgdGhlIGBwdWJsaXNoZWRBdGAgYW5kIGBwdWJsaXNoZWRCeWAgZmllbGRzLlxuICAgIGJhdGNoLnVwZGF0ZShkcmFmdFJlZiwge1xuICAgICAgJ3N5cy5zY2hlZHVsZWRBdCc6IEZpZWxkVmFsdWUuZGVsZXRlKCksXG4gICAgICAnc3lzLnNjaGVkdWxlZEJ5JzogRmllbGRWYWx1ZS5kZWxldGUoKSxcbiAgICAgICdzeXMuZmlyc3RQdWJsaXNoZWRBdCc6IGZpcnN0UHVibGlzaGVkQXQsXG4gICAgICAnc3lzLmZpcnN0UHVibGlzaGVkQnknOiBmaXJzdFB1Ymxpc2hlZEJ5LFxuICAgICAgJ3N5cy5wdWJsaXNoZWRBdCc6IEZpZWxkVmFsdWUuc2VydmVyVGltZXN0YW1wKCksXG4gICAgICAnc3lzLnB1Ymxpc2hlZEJ5Jzogc2NoZWR1bGVkQnkgfHwgJycsXG4gICAgfSk7XG4gICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgcHVibGlzaGVkRG9jcy5wdXNoKGRvYyk7XG5cbiAgICBpZiAoYmF0Y2hDb3VudCA+PSA0OTgpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuICBjb25zb2xlLmxvZyhgcHVibGlzaGVkICR7cHVibGlzaGVkRG9jcy5sZW5ndGh9IGRvY3MhYCk7XG4gIHJldHVybiBwdWJsaXNoZWREb2NzO1xufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkIFVzZSBgUm9vdENNU0NsaWVudC5sb2FkVHJhbnNsYXRpb25zKClgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFRyYW5zbGF0aW9ucyhcbiAgcm9vdENvbmZpZzogUm9vdENvbmZpZyxcbiAgb3B0aW9ucz86IExvYWRUcmFuc2xhdGlvbnNPcHRpb25zXG4pOiBQcm9taXNlPFRyYW5zbGF0aW9uc01hcD4ge1xuICBjb25zdCBjbXNQbHVnaW4gPSBnZXRDbXNQbHVnaW4ocm9vdENvbmZpZyk7XG4gIGNvbnN0IGNtc1BsdWdpbk9wdGlvbnMgPSBjbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gIGNvbnN0IHByb2plY3RJZCA9IGNtc1BsdWdpbk9wdGlvbnMuaWQgfHwgJ2RlZmF1bHQnO1xuICBjb25zdCBhcHAgPSBjbXNQbHVnaW4uZ2V0RmlyZWJhc2VBcHAoKTtcbiAgY29uc3QgZGIgPSBnZXRGaXJlc3RvcmUoYXBwKTtcblxuICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHtwcm9qZWN0SWR9L1RyYW5zbGF0aW9uc2A7XG4gIGxldCBxdWVyeTogUXVlcnkgPSBkYi5jb2xsZWN0aW9uKGRiUGF0aCk7XG4gIGlmIChvcHRpb25zPy50YWdzKSB7XG4gICAgcXVlcnkgPSBxdWVyeS53aGVyZSgndGFncycsICdhcnJheS1jb250YWlucy1hbnknLCBvcHRpb25zLnRhZ3MpO1xuICB9XG5cbiAgY29uc3QgcXVlcnlTbmFwc2hvdCA9IGF3YWl0IHF1ZXJ5LmdldCgpO1xuICBjb25zdCB0cmFuc2xhdGlvbnNNYXA6IFRyYW5zbGF0aW9uc01hcCA9IHt9O1xuICBxdWVyeVNuYXBzaG90LmZvckVhY2goKGRvYykgPT4ge1xuICAgIGNvbnN0IGhhc2ggPSBkb2MuaWQ7XG4gICAgdHJhbnNsYXRpb25zTWFwW2hhc2hdID0gZG9jLmRhdGEoKSBhcyBUcmFuc2xhdGlvbjtcbiAgfSk7XG4gIHJldHVybiB0cmFuc2xhdGlvbnNNYXA7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNlIGBSb290Q01TQ2xpZW50LmxvYWRUcmFuc2xhdGlvbnNGb3JMb2NhbGUoKWAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkVHJhbnNsYXRpb25zRm9yTG9jYWxlKFxuICByb290Q29uZmlnOiBSb290Q29uZmlnLFxuICBsb2NhbGU6IHN0cmluZyxcbiAgb3B0aW9ucz86IExvYWRUcmFuc2xhdGlvbnNPcHRpb25zXG4pOiBQcm9taXNlPExvY2FsZVRyYW5zbGF0aW9ucz4ge1xuICBjb25zdCB0cmFuc2xhdGlvbnNNYXAgPSBhd2FpdCBsb2FkVHJhbnNsYXRpb25zKHJvb3RDb25maWcsIG9wdGlvbnMpO1xuICByZXR1cm4gdHJhbnNsYXRpb25zRm9yTG9jYWxlKHRyYW5zbGF0aW9uc01hcCwgbG9jYWxlKTtcbn1cbiIsICJpbXBvcnQgY3J5cHRvIGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7UGx1Z2luLCBSb290Q29uZmlnfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IHtBcHB9IGZyb20gJ2ZpcmViYXNlLWFkbWluL2FwcCc7XG5pbXBvcnQge1xuICBGaWVsZFZhbHVlLFxuICBGaXJlc3RvcmUsXG4gIFF1ZXJ5LFxuICBUaW1lc3RhbXAsXG4gIGdldEZpcmVzdG9yZSxcbn0gZnJvbSAnZmlyZWJhc2UtYWRtaW4vZmlyZXN0b3JlJztcbmltcG9ydCB7Q01TUGx1Z2lufSBmcm9tICcuL3BsdWdpbi5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG9jPEZpZWxkcyA9IGFueT4ge1xuICAvKiogVGhlIGlkIG9mIHRoZSBkb2MsIGUuZy4gXCJQYWdlcy9mb28tYmFyXCIuICovXG4gIGlkOiBzdHJpbmc7XG4gIC8qKiBUaGUgY29sbGVjdGlvbiBpZCBvZiB0aGUgZG9jLCBlLmcuIFwiUGFnZXNcIi4gKi9cbiAgY29sbGVjdGlvbklkOiBzdHJpbmc7XG4gIC8qKiBUaGUgc2x1ZyBvZiB0aGUgZG9jLCBlLmcuIFwiZm9vLWJhclwiLiAqL1xuICBzbHVnOiBzdHJpbmc7XG4gIHN5czoge1xuICAgIGNyZWF0ZWRBdDogbnVtYmVyO1xuICAgIGNyZWF0ZWRCeTogc3RyaW5nO1xuICAgIG1vZGlmaWVkQXQ6IG51bWJlcjtcbiAgICBtb2RpZmllZEJ5OiBzdHJpbmc7XG4gICAgZmlyc3RQdWJsaXNoZWRBdD86IG51bWJlcjtcbiAgICBmaXJzdFB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xuICAgIHB1Ymxpc2hlZEF0PzogbnVtYmVyO1xuICAgIHB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xuICAgIGxvY2FsZXM/OiBzdHJpbmdbXTtcbiAgfTtcbiAgZmllbGRzOiBGaWVsZHM7XG59XG5cbmV4cG9ydCB0eXBlIERvY01vZGUgPSAnZHJhZnQnIHwgJ3B1Ymxpc2hlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2V0RG9jT3B0aW9ucyB7XG4gIC8qKiBNb2RlLCBlaXRoZXIgXCJkcmFmdFwiIG9yIFwicHVibGlzaGVkXCIuICovXG4gIG1vZGU6IERvY01vZGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2V0RG9jT3B0aW9ucyB7XG4gIC8qKiBNb2RlLCBlaXRoZXIgXCJkcmFmdFwiIG9yIFwicHVibGlzaGVkXCIuICovXG4gIG1vZGU6IERvY01vZGU7XG4gIC8qKlxuICAgKiBFbWFpbCBvZiB1c2VyIG1vZGlmeWluZyB0aGUgZG9jLiBJZiBibGFuaywgZGVmYXVsdHMgdG8gYHJvb3QtY21zLWNsaWVudGAuXG4gICAqL1xuICBtb2RpZmllZEJ5Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3REb2NzT3B0aW9ucyB7XG4gIG1vZGU6IERvY01vZGU7XG4gIG9mZnNldD86IG51bWJlcjtcbiAgbGltaXQ/OiBudW1iZXI7XG4gIG9yZGVyQnk/OiBzdHJpbmc7XG4gIG9yZGVyQnlEaXJlY3Rpb24/OiAnYXNjJyB8ICdkZXNjJztcbiAgcXVlcnk/OiAocXVlcnk6IFF1ZXJ5KSA9PiBRdWVyeTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZXRDb3VudE9wdGlvbnMge1xuICBtb2RlOiBEb2NNb2RlO1xuICBxdWVyeT86IChxdWVyeTogUXVlcnkpID0+IFF1ZXJ5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uIHtcbiAgW2xvY2FsZTogc3RyaW5nXTogc3RyaW5nO1xuICBzb3VyY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbnNNYXAge1xuICBbaGFzaDogc3RyaW5nXTogVHJhbnNsYXRpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9jYWxlVHJhbnNsYXRpb25zIHtcbiAgW3NvdXJjZTogc3RyaW5nXTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvYWRUcmFuc2xhdGlvbnNPcHRpb25zIHtcbiAgdGFncz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgUm9vdENNU0NsaWVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdENvbmZpZzogUm9vdENvbmZpZztcbiAgcHJpdmF0ZSByZWFkb25seSBjbXNQbHVnaW46IENNU1BsdWdpbjtcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9qZWN0SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IEFwcDtcbiAgcHJpdmF0ZSByZWFkb25seSBkYjogRmlyZXN0b3JlO1xuXG4gIGNvbnN0cnVjdG9yKHJvb3RDb25maWc6IFJvb3RDb25maWcpIHtcbiAgICB0aGlzLnJvb3RDb25maWcgPSByb290Q29uZmlnO1xuICAgIHRoaXMuY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHJvb3RDb25maWcpO1xuXG4gICAgY29uc3QgY21zUGx1Z2luT3B0aW9ucyA9IHRoaXMuY21zUGx1Z2luLmdldENvbmZpZygpO1xuICAgIHRoaXMucHJvamVjdElkID0gY21zUGx1Z2luT3B0aW9ucy5pZCB8fCAnZGVmYXVsdCc7XG4gICAgdGhpcy5hcHAgPSB0aGlzLmNtc1BsdWdpbi5nZXRGaXJlYmFzZUFwcCgpO1xuICAgIHRoaXMuZGIgPSBnZXRGaXJlc3RvcmUodGhpcy5hcHApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBkb2MgZGF0YSBmcm9tIFJvb3QuanMgQ01TLlxuICAgKi9cbiAgYXN5bmMgZ2V0RG9jPEZpZWxkcyA9IGFueT4oXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgc2x1Zzogc3RyaW5nLFxuICAgIG9wdGlvbnM6IEdldERvY09wdGlvbnNcbiAgKTogUHJvbWlzZTxEb2M8RmllbGRzPiB8IG51bGw+IHtcbiAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgdGhpcy5nZXRSYXdEb2MoY29sbGVjdGlvbklkLCBzbHVnLCBvcHRpb25zKTtcbiAgICBpZiAocmF3RGF0YSkge1xuICAgICAgcmV0dXJuIHVubWFyc2hhbERhdGEocmF3RGF0YSkgYXMgRG9jPEZpZWxkcz47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyByYXcgZG9jIGRhdGEgYXMgc3RvcmVkIGluIHRoZSBkYXRhYmFzZS4gT25seSB1c2UgdGhpcyBpZiB5b3Uga25vd1xuICAgKiB3aGF0IHlvdSBhcmUgZG9pbmcuXG4gICAqL1xuICBhc3luYyBnZXRSYXdEb2MoXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgc2x1Zzogc3RyaW5nLFxuICAgIG9wdGlvbnM6IEdldERvY09wdGlvbnNcbiAgKTogUHJvbWlzZTxhbnkgfCBudWxsPiB7XG4gICAgY29uc3QgbW9kZSA9IG9wdGlvbnMubW9kZTtcbiAgICBjb25zdCBtb2RlQ29sbGVjdGlvbiA9IG1vZGUgPT09ICdkcmFmdCcgPyAnRHJhZnRzJyA6ICdQdWJsaXNoZWQnO1xuICAgIC8vIFNsdWdzIHdpdGggc2xhc2hlcyBhcmUgZW5jb2RlZCBhcyBgLS1gIGluIHRoZSBEQi5cbiAgICBzbHVnID0gc2x1Zy5yZXBsYWNlQWxsKCcvJywgJy0tJyk7XG4gICAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zLyR7Y29sbGVjdGlvbklkfS8ke21vZGVDb2xsZWN0aW9ufS8ke3NsdWd9YDtcbiAgICBjb25zdCBkb2NSZWYgPSB0aGlzLmRiLmRvYyhkYlBhdGgpO1xuICAgIGNvbnN0IGRvYyA9IGF3YWl0IGRvY1JlZi5nZXQoKTtcbiAgICBpZiAoZG9jLmV4aXN0cykge1xuICAgICAgcmV0dXJuIGRvYy5kYXRhKCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYXN5bmMgc2V0UmF3RG9jKFxuICAgIGNvbGxlY3Rpb25JZDogc3RyaW5nLFxuICAgIHNsdWc6IHN0cmluZyxcbiAgICBkYXRhOiBhbnksXG4gICAgb3B0aW9uczogU2V0RG9jT3B0aW9uc1xuICApIHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zLyR7Y29sbGVjdGlvbklkfS8ke21vZGVDb2xsZWN0aW9ufS8ke3NsdWd9YDtcbiAgICBjb25zdCBkb2NSZWYgPSB0aGlzLmRiLmRvYyhkYlBhdGgpO1xuICAgIGF3YWl0IGRvY1JlZi5zZXQoZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgZG9jcyBmcm9tIGEgUm9vdC5qcyBDTVMgY29sbGVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGxpc3REb2NzPFQ+KFxuICAgIGNvbGxlY3Rpb25JZDogc3RyaW5nLFxuICAgIG9wdGlvbnM6IExpc3REb2NzT3B0aW9uc1xuICApOiBQcm9taXNlPHtkb2NzOiBUW119PiB7XG4gICAgY29uc3QgbW9kZSA9IG9wdGlvbnMubW9kZTtcbiAgICBjb25zdCBtb2RlQ29sbGVjdGlvbiA9IG1vZGUgPT09ICdkcmFmdCcgPyAnRHJhZnRzJyA6ICdQdWJsaXNoZWQnO1xuICAgIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9Db2xsZWN0aW9ucy8ke2NvbGxlY3Rpb25JZH0vJHttb2RlQ29sbGVjdGlvbn1gO1xuICAgIGxldCBxdWVyeTogUXVlcnkgPSB0aGlzLmRiLmNvbGxlY3Rpb24oZGJQYXRoKTtcbiAgICBpZiAob3B0aW9ucy5saW1pdCkge1xuICAgICAgcXVlcnkgPSBxdWVyeS5saW1pdChvcHRpb25zLmxpbWl0KTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMub2Zmc2V0KSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5Lm9mZnNldChvcHRpb25zLm9mZnNldCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLm9yZGVyQnkpIHtcbiAgICAgIHF1ZXJ5ID0gcXVlcnkub3JkZXJCeShvcHRpb25zLm9yZGVyQnksIG9wdGlvbnMub3JkZXJCeURpcmVjdGlvbik7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBxdWVyeSA9IG9wdGlvbnMucXVlcnkocXVlcnkpO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgcXVlcnkuZ2V0KCk7XG4gICAgY29uc3QgZG9jczogVFtdID0gW107XG4gICAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQpID0+IHtcbiAgICAgIGNvbnN0IGRvYyA9IHVubWFyc2hhbERhdGEocmVzdWx0LmRhdGEoKSkgYXMgVDtcbiAgICAgIGRvY3MucHVzaChkb2MpO1xuICAgIH0pO1xuICAgIHJldHVybiB7ZG9jc307XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRvY3MgaW4gYSBSb290LmpzIENNUyBjb2xsZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZ2V0RG9jc0NvdW50KGNvbGxlY3Rpb25JZDogc3RyaW5nLCBvcHRpb25zOiBHZXRDb3VudE9wdGlvbnMpIHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zLyR7Y29sbGVjdGlvbklkfS8ke21vZGVDb2xsZWN0aW9ufWA7XG4gICAgbGV0IHF1ZXJ5OiBRdWVyeSA9IHRoaXMuZGIuY29sbGVjdGlvbihkYlBhdGgpO1xuICAgIGlmIChvcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBxdWVyeSA9IG9wdGlvbnMucXVlcnkocXVlcnkpO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgcXVlcnkuY291bnQoKS5nZXQoKTtcbiAgICBjb25zdCBjb3VudCA9IHJlc3VsdHMuZGF0YSgpLmNvdW50O1xuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgc2NoZWR1bGVkIGRvY3MuXG4gICAqL1xuICBhc3luYyBwdWJsaXNoU2NoZWR1bGVkRG9jcygpIHtcbiAgICBjb25zdCBwcm9qZWN0Q29sbGVjdGlvbnNQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zYDtcbiAgICBjb25zdCBub3cgPSBNYXRoLmNlaWwobmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuXG4gICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCB0aGlzLmRiLmNvbGxlY3Rpb25Hcm91cCgnU2NoZWR1bGVkJykuZ2V0KCk7XG4gICAgY29uc3QgZG9jcyA9IHNuYXBzaG90LmRvY3NcbiAgICAgIC5maWx0ZXIoKGQpID0+IHtcbiAgICAgICAgLy8gRmlsdGVyIGRvY3MgYnkgcHJvamVjdC5cbiAgICAgICAgaWYgKCFkLnJlZi5wYXRoLnN0YXJ0c1dpdGgocHJvamVjdENvbGxlY3Rpb25zUGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmlsdGVyIGRvY3Mgd2hlcmUgc2NoZWR1bGVkQXQgaXMgaW4gdGhlIHBhc3QuXG4gICAgICAgIC8vIE5PVEUoc3RldmVubGUpOiB0aGUgZmlsdGVyaW5nIGlzIGRvbmUgbWFudWFsbHkgaW5zdGVhZCBvZiB1c2luZyBhIHF1ZXJ5XG4gICAgICAgIC8vIHRvIGF2b2lkIGhhdmluZyB0byBjcmVhdGUgYW4gaW5kZXggaW4gZmlyZXN0b3JlLlxuICAgICAgICBjb25zdCBkYXRhID0gZC5kYXRhKCkgfHwge307XG4gICAgICAgIGNvbnN0IHNjaGVkdWxlZEF0OiBUaW1lc3RhbXAgfCB1bmRlZmluZWQgPSBkYXRhLnN5cz8uc2NoZWR1bGVkQXQ7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgc2NoZWR1bGVkQXQgJiYgc2NoZWR1bGVkQXQudG9NaWxsaXMgJiYgc2NoZWR1bGVkQXQudG9NaWxsaXMoKSA8PSBub3dcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAubWFwKChkKSA9PiB7XG4gICAgICAgIGNvbnN0IGRiUGF0aCA9IGQucmVmLnBhdGg7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gZGJQYXRoLnNwbGl0KCcvJyk7XG4gICAgICAgIGNvbnN0IHNsdWcgPSBzZWdtZW50cy5hdCgtMSk7XG4gICAgICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBzZWdtZW50cy5hdCgtMyk7XG4gICAgICAgIGNvbnN0IGlkID0gYCR7Y29sbGVjdGlvbn0vJHtzbHVnfWA7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGF0YTogZC5kYXRhKCksXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgICBzbHVnLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICBpZiAoZG9jcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdubyBkb2NzIHRvIHNjaGVkdWxlJyk7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gRWFjaCB0cmFuc2FjdGlvbiBvciBiYXRjaCBjYW4gd3JpdGUgYSBtYXggb2YgNTAwIG9wcy5cbiAgICAvLyBodHRwczovL2ZpcmViYXNlLmdvb2dsZS5jb20vZG9jcy9maXJlc3RvcmUvbWFuYWdlLWRhdGEvdHJhbnNhY3Rpb25zXG4gICAgbGV0IGJhdGNoQ291bnQgPSAwO1xuICAgIGNvbnN0IGJhdGNoID0gdGhpcy5kYi5iYXRjaCgpO1xuICAgIGNvbnN0IHB1Ymxpc2hlZERvY3M6IGFueVtdID0gW107XG4gICAgZm9yIChjb25zdCBkb2Mgb2YgZG9jcykge1xuICAgICAgY29uc3Qge2lkLCBjb2xsZWN0aW9uLCBzbHVnLCBkYXRhfSA9IGRvYztcbiAgICAgIGNvbnN0IGRyYWZ0UmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vRHJhZnRzLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgY29uc3Qgc2NoZWR1bGVkUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vU2NoZWR1bGVkLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgY29uc3QgcHVibGlzaGVkUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vUHVibGlzaGVkLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgY29uc3Qge3NjaGVkdWxlZEF0LCBzY2hlZHVsZWRCeSwgLi4uc3lzfSA9IGRhdGEuc3lzIHx8IHt9O1xuXG4gICAgICAvLyBPbmx5IHVwZGF0ZSBgZmlyc3RQdWJsaXNoZWRgIGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC5cbiAgICAgIGNvbnN0IGZpcnN0UHVibGlzaGVkQXQgPSBzeXMuZmlyc3RQdWJsaXNoZWRBdCA/PyBzY2hlZHVsZWRBdDtcbiAgICAgIGNvbnN0IGZpcnN0UHVibGlzaGVkQnkgPSBzeXMuZmlyc3RQdWJsaXNoZWRCeSA/PyAoc2NoZWR1bGVkQnkgfHwgJycpO1xuXG4gICAgICAvLyBTYXZlIHB1Ymxpc2hlZCBkb2MuXG4gICAgICBiYXRjaC5zZXQocHVibGlzaGVkUmVmLCB7XG4gICAgICAgIGlkLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBzbHVnLFxuICAgICAgICBmaWVsZHM6IGRhdGEuZmllbGRzIHx8IHt9LFxuICAgICAgICBzeXM6IHtcbiAgICAgICAgICAuLi5zeXMsXG4gICAgICAgICAgZmlyc3RQdWJsaXNoZWRBdDogZmlyc3RQdWJsaXNoZWRBdCxcbiAgICAgICAgICBmaXJzdFB1Ymxpc2hlZEJ5OiBmaXJzdFB1Ymxpc2hlZEJ5LFxuICAgICAgICAgIHB1Ymxpc2hlZEF0OiBGaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpLFxuICAgICAgICAgIHB1Ymxpc2hlZEJ5OiBzY2hlZHVsZWRCeSB8fCAnJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgICAvLyBSZW1vdmUgcHVibGlzaGVkIGRvYy5cbiAgICAgIGJhdGNoLmRlbGV0ZShzY2hlZHVsZWRSZWYpO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgICAvLyBVcGRhdGUgdGhlIGRyYWZ0IGRvYyB0byByZW1vdmUgYHNjaGVkdWxlZEF0YCBhbmQgYHNjaGVkdWxlZEJ5YCBmaWVsZHNcbiAgICAgIC8vIGFuZCB1cGRhdGUgdGhlIGBwdWJsaXNoZWRBdGAgYW5kIGBwdWJsaXNoZWRCeWAgZmllbGRzLlxuICAgICAgYmF0Y2gudXBkYXRlKGRyYWZ0UmVmLCB7XG4gICAgICAgICdzeXMuc2NoZWR1bGVkQXQnOiBGaWVsZFZhbHVlLmRlbGV0ZSgpLFxuICAgICAgICAnc3lzLnNjaGVkdWxlZEJ5JzogRmllbGRWYWx1ZS5kZWxldGUoKSxcbiAgICAgICAgJ3N5cy5maXJzdFB1Ymxpc2hlZEF0JzogZmlyc3RQdWJsaXNoZWRBdCxcbiAgICAgICAgJ3N5cy5maXJzdFB1Ymxpc2hlZEJ5JzogZmlyc3RQdWJsaXNoZWRCeSxcbiAgICAgICAgJ3N5cy5wdWJsaXNoZWRBdCc6IEZpZWxkVmFsdWUuc2VydmVyVGltZXN0YW1wKCksXG4gICAgICAgICdzeXMucHVibGlzaGVkQnknOiBzY2hlZHVsZWRCeSB8fCAnJyxcbiAgICAgIH0pO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgICBwdWJsaXNoZWREb2NzLnB1c2goZG9jKTtcblxuICAgICAgaWYgKGJhdGNoQ291bnQgPj0gNDk4KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuICAgIGNvbnNvbGUubG9nKGBwdWJsaXNoZWQgJHtwdWJsaXNoZWREb2NzLmxlbmd0aH0gZG9jcyFgKTtcbiAgICByZXR1cm4gcHVibGlzaGVkRG9jcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0cmFuc2xhdGlvbnMgc2F2ZWQgaW4gdGhlIHRyYW5zbGF0aW9ucyBjb2xsZWN0aW9uLCBvcHRpb25hbGx5XG4gICAqIGZpbHRlcmVkIGJ5IHRhZy5cbiAgICpcbiAgICogUmV0dXJucyBhIG1hcCBsaWtlOlxuICAgKiBgYGBcbiAgICoge1xuICAgKiAgIFwiPGhhc2g+XCI6IHtcInNvdXJjZVwiOiBcIkhlbGxvXCIsIFwiZXNcIjogXCJIb2xhXCIsIFwiZnJcIjogXCJCb25qb3VyXCJ9LFxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgbG9hZFRyYW5zbGF0aW9ucyhcbiAgICBvcHRpb25zPzogTG9hZFRyYW5zbGF0aW9uc09wdGlvbnNcbiAgKTogUHJvbWlzZTxUcmFuc2xhdGlvbnNNYXA+IHtcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vVHJhbnNsYXRpb25zYDtcbiAgICBsZXQgcXVlcnk6IFF1ZXJ5ID0gdGhpcy5kYi5jb2xsZWN0aW9uKGRiUGF0aCk7XG4gICAgaWYgKG9wdGlvbnM/LnRhZ3MpIHtcbiAgICAgIHF1ZXJ5ID0gcXVlcnkud2hlcmUoJ3RhZ3MnLCAnYXJyYXktY29udGFpbnMtYW55Jywgb3B0aW9ucy50YWdzKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeVNuYXBzaG90ID0gYXdhaXQgcXVlcnkuZ2V0KCk7XG4gICAgY29uc3QgdHJhbnNsYXRpb25zTWFwOiBUcmFuc2xhdGlvbnNNYXAgPSB7fTtcbiAgICBxdWVyeVNuYXBzaG90LmZvckVhY2goKGRvYykgPT4ge1xuICAgICAgY29uc3QgaGFzaCA9IGRvYy5pZDtcbiAgICAgIHRyYW5zbGF0aW9uc01hcFtoYXNoXSA9IGRvYy5kYXRhKCkgYXMgVHJhbnNsYXRpb247XG4gICAgfSk7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uc01hcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlcyBhIG1hcCBvZiB0cmFuc2xhdGlvbnMsIGUuZy46XG4gICAqIGBgYFxuICAgKiBhd2FpdCBjbGllbnQuc2F2ZVRyYW5zbGF0aW9ucyh7XG4gICAqICAgXCJIZWxsb1wiOiB7XCJlc1wiOiBcIkhvbGFcIiwgXCJmclwiOiBcIkJvbmpvdXJcIn0sXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIHNhdmVUcmFuc2xhdGlvbnMoXG4gICAgdHJhbnNsYXRpb25zOiB7XG4gICAgICBbc291cmNlOiBzdHJpbmddOiB7W2xvY2FsZTogc3RyaW5nXTogc3RyaW5nfTtcbiAgICB9LFxuICAgIHRhZ3M/OiBzdHJpbmdbXVxuICApIHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L1RyYW5zbGF0aW9uc2A7XG4gICAgY29uc3QgYmF0Y2ggPSB0aGlzLmRiLmJhdGNoKCk7XG4gICAgbGV0IGJhdGNoQ291bnQgPSAwO1xuICAgIE9iamVjdC5lbnRyaWVzKHRyYW5zbGF0aW9ucykuZm9yRWFjaCgoW3NvdXJjZSwgc291cmNlVHJhbnNsYXRpb25zXSkgPT4ge1xuICAgICAgY29uc3QgaGFzaCA9IHRoaXMuZ2V0VHJhbnNsYXRpb25LZXkoc291cmNlKTtcbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uUmVmID0gdGhpcy5kYi5kb2MoYCR7dHJhbnNsYXRpb25zUGF0aH0vJHtoYXNofWApO1xuICAgICAgY29uc3QgZGF0YTogYW55ID0ge1xuICAgICAgICAuLi5zb3VyY2VUcmFuc2xhdGlvbnMsXG4gICAgICAgIHNvdXJjZTogdGhpcy5ub3JtYWxpemVTdHJpbmcoc291cmNlKSxcbiAgICAgIH07XG4gICAgICBpZiAodGFncykge1xuICAgICAgICBkYXRhLnRhZ3MgPSB0YWdzO1xuICAgICAgfVxuICAgICAgYmF0Y2gudXBkYXRlKHRyYW5zbGF0aW9uUmVmLCBkYXRhKTtcbiAgICAgIGJhdGNoQ291bnQgKz0gMTtcbiAgICB9KTtcbiAgICBpZiAoYmF0Y2hDb3VudCA+IDUwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1cCB0byA1MDAgdHJhbnNsYXRpb25zIGNhbiBiZSBzYXZlZCBhdCBhIHRpbWUuJyk7XG4gICAgfVxuICAgIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIFwia2V5XCIgdXNlZCBmb3IgYSB0cmFuc2xhdGlvbiBhcyBzdG9yZWQgaW4gdGhlIGRiLiBUcmFuc2xhdGlvbnNcbiAgICogYXJlIHN0b3JlZCB1bmRlciBgUHJvamVjdHMvPHByb2plY3QgaWQ+L1RyYW5zbGF0aW9ucy88c2hhMSBoYXNoPmAuXG4gICAqL1xuICBnZXRUcmFuc2xhdGlvbktleShzb3VyY2U6IHN0cmluZykge1xuICAgIGNvbnN0IHNoYTEgPSBjcnlwdG9cbiAgICAgIC5jcmVhdGVIYXNoKCdzaGExJylcbiAgICAgIC51cGRhdGUodGhpcy5ub3JtYWxpemVTdHJpbmcoc291cmNlKSlcbiAgICAgIC5kaWdlc3QoJ2hleCcpO1xuICAgIHJldHVybiBzaGExO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyBhIHN0cmluZyB0aGF0J3MgdXNlZCBmb3IgdHJhbnNsYXRpb25zLiBQZXJmb3JtcyB0aGUgZm9sbG93aW5nOlxuICAgKiAtIFJlbW92ZXMgYW55IGxlYWRpbmcvdHJhaWxpbmcgd2hpdGVzcGFjZVxuICAgKiAtIFJlbW92ZXMgc3BhY2VzIGF0IHRoZSBlbmQgb2YgYW55IGxpbmVcbiAgICovXG4gIG5vcm1hbGl6ZVN0cmluZyhzdHI6IHN0cmluZykge1xuICAgIGNvbnN0IGxpbmVzID0gU3RyaW5nKHN0cilcbiAgICAgIC50cmltKClcbiAgICAgIC5zcGxpdCgnXFxuJylcbiAgICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbUVuZCgpKTtcbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgdHJhbnNsYXRpb25zIGZvciBhIHBhcnRpY3VsYXIgbG9jYWxlLlxuICAgKlxuICAgKiBSZXR1cm5zIGEgbWFwIGxpa2U6XG4gICAqIGBgYFxuICAgKiB7XG4gICAqICAgXCJIZWxsb1wiOiBcIkJvbmpvdXJcIixcbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGxvYWRUcmFuc2xhdGlvbnNGb3JMb2NhbGUoXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IExvYWRUcmFuc2xhdGlvbnNPcHRpb25zXG4gICk6IFByb21pc2U8TG9jYWxlVHJhbnNsYXRpb25zPiB7XG4gICAgY29uc3QgdHJhbnNsYXRpb25zTWFwID0gYXdhaXQgdGhpcy5sb2FkVHJhbnNsYXRpb25zKG9wdGlvbnMpO1xuICAgIHJldHVybiB0cmFuc2xhdGlvbnNGb3JMb2NhbGUodHJhbnNsYXRpb25zTWFwLCBsb2NhbGUpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbXNQbHVnaW4ocm9vdENvbmZpZzogUm9vdENvbmZpZyk6IENNU1BsdWdpbiB7XG4gIGNvbnN0IHBsdWdpbnM6IFBsdWdpbltdID0gcm9vdENvbmZpZy5wbHVnaW5zIHx8IFtdO1xuICBjb25zdCBwbHVnaW4gPSBwbHVnaW5zLmZpbmQoKHBsdWdpbikgPT4gcGx1Z2luLm5hbWUgPT09ICdyb290LWNtcycpO1xuICBpZiAoIXBsdWdpbikge1xuICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IGZpbmQgcm9vdC1jbXMgcGx1Z2luIGNvbmZpZyBpbiByb290LmNvbmZpZy50cycpO1xuICB9XG4gIHJldHVybiBwbHVnaW4gYXMgQ01TUGx1Z2luO1xufVxuXG4vKipcbiAqIFdhbGtzIHRoZSBkYXRhIHRyZWUgYW5kIGNvbnZlcnRzIGFueSBUaW1lc3RhbXAgb2JqZWN0cyB0byBtaWxsaXMgYW5kIGFueVxuICogX2FycmF5IG1hcHMgdG8gbm9ybWFsIGFycmF5cy5cbiAqXG4gKiBFLmcuOlxuICpcbiAqIG5vcm1hbGl6ZURhdGEoe1xuICogICBzeXM6IHttb2RpZmllZEF0OiBUaW1lc3RhbXAoMTIzKX0sXG4gKiAgIGZpZWxkczoge1xuICogICAgIF9hcnJheTogWydhc2RmJ10sXG4gKiAgICAgYXNkZjoge3RpdGxlOiAnaGVsbG8nfVxuICogICB9XG4gKiB9KVxuICogLy8gPT4ge3N5czoge21vZGlmaWVkQXQ6IDEyM30sIGZpZWxkczoge2ZvbzogW3t0aXRsZTogJ2hlbGxvJ31dfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVubWFyc2hhbERhdGEoZGF0YTogYW55KTogYW55IHtcbiAgY29uc3QgcmVzdWx0OiBhbnkgPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YSkge1xuICAgIGNvbnN0IHZhbCA9IGRhdGFba2V5XTtcbiAgICBpZiAoaXNPYmplY3QodmFsKSkge1xuICAgICAgaWYgKHZhbC50b01pbGxpcykge1xuICAgICAgICByZXN1bHRba2V5XSA9IHZhbC50b01pbGxpcygpO1xuICAgICAgfSBlbHNlIGlmIChPYmplY3QuaGFzT3duKHZhbCwgJ19hcnJheScpICYmIEFycmF5LmlzQXJyYXkodmFsLl9hcnJheSkpIHtcbiAgICAgICAgY29uc3QgYXJyID0gdmFsLl9hcnJheS5tYXAoKGs6IHN0cmluZykgPT4gdW5tYXJzaGFsRGF0YSh2YWxba10gfHwge30pKTtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBhcnI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRba2V5XSA9IHVubWFyc2hhbERhdGEodmFsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHVubWFyc2hhbERhdGEoKWAgaW5zdGVhZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhKGRhdGE6IGFueSk6IGFueSB7XG4gIHJldHVybiB1bm1hcnNoYWxEYXRhKGRhdGEpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5T2JqZWN0IHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xuICBfYXJyYXk6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZXMgYW4gYXJyYXkgaW50byBhbiBgQXJyYXlPYmplY3RgLCBlLmcuOlxuICpcbiAqIGBgYFxuICogbWFyc2hhbEFycmF5KFsxLCAyLCAzXSlcbiAqIC8vID0+IHthOiAxLCBiOiAyLCBjOiAzLCBfYXJyYXk6IFsnYScsICdiJywgJ2MnXX1cbiAqIGBgYFxuICpcbiAqIFRoaXMgZGF0YWJhc2Ugc3RvcmFnZSBtZXRob2QgbWFrZXMgaXQgZWFzaWVyIHRvIHVwZGF0ZSBhIHNpbmdsZSBmaWVsZCBpbiBhXG4gKiBkZWVwbHkgbmVzdGVkIGFycmF5IG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcnNoYWxBcnJheShhcnI6IGFueVtdKTogQXJyYXlPYmplY3Qge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIHJldHVybiBhcnI7XG4gIH1cbiAgY29uc3QgYXJyT2JqZWN0OiBBcnJheU9iamVjdCA9IHtfYXJyYXk6IFtdfTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgIGNvbnN0IGtleSA9IHJhbmRTdHJpbmcoNik7XG4gICAgYXJyT2JqZWN0W2tleV0gPSBpdGVtO1xuICAgIGFyck9iamVjdC5fYXJyYXkucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBhcnJPYmplY3Q7XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gYEFycmF5T2JqZWN0YCB0byBhIG5vcm1hbCBhcnJheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVubWFyc2hhbEFycmF5KGFyck9iamVjdDogQXJyYXlPYmplY3QpOiBhbnlbXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShhcnJPYmplY3Q/Ll9hcnJheSkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgY29uc3QgYXJyID0gYXJyT2JqZWN0Ll9hcnJheS5tYXAoKGs6IHN0cmluZykgPT4gYXJyT2JqZWN0W2tdKTtcbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoZGF0YTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgJiYgZGF0YSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmFuZFN0cmluZyhsZW46IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBjaGFycyA9XG4gICAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGNvbnN0IHJhbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpO1xuICAgIHJlc3VsdC5wdXNoKGNoYXJzLmNoYXJBdChyYW5kKSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHRyYW5zbGF0aW9ucyBtYXAgZnJvbSBgbG9hZFRyYW5zbGF0aW9ucygpYCB0byBhIG1hcCBvZiBzb3VyY2UgdG9cbiAqIHRyYW5zbGF0ZWQgc3RyaW5nIGZvciBhIHBhcnRpY3VsYXIgbG9jYWxlLlxuICpcbiAqIFJldHVybnMgYSBtYXAgbGlrZTpcbiAqIGBgYFxuICoge1xuICogICBcIkhlbGxvXCI6IFwiQm9uam91clwiLFxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGlvbnNGb3JMb2NhbGUoXG4gIHRyYW5zbGF0aW9uc01hcDogVHJhbnNsYXRpb25zTWFwLFxuICBsb2NhbGU6IHN0cmluZ1xuKSB7XG4gIGNvbnN0IGxvY2FsZVRyYW5zbGF0aW9uczogTG9jYWxlVHJhbnNsYXRpb25zID0ge307XG4gIE9iamVjdC52YWx1ZXModHJhbnNsYXRpb25zTWFwKS5mb3JFYWNoKChzdHJpbmcpID0+IHtcbiAgICBjb25zdCBzb3VyY2UgPSBzdHJpbmcuc291cmNlO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gc3RyaW5nW2xvY2FsZV0gfHwgc3RyaW5nLmVuIHx8IHN0cmluZy5zb3VyY2U7XG4gICAgbG9jYWxlVHJhbnNsYXRpb25zW3NvdXJjZV0gPSB0cmFuc2xhdGlvbjtcbiAgfSk7XG4gIHJldHVybiBsb2NhbGVUcmFuc2xhdGlvbnM7XG59XG4iLCAiLyoqXG4gKiBEb2N1bWVudCB2ZXJpb24gaGlzdG9yeS5cbiAqXG4gKiBWZXJpb25zIHNhdmUgdGhlIHN0YXRlIG9mIGEgZG9jdW1lbnQgYXQgZGlmZmVyZW50IG1vbWVudHMgaW4gdGltZSwgYWxsb3dpbmdcbiAqIHVzZXJzIHRvIHJldmVydCBiYWNrIHRvIGEgdmVyc2lvbiBpZi93aGVuIG5lZWRlZC5cbiAqXG4gKiBUaGUgc2F2ZVZlcnNpb25zKCkgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgcnVuIHdpdGhpbiBhIGNyb24gam9iIChlLmcgdXNpbmdcbiAqIGZpcmViYXNlIGZ1bmN0aW9ucykuIEV2ZXJ5IG1pbnV0ZSwgdGhlIHJ1bm5lciBjaGVja3MgZm9yIGFsbCBkb2N1bWVudHMgdGhhdFxuICogaGF2ZSBiZWVuIGVkaXRlZCBzaW5jZSB0aGUgbGFzdCBydW4uIFRvIGF2b2lkIHNhdmluZyBcInBhcnRpYWxcIiB2ZXJzaW9uc1xuICogKHdoZW4gdGhlIHVzZXIgbWlnaHQgYmUgaW4gdGhlIG1pZGRsZSBvZiBlZGl0aW5nIGEgZG9jdW1lbnQpLCB2ZXJzaW9ucyBvbmx5XG4gKiBydW4gb24gZG9jdW1lbnRzIHRoYXQgaGF2ZW4ndCBiZWVuIGVkaXRlZCB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGVuc3VyZVxuICogdGhhdCB2ZXJzaW9uIGlzIFwic3RhYmxlXCIuXG4gKlxuICogSW4gdGhlIGRhdGFiYXNlLCB2ZXJzaW9ucyBhcmUgc3RvcmVkIGFzOlxuICogL1Byb2plY3RzLzxwcm9qZWN0SWQ+L0NvbGxlY3Rpb25zLzxjb2xsZWN0aW9uSWQ+L0RyYWZ0cy88ZG9jSWQ+L1ZlcnNpb25zLzx0aW1lc3RhbXA+XG4gKlxuICogV2hlcmUgPHRpbWVzdGFtcD4gaXMgdGhlIHVuaXggdGltZXN0YW1wIChtaWxsaXMpIHRoYXQgdGhlIGRvY3VtZW50IHdhcyBsYXN0XG4gKiBlZGl0ZWQuXG4gKi9cblxuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7Um9vdENvbmZpZ30gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCB7XG4gIEZpcmVzdG9yZSxcbiAgUXVlcnksXG4gIFRpbWVzdGFtcCxcbiAgZ2V0RmlyZXN0b3JlLFxufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9maXJlc3RvcmUnO1xuaW1wb3J0IGdsb2IgZnJvbSAndGlueS1nbG9iJztcbmltcG9ydCB7Z2V0Q21zUGx1Z2lufSBmcm9tICcuL2NsaWVudC5qcyc7XG5cbi8vIFRvIGF2b2lkIHNhdmluZyBcInBhcnRpYWxcIiB2ZXJzaW9ucyAod2hlbiB0aGUgdXNlciBtaWdodCBiZSBpbiB0aGUgbWlkZGxlIG9mXG4vLyBlZGl0aW5nIGEgZG9jdW1lbnQpLCB2ZXJzaW9ucyBvbmx5IHJ1biBvbiBkb2N1bWVudHMgdGhhdCBoYXZlbid0IGJlZW4gZWRpdGVkXG4vLyB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGVuc3VyZSB0aGF0IHZlcnNpb24gaXMgXCJzdGFibGVcIi5cbmNvbnN0IERPQ1VNRU5UX1NBVkVfT0ZGU0VUID0gNSAqIDYwICogMTAwMDtcblxuaW50ZXJmYWNlIFBhcnRpYWxDTVNEb2Mge1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbGxlY3Rpb246IHN0cmluZztcbiAgc2x1Zzogc3RyaW5nO1xuICBzeXM6IHtcbiAgICBtb2RpZmllZEF0OiBUaW1lc3RhbXA7XG4gICAgbW9kaWZpZWRCeTogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgVmVyc2lvbnNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSByb290Q29uZmlnOiBSb290Q29uZmlnO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2plY3RJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRiOiBGaXJlc3RvcmU7XG5cbiAgY29uc3RydWN0b3Iocm9vdENvbmZpZzogUm9vdENvbmZpZykge1xuICAgIHRoaXMucm9vdENvbmZpZyA9IHJvb3RDb25maWc7XG4gICAgY29uc3QgY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHJvb3RDb25maWcpO1xuICAgIGNvbnN0IGNtc1BsdWdpbk9wdGlvbnMgPSBjbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgcHJvamVjdElkID0gY21zUGx1Z2luT3B0aW9ucy5pZCB8fCAnZGVmYXVsdCc7XG4gICAgdGhpcy5wcm9qZWN0SWQgPSBwcm9qZWN0SWQ7XG4gICAgY29uc3QgYXBwID0gY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gICAgdGhpcy5kYiA9IGdldEZpcmVzdG9yZShhcHApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgdmVyc2lvbiBvZiBhbGwgZG9jdW1lbnRzIHRoYXQgaGF2ZSBiZWVuIGVkaXRlZCBzaW5jZSB0aGUgbGFzdCBydW4uXG4gICAqL1xuICBhc3luYyBzYXZlVmVyc2lvbnMoKSB7XG4gICAgLy8gT2Zmc2V0IHRoZSBcImxhc3QgcnVuXCIgdGltZSBieSA1IG1pbnMuIFZlcnNpb25zIGlnbm9yZSBkb2NzIHRoYXQgd2VyZVxuICAgIC8vIGVkaXRlZCB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGF2b2lkIHBvdGVudGlhbCBcInBhcnRpYWxcIiB2ZXJzaW9ucyB3aGVuXG4gICAgLy8gdXNlciBpcyBpbiB0aGUgbWlkZGxlIG9mIGVkaXRpbmcgYSBkb2N1bWVudC5cbiAgICBjb25zdCBsYXN0UnVuID0gYXdhaXQgdGhpcy5nZXRMYXN0UnVuKCk7XG4gICAgY29uc3QgbGFzdFJ1bldpdGhPZmZzZXQgPVxuICAgICAgbGFzdFJ1biA9PT0gMCA/IGxhc3RSdW4gOiBsYXN0UnVuIC0gRE9DVU1FTlRfU0FWRV9PRkZTRVQ7XG4gICAgY29uc3QgY2hhbmdlZERvY3MgPSBhd2FpdCB0aGlzLmdldERvY3NNb2RpZmllZEFmdGVyKGxhc3RSdW5XaXRoT2Zmc2V0KTtcbiAgICBjb25zdCBub3cgPSBUaW1lc3RhbXAubm93KCkudG9NaWxsaXMoKTtcbiAgICBjb25zdCB2ZXJzaW9ucyA9IGNoYW5nZWREb2NzLmZpbHRlcigoZG9jKSA9PiB7XG4gICAgICBjb25zdCBtb2RpZmllZEF0ID0gZG9jLnN5cy5tb2RpZmllZEF0LnRvTWlsbGlzKCk7XG4gICAgICByZXR1cm4gbW9kaWZpZWRBdCA8PSBub3cgLSBET0NVTUVOVF9TQVZFX09GRlNFVDtcbiAgICB9KTtcbiAgICBpZiAodmVyc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zYXZlVmVyc2lvbnNUb0ZpcmVzdG9yZSh2ZXJzaW9ucyk7XG4gICAgfVxuICAgIHRoaXMuc2F2ZUxhc3RSdW4obm93KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2F2ZVZlcnNpb25zVG9GaXJlc3RvcmUodmVyc2lvbnM6IFBhcnRpYWxDTVNEb2NbXSkge1xuICAgIGNvbnN0IGJhdGNoID0gdGhpcy5kYi5iYXRjaCgpO1xuICAgIHZlcnNpb25zLmZvckVhY2goKHZlcnNpb24pID0+IHtcbiAgICAgIGlmICghdmVyc2lvbi5jb2xsZWN0aW9uIHx8ICF2ZXJzaW9uLnNsdWcgfHwgIXZlcnNpb24uc3lzPy5tb2RpZmllZEF0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1vZGlmaWVkQXRNaWxsaXMgPSB2ZXJzaW9uLnN5cy5tb2RpZmllZEF0LnRvTWlsbGlzKCk7XG4gICAgICBjb25zdCB2ZXJzaW9uUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9Db2xsZWN0aW9ucy8ke3ZlcnNpb24uY29sbGVjdGlvbn0vRHJhZnRzLyR7dmVyc2lvbi5zbHVnfS9WZXJzaW9ucy8ke21vZGlmaWVkQXRNaWxsaXN9YDtcbiAgICAgIGNvbnNvbGUubG9nKHZlcnNpb25QYXRoKTtcbiAgICAgIGNvbnN0IHZlcnNpb25SZWYgPSB0aGlzLmRiLmRvYyh2ZXJzaW9uUGF0aCk7XG4gICAgICBiYXRjaC5zZXQodmVyc2lvblJlZiwgdmVyc2lvbik7XG4gICAgfSk7XG4gICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gICAgY29uc29sZS5sb2coYHZlcnNpb25zOiBzYXZlZCAke3ZlcnNpb25zLmxlbmd0aH0gdmVyc2lvbnNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBsYXN0IHRpbWUgKGluIG1pbGxpcykgc2F2ZVZlcnNpb25zKCkgd2FzIHJ1biwgb3IgMCBpZiBoYXNcbiAgICogbmV2ZXIgYmVlbiBydW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldExhc3RSdW4oKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBwcm9qZWN0RG9jUmVmID0gdGhpcy5kYi5jb2xsZWN0aW9uKCdQcm9qZWN0cycpLmRvYyh0aGlzLnByb2plY3RJZCk7XG4gICAgY29uc3QgcHJvamVjdERvYyA9IGF3YWl0IHByb2plY3REb2NSZWYuZ2V0KCk7XG4gICAgaWYgKHByb2plY3REb2MuZXhpc3RzKSB7XG4gICAgICBjb25zdCBkYXRhID0gcHJvamVjdERvYy5kYXRhKCkgfHwge307XG4gICAgICBjb25zdCB0cyA9IGRhdGEudmVyc2lvbnNMYXN0UnVuIGFzIFRpbWVzdGFtcDtcbiAgICAgIGlmICh0cykge1xuICAgICAgICByZXR1cm4gdHMudG9NaWxsaXMoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZXMge3ZlcnNpb25MYXN0UnVuOiA8dGltZXN0YW1wPn0gdG8gdGhlIFByb2plY3RzLzxwcm9qZWN0SWQ+IGRvYy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2F2ZUxhc3RSdW4obWlsbGlzOiBudW1iZXIpIHtcbiAgICBjb25zdCB0cyA9IFRpbWVzdGFtcC5mcm9tTWlsbGlzKG1pbGxpcyk7XG4gICAgY29uc3QgcHJvamVjdERvY1JlZiA9IHRoaXMuZGIuY29sbGVjdGlvbignUHJvamVjdHMnKS5kb2ModGhpcy5wcm9qZWN0SWQpO1xuICAgIGF3YWl0IHByb2plY3REb2NSZWYuc2V0KHt2ZXJzaW9uc0xhc3RSdW46IHRzfSwge21lcmdlOiB0cnVlfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIGRvY3MgdGhhdCB3ZXJlIGVkaXRlZCBhZnRlciBhIGNlcnRhaW4gdGltZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0RG9jc01vZGlmaWVkQWZ0ZXIobWlsbGlzOiBudW1iZXIpOiBQcm9taXNlPFBhcnRpYWxDTVNEb2NbXT4ge1xuICAgIGNvbnN0IHRzID0gVGltZXN0YW1wLmZyb21NaWxsaXMobWlsbGlzKTtcbiAgICBjb25zdCByZXN1bHRzOiBQYXJ0aWFsQ01TRG9jW10gPSBbXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uSWRzID0gYXdhaXQgdGhpcy5saXN0Q29sbGVjdGlvbnMoKTtcbiAgICAvLyBOT1RFOiBJbmRpdmlkdWFsIGNvbGxlY3Rpb25zIGFyZSBxdWVyaWVkIGluc3RlYWQgb2YgdXNpbmcgYVxuICAgIC8vIGNvbGxlY3Rpb25Hcm91cCBxdWVyeSBiZWNhdXNlIHRoZSBsYXR0ZXIgcmVxdWlyZXMgYSBmaXJlc3RvcmUgaW5kZXggdG8gYmVcbiAgICAvLyBzZXQgdXAuXG4gICAgZm9yIChjb25zdCBjb2xsZWN0aW9uSWQgb2YgY29sbGVjdGlvbklkcykge1xuICAgICAgY29uc3QgY29sbGVjdGlvblBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9L0RyYWZ0c2A7XG4gICAgICBjb25zdCBxdWVyeTogUXVlcnkgPSB0aGlzLmRiXG4gICAgICAgIC5jb2xsZWN0aW9uKGNvbGxlY3Rpb25QYXRoKVxuICAgICAgICAud2hlcmUoJ3N5cy5tb2RpZmllZEF0JywgJz49JywgdHMpO1xuICAgICAgY29uc3QgcXVlcnlTbmFwc2hvdCA9IGF3YWl0IHF1ZXJ5LmdldCgpO1xuICAgICAgcXVlcnlTbmFwc2hvdC5mb3JFYWNoKChkb2MpID0+IHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGRvYy5kYXRhKCkgYXMgUGFydGlhbENNU0RvYyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgY29sbGVjdGlvbiBpZHMgZm9yIHRoZSBSb290IHByb2plY3QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxpc3RDb2xsZWN0aW9ucygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgY29sbGVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uRmlsZU5hbWVzID0gYXdhaXQgZ2xvYignKi5zY2hlbWEudHMnLCB7XG4gICAgICBjd2Q6IHBhdGguam9pbih0aGlzLnJvb3RDb25maWcucm9vdERpciwgJ2NvbGxlY3Rpb25zJyksXG4gICAgfSk7XG4gICAgY29sbGVjdGlvbkZpbGVOYW1lcy5mb3JFYWNoKChmaWxlbmFtZSkgPT4ge1xuICAgICAgY29sbGVjdGlvbklkcy5wdXNoKGZpbGVuYW1lLnNsaWNlKDAsIC0xMCkpO1xuICAgIH0pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uSWRzO1xuICB9XG59XG4iLCAiaW1wb3J0IHtSb290Q29uZmlnfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IHtwdWJsaXNoU2NoZWR1bGVkRG9jc30gZnJvbSAnLi9ydW50aW1lLmpzJztcbmltcG9ydCB7VmVyc2lvbnNTZXJ2aWNlfSBmcm9tICcuL3ZlcnNpb25zLmpzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkNyb25Kb2JzKHJvb3RDb25maWc6IFJvb3RDb25maWcpIHtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgIHJ1bkNyb25Kb2IoJ3B1Ymxpc2hTY2hlZHVsZWREb2NzJywgcnVuUHVibGlzaFNjaGVkdWxlZERvY3MsIHJvb3RDb25maWcpLFxuICAgIHJ1bkNyb25Kb2IoJ3NhdmVWZXJzaW9ucycsIHJ1blNhdmVWZXJzaW9ucywgcm9vdENvbmZpZyksXG4gIF0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBydW5Dcm9uSm9iKFxuICBuYW1lOiBzdHJpbmcsXG4gIGZuOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgLi4uYXJnczogYW55W11cbikge1xuICB0cnkge1xuICAgIGF3YWl0IGZuKC4uLmFyZ3MpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zb2xlLmxvZyhgY3JvbiBmYWlsZWQ6ICR7bmFtZX1gKTtcbiAgICBjb25zb2xlLmVycm9yKFN0cmluZyhlcnIuc3RhY2sgfHwgZXJyKSk7XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1blB1Ymxpc2hTY2hlZHVsZWREb2NzKHJvb3RDb25maWc6IFJvb3RDb25maWcpIHtcbiAgYXdhaXQgcHVibGlzaFNjaGVkdWxlZERvY3Mocm9vdENvbmZpZyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1blNhdmVWZXJzaW9ucyhyb290Q29uZmlnOiBSb290Q29uZmlnKSB7XG4gIGNvbnN0IHNlcnZpY2UgPSBuZXcgVmVyc2lvbnNTZXJ2aWNlKHJvb3RDb25maWcpO1xuICBhd2FpdCBzZXJ2aWNlLnNhdmVWZXJzaW9ucygpO1xufVxuIiwgImltcG9ydCB7cGFyc2UgYXMgY3N2UGFyc2V9IGZyb20gJ2Nzdi1wYXJzZS9zeW5jJztcbmltcG9ydCB7c3RyaW5naWZ5IGFzIGNzdlN0cmluZ2lmeX0gZnJvbSAnY3N2LXN0cmluZ2lmeS9zeW5jJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5VG9Dc3YocmVxOiB7XG4gIGhlYWRlcnM6IHN0cmluZ1tdO1xuICByb3dzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pjtcbn0pOiBzdHJpbmcge1xuICBjb25zdCBoZWFkZXJzID0gcmVxLmhlYWRlcnMgfHwgW107XG4gIGNvbnN0IHJvd3MgPSByZXEucm93cyB8fCBbXTtcbiAgcmV0dXJuIGNzdlN0cmluZ2lmeShyb3dzLCB7XG4gICAgaGVhZGVyOiB0cnVlLFxuICAgIGNvbHVtbnM6IGhlYWRlcnMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3N2VG9BcnJheShjc3ZTdHJpbmc6IHN0cmluZykge1xuICBjb25zdCByb3dzID0gY3N2UGFyc2UoY3N2U3RyaW5nLCB7XG4gICAgY29sdW1uczogdHJ1ZSxcbiAgICBza2lwX2VtcHR5X2xpbmVzOiB0cnVlLFxuICB9KTtcbiAgcmV0dXJuIHJvd3M7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQUEsU0FBUSxZQUFZLFVBQVM7QUFDN0IsT0FBT0EsV0FBVTtBQUNqQixTQUFRLHFCQUFvQjtBQVU1QixPQUFPLGdCQUFnQjtBQUN2QjtBQUFBLEVBRUU7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFRLGVBQThCO0FBQ3RDLE9BQU8sVUFBVTs7O0FDbkJqQixTQUFRLDJCQUEwQjs7O0FDRWxDO0FBQUEsRUFDRSxjQUFBQztBQUFBLEVBR0EsZ0JBQUFDO0FBQUEsT0FDSzs7O0FDUlAsT0FBTyxZQUFZO0FBR25CO0FBQUEsRUFDRTtBQUFBLEVBSUE7QUFBQSxPQUNLO0FBbVpBLFNBQVMsYUFBYSxZQUFtQztBQUM5RCxRQUFNLFVBQW9CLFdBQVcsV0FBVyxDQUFDO0FBQ2pELFFBQU0sU0FBUyxRQUFRLEtBQUssQ0FBQ0MsWUFBV0EsUUFBTyxTQUFTLFVBQVU7QUFDbEUsTUFBSSxDQUFDLFFBQVE7QUFDWCxVQUFNLElBQUksTUFBTSx5REFBeUQ7QUFBQSxFQUMzRTtBQUNBLFNBQU87QUFDVDs7O0FEalNBLGVBQXNCLHFCQUFxQixZQUF3QjtBQUNqRSxRQUFNQyxhQUFZLGFBQWEsVUFBVTtBQUN6QyxRQUFNLG1CQUFtQkEsV0FBVSxVQUFVO0FBQzdD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QkFBc0I7QUFBQSxRQUM3QztBQUFBLE1BQ0YsQ0FBQztBQUdELGFBQU8sSUFBSSxlQUFlLE9BQU8sS0FBYyxRQUFrQjtBQUMvRCxZQUFJLFFBQVEsV0FBVyxtQkFBbUI7QUFDMUMsWUFBSSxZQUFZO0FBQ2hCLFlBQUksU0FBUyxZQUFZO0FBQUEsTUFDM0IsQ0FBQztBQUdELGFBQU8sSUFBSSxPQUFPLEtBQWMsS0FBZSxTQUF1QjtBQUNwRSxZQUFJLENBQUMsY0FBYyxHQUFHLEdBQUc7QUFDdkIsZUFBSztBQUNMO0FBQUEsUUFDRjtBQUNBLGNBQU0saUJBQWlCLE1BQU0sa0JBQWtCLEdBQUc7QUFDbEQsWUFBSSxnQkFBZ0I7QUFDbEIsZUFBSztBQUNMO0FBQUEsUUFDRjtBQUNBLFlBQUksSUFBSSxZQUFZLFdBQVcsVUFBVSxHQUFHO0FBQzFDLGNBQUksT0FBTyxHQUFHLEVBQUUsS0FBSyxFQUFDLFNBQVMsT0FBTyxPQUFPLGlCQUFnQixDQUFDO0FBQzlEO0FBQUEsUUFDRjtBQUNBLGdCQUFRLElBQUksMkJBQTJCO0FBQ3ZDLGNBQU0sU0FBUyxJQUFJLGdCQUFnQjtBQUFBLFVBQ2pDLFVBQVUsSUFBSTtBQUFBLFFBQ2hCLENBQUM7QUFDRCxZQUFJLFNBQVMsY0FBYyxPQUFPLFNBQVMsQ0FBQyxFQUFFO0FBQUEsTUFDaEQsQ0FBQztBQUdELFVBQUksTUFBTTtBQUdWLGFBQU8sSUFBSSxRQUFRLE9BQU8sS0FBYyxRQUFrQjtBQUN4RCxZQUFJO0FBQ0YsZ0JBQU1BLE9BQU0sTUFBTSxZQUFZLEdBQUc7QUFDakMsZ0JBQU1BLEtBQUksVUFBVSxLQUFLLEtBQUs7QUFBQSxZQUM1QixZQUFZLElBQUk7QUFBQSxZQUNoQixXQUFXO0FBQUEsWUFDWCxnQkFBZ0IsUUFBUTtBQUFBLFVBQzFCLENBQUM7QUFBQSxRQUNILFNBQVMsS0FBSztBQUVaLGtCQUFRLE1BQU0sR0FBRztBQUNqQixjQUFJLE9BQU8sR0FBRyxFQUFFLEtBQUssc0JBQXNCO0FBQUEsUUFDN0M7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBQUEsRUFDRjtBQUNGO0FBRUEsU0FBUyxXQUFXLFVBQW9DO0FBQ3RELFNBQU8sR0FDSixPQUFPLFFBQVEsRUFDZixLQUFLLE1BQU0sSUFBSSxFQUNmLE1BQU0sTUFBTSxLQUFLO0FBQ3RCOyIsCiAgIm5hbWVzIjogWyJwYXRoIiwgIkZpZWxkVmFsdWUiLCAiZ2V0RmlyZXN0b3JlIiwgInBsdWdpbiIsICJjbXNQbHVnaW4iLCAiZ2V0RmlyZXN0b3JlIiwgIkZpZWxkVmFsdWUiLCAiVGltZXN0YW1wIiwgImdldEZpcmVzdG9yZSIsICJjbXNQbHVnaW4iLCAiZ2V0RmlyZXN0b3JlIiwgIlRpbWVzdGFtcCIsICJwYXRoIiwgImFwcCJdCn0K
|
|
1091
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9wbHVnaW4udHMiLCAiLi4vY29yZS9hcGkudHMiLCAiLi4vY29yZS9jbGllbnQudHMiLCAiLi4vY29yZS92ZXJzaW9ucy50cyIsICIuLi9jb3JlL2Nyb24udHMiLCAiLi4vY29yZS9jc3YudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7cHJvbWlzZXMgYXMgZnN9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7ZmlsZVVSTFRvUGF0aH0gZnJvbSAnbm9kZTp1cmwnO1xuXG5pbXBvcnQge1xuICBDb25maWd1cmVTZXJ2ZXJPcHRpb25zLFxuICBOZXh0RnVuY3Rpb24sXG4gIFBsdWdpbixcbiAgUmVxdWVzdCxcbiAgUmVzcG9uc2UsXG4gIFNlcnZlcixcbn0gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCBib2R5UGFyc2VyIGZyb20gJ2JvZHktcGFyc2VyJztcbmltcG9ydCB7XG4gIEFwcCxcbiAgYXBwbGljYXRpb25EZWZhdWx0LFxuICBnZXRBcHAsXG4gIGluaXRpYWxpemVBcHAsXG59IGZyb20gJ2ZpcmViYXNlLWFkbWluL2FwcCc7XG5pbXBvcnQge2dldEF1dGgsIERlY29kZWRJZFRva2VufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9hdXRoJztcbmltcG9ydCAqIGFzIGpzb253ZWJ0b2tlbiBmcm9tICdqc29ud2VidG9rZW4nO1xuaW1wb3J0IHNpcnYgZnJvbSAnc2lydic7XG5pbXBvcnQge2FwaX0gZnJvbSAnLi9hcGkuanMnO1xuaW1wb3J0IHtSb290Q01TQ2xpZW50fSBmcm9tICcuL2NsaWVudC5qcyc7XG5cbmNvbnN0IF9fZGlybmFtZSA9IHBhdGguZGlybmFtZShmaWxlVVJMVG9QYXRoKGltcG9ydC5tZXRhLnVybCkpO1xuXG50eXBlIEFwcE1vZHVsZSA9IHR5cGVvZiBpbXBvcnQoJy4vYXBwLmpzJyk7XG5cbi8vIFRoZSBzZXNzaW9uIGtleSBuYW1lIHVzZWQgZm9yIFJvb3QgQ01TIGF1dGhlbnRpY2F0aW9uLlxuY29uc3QgU0VTU0lPTl9DT09LSUVfQVVUSCA9ICdyb290LWNtcy1hdXRoJztcblxuZXhwb3J0IGludGVyZmFjZSBDTVNVc2VyIHtcbiAgZW1haWw6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgQ01TUGx1Z2luT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIFRoZSBJRCBvZiB0aGUgcHJvamVjdC4gRGF0YSB3aWxsIGJlIHN0b3JlZCB1bmRlciB0aGUgbmFtZXNwYWNlXG4gICAqIGBQcm9qZWN0cy8ke2lkfWAgaW4gZmlyZXN0b3JlLlxuICAgKi9cbiAgaWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBwcm9qZWN0LiBVc2VkIGluIHRoZSBoZWFkZXIgb2YgdGhlIENNUyB0byBoZWxwIGlkZW50aWZ5XG4gICAqIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgbmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogRmlyZWJhc2UgY29uZmlnIG9iamVjdCwgd2hpY2ggY2FuIGJlIG9idGFpbmVkIGluIHRoZSBGaXJlYmFzZSBDb25zb2xlIGJ5XG4gICAqIGdvaW5nIHRvIFwiUHJvamVjdCBTZXR0aW5nc1wiLlxuICAgKi9cbiAgZmlyZWJhc2VDb25maWc6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmc7XG4gICAgYXBpS2V5OiBzdHJpbmc7XG4gICAgYXV0aERvbWFpbjogc3RyaW5nO1xuICAgIHByb2plY3RJZDogc3RyaW5nO1xuICAgIHN0b3JhZ2VCdWNrZXQ6IHN0cmluZztcbiAgfTtcblxuICAvKipcbiAgICogR0FQSSBjcmVkZW50aWFscy4gSW5jbHVkZSBpZiB1c2luZyBHb29nbGUgRHJpdmUgYW5kIEdvb2dsZSBTaGVldHMgZmVhdHVyZXMuXG4gICAqIFNlZTogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vc2hlZXRzL2FwaS9xdWlja3N0YXJ0L2pzXG4gICAqL1xuICBnYXBpPzoge1xuICAgIC8qKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9zaGVldHMvYXBpL3F1aWNrc3RhcnQvanMjY3JlYXRlX2FuX2FwaV9rZXkgKi9cbiAgICBhcGlLZXk6IHN0cmluZztcbiAgICAvKiogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vc2hlZXRzL2FwaS9xdWlja3N0YXJ0L2pzI2F1dGhvcml6ZV9jcmVkZW50aWFsc19mb3JfYV93ZWJfYXBwbGljYXRpb24gKi9cbiAgICBjbGllbnRJZDogc3RyaW5nO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTZWNyZXQgdmFsdWUocykgdXNlZCBmb3Igc2lnbmluZyB0aGUgdXNlciBhdXRoZW50aWNhdGlvbiBjb29raWUuXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgaXMgbm93IGhhbmRsZWQgZGlyZWN0bHkgYnkgcm9vdCdzIHNlc3Npb25NaWRkbGV3YXJlIHVuZGVyXG4gICAqIGBzZXJ2ZXIuc2Vzc2lvbkNvb2tpZVNlY3JldGAgaW4gcm9vdC5jb25maWcudHMuXG4gICAqL1xuICBjb29raWVTZWNyZXQ/OiBzdHJpbmcgfCBzdHJpbmdbXTtcblxuICAvKiogRnVuY3Rpb24gY2FsbGVkIHRvIGNoZWNrIGlmIGEgdXNlciBzaG91bGQgaGF2ZSBhY2Nlc3MgdG8gdGhlIENNUy4gKi9cbiAgaXNVc2VyQXV0aG9yaXplZD86IChcbiAgICByZXE6IFJlcXVlc3QsXG4gICAgdXNlcjogQ01TVXNlclxuICApID0+IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0byBjYWxsIHRvIGNoZWNrIGlmIGxvZ2luIGlzIHJlcXVpcmVkIGZvciBhIHBhcnRpY3VsYXIgcmVxdWVzdC5cbiAgICovXG4gIGlzTG9naW5SZXF1aXJlZD86IChyZXE6IFJlcXVlc3QpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFVSTCB0byBHQ0kgc2VydmljZSBmb3IgdHJhbnNmb3JtaW5nIHVwbG9hZGVkIEdDUyBpbWFnZXMgdG8gYSBHb29nbGUgQXBwXG4gICAqIEVuZ2luZSBJbWFnZXMgQVBJIHNlcnZpbmcgVVJMLlxuICAgKlxuICAgKiBTZXR0aW5nIHRoaXMgdG8gYHRydWVgIHVzZXMgdGhlIGRlZmF1bHQgaG9zdGVkIHNlcnZpY2UgYXRcbiAgICogaHR0cHM6Ly9nY2kucm9vdGpzLmRldi5cbiAgICpcbiAgICogVG8gc2V0IHVwIEdDSTpcbiAgICpcbiAgICogLSBDcmVhdGUgYSBHQ1MgYnVja2V0IHdpdGggZmluZS1ncmFpbmVkIHBlcm1pc3Npb25zXG4gICAqIC0gU2hhcmUgb3duZXIgYWNjZXNzIHRvIHRoZSBidWNrZXQgd2l0aCB0aGUgc2VydmljZSBhY2NvdW50IHJldHVybmVkIGluXG4gICAqICAgaHR0cHM6Ly9nY2kucm9vdGpzLmRldi9fL3NlcnZpY2VfYWNjb3VudFxuICAgKlxuICAgKiBUbyBkaXNhYmxlIEdDSSwgbGVhdmUgdGhpcyB2YWx1ZSBlbXB0eSBvciBzZXQgdG8gYGZhbHNlYCwgd2hpY2ggd2hpY2ggd2lsbFxuICAgKiBzZXJ2ZSBpbWFnZXMgZGlyZWN0bHkgZnJvbSBHQ1MgaW5zdGVhZC5cbiAgICovXG4gIGdjaT86IHN0cmluZyB8IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBDTVNQbHVnaW4gPSBQbHVnaW4gJiB7XG4gIG5hbWU6ICdyb290LWNtcyc7XG4gIGdldENvbmZpZzogKCkgPT4gQ01TUGx1Z2luT3B0aW9ucztcbiAgZ2V0RmlyZWJhc2VBcHA6ICgpID0+IEFwcDtcbn07XG5cbmZ1bmN0aW9uIGlzRXhwaXJlZChkZWNvZGVkSWRUb2tlbjogRGVjb2RlZElkVG9rZW4pIHtcbiAgY29uc3QgdHMgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gIHJldHVybiB0cyA+PSBkZWNvZGVkSWRUb2tlbi5leHA7XG59XG5cbmZ1bmN0aW9uIGdldEZpcmViYXNlQXBwKGdjcFByb2plY3RJZDogc3RyaW5nKTogQXBwIHtcbiAgY29uc3QgYXBwTmFtZSA9ICdyb290LWNtcyc7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGdldEFwcChhcHBOYW1lKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyciAmJiBlcnIuY29kZSA9PT0gJ2FwcC9uby1hcHAnKSB7XG4gICAgICByZXR1cm4gaW5pdGlhbGl6ZUFwcChcbiAgICAgICAge1xuICAgICAgICAgIHByb2plY3RJZDogZ2NwUHJvamVjdElkLFxuICAgICAgICAgIGNyZWRlbnRpYWw6IGFwcGxpY2F0aW9uRGVmYXVsdCgpLFxuICAgICAgICB9LFxuICAgICAgICBhcHBOYW1lXG4gICAgICApO1xuICAgIH1cbiAgICB0aHJvdyBlcnI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNtc1BsdWdpbihvcHRpb25zOiBDTVNQbHVnaW5PcHRpb25zKTogQ01TUGx1Z2luIHtcbiAgY29uc3QgZmlyZWJhc2VDb25maWcgPSBvcHRpb25zLmZpcmViYXNlQ29uZmlnO1xuICBjb25zdCBhcHAgPSBnZXRGaXJlYmFzZUFwcChmaXJlYmFzZUNvbmZpZy5wcm9qZWN0SWQpO1xuICBjb25zdCBhdXRoID0gZ2V0QXV0aChhcHApO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgbG9naW4gaXMgcmVxdWlyZWQgZm9yIHRoZSByZXF1ZXN0LiBDdXJyZW50bHkgcmV0dXJucyBgdHJ1ZWAgaWZcbiAgICogdGhlIFVSTCBwYXRoIHN0YXJ0cyB3aXRoIC9jbXMgb3IgaWYgP3ByZXZpZXc9dHJ1ZSBpcyBpbiB0aGUgVVJMLlxuICAgKi9cbiAgZnVuY3Rpb24gbG9naW5SZXF1aXJlZChyZXE6IFJlcXVlc3QpOiBib29sZWFuIHtcbiAgICAvLyBBbGxvdyB0aGUgY3JvbiB0byBydW4gdW5hdXRoZW50aWNhdGVkLiBUaGUgY3JvbiBqb2IgaXMgcmVzcG9uc2libGVcbiAgICAvLyBmb3Igc2F2aW5nIHZlcnNpb24gaGlzdG9yeS5cbiAgICBpZiAocmVxLm9yaWdpbmFsVXJsID09PSAnL2Ntcy9hcGkvY3Jvbi5ydW4nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlcXVpcmUgbG9naW4gb24gYWxsIGAvY21zL2AgcGF0aHMuXG4gICAgaWYgKHJlcS5vcmlnaW5hbFVybC5zdGFydHNXaXRoKCcvY21zJykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBSZXF1aXJlIGxvZ2luIG9uIGFsbCBwYXRocyB0aGF0IGhhdmUgYD9wcmV2aWV3PXRydWVgLCB3aGljaCBpcyB1c2VkIGJ5XG4gICAgLy8gdGhlIHByZXZpZXcgaWZyYW1lIHRvIHJlbmRlciB0aGUgcHJldmlldyBmb3IgYSBwYWdlLlxuICAgIGlmIChTdHJpbmcocmVxLnF1ZXJ5LnByZXZpZXcpID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5pc0xvZ2luUmVxdWlyZWQgJiYgb3B0aW9ucy5pc0xvZ2luUmVxdWlyZWQocmVxKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhIG5ldyBsb2dpbiByZXF1ZXN0IGZvciBhIHVzZXIuIFRoZSByZXF1ZXN0IGJvZHkgc2hvdWxkIGNvbnRhaW5cbiAgICogYW4gaWRUb2tlbiwgd2hpY2ggaXMgdmVyaWZpZWQgb24gcHJvZCB1c2luZyBGaXJlYmFzZSBBZG1pbiBhbmQgSWRlbnRpdHlcbiAgICogVG9vbGtpdC4gSWYgYSBgaXNVc2VyQXV0aG9yaXplZCgpYCBjb25maWcgaXMgc2V0LCB0aGlzIGZ1bmN0aW9uIHdpbGwgYWxzb1xuICAgKiB2ZXJpZnkgdmlhIHRoYXQgZnVuY3Rpb24uIFJldHVybnMgdHJ1ZSBpZiB0aGUgbG9naW4gdmVyaWZpY2F0aW9uIHN1Y2NlZWRzLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gdmVyaWZ5VXNlckxvZ2luKFxuICAgIHJlcTogUmVxdWVzdFxuICApOiBQcm9taXNlPHthdXRob3JpemVkOiBib29sZWFuOyByZWFzb24/OiBzdHJpbmd9PiB7XG4gICAgY29uc3QgaWRUb2tlbiA9IHJlcS5ib2R5Py5pZFRva2VuO1xuICAgIGlmICghaWRUb2tlbikge1xuICAgICAgY29uc29sZS5sb2coJ2xvZ2luIGZhaWxlZDogbm8gaWQgdG9rZW4nKTtcbiAgICAgIHJldHVybiB7YXV0aG9yaXplZDogZmFsc2UsIHJlYXNvbjogJ25vIHRva2VuJ307XG4gICAgfVxuXG4gICAgbGV0IHVzZXI6IENNU1VzZXI7XG5cbiAgICAvLyBPbiBsb2NhbCBkZXYsIHNpbXBseSB2ZXJpZnkgdGhlIGRlY29kZWQgaWRUb2tlbidzIGVtYWlsIGlzIHNldC4gVGhlXG4gICAgLy8gaWRlbnRpdHkgdG9vbGtpdCB0aGF0IHZlcmlmaWVzIGlkIHRva2VucyByZXF1aXJlcyBhIHNlcnZpY2UgYWNjb3VudCxcbiAgICAvLyB3aGljaCB3ZSB3YW50IHRvIGF2b2lkIGhhdmluZyB0byBzZXQgdXAgd2hlbiB1c2VycyBhcmUgZG9pbmcgbG9jYWwgZGV2LlxuICAgIC8vIEF1dGhlbnRpY2F0aW9uIGlzIHN0aWxsIHJlcXVpcmVkIGJ5IHRoZSBmcm9udGVuZCB1c2luZyBGaXJlYmFzZSBBdXRoLFxuICAgIC8vIHRoaXMganVzdCBieXBhc3NlcyB0aGUgaW5pdGlhbCBzZXJ2ZXIgY2hlY2sgYmVmb3JlIHRoZSB1aSBpcyByZW5kZXJlZC5cbiAgICB0cnkge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgICAgIGNvbnN0IGp3dCA9IGpzb253ZWJ0b2tlbi5kZWNvZGUoaWRUb2tlbikgYXMganNvbndlYnRva2VuLkp3dFBheWxvYWQ7XG4gICAgICAgIGlmICghand0LmVtYWlsIHx8ICFqd3QuZW1haWxfdmVyaWZpZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnbG9naW4gZmFpbGVkOiBlbWFpbCB1bnZlcmlmaWVkJyk7XG4gICAgICAgICAgcmV0dXJuIHthdXRob3JpemVkOiBmYWxzZSwgcmVhc29uOiAnbG9naW4gZmFpbGVkJ307XG4gICAgICAgIH1cbiAgICAgICAgdXNlciA9IHtlbWFpbDogand0LmVtYWlsfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGp3dCA9IGF3YWl0IGF1dGgudmVyaWZ5SWRUb2tlbihpZFRva2VuLCB0cnVlKTtcbiAgICAgICAgaWYgKGlzRXhwaXJlZChqd3QpKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ2xvZ2luIGZhaWxlZDogaWQgdG9rZW4gaXMgZXhwaXJlZCcpO1xuICAgICAgICAgIHJldHVybiB7YXV0aG9yaXplZDogZmFsc2UsIHJlYXNvbjogJ2xvZ2luIGZhaWxlZCd9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghand0LmVtYWlsIHx8ICFqd3QuZW1haWxfdmVyaWZpZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnbG9naW4gZmFpbGVkOiBlbWFpbCB1bnZlcmlmaWVkJyk7XG4gICAgICAgICAgcmV0dXJuIHthdXRob3JpemVkOiBmYWxzZSwgcmVhc29uOiAnbG9naW4gZmFpbGVkJ307XG4gICAgICAgIH1cbiAgICAgICAgdXNlciA9IHtlbWFpbDogand0LmVtYWlsfTtcbiAgICAgIH1cblxuICAgICAgLy8gVmVyaWZ5IHRoZSBwcm9qZWN0J3MgYGlzVXNlckF1dGhvcml6ZWQoKWAgY29uZmlnIG9wdGlvbi5cbiAgICAgIGlmIChvcHRpb25zLmlzVXNlckF1dGhvcml6ZWQpIHtcbiAgICAgICAgY29uc3QgYXV0aG9yaXplZCA9IGF3YWl0IG9wdGlvbnMuaXNVc2VyQXV0aG9yaXplZChyZXEsIHtcbiAgICAgICAgICBlbWFpbDogdXNlci5lbWFpbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghYXV0aG9yaXplZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdsb2dpbiBmYWlsZWQ6IHVzZXIgaXMgbm90IGF1dGhvcml6ZWQnKTtcbiAgICAgICAgICByZXR1cm4ge2F1dGhvcml6ZWQ6IGZhbHNlLCByZWFzb246ICdub3QgYXV0aG9yaXplZCd9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFZlcmlmeSB0aGUgdXNlciBleGlzdHMgaW4gdGhlIERCJ3MgQUNMIGxpc3QuXG4gICAgICBjb25zdCBjbXNDbGllbnQgPSBuZXcgUm9vdENNU0NsaWVudChyZXEucm9vdENvbmZpZyEpO1xuICAgICAgY29uc3QgdXNlckhhc0FjY2VzcyA9IGF3YWl0IGNtc0NsaWVudC51c2VyRXhpc3RzSW5BY2wodXNlci5lbWFpbCk7XG4gICAgICBpZiAoIXVzZXJIYXNBY2Nlc3MpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2xvZ2luIGZhaWxlZDogdXNlciBpcyBub3QgaW4gdGhlIGZpcmVzdG9yZSBhY2wgbGlzdCcpO1xuICAgICAgICByZXR1cm4ge2F1dGhvcml6ZWQ6IGZhbHNlLCByZWFzb246ICdub3QgYXV0aG9yaXplZCd9O1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignZmFpbGVkIHRvIHZlcmlmeSBqd3QgdG9rZW4nKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybiB7YXV0aG9yaXplZDogZmFsc2UsIHJlYXNvbjogJ3Vua25vd24gZXJyb3InfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2F1dGhvcml6ZWQ6IHRydWV9O1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZ2V0Q3VycmVudFVzZXIocmVxOiBSZXF1ZXN0KTogUHJvbWlzZTxDTVNVc2VyIHwgbnVsbD4ge1xuICAgIGNvbnN0IHNlc3Npb25Db29raWUgPSByZXEuc2Vzc2lvbi5nZXRJdGVtKFNFU1NJT05fQ09PS0lFX0FVVEgpO1xuICAgIGlmICghc2Vzc2lvbkNvb2tpZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gT24gbG9jYWwgZGV2LCB2ZXJpZnkgdGhlIGRlY29kZWQgaWRUb2tlbiBoYXMgYSB2YWxpZCBlbWFpbC4gVGhlIGZpcmViYXNlXG4gICAgLy8gYXV0aCB2ZXJpZmljYXRpb24gb3RoZXJ3aXNlIHdvdWxkIHJlcXVpcmUgYSBzZXJ2aWNlIGFjY291bnQuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgICBjb25zdCBqd3QgPSBqc29ud2VidG9rZW4uZGVjb2RlKHNlc3Npb25Db29raWUpIGFzIGpzb253ZWJ0b2tlbi5Kd3RQYXlsb2FkO1xuICAgICAgaWYgKCFqd3Q/LmVtYWlsIHx8ICFqd3Q/LmVtYWlsX3ZlcmlmaWVkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgd2hldGhlciB1c2VyIGlzIGF1dGhvcml6ZWQuXG4gICAgICBpZiAob3B0aW9ucy5pc1VzZXJBdXRob3JpemVkKSB7XG4gICAgICAgIGNvbnN0IGF1dGhvcml6ZWQgPSBhd2FpdCBvcHRpb25zLmlzVXNlckF1dGhvcml6ZWQocmVxLCB7XG4gICAgICAgICAgZW1haWw6IGp3dC5lbWFpbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghYXV0aG9yaXplZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogbm90IGF1dGhvcml6ZWQnKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gVmVyaWZ5IHRoZSB1c2VyIGV4aXN0cyBpbiB0aGUgREIncyBBQ0wgbGlzdC5cbiAgICAgIGNvbnN0IGNtc0NsaWVudCA9IG5ldyBSb290Q01TQ2xpZW50KHJlcS5yb290Q29uZmlnISk7XG4gICAgICBjb25zdCB1c2VySGFzQWNjZXNzID0gYXdhaXQgY21zQ2xpZW50LnVzZXJFeGlzdHNJbkFjbChqd3QuZW1haWwpO1xuICAgICAgaWYgKCF1c2VySGFzQWNjZXNzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogdXNlciBpcyBub3QgaW4gdGhlIGZpcmVzdG9yZSBhY2wgbGlzdCcpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7ZW1haWw6IGp3dC5lbWFpbH07XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFZlcmlmeSB0aGUgaWRUb2tlbiB1c2luZyBmaXJlYmFzZSBhdXRoLCBjaGVja2luZyBmb3IgdG9rZW4gcmV2b2NhdGlvbnMuXG4gICAgICBjb25zdCBqd3QgPSBhd2FpdCBhdXRoLnZlcmlmeVNlc3Npb25Db29raWUoc2Vzc2lvbkNvb2tpZSwgdHJ1ZSk7XG4gICAgICBpZiAoaXNFeHBpcmVkKGp3dCkpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3Nlc3Npb24gZmFpbGVkOiB0b2tlbiBpcyBleHBpcmVkJyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gVmVyaWZ5IHVzZXIncyBlbWFpbCBpcyB2ZXJpZmllZC5cbiAgICAgIGlmICghand0LmVtYWlsIHx8ICFqd3QuZW1haWxfdmVyaWZpZWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3Nlc3Npb24gZmFpbGVkOiBlbWFpbCBub3QgdmVyaWZpZWQnKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICAvLyBDaGVjayB3aGV0aGVyIHVzZXIgaXMgYXV0aG9yaXplZC5cbiAgICAgIGlmIChvcHRpb25zLmlzVXNlckF1dGhvcml6ZWQpIHtcbiAgICAgICAgY29uc3QgYXV0aG9yaXplZCA9IGF3YWl0IG9wdGlvbnMuaXNVc2VyQXV0aG9yaXplZChyZXEsIHtcbiAgICAgICAgICBlbWFpbDogand0LmVtYWlsISxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghYXV0aG9yaXplZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogbm90IGF1dGhvcml6ZWQnKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gVmVyaWZ5IHRoZSB1c2VyIGV4aXN0cyBpbiB0aGUgREIncyBBQ0wgbGlzdC5cbiAgICAgIGNvbnN0IGNtc0NsaWVudCA9IG5ldyBSb290Q01TQ2xpZW50KHJlcS5yb290Q29uZmlnISk7XG4gICAgICBjb25zdCB1c2VySGFzQWNjZXNzID0gYXdhaXQgY21zQ2xpZW50LnVzZXJFeGlzdHNJbkFjbChqd3QuZW1haWwpO1xuICAgICAgaWYgKCF1c2VySGFzQWNjZXNzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdzZXNzaW9uIGZhaWxlZDogdXNlciBpcyBub3QgaW4gdGhlIGZpcmVzdG9yZSBhY2wgbGlzdCcpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIEpXVCB2ZXJpZmllZC5cbiAgICAgIHJldHVybiB7ZW1haWw6IGp3dC5lbWFpbCF9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignZmFpbGVkIHRvIHZlcmlmeSBqd3QgdG9rZW4nKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3Jvb3QtY21zJyxcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGNvbmZpZyBvcHRpb25zIHBhc3NlZCB0byB0aGUgcGx1Z2luLlxuICAgICAqL1xuICAgIGdldENvbmZpZzogKCkgPT4ge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEZpcmViYXNlIEFwcCBpbnN0YW5jZSB1c2VkIGJ5IHRoZSBwbHVnaW4uXG4gICAgICovXG4gICAgZ2V0RmlyZWJhc2VBcHA6ICgpID0+IHtcbiAgICAgIHJldHVybiBhcHA7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgbWFwIG9mIHNzciBmaWxlcyB0byBpbmNsdWRlIHdoZW4gcnVubmluZyBgcm9vdCBidWlsZGAuXG4gICAgICovXG4gICAgc3NySW5wdXQ6ICgpID0+ICh7XG4gICAgICBjbXM6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2FwcC5qcycpLFxuICAgIH0pLFxuXG4gICAgLyoqXG4gICAgICogQXR0YWNoZXMgQ01TLXNwZWNpZmljIG1pZGRsZXdhcmUgdG8gdGhlIFJvb3QuanMgc2VydmVyLlxuICAgICAqL1xuICAgIGNvbmZpZ3VyZVNlcnZlcjogYXN5bmMgKFxuICAgICAgc2VydmVyOiBTZXJ2ZXIsXG4gICAgICBzZXJ2ZXJPcHRpb25zOiBDb25maWd1cmVTZXJ2ZXJPcHRpb25zXG4gICAgKSA9PiB7XG4gICAgICBzZXJ2ZXIudXNlKGJvZHlQYXJzZXIuanNvbigpKTtcblxuICAgICAgYXN5bmMgZnVuY3Rpb24gZ2V0UmVuZGVyZXIocmVxOiBSZXF1ZXN0KTogUHJvbWlzZTxBcHBNb2R1bGU+IHtcbiAgICAgICAgaWYgKHNlcnZlck9wdGlvbnMudHlwZSA9PT0gJ2RldicpIHtcbiAgICAgICAgICBjb25zdCBhcHBGaWxlUGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2FwcC5qcycpO1xuICAgICAgICAgIGNvbnN0IGFwcCA9IChhd2FpdCByZXEudml0ZVNlcnZlciEuc3NyTG9hZE1vZHVsZShcbiAgICAgICAgICAgIGFwcEZpbGVQYXRoXG4gICAgICAgICAgKSkgYXMgQXBwTW9kdWxlO1xuICAgICAgICAgIHJldHVybiBhcHA7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcHBJbXBvcnRQYXRoID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHJlcS5yb290Q29uZmlnIS5yb290RGlyLFxuICAgICAgICAgICdkaXN0L3NlcnZlci9jbXMuanMnXG4gICAgICAgICk7XG4gICAgICAgIGlmICghKGF3YWl0IGZpbGVFeGlzdHMoYXBwSW1wb3J0UGF0aCkpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ2Rpc3Qvc2VydmVyL2Ntcy5qcyBub3QgZm91bmQuIHJ1biBgcm9vdCBidWlsZGAgdG8gY3JlYXRlIGl0LidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwcCA9IChhd2FpdCBpbXBvcnQoYXBwSW1wb3J0UGF0aCkpIGFzIEFwcE1vZHVsZTtcbiAgICAgICAgcmV0dXJuIGFwcDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdGljRGlyID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJ3VpJyk7XG4gICAgICBzZXJ2ZXIudXNlKCcvY21zL3N0YXRpYycsIHNpcnYoc3RhdGljRGlyLCB7ZGV2OiBmYWxzZX0pKTtcblxuICAgICAgLy8gTG9naW4gaGFuZGxlci5cbiAgICAgIHNlcnZlci51c2UoJy9jbXMvbG9naW4nLCBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXEubWV0aG9kID09PSAnUFVUJyAmJlxuICAgICAgICAgIHJlcS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7YXV0aG9yaXplZCwgcmVhc29ufSA9IGF3YWl0IHZlcmlmeVVzZXJMb2dpbihyZXEpO1xuICAgICAgICAgICAgaWYgKCFhdXRob3JpemVkKSB7XG4gICAgICAgICAgICAgIHJlc1xuICAgICAgICAgICAgICAgIC5zdGF0dXMoNDAxKVxuICAgICAgICAgICAgICAgIC5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdOT1RfQVVUSE9SSVpFRCcsIHJlYXNvbn0pO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCBzZXNzaW9uIGV4cGlyYXRpb24gdG8gNSBkYXlzLlxuICAgICAgICAgICAgY29uc3QgZXhwaXJlc0luID0gNjAgKiA2MCAqIDI0ICogNSAqIDEwMDA7XG4gICAgICAgICAgICBjb25zdCBpZFRva2VuID0gcmVxLmJvZHkuaWRUb2tlbiE7XG5cbiAgICAgICAgICAgIGxldCBzZXNzaW9uQ29va2llOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCcpIHtcbiAgICAgICAgICAgICAgc2Vzc2lvbkNvb2tpZSA9IGlkVG9rZW47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzZXNzaW9uQ29va2llID0gYXdhaXQgYXV0aC5jcmVhdGVTZXNzaW9uQ29va2llKGlkVG9rZW4sIHtcbiAgICAgICAgICAgICAgICBleHBpcmVzSW4sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLnNlc3Npb24uc2V0SXRlbShTRVNTSU9OX0NPT0tJRV9BVVRILCBzZXNzaW9uQ29va2llKTtcbiAgICAgICAgICAgIHJlcy5zYXZlU2Vzc2lvbigpO1xuICAgICAgICAgICAgcmVzLmpzb24oe3N1Y2Nlc3M6IHRydWV9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIuc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzXG4gICAgICAgICAgICAgIC5zdGF0dXMoNTAwKVxuICAgICAgICAgICAgICAuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnVU5LTk9XTl9TRVJWRVJfRVJST1InfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYXBwID0gYXdhaXQgZ2V0UmVuZGVyZXIocmVxKTtcbiAgICAgICAgICBhcHAucmVuZGVyU2lnbkluKHJlcSwgcmVzLCBvcHRpb25zKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyLnN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJ1VOS05PV04gU0VSVkVSIEVSUk9SJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBMb2dvdXQgaGFuZGxlci5cbiAgICAgIHNlcnZlci51c2UoJy9jbXMvbG9nb3V0JywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICByZXMuc2Vzc2lvbi5yZW1vdmVJdGVtKFNFU1NJT05fQ09PS0lFX0FVVEgpO1xuICAgICAgICByZXMuc2F2ZVNlc3Npb24oKTtcbiAgICAgICAgcmVzLnJlZGlyZWN0KCcvY21zL2xvZ2luJyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSW5qZWN0IHRoZSBjdXJyZW50IHVzZXIgaW50byB0aGUgcmVxIG9iamVjdCBhbmQgY2hlY2sgaWYgbG9naW4gaXNcbiAgICAgIC8vIHJlcXVpcmVkLCBzZW5kaW5nIHVuYXV0aGVudGljYXRlZCB1c2VycyB0byB0aGUgbG9naW4gcGFnZS5cbiAgICAgIHNlcnZlci51c2UoYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBnZXRDdXJyZW50VXNlcihyZXEpO1xuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgIHJlcS51c2VyID0gdXNlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIG5vIHVzZXIgYW5kIGxvZ2luIGlzIHJlcXVpcmVkIGZvciB0aGUgZ2l2ZW4gcGF0aCwgcmVkaXJlY3QgdG8gdGhlXG4gICAgICAgIC8vIGxvZ2luIHBhZ2UuXG4gICAgICAgIGlmICghdXNlciAmJiBsb2dpblJlcXVpcmVkKHJlcSkpIHtcbiAgICAgICAgICBpZiAocmVxLm9yaWdpbmFsVXJsLnN0YXJ0c1dpdGgoJy9jbXMvYXBpJykpIHtcbiAgICAgICAgICAgIHJlcy5zdGF0dXMoNDAxKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdOT1RfQVVUSE9SSVpFRCd9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc29sZS5sb2coJ3JlZGlyZWN0aW5nIHRvIGxvZ2luIHBhZ2UnKTtcbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgICAgICAgIGNvbnRpbnVlOiByZXEub3JpZ2luYWxVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzLnJlZGlyZWN0KGAvY21zL2xvZ2luPyR7cGFyYW1zLnRvU3RyaW5nKCl9YCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV4dCgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFJlZ2lzdGVyIEFQSSBoYW5kbGVycy5cbiAgICAgIGFwaShzZXJ2ZXIpO1xuXG4gICAgICAvLyBSZW5kZXIgdGhlIENNUyBTUEEuXG4gICAgICBzZXJ2ZXIudXNlKCcvY21zJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGFwcCA9IGF3YWl0IGdldFJlbmRlcmVyKHJlcSk7XG4gICAgICAgICAgYXdhaXQgYXBwLnJlbmRlckFwcChyZXEsIHJlcywge1xuICAgICAgICAgICAgcm9vdENvbmZpZzogcmVxLnJvb3RDb25maWcsXG4gICAgICAgICAgICBjbXNDb25maWc6IG9wdGlvbnMsXG4gICAgICAgICAgICBmaXJlYmFzZUNvbmZpZzogb3B0aW9ucy5maXJlYmFzZUNvbmZpZyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy8gVE9ETyhzdGV2ZW5sZSk6IHJlbmRlciBhIGN1c3RvbSBlcnJvciBwYWdlLlxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICByZXMuc3RhdHVzKDUwMCkuc2VuZCgnVU5LTk9XTiBTRVJWRVIgRVJST1InKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmlsZUV4aXN0cyhmaWxlcGF0aDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHJldHVybiBmc1xuICAgIC5hY2Nlc3MoZmlsZXBhdGgpXG4gICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAuY2F0Y2goKCkgPT4gZmFsc2UpO1xufVxuIiwgImltcG9ydCB7U2VydmVyLCBSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCB7bXVsdGlwYXJ0TWlkZGxld2FyZX0gZnJvbSAnQGJsaW5ray9yb290L21pZGRsZXdhcmUnO1xuaW1wb3J0IHtSb290Q01TQ2xpZW50fSBmcm9tICcuL2NsaWVudC5qcyc7XG5pbXBvcnQge3J1bkNyb25Kb2JzfSBmcm9tICcuL2Nyb24uanMnO1xuaW1wb3J0IHthcnJheVRvQ3N2LCBjc3ZUb0FycmF5fSBmcm9tICcuL2Nzdi5qcyc7XG5cbi8qKlxuICogUmVnaXN0ZXJzIEFQSSBtaWRkbGV3YXJlIGhhbmRsZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBpKHNlcnZlcjogU2VydmVyKSB7XG4gIC8qKlxuICAgKiBSdW5zIENNUyBjcm9uIGpvYnMuXG4gICAqL1xuICBzZXJ2ZXIudXNlKCcvY21zL2FwaS9jcm9uLnJ1bicsIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcnVuQ3JvbkpvYnMocmVxLnJvb3RDb25maWchKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7c3VjY2VzczogZmFsc2V9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBBY2NlcHRzIGEgSlNPTiBvYmplY3QgY29udGFpbmluZyB7aGVhZGVyczogWy4uLl0sIHJvd3M6IFsuLi5dfSBhbmQgc2VuZHNcbiAgICogYW4gSFRUUCByZXNwb25zZSB3aXRoIGEgY29ycmVzcG9uZGluZyBDU1YgZmlsZSBhcyBhbiBhdHRhY2htZW50LlxuICAgKlxuICAgKiBTYW1wbGUgcmVxdWVzdDpcbiAgICpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJoZWFkZXJzXCI6IFtcImZvb1wiXSxcbiAgICogICBcInJvd3NcIjogW1xuICAgKiAgICAge1wiZm9vXCI6IFwiYmFyXCJ9LFxuICAgKiAgICAge1wiZm9vXCI6IFwiYmF6XCJ9LFxuICAgKiAgIF1cbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIHNlcnZlci51c2UoJy9jbXMvYXBpL2Nzdi5kb3dubG9hZCcsIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICBpZiAoXG4gICAgICByZXEubWV0aG9kICE9PSAnUE9TVCcgfHxcbiAgICAgICFTdHJpbmcocmVxLmdldCgnY29udGVudC10eXBlJykpLnN0YXJ0c1dpdGgoJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICkge1xuICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ0JBRF9SRVFVRVNUJ30pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBib2R5ID0gcmVxLmJvZHkgfHwge307XG4gICAgICBjb25zdCBoZWFkZXJzID0gYm9keS5oZWFkZXJzIHx8IFtdO1xuICAgICAgY29uc3Qgcm93cyA9IGJvZHkucm93cyB8fCBbXTtcbiAgICAgIGNvbnN0IGNzdiA9IGFycmF5VG9Dc3Yoe2hlYWRlcnMsIHJvd3N9KTtcbiAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2NzdicpO1xuICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbicsICdhdHRhY2htZW50OyBmaWxlbmFtZT1cImRhdGEuY3N2XCInKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5lbmQoY3N2KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyLnN0YWNrIHx8IGVycik7XG4gICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnVU5LTk9XTid9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGEgQ1NWIGZpbGUgYW5kIHJldHVybnMgYSBKU09OIGFycmF5IG9mIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZVxuICAgKiBDU1YuXG4gICAqXG4gICAqIFNhbXBsZSByZXNwb25zZTpcbiAgICpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJzdWNjZXNzXCI6IHRydWUsXG4gICAqICAgXCJkYXRhXCI6IFtcbiAgICogICAgIHtcImZvb1wiOiBcImJhclwifSxcbiAgICogICAgIHtcImZvb1wiOiBcImJhelwifSxcbiAgICogICBdXG4gICAqIH1cbiAgICogYGBgXG4gICAqL1xuICBzZXJ2ZXIudXNlKFxuICAgICcvY21zL2FwaS9jc3YuaW1wb3J0JyxcbiAgICBtdWx0aXBhcnRNaWRkbGV3YXJlKCksXG4gICAgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgaWYgKHJlcS5tZXRob2QgIT09ICdQT1NUJyB8fCAhcmVxLmZpbGVzIHx8ICFyZXEuZmlsZXMuZmlsZSkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnQkFEX1JFUVVFU1QnfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZmlsZSA9IHJlcS5maWxlcy5maWxlO1xuICAgICAgICBjb25zdCBjc3ZTdHJpbmcgPSBmaWxlLmJ1ZmZlci50b1N0cmluZygndXRmOCcpO1xuICAgICAgICBjb25zdCByb3dzID0gY3N2VG9BcnJheShjc3ZTdHJpbmcpO1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcm93c30pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyLnN0YWNrIHx8IGVycik7XG4gICAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdVTktOT1dOJ30pO1xuICAgICAgfVxuICAgIH1cbiAgKTtcblxuICAvKipcbiAgICogUnVucyBhIGRhdGEgc291cmNlIHN5bmMuXG4gICAqL1xuICBzZXJ2ZXIudXNlKCcvY21zL2FwaS9kYXRhLnN5bmMnLCBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgaWYgKFxuICAgICAgcmVxLm1ldGhvZCAhPT0gJ1BPU1QnIHx8XG4gICAgICAhU3RyaW5nKHJlcS5nZXQoJ2NvbnRlbnQtdHlwZScpKS5zdGFydHNXaXRoKCdhcHBsaWNhdGlvbi9qc29uJylcbiAgICApIHtcbiAgICAgIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgZXJyb3I6ICdCQURfUkVRVUVTVCd9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXJlcS51c2VyPy5lbWFpbCkge1xuICAgICAgcmVzLnN0YXR1cyg0MDEpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ1VOQVVUSE9SSVpFRCd9KTtcbiAgICB9XG5cbiAgICBjb25zdCByZXFCb2R5ID0gcmVxLmJvZHkgfHwge307XG4gICAgY29uc3QgZGF0YVNvdXJjZUlkID0gcmVxQm9keS5pZDtcbiAgICBpZiAoIWRhdGFTb3VyY2VJZCkge1xuICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogJ01JU1NJTkdfSUQnfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNtc0NsaWVudCA9IG5ldyBSb290Q01TQ2xpZW50KHJlcS5yb290Q29uZmlnKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY21zQ2xpZW50LnN5bmNEYXRhU291cmNlKGRhdGFTb3VyY2VJZCwge3N5bmNlZEJ5OiByZXEudXNlci5lbWFpbH0pO1xuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGlkOiBkYXRhU291cmNlSWR9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyLnN0YWNrIHx8IGVycik7XG4gICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIGVycm9yOiAnVU5LTk9XTid9KTtcbiAgICB9XG4gIH0pO1xufVxuIiwgImltcG9ydCBjcnlwdG8gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtQbHVnaW4sIFJvb3RDb25maWd9IGZyb20gJ0BibGlua2svcm9vdCc7XG5pbXBvcnQge0FwcH0gZnJvbSAnZmlyZWJhc2UtYWRtaW4vYXBwJztcbmltcG9ydCB7XG4gIEZpZWxkVmFsdWUsXG4gIEZpcmVzdG9yZSxcbiAgUXVlcnksXG4gIFRpbWVzdGFtcCxcbiAgV3JpdGVCYXRjaCxcbiAgZ2V0RmlyZXN0b3JlLFxufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9maXJlc3RvcmUnO1xuaW1wb3J0IHtDTVNQbHVnaW59IGZyb20gJy4vcGx1Z2luLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBEb2M8RmllbGRzID0gYW55PiB7XG4gIC8qKiBUaGUgaWQgb2YgdGhlIGRvYywgZS5nLiBcIlBhZ2VzL2Zvby1iYXJcIi4gKi9cbiAgaWQ6IHN0cmluZztcbiAgLyoqIFRoZSBjb2xsZWN0aW9uIGlkIG9mIHRoZSBkb2MsIGUuZy4gXCJQYWdlc1wiLiAqL1xuICBjb2xsZWN0aW9uOiBzdHJpbmc7XG4gIC8qKiBUaGUgc2x1ZyBvZiB0aGUgZG9jLCBlLmcuIFwiZm9vLWJhclwiLiAqL1xuICBzbHVnOiBzdHJpbmc7XG4gIHN5czoge1xuICAgIGNyZWF0ZWRBdDogbnVtYmVyO1xuICAgIGNyZWF0ZWRCeTogc3RyaW5nO1xuICAgIG1vZGlmaWVkQXQ6IG51bWJlcjtcbiAgICBtb2RpZmllZEJ5OiBzdHJpbmc7XG4gICAgZmlyc3RQdWJsaXNoZWRBdD86IG51bWJlcjtcbiAgICBmaXJzdFB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xuICAgIHB1Ymxpc2hlZEF0PzogbnVtYmVyO1xuICAgIHB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xuICAgIGxvY2FsZXM/OiBzdHJpbmdbXTtcbiAgfTtcbiAgZmllbGRzOiBGaWVsZHM7XG59XG5cbmV4cG9ydCB0eXBlIERvY01vZGUgPSAnZHJhZnQnIHwgJ3B1Ymxpc2hlZCc7XG5cbmV4cG9ydCB0eXBlIEh0dHBNZXRob2QgPSAnR0VUJyB8ICdQT1NUJztcblxuZXhwb3J0IGludGVyZmFjZSBEYXRhU291cmNlIHtcbiAgaWQ6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIHR5cGU6ICdodHRwJyB8ICdnc2hlZXQnO1xuICB1cmw6IHN0cmluZztcbiAgLyoqXG4gICAqIEN1cnJlbnRseSBvbmx5IHVzZWQgYnkgZ3NoZWV0LiBgYXJyYXlgIHJldHVybnMgdGhlIHNoZWV0IGFzIGFuIGFycmF5IG9mXG4gICAqIGFycmF5cywgYG1hcGAgcmV0dXJucyB0aGUgc2hlZXQgYXMgYW4gYXJyYXkgb2Ygb2JqZWN0cy5cbiAgICovXG4gIGRhdGFGb3JtYXQ/OiAnYXJyYXknIHwgJ21hcCc7XG4gIC8qKlxuICAgKiBPcHRpb25zIGZvciBIVFRQIHJlcXVlc3RzLlxuICAgKi9cbiAgaHR0cE9wdGlvbnM/OiB7XG4gICAgbWV0aG9kOiBIdHRwTWV0aG9kO1xuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgIGJvZHk/OiBzdHJpbmc7XG4gIH07XG4gIGNyZWF0ZWRBdDogVGltZXN0YW1wO1xuICBjcmVhdGVkQnk6IHN0cmluZztcbiAgc3luY2VkQXQ/OiBUaW1lc3RhbXA7XG4gIHN5bmNlZEJ5Pzogc3RyaW5nO1xuICBwdWJsaXNoZWRBdD86IFRpbWVzdGFtcDtcbiAgcHVibGlzaGVkQnk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YVNvdXJjZURhdGE8VCA9IGFueT4ge1xuICBkYXRhU291cmNlOiBEYXRhU291cmNlO1xuICBkYXRhOiBUO1xufVxuXG5leHBvcnQgdHlwZSBEYXRhU291cmNlTW9kZSA9ICdkcmFmdCcgfCAncHVibGlzaGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBHZXREb2NPcHRpb25zIHtcbiAgLyoqIE1vZGUsIGVpdGhlciBcImRyYWZ0XCIgb3IgXCJwdWJsaXNoZWRcIi4gKi9cbiAgbW9kZTogRG9jTW9kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXREb2NPcHRpb25zIHtcbiAgLyoqIE1vZGUsIGVpdGhlciBcImRyYWZ0XCIgb3IgXCJwdWJsaXNoZWRcIi4gKi9cbiAgbW9kZTogRG9jTW9kZTtcbiAgLyoqXG4gICAqIEVtYWlsIG9mIHVzZXIgbW9kaWZ5aW5nIHRoZSBkb2MuIElmIGJsYW5rLCBkZWZhdWx0cyB0byBgcm9vdC1jbXMtY2xpZW50YC5cbiAgICovXG4gIG1vZGlmaWVkQnk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdERvY3NPcHRpb25zIHtcbiAgbW9kZTogRG9jTW9kZTtcbiAgb2Zmc2V0PzogbnVtYmVyO1xuICBsaW1pdD86IG51bWJlcjtcbiAgb3JkZXJCeT86IHN0cmluZztcbiAgb3JkZXJCeURpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xuICBxdWVyeT86IChxdWVyeTogUXVlcnkpID0+IFF1ZXJ5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdldENvdW50T3B0aW9ucyB7XG4gIG1vZGU6IERvY01vZGU7XG4gIHF1ZXJ5PzogKHF1ZXJ5OiBRdWVyeSkgPT4gUXVlcnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNsYXRpb24ge1xuICBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmc7XG4gIHNvdXJjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uc01hcCB7XG4gIFtoYXNoOiBzdHJpbmddOiBUcmFuc2xhdGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2NhbGVUcmFuc2xhdGlvbnMge1xuICBbc291cmNlOiBzdHJpbmddOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZFRyYW5zbGF0aW9uc09wdGlvbnMge1xuICB0YWdzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVsZWFzZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBkb2NJZHM/OiBzdHJpbmdbXTtcbiAgY3JlYXRlZEF0PzogVGltZXN0YW1wO1xuICBjcmVhdGVkQnk/OiBzdHJpbmc7XG4gIHNjaGVkdWxlZEF0PzogVGltZXN0YW1wO1xuICBzY2hlZHVsZWRCeT86IHN0cmluZztcbiAgcHVibGlzaGVkQXQ/OiBUaW1lc3RhbXA7XG4gIHB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgUm9vdENNU0NsaWVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdENvbmZpZzogUm9vdENvbmZpZztcbiAgcHJpdmF0ZSByZWFkb25seSBjbXNQbHVnaW46IENNU1BsdWdpbjtcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9qZWN0SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IEFwcDtcbiAgcHJpdmF0ZSByZWFkb25seSBkYjogRmlyZXN0b3JlO1xuXG4gIGNvbnN0cnVjdG9yKHJvb3RDb25maWc6IFJvb3RDb25maWcpIHtcbiAgICB0aGlzLnJvb3RDb25maWcgPSByb290Q29uZmlnO1xuICAgIHRoaXMuY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHRoaXMucm9vdENvbmZpZyk7XG5cbiAgICBjb25zdCBjbXNQbHVnaW5PcHRpb25zID0gdGhpcy5jbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5wcm9qZWN0SWQgPSBjbXNQbHVnaW5PcHRpb25zLmlkIHx8ICdkZWZhdWx0JztcbiAgICB0aGlzLmFwcCA9IHRoaXMuY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gICAgdGhpcy5kYiA9IGdldEZpcmVzdG9yZSh0aGlzLmFwcCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGRvYyBkYXRhIGZyb20gUm9vdC5qcyBDTVMuXG4gICAqL1xuICBhc3luYyBnZXREb2M8RmllbGRzID0gYW55PihcbiAgICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgICBzbHVnOiBzdHJpbmcsXG4gICAgb3B0aW9uczogR2V0RG9jT3B0aW9uc1xuICApOiBQcm9taXNlPERvYzxGaWVsZHM+IHwgbnVsbD4ge1xuICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCB0aGlzLmdldFJhd0RvYyhjb2xsZWN0aW9uSWQsIHNsdWcsIG9wdGlvbnMpO1xuICAgIGlmIChyYXdEYXRhKSB7XG4gICAgICByZXR1cm4gdW5tYXJzaGFsRGF0YShyYXdEYXRhKSBhcyBEb2M8RmllbGRzPjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHJhdyBkb2MgZGF0YSBhcyBzdG9yZWQgaW4gdGhlIGRhdGFiYXNlLiBPbmx5IHVzZSB0aGlzIGlmIHlvdSBrbm93XG4gICAqIHdoYXQgeW91IGFyZSBkb2luZy5cbiAgICovXG4gIGFzeW5jIGdldFJhd0RvYyhcbiAgICBjb2xsZWN0aW9uSWQ6IHN0cmluZyxcbiAgICBzbHVnOiBzdHJpbmcsXG4gICAgb3B0aW9uczogR2V0RG9jT3B0aW9uc1xuICApOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgLy8gU2x1Z3Mgd2l0aCBzbGFzaGVzIGFyZSBlbmNvZGVkIGFzIGAtLWAgaW4gdGhlIERCLlxuICAgIHNsdWcgPSBzbHVnLnJlcGxhY2VBbGwoJy8nLCAnLS0nKTtcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgIGNvbnN0IGRvY1JlZiA9IHRoaXMuZGIuZG9jKGRiUGF0aCk7XG4gICAgY29uc3QgZG9jID0gYXdhaXQgZG9jUmVmLmdldCgpO1xuICAgIGlmIChkb2MuZXhpc3RzKSB7XG4gICAgICByZXR1cm4gZG9jLmRhdGEoKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBhc3luYyBzZXRSYXdEb2MoXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgc2x1Zzogc3RyaW5nLFxuICAgIGRhdGE6IGFueSxcbiAgICBvcHRpb25zOiBTZXREb2NPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGU7XG4gICAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgIGNvbnN0IGRvY1JlZiA9IHRoaXMuZGIuZG9jKGRiUGF0aCk7XG4gICAgYXdhaXQgZG9jUmVmLnNldChkYXRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyBkb2NzIGZyb20gYSBSb290LmpzIENNUyBjb2xsZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgbGlzdERvY3M8VD4oXG4gICAgY29sbGVjdGlvbklkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogTGlzdERvY3NPcHRpb25zXG4gICk6IFByb21pc2U8e2RvY3M6IFRbXX0+IHtcbiAgICBjb25zdCBtb2RlID0gb3B0aW9ucy5tb2RlO1xuICAgIGNvbnN0IG1vZGVDb2xsZWN0aW9uID0gbW9kZSA9PT0gJ2RyYWZ0JyA/ICdEcmFmdHMnIDogJ1B1Ymxpc2hlZCc7XG4gICAgY29uc3QgZGJQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0NvbGxlY3Rpb25zLyR7Y29sbGVjdGlvbklkfS8ke21vZGVDb2xsZWN0aW9ufWA7XG4gICAgbGV0IHF1ZXJ5OiBRdWVyeSA9IHRoaXMuZGIuY29sbGVjdGlvbihkYlBhdGgpO1xuICAgIGlmIChvcHRpb25zLmxpbWl0KSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5LmxpbWl0KG9wdGlvbnMubGltaXQpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5vZmZzZXQpIHtcbiAgICAgIHF1ZXJ5ID0gcXVlcnkub2Zmc2V0KG9wdGlvbnMub2Zmc2V0KTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMub3JkZXJCeSkge1xuICAgICAgcXVlcnkgPSBxdWVyeS5vcmRlckJ5KG9wdGlvbnMub3JkZXJCeSwgb3B0aW9ucy5vcmRlckJ5RGlyZWN0aW9uKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeShxdWVyeSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBxdWVyeS5nZXQoKTtcbiAgICBjb25zdCBkb2NzOiBUW10gPSBbXTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCkgPT4ge1xuICAgICAgY29uc3QgZG9jID0gdW5tYXJzaGFsRGF0YShyZXN1bHQuZGF0YSgpKSBhcyBUO1xuICAgICAgZG9jcy5wdXNoKGRvYyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtkb2NzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZG9jcyBpbiBhIFJvb3QuanMgQ01TIGNvbGxlY3Rpb24uXG4gICAqL1xuICBhc3luYyBnZXREb2NzQ291bnQoY29sbGVjdGlvbklkOiBzdHJpbmcsIG9wdGlvbnM6IEdldENvdW50T3B0aW9ucykge1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGU7XG4gICAgY29uc3QgbW9kZUNvbGxlY3Rpb24gPSBtb2RlID09PSAnZHJhZnQnID8gJ0RyYWZ0cycgOiAnUHVibGlzaGVkJztcbiAgICBjb25zdCBkYlBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9LyR7bW9kZUNvbGxlY3Rpb259YDtcbiAgICBsZXQgcXVlcnk6IFF1ZXJ5ID0gdGhpcy5kYi5jb2xsZWN0aW9uKGRiUGF0aCk7XG4gICAgaWYgKG9wdGlvbnMucXVlcnkpIHtcbiAgICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeShxdWVyeSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBxdWVyeS5jb3VudCgpLmdldCgpO1xuICAgIGNvbnN0IGNvdW50ID0gcmVzdWx0cy5kYXRhKCkuY291bnQ7XG4gICAgcmV0dXJuIGNvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJhdGNoIHB1Ymxpc2hlcyBhIHNldCBvZiBkb2NzIGJ5IGlkLlxuICAgKi9cbiAgYXN5bmMgcHVibGlzaERvY3MoXG4gICAgZG9jSWRzOiBzdHJpbmdbXSxcbiAgICBvcHRpb25zPzoge3B1Ymxpc2hlZEJ5OiBzdHJpbmc7IGJhdGNoPzogV3JpdGVCYXRjaH1cbiAgKSB7XG4gICAgY29uc3QgcHJvamVjdENvbGxlY3Rpb25zUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9Db2xsZWN0aW9uc2A7XG4gICAgY29uc3QgcHVibGlzaGVkQnkgPSBvcHRpb25zPy5wdWJsaXNoZWRCeSB8fCAncm9vdC1jbXMtY2xpZW50JztcblxuICAgIC8vIEZldGNoIHRoZSBjdXJyZW50IGRyYWZ0IGRhdGEgZm9yIGVhY2ggZG9jLlxuICAgIGNvbnN0IGRvY1JlZnMgPSBkb2NJZHMubWFwKChkb2NJZCkgPT4ge1xuICAgICAgY29uc3QgW2NvbGxlY3Rpb24sIHNsdWddID0gZG9jSWQuc3BsaXQoJy8nKTtcbiAgICAgIGlmICghY29sbGVjdGlvbiB8fCAhc2x1Zykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZG9jIGlkOiAke2RvY0lkfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgZG9jUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vRHJhZnRzLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgcmV0dXJuIGRvY1JlZjtcbiAgICB9KTtcbiAgICBjb25zdCBkb2NTbmFwc2hvdHMgPSBhd2FpdCB0aGlzLmRiLmdldEFsbCguLi5kb2NSZWZzKTtcbiAgICBjb25zdCBkb2NzID0gZG9jU25hcHNob3RzXG4gICAgICAvLyBSZXRyaWV2ZSBzbmFwc2hvdCBkYXRhIGZvciBlYWNoIGRvYy5cbiAgICAgIC5tYXAoKHNuYXBzaG90KSA9PiBzbmFwc2hvdC5kYXRhKCkgYXMgRG9jKVxuICAgICAgLy8gUmVtb3ZlIGRvY3MgdGhhdCBkb24ndCBleGlzdC5cbiAgICAgIC5maWx0ZXIoKGQpID0+ICEhZCk7XG5cbiAgICBpZiAoZG9jcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdubyBkb2NzIHRvIHB1Ymxpc2gnKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvLyAvLyBFYWNoIHRyYW5zYWN0aW9uIG9yIGJhdGNoIGNhbiB3cml0ZSBhIG1heCBvZiA1MDAgb3BzLlxuICAgIC8vIC8vIGh0dHBzOi8vZmlyZWJhc2UuZ29vZ2xlLmNvbS9kb2NzL2ZpcmVzdG9yZS9tYW5hZ2UtZGF0YS90cmFuc2FjdGlvbnNcbiAgICBsZXQgYmF0Y2hDb3VudCA9IDA7XG4gICAgY29uc3QgYmF0Y2ggPSBvcHRpb25zPy5iYXRjaCB8fCB0aGlzLmRiLmJhdGNoKCk7XG4gICAgY29uc3QgcHVibGlzaGVkRG9jczogYW55W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGRvYyBvZiBkb2NzKSB7XG4gICAgICBjb25zdCB7aWQsIGNvbGxlY3Rpb24sIHNsdWcsIHN5cywgZmllbGRzfSA9IGRvYztcbiAgICAgIGNvbnN0IGRyYWZ0UmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vRHJhZnRzLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgY29uc3Qgc2NoZWR1bGVkUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vU2NoZWR1bGVkLyR7c2x1Z31gXG4gICAgICApO1xuICAgICAgY29uc3QgcHVibGlzaGVkUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICAgIGAke3Byb2plY3RDb2xsZWN0aW9uc1BhdGh9LyR7Y29sbGVjdGlvbn0vUHVibGlzaGVkLyR7c2x1Z31gXG4gICAgICApO1xuXG4gICAgICAvLyBPbmx5IHVwZGF0ZSBgZmlyc3RQdWJsaXNoZWRgIGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC5cbiAgICAgIGNvbnN0IGZpcnN0UHVibGlzaGVkQXQgPVxuICAgICAgICBzeXMuZmlyc3RQdWJsaXNoZWRBdCA/PyBGaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpO1xuICAgICAgY29uc3QgZmlyc3RQdWJsaXNoZWRCeSA9IHN5cy5maXJzdFB1Ymxpc2hlZEJ5ID8/IHB1Ymxpc2hlZEJ5O1xuXG4gICAgICAvLyBTYXZlIHB1Ymxpc2hlZCBkb2MuXG4gICAgICBiYXRjaC5zZXQocHVibGlzaGVkUmVmLCB7XG4gICAgICAgIGlkLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBzbHVnLFxuICAgICAgICBmaWVsZHM6IGZpZWxkcyB8fCB7fSxcbiAgICAgICAgc3lzOiB7XG4gICAgICAgICAgLi4uc3lzLFxuICAgICAgICAgIGZpcnN0UHVibGlzaGVkQXQ6IGZpcnN0UHVibGlzaGVkQXQsXG4gICAgICAgICAgZmlyc3RQdWJsaXNoZWRCeTogZmlyc3RQdWJsaXNoZWRCeSxcbiAgICAgICAgICBwdWJsaXNoZWRBdDogRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKSxcbiAgICAgICAgICBwdWJsaXNoZWRCeTogcHVibGlzaGVkQnksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgICAgLy8gUmVtb3ZlIHNjaGVkdWxlZCBkb2MsIGlmIGFueS5cbiAgICAgIGJhdGNoLmRlbGV0ZShzY2hlZHVsZWRSZWYpO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgICAvLyBVcGRhdGUgdGhlIGRyYWZ0IGRvYyB0byByZW1vdmUgYHNjaGVkdWxlZEF0YCBhbmQgYHNjaGVkdWxlZEJ5YCBmaWVsZHNcbiAgICAgIC8vIGFuZCB1cGRhdGUgdGhlIGBwdWJsaXNoZWRBdGAgYW5kIGBwdWJsaXNoZWRCeWAgZmllbGRzLlxuICAgICAgYmF0Y2gudXBkYXRlKGRyYWZ0UmVmLCB7XG4gICAgICAgICdzeXMuc2NoZWR1bGVkQXQnOiBGaWVsZFZhbHVlLmRlbGV0ZSgpLFxuICAgICAgICAnc3lzLnNjaGVkdWxlZEJ5JzogRmllbGRWYWx1ZS5kZWxldGUoKSxcbiAgICAgICAgJ3N5cy5maXJzdFB1Ymxpc2hlZEF0JzogZmlyc3RQdWJsaXNoZWRBdCxcbiAgICAgICAgJ3N5cy5maXJzdFB1Ymxpc2hlZEJ5JzogZmlyc3RQdWJsaXNoZWRCeSxcbiAgICAgICAgJ3N5cy5wdWJsaXNoZWRBdCc6IEZpZWxkVmFsdWUuc2VydmVyVGltZXN0YW1wKCksXG4gICAgICAgICdzeXMucHVibGlzaGVkQnknOiBwdWJsaXNoZWRCeSxcbiAgICAgIH0pO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuXG4gICAgICBwdWJsaXNoZWREb2NzLnB1c2goZG9jKTtcblxuICAgICAgaWYgKGJhdGNoQ291bnQgPj0gNDAwKSB7XG4gICAgICAgIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuICAgICAgICBiYXRjaENvdW50ID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYmF0Y2hDb3VudCA+IDApIHtcbiAgICAgIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgcHVibGlzaGVkICR7cHVibGlzaGVkRG9jcy5sZW5ndGh9IGRvY3MhYCk7XG4gICAgcmV0dXJuIHB1Ymxpc2hlZERvY3M7XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaGVzIHNjaGVkdWxlZCBkb2NzLlxuICAgKi9cbiAgYXN5bmMgcHVibGlzaFNjaGVkdWxlZERvY3MoKSB7XG4gICAgY29uc3QgcHJvamVjdENvbGxlY3Rpb25zUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9Db2xsZWN0aW9uc2A7XG4gICAgY29uc3Qgbm93ID0gTWF0aC5jZWlsKG5ldyBEYXRlKCkuZ2V0VGltZSgpKTtcblxuICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgdGhpcy5kYi5jb2xsZWN0aW9uR3JvdXAoJ1NjaGVkdWxlZCcpLmdldCgpO1xuICAgIGNvbnN0IGRvY3MgPSBzbmFwc2hvdC5kb2NzXG4gICAgICAuZmlsdGVyKChkKSA9PiB7XG4gICAgICAgIC8vIEZpbHRlciBkb2NzIGJ5IHByb2plY3QuXG4gICAgICAgIGlmICghZC5yZWYucGF0aC5zdGFydHNXaXRoKHByb2plY3RDb2xsZWN0aW9uc1BhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpbHRlciBkb2NzIHdoZXJlIHNjaGVkdWxlZEF0IGlzIGluIHRoZSBwYXN0LlxuICAgICAgICAvLyBOT1RFKHN0ZXZlbmxlKTogdGhlIGZpbHRlcmluZyBpcyBkb25lIG1hbnVhbGx5IGluc3RlYWQgb2YgdXNpbmcgYSBxdWVyeVxuICAgICAgICAvLyB0byBhdm9pZCBoYXZpbmcgdG8gY3JlYXRlIGFuIGluZGV4IGluIGZpcmVzdG9yZS5cbiAgICAgICAgY29uc3QgZGF0YSA9IGQuZGF0YSgpIHx8IHt9O1xuICAgICAgICBjb25zdCBzY2hlZHVsZWRBdDogVGltZXN0YW1wIHwgdW5kZWZpbmVkID0gZGF0YS5zeXM/LnNjaGVkdWxlZEF0O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHNjaGVkdWxlZEF0ICYmIHNjaGVkdWxlZEF0LnRvTWlsbGlzICYmIHNjaGVkdWxlZEF0LnRvTWlsbGlzKCkgPD0gbm93XG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICAgLm1hcCgoZCkgPT4ge1xuICAgICAgICBjb25zdCBkYlBhdGggPSBkLnJlZi5wYXRoO1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IGRiUGF0aC5zcGxpdCgnLycpO1xuICAgICAgICBjb25zdCBzbHVnID0gc2VnbWVudHMuYXQoLTEpO1xuICAgICAgICBjb25zdCBjb2xsZWN0aW9uID0gc2VnbWVudHMuYXQoLTMpO1xuICAgICAgICBjb25zdCBpZCA9IGAke2NvbGxlY3Rpb259LyR7c2x1Z31gO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRhdGE6IGQuZGF0YSgpLFxuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgICAgc2x1ZyxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKGRvY3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLmxvZygnbm8gZG9jcyB0byBzY2hlZHVsZScpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIEVhY2ggdHJhbnNhY3Rpb24gb3IgYmF0Y2ggY2FuIHdyaXRlIGEgbWF4IG9mIDUwMCBvcHMuXG4gICAgLy8gaHR0cHM6Ly9maXJlYmFzZS5nb29nbGUuY29tL2RvY3MvZmlyZXN0b3JlL21hbmFnZS1kYXRhL3RyYW5zYWN0aW9uc1xuICAgIGxldCBiYXRjaENvdW50ID0gMDtcbiAgICBjb25zdCBiYXRjaCA9IHRoaXMuZGIuYmF0Y2goKTtcbiAgICBjb25zdCBwdWJsaXNoZWREb2NzOiBhbnlbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgZG9jIG9mIGRvY3MpIHtcbiAgICAgIGNvbnN0IHtpZCwgY29sbGVjdGlvbiwgc2x1ZywgZGF0YX0gPSBkb2M7XG4gICAgICBjb25zdCBkcmFmdFJlZiA9IHRoaXMuZGIuZG9jKFxuICAgICAgICBgJHtwcm9qZWN0Q29sbGVjdGlvbnNQYXRofS8ke2NvbGxlY3Rpb259L0RyYWZ0cy8ke3NsdWd9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNjaGVkdWxlZFJlZiA9IHRoaXMuZGIuZG9jKFxuICAgICAgICBgJHtwcm9qZWN0Q29sbGVjdGlvbnNQYXRofS8ke2NvbGxlY3Rpb259L1NjaGVkdWxlZC8ke3NsdWd9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHB1Ymxpc2hlZFJlZiA9IHRoaXMuZGIuZG9jKFxuICAgICAgICBgJHtwcm9qZWN0Q29sbGVjdGlvbnNQYXRofS8ke2NvbGxlY3Rpb259L1B1Ymxpc2hlZC8ke3NsdWd9YFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHtzY2hlZHVsZWRBdCwgc2NoZWR1bGVkQnksIC4uLnN5c30gPSBkYXRhLnN5cyB8fCB7fTtcblxuICAgICAgLy8gT25seSB1cGRhdGUgYGZpcnN0UHVibGlzaGVkYCBpZiBpdCBkb2Vzbid0IGFscmVhZHkgZXhpc3QuXG4gICAgICBjb25zdCBmaXJzdFB1Ymxpc2hlZEF0ID0gc3lzLmZpcnN0UHVibGlzaGVkQXQgPz8gc2NoZWR1bGVkQXQ7XG4gICAgICBjb25zdCBmaXJzdFB1Ymxpc2hlZEJ5ID1cbiAgICAgICAgc3lzLmZpcnN0UHVibGlzaGVkQnkgPz8gKHNjaGVkdWxlZEJ5IHx8ICdyb290LWNtcy1jbGllbnQnKTtcblxuICAgICAgLy8gU2F2ZSBwdWJsaXNoZWQgZG9jLlxuICAgICAgYmF0Y2guc2V0KHB1Ymxpc2hlZFJlZiwge1xuICAgICAgICBpZCxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgc2x1ZyxcbiAgICAgICAgZmllbGRzOiBkYXRhLmZpZWxkcyB8fCB7fSxcbiAgICAgICAgc3lzOiB7XG4gICAgICAgICAgLi4uc3lzLFxuICAgICAgICAgIGZpcnN0UHVibGlzaGVkQXQ6IGZpcnN0UHVibGlzaGVkQXQsXG4gICAgICAgICAgZmlyc3RQdWJsaXNoZWRCeTogZmlyc3RQdWJsaXNoZWRCeSxcbiAgICAgICAgICBwdWJsaXNoZWRBdDogRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKSxcbiAgICAgICAgICBwdWJsaXNoZWRCeTogc2NoZWR1bGVkQnkgfHwgJycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgICAgLy8gUmVtb3ZlIHB1Ymxpc2hlZCBkb2MuXG4gICAgICBiYXRjaC5kZWxldGUoc2NoZWR1bGVkUmVmKTtcbiAgICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgICAgLy8gVXBkYXRlIHRoZSBkcmFmdCBkb2MgdG8gcmVtb3ZlIGBzY2hlZHVsZWRBdGAgYW5kIGBzY2hlZHVsZWRCeWAgZmllbGRzXG4gICAgICAvLyBhbmQgdXBkYXRlIHRoZSBgcHVibGlzaGVkQXRgIGFuZCBgcHVibGlzaGVkQnlgIGZpZWxkcy5cbiAgICAgIGJhdGNoLnVwZGF0ZShkcmFmdFJlZiwge1xuICAgICAgICAnc3lzLnNjaGVkdWxlZEF0JzogRmllbGRWYWx1ZS5kZWxldGUoKSxcbiAgICAgICAgJ3N5cy5zY2hlZHVsZWRCeSc6IEZpZWxkVmFsdWUuZGVsZXRlKCksXG4gICAgICAgICdzeXMuZmlyc3RQdWJsaXNoZWRBdCc6IGZpcnN0UHVibGlzaGVkQXQsXG4gICAgICAgICdzeXMuZmlyc3RQdWJsaXNoZWRCeSc6IGZpcnN0UHVibGlzaGVkQnksXG4gICAgICAgICdzeXMucHVibGlzaGVkQXQnOiBGaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpLFxuICAgICAgICAnc3lzLnB1Ymxpc2hlZEJ5Jzogc2NoZWR1bGVkQnkgfHwgJ3Jvb3QtY21zLWNsaWVudCcsXG4gICAgICB9KTtcbiAgICAgIGJhdGNoQ291bnQgKz0gMTtcblxuICAgICAgcHVibGlzaGVkRG9jcy5wdXNoKGRvYyk7XG5cbiAgICAgIGlmIChiYXRjaENvdW50ID49IDQwMCkge1xuICAgICAgICBhd2FpdCBiYXRjaC5jb21taXQoKTtcbiAgICAgICAgYmF0Y2hDb3VudCA9IDA7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChiYXRjaENvdW50ID4gMCkge1xuICAgICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBwdWJsaXNoZWQgJHtwdWJsaXNoZWREb2NzLmxlbmd0aH0gZG9jcyFgKTtcbiAgICByZXR1cm4gcHVibGlzaGVkRG9jcztcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgZG9jcyBpbiBzY2hlZHVsZWQgcmVsZWFzZXMuXG4gICAqL1xuICBhc3luYyBwdWJsaXNoU2NoZWR1bGVkUmVsZWFzZXMoKSB7XG4gICAgY29uc3QgcmVsZWFzZXNQYXRoID0gYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L1JlbGVhc2VzYDtcbiAgICBjb25zdCBub3cgPSBNYXRoLmNlaWwobmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuICAgIGNvbnN0IHF1ZXJ5OiBRdWVyeSA9IHRoaXMuZGJcbiAgICAgIC5jb2xsZWN0aW9uKHJlbGVhc2VzUGF0aClcbiAgICAgIC53aGVyZSgnc2NoZWR1bGVkQXQnLCAnPD0nLCBUaW1lc3RhbXAuZnJvbU1pbGxpcyhub3cpKTtcbiAgICBjb25zdCBxdWVyeVNuYXBzaG90ID0gYXdhaXQgcXVlcnkuZ2V0KCk7XG5cbiAgICBmb3IgKGNvbnN0IHNuYXBzaG90IG9mIHF1ZXJ5U25hcHNob3QuZG9jcykge1xuICAgICAgY29uc3QgcmVsZWFzZSA9IHNuYXBzaG90LmRhdGEoKSBhcyBSZWxlYXNlO1xuICAgICAgY29uc3QgYmF0Y2ggPSB0aGlzLmRiLmJhdGNoKCk7XG4gICAgICBjb25zdCBwdWJsaXNoZWRCeSA9IHJlbGVhc2Uuc2NoZWR1bGVkQnkgfHwgJ3Jvb3QtY21zLWNsaWVudCc7XG4gICAgICBiYXRjaC51cGRhdGUoc25hcHNob3QucmVmLCB7XG4gICAgICAgIHB1Ymxpc2hlZEF0OiBUaW1lc3RhbXAubm93KCksXG4gICAgICAgIHB1Ymxpc2hlZEJ5OiBwdWJsaXNoZWRCeSxcbiAgICAgICAgc2NoZWR1bGVkQXQ6IEZpZWxkVmFsdWUuZGVsZXRlKCksXG4gICAgICAgIHNjaGVkdWxlZEJ5OiBGaWVsZFZhbHVlLmRlbGV0ZSgpLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aGlzLnB1Ymxpc2hEb2NzKHJlbGVhc2UuZG9jSWRzIHx8IFtdLCB7cHVibGlzaGVkQnksIGJhdGNofSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRyYW5zbGF0aW9ucyBzYXZlZCBpbiB0aGUgdHJhbnNsYXRpb25zIGNvbGxlY3Rpb24sIG9wdGlvbmFsbHlcbiAgICogZmlsdGVyZWQgYnkgdGFnLlxuICAgKlxuICAgKiBSZXR1cm5zIGEgbWFwIGxpa2U6XG4gICAqIGBgYFxuICAgKiB7XG4gICAqICAgXCI8aGFzaD5cIjoge1wic291cmNlXCI6IFwiSGVsbG9cIiwgXCJlc1wiOiBcIkhvbGFcIiwgXCJmclwiOiBcIkJvbmpvdXJcIn0sXG4gICAqIH1cbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBsb2FkVHJhbnNsYXRpb25zKFxuICAgIG9wdGlvbnM/OiBMb2FkVHJhbnNsYXRpb25zT3B0aW9uc1xuICApOiBQcm9taXNlPFRyYW5zbGF0aW9uc01hcD4ge1xuICAgIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9UcmFuc2xhdGlvbnNgO1xuICAgIGxldCBxdWVyeTogUXVlcnkgPSB0aGlzLmRiLmNvbGxlY3Rpb24oZGJQYXRoKTtcbiAgICBpZiAob3B0aW9ucz8udGFncykge1xuICAgICAgcXVlcnkgPSBxdWVyeS53aGVyZSgndGFncycsICdhcnJheS1jb250YWlucy1hbnknLCBvcHRpb25zLnRhZ3MpO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5U25hcHNob3QgPSBhd2FpdCBxdWVyeS5nZXQoKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNNYXA6IFRyYW5zbGF0aW9uc01hcCA9IHt9O1xuICAgIHF1ZXJ5U25hcHNob3QuZm9yRWFjaCgoZG9jKSA9PiB7XG4gICAgICBjb25zdCBoYXNoID0gZG9jLmlkO1xuICAgICAgdHJhbnNsYXRpb25zTWFwW2hhc2hdID0gZG9jLmRhdGEoKSBhcyBUcmFuc2xhdGlvbjtcbiAgICB9KTtcbiAgICByZXR1cm4gdHJhbnNsYXRpb25zTWFwO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgbWFwIG9mIHRyYW5zbGF0aW9ucywgZS5nLjpcbiAgICogYGBgXG4gICAqIGF3YWl0IGNsaWVudC5zYXZlVHJhbnNsYXRpb25zKHtcbiAgICogICBcIkhlbGxvXCI6IHtcImVzXCI6IFwiSG9sYVwiLCBcImZyXCI6IFwiQm9uam91clwifSxcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgc2F2ZVRyYW5zbGF0aW9ucyhcbiAgICB0cmFuc2xhdGlvbnM6IHtcbiAgICAgIFtzb3VyY2U6IHN0cmluZ106IHtbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmd9O1xuICAgIH0sXG4gICAgdGFncz86IHN0cmluZ1tdXG4gICkge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uc1BhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vVHJhbnNsYXRpb25zYDtcbiAgICBjb25zdCBiYXRjaCA9IHRoaXMuZGIuYmF0Y2goKTtcbiAgICBsZXQgYmF0Y2hDb3VudCA9IDA7XG4gICAgT2JqZWN0LmVudHJpZXModHJhbnNsYXRpb25zKS5mb3JFYWNoKChbc291cmNlLCBzb3VyY2VUcmFuc2xhdGlvbnNdKSA9PiB7XG4gICAgICBjb25zdCBoYXNoID0gdGhpcy5nZXRUcmFuc2xhdGlvbktleShzb3VyY2UpO1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25SZWYgPSB0aGlzLmRiLmRvYyhgJHt0cmFuc2xhdGlvbnNQYXRofS8ke2hhc2h9YCk7XG4gICAgICBjb25zdCBkYXRhOiBhbnkgPSB7XG4gICAgICAgIC4uLnNvdXJjZVRyYW5zbGF0aW9ucyxcbiAgICAgICAgc291cmNlOiB0aGlzLm5vcm1hbGl6ZVN0cmluZyhzb3VyY2UpLFxuICAgICAgfTtcbiAgICAgIGlmICh0YWdzKSB7XG4gICAgICAgIGRhdGEudGFncyA9IHRhZ3M7XG4gICAgICB9XG4gICAgICBiYXRjaC51cGRhdGUodHJhbnNsYXRpb25SZWYsIGRhdGEpO1xuICAgICAgYmF0Y2hDb3VudCArPSAxO1xuICAgIH0pO1xuICAgIGlmIChiYXRjaENvdW50ID4gNTAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VwIHRvIDUwMCB0cmFuc2xhdGlvbnMgY2FuIGJlIHNhdmVkIGF0IGEgdGltZS4nKTtcbiAgICB9XG4gICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgXCJrZXlcIiB1c2VkIGZvciBhIHRyYW5zbGF0aW9uIGFzIHN0b3JlZCBpbiB0aGUgZGIuIFRyYW5zbGF0aW9uc1xuICAgKiBhcmUgc3RvcmVkIHVuZGVyIGBQcm9qZWN0cy88cHJvamVjdCBpZD4vVHJhbnNsYXRpb25zLzxzaGExIGhhc2g+YC5cbiAgICovXG4gIGdldFRyYW5zbGF0aW9uS2V5KHNvdXJjZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgc2hhMSA9IGNyeXB0b1xuICAgICAgLmNyZWF0ZUhhc2goJ3NoYTEnKVxuICAgICAgLnVwZGF0ZSh0aGlzLm5vcm1hbGl6ZVN0cmluZyhzb3VyY2UpKVxuICAgICAgLmRpZ2VzdCgnaGV4Jyk7XG4gICAgcmV0dXJuIHNoYTE7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5zIGEgc3RyaW5nIHRoYXQncyB1c2VkIGZvciB0cmFuc2xhdGlvbnMuIFBlcmZvcm1zIHRoZSBmb2xsb3dpbmc6XG4gICAqIC0gUmVtb3ZlcyBhbnkgbGVhZGluZy90cmFpbGluZyB3aGl0ZXNwYWNlXG4gICAqIC0gUmVtb3ZlcyBzcGFjZXMgYXQgdGhlIGVuZCBvZiBhbnkgbGluZVxuICAgKi9cbiAgbm9ybWFsaXplU3RyaW5nKHN0cjogc3RyaW5nKSB7XG4gICAgY29uc3QgbGluZXMgPSBTdHJpbmcoc3RyKVxuICAgICAgLnRyaW0oKVxuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltRW5kKCkpO1xuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0cmFuc2xhdGlvbnMgZm9yIGEgcGFydGljdWxhciBsb2NhbGUuXG4gICAqXG4gICAqIFJldHVybnMgYSBtYXAgbGlrZTpcbiAgICogYGBgXG4gICAqIHtcbiAgICogICBcIkhlbGxvXCI6IFwiQm9uam91clwiLFxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgbG9hZFRyYW5zbGF0aW9uc0ZvckxvY2FsZShcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogTG9hZFRyYW5zbGF0aW9uc09wdGlvbnNcbiAgKTogUHJvbWlzZTxMb2NhbGVUcmFuc2xhdGlvbnM+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNNYXAgPSBhd2FpdCB0aGlzLmxvYWRUcmFuc2xhdGlvbnMob3B0aW9ucyk7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uc0ZvckxvY2FsZSh0cmFuc2xhdGlvbnNNYXAsIGxvY2FsZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGRhdGEgc291cmNlIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YVNvdXJjZShkYXRhU291cmNlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9EYXRhU291cmNlcy8ke2RhdGFTb3VyY2VJZH1gO1xuICAgIGNvbnN0IGRvY1JlZiA9IHRoaXMuZGIuZG9jKGRiUGF0aCk7XG4gICAgY29uc3QgZG9jID0gYXdhaXQgZG9jUmVmLmdldCgpO1xuICAgIGlmIChkb2MuZXhpc3RzKSB7XG4gICAgICByZXR1cm4gZG9jLmRhdGEoKSBhcyBEYXRhU291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jcyBhIGRhdGEgc291cmNlIHRvIGRyYWZ0IHN0YXRlLlxuICAgKi9cbiAgYXN5bmMgc3luY0RhdGFTb3VyY2UoZGF0YVNvdXJjZUlkOiBzdHJpbmcsIG9wdGlvbnM/OiB7c3luY2VkQnk/OiBzdHJpbmd9KSB7XG4gICAgY29uc3QgZGF0YVNvdXJjZSA9IGF3YWl0IHRoaXMuZ2V0RGF0YVNvdXJjZShkYXRhU291cmNlSWQpO1xuICAgIGlmICghZGF0YVNvdXJjZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBkYXRhIHNvdXJjZSBub3QgZm91bmQ6ICR7ZGF0YVNvdXJjZUlkfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmZldGNoRGF0YShkYXRhU291cmNlKTtcblxuICAgIGNvbnN0IGRhdGFTb3VyY2VEb2NSZWYgPSB0aGlzLmRiLmRvYyhcbiAgICAgIGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9EYXRhU291cmNlcy8ke2RhdGFTb3VyY2VJZH1gXG4gICAgKTtcbiAgICBjb25zdCBkYXRhRG9jUmVmID0gdGhpcy5kYi5kb2MoXG4gICAgICBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vRGF0YVNvdXJjZXMvJHtkYXRhU291cmNlSWR9L0RhdGEvZHJhZnRgXG4gICAgKTtcbiAgICBjb25zdCBzeW5jZWRCeSA9IG9wdGlvbnM/LnN5bmNlZEJ5IHx8ICdyb290LWNtcy1jbGllbnQnO1xuXG4gICAgY29uc3QgdXBkYXRlZERhdGFTb3VyY2U6IERhdGFTb3VyY2UgPSB7XG4gICAgICAuLi5kYXRhU291cmNlLFxuICAgICAgc3luY2VkQXQ6IFRpbWVzdGFtcC5ub3coKSxcbiAgICAgIHN5bmNlZEJ5OiBzeW5jZWRCeSxcbiAgICB9O1xuXG4gICAgY29uc3QgYmF0Y2ggPSB0aGlzLmRiLmJhdGNoKCk7XG4gICAgYmF0Y2guc2V0KGRhdGFEb2NSZWYsIHtcbiAgICAgIGRhdGFTb3VyY2U6IHVwZGF0ZWREYXRhU291cmNlLFxuICAgICAgZGF0YTogZGF0YSxcbiAgICB9KTtcbiAgICBiYXRjaC51cGRhdGUoZGF0YVNvdXJjZURvY1JlZiwge1xuICAgICAgc3luY2VkQXQ6IFRpbWVzdGFtcC5ub3coKSxcbiAgICAgIHN5bmNlZEJ5OiBzeW5jZWRCeSxcbiAgICB9KTtcbiAgICBhd2FpdCBiYXRjaC5jb21taXQoKTtcblxuICAgIGNvbnNvbGUubG9nKGBzeW5jZWQgZGF0YSBzb3VyY2U6ICR7ZGF0YVNvdXJjZUlkfWApO1xuICAgIGNvbnNvbGUubG9nKGBzeW5jZWQgYnk6ICR7c3luY2VkQnl9YCk7XG4gIH1cblxuICBhc3luYyBwdWJsaXNoRGF0YVNvdXJjZShcbiAgICBkYXRhU291cmNlSWQ6IHN0cmluZyxcbiAgICBvcHRpb25zPzoge3B1Ymxpc2hlZEJ5Pzogc3RyaW5nfVxuICApIHtcbiAgICBjb25zdCBkYXRhU291cmNlID0gYXdhaXQgdGhpcy5nZXREYXRhU291cmNlKGRhdGFTb3VyY2VJZCk7XG4gICAgaWYgKCFkYXRhU291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGRhdGEgc291cmNlIG5vdCBmb3VuZDogJHtkYXRhU291cmNlSWR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YVNvdXJjZURvY1JlZiA9IHRoaXMuZGIuZG9jKFxuICAgICAgYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0RhdGFTb3VyY2VzLyR7ZGF0YVNvdXJjZUlkfWBcbiAgICApO1xuICAgIGNvbnN0IGRhdGFEb2NSZWZEcmFmdCA9IHRoaXMuZGIuZG9jKFxuICAgICAgYFByb2plY3RzLyR7dGhpcy5wcm9qZWN0SWR9L0RhdGFTb3VyY2VzLyR7ZGF0YVNvdXJjZUlkfS9kcmFmdGBcbiAgICApO1xuICAgIGNvbnN0IGRhdGFEb2NSZWZQdWJsaXNoZWQgPSB0aGlzLmRiLmRvYyhcbiAgICAgIGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9EYXRhU291cmNlcy8ke2RhdGFTb3VyY2VJZH0vcHVibGlzaGVkYFxuICAgICk7XG5cbiAgICBjb25zdCBkYXRhUmVzID0gYXdhaXQgdGhpcy5nZXRGcm9tRGF0YVNvdXJjZShkYXRhU291cmNlSWQsIHttb2RlOiAnZHJhZnQnfSk7XG5cbiAgICBjb25zdCBwdWJsaXNoZWRCeSA9IG9wdGlvbnM/LnB1Ymxpc2hlZEJ5IHx8ICdyb290LWNtcy1jbGllbnQnO1xuXG4gICAgY29uc3QgdXBkYXRlZERhdGFTb3VyY2U6IERhdGFTb3VyY2UgPSB7XG4gICAgICAuLi5kYXRhU291cmNlLFxuICAgICAgcHVibGlzaGVkQXQ6IFRpbWVzdGFtcC5ub3coKSxcbiAgICAgIHB1Ymxpc2hlZEJ5OiBwdWJsaXNoZWRCeSxcbiAgICB9O1xuXG4gICAgY29uc3QgYmF0Y2ggPSB0aGlzLmRiLmJhdGNoKCk7XG4gICAgYmF0Y2guc2V0KGRhdGFEb2NSZWZQdWJsaXNoZWQsIHtcbiAgICAgIGRhdGFTb3VyY2U6IHVwZGF0ZWREYXRhU291cmNlLFxuICAgICAgZGF0YTogZGF0YVJlcz8uZGF0YSB8fCBudWxsLFxuICAgIH0pO1xuICAgIGJhdGNoLnVwZGF0ZShkYXRhRG9jUmVmRHJhZnQsIHtcbiAgICAgIGRhdGFTb3VyY2U6IHVwZGF0ZWREYXRhU291cmNlLFxuICAgIH0pO1xuICAgIGJhdGNoLnVwZGF0ZShkYXRhU291cmNlRG9jUmVmLCB7XG4gICAgICBwdWJsaXNoZWRBdDogVGltZXN0YW1wLm5vdygpLFxuICAgICAgcHVibGlzaGVkQnk6IHB1Ymxpc2hlZEJ5LFxuICAgIH0pO1xuICAgIGF3YWl0IGJhdGNoLmNvbW1pdCgpO1xuXG4gICAgY29uc29sZS5sb2coYHB1Ymxpc2hlZCBkYXRhICR7ZGF0YVNvdXJjZUlkfWApO1xuICAgIGNvbnNvbGUubG9nKGBwdWJsaXNoZWQgYnk6ICR7cHVibGlzaGVkQnl9YCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoRGF0YShkYXRhU291cmNlOiBEYXRhU291cmNlKSB7XG4gICAgaWYgKGRhdGFTb3VyY2UudHlwZSA9PT0gJ2h0dHAnKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5mZXRjaEh0dHBEYXRhKGRhdGFTb3VyY2UpO1xuICAgIH1cbiAgICAvLyBUT0RPKHN0ZXZlbmxlKTogaW1wbC5cbiAgICAvLyBpZiAoZGF0YVNvdXJjZS50eXBlID09PSAnZ3NoZWV0Jykge1xuICAgIC8vICAgcmV0dXJuIGF3YWl0IGZldGNoR3NoZWV0RGF0YShkYXRhU291cmNlKTtcbiAgICAvLyB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHNvdXJjZTogJHtkYXRhU291cmNlLnR5cGV9YCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoSHR0cERhdGEoZGF0YVNvdXJjZTogRGF0YVNvdXJjZSkge1xuICAgIGNvbnN0IHVybCA9IGRhdGFTb3VyY2UudXJsIHx8ICcnO1xuICAgIGlmICghdXJsLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdXJsIG5vdCBzdXBwb3J0ZWQ6ICR7dXJsfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgbWV0aG9kOiBkYXRhU291cmNlLmh0dHBPcHRpb25zPy5tZXRob2QgfHwgJ0dFVCcsXG4gICAgICBoZWFkZXJzOiBkYXRhU291cmNlLmh0dHBPcHRpb25zPy5oZWFkZXJzIHx8IFtdLFxuICAgICAgYm9keTogZGF0YVNvdXJjZS5odHRwT3B0aW9ucz8uYm9keSB8fCB1bmRlZmluZWQsXG4gICAgfSk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICBjb25zdCBlcnIgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXEgZmFpbGVkOiAke2Vycn1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50VHlwZSA9IFN0cmluZyhyZXMuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpKTtcbiAgICBpZiAoY29udGVudFR5cGUuaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlcy5qc29uKCk7XG4gICAgfVxuICAgIHJldHVybiByZXMudGV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgZGF0YSBmcm9tIGEgZGF0YSBzb3VyY2UuXG4gICAqL1xuICBhc3luYyBnZXRGcm9tRGF0YVNvdXJjZTxUID0gYW55PihcbiAgICBkYXRhU291cmNlSWQ6IHN0cmluZyxcbiAgICBvcHRpb25zPzoge21vZGU/OiAnZHJhZnQnIHwgJ3B1Ymxpc2hlZCd9XG4gICk6IFByb21pc2U8RGF0YVNvdXJjZURhdGE8VD4gfCBudWxsPiB7XG4gICAgY29uc3QgbW9kZSA9IG9wdGlvbnM/Lm1vZGUgfHwgJ3B1Ymxpc2hlZCc7XG4gICAgaWYgKCEobW9kZSA9PT0gJ2RyYWZ0JyB8fCBtb2RlID09PSAncHVibGlzaGVkJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBtb2RlOiAke21vZGV9YCk7XG4gICAgfVxuICAgIGlmICghZGF0YVNvdXJjZUlkIHx8IGRhdGFTb3VyY2VJZC5pbmNsdWRlcygnLycpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZGF0YSBzb3VyY2UgaWQ6ICR7ZGF0YVNvdXJjZUlkfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRiUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9EYXRhU291cmNlcy8ke2RhdGFTb3VyY2VJZH0vRGF0YS8ke21vZGV9YDtcbiAgICBjb25zdCBkb2NSZWYgPSB0aGlzLmRiLmRvYyhkYlBhdGgpO1xuICAgIGNvbnN0IGRvYyA9IGF3YWl0IGRvY1JlZi5nZXQoKTtcbiAgICBpZiAoZG9jLmV4aXN0cykge1xuICAgICAgcmV0dXJuIGRvYy5kYXRhKCkgYXMgRGF0YVNvdXJjZURhdGE8VD47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHVzZXIgZXhpc3RzIGluIHRoZSBBQ0wgbGlzdC5cbiAgICovXG4gIGFzeW5jIHVzZXJFeGlzdHNJbkFjbChlbWFpbDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBkb2NSZWYgPSB0aGlzLmRiLmRvYyhgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH1gKTtcbiAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGRvY1JlZi5nZXQoKTtcbiAgICBjb25zdCBkYXRhID0gc25hcHNob3QuZGF0YSgpIHx8IHt9O1xuICAgIGNvbnN0IGFjbCA9IGRhdGEucm9sZXMgfHwge307XG4gICAgaWYgKGVtYWlsIGluIGFjbCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgd2lsZGNhcmQgZG9tYWlucywgZS5nLiBgKkBleGFtcGxlLmNvbWAuXG4gICAgaWYgKCFlbWFpbC5pbmNsdWRlcygnQCcpKSB7XG4gICAgICBjb25zb2xlLndhcm4oYGludmFsaWQgZW1haWw6ICR7ZW1haWx9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGRvbWFpbiA9IGVtYWlsLnNwbGl0KCdAJykuYXQoLTEpO1xuICAgIGlmIChkb21haW4gJiYgYCpAJHtkb21haW59YCBpbiBhY2wpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENtc1BsdWdpbihyb290Q29uZmlnOiBSb290Q29uZmlnKTogQ01TUGx1Z2luIHtcbiAgY29uc3QgcGx1Z2luczogUGx1Z2luW10gPSByb290Q29uZmlnLnBsdWdpbnMgfHwgW107XG4gIGNvbnN0IHBsdWdpbiA9IHBsdWdpbnMuZmluZCgocGx1Z2luKSA9PiBwbHVnaW4ubmFtZSA9PT0gJ3Jvb3QtY21zJyk7XG4gIGlmICghcGx1Z2luKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCByb290LWNtcyBwbHVnaW4gY29uZmlnIGluIHJvb3QuY29uZmlnLnRzJyk7XG4gIH1cbiAgcmV0dXJuIHBsdWdpbiBhcyBDTVNQbHVnaW47XG59XG5cbi8qKlxuICogV2Fsa3MgdGhlIGRhdGEgdHJlZSBhbmQgY29udmVydHMgYW55IFRpbWVzdGFtcCBvYmplY3RzIHRvIG1pbGxpcyBhbmQgYW55XG4gKiBfYXJyYXkgbWFwcyB0byBub3JtYWwgYXJyYXlzLlxuICpcbiAqIEUuZy46XG4gKlxuICogbm9ybWFsaXplRGF0YSh7XG4gKiAgIHN5czoge21vZGlmaWVkQXQ6IFRpbWVzdGFtcCgxMjMpfSxcbiAqICAgZmllbGRzOiB7XG4gKiAgICAgX2FycmF5OiBbJ2FzZGYnXSxcbiAqICAgICBhc2RmOiB7dGl0bGU6ICdoZWxsbyd9XG4gKiAgIH1cbiAqIH0pXG4gKiAvLyA9PiB7c3lzOiB7bW9kaWZpZWRBdDogMTIzfSwgZmllbGRzOiB7Zm9vOiBbe3RpdGxlOiAnaGVsbG8nfV19fVxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5tYXJzaGFsRGF0YShkYXRhOiBhbnkpOiBhbnkge1xuICBjb25zdCByZXN1bHQ6IGFueSA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgY29uc3QgdmFsID0gZGF0YVtrZXldO1xuICAgIGlmIChpc09iamVjdCh2YWwpKSB7XG4gICAgICBpZiAodmFsLnRvTWlsbGlzKSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdmFsLnRvTWlsbGlzKCk7XG4gICAgICB9IGVsc2UgaWYgKE9iamVjdC5oYXNPd24odmFsLCAnX2FycmF5JykgJiYgQXJyYXkuaXNBcnJheSh2YWwuX2FycmF5KSkge1xuICAgICAgICBjb25zdCBhcnIgPSB2YWwuX2FycmF5Lm1hcCgoYXJyYXlLZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi51bm1hcnNoYWxEYXRhKHZhbFthcnJheUtleV0gfHwge30pLFxuICAgICAgICAgICAgX2FycmF5S2V5OiBhcnJheUtleSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBhcnI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRba2V5XSA9IHVubWFyc2hhbERhdGEodmFsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHVubWFyc2hhbERhdGEoKWAgaW5zdGVhZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhKGRhdGE6IGFueSk6IGFueSB7XG4gIHJldHVybiB1bm1hcnNoYWxEYXRhKGRhdGEpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5T2JqZWN0IHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xuICBfYXJyYXk6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZXMgYW4gYXJyYXkgaW50byBhbiBgQXJyYXlPYmplY3RgLCBlLmcuOlxuICpcbiAqIGBgYFxuICogbWFyc2hhbEFycmF5KFsxLCAyLCAzXSlcbiAqIC8vID0+IHthOiAxLCBiOiAyLCBjOiAzLCBfYXJyYXk6IFsnYScsICdiJywgJ2MnXX1cbiAqIGBgYFxuICpcbiAqIFRoaXMgZGF0YWJhc2Ugc3RvcmFnZSBtZXRob2QgbWFrZXMgaXQgZWFzaWVyIHRvIHVwZGF0ZSBhIHNpbmdsZSBmaWVsZCBpbiBhXG4gKiBkZWVwbHkgbmVzdGVkIGFycmF5IG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcnNoYWxBcnJheShhcnI6IGFueVtdKTogQXJyYXlPYmplY3Qge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIHJldHVybiBhcnI7XG4gIH1cbiAgY29uc3QgYXJyT2JqZWN0OiBBcnJheU9iamVjdCA9IHtfYXJyYXk6IFtdfTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgIGNvbnN0IGtleSA9IHJhbmRTdHJpbmcoNik7XG4gICAgYXJyT2JqZWN0W2tleV0gPSBpdGVtO1xuICAgIGFyck9iamVjdC5fYXJyYXkucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBhcnJPYmplY3Q7XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gYEFycmF5T2JqZWN0YCB0byBhIG5vcm1hbCBhcnJheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVubWFyc2hhbEFycmF5KGFyck9iamVjdDogQXJyYXlPYmplY3QpOiBhbnlbXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShhcnJPYmplY3Q/Ll9hcnJheSkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgY29uc3QgYXJyID0gYXJyT2JqZWN0Ll9hcnJheS5tYXAoKGs6IHN0cmluZykgPT4gYXJyT2JqZWN0W2tdKTtcbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoZGF0YTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgJiYgZGF0YSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmFuZFN0cmluZyhsZW46IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBjaGFycyA9XG4gICAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGNvbnN0IHJhbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpO1xuICAgIHJlc3VsdC5wdXNoKGNoYXJzLmNoYXJBdChyYW5kKSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHRyYW5zbGF0aW9ucyBtYXAgZnJvbSBgbG9hZFRyYW5zbGF0aW9ucygpYCB0byBhIG1hcCBvZiBzb3VyY2UgdG9cbiAqIHRyYW5zbGF0ZWQgc3RyaW5nIGZvciBhIHBhcnRpY3VsYXIgbG9jYWxlLlxuICpcbiAqIFJldHVybnMgYSBtYXAgbGlrZTpcbiAqIGBgYFxuICoge1xuICogICBcIkhlbGxvXCI6IFwiQm9uam91clwiLFxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGlvbnNGb3JMb2NhbGUoXG4gIHRyYW5zbGF0aW9uc01hcDogVHJhbnNsYXRpb25zTWFwLFxuICBsb2NhbGU6IHN0cmluZ1xuKSB7XG4gIGNvbnN0IGxvY2FsZVRyYW5zbGF0aW9uczogTG9jYWxlVHJhbnNsYXRpb25zID0ge307XG4gIE9iamVjdC52YWx1ZXModHJhbnNsYXRpb25zTWFwKS5mb3JFYWNoKChzdHJpbmcpID0+IHtcbiAgICBjb25zdCBzb3VyY2UgPSBzdHJpbmcuc291cmNlO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gc3RyaW5nW2xvY2FsZV0gfHwgc3RyaW5nLmVuIHx8IHN0cmluZy5zb3VyY2U7XG4gICAgbG9jYWxlVHJhbnNsYXRpb25zW3NvdXJjZV0gPSB0cmFuc2xhdGlvbjtcbiAgfSk7XG4gIHJldHVybiBsb2NhbGVUcmFuc2xhdGlvbnM7XG59XG4iLCAiLyoqXG4gKiBEb2N1bWVudCB2ZXJpb24gaGlzdG9yeS5cbiAqXG4gKiBWZXJpb25zIHNhdmUgdGhlIHN0YXRlIG9mIGEgZG9jdW1lbnQgYXQgZGlmZmVyZW50IG1vbWVudHMgaW4gdGltZSwgYWxsb3dpbmdcbiAqIHVzZXJzIHRvIHJldmVydCBiYWNrIHRvIGEgdmVyc2lvbiBpZi93aGVuIG5lZWRlZC5cbiAqXG4gKiBUaGUgc2F2ZVZlcnNpb25zKCkgZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgcnVuIHdpdGhpbiBhIGNyb24gam9iIChlLmcgdXNpbmdcbiAqIGZpcmViYXNlIGZ1bmN0aW9ucykuIEV2ZXJ5IG1pbnV0ZSwgdGhlIHJ1bm5lciBjaGVja3MgZm9yIGFsbCBkb2N1bWVudHMgdGhhdFxuICogaGF2ZSBiZWVuIGVkaXRlZCBzaW5jZSB0aGUgbGFzdCBydW4uIFRvIGF2b2lkIHNhdmluZyBcInBhcnRpYWxcIiB2ZXJzaW9uc1xuICogKHdoZW4gdGhlIHVzZXIgbWlnaHQgYmUgaW4gdGhlIG1pZGRsZSBvZiBlZGl0aW5nIGEgZG9jdW1lbnQpLCB2ZXJzaW9ucyBvbmx5XG4gKiBydW4gb24gZG9jdW1lbnRzIHRoYXQgaGF2ZW4ndCBiZWVuIGVkaXRlZCB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGVuc3VyZVxuICogdGhhdCB2ZXJzaW9uIGlzIFwic3RhYmxlXCIuXG4gKlxuICogSW4gdGhlIGRhdGFiYXNlLCB2ZXJzaW9ucyBhcmUgc3RvcmVkIGFzOlxuICogL1Byb2plY3RzLzxwcm9qZWN0SWQ+L0NvbGxlY3Rpb25zLzxjb2xsZWN0aW9uSWQ+L0RyYWZ0cy88ZG9jSWQ+L1ZlcnNpb25zLzx0aW1lc3RhbXA+XG4gKlxuICogV2hlcmUgPHRpbWVzdGFtcD4gaXMgdGhlIHVuaXggdGltZXN0YW1wIChtaWxsaXMpIHRoYXQgdGhlIGRvY3VtZW50IHdhcyBsYXN0XG4gKiBlZGl0ZWQuXG4gKi9cblxuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7Um9vdENvbmZpZ30gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCB7XG4gIEZpcmVzdG9yZSxcbiAgUXVlcnksXG4gIFRpbWVzdGFtcCxcbiAgZ2V0RmlyZXN0b3JlLFxufSBmcm9tICdmaXJlYmFzZS1hZG1pbi9maXJlc3RvcmUnO1xuaW1wb3J0IGdsb2IgZnJvbSAndGlueS1nbG9iJztcbmltcG9ydCB7Z2V0Q21zUGx1Z2lufSBmcm9tICcuL2NsaWVudC5qcyc7XG5cbi8vIFRvIGF2b2lkIHNhdmluZyBcInBhcnRpYWxcIiB2ZXJzaW9ucyAod2hlbiB0aGUgdXNlciBtaWdodCBiZSBpbiB0aGUgbWlkZGxlIG9mXG4vLyBlZGl0aW5nIGEgZG9jdW1lbnQpLCB2ZXJzaW9ucyBvbmx5IHJ1biBvbiBkb2N1bWVudHMgdGhhdCBoYXZlbid0IGJlZW4gZWRpdGVkXG4vLyB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGVuc3VyZSB0aGF0IHZlcnNpb24gaXMgXCJzdGFibGVcIi5cbmNvbnN0IERPQ1VNRU5UX1NBVkVfT0ZGU0VUID0gNSAqIDYwICogMTAwMDtcblxuaW50ZXJmYWNlIFBhcnRpYWxDTVNEb2Mge1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbGxlY3Rpb246IHN0cmluZztcbiAgc2x1Zzogc3RyaW5nO1xuICBzeXM6IHtcbiAgICBtb2RpZmllZEF0OiBUaW1lc3RhbXA7XG4gICAgbW9kaWZpZWRCeTogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgVmVyc2lvbnNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSByb290Q29uZmlnOiBSb290Q29uZmlnO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2plY3RJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRiOiBGaXJlc3RvcmU7XG5cbiAgY29uc3RydWN0b3Iocm9vdENvbmZpZzogUm9vdENvbmZpZykge1xuICAgIHRoaXMucm9vdENvbmZpZyA9IHJvb3RDb25maWc7XG4gICAgY29uc3QgY21zUGx1Z2luID0gZ2V0Q21zUGx1Z2luKHJvb3RDb25maWcpO1xuICAgIGNvbnN0IGNtc1BsdWdpbk9wdGlvbnMgPSBjbXNQbHVnaW4uZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgcHJvamVjdElkID0gY21zUGx1Z2luT3B0aW9ucy5pZCB8fCAnZGVmYXVsdCc7XG4gICAgdGhpcy5wcm9qZWN0SWQgPSBwcm9qZWN0SWQ7XG4gICAgY29uc3QgYXBwID0gY21zUGx1Z2luLmdldEZpcmViYXNlQXBwKCk7XG4gICAgdGhpcy5kYiA9IGdldEZpcmVzdG9yZShhcHApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgdmVyc2lvbiBvZiBhbGwgZG9jdW1lbnRzIHRoYXQgaGF2ZSBiZWVuIGVkaXRlZCBzaW5jZSB0aGUgbGFzdCBydW4uXG4gICAqL1xuICBhc3luYyBzYXZlVmVyc2lvbnMoKSB7XG4gICAgLy8gT2Zmc2V0IHRoZSBcImxhc3QgcnVuXCIgdGltZSBieSA1IG1pbnMuIFZlcnNpb25zIGlnbm9yZSBkb2NzIHRoYXQgd2VyZVxuICAgIC8vIGVkaXRlZCB3aXRoaW4gdGhlIGxhc3QgNSBtaW5zIHRvIGF2b2lkIHBvdGVudGlhbCBcInBhcnRpYWxcIiB2ZXJzaW9ucyB3aGVuXG4gICAgLy8gdXNlciBpcyBpbiB0aGUgbWlkZGxlIG9mIGVkaXRpbmcgYSBkb2N1bWVudC5cbiAgICBjb25zdCBsYXN0UnVuID0gYXdhaXQgdGhpcy5nZXRMYXN0UnVuKCk7XG4gICAgY29uc3QgbGFzdFJ1bldpdGhPZmZzZXQgPVxuICAgICAgbGFzdFJ1biA9PT0gMCA/IGxhc3RSdW4gOiBsYXN0UnVuIC0gRE9DVU1FTlRfU0FWRV9PRkZTRVQ7XG4gICAgY29uc3QgY2hhbmdlZERvY3MgPSBhd2FpdCB0aGlzLmdldERvY3NNb2RpZmllZEFmdGVyKGxhc3RSdW5XaXRoT2Zmc2V0KTtcbiAgICBjb25zdCBub3cgPSBUaW1lc3RhbXAubm93KCkudG9NaWxsaXMoKTtcbiAgICBjb25zdCB2ZXJzaW9ucyA9IGNoYW5nZWREb2NzLmZpbHRlcigoZG9jKSA9PiB7XG4gICAgICBjb25zdCBtb2RpZmllZEF0ID0gZG9jLnN5cy5tb2RpZmllZEF0LnRvTWlsbGlzKCk7XG4gICAgICByZXR1cm4gbW9kaWZpZWRBdCA8PSBub3cgLSBET0NVTUVOVF9TQVZFX09GRlNFVDtcbiAgICB9KTtcbiAgICBpZiAodmVyc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zYXZlVmVyc2lvbnNUb0ZpcmVzdG9yZSh2ZXJzaW9ucyk7XG4gICAgfVxuICAgIHRoaXMuc2F2ZUxhc3RSdW4obm93KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2F2ZVZlcnNpb25zVG9GaXJlc3RvcmUodmVyc2lvbnM6IFBhcnRpYWxDTVNEb2NbXSkge1xuICAgIGNvbnN0IGJhdGNoID0gdGhpcy5kYi5iYXRjaCgpO1xuICAgIHZlcnNpb25zLmZvckVhY2goKHZlcnNpb24pID0+IHtcbiAgICAgIGlmICghdmVyc2lvbi5jb2xsZWN0aW9uIHx8ICF2ZXJzaW9uLnNsdWcgfHwgIXZlcnNpb24uc3lzPy5tb2RpZmllZEF0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1vZGlmaWVkQXRNaWxsaXMgPSB2ZXJzaW9uLnN5cy5tb2RpZmllZEF0LnRvTWlsbGlzKCk7XG4gICAgICBjb25zdCB2ZXJzaW9uUGF0aCA9IGBQcm9qZWN0cy8ke3RoaXMucHJvamVjdElkfS9Db2xsZWN0aW9ucy8ke3ZlcnNpb24uY29sbGVjdGlvbn0vRHJhZnRzLyR7dmVyc2lvbi5zbHVnfS9WZXJzaW9ucy8ke21vZGlmaWVkQXRNaWxsaXN9YDtcbiAgICAgIGNvbnNvbGUubG9nKHZlcnNpb25QYXRoKTtcbiAgICAgIGNvbnN0IHZlcnNpb25SZWYgPSB0aGlzLmRiLmRvYyh2ZXJzaW9uUGF0aCk7XG4gICAgICBiYXRjaC5zZXQodmVyc2lvblJlZiwgdmVyc2lvbik7XG4gICAgfSk7XG4gICAgYXdhaXQgYmF0Y2guY29tbWl0KCk7XG4gICAgY29uc29sZS5sb2coYHZlcnNpb25zOiBzYXZlZCAke3ZlcnNpb25zLmxlbmd0aH0gdmVyc2lvbnNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBsYXN0IHRpbWUgKGluIG1pbGxpcykgc2F2ZVZlcnNpb25zKCkgd2FzIHJ1biwgb3IgMCBpZiBoYXNcbiAgICogbmV2ZXIgYmVlbiBydW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldExhc3RSdW4oKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBwcm9qZWN0RG9jUmVmID0gdGhpcy5kYi5jb2xsZWN0aW9uKCdQcm9qZWN0cycpLmRvYyh0aGlzLnByb2plY3RJZCk7XG4gICAgY29uc3QgcHJvamVjdERvYyA9IGF3YWl0IHByb2plY3REb2NSZWYuZ2V0KCk7XG4gICAgaWYgKHByb2plY3REb2MuZXhpc3RzKSB7XG4gICAgICBjb25zdCBkYXRhID0gcHJvamVjdERvYy5kYXRhKCkgfHwge307XG4gICAgICBjb25zdCB0cyA9IGRhdGEudmVyc2lvbnNMYXN0UnVuIGFzIFRpbWVzdGFtcDtcbiAgICAgIGlmICh0cykge1xuICAgICAgICByZXR1cm4gdHMudG9NaWxsaXMoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZXMge3ZlcnNpb25MYXN0UnVuOiA8dGltZXN0YW1wPn0gdG8gdGhlIFByb2plY3RzLzxwcm9qZWN0SWQ+IGRvYy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2F2ZUxhc3RSdW4obWlsbGlzOiBudW1iZXIpIHtcbiAgICBjb25zdCB0cyA9IFRpbWVzdGFtcC5mcm9tTWlsbGlzKG1pbGxpcyk7XG4gICAgY29uc3QgcHJvamVjdERvY1JlZiA9IHRoaXMuZGIuY29sbGVjdGlvbignUHJvamVjdHMnKS5kb2ModGhpcy5wcm9qZWN0SWQpO1xuICAgIGF3YWl0IHByb2plY3REb2NSZWYuc2V0KHt2ZXJzaW9uc0xhc3RSdW46IHRzfSwge21lcmdlOiB0cnVlfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIGRvY3MgdGhhdCB3ZXJlIGVkaXRlZCBhZnRlciBhIGNlcnRhaW4gdGltZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0RG9jc01vZGlmaWVkQWZ0ZXIobWlsbGlzOiBudW1iZXIpOiBQcm9taXNlPFBhcnRpYWxDTVNEb2NbXT4ge1xuICAgIGNvbnN0IHRzID0gVGltZXN0YW1wLmZyb21NaWxsaXMobWlsbGlzKTtcbiAgICBjb25zdCByZXN1bHRzOiBQYXJ0aWFsQ01TRG9jW10gPSBbXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uSWRzID0gYXdhaXQgdGhpcy5saXN0Q29sbGVjdGlvbnMoKTtcbiAgICAvLyBOT1RFOiBJbmRpdmlkdWFsIGNvbGxlY3Rpb25zIGFyZSBxdWVyaWVkIGluc3RlYWQgb2YgdXNpbmcgYVxuICAgIC8vIGNvbGxlY3Rpb25Hcm91cCBxdWVyeSBiZWNhdXNlIHRoZSBsYXR0ZXIgcmVxdWlyZXMgYSBmaXJlc3RvcmUgaW5kZXggdG8gYmVcbiAgICAvLyBzZXQgdXAuXG4gICAgZm9yIChjb25zdCBjb2xsZWN0aW9uSWQgb2YgY29sbGVjdGlvbklkcykge1xuICAgICAgY29uc3QgY29sbGVjdGlvblBhdGggPSBgUHJvamVjdHMvJHt0aGlzLnByb2plY3RJZH0vQ29sbGVjdGlvbnMvJHtjb2xsZWN0aW9uSWR9L0RyYWZ0c2A7XG4gICAgICBjb25zdCBxdWVyeTogUXVlcnkgPSB0aGlzLmRiXG4gICAgICAgIC5jb2xsZWN0aW9uKGNvbGxlY3Rpb25QYXRoKVxuICAgICAgICAud2hlcmUoJ3N5cy5tb2RpZmllZEF0JywgJz49JywgdHMpO1xuICAgICAgY29uc3QgcXVlcnlTbmFwc2hvdCA9IGF3YWl0IHF1ZXJ5LmdldCgpO1xuICAgICAgcXVlcnlTbmFwc2hvdC5mb3JFYWNoKChkb2MpID0+IHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGRvYy5kYXRhKCkgYXMgUGFydGlhbENNU0RvYyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgY29sbGVjdGlvbiBpZHMgZm9yIHRoZSBSb290IHByb2plY3QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxpc3RDb2xsZWN0aW9ucygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgY29sbGVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uRmlsZU5hbWVzID0gYXdhaXQgZ2xvYignKi5zY2hlbWEudHMnLCB7XG4gICAgICBjd2Q6IHBhdGguam9pbih0aGlzLnJvb3RDb25maWcucm9vdERpciwgJ2NvbGxlY3Rpb25zJyksXG4gICAgfSk7XG4gICAgY29sbGVjdGlvbkZpbGVOYW1lcy5mb3JFYWNoKChmaWxlbmFtZSkgPT4ge1xuICAgICAgY29sbGVjdGlvbklkcy5wdXNoKGZpbGVuYW1lLnNsaWNlKDAsIC0xMCkpO1xuICAgIH0pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uSWRzO1xuICB9XG59XG4iLCAiaW1wb3J0IHtSb290Q29uZmlnfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IHtSb290Q01TQ2xpZW50fSBmcm9tICcuL2NsaWVudC5qcyc7XG5pbXBvcnQge1ZlcnNpb25zU2VydmljZX0gZnJvbSAnLi92ZXJzaW9ucy5qcyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5Dcm9uSm9icyhyb290Q29uZmlnOiBSb290Q29uZmlnKSB7XG4gIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICBydW5Dcm9uSm9iKCdwdWJsaXNoU2NoZWR1bGVkRG9jcycsIHJ1blB1Ymxpc2hTY2hlZHVsZWREb2NzLCByb290Q29uZmlnKSxcbiAgICBydW5Dcm9uSm9iKCdzYXZlVmVyc2lvbnMnLCBydW5TYXZlVmVyc2lvbnMsIHJvb3RDb25maWcpLFxuICBdKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuQ3JvbkpvYihcbiAgbmFtZTogc3RyaW5nLFxuICBmbjogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnksXG4gIC4uLmFyZ3M6IGFueVtdXG4pIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmbiguLi5hcmdzKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY29uc29sZS5sb2coYGNyb24gZmFpbGVkOiAke25hbWV9YCk7XG4gICAgY29uc29sZS5lcnJvcihTdHJpbmcoZXJyLnN0YWNrIHx8IGVycikpO1xuICAgIHRocm93IGVycjtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBydW5QdWJsaXNoU2NoZWR1bGVkRG9jcyhyb290Q29uZmlnOiBSb290Q29uZmlnKSB7XG4gIGNvbnN0IGNtc0NsaWVudCA9IG5ldyBSb290Q01TQ2xpZW50KHJvb3RDb25maWcpO1xuICBhd2FpdCBjbXNDbGllbnQucHVibGlzaFNjaGVkdWxlZERvY3MoKTtcbiAgYXdhaXQgY21zQ2xpZW50LnB1Ymxpc2hTY2hlZHVsZWRSZWxlYXNlcygpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBydW5TYXZlVmVyc2lvbnMocm9vdENvbmZpZzogUm9vdENvbmZpZykge1xuICBjb25zdCBzZXJ2aWNlID0gbmV3IFZlcnNpb25zU2VydmljZShyb290Q29uZmlnKTtcbiAgYXdhaXQgc2VydmljZS5zYXZlVmVyc2lvbnMoKTtcbn1cbiIsICJpbXBvcnQge3BhcnNlIGFzIGNzdlBhcnNlfSBmcm9tICdjc3YtcGFyc2Uvc3luYyc7XG5pbXBvcnQge3N0cmluZ2lmeSBhcyBjc3ZTdHJpbmdpZnl9IGZyb20gJ2Nzdi1zdHJpbmdpZnkvc3luYyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheVRvQ3N2KHJlcToge1xuICBoZWFkZXJzOiBzdHJpbmdbXTtcbiAgcm93czogQXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj47XG59KTogc3RyaW5nIHtcbiAgY29uc3QgaGVhZGVycyA9IHJlcS5oZWFkZXJzIHx8IFtdO1xuICBjb25zdCByb3dzID0gcmVxLnJvd3MgfHwgW107XG4gIHJldHVybiBjc3ZTdHJpbmdpZnkocm93cywge1xuICAgIGhlYWRlcjogdHJ1ZSxcbiAgICBjb2x1bW5zOiBoZWFkZXJzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNzdlRvQXJyYXkoY3N2U3RyaW5nOiBzdHJpbmcpIHtcbiAgY29uc3Qgcm93cyA9IGNzdlBhcnNlKGNzdlN0cmluZywge1xuICAgIGNvbHVtbnM6IHRydWUsXG4gICAgc2tpcF9lbXB0eV9saW5lczogdHJ1ZSxcbiAgfSk7XG4gIHJldHVybiByb3dzO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFBLFNBQVEsWUFBWSxVQUFTO0FBQzdCLE9BQU9BLFdBQVU7QUFDakIsU0FBUSxxQkFBb0I7QUFVNUIsT0FBTyxnQkFBZ0I7QUFDdkI7QUFBQSxFQUVFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUSxlQUE4QjtBQUN0QyxZQUFZLGtCQUFrQjtBQUM5QixPQUFPLFVBQVU7OztBQ3BCakIsU0FBUSwyQkFBMEI7OztBQ0RsQyxPQUFPLFlBQVk7QUFHbkI7QUFBQSxFQUNFO0FBQUEsRUFHQTtBQUFBLEVBRUE7QUFBQSxPQUNLO0FBc0hBLElBQU0sZ0JBQU4sTUFBb0I7QUFBQSxFQU96QixZQUFZLFlBQXdCO0FBQ2xDLFNBQUssYUFBYTtBQUNsQixTQUFLLFlBQVksYUFBYSxLQUFLLFVBQVU7QUFFN0MsVUFBTSxtQkFBbUIsS0FBSyxVQUFVLFVBQVU7QUFDbEQsU0FBSyxZQUFZLGlCQUFpQixNQUFNO0FBQ3hDLFNBQUssTUFBTSxLQUFLLFVBQVUsZUFBZTtBQUN6QyxTQUFLLEtBQUssYUFBYSxLQUFLLEdBQUc7QUFBQSxFQUNqQztBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0EsTUFBTSxPQUNKLGNBQ0EsTUFDQSxTQUM2QjtBQUM3QixVQUFNLFVBQVUsTUFBTSxLQUFLLFVBQVUsY0FBYyxNQUFNLE9BQU87QUFDaEUsUUFBSSxTQUFTO0FBQ1gsYUFBTyxjQUFjLE9BQU87QUFBQSxJQUM5QjtBQUNBLFdBQU87QUFBQSxFQUNUO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU1BLE1BQU0sVUFDSixjQUNBLE1BQ0EsU0FDcUI7QUFDckIsVUFBTSxPQUFPLFFBQVE7QUFDckIsVUFBTSxpQkFBaUIsU0FBUyxVQUFVLFdBQVc7QUFFckQsV0FBTyxLQUFLLFdBQVcsS0FBSyxJQUFJO0FBQ2hDLFVBQU0sU0FBUyxZ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QUFrQjtBQUMvRCxZQUFJLFFBQVEsV0FBVyxtQkFBbUI7QUFDMUMsWUFBSSxZQUFZO0FBQ2hCLFlBQUksU0FBUyxZQUFZO0FBQUEsTUFDM0IsQ0FBQztBQUlELGFBQU8sSUFBSSxPQUFPLEtBQWMsS0FBZSxTQUF1QjtBQUNwRSxjQUFNLE9BQU8sTUFBTSxlQUFlLEdBQUc7QUFDckMsWUFBSSxNQUFNO0FBQ1IsY0FBSSxPQUFPO0FBQUEsUUFDYjtBQUlBLFlBQUksQ0FBQyxRQUFRLGNBQWMsR0FBRyxHQUFHO0FBQy9CLGNBQUksSUFBSSxZQUFZLFdBQVcsVUFBVSxHQUFHO0FBQzFDLGdCQUFJLE9BQU8sR0FBRyxFQUFFLEtBQUssRUFBQyxTQUFTLE9BQU8sT0FBTyxpQkFBZ0IsQ0FBQztBQUM5RDtBQUFBLFVBQ0Y7QUFDQSxrQkFBUSxJQUFJLDJCQUEyQjtBQUN2QyxnQkFBTSxTQUFTLElBQUksZ0JBQWdCO0FBQUEsWUFDakMsVUFBVSxJQUFJO0FBQUEsVUFDaEIsQ0FBQztBQUNELGNBQUksU0FBUyxjQUFjLE9BQU8sU0FBUyxDQUFDLEVBQUU7QUFDOUM7QUFBQSxRQUNGO0FBRUEsYUFBSztBQUFBLE1BQ1AsQ0FBQztBQUdELFVBQUksTUFBTTtBQUdWLGFBQU8sSUFBSSxRQUFRLE9BQU8sS0FBYyxRQUFrQjtBQUN4RCxZQUFJO0FBQ0YsZ0JBQU1BLE9BQU0sTUFBTSxZQUFZLEdBQUc7QUFDakMsZ0JBQU1BLEtBQUksVUFBVSxLQUFLLEtBQUs7QUFBQSxZQUM1QixZQUFZLElBQUk7QUFBQSxZQUNoQixXQUFXO0FBQUEsWUFDWCxnQkFBZ0IsUUFBUTtBQUFBLFVBQzFCLENBQUM7QUFBQSxRQUNILFNBQVMsS0FBSztBQUVaLGtCQUFRLE1BQU0sR0FBRztBQUNqQixjQUFJLE9BQU8sR0FBRyxFQUFFLEtBQUssc0JBQXNCO0FBQUEsUUFDN0M7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBQUEsRUFDRjtBQUNGO0FBRUEsU0FBUyxXQUFXLFVBQW9DO0FBQ3RELFNBQU8sR0FDSixPQUFPLFFBQVEsRUFDZixLQUFLLE1BQU0sSUFBSSxFQUNmLE1BQU0sTUFBTSxLQUFLO0FBQ3RCOyIsCiAgIm5hbWVzIjogWyJwYXRoIiwgInBsdWdpbiIsICJUaW1lc3RhbXAiLCAiZ2V0RmlyZXN0b3JlIiwgImNtc1BsdWdpbiIsICJnZXRGaXJlc3RvcmUiLCAiVGltZXN0YW1wIiwgInBhdGgiLCAiYXBwIl0KfQo=
|