@ukwhatn/wikidot 1.0.10 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +227 -79
  2. package/dist/errors.cjs +114 -0
  3. package/dist/errors.d.cts +94 -0
  4. package/dist/errors.d.ts +94 -0
  5. package/dist/errors.js +81 -0
  6. package/dist/index.cjs +4624 -0
  7. package/dist/index.d.cts +2106 -0
  8. package/dist/index.d.ts +2106 -1
  9. package/dist/index.js +2651 -6
  10. package/dist/shared/index-7dqqxq7x.js +105 -0
  11. package/dist/shared/index-f2eh3ykk.js +172 -0
  12. package/dist/shared/index-kka6e8cb.js +627 -0
  13. package/dist/shared/index-ytknx2hn.js +980 -0
  14. package/package.json +64 -40
  15. package/.eslintrc.js +0 -23
  16. package/.github/dependabot.yml +0 -12
  17. package/.prettierrc +0 -6
  18. package/Makefile +0 -24
  19. package/dist/common/exceptions.d.ts +0 -95
  20. package/dist/common/exceptions.js +0 -146
  21. package/dist/common/exceptions.js.map +0 -1
  22. package/dist/common/index.d.ts +0 -1
  23. package/dist/common/index.js +0 -6
  24. package/dist/common/index.js.map +0 -1
  25. package/dist/common/logger.d.ts +0 -2
  26. package/dist/common/logger.js +0 -19
  27. package/dist/common/logger.js.map +0 -1
  28. package/dist/connector/ajax.d.ts +0 -142
  29. package/dist/connector/ajax.js +0 -260
  30. package/dist/connector/ajax.js.map +0 -1
  31. package/dist/connector/api.d.ts +0 -11
  32. package/dist/connector/api.js +0 -17
  33. package/dist/connector/api.js.map +0 -1
  34. package/dist/connector/index.d.ts +0 -0
  35. package/dist/connector/index.js +0 -2
  36. package/dist/connector/index.js.map +0 -1
  37. package/dist/index.js.map +0 -1
  38. package/dist/module/auth.d.ts +0 -8
  39. package/dist/module/auth.js +0 -80
  40. package/dist/module/auth.js.map +0 -1
  41. package/dist/module/client.d.ts +0 -39
  42. package/dist/module/client.js +0 -96
  43. package/dist/module/client.js.map +0 -1
  44. package/dist/module/index.d.ts +0 -0
  45. package/dist/module/index.js +0 -2
  46. package/dist/module/index.js.map +0 -1
  47. package/dist/module/page.d.ts +0 -102
  48. package/dist/module/page.js +0 -402
  49. package/dist/module/page.js.map +0 -1
  50. package/dist/module/pageRevision.d.ts +0 -29
  51. package/dist/module/pageRevision.js +0 -114
  52. package/dist/module/pageRevision.js.map +0 -1
  53. package/dist/module/pageSource.d.ts +0 -7
  54. package/dist/module/pageSource.js +0 -11
  55. package/dist/module/pageSource.js.map +0 -1
  56. package/dist/module/pageVote.d.ts +0 -14
  57. package/dist/module/pageVote.js +0 -20
  58. package/dist/module/pageVote.js.map +0 -1
  59. package/dist/module/privateMessage.d.ts +0 -29
  60. package/dist/module/privateMessage.js +0 -132
  61. package/dist/module/privateMessage.js.map +0 -1
  62. package/dist/module/site.d.ts +0 -32
  63. package/dist/module/site.js +0 -117
  64. package/dist/module/site.js.map +0 -1
  65. package/dist/module/siteApplication.d.ts +0 -14
  66. package/dist/module/siteApplication.js +0 -100
  67. package/dist/module/siteApplication.js.map +0 -1
  68. package/dist/module/user.d.ts +0 -56
  69. package/dist/module/user.js +0 -115
  70. package/dist/module/user.js.map +0 -1
  71. package/dist/util/index.d.ts +0 -3
  72. package/dist/util/index.js +0 -10
  73. package/dist/util/index.js.map +0 -1
  74. package/dist/util/parser/index.d.ts +0 -1
  75. package/dist/util/parser/index.js +0 -18
  76. package/dist/util/parser/index.js.map +0 -1
  77. package/dist/util/parser/odate.d.ts +0 -12
  78. package/dist/util/parser/odate.js +0 -25
  79. package/dist/util/parser/odate.js.map +0 -1
  80. package/dist/util/parser/user.d.ts +0 -16
  81. package/dist/util/parser/user.js +0 -36
  82. package/dist/util/parser/user.js.map +0 -1
  83. package/dist/util/quickModule.d.ts +0 -96
  84. package/dist/util/quickModule.js +0 -137
  85. package/dist/util/quickModule.js.map +0 -1
  86. package/dist/util/requestUtil.d.ts +0 -26
  87. package/dist/util/requestUtil.js +0 -69
  88. package/dist/util/requestUtil.js.map +0 -1
  89. package/dist/util/stringUtil.d.ts +0 -21
  90. package/dist/util/stringUtil.js +0 -64
  91. package/dist/util/stringUtil.js.map +0 -1
  92. package/dist/util/table/charTable.d.ts +0 -3
  93. package/dist/util/table/charTable.js +0 -472
  94. package/dist/util/table/charTable.js.map +0 -1
  95. package/dist/util/table/index.d.ts +0 -1
  96. package/dist/util/table/index.js +0 -18
  97. package/dist/util/table/index.js.map +0 -1
@@ -0,0 +1,980 @@
1
+ import {
2
+ User
3
+ } from "./index-kka6e8cb.js";
4
+ import {
5
+ LoginRequiredError,
6
+ NoElementError,
7
+ UnexpectedError,
8
+ __legacyDecorateClassTS,
9
+ fromPromise,
10
+ wdErrAsync
11
+ } from "./index-7dqqxq7x.js";
12
+
13
+ // src/module/forum/forum-category.ts
14
+ import * as cheerio3 from "cheerio";
15
+
16
+ // src/common/decorators.ts
17
+ function getClientRef(obj) {
18
+ if (obj.client)
19
+ return obj.client;
20
+ if (obj.site?.client)
21
+ return obj.site.client;
22
+ if (obj.thread?.site?.client)
23
+ return obj.thread.site.client;
24
+ return null;
25
+ }
26
+ function RequireLogin(target, _context) {
27
+ return function(...args) {
28
+ const clientRef = getClientRef(this);
29
+ if (!clientRef) {
30
+ return wdErrAsync(new LoginRequiredError("Client reference not found"));
31
+ }
32
+ const loginResult = clientRef.requireLogin();
33
+ if (loginResult.isErr()) {
34
+ return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required"));
35
+ }
36
+ return target.call(this, ...args);
37
+ };
38
+ }
39
+
40
+ // src/module/forum/forum-thread.ts
41
+ import * as cheerio2 from "cheerio";
42
+
43
+ // src/common/logger.ts
44
+ var LOG_LEVEL_PRIORITY = {
45
+ debug: 0,
46
+ info: 1,
47
+ warn: 2,
48
+ error: 3
49
+ };
50
+ var nullHandler = () => {};
51
+ var consoleHandler = (level, name, message, ...args) => {
52
+ const timestamp = new Date().toISOString();
53
+ const formattedMessage = `${timestamp} [${name}/${level.toUpperCase()}] ${message}`;
54
+ switch (level) {
55
+ case "debug":
56
+ console.debug(formattedMessage, ...args);
57
+ break;
58
+ case "info":
59
+ console.info(formattedMessage, ...args);
60
+ break;
61
+ case "warn":
62
+ console.warn(formattedMessage, ...args);
63
+ break;
64
+ case "error":
65
+ console.error(formattedMessage, ...args);
66
+ break;
67
+ }
68
+ };
69
+
70
+ class Logger {
71
+ name;
72
+ handler;
73
+ level;
74
+ constructor(name, handler = nullHandler, level = "warn") {
75
+ this.name = name;
76
+ this.handler = handler;
77
+ this.level = level;
78
+ }
79
+ setHandler(handler) {
80
+ this.handler = handler;
81
+ }
82
+ setLevel(level) {
83
+ this.level = level;
84
+ }
85
+ shouldLog(level) {
86
+ return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.level];
87
+ }
88
+ log(level, message, ...args) {
89
+ if (this.shouldLog(level)) {
90
+ this.handler(level, this.name, message, ...args);
91
+ }
92
+ }
93
+ debug(message, ...args) {
94
+ this.log("debug", message, ...args);
95
+ }
96
+ info(message, ...args) {
97
+ this.log("info", message, ...args);
98
+ }
99
+ warn(message, ...args) {
100
+ this.log("warn", message, ...args);
101
+ }
102
+ error(message, ...args) {
103
+ this.log("error", message, ...args);
104
+ }
105
+ }
106
+ function getLogger(name = "wikidot") {
107
+ return new Logger(name);
108
+ }
109
+ function setupConsoleHandler(logger, level = "warn") {
110
+ logger.setHandler(consoleHandler);
111
+ logger.setLevel(level);
112
+ }
113
+ var logger = getLogger();
114
+
115
+ // src/module/user/anonymous-user.ts
116
+ class AnonymousUser {
117
+ client;
118
+ id = 0;
119
+ name = "Anonymous";
120
+ unixName = "anonymous";
121
+ avatarUrl = null;
122
+ ip;
123
+ userType = "anonymous";
124
+ constructor(client, ip) {
125
+ this.client = client;
126
+ this.ip = ip;
127
+ }
128
+ isUser() {
129
+ return false;
130
+ }
131
+ isDeletedUser() {
132
+ return false;
133
+ }
134
+ isAnonymousUser() {
135
+ return true;
136
+ }
137
+ isGuestUser() {
138
+ return false;
139
+ }
140
+ isWikidotUser() {
141
+ return false;
142
+ }
143
+ toString() {
144
+ return `AnonymousUser(name=${this.name}, unixName=${this.unixName}, ip=${this.ip})`;
145
+ }
146
+ }
147
+ // src/module/user/deleted-user.ts
148
+ class DeletedUser {
149
+ client;
150
+ id;
151
+ name = "account deleted";
152
+ unixName = "account_deleted";
153
+ avatarUrl = null;
154
+ ip = null;
155
+ userType = "deleted";
156
+ constructor(client, id) {
157
+ this.client = client;
158
+ this.id = id;
159
+ }
160
+ isUser() {
161
+ return false;
162
+ }
163
+ isDeletedUser() {
164
+ return true;
165
+ }
166
+ isAnonymousUser() {
167
+ return false;
168
+ }
169
+ isGuestUser() {
170
+ return false;
171
+ }
172
+ isWikidotUser() {
173
+ return false;
174
+ }
175
+ toString() {
176
+ return `DeletedUser(id=${this.id}, name=${this.name}, unixName=${this.unixName})`;
177
+ }
178
+ }
179
+ // src/module/user/guest-user.ts
180
+ class GuestUser {
181
+ client;
182
+ id = 0;
183
+ name;
184
+ unixName = null;
185
+ avatarUrl;
186
+ ip = null;
187
+ userType = "guest";
188
+ constructor(client, name, avatarUrl = null) {
189
+ this.client = client;
190
+ this.name = name;
191
+ this.avatarUrl = avatarUrl;
192
+ }
193
+ isUser() {
194
+ return false;
195
+ }
196
+ isDeletedUser() {
197
+ return false;
198
+ }
199
+ isAnonymousUser() {
200
+ return false;
201
+ }
202
+ isGuestUser() {
203
+ return true;
204
+ }
205
+ isWikidotUser() {
206
+ return false;
207
+ }
208
+ toString() {
209
+ return `GuestUser(name=${this.name})`;
210
+ }
211
+ }
212
+ // src/module/user/wikidot-user.ts
213
+ class WikidotUser {
214
+ client;
215
+ id = 0;
216
+ name = "Wikidot";
217
+ unixName = "wikidot";
218
+ avatarUrl = null;
219
+ ip = null;
220
+ userType = "wikidot";
221
+ constructor(client) {
222
+ this.client = client;
223
+ }
224
+ isUser() {
225
+ return false;
226
+ }
227
+ isDeletedUser() {
228
+ return false;
229
+ }
230
+ isAnonymousUser() {
231
+ return false;
232
+ }
233
+ isGuestUser() {
234
+ return false;
235
+ }
236
+ isWikidotUser() {
237
+ return true;
238
+ }
239
+ toString() {
240
+ return `WikidotUser(name=${this.name}, unixName=${this.unixName})`;
241
+ }
242
+ }
243
+ // src/util/parser/user.ts
244
+ function parseUser(client, elem) {
245
+ const classAttr = elem.attr("class") ?? "";
246
+ const classes = classAttr.split(/\s+/);
247
+ if (classes.includes("deleted")) {
248
+ const dataId = elem.attr("data-id");
249
+ const userId2 = dataId ? Number.parseInt(dataId, 10) : 0;
250
+ return new DeletedUser(client, userId2);
251
+ }
252
+ const text = elem.text().trim();
253
+ if (text === "(user deleted)") {
254
+ return new DeletedUser(client, 0);
255
+ }
256
+ if (classes.includes("anonymous")) {
257
+ const ipElem = elem.find("span.ip");
258
+ if (ipElem.length > 0) {
259
+ const ip = ipElem.text().replace(/[()]/g, "").trim();
260
+ return new AnonymousUser(client, ip);
261
+ }
262
+ return new AnonymousUser(client, "");
263
+ }
264
+ const imgElem = elem.find("img");
265
+ if (imgElem.length > 0) {
266
+ const src = imgElem.attr("src") ?? "";
267
+ if (src.includes("gravatar.com")) {
268
+ const guestName = text.split(" ")[0] ?? "Guest";
269
+ return new GuestUser(client, guestName, src);
270
+ }
271
+ }
272
+ if (text === "Wikidot") {
273
+ return new WikidotUser(client);
274
+ }
275
+ const links = elem.find("a");
276
+ if (links.length === 0) {
277
+ return new DeletedUser(client, 0);
278
+ }
279
+ const userLink = links.last();
280
+ const userName = userLink.text().trim();
281
+ const href = userLink.attr("href") ?? "";
282
+ const onclick = userLink.attr("onclick") ?? "";
283
+ const unixName = href.replace(/^.*\/user:info\//, "").replace(/\/$/, "");
284
+ const userIdMatch = onclick.match(/userInfo\((\d+)\)/);
285
+ const userId = userIdMatch?.[1] ? Number.parseInt(userIdMatch[1], 10) : 0;
286
+ const avatarUrl = userId > 0 ? `http://www.wikidot.com/avatar.php?userid=${userId}` : undefined;
287
+ return new User(client, {
288
+ id: userId,
289
+ name: userName,
290
+ unixName,
291
+ avatarUrl
292
+ });
293
+ }
294
+ function parseOdate(elem) {
295
+ const classAttr = elem.attr("class") ?? "";
296
+ const timeMatch = classAttr.match(/time_(\d+)/);
297
+ if (timeMatch?.[1]) {
298
+ const unixTime = Number.parseInt(timeMatch[1], 10);
299
+ return new Date(unixTime * 1000);
300
+ }
301
+ const text = elem.text().trim();
302
+ const parsed = Date.parse(text);
303
+ if (!Number.isNaN(parsed)) {
304
+ return new Date(parsed);
305
+ }
306
+ logger.warn(`Failed to parse odate element: class="${classAttr}", text="${text}"`);
307
+ return null;
308
+ }
309
+ // src/module/forum/forum-post.ts
310
+ import * as cheerio from "cheerio";
311
+ class ForumPost {
312
+ thread;
313
+ id;
314
+ title;
315
+ text;
316
+ element;
317
+ createdBy;
318
+ createdAt;
319
+ editedBy;
320
+ editedAt;
321
+ _parentId;
322
+ _source = null;
323
+ constructor(data) {
324
+ this.thread = data.thread;
325
+ this.id = data.id;
326
+ this.title = data.title;
327
+ this.text = data.text;
328
+ this.element = data.element;
329
+ this.createdBy = data.createdBy;
330
+ this.createdAt = data.createdAt;
331
+ this.editedBy = data.editedBy ?? null;
332
+ this.editedAt = data.editedAt ?? null;
333
+ this._parentId = data.parentId ?? null;
334
+ }
335
+ get parentId() {
336
+ return this._parentId;
337
+ }
338
+ getSource() {
339
+ if (this._source !== null) {
340
+ return fromPromise(Promise.resolve(this._source), (e) => new UnexpectedError(String(e)));
341
+ }
342
+ return fromPromise((async () => {
343
+ const result = await this.thread.site.amcRequest([
344
+ {
345
+ moduleName: "forum/sub/ForumEditPostFormModule",
346
+ threadId: this.thread.id,
347
+ postId: this.id
348
+ }
349
+ ]);
350
+ if (result.isErr()) {
351
+ throw result.error;
352
+ }
353
+ const response = result.value[0];
354
+ if (!response) {
355
+ throw new NoElementError("Empty response");
356
+ }
357
+ const $ = cheerio.load(String(response.body ?? ""));
358
+ const sourceElem = $("textarea[name='source']");
359
+ if (sourceElem.length === 0) {
360
+ throw new NoElementError("Source textarea not found");
361
+ }
362
+ this._source = sourceElem.text();
363
+ return this._source;
364
+ })(), (error) => {
365
+ if (error instanceof NoElementError)
366
+ return error;
367
+ return new UnexpectedError(`Failed to get post source: ${String(error)}`);
368
+ });
369
+ }
370
+ edit(source, title) {
371
+ return fromPromise((async () => {
372
+ const formResult = await this.thread.site.amcRequest([
373
+ {
374
+ moduleName: "forum/sub/ForumEditPostFormModule",
375
+ threadId: this.thread.id,
376
+ postId: this.id
377
+ }
378
+ ]);
379
+ if (formResult.isErr()) {
380
+ throw formResult.error;
381
+ }
382
+ const formResponse = formResult.value[0];
383
+ if (!formResponse) {
384
+ throw new NoElementError("Empty form response");
385
+ }
386
+ const $ = cheerio.load(String(formResponse.body ?? ""));
387
+ const revisionInput = $("input[name='currentRevisionId']");
388
+ if (revisionInput.length === 0) {
389
+ throw new NoElementError("Current revision ID input not found");
390
+ }
391
+ const revisionValue = revisionInput.val();
392
+ const currentRevisionId = Number.parseInt(String(revisionValue ?? ""), 10);
393
+ if (Number.isNaN(currentRevisionId)) {
394
+ throw new NoElementError("Invalid revision ID value");
395
+ }
396
+ const editResult = await this.thread.site.amcRequest([
397
+ {
398
+ action: "ForumAction",
399
+ event: "saveEditPost",
400
+ moduleName: "Empty",
401
+ postId: this.id,
402
+ currentRevisionId,
403
+ title: title ?? this.title,
404
+ source
405
+ }
406
+ ]);
407
+ if (editResult.isErr()) {
408
+ throw editResult.error;
409
+ }
410
+ if (title !== undefined) {
411
+ this.title = title;
412
+ }
413
+ this._source = source;
414
+ })(), (error) => {
415
+ if (error instanceof NoElementError || error instanceof LoginRequiredError) {
416
+ return error;
417
+ }
418
+ return new UnexpectedError(`Failed to edit post: ${String(error)}`);
419
+ });
420
+ }
421
+ toString() {
422
+ return `ForumPost(id=${this.id}, title=${this.title})`;
423
+ }
424
+ }
425
+ __legacyDecorateClassTS([
426
+ RequireLogin
427
+ ], ForumPost.prototype, "edit", null);
428
+
429
+ class ForumPostCollection extends Array {
430
+ thread;
431
+ constructor(thread, posts) {
432
+ super();
433
+ this.thread = thread;
434
+ if (posts) {
435
+ this.push(...posts);
436
+ }
437
+ }
438
+ findById(id) {
439
+ return this.find((post) => post.id === id);
440
+ }
441
+ static _parse(thread, $) {
442
+ const posts = [];
443
+ $("div.post").each((_i, postElem) => {
444
+ const $post = $(postElem);
445
+ const postIdAttr = $post.attr("id");
446
+ if (!postIdAttr)
447
+ return;
448
+ const postId = Number.parseInt(postIdAttr.replace("post-", ""), 10);
449
+ if (Number.isNaN(postId))
450
+ return;
451
+ let parentId = null;
452
+ const $parentContainer = $post.parent();
453
+ if ($parentContainer.length > 0) {
454
+ const $grandparent = $parentContainer.parent();
455
+ if ($grandparent.length > 0 && $grandparent[0]?.name !== "body") {
456
+ const grandparentClasses = $grandparent.attr("class") ?? "";
457
+ if (grandparentClasses.includes("post-container")) {
458
+ const $parentPost = $grandparent.find("> div.post");
459
+ if ($parentPost.length > 0) {
460
+ const parentPostIdAttr = $parentPost.attr("id");
461
+ if (parentPostIdAttr) {
462
+ parentId = Number.parseInt(parentPostIdAttr.replace("post-", ""), 10);
463
+ }
464
+ }
465
+ }
466
+ }
467
+ }
468
+ const $wrapper = $post.find("div.long");
469
+ if ($wrapper.length === 0)
470
+ return;
471
+ const $head = $wrapper.find("div.head");
472
+ if ($head.length === 0)
473
+ return;
474
+ const $title = $head.find("div.title");
475
+ const title = $title.text().trim();
476
+ const $content = $wrapper.find("div.content");
477
+ const text = $content.html() ?? "";
478
+ const $info = $head.find("div.info");
479
+ if ($info.length === 0)
480
+ return;
481
+ const $userElem = $info.find("span.printuser");
482
+ if ($userElem.length === 0)
483
+ return;
484
+ const createdBy = parseUser(thread.site.client, $userElem);
485
+ const $odateElem = $info.find("span.odate");
486
+ if ($odateElem.length === 0)
487
+ return;
488
+ const createdAt = parseOdate($odateElem) ?? new Date;
489
+ let editedBy = null;
490
+ let editedAt = null;
491
+ const $changes = $wrapper.find("div.changes");
492
+ if ($changes.length > 0) {
493
+ const $editUserElem = $changes.find("span.printuser");
494
+ const $editOdateElem = $changes.find("span.odate");
495
+ if ($editUserElem.length > 0 && $editOdateElem.length > 0) {
496
+ editedBy = parseUser(thread.site.client, $editUserElem);
497
+ editedAt = parseOdate($editOdateElem);
498
+ }
499
+ }
500
+ posts.push(new ForumPost({
501
+ thread,
502
+ id: postId,
503
+ title,
504
+ text,
505
+ element: postElem,
506
+ createdBy,
507
+ createdAt,
508
+ editedBy,
509
+ editedAt,
510
+ parentId
511
+ }));
512
+ });
513
+ return posts;
514
+ }
515
+ static acquireAllInThread(thread) {
516
+ return fromPromise((async () => {
517
+ const posts = [];
518
+ const firstResult = await thread.site.amcRequest([
519
+ {
520
+ moduleName: "forum/ForumViewThreadPostsModule",
521
+ pageNo: "1",
522
+ t: String(thread.id)
523
+ }
524
+ ]);
525
+ if (firstResult.isErr()) {
526
+ throw firstResult.error;
527
+ }
528
+ const firstResponse = firstResult.value[0];
529
+ if (!firstResponse) {
530
+ throw new NoElementError("Empty response");
531
+ }
532
+ const firstBody = String(firstResponse.body ?? "");
533
+ const $first = cheerio.load(firstBody);
534
+ posts.push(...ForumPostCollection._parse(thread, $first));
535
+ const $pager = $first("div.pager");
536
+ if ($pager.length === 0) {
537
+ return new ForumPostCollection(thread, posts);
538
+ }
539
+ const $pagerTargets = $pager.find("span.target");
540
+ if ($pagerTargets.length < 2) {
541
+ return new ForumPostCollection(thread, posts);
542
+ }
543
+ const lastPageText = $pagerTargets.eq($pagerTargets.length - 2).text().trim();
544
+ const lastPage = Number.parseInt(lastPageText, 10);
545
+ if (Number.isNaN(lastPage) || lastPage <= 1) {
546
+ return new ForumPostCollection(thread, posts);
547
+ }
548
+ const bodies = [];
549
+ for (let page = 2;page <= lastPage; page++) {
550
+ bodies.push({
551
+ moduleName: "forum/ForumViewThreadPostsModule",
552
+ pageNo: String(page),
553
+ t: String(thread.id)
554
+ });
555
+ }
556
+ const additionalResults = await thread.site.amcRequest(bodies);
557
+ if (additionalResults.isErr()) {
558
+ throw additionalResults.error;
559
+ }
560
+ for (const response of additionalResults.value) {
561
+ const body = String(response?.body ?? "");
562
+ const $ = cheerio.load(body);
563
+ posts.push(...ForumPostCollection._parse(thread, $));
564
+ }
565
+ return new ForumPostCollection(thread, posts);
566
+ })(), (error) => {
567
+ if (error instanceof NoElementError)
568
+ return error;
569
+ return new UnexpectedError(`Failed to acquire posts: ${String(error)}`);
570
+ });
571
+ }
572
+ }
573
+
574
+ // src/module/forum/forum-thread.ts
575
+ class ForumThread {
576
+ site;
577
+ id;
578
+ title;
579
+ description;
580
+ createdBy;
581
+ createdAt;
582
+ postCount;
583
+ category;
584
+ _posts = null;
585
+ constructor(data) {
586
+ this.site = data.site;
587
+ this.id = data.id;
588
+ this.title = data.title;
589
+ this.description = data.description;
590
+ this.createdBy = data.createdBy;
591
+ this.createdAt = data.createdAt;
592
+ this.postCount = data.postCount;
593
+ this.category = data.category ?? null;
594
+ }
595
+ getUrl() {
596
+ return `${this.site.getBaseUrl()}/forum/t-${this.id}/`;
597
+ }
598
+ getPosts() {
599
+ if (this._posts !== null) {
600
+ return fromPromise(Promise.resolve(this._posts), (e) => new UnexpectedError(String(e)));
601
+ }
602
+ return ForumPostCollection.acquireAllInThread(this);
603
+ }
604
+ reply(source, title = "", parentPostId = null) {
605
+ return fromPromise((async () => {
606
+ const result = await this.site.amcRequest([
607
+ {
608
+ threadId: String(this.id),
609
+ parentId: parentPostId !== null ? String(parentPostId) : "",
610
+ title,
611
+ source,
612
+ action: "ForumAction",
613
+ event: "savePost",
614
+ moduleName: "Empty"
615
+ }
616
+ ]);
617
+ if (result.isErr()) {
618
+ throw result.error;
619
+ }
620
+ this._posts = null;
621
+ this.postCount += 1;
622
+ return this;
623
+ })(), (error) => new UnexpectedError(`Failed to reply: ${String(error)}`));
624
+ }
625
+ toString() {
626
+ return `ForumThread(id=${this.id}, title=${this.title})`;
627
+ }
628
+ static getFromId(site, threadId, category = null) {
629
+ return fromPromise((async () => {
630
+ const result = await ForumThreadCollection.acquireFromThreadIds(site, [threadId], category);
631
+ if (result.isErr()) {
632
+ throw result.error;
633
+ }
634
+ const thread = result.value[0];
635
+ if (!thread) {
636
+ throw new NoElementError(`Thread not found: ${threadId}`);
637
+ }
638
+ return thread;
639
+ })(), (error) => {
640
+ if (error instanceof NoElementError)
641
+ return error;
642
+ return new UnexpectedError(`Failed to get thread: ${String(error)}`);
643
+ });
644
+ }
645
+ }
646
+ __legacyDecorateClassTS([
647
+ RequireLogin
648
+ ], ForumThread.prototype, "reply", null);
649
+
650
+ class ForumThreadCollection extends Array {
651
+ site;
652
+ constructor(site, threads) {
653
+ super();
654
+ this.site = site;
655
+ if (threads) {
656
+ this.push(...threads);
657
+ }
658
+ }
659
+ findById(id) {
660
+ return this.find((thread) => thread.id === id);
661
+ }
662
+ static acquireAllInCategory(category) {
663
+ return fromPromise((async () => {
664
+ const threads = [];
665
+ const firstResult = await category.site.amcRequest([
666
+ {
667
+ p: 1,
668
+ c: category.id,
669
+ moduleName: "forum/ForumViewCategoryModule"
670
+ }
671
+ ]);
672
+ if (firstResult.isErr()) {
673
+ throw firstResult.error;
674
+ }
675
+ const firstResponse = firstResult.value[0];
676
+ if (!firstResponse) {
677
+ throw new NoElementError("Empty response");
678
+ }
679
+ const firstBody = String(firstResponse.body ?? "");
680
+ const $first = cheerio2.load(firstBody);
681
+ $first("table.table tr.head~tr").each((_i, elem) => {
682
+ const $row = $first(elem);
683
+ const titleElem = $row.find("div.title a");
684
+ const href = titleElem.attr("href") ?? "";
685
+ const threadIdMatch = href.match(/t-(\d+)/);
686
+ if (!threadIdMatch?.[1])
687
+ return;
688
+ const threadId = Number.parseInt(threadIdMatch[1], 10);
689
+ const title = titleElem.text().trim();
690
+ const description = $row.find("div.description").text().trim();
691
+ const postCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
692
+ const $userElem = $row.find("td.started span.printuser");
693
+ const $odateElem = $row.find("td.started span.odate");
694
+ const createdBy = $userElem.length > 0 ? parseUser(category.site.client, $userElem) : null;
695
+ const createdAt = $odateElem.length > 0 ? parseOdate($odateElem) ?? new Date : new Date;
696
+ threads.push(new ForumThread({
697
+ site: category.site,
698
+ id: threadId,
699
+ title,
700
+ description,
701
+ createdBy,
702
+ createdAt,
703
+ postCount,
704
+ category
705
+ }));
706
+ });
707
+ const pager = $first("div.pager");
708
+ if (pager.length === 0) {
709
+ return new ForumThreadCollection(category.site, threads);
710
+ }
711
+ const pagerLinks = pager.find("a");
712
+ if (pagerLinks.length < 2) {
713
+ return new ForumThreadCollection(category.site, threads);
714
+ }
715
+ const lastPageLink = pagerLinks[pagerLinks.length - 2];
716
+ const lastPageText = lastPageLink ? $first(lastPageLink).text().trim() : "1";
717
+ const lastPage = Number.parseInt(lastPageText, 10) || 1;
718
+ if (lastPage <= 1) {
719
+ return new ForumThreadCollection(category.site, threads);
720
+ }
721
+ const bodies = [];
722
+ for (let page = 2;page <= lastPage; page++) {
723
+ bodies.push({
724
+ p: page,
725
+ c: category.id,
726
+ moduleName: "forum/ForumViewCategoryModule"
727
+ });
728
+ }
729
+ const additionalResults = await category.site.amcRequest(bodies);
730
+ if (additionalResults.isErr()) {
731
+ throw additionalResults.error;
732
+ }
733
+ for (const response of additionalResults.value) {
734
+ const body = String(response?.body ?? "");
735
+ const $ = cheerio2.load(body);
736
+ $("table.table tr.head~tr").each((_i, elem) => {
737
+ const $row = $(elem);
738
+ const titleElem = $row.find("div.title a");
739
+ const href = titleElem.attr("href") ?? "";
740
+ const threadIdMatch = href.match(/t-(\d+)/);
741
+ if (!threadIdMatch?.[1])
742
+ return;
743
+ const threadId = Number.parseInt(threadIdMatch[1], 10);
744
+ const title = titleElem.text().trim();
745
+ const description = $row.find("div.description").text().trim();
746
+ const postCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
747
+ const $userElem = $row.find("td.started span.printuser");
748
+ const $odateElem = $row.find("td.started span.odate");
749
+ const createdBy = $userElem.length > 0 ? parseUser(category.site.client, $userElem) : null;
750
+ const createdAt = $odateElem.length > 0 ? parseOdate($odateElem) ?? new Date : new Date;
751
+ threads.push(new ForumThread({
752
+ site: category.site,
753
+ id: threadId,
754
+ title,
755
+ description,
756
+ createdBy,
757
+ createdAt,
758
+ postCount,
759
+ category
760
+ }));
761
+ });
762
+ }
763
+ return new ForumThreadCollection(category.site, threads);
764
+ })(), (error) => {
765
+ if (error instanceof NoElementError)
766
+ return error;
767
+ return new UnexpectedError(`Failed to acquire threads: ${String(error)}`);
768
+ });
769
+ }
770
+ static fromId(site, threadId) {
771
+ return fromPromise((async () => {
772
+ const result = await ForumThreadCollection.acquireFromThreadIds(site, [threadId]);
773
+ if (result.isErr()) {
774
+ throw result.error;
775
+ }
776
+ const thread = result.value[0];
777
+ if (!thread) {
778
+ throw new NoElementError(`Thread not found: ${threadId}`);
779
+ }
780
+ return thread;
781
+ })(), (error) => {
782
+ if (error instanceof NoElementError)
783
+ return error;
784
+ return new UnexpectedError(`Failed to get thread: ${String(error)}`);
785
+ });
786
+ }
787
+ static acquireFromThreadIds(site, threadIds, category = null) {
788
+ return fromPromise((async () => {
789
+ const result = await site.amcRequest(threadIds.map((threadId) => ({
790
+ t: threadId,
791
+ moduleName: "forum/ForumViewThreadModule"
792
+ })));
793
+ if (result.isErr()) {
794
+ throw result.error;
795
+ }
796
+ const threads = [];
797
+ for (let i = 0;i < threadIds.length; i++) {
798
+ const response = result.value[i];
799
+ const threadId = threadIds[i];
800
+ if (!response || !threadId)
801
+ continue;
802
+ const body = String(response.body ?? "");
803
+ const $ = cheerio2.load(body);
804
+ const bcElem = $("div.forum-breadcrumbs");
805
+ if (bcElem.length === 0) {
806
+ throw new NoElementError("Breadcrumbs not found");
807
+ }
808
+ const bcParts = bcElem.text().split("»");
809
+ const title = bcParts.length > 0 ? bcParts[bcParts.length - 1]?.trim() ?? "" : "";
810
+ const descBlockElem = $("div.description-block");
811
+ const description = descBlockElem.text().trim();
812
+ const postCountMatch = $("div.statistics").text().match(/(\d+)/);
813
+ const postCount = postCountMatch?.[1] ? Number.parseInt(postCountMatch[1], 10) : 0;
814
+ threads.push(new ForumThread({
815
+ site,
816
+ id: threadId,
817
+ title,
818
+ description,
819
+ createdBy: null,
820
+ createdAt: new Date,
821
+ postCount,
822
+ category
823
+ }));
824
+ }
825
+ return new ForumThreadCollection(site, threads);
826
+ })(), (error) => {
827
+ if (error instanceof NoElementError)
828
+ return error;
829
+ return new UnexpectedError(`Failed to acquire threads: ${String(error)}`);
830
+ });
831
+ }
832
+ }
833
+
834
+ // src/module/forum/forum-category.ts
835
+ class ForumCategory {
836
+ site;
837
+ id;
838
+ title;
839
+ description;
840
+ threadsCount;
841
+ postsCount;
842
+ _threads = null;
843
+ constructor(data) {
844
+ this.site = data.site;
845
+ this.id = data.id;
846
+ this.title = data.title;
847
+ this.description = data.description;
848
+ this.threadsCount = data.threadsCount;
849
+ this.postsCount = data.postsCount;
850
+ }
851
+ getThreads() {
852
+ if (this._threads !== null) {
853
+ return fromPromise(Promise.resolve(this._threads), (e) => new UnexpectedError(String(e)));
854
+ }
855
+ return fromPromise((async () => {
856
+ const result = await ForumThreadCollection.acquireAllInCategory(this);
857
+ if (result.isErr()) {
858
+ throw result.error;
859
+ }
860
+ this._threads = result.value;
861
+ return this._threads;
862
+ })(), (error) => new UnexpectedError(`Failed to get threads: ${String(error)}`));
863
+ }
864
+ reloadThreads() {
865
+ this._threads = null;
866
+ return this.getThreads();
867
+ }
868
+ createThread(title, description, source) {
869
+ return fromPromise((async () => {
870
+ const result = await this.site.amcRequest([
871
+ {
872
+ moduleName: "Empty",
873
+ action: "ForumAction",
874
+ event: "newThread",
875
+ category_id: this.id,
876
+ title,
877
+ description,
878
+ source
879
+ }
880
+ ]);
881
+ if (result.isErr()) {
882
+ throw result.error;
883
+ }
884
+ const response = result.value[0];
885
+ if (!response || typeof response.threadId !== "number") {
886
+ throw new NoElementError("Thread ID not found in response");
887
+ }
888
+ const threadId = response.threadId;
889
+ const threadResult = await ForumThread.getFromId(this.site, threadId, this);
890
+ if (threadResult.isErr()) {
891
+ throw threadResult.error;
892
+ }
893
+ return threadResult.value;
894
+ })(), (error) => {
895
+ if (error instanceof NoElementError || error instanceof LoginRequiredError) {
896
+ return error;
897
+ }
898
+ return new UnexpectedError(`Failed to create thread: ${String(error)}`);
899
+ });
900
+ }
901
+ toString() {
902
+ return `ForumCategory(id=${this.id}, title=${this.title})`;
903
+ }
904
+ }
905
+ __legacyDecorateClassTS([
906
+ RequireLogin
907
+ ], ForumCategory.prototype, "createThread", null);
908
+
909
+ class ForumCategoryCollection extends Array {
910
+ site;
911
+ constructor(site, categories) {
912
+ super();
913
+ this.site = site;
914
+ if (categories) {
915
+ this.push(...categories);
916
+ }
917
+ }
918
+ findById(id) {
919
+ return this.find((category) => category.id === id);
920
+ }
921
+ static acquireAll(site) {
922
+ return fromPromise((async () => {
923
+ const result = await site.amcRequest([
924
+ {
925
+ moduleName: "forum/ForumStartModule",
926
+ hidden: "true"
927
+ }
928
+ ]);
929
+ if (result.isErr()) {
930
+ throw result.error;
931
+ }
932
+ const response = result.value[0];
933
+ if (!response) {
934
+ throw new NoElementError("Empty response");
935
+ }
936
+ const body = String(response.body ?? "");
937
+ const $ = cheerio3.load(body);
938
+ const categories = [];
939
+ $("table tr.head~tr").each((_i, row) => {
940
+ const $row = $(row);
941
+ const nameElem = $row.find("td.name");
942
+ const nameLinkElem = nameElem.find("a");
943
+ const href = nameLinkElem.attr("href") ?? "";
944
+ const categoryIdMatch = href.match(/c-(\d+)/);
945
+ if (!categoryIdMatch?.[1])
946
+ return;
947
+ const categoryId = Number.parseInt(categoryIdMatch[1], 10);
948
+ const title = nameLinkElem.text().trim();
949
+ const description = nameElem.find("div.description").text().trim();
950
+ const threadsCount = Number.parseInt($row.find("td.threads").text().trim(), 10) || 0;
951
+ const postsCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
952
+ categories.push(new ForumCategory({
953
+ site,
954
+ id: categoryId,
955
+ title,
956
+ description,
957
+ threadsCount,
958
+ postsCount
959
+ }));
960
+ });
961
+ return new ForumCategoryCollection(site, categories);
962
+ })(), (error) => {
963
+ if (error instanceof NoElementError)
964
+ return error;
965
+ return new UnexpectedError(`Failed to acquire categories: ${String(error)}`);
966
+ });
967
+ }
968
+ }
969
+ export {
970
+ ForumThreadCollection,
971
+ ForumThread,
972
+ ForumPostCollection,
973
+ ForumPost,
974
+ ForumCategoryCollection,
975
+ ForumCategory
976
+ };
977
+ export { nullHandler, consoleHandler, Logger, getLogger, setupConsoleHandler, logger, AnonymousUser, DeletedUser, GuestUser, WikidotUser, parseUser, parseOdate, RequireLogin, ForumPost, ForumPostCollection, ForumThread, ForumThreadCollection, ForumCategory, ForumCategoryCollection };
978
+
979
+ //# debugId=B1748EA576F96A3164756E2164756E21
980
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21vZHVsZS9mb3J1bS9mb3J1bS1jYXRlZ29yeS50cyIsICJzcmMvY29tbW9uL2RlY29yYXRvcnMudHMiLCAic3JjL21vZHVsZS9mb3J1bS9mb3J1bS10aHJlYWQudHMiLCAic3JjL2NvbW1vbi9sb2dnZXIudHMiLCAic3JjL21vZHVsZS91c2VyL2Fub255bW91cy11c2VyLnRzIiwgInNyYy9tb2R1bGUvdXNlci9kZWxldGVkLXVzZXIudHMiLCAic3JjL21vZHVsZS91c2VyL2d1ZXN0LXVzZXIudHMiLCAic3JjL21vZHVsZS91c2VyL3dpa2lkb3QtdXNlci50cyIsICJzcmMvdXRpbC9wYXJzZXIvdXNlci50cyIsICJzcmMvbW9kdWxlL2ZvcnVtL2ZvcnVtLXBvc3QudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW1wb3J0ICogYXMgY2hlZXJpbyBmcm9tICdjaGVlcmlvJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IExvZ2luUmVxdWlyZWRFcnJvciwgTm9FbGVtZW50RXJyb3IsIFVuZXhwZWN0ZWRFcnJvciB9IGZyb20gJy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgU2l0ZSB9IGZyb20gJy4uL3NpdGUnO1xuaW1wb3J0IHsgRm9ydW1UaHJlYWQsIEZvcnVtVGhyZWFkQ29sbGVjdGlvbiB9IGZyb20gJy4vZm9ydW0tdGhyZWFkJztcblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgqvjg4bjgrTjg6rjg4fjg7zjgr9cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3J1bUNhdGVnb3J5RGF0YSB7XG4gIHNpdGU6IFNpdGU7XG4gIGlkOiBudW1iZXI7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHRocmVhZHNDb3VudDogbnVtYmVyO1xuICBwb3N0c0NvdW50OiBudW1iZXI7XG59XG5cbi8qKlxuICog44OV44Kp44O844Op44Og44Kr44OG44K044OqXG4gKi9cbmV4cG9ydCBjbGFzcyBGb3J1bUNhdGVnb3J5IHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSB0aHJlYWRzQ291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IHBvc3RzQ291bnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBfdGhyZWFkczogRm9ydW1UaHJlYWRDb2xsZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogRm9ydW1DYXRlZ29yeURhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy50aXRsZSA9IGRhdGEudGl0bGU7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRhdGEuZGVzY3JpcHRpb247XG4gICAgdGhpcy50aHJlYWRzQ291bnQgPSBkYXRhLnRocmVhZHNDb3VudDtcbiAgICB0aGlzLnBvc3RzQ291bnQgPSBkYXRhLnBvc3RzQ291bnQ7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5LiA6Kan44KS5Y+W5b6XXG4gICAqL1xuICBnZXRUaHJlYWRzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICBpZiAodGhpcy5fdGhyZWFkcyAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFByb21pc2UucmVzb2x2ZSh0aGlzLl90aHJlYWRzKSwgKGUpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoU3RyaW5nKGUpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVBbGxJbkNhdGVnb3J5KHRoaXMpO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGhyZWFkcyA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RocmVhZHM7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gZ2V0IHRocmVhZHM6ICR7U3RyaW5nKGVycm9yKX1gKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5LiA6Kan44KS5YaN5Y+W5b6XXG4gICAqL1xuICByZWxvYWRUaHJlYWRzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICB0aGlzLl90aHJlYWRzID0gbnVsbDtcbiAgICByZXR1cm4gdGhpcy5nZXRUaHJlYWRzKCk7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ44KS5L2c5oiQXG4gICAqL1xuICBAUmVxdWlyZUxvZ2luXG4gIGNyZWF0ZVRocmVhZChcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgc291cmNlOiBzdHJpbmdcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdFbXB0eScsXG4gICAgICAgICAgICBhY3Rpb246ICdGb3J1bUFjdGlvbicsXG4gICAgICAgICAgICBldmVudDogJ25ld1RocmVhZCcsXG4gICAgICAgICAgICBjYXRlZ29yeV9pZDogdGhpcy5pZCxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UgfHwgdHlwZW9mIHJlc3BvbnNlLnRocmVhZElkICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignVGhyZWFkIElEIG5vdCBmb3VuZCBpbiByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGhyZWFkSWQgPSByZXNwb25zZS50aHJlYWRJZCBhcyBudW1iZXI7XG4gICAgICAgIGNvbnN0IHRocmVhZFJlc3VsdCA9IGF3YWl0IEZvcnVtVGhyZWFkLmdldEZyb21JZCh0aGlzLnNpdGUsIHRocmVhZElkLCB0aGlzKTtcbiAgICAgICAgaWYgKHRocmVhZFJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgdGhyZWFkUmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aHJlYWRSZXN1bHQudmFsdWU7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIHRocmVhZDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgRm9ydW1DYXRlZ29yeShpZD0ke3RoaXMuaWR9LCB0aXRsZT0ke3RoaXMudGl0bGV9KWA7XG4gIH1cbn1cblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgqvjg4bjgrTjg6rjgrPjg6zjgq/jgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGNsYXNzIEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8Rm9ydW1DYXRlZ29yeT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgc2l0ZTogU2l0ZTtcblxuICBjb25zdHJ1Y3RvcihzaXRlOiBTaXRlLCBjYXRlZ29yaWVzPzogRm9ydW1DYXRlZ29yeVtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNpdGUgPSBzaXRlO1xuICAgIGlmIChjYXRlZ29yaWVzKSB7XG4gICAgICB0aGlzLnB1c2goLi4uY2F0ZWdvcmllcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqL1xuICBmaW5kQnlJZChpZDogbnVtYmVyKTogRm9ydW1DYXRlZ29yeSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgoY2F0ZWdvcnkpID0+IGNhdGVnb3J5LmlkID09PSBpZCk7XG4gIH1cblxuICAvKipcbiAgICog44K144Kk44OI44Gu5YWo44Kr44OG44K044Oq44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUFsbChzaXRlOiBTaXRlKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnZm9ydW0vRm9ydW1TdGFydE1vZHVsZScsXG4gICAgICAgICAgICBoaWRkZW46ICd0cnVlJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignRW1wdHkgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoYm9keSk7XG5cbiAgICAgICAgY29uc3QgY2F0ZWdvcmllczogRm9ydW1DYXRlZ29yeVtdID0gW107XG5cbiAgICAgICAgJCgndGFibGUgdHIuaGVhZH50cicpLmVhY2goKF9pLCByb3cpID0+IHtcbiAgICAgICAgICBjb25zdCAkcm93ID0gJChyb3cpO1xuICAgICAgICAgIGNvbnN0IG5hbWVFbGVtID0gJHJvdy5maW5kKCd0ZC5uYW1lJyk7XG4gICAgICAgICAgY29uc3QgbmFtZUxpbmtFbGVtID0gbmFtZUVsZW0uZmluZCgnYScpO1xuICAgICAgICAgIGNvbnN0IGhyZWYgPSBuYW1lTGlua0VsZW0uYXR0cignaHJlZicpID8/ICcnO1xuXG4gICAgICAgICAgY29uc3QgY2F0ZWdvcnlJZE1hdGNoID0gaHJlZi5tYXRjaCgvYy0oXFxkKykvKTtcbiAgICAgICAgICBpZiAoIWNhdGVnb3J5SWRNYXRjaD8uWzFdKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBjYXRlZ29yeUlkID0gTnVtYmVyLnBhcnNlSW50KGNhdGVnb3J5SWRNYXRjaFsxXSwgMTApO1xuICAgICAgICAgIGNvbnN0IHRpdGxlID0gbmFtZUxpbmtFbGVtLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBuYW1lRWxlbS5maW5kKCdkaXYuZGVzY3JpcHRpb24nKS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IHRocmVhZHNDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnRocmVhZHMnKS50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMDtcbiAgICAgICAgICBjb25zdCBwb3N0c0NvdW50ID0gTnVtYmVyLnBhcnNlSW50KCRyb3cuZmluZCgndGQucG9zdHMnKS50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMDtcblxuICAgICAgICAgIGNhdGVnb3JpZXMucHVzaChcbiAgICAgICAgICAgIG5ldyBGb3J1bUNhdGVnb3J5KHtcbiAgICAgICAgICAgICAgc2l0ZSxcbiAgICAgICAgICAgICAgaWQ6IGNhdGVnb3J5SWQsXG4gICAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgdGhyZWFkc0NvdW50LFxuICAgICAgICAgICAgICBwb3N0c0NvdW50LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uKHNpdGUsIGNhdGVnb3JpZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgY2F0ZWdvcmllczogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiLyoqXG4gKiDjg4fjgrPjg6zjg7zjgr/jg6bjg7zjg4bjgqPjg6rjg4bjgqNcbiAqL1xuXG5pbXBvcnQgeyBMb2dpblJlcXVpcmVkRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMsIHdkRXJyQXN5bmMgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiDjgq/jg6njgqTjgqLjg7Pjg4jlj4LnhafjgpLmjIHjgaTjgqrjg5bjgrjjgqfjgq/jg4jjga7lnotcbiAqL1xuaW50ZXJmYWNlIEhhc0NsaWVudCB7XG4gIGNsaWVudD86IHsgcmVxdWlyZUxvZ2luKCk6IHsgaXNFcnIoKTogYm9vbGVhbjsgZXJyb3I/OiBFcnJvciB9IH07XG4gIHNpdGU/OiB7IGNsaWVudDogeyByZXF1aXJlTG9naW4oKTogeyBpc0VycigpOiBib29sZWFuOyBlcnJvcj86IEVycm9yIH0gfSB9O1xuICB0aHJlYWQ/OiB7IHNpdGU6IHsgY2xpZW50OiB7IHJlcXVpcmVMb2dpbigpOiB7IGlzRXJyKCk6IGJvb2xlYW47IGVycm9yPzogRXJyb3IgfSB9IH0gfTtcbn1cblxuLyoqXG4gKiDjgqrjg5bjgrjjgqfjgq/jg4jjgYvjgonjgq/jg6njgqTjgqLjg7Pjg4jlj4LnhafjgpLlj5blvpfjgZnjgotcbiAqL1xuZnVuY3Rpb24gZ2V0Q2xpZW50UmVmKFxuICBvYmo6IEhhc0NsaWVudFxuKTogeyByZXF1aXJlTG9naW4oKTogeyBpc0VycigpOiBib29sZWFuOyBlcnJvcj86IEVycm9yIH0gfSB8IG51bGwge1xuICBpZiAob2JqLmNsaWVudCkgcmV0dXJuIG9iai5jbGllbnQ7XG4gIGlmIChvYmouc2l0ZT8uY2xpZW50KSByZXR1cm4gb2JqLnNpdGUuY2xpZW50O1xuICBpZiAob2JqLnRocmVhZD8uc2l0ZT8uY2xpZW50KSByZXR1cm4gb2JqLnRocmVhZC5zaXRlLmNsaWVudDtcbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICog44Ot44Kw44Kk44Oz5b+F6aCI44Oh44K944OD44OJ44OH44Kz44Os44O844K/XG4gKlxuICog44GT44Gu44OH44Kz44Os44O844K/44KS6YGp55So44GX44Gf44Oh44K944OD44OJ44Gv44CB5a6f6KGM5YmN44Gr44Ot44Kw44Kk44Oz54q25oWL44KS44OB44Kn44OD44Kv44GZ44KL44CCXG4gKiDjg63jgrDjgqTjg7PjgZfjgabjgYTjgarjgYTloLTlkIjjga8gTG9naW5SZXF1aXJlZEVycm9yIOOCkui/lOOBmeOAglxuICpcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBQYWdlIHtcbiAqICAgQFJlcXVpcmVMb2dpblxuICogICBkZXN0cm95KCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gKiAgICAgcmV0dXJuIGZyb21Qcm9taXNlKGFzeW5jICgpID0+IHsgLi4uIH0sIChlKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKC4uLikpO1xuICogICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBSZXF1aXJlTG9naW48XG4gIFRoaXMgZXh0ZW5kcyBIYXNDbGllbnQsXG4gIEFyZ3MgZXh0ZW5kcyB1bmtub3duW10sXG4gIFJldHVybiBleHRlbmRzIFdpa2lkb3RSZXN1bHRBc3luYzx1bmtub3duPixcbj4oXG4gIHRhcmdldDogKHRoaXM6IFRoaXMsIC4uLmFyZ3M6IEFyZ3MpID0+IFJldHVybixcbiAgX2NvbnRleHQ6IENsYXNzTWV0aG9kRGVjb3JhdG9yQ29udGV4dDxUaGlzLCAodGhpczogVGhpcywgLi4uYXJnczogQXJncykgPT4gUmV0dXJuPlxuKTogKHRoaXM6IFRoaXMsIC4uLmFyZ3M6IEFyZ3MpID0+IFJldHVybiB7XG4gIHJldHVybiBmdW5jdGlvbiAodGhpczogVGhpcywgLi4uYXJnczogQXJncyk6IFJldHVybiB7XG4gICAgY29uc3QgY2xpZW50UmVmID0gZ2V0Q2xpZW50UmVmKHRoaXMpO1xuICAgIGlmICghY2xpZW50UmVmKSB7XG4gICAgICByZXR1cm4gd2RFcnJBc3luYyhuZXcgTG9naW5SZXF1aXJlZEVycm9yKCdDbGllbnQgcmVmZXJlbmNlIG5vdCBmb3VuZCcpKSBhcyB1bmtub3duIGFzIFJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsb2dpblJlc3VsdCA9IGNsaWVudFJlZi5yZXF1aXJlTG9naW4oKTtcbiAgICBpZiAobG9naW5SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgICBQcm9taXNlLnJlamVjdChsb2dpblJlc3VsdC5lcnJvciksXG4gICAgICAgICgpID0+IG5ldyBMb2dpblJlcXVpcmVkRXJyb3IoJ0xvZ2luIHJlcXVpcmVkJylcbiAgICAgICkgYXMgdW5rbm93biBhcyBSZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldC5jYWxsKHRoaXMsIC4uLmFyZ3MpO1xuICB9O1xufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IENoZWVyaW8gfSBmcm9tICdjaGVlcmlvJztcbmltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IE5vRWxlbWVudEVycm9yLCBVbmV4cGVjdGVkRXJyb3IgfSBmcm9tICcuLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uLy4uL2NvbW1vbi90eXBlcyc7XG5pbXBvcnQgeyBwYXJzZU9kYXRlLCBwYXJzZVVzZXIgfSBmcm9tICcuLi8uLi91dGlsL3BhcnNlcic7XG5pbXBvcnQgdHlwZSB7IFNpdGUgfSBmcm9tICcuLi9zaXRlJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyIH0gZnJvbSAnLi4vdXNlcic7XG5pbXBvcnQgdHlwZSB7IEZvcnVtQ2F0ZWdvcnkgfSBmcm9tICcuL2ZvcnVtLWNhdGVnb3J5JztcbmltcG9ydCB7IEZvcnVtUG9zdENvbGxlY3Rpb24gfSBmcm9tICcuL2ZvcnVtLXBvc3QnO1xuXG4vKipcbiAqIOODleOCqeODvOODqeODoOOCueODrOODg+ODieODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvcnVtVGhyZWFkRGF0YSB7XG4gIHNpdGU6IFNpdGU7XG4gIGlkOiBudW1iZXI7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICBwb3N0Q291bnQ6IG51bWJlcjtcbiAgY2F0ZWdvcnk/OiBGb3J1bUNhdGVnb3J5IHwgbnVsbDtcbn1cblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgrnjg6zjg4Pjg4lcbiAqL1xuZXhwb3J0IGNsYXNzIEZvcnVtVGhyZWFkIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQnk6IEFic3RyYWN0VXNlciB8IG51bGw7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQXQ6IERhdGU7XG4gIHB1YmxpYyBwb3N0Q291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbDtcbiAgcHJpdmF0ZSBfcG9zdHM6IEZvcnVtUG9zdENvbGxlY3Rpb24gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBGb3J1bVRocmVhZERhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy50aXRsZSA9IGRhdGEudGl0bGU7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRhdGEuZGVzY3JpcHRpb247XG4gICAgdGhpcy5jcmVhdGVkQnkgPSBkYXRhLmNyZWF0ZWRCeTtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IGRhdGEuY3JlYXRlZEF0O1xuICAgIHRoaXMucG9zdENvdW50ID0gZGF0YS5wb3N0Q291bnQ7XG4gICAgdGhpcy5jYXRlZ29yeSA9IGRhdGEuY2F0ZWdvcnkgPz8gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgrnjg6zjg4Pjg4lVUkxcbiAgICovXG4gIGdldFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnNpdGUuZ2V0QmFzZVVybCgpfS9mb3J1bS90LSR7dGhpcy5pZH0vYDtcbiAgfVxuXG4gIC8qKlxuICAgKiDmipXnqL/kuIDopqfjgpLlj5blvpdcbiAgICovXG4gIGdldFBvc3RzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVBvc3RDb2xsZWN0aW9uPiB7XG4gICAgaWYgKHRoaXMuX3Bvc3RzICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3Bvc3RzKSwgKGUpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoU3RyaW5nKGUpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEZvcnVtUG9zdENvbGxlY3Rpb24uYWNxdWlyZUFsbEluVGhyZWFkKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCueODrOODg+ODieOBq+i/lOS/oVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICByZXBseShcbiAgICBzb3VyY2U6IHN0cmluZyxcbiAgICB0aXRsZSA9ICcnLFxuICAgIHBhcmVudFBvc3RJZDogbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRocmVhZElkOiBTdHJpbmcodGhpcy5pZCksXG4gICAgICAgICAgICBwYXJlbnRJZDogcGFyZW50UG9zdElkICE9PSBudWxsID8gU3RyaW5nKHBhcmVudFBvc3RJZCkgOiAnJyxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgc291cmNlLFxuICAgICAgICAgICAgYWN0aW9uOiAnRm9ydW1BY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQ6ICdzYXZlUG9zdCcsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcG9zdHMgPSBudWxsO1xuICAgICAgICB0aGlzLnBvc3RDb3VudCArPSAxO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byByZXBseTogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBGb3J1bVRocmVhZChpZD0ke3RoaXMuaWR9LCB0aXRsZT0ke3RoaXMudGl0bGV9KWA7XG4gIH1cblxuICAvKipcbiAgICogSUTjgYvjgonjgrnjg6zjg4Pjg4njgpLlj5blvpdcbiAgICovXG4gIHN0YXRpYyBnZXRGcm9tSWQoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICB0aHJlYWRJZDogbnVtYmVyLFxuICAgIGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVGcm9tVGhyZWFkSWRzKHNpdGUsIFt0aHJlYWRJZF0sIGNhdGVnb3J5KTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRocmVhZCA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCF0aHJlYWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoYFRocmVhZCBub3QgZm91bmQ6ICR7dGhyZWFkSWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRocmVhZDtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm9FbGVtZW50RXJyb3IpIHJldHVybiBlcnJvcjtcbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBnZXQgdGhyZWFkOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOOCueODrOODg+ODieOCs+ODrOOCr+OCt+ODp+ODs1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1UaHJlYWRDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8Rm9ydW1UaHJlYWQ+IHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG5cbiAgY29uc3RydWN0b3Ioc2l0ZTogU2l0ZSwgdGhyZWFkcz86IEZvcnVtVGhyZWFkW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2l0ZSA9IHNpdGU7XG4gICAgaWYgKHRocmVhZHMpIHtcbiAgICAgIHRoaXMucHVzaCguLi50aHJlYWRzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSUTjgafmpJzntKJcbiAgICovXG4gIGZpbmRCeUlkKGlkOiBudW1iZXIpOiBGb3J1bVRocmVhZCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgodGhyZWFkKSA9PiB0aHJlYWQuaWQgPT09IGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgqvjg4bjgrTjg6rlhoXjga7lhajjgrnjg6zjg4Pjg4njgpLlj5blvpdcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlQWxsSW5DYXRlZ29yeShjYXRlZ29yeTogRm9ydW1DYXRlZ29yeSk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB0aHJlYWRzOiBGb3J1bVRocmVhZFtdID0gW107XG5cbiAgICAgICAgY29uc3QgZmlyc3RSZXN1bHQgPSBhd2FpdCBjYXRlZ29yeS5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHA6IDEsXG4gICAgICAgICAgICBjOiBjYXRlZ29yeS5pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdmb3J1bS9Gb3J1bVZpZXdDYXRlZ29yeU1vZHVsZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RCb2R5ID0gU3RyaW5nKGZpcnN0UmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICRmaXJzdCA9IGNoZWVyaW8ubG9hZChmaXJzdEJvZHkpO1xuXG4gICAgICAgICRmaXJzdCgndGFibGUudGFibGUgdHIuaGVhZH50cicpLmVhY2goKF9pLCBlbGVtKSA9PiB7XG4gICAgICAgICAgY29uc3QgJHJvdyA9ICRmaXJzdChlbGVtKTtcbiAgICAgICAgICBjb25zdCB0aXRsZUVsZW0gPSAkcm93LmZpbmQoJ2Rpdi50aXRsZSBhJyk7XG4gICAgICAgICAgY29uc3QgaHJlZiA9IHRpdGxlRWxlbS5hdHRyKCdocmVmJykgPz8gJyc7XG4gICAgICAgICAgY29uc3QgdGhyZWFkSWRNYXRjaCA9IGhyZWYubWF0Y2goL3QtKFxcZCspLyk7XG4gICAgICAgICAgaWYgKCF0aHJlYWRJZE1hdGNoPy5bMV0pIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IHRocmVhZElkID0gTnVtYmVyLnBhcnNlSW50KHRocmVhZElkTWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJHJvdy5maW5kKCdkaXYuZGVzY3JpcHRpb24nKS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IHBvc3RDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnBvc3RzJykudGV4dCgpLnRyaW0oKSwgMTApIHx8IDA7XG5cbiAgICAgICAgICAvLyDjg6bjg7zjgrbjg7zjgajml6XmmYLjga7jg5Hjg7zjgrlcbiAgICAgICAgICBjb25zdCAkdXNlckVsZW0gPSAkcm93LmZpbmQoJ3RkLnN0YXJ0ZWQgc3Bhbi5wcmludHVzZXInKTtcbiAgICAgICAgICBjb25zdCAkb2RhdGVFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ub2RhdGUnKTtcblxuICAgICAgICAgIGNvbnN0IGNyZWF0ZWRCeSA9XG4gICAgICAgICAgICAkdXNlckVsZW0ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICA/IHBhcnNlVXNlcihjYXRlZ29yeS5zaXRlLmNsaWVudCwgJHVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pXG4gICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICBjb25zdCBjcmVhdGVkQXQgPVxuICAgICAgICAgICAgJG9kYXRlRWxlbS5sZW5ndGggPiAwXG4gICAgICAgICAgICAgID8gKHBhcnNlT2RhdGUoJG9kYXRlRWxlbSBhcyBDaGVlcmlvPEFueU5vZGU+KSA/PyBuZXcgRGF0ZSgpKVxuICAgICAgICAgICAgICA6IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgICB0aHJlYWRzLnB1c2goXG4gICAgICAgICAgICBuZXcgRm9ydW1UaHJlYWQoe1xuICAgICAgICAgICAgICBzaXRlOiBjYXRlZ29yeS5zaXRlLFxuICAgICAgICAgICAgICBpZDogdGhyZWFkSWQsXG4gICAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgICAgICBjcmVhdGVkQXQsXG4gICAgICAgICAgICAgIHBvc3RDb3VudCxcbiAgICAgICAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENoZWNrIHBhZ2luYXRpb25cbiAgICAgICAgY29uc3QgcGFnZXIgPSAkZmlyc3QoJ2Rpdi5wYWdlcicpO1xuICAgICAgICBpZiAocGFnZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYWdlckxpbmtzID0gcGFnZXIuZmluZCgnYScpO1xuICAgICAgICBpZiAocGFnZXJMaW5rcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsYXN0UGFnZUxpbmsgPSBwYWdlckxpbmtzW3BhZ2VyTGlua3MubGVuZ3RoIC0gMl07XG4gICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9IGxhc3RQYWdlTGluayA/ICRmaXJzdChsYXN0UGFnZUxpbmspLnRleHQoKS50cmltKCkgOiAnMSc7XG4gICAgICAgIGNvbnN0IGxhc3RQYWdlID0gTnVtYmVyLnBhcnNlSW50KGxhc3RQYWdlVGV4dCwgMTApIHx8IDE7XG5cbiAgICAgICAgaWYgKGxhc3RQYWdlIDw9IDEpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtVGhyZWFkQ29sbGVjdGlvbihjYXRlZ29yeS5zaXRlLCB0aHJlYWRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZldGNoIHJlbWFpbmluZyBwYWdlc1xuICAgICAgICBjb25zdCBib2RpZXM6IHsgcDogbnVtYmVyOyBjOiBudW1iZXI7IG1vZHVsZU5hbWU6IHN0cmluZyB9W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgcGFnZSA9IDI7IHBhZ2UgPD0gbGFzdFBhZ2U7IHBhZ2UrKykge1xuICAgICAgICAgIGJvZGllcy5wdXNoKHtcbiAgICAgICAgICAgIHA6IHBhZ2UsXG4gICAgICAgICAgICBjOiBjYXRlZ29yeS5pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdmb3J1bS9Gb3J1bVZpZXdDYXRlZ29yeU1vZHVsZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IGNhdGVnb3J5LnNpdGUuYW1jUmVxdWVzdChib2RpZXMpO1xuICAgICAgICBpZiAoYWRkaXRpb25hbFJlc3VsdHMuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGFkZGl0aW9uYWxSZXN1bHRzLmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCByZXNwb25zZSBvZiBhZGRpdGlvbmFsUmVzdWx0cy52YWx1ZSkge1xuICAgICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2U/LmJvZHkgPz8gJycpO1xuICAgICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoYm9keSk7XG5cbiAgICAgICAgICAkKCd0YWJsZS50YWJsZSB0ci5oZWFkfnRyJykuZWFjaCgoX2ksIGVsZW0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRyb3cgPSAkKGVsZW0pO1xuICAgICAgICAgICAgY29uc3QgdGl0bGVFbGVtID0gJHJvdy5maW5kKCdkaXYudGl0bGUgYScpO1xuICAgICAgICAgICAgY29uc3QgaHJlZiA9IHRpdGxlRWxlbS5hdHRyKCdocmVmJykgPz8gJyc7XG4gICAgICAgICAgICBjb25zdCB0aHJlYWRJZE1hdGNoID0gaHJlZi5tYXRjaCgvdC0oXFxkKykvKTtcbiAgICAgICAgICAgIGlmICghdGhyZWFkSWRNYXRjaD8uWzFdKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHRocmVhZElkID0gTnVtYmVyLnBhcnNlSW50KHRocmVhZElkTWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgICBjb25zdCBkZXNjcmlwdGlvbiA9ICRyb3cuZmluZCgnZGl2LmRlc2NyaXB0aW9uJykudGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc3RDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnBvc3RzJykudGV4dCgpLnRyaW0oKSwgMTApIHx8IDA7XG5cbiAgICAgICAgICAgIC8vIOODpuODvOOCtuODvOOBqOaXpeaZguOBruODkeODvOOCuVxuICAgICAgICAgICAgY29uc3QgJHVzZXJFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgICAgICBjb25zdCAkb2RhdGVFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ub2RhdGUnKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlZEJ5ID1cbiAgICAgICAgICAgICAgJHVzZXJFbGVtLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IHBhcnNlVXNlcihjYXRlZ29yeS5zaXRlLmNsaWVudCwgJHVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pXG4gICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlZEF0ID1cbiAgICAgICAgICAgICAgJG9kYXRlRWxlbS5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgPyAocGFyc2VPZGF0ZSgkb2RhdGVFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pID8/IG5ldyBEYXRlKCkpXG4gICAgICAgICAgICAgICAgOiBuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICB0aHJlYWRzLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBGb3J1bVRocmVhZCh7XG4gICAgICAgICAgICAgICAgc2l0ZTogY2F0ZWdvcnkuc2l0ZSxcbiAgICAgICAgICAgICAgICBpZDogdGhyZWFkSWQsXG4gICAgICAgICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBwb3N0Q291bnQsXG4gICAgICAgICAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yKSByZXR1cm4gZXJyb3I7XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSB0aHJlYWRzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgrnjg6zjg4Pjg4lJROOBi+OCieWNmOS4gOOBruOCueODrOODg+ODieOCkuWPluW+l1xuICAgKiBAcGFyYW0gc2l0ZSAtIOOCteOCpOODiFxuICAgKiBAcGFyYW0gdGhyZWFkSWQgLSDjgrnjg6zjg4Pjg4lJRFxuICAgKi9cbiAgc3RhdGljIGZyb21JZChzaXRlOiBTaXRlLCB0aHJlYWRJZDogbnVtYmVyKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVGcm9tVGhyZWFkSWRzKHNpdGUsIFt0aHJlYWRJZF0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGhyZWFkID0gcmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAoIXRocmVhZCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcihgVGhyZWFkIG5vdCBmb3VuZDogJHt0aHJlYWRJZH1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhyZWFkO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCB0aHJlYWQ6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCueODrOODg+ODiUlE44GL44KJ44K544Os44OD44OJ44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUZyb21UaHJlYWRJZHMoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICB0aHJlYWRJZHM6IG51bWJlcltdLFxuICAgIGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChcbiAgICAgICAgICB0aHJlYWRJZHMubWFwKCh0aHJlYWRJZCkgPT4gKHtcbiAgICAgICAgICAgIHQ6IHRocmVhZElkLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZE1vZHVsZScsXG4gICAgICAgICAgfSkpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGhyZWFkczogRm9ydW1UaHJlYWRbXSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhyZWFkSWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbaV07XG4gICAgICAgICAgY29uc3QgdGhyZWFkSWQgPSB0aHJlYWRJZHNbaV07XG4gICAgICAgICAgaWYgKCFyZXNwb25zZSB8fCAhdGhyZWFkSWQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgYm9keSA9IFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKTtcbiAgICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKGJvZHkpO1xuXG4gICAgICAgICAgLy8gUGFyc2UgdGhyZWFkIGluZm8gZnJvbSBwYWdlXG4gICAgICAgICAgY29uc3QgYmNFbGVtID0gJCgnZGl2LmZvcnVtLWJyZWFkY3J1bWJzJyk7XG4gICAgICAgICAgaWYgKGJjRWxlbS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignQnJlYWRjcnVtYnMgbm90IGZvdW5kJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGJjUGFydHMgPSBiY0VsZW0udGV4dCgpLnNwbGl0KCfCuycpO1xuICAgICAgICAgIGNvbnN0IHRpdGxlID0gYmNQYXJ0cy5sZW5ndGggPiAwID8gKGJjUGFydHNbYmNQYXJ0cy5sZW5ndGggLSAxXT8udHJpbSgpID8/ICcnKSA6ICcnO1xuXG4gICAgICAgICAgY29uc3QgZGVzY0Jsb2NrRWxlbSA9ICQoJ2Rpdi5kZXNjcmlwdGlvbi1ibG9jaycpO1xuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZGVzY0Jsb2NrRWxlbS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICAgICAgY29uc3QgcG9zdENvdW50TWF0Y2ggPSAkKCdkaXYuc3RhdGlzdGljcycpLnRleHQoKS5tYXRjaCgvKFxcZCspLyk7XG4gICAgICAgICAgY29uc3QgcG9zdENvdW50ID0gcG9zdENvdW50TWF0Y2g/LlsxXSA/IE51bWJlci5wYXJzZUludChwb3N0Q291bnRNYXRjaFsxXSwgMTApIDogMDtcblxuICAgICAgICAgIHRocmVhZHMucHVzaChcbiAgICAgICAgICAgIG5ldyBGb3J1bVRocmVhZCh7XG4gICAgICAgICAgICAgIHNpdGUsXG4gICAgICAgICAgICAgIGlkOiB0aHJlYWRJZCxcbiAgICAgICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICBjcmVhdGVkQnk6IG51bGwsXG4gICAgICAgICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgICAgcG9zdENvdW50LFxuICAgICAgICAgICAgICBjYXRlZ29yeSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgRm9ydW1UaHJlYWRDb2xsZWN0aW9uKHNpdGUsIHRocmVhZHMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgdGhyZWFkczogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiLyoqXG4gKiDjg63jgq7jg7PjgrDmqZ/og73jgpLmj5DkvpvjgZnjgovjg6Ljgrjjg6Xjg7zjg6tcbiAqXG4gKiDjgZPjga7jg6Ljgrjjg6Xjg7zjg6vjga/jgIHjg6njgqTjg5bjg6njg6rlhajkvZPjgafkvb/nlKjjgZXjgozjgovjg63jgqzjg7zjgpLoqK3lrprjgZfjgIHmj5DkvpvjgZnjgovjgIJcbiAqIOODh+ODleOCqeODq+ODiOOBp+OBr+WHuuWKm+OCkuihjOOCj+OBmuOAgeOCouODl+ODquOCseODvOOCt+ODp+ODs+WBtOOBp+OBruODreOCsOWItuW+oeOCkuWPr+iDveOBq+OBmeOCi+OAglxuICovXG5cbi8qKlxuICog44Ot44Kw44Os44OZ44OrXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gJ2RlYnVnJyB8ICdpbmZvJyB8ICd3YXJuJyB8ICdlcnJvcic7XG5cbi8qKlxuICog44Ot44Kw44Os44OZ44Or44Gu5YSq5YWI5bqm77yI5pWw5YCk44GM5aSn44GN44GE44G744Gp6YeN6KaB77yJXG4gKi9cbmNvbnN0IExPR19MRVZFTF9QUklPUklUWTogUmVjb3JkPExvZ0xldmVsLCBudW1iZXI+ID0ge1xuICBkZWJ1ZzogMCxcbiAgaW5mbzogMSxcbiAgd2FybjogMixcbiAgZXJyb3I6IDMsXG59O1xuXG4vKipcbiAqIOODreOCrOODvOODj+ODs+ODieODqeODvFxuICovXG5leHBvcnQgdHlwZSBMb2dIYW5kbGVyID0gKFxuICBsZXZlbDogTG9nTGV2ZWwsXG4gIG5hbWU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbikgPT4gdm9pZDtcblxuLyoqXG4gKiBOdWxsSGFuZGxlcjog5L2V44KC5Ye65Yqb44GX44Gq44GE77yI44OH44OV44Kp44Or44OI77yJXG4gKi9cbmV4cG9ydCBjb25zdCBudWxsSGFuZGxlcjogTG9nSGFuZGxlciA9ICgpID0+IHtcbiAgLy8g5L2V44KC44GX44Gq44GEXG59O1xuXG4vKipcbiAqIENvbnNvbGVIYW5kbGVyOiDjgrPjg7Pjgr3jg7zjg6vjgavlh7rlipvjgZnjgotcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnNvbGVIYW5kbGVyOiBMb2dIYW5kbGVyID0gKFxuICBsZXZlbDogTG9nTGV2ZWwsXG4gIG5hbWU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbikgPT4ge1xuICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIGNvbnN0IGZvcm1hdHRlZE1lc3NhZ2UgPSBgJHt0aW1lc3RhbXB9IFske25hbWV9LyR7bGV2ZWwudG9VcHBlckNhc2UoKX1dICR7bWVzc2FnZX1gO1xuXG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdkZWJ1Zyc6XG4gICAgICBjb25zb2xlLmRlYnVnKGZvcm1hdHRlZE1lc3NhZ2UsIC4uLmFyZ3MpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaW5mbyc6XG4gICAgICBjb25zb2xlLmluZm8oZm9ybWF0dGVkTWVzc2FnZSwgLi4uYXJncyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd3YXJuJzpcbiAgICAgIGNvbnNvbGUud2Fybihmb3JtYXR0ZWRNZXNzYWdlLCAuLi5hcmdzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0dGVkTWVzc2FnZSwgLi4uYXJncyk7XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuLyoqXG4gKiDjg63jgqzjg7zjgq/jg6njgrlcbiAqL1xuZXhwb3J0IGNsYXNzIExvZ2dlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGhhbmRsZXI6IExvZ0hhbmRsZXI7XG4gIHByaXZhdGUgbGV2ZWw6IExvZ0xldmVsO1xuXG4gIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgaGFuZGxlcjogTG9nSGFuZGxlciA9IG51bGxIYW5kbGVyLCBsZXZlbDogTG9nTGV2ZWwgPSAnd2FybicpIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gICAgdGhpcy5sZXZlbCA9IGxldmVsO1xuICB9XG5cbiAgLyoqXG4gICAqIOODj+ODs+ODieODqeODvOOCkuioreWumlxuICAgKi9cbiAgc2V0SGFuZGxlcihoYW5kbGVyOiBMb2dIYW5kbGVyKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDjg6zjg5njg6vjgpLoqK3lrppcbiAgICovXG4gIHNldExldmVsKGxldmVsOiBMb2dMZXZlbCk6IHZvaWQge1xuICAgIHRoaXMubGV2ZWwgPSBsZXZlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDmjIflrprjg6zjg5njg6vjgYzjg63jgrDlh7rlipvlr77osaHjgYvjganjgYbjgYtcbiAgICovXG4gIHByaXZhdGUgc2hvdWxkTG9nKGxldmVsOiBMb2dMZXZlbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBMT0dfTEVWRUxfUFJJT1JJVFlbbGV2ZWxdID49IExPR19MRVZFTF9QUklPUklUWVt0aGlzLmxldmVsXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDlh7rliptcbiAgICovXG4gIHByaXZhdGUgbG9nKGxldmVsOiBMb2dMZXZlbCwgbWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zaG91bGRMb2cobGV2ZWwpKSB7XG4gICAgICB0aGlzLmhhbmRsZXIobGV2ZWwsIHRoaXMubmFtZSwgbWVzc2FnZSwgLi4uYXJncyk7XG4gICAgfVxuICB9XG5cbiAgZGVidWcobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmxvZygnZGVidWcnLCBtZXNzYWdlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGluZm8obWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmxvZygnaW5mbycsIG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG5cbiAgd2FybihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIHRoaXMubG9nKCd3YXJuJywgbWVzc2FnZSwgLi4uYXJncyk7XG4gIH1cblxuICBlcnJvcihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIHRoaXMubG9nKCdlcnJvcicsIG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG59XG5cbi8qKlxuICog44Ot44Ks44O844KS5Y+W5b6XXG4gKiBAcGFyYW0gbmFtZSAtIOODreOCrOODvOWQje+8iOODh+ODleOCqeODq+ODiDogXCJ3aWtpZG90XCLvvIlcbiAqIEByZXR1cm5zIOODreOCrOODvOOCpOODs+OCueOCv+ODs+OCuVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyKG5hbWUgPSAnd2lraWRvdCcpOiBMb2dnZXIge1xuICByZXR1cm4gbmV3IExvZ2dlcihuYW1lKTtcbn1cblxuLyoqXG4gKiDjgrPjg7Pjgr3jg7zjg6vlh7rlipvnlKjjg4/jg7Pjg4njg6njgpLoqK3lrppcbiAqIEBwYXJhbSBsb2dnZXIgLSDoqK3lrprjgZnjgovjg63jgqzjg7xcbiAqIEBwYXJhbSBsZXZlbCAtIOODreOCsOODrOODmeODq++8iOODh+ODleOCqeODq+ODiDogXCJ3YXJuXCLvvIlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldHVwQ29uc29sZUhhbmRsZXIobG9nZ2VyOiBMb2dnZXIsIGxldmVsOiBMb2dMZXZlbCA9ICd3YXJuJyk6IHZvaWQge1xuICBsb2dnZXIuc2V0SGFuZGxlcihjb25zb2xlSGFuZGxlcik7XG4gIGxvZ2dlci5zZXRMZXZlbChsZXZlbCk7XG59XG5cbi8qKlxuICog44OR44OD44Kx44O844K45YWo5L2T44Gn5L2/55So44GV44KM44KL44OH44OV44Kp44Or44OI44Ot44Ks44O8XG4gKi9cbmV4cG9ydCBjb25zdCBsb2dnZXI6IExvZ2dlciA9IGdldExvZ2dlcigpO1xuIiwKICAgICJpbXBvcnQgdHlwZSB7IENsaWVudFJlZiB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyLCBVc2VyVHlwZSB9IGZyb20gJy4vYWJzdHJhY3QtdXNlcic7XG5cbi8qKlxuICog5Yy/5ZCN44Om44O844K244O8XG4gKi9cbmV4cG9ydCBjbGFzcyBBbm9ueW1vdXNVc2VyIGltcGxlbWVudHMgQWJzdHJhY3RVc2VyIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50UmVmO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7xJRO+8iOWMv+WQjeOBrzDvvIkgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlkOiBudW1iZXIgPSAwO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7zlkI3vvIjljL/lkI3jga9cIkFub255bW91c1wi77yJICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnQW5vbnltb3VzJztcblxuICAvKiogVU5JWOW9ouW8j+OBruODpuODvOOCtuODvOWQjSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdW5peE5hbWU6IHN0cmluZyA9ICdhbm9ueW1vdXMnO1xuXG4gIC8qKiDjgqLjg5Djgr/jg7xVUkzvvIjljL/lkI3jga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBJUOOCouODieODrOOCuSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXA6IHN0cmluZztcblxuICAvKiog44Om44O844K244O856iu5YilICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyVHlwZTogVXNlclR5cGUgPSAnYW5vbnltb3VzJztcblxuICBjb25zdHJ1Y3RvcihjbGllbnQ6IENsaWVudFJlZiwgaXA6IHN0cmluZykge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMuaXAgPSBpcDtcbiAgfVxuXG4gIC8vIEFic3RyYWN0VXNlcuWun+ijhVxuICBpc1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzRGVsZXRlZFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzQW5vbnltb3VzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpc0d1ZXN0VXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNXaWtpZG90VXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgQW5vbnltb3VzVXNlcihuYW1lPSR7dGhpcy5uYW1lfSwgdW5peE5hbWU9JHt0aGlzLnVuaXhOYW1lfSwgaXA9JHt0aGlzLmlwfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7xcbiAqL1xuZXhwb3J0IGNsYXNzIERlbGV0ZWRVc2VyIGltcGxlbWVudHMgQWJzdHJhY3RVc2VyIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50UmVmO1xuXG4gIC8qKiDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7xJRCAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlcjtcblxuICAvKiog44Om44O844K244O85ZCN77yI5YmK6Zmk5riI44G/44GvXCJhY2NvdW50IGRlbGV0ZWRcIu+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ2FjY291bnQgZGVsZXRlZCc7XG5cbiAgLyoqIFVOSVjlvaLlvI/jga7jg6bjg7zjgrbjg7zlkI0gKi9cbiAgcHVibGljIHJlYWRvbmx5IHVuaXhOYW1lOiBzdHJpbmcgPSAnYWNjb3VudF9kZWxldGVkJztcblxuICAvKiog44Ki44OQ44K/44O8VVJM77yI5YmK6Zmk5riI44G/44GvbnVsbO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXZhdGFyVXJsOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogSVDjgqLjg4njg6zjgrnvvIjliYrpmaTmuIjjgb/jga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBpcDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIOODpuODvOOCtuODvOeoruWIpSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlclR5cGU6IFVzZXJUeXBlID0gJ2RlbGV0ZWQnO1xuXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50UmVmLCBpZDogbnVtYmVyKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5pZCA9IGlkO1xuICB9XG5cbiAgLy8gQWJzdHJhY3RVc2Vy5a6f6KOFXG4gIGlzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNEZWxldGVkVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpc0Fub255bW91c1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzR3Vlc3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc1dpa2lkb3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBEZWxldGVkVXNlcihpZD0ke3RoaXMuaWR9LCBuYW1lPSR7dGhpcy5uYW1lfSwgdW5peE5hbWU9JHt0aGlzLnVuaXhOYW1lfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiDjgrLjgrnjg4jjg6bjg7zjgrbjg7xcbiAqL1xuZXhwb3J0IGNsYXNzIEd1ZXN0VXNlciBpbXBsZW1lbnRzIEFic3RyYWN0VXNlciB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudFJlZjtcblxuICAvKiog44Om44O844K244O8SUTvvIjjgrLjgrnjg4jjga8w77yJICovXG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyID0gMDtcblxuICAvKiog44Ky44K544OI5ZCNICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFVOSVjlvaLlvI/jga7jg6bjg7zjgrbjg7zlkI3vvIjjgrLjgrnjg4jjga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSB1bml4TmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIOOCouODkOOCv+ODvFVSTO+8iEdyYXZhdGFy44Gu5aC05ZCI44GC44KK77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGw7XG5cbiAgLyoqIElQ44Ki44OJ44Os44K577yI44Ky44K544OI44GvbnVsbO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXA6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7znqK7liKUgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVzZXJUeXBlOiBVc2VyVHlwZSA9ICdndWVzdCc7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnRSZWYsIG5hbWU6IHN0cmluZywgYXZhdGFyVXJsOiBzdHJpbmcgfCBudWxsID0gbnVsbCkge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5hdmF0YXJVcmwgPSBhdmF0YXJVcmw7XG4gIH1cblxuICAvLyBBYnN0cmFjdFVzZXLlrp/oo4VcbiAgaXNVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc0RlbGV0ZWRVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc0Fub255bW91c1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzR3Vlc3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlzV2lraWRvdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYEd1ZXN0VXNlcihuYW1lPSR7dGhpcy5uYW1lfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiBXaWtpZG9044K344K544OG44Og44Om44O844K244O8XG4gKi9cbmV4cG9ydCBjbGFzcyBXaWtpZG90VXNlciBpbXBsZW1lbnRzIEFic3RyYWN0VXNlciB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudFJlZjtcblxuICAvKiog44Om44O844K244O8SUTvvIhXaWtpZG9044K344K544OG44Og44GvMO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlciA9IDA7XG5cbiAgLyoqIOODpuODvOOCtuODvOWQjSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ1dpa2lkb3QnO1xuXG4gIC8qKiBVTklY5b2i5byP44Gu44Om44O844K244O85ZCNICovXG4gIHB1YmxpYyByZWFkb25seSB1bml4TmFtZTogc3RyaW5nID0gJ3dpa2lkb3QnO1xuXG4gIC8qKiDjgqLjg5Djgr/jg7xVUkzvvIjjgrfjgrnjg4bjg6Djg6bjg7zjgrbjg7zjga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBJUOOCouODieODrOOCue+8iOOCt+OCueODhuODoOODpuODvOOCtuODvOOBr251bGzvvIkgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiog44Om44O844K244O856iu5YilICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyVHlwZTogVXNlclR5cGUgPSAnd2lraWRvdCc7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnRSZWYpIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgfVxuXG4gIC8vIEFic3RyYWN0VXNlcuWun+ijhVxuICBpc1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzRGVsZXRlZFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzQW5vbnltb3VzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNHdWVzdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzV2lraWRvdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgV2lraWRvdFVzZXIobmFtZT0ke3RoaXMubmFtZX0sIHVuaXhOYW1lPSR7dGhpcy51bml4TmFtZX0pYDtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgdHlwZSAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL2NvbW1vbi9sb2dnZXInO1xuaW1wb3J0IHR5cGUgeyBDbGllbnRSZWYgfSBmcm9tICcuLi8uLi9tb2R1bGUvdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIgfSBmcm9tICcuLi8uLi9tb2R1bGUvdXNlcic7XG5pbXBvcnQgeyBBbm9ueW1vdXNVc2VyLCBEZWxldGVkVXNlciwgR3Vlc3RVc2VyLCBVc2VyLCBXaWtpZG90VXNlciB9IGZyb20gJy4uLy4uL21vZHVsZS91c2VyJztcblxuLyoqXG4gKiBwcmludHVzZXLopoHntKDjgpLjg5Hjg7zjgrnjgZfjgIHjg6bjg7zjgrbjg7zjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZlcbiAqXG4gKiBAcGFyYW0gY2xpZW50IC0gV2lraWRvdOOCr+ODqeOCpOOCouODs+ODiFxuICogQHBhcmFtIGVsZW0gLSDjg5Hjg7zjgrnlr77osaHjga7opoHntKDvvIhwcmludHVzZXLjgq/jg6njgrnjgYzjgaTjgYTjgZ/opoHntKDvvIlcbiAqIEByZXR1cm5zIOODkeODvOOCueOBleOCjOOBpuW+l+OCieOCjOOBn+ODpuODvOOCtuODvOOCquODluOCuOOCp+OCr+ODiFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VVc2VyKGNsaWVudDogQ2xpZW50UmVmLCBlbGVtOiBjaGVlcmlvLkNoZWVyaW88QW55Tm9kZT4pOiBBYnN0cmFjdFVzZXIge1xuICBjb25zdCBjbGFzc0F0dHIgPSBlbGVtLmF0dHIoJ2NsYXNzJykgPz8gJyc7XG4gIGNvbnN0IGNsYXNzZXMgPSBjbGFzc0F0dHIuc3BsaXQoL1xccysvKTtcblxuICAvLyDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7zliKTlrppcbiAgaWYgKGNsYXNzZXMuaW5jbHVkZXMoJ2RlbGV0ZWQnKSkge1xuICAgIGNvbnN0IGRhdGFJZCA9IGVsZW0uYXR0cignZGF0YS1pZCcpO1xuICAgIGNvbnN0IHVzZXJJZCA9IGRhdGFJZCA/IE51bWJlci5wYXJzZUludChkYXRhSWQsIDEwKSA6IDA7XG4gICAgcmV0dXJuIG5ldyBEZWxldGVkVXNlcihjbGllbnQsIHVzZXJJZCk7XG4gIH1cblxuICAvLyDjg4bjgq3jgrnjg4jjgYwgXCIodXNlciBkZWxldGVkKVwiIOOBruWgtOWQiFxuICBjb25zdCB0ZXh0ID0gZWxlbS50ZXh0KCkudHJpbSgpO1xuICBpZiAodGV4dCA9PT0gJyh1c2VyIGRlbGV0ZWQpJykge1xuICAgIHJldHVybiBuZXcgRGVsZXRlZFVzZXIoY2xpZW50LCAwKTtcbiAgfVxuXG4gIC8vIOWMv+WQjeODpuODvOOCtuODvOWIpOWumlxuICBpZiAoY2xhc3Nlcy5pbmNsdWRlcygnYW5vbnltb3VzJykpIHtcbiAgICBjb25zdCBpcEVsZW0gPSBlbGVtLmZpbmQoJ3NwYW4uaXAnKTtcbiAgICBpZiAoaXBFbGVtLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGlwID0gaXBFbGVtLnRleHQoKS5yZXBsYWNlKC9bKCldL2csICcnKS50cmltKCk7XG4gICAgICByZXR1cm4gbmV3IEFub255bW91c1VzZXIoY2xpZW50LCBpcCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzVXNlcihjbGllbnQsICcnKTtcbiAgfVxuXG4gIC8vIOOCsuOCueODiOODpuODvOOCtuODvOWIpOWumu+8iEdyYXZhdGFy44Ki44OQ44K/44O844KS5oyB44Gk77yJXG4gIGNvbnN0IGltZ0VsZW0gPSBlbGVtLmZpbmQoJ2ltZycpO1xuICBpZiAoaW1nRWxlbS5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgc3JjID0gaW1nRWxlbS5hdHRyKCdzcmMnKSA/PyAnJztcbiAgICBpZiAoc3JjLmluY2x1ZGVzKCdncmF2YXRhci5jb20nKSkge1xuICAgICAgY29uc3QgZ3Vlc3ROYW1lID0gdGV4dC5zcGxpdCgnICcpWzBdID8/ICdHdWVzdCc7XG4gICAgICByZXR1cm4gbmV3IEd1ZXN0VXNlcihjbGllbnQsIGd1ZXN0TmFtZSwgc3JjKTtcbiAgICB9XG4gIH1cblxuICAvLyBXaWtpZG9044K344K544OG44Og44Om44O844K244O85Yik5a6aXG4gIGlmICh0ZXh0ID09PSAnV2lraWRvdCcpIHtcbiAgICByZXR1cm4gbmV3IFdpa2lkb3RVc2VyKGNsaWVudCk7XG4gIH1cblxuICAvLyDpgJrluLjjg6bjg7zjgrbjg7xcbiAgY29uc3QgbGlua3MgPSBlbGVtLmZpbmQoJ2EnKTtcbiAgaWYgKGxpbmtzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIOODquODs+OCr+OBjOOBquOBhOWgtOWQiOOBr0RlbGV0ZWRVc2Vy44Go44GX44Gm5omx44GGXG4gICAgcmV0dXJuIG5ldyBEZWxldGVkVXNlcihjbGllbnQsIDApO1xuICB9XG5cbiAgLy8g5pyA5b6M44Gu44Oq44Oz44Kv44GM44Om44O844K244O844Oq44Oz44KvXG4gIGNvbnN0IHVzZXJMaW5rID0gbGlua3MubGFzdCgpO1xuICBjb25zdCB1c2VyTmFtZSA9IHVzZXJMaW5rLnRleHQoKS50cmltKCk7XG4gIGNvbnN0IGhyZWYgPSB1c2VyTGluay5hdHRyKCdocmVmJykgPz8gJyc7XG4gIGNvbnN0IG9uY2xpY2sgPSB1c2VyTGluay5hdHRyKCdvbmNsaWNrJykgPz8gJyc7XG5cbiAgLy8gdW5peF9uYW1l44KSaHJlZuOBi+OCieaKveWHulxuICBjb25zdCB1bml4TmFtZSA9IGhyZWYucmVwbGFjZSgvXi4qXFwvdXNlcjppbmZvXFwvLywgJycpLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG5cbiAgLy8gdXNlcl9pZOOCkm9uY2xpY2vjgYvjgonmir3lh7pcbiAgLy8g44OR44K/44O844OzOiBcIldJS0lET1QucGFnZS5saXN0ZW5lcnMudXNlckluZm8oMTIzNDU2KTsgcmV0dXJuIGZhbHNlO1wiXG4gIGNvbnN0IHVzZXJJZE1hdGNoID0gb25jbGljay5tYXRjaCgvdXNlckluZm9cXCgoXFxkKylcXCkvKTtcbiAgY29uc3QgdXNlcklkID0gdXNlcklkTWF0Y2g/LlsxXSA/IE51bWJlci5wYXJzZUludCh1c2VySWRNYXRjaFsxXSwgMTApIDogMDtcblxuICAvLyDjgqLjg5Djgr/jg7xVUkzjgpLnlJ/miJBcbiAgY29uc3QgYXZhdGFyVXJsID0gdXNlcklkID4gMCA/IGBodHRwOi8vd3d3Lndpa2lkb3QuY29tL2F2YXRhci5waHA/dXNlcmlkPSR7dXNlcklkfWAgOiB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIG5ldyBVc2VyKGNsaWVudCwge1xuICAgIGlkOiB1c2VySWQsXG4gICAgbmFtZTogdXNlck5hbWUsXG4gICAgdW5peE5hbWUsXG4gICAgYXZhdGFyVXJsLFxuICB9KTtcbn1cblxuLyoqXG4gKiBvZGF0Zeimgee0oOOBi+OCieaXpeaZguOCkuODkeODvOOCueOBmeOCi1xuICpcbiAqIEBwYXJhbSBlbGVtIC0g44OR44O844K55a++6LGh44Gu6KaB57Sg77yIb2RhdGXopoHntKDvvIlcbiAqIEByZXR1cm5zIOODkeODvOOCueOBleOCjOOBn0RhdGXjgIHjg5Hjg7zjgrnlpLHmlZfmmYLjga9udWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU9kYXRlKGVsZW06IGNoZWVyaW8uQ2hlZXJpbzxBbnlOb2RlPik6IERhdGUgfCBudWxsIHtcbiAgY29uc3QgY2xhc3NBdHRyID0gZWxlbS5hdHRyKCdjbGFzcycpID8/ICcnO1xuXG4gIC8vIOOCr+ODqeOCueOBi+OCiSBVbml4IOOCv+OCpOODoOOCueOCv+ODs+ODl+OCkuaKveWHulxuICAvLyDjg5Hjgr/jg7zjg7M6IFwib2RhdGUgdGltZV8xMjM0NTY3ODkwIGZvcm1hdF8uLi5cIiDjga7jgojjgYbjgarlvaLlvI9cbiAgY29uc3QgdGltZU1hdGNoID0gY2xhc3NBdHRyLm1hdGNoKC90aW1lXyhcXGQrKS8pO1xuICBpZiAodGltZU1hdGNoPy5bMV0pIHtcbiAgICBjb25zdCB1bml4VGltZSA9IE51bWJlci5wYXJzZUludCh0aW1lTWF0Y2hbMV0sIDEwKTtcbiAgICByZXR1cm4gbmV3IERhdGUodW5peFRpbWUgKiAxMDAwKTtcbiAgfVxuXG4gIC8vIOODleOCqeODvOODq+ODkOODg+OCrzog44OG44Kt44K544OI44GL44KJ44OR44O844K5XG4gIGNvbnN0IHRleHQgPSBlbGVtLnRleHQoKS50cmltKCk7XG4gIGNvbnN0IHBhcnNlZCA9IERhdGUucGFyc2UodGV4dCk7XG4gIGlmICghTnVtYmVyLmlzTmFOKHBhcnNlZCkpIHtcbiAgICByZXR1cm4gbmV3IERhdGUocGFyc2VkKTtcbiAgfVxuXG4gIC8vIOODkeODvOOCueOBp+OBjeOBquOBhOWgtOWQiOOBr251bGzjgpLov5TljbTjgZfjgIHorablkYrjgpLjg63jgrDlh7rliptcbiAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBwYXJzZSBvZGF0ZSBlbGVtZW50OiBjbGFzcz1cIiR7Y2xhc3NBdHRyfVwiLCB0ZXh0PVwiJHt0ZXh0fVwiYCk7XG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IENoZWVyaW8sIENoZWVyaW9BUEkgfSBmcm9tICdjaGVlcmlvJztcbmltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUsIEVsZW1lbnQgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IExvZ2luUmVxdWlyZWRFcnJvciwgTm9FbGVtZW50RXJyb3IsIFVuZXhwZWN0ZWRFcnJvciB9IGZyb20gJy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB7IHBhcnNlT2RhdGUsIHBhcnNlVXNlciB9IGZyb20gJy4uLy4uL3V0aWwvcGFyc2VyJztcbmltcG9ydCB0eXBlIHsgQ2xpZW50IH0gZnJvbSAnLi4vY2xpZW50JztcbmltcG9ydCB0eXBlIHsgRm9ydW1UaHJlYWRSZWYgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IEFic3RyYWN0VXNlciB9IGZyb20gJy4uL3VzZXInO1xuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov+ODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvcnVtUG9zdERhdGEge1xuICB0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmO1xuICBpZDogbnVtYmVyO1xuICB0aXRsZTogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gIGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGVkaXRlZEJ5PzogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgZWRpdGVkQXQ/OiBEYXRlIHwgbnVsbDtcbiAgcGFyZW50SWQ/OiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1Qb3N0IHtcbiAgcHVibGljIHJlYWRvbmx5IHRocmVhZDogRm9ydW1UaHJlYWRSZWY7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGVsZW1lbnQ6IEVsZW1lbnQ7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQnk6IEFic3RyYWN0VXNlcjtcbiAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRBdDogRGF0ZTtcbiAgcHVibGljIHJlYWRvbmx5IGVkaXRlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsO1xuICBwdWJsaWMgcmVhZG9ubHkgZWRpdGVkQXQ6IERhdGUgfCBudWxsO1xuICBwcml2YXRlIF9wYXJlbnRJZDogbnVtYmVyIHwgbnVsbDtcbiAgcHJpdmF0ZSBfc291cmNlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBGb3J1bVBvc3REYXRhKSB7XG4gICAgdGhpcy50aHJlYWQgPSBkYXRhLnRocmVhZDtcbiAgICB0aGlzLmlkID0gZGF0YS5pZDtcbiAgICB0aGlzLnRpdGxlID0gZGF0YS50aXRsZTtcbiAgICB0aGlzLnRleHQgPSBkYXRhLnRleHQ7XG4gICAgdGhpcy5lbGVtZW50ID0gZGF0YS5lbGVtZW50O1xuICAgIHRoaXMuY3JlYXRlZEJ5ID0gZGF0YS5jcmVhdGVkQnk7XG4gICAgdGhpcy5jcmVhdGVkQXQgPSBkYXRhLmNyZWF0ZWRBdDtcbiAgICB0aGlzLmVkaXRlZEJ5ID0gZGF0YS5lZGl0ZWRCeSA/PyBudWxsO1xuICAgIHRoaXMuZWRpdGVkQXQgPSBkYXRhLmVkaXRlZEF0ID8/IG51bGw7XG4gICAgdGhpcy5fcGFyZW50SWQgPSBkYXRhLnBhcmVudElkID8/IG51bGw7XG4gIH1cblxuICAvKipcbiAgICog6Kaq5oqV56i/SURcbiAgICovXG4gIGdldCBwYXJlbnRJZCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50SWQ7XG4gIH1cblxuICAvKipcbiAgICog44K944O844K544Kz44O844OJ77yIV2lraWRvdOiomOazle+8ieOCkuWPluW+l1xuICAgKi9cbiAgZ2V0U291cmNlKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxzdHJpbmc+IHtcbiAgICBpZiAodGhpcy5fc291cmNlICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NvdXJjZSksIChlKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKFN0cmluZyhlKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL3N1Yi9Gb3J1bUVkaXRQb3N0Rm9ybU1vZHVsZScsXG4gICAgICAgICAgICB0aHJlYWRJZDogdGhpcy50aHJlYWQuaWQsXG4gICAgICAgICAgICBwb3N0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ0VtcHR5IHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKSk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUVsZW0gPSAkKFwidGV4dGFyZWFbbmFtZT0nc291cmNlJ11cIik7XG4gICAgICAgIGlmIChzb3VyY2VFbGVtLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignU291cmNlIHRleHRhcmVhIG5vdCBmb3VuZCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHNvdXJjZUVsZW0udGV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBwb3N0IHNvdXJjZTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5oqV56i/44KS57eo6ZuG44GZ44KLXG4gICAqIEBwYXJhbSBzb3VyY2UgLSDmlrDjgZfjgYTjgr3jg7zjgrnvvIhXaWtpZG906KiY5rOV77yJXG4gICAqIEBwYXJhbSB0aXRsZSAtIOaWsOOBl+OBhOOCv+OCpOODiOODq++8iOecgeeVpeaZguOBr+ePvuWcqOOBruOCv+OCpOODiOODq+OCkue2reaMge+8iVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBlZGl0KHNvdXJjZTogc3RyaW5nLCB0aXRsZT86IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8g54++5Zyo44Gu44Oq44OT44K444On44OzSUTjgpLlj5blvpdcbiAgICAgICAgY29uc3QgZm9ybVJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL3N1Yi9Gb3J1bUVkaXRQb3N0Rm9ybU1vZHVsZScsXG4gICAgICAgICAgICB0aHJlYWRJZDogdGhpcy50aHJlYWQuaWQsXG4gICAgICAgICAgICBwb3N0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZvcm1SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGZvcm1SZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmb3JtUmVzcG9uc2UgPSBmb3JtUmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAoIWZvcm1SZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignRW1wdHkgZm9ybSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChTdHJpbmcoZm9ybVJlc3BvbnNlLmJvZHkgPz8gJycpKTtcbiAgICAgICAgY29uc3QgcmV2aXNpb25JbnB1dCA9ICQoXCJpbnB1dFtuYW1lPSdjdXJyZW50UmV2aXNpb25JZCddXCIpO1xuICAgICAgICBpZiAocmV2aXNpb25JbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ0N1cnJlbnQgcmV2aXNpb24gSUQgaW5wdXQgbm90IGZvdW5kJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXZpc2lvblZhbHVlID0gcmV2aXNpb25JbnB1dC52YWwoKTtcbiAgICAgICAgY29uc3QgY3VycmVudFJldmlzaW9uSWQgPSBOdW1iZXIucGFyc2VJbnQoU3RyaW5nKHJldmlzaW9uVmFsdWUgPz8gJycpLCAxMCk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNOYU4oY3VycmVudFJldmlzaW9uSWQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdJbnZhbGlkIHJldmlzaW9uIElEIHZhbHVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDnt6jpm4bjgpLkv53lrZhcbiAgICAgICAgY29uc3QgZWRpdFJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWN0aW9uOiAnRm9ydW1BY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQ6ICdzYXZlRWRpdFBvc3QnLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICAgIHBvc3RJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGN1cnJlbnRSZXZpc2lvbklkLFxuICAgICAgICAgICAgdGl0bGU6IHRpdGxlID8/IHRoaXMudGl0bGUsXG4gICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGVkaXRSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGVkaXRSZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDjg63jg7zjgqvjg6vnirbmhYvjgpLmm7TmlrBcbiAgICAgICAgaWYgKHRpdGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLnRpdGxlID0gdGl0bGU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlID0gc291cmNlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGVkaXQgcG9zdDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgRm9ydW1Qb3N0KGlkPSR7dGhpcy5pZH0sIHRpdGxlPSR7dGhpcy50aXRsZX0pYDtcbiAgfVxufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov+OCs+ODrOOCr+OCt+ODp+ODs1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1Qb3N0Q29sbGVjdGlvbiBleHRlbmRzIEFycmF5PEZvcnVtUG9zdD4ge1xuICBwdWJsaWMgcmVhZG9ubHkgdGhyZWFkOiBGb3J1bVRocmVhZFJlZjtcblxuICBjb25zdHJ1Y3Rvcih0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmLCBwb3N0cz86IEZvcnVtUG9zdFtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnRocmVhZCA9IHRocmVhZDtcbiAgICBpZiAocG9zdHMpIHtcbiAgICAgIHRoaXMucHVzaCguLi5wb3N0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqIEBwYXJhbSBpZCAtIOaKleeov0lEXG4gICAqIEByZXR1cm5zIOaKleeov++8iOWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr3VuZGVmaW5lZO+8iVxuICAgKi9cbiAgZmluZEJ5SWQoaWQ6IG51bWJlcik6IEZvcnVtUG9zdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgocG9zdCkgPT4gcG9zdC5pZCA9PT0gaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhUTUzjgYvjgonmipXnqL/jgpLjg5Hjg7zjgrnjgZnjgovvvIjlhoXpg6jjg6Hjgr3jg4Pjg4nvvIlcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9wYXJzZSh0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmLCAkOiBDaGVlcmlvQVBJKTogRm9ydW1Qb3N0W10ge1xuICAgIGNvbnN0IHBvc3RzOiBGb3J1bVBvc3RbXSA9IFtdO1xuXG4gICAgJCgnZGl2LnBvc3QnKS5lYWNoKChfaSwgcG9zdEVsZW0pID0+IHtcbiAgICAgIGNvbnN0ICRwb3N0ID0gJChwb3N0RWxlbSk7XG4gICAgICBjb25zdCBwb3N0SWRBdHRyID0gJHBvc3QuYXR0cignaWQnKTtcbiAgICAgIGlmICghcG9zdElkQXR0cikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3N0SWQgPSBOdW1iZXIucGFyc2VJbnQocG9zdElkQXR0ci5yZXBsYWNlKCdwb3N0LScsICcnKSwgMTApO1xuICAgICAgaWYgKE51bWJlci5pc05hTihwb3N0SWQpKSByZXR1cm47XG5cbiAgICAgIC8vIOimquaKleeov0lE44Gu5Y+W5b6XXG4gICAgICBsZXQgcGFyZW50SWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgJHBhcmVudENvbnRhaW5lciA9ICRwb3N0LnBhcmVudCgpO1xuICAgICAgaWYgKCRwYXJlbnRDb250YWluZXIubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCAkZ3JhbmRwYXJlbnQgPSAkcGFyZW50Q29udGFpbmVyLnBhcmVudCgpO1xuICAgICAgICBpZiAoJGdyYW5kcGFyZW50Lmxlbmd0aCA+IDAgJiYgJGdyYW5kcGFyZW50WzBdPy5uYW1lICE9PSAnYm9keScpIHtcbiAgICAgICAgICBjb25zdCBncmFuZHBhcmVudENsYXNzZXMgPSAkZ3JhbmRwYXJlbnQuYXR0cignY2xhc3MnKSA/PyAnJztcbiAgICAgICAgICBpZiAoZ3JhbmRwYXJlbnRDbGFzc2VzLmluY2x1ZGVzKCdwb3N0LWNvbnRhaW5lcicpKSB7XG4gICAgICAgICAgICBjb25zdCAkcGFyZW50UG9zdCA9ICRncmFuZHBhcmVudC5maW5kKCc+IGRpdi5wb3N0Jyk7XG4gICAgICAgICAgICBpZiAoJHBhcmVudFBvc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBwYXJlbnRQb3N0SWRBdHRyID0gJHBhcmVudFBvc3QuYXR0cignaWQnKTtcbiAgICAgICAgICAgICAgaWYgKHBhcmVudFBvc3RJZEF0dHIpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRJZCA9IE51bWJlci5wYXJzZUludChwYXJlbnRQb3N0SWRBdHRyLnJlcGxhY2UoJ3Bvc3QtJywgJycpLCAxMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g44K/44Kk44OI44Or44Go5pys5paH44Gu5Y+W5b6XXG4gICAgICBjb25zdCAkd3JhcHBlciA9ICRwb3N0LmZpbmQoJ2Rpdi5sb25nJyk7XG4gICAgICBpZiAoJHdyYXBwZXIubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGNvbnN0ICRoZWFkID0gJHdyYXBwZXIuZmluZCgnZGl2LmhlYWQnKTtcbiAgICAgIGlmICgkaGVhZC5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgJHRpdGxlID0gJGhlYWQuZmluZCgnZGl2LnRpdGxlJyk7XG4gICAgICBjb25zdCB0aXRsZSA9ICR0aXRsZS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICBjb25zdCAkY29udGVudCA9ICR3cmFwcGVyLmZpbmQoJ2Rpdi5jb250ZW50Jyk7XG4gICAgICBjb25zdCB0ZXh0ID0gJGNvbnRlbnQuaHRtbCgpID8/ICcnO1xuXG4gICAgICAvLyDmipXnqL/ogIXjgajml6XmmYJcbiAgICAgIGNvbnN0ICRpbmZvID0gJGhlYWQuZmluZCgnZGl2LmluZm8nKTtcbiAgICAgIGlmICgkaW5mby5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgJHVzZXJFbGVtID0gJGluZm8uZmluZCgnc3Bhbi5wcmludHVzZXInKTtcbiAgICAgIGlmICgkdXNlckVsZW0ubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGNyZWF0ZWRCeSA9IHBhcnNlVXNlcih0aHJlYWQuc2l0ZS5jbGllbnQgYXMgQ2xpZW50LCAkdXNlckVsZW0gYXMgQ2hlZXJpbzxBbnlOb2RlPik7XG5cbiAgICAgIGNvbnN0ICRvZGF0ZUVsZW0gPSAkaW5mby5maW5kKCdzcGFuLm9kYXRlJyk7XG4gICAgICBpZiAoJG9kYXRlRWxlbS5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgY3JlYXRlZEF0ID0gcGFyc2VPZGF0ZSgkb2RhdGVFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pID8/IG5ldyBEYXRlKCk7XG5cbiAgICAgIC8vIOe3qOmbhuaDheWgse+8iOWtmOWcqOOBmeOCi+WgtOWQiO+8iVxuICAgICAgbGV0IGVkaXRlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCBlZGl0ZWRBdDogRGF0ZSB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgJGNoYW5nZXMgPSAkd3JhcHBlci5maW5kKCdkaXYuY2hhbmdlcycpO1xuICAgICAgaWYgKCRjaGFuZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgJGVkaXRVc2VyRWxlbSA9ICRjaGFuZ2VzLmZpbmQoJ3NwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgIGNvbnN0ICRlZGl0T2RhdGVFbGVtID0gJGNoYW5nZXMuZmluZCgnc3Bhbi5vZGF0ZScpO1xuICAgICAgICBpZiAoJGVkaXRVc2VyRWxlbS5sZW5ndGggPiAwICYmICRlZGl0T2RhdGVFbGVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBlZGl0ZWRCeSA9IHBhcnNlVXNlcih0aHJlYWQuc2l0ZS5jbGllbnQgYXMgQ2xpZW50LCAkZWRpdFVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pO1xuICAgICAgICAgIGVkaXRlZEF0ID0gcGFyc2VPZGF0ZSgkZWRpdE9kYXRlRWxlbSBhcyBDaGVlcmlvPEFueU5vZGU+KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwb3N0cy5wdXNoKFxuICAgICAgICBuZXcgRm9ydW1Qb3N0KHtcbiAgICAgICAgICB0aHJlYWQsXG4gICAgICAgICAgaWQ6IHBvc3RJZCxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICAgIGVsZW1lbnQ6IHBvc3RFbGVtIGFzIEVsZW1lbnQsXG4gICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgIGNyZWF0ZWRBdCxcbiAgICAgICAgICBlZGl0ZWRCeSxcbiAgICAgICAgICBlZGl0ZWRBdCxcbiAgICAgICAgICBwYXJlbnRJZCxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcG9zdHM7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5YaF44Gu5YWo5oqV56i/44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUFsbEluVGhyZWFkKHRocmVhZDogRm9ydW1UaHJlYWRSZWYpOiBXaWtpZG90UmVzdWx0QXN5bmM8Rm9ydW1Qb3N0Q29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBvc3RzOiBGb3J1bVBvc3RbXSA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gYXdhaXQgdGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZFBvc3RzTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VObzogJzEnLFxuICAgICAgICAgICAgdDogU3RyaW5nKHRocmVhZC5pZCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RCb2R5ID0gU3RyaW5nKGZpcnN0UmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICRmaXJzdCA9IGNoZWVyaW8ubG9hZChmaXJzdEJvZHkpO1xuXG4gICAgICAgIHBvc3RzLnB1c2goLi4uRm9ydW1Qb3N0Q29sbGVjdGlvbi5fcGFyc2UodGhyZWFkLCAkZmlyc3QpKTtcblxuICAgICAgICAvLyDjg5rjg7zjgrjjg43jg7zjgrfjg6fjg7Pnorroqo1cbiAgICAgICAgY29uc3QgJHBhZ2VyID0gJGZpcnN0KCdkaXYucGFnZXInKTtcbiAgICAgICAgaWYgKCRwYWdlci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCAkcGFnZXJUYXJnZXRzID0gJHBhZ2VyLmZpbmQoJ3NwYW4udGFyZ2V0Jyk7XG4gICAgICAgIGlmICgkcGFnZXJUYXJnZXRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDmnIDlvozjgYvjgoky55Wq55uu44Gu44Oa44O844K444Oq44Oz44Kv44GL44KJ5pyA57WC44Oa44O844K455Wq5Y+344KS5Y+W5b6XXG4gICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9ICRwYWdlclRhcmdldHNcbiAgICAgICAgICAuZXEoJHBhZ2VyVGFyZ2V0cy5sZW5ndGggLSAyKVxuICAgICAgICAgIC50ZXh0KClcbiAgICAgICAgICAudHJpbSgpO1xuICAgICAgICBjb25zdCBsYXN0UGFnZSA9IE51bWJlci5wYXJzZUludChsYXN0UGFnZVRleHQsIDEwKTtcbiAgICAgICAgaWYgKE51bWJlci5pc05hTihsYXN0UGFnZSkgfHwgbGFzdFBhZ2UgPD0gMSkge1xuICAgICAgICAgIHJldHVybiBuZXcgRm9ydW1Qb3N0Q29sbGVjdGlvbih0aHJlYWQsIHBvc3RzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOaui+OCiuOBruODmuODvOOCuOOCkuWPluW+l1xuICAgICAgICBjb25zdCBib2RpZXM6IHsgbW9kdWxlTmFtZTogc3RyaW5nOyBwYWdlTm86IHN0cmluZzsgdDogc3RyaW5nIH1bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBwYWdlID0gMjsgcGFnZSA8PSBsYXN0UGFnZTsgcGFnZSsrKSB7XG4gICAgICAgICAgYm9kaWVzLnB1c2goe1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZFBvc3RzTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VObzogU3RyaW5nKHBhZ2UpLFxuICAgICAgICAgICAgdDogU3RyaW5nKHRocmVhZC5pZCksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IHRocmVhZC5zaXRlLmFtY1JlcXVlc3QoYm9kaWVzKTtcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxSZXN1bHRzLmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBhZGRpdGlvbmFsUmVzdWx0cy5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2Ugb2YgYWRkaXRpb25hbFJlc3VsdHMudmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gU3RyaW5nKHJlc3BvbnNlPy5ib2R5ID8/ICcnKTtcbiAgICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKGJvZHkpO1xuICAgICAgICAgIHBvc3RzLnB1c2goLi4uRm9ydW1Qb3N0Q29sbGVjdGlvbi5fcGFyc2UodGhyZWFkLCAkKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yKSByZXR1cm4gZXJyb3I7XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBwb3N0czogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7O0FDbUJBLFNBQVMsWUFBWSxDQUNuQixLQUNnRTtBQUFBLEVBQ2hFLElBQUksSUFBSTtBQUFBLElBQVEsT0FBTyxJQUFJO0FBQUEsRUFDM0IsSUFBSSxJQUFJLE1BQU07QUFBQSxJQUFRLE9BQU8sSUFBSSxLQUFLO0FBQUEsRUFDdEMsSUFBSSxJQUFJLFFBQVEsTUFBTTtBQUFBLElBQVEsT0FBTyxJQUFJLE9BQU8sS0FBSztBQUFB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LFlBQVk7QUFBQSxNQUNYLE1BQU0sU0FBUyxNQUFNLEtBQUssV0FBVztBQUFBLFFBQ25DO0FBQUEsVUFDRSxZQUFZO0FBQUEsVUFDWixRQUFRO0FBQUEsUUFDVjtBQUFBLE1BQ0YsQ0FBQztBQUFBLE1BRUQsSUFBSSxPQUFPLE1BQU0sR0FBRztBQUFBLFFBQ2xCLE1BQU0sT0FBTztBQUFBLE1BQ2Y7QUFBQSxNQUVBLE1BQU0sV0FBVyxPQUFPLE1BQU07QUFBQSxNQUM5QixJQUFJLENBQUMsVUFBVTtBQUFBLFFBQ2IsTUFBTSxJQUFJLGVBQWUsZ0JBQWdCO0FBQUEsTUFDM0M7QUFBQSxNQUVBLE1BQU0sT0FBTyxPQUFPLFNBQVMsUUFBUSxFQUFFO0FBQUEsTUFDdkMsTUFBTSxJQUFZLGNBQUssSUFBSTtBQUFBLE1BRTNCLE1BQU0sYUFBOEIsQ0FBQztBQUFBLE1BRXJDLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLElBQUksUUFBUTtBQUFBLFFBQ3RDLE1BQU0sT0FBTyxFQUFFLEdBQUc7QUFBQSxRQUNsQixNQUFNLFdBQVcsS0FBSyxLQUFLLFNBQVM7QUFBQSxRQUNwQyxNQUFNLGVBQWUsU0FBUyxLQUFLLEdBQUc7QUFBQSxRQUN0QyxNQUFNLE9BQU8sYUFBYSxLQUFLLE1BQU0sS0FBSztBQUFBLFFBRTFDLE1BQU0sa0JBQWtCLEtBQUssTUFBTSxTQUFTO0FBQUEsUUFDNUMsSUFBSSxDQUFDLGtCQUFrQjtBQUFBLFVBQUk7QUFBQSxRQUUzQixNQUFNLGFBQWEsT0FBTyxTQUFTLGdCQUFnQixJQUFJLEVBQUU7QUFBQSxRQUN6RCxNQUFNLFFBQVEsYUFBYSxLQUFLLEVBQUUsS0FBSztBQUFBLFFBQ3ZDLE1BQU0sY0FBYyxTQUFTLEtBQUssaUJBQWlCLEVBQUUsS0FBSyxFQUFFLEtBQUs7QUFBQSxRQUNqRSxNQUFNLGVBQWUsT0FBTyxTQUFTLEtBQUssS0FBSyxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEtBQUs7QUFBQSxRQUNuRixNQUFNLGFBQWEsT0FBTyxTQUFTLEtBQUssS0FBSyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEtBQUs7QUFBQSxRQUUvRSxXQUFXLEtBQ1QsSUFBSSxjQUFjO0FBQUEsVUFDaEI7QUFBQSxVQUNBLElBQUk7QUFBQSxVQUNKO0FBQUEsVUFDQTtBQUFBLFVBQ0E7QUFBQSxVQUNBO0FBQUEsUUFDRixDQUFDLENBQ0g7QUFBQSxPQUNEO0FBQUEsTUFFRCxPQUFPLElBQUksd0JBQXdCLE1BQU0sVUFBVTtBQUFBLE9BQ2xELEdBQ0gsQ0FBQyxVQUFVO0FBQUEsTUFDVCxJQUFJLGlCQUFpQjtBQUFBLFFBQWdCLE9BQU87QUFBQSxNQUM1QyxPQUFPLElBQUksZ0JBQWdCLGlDQUFpQyxPQUFPLEtBQUssR0FBRztBQUFBLEtBRS9FO0FBQUE7QUFFSjsiLAogICJkZWJ1Z0lkIjogIkIxNzQ4RUE1NzZGOTZBMzE2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9