@media-quest/engine 0.0.14 → 0.0.15

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 (60) hide show
  1. package/package.json +1 -2
  2. package/src/Delement/DElement.dto.ts +5 -0
  3. package/src/Delement/DElement.ts +78 -253
  4. package/src/Delement/DImg.ts +31 -70
  5. package/src/Delement/DStyle.ts +156 -156
  6. package/src/Delement/DText.ts +9 -25
  7. package/src/Delement/Ddiv.ts +10 -23
  8. package/src/Delement/button-click-action.ts +11 -0
  9. package/src/Delement/element-factory.ts +40 -0
  10. package/src/engine/DCommand.ts +21 -0
  11. package/src/engine/SchemaDto.ts +24 -0
  12. package/src/engine/SchemaEngine.ts +48 -120
  13. package/src/{player → engine}/dplayer.spec.ts +20 -17
  14. package/src/{player → engine}/dplayer.ts +29 -16
  15. package/src/engine/history-que.spec.ts +59 -0
  16. package/src/engine/history-que.ts +39 -0
  17. package/src/{player → engine}/next-que.spec.ts +19 -8
  18. package/src/engine/next-que.ts +93 -0
  19. package/src/page/Page.ts +160 -0
  20. package/src/page/media-player.ts +117 -0
  21. package/src/page/page-component.ts +113 -0
  22. package/src/page/page-result.ts +11 -0
  23. package/src/page/task-manager.ts +203 -0
  24. package/src/page/task-state.ts +55 -0
  25. package/src/page/task.ts +87 -0
  26. package/src/public-api.ts +17 -13
  27. package/src/rules/__test__/rule-engine.spec.ts +1 -1
  28. package/src/utils/DUtil.ts +110 -103
  29. package/tsconfig.tsbuildinfo +1 -0
  30. package/dist/public-api.js +0 -2245
  31. package/dist/public-api.mjs +0 -2205
  32. package/src/Delement/AudioContainer.ts +0 -169
  33. package/src/Delement/DAuto-play.ts +0 -36
  34. package/src/Delement/VideoContainer.ts +0 -199
  35. package/src/commands/DCommand.ts +0 -63
  36. package/src/commands/DCommandBus.ts +0 -60
  37. package/src/dto/AnimationDto.ts +0 -4
  38. package/src/dto/DElement.dto.ts +0 -46
  39. package/src/dto/SchemaDto.ts +0 -65
  40. package/src/engine/DPage.ts +0 -60
  41. package/src/engine/element-factory.ts +0 -52
  42. package/src/event-handlers/DEventHandler.ts +0 -29
  43. package/src/events/DEvents.ts +0 -94
  44. package/src/events/event-bus.spec.ts +0 -21
  45. package/src/events/event-bus.ts +0 -81
  46. package/src/kladd/context-menu-manager.ts +0 -56
  47. package/src/player/history-que.spec.ts +0 -46
  48. package/src/player/history-que.ts +0 -38
  49. package/src/player/next-que.ts +0 -93
  50. package/src/services/DMedia-manager.spec.ts +0 -27
  51. package/src/services/DMedia-manager.ts +0 -179
  52. package/src/services/resource-provider.ts +0 -33
  53. package/src/services/sequence-manager.spec.ts +0 -168
  54. package/src/services/sequence-manager.ts +0 -133
  55. package/src/state/Dstate.spec.ts +0 -7
  56. package/src/state/Dstate.ts +0 -105
  57. package/src/state/boolean-property.ts +0 -69
  58. package/src/state/state-service.spec.ts +0 -307
  59. package/src/state/state-service.ts +0 -251
  60. package/src/state/state-testing-helpers.ts +0 -59
@@ -1,2205 +0,0 @@
1
- // src/dto/SchemaDto.ts
2
- var SchemaDto;
3
- ((SchemaDto2) => {
4
- SchemaDto2.getResources = (schema) => {
5
- const { pages } = schema;
6
- const videoList = pages.reduce((acc, curr) => {
7
- if (Array.isArray(curr.video)) {
8
- acc.push(...curr.video);
9
- }
10
- return acc;
11
- }, []);
12
- const audioList = pages.reduce((acc, curr) => {
13
- if (Array.isArray(curr.audio)) {
14
- acc.push(...curr.audio);
15
- }
16
- return acc;
17
- }, []);
18
- return { videoList, audioList, imageList: [] };
19
- };
20
- })(SchemaDto || (SchemaDto = {}));
21
-
22
- // src/common/DTimestamp.ts
23
- var DTimestamp;
24
- ((DTimestamp2) => {
25
- DTimestamp2.now = () => Date.now();
26
- DTimestamp2.addMills = (t, ms) => {
27
- const res = t + Math.abs(ms);
28
- return res;
29
- };
30
- DTimestamp2.diff = (t1, t2) => {
31
- const t1Abs = Math.abs(t1);
32
- const t2Abs = Math.abs(t2);
33
- return Math.abs(t1Abs - t2Abs);
34
- };
35
- DTimestamp2.diffNow = (t) => {
36
- return (0, DTimestamp2.diff)(t, (0, DTimestamp2.now)());
37
- };
38
- })(DTimestamp || (DTimestamp = {}));
39
-
40
- // src/utils/DUtil.ts
41
- var DUtil;
42
- ((DUtil2) => {
43
- DUtil2.randomString = (length) => {
44
- const letters = "abcdefghijklmnopqrstuvxyz";
45
- const uppercase = letters.toUpperCase();
46
- const all = letters + uppercase;
47
- const abs = Math.abs(length);
48
- let result = "";
49
- for (let i = 0; i < abs; i++) {
50
- const char = all.charAt(Math.floor(Math.random() * all.length));
51
- result += char;
52
- }
53
- return result;
54
- };
55
- DUtil2.randomObjectId = () => (0, DUtil2.randomString)(32);
56
- DUtil2.deleteProp = (obj, key) => {
57
- delete obj[key];
58
- return obj;
59
- };
60
- DUtil2.isInRange = (min, max) => {
61
- return (value) => value >= min && value <= max;
62
- };
63
- DUtil2.isInfinity = (number) => {
64
- return number === Number.POSITIVE_INFINITY || number === Number.NEGATIVE_INFINITY || number === Infinity;
65
- };
66
- DUtil2.isNonEmptyArray = (array) => {
67
- return array.length > 0;
68
- };
69
- DUtil2.neverCheck = (args) => {
70
- console.log("OOPS: This value slipped through the never-check", args);
71
- };
72
- DUtil2.isString = (str) => typeof str === "string";
73
- DUtil2.hasKey = (obj, key) => {
74
- if (!(0, DUtil2.isRecord)(obj)) {
75
- return false;
76
- }
77
- return Object.prototype.hasOwnProperty.call(obj, key);
78
- };
79
- DUtil2.isRecord = (obj) => {
80
- if (!obj) {
81
- return false;
82
- }
83
- if (Array.isArray(obj)) {
84
- return false;
85
- }
86
- if (typeof obj !== "object") {
87
- return false;
88
- }
89
- if (obj === null) {
90
- return false;
91
- }
92
- return true;
93
- };
94
- DUtil2.isBool = (obj) => typeof obj === "boolean";
95
- DUtil2.isTrue = (bool) => bool === true;
96
- DUtil2.isFalse = (bool) => bool === false;
97
- DUtil2.isDefined = (obj) => {
98
- const notNull = obj !== null;
99
- const notUndefined = obj !== void 0;
100
- return notNull && notUndefined;
101
- };
102
- DUtil2.hasKind = (obj) => {
103
- if (!(0, DUtil2.hasKey)(obj, "kind")) {
104
- return false;
105
- }
106
- if (typeof obj.kind !== "string") {
107
- return false;
108
- }
109
- return obj.kind.length > 0;
110
- };
111
- DUtil2.hasValue = (obj) => {
112
- return (0, DUtil2.hasKey)(obj, "value");
113
- };
114
- DUtil2.isNumber = (value) => {
115
- const isNumber2 = typeof value === "number";
116
- const notNaN = !Number.isNaN(value);
117
- return isNumber2 && notNaN;
118
- };
119
- DUtil2.maxFn = (upperLimit) => {
120
- return (value) => {
121
- return Math.min(value, upperLimit);
122
- };
123
- };
124
- DUtil2.minFn = (lowerLimit) => {
125
- return (value) => {
126
- return Math.min(value, lowerLimit);
127
- };
128
- };
129
- })(DUtil || (DUtil = {}));
130
-
131
- // src/Delement/css.ts
132
- var DCss;
133
- ((DCss2) => {
134
- DCss2.toString = (unit, scale) => {
135
- const clampedScale = Math.max(scale, 0.03);
136
- if (unit._unit === "px") {
137
- if (unit.value < 0.1) {
138
- return "0px";
139
- }
140
- const rounded = Math.round(unit.value * clampedScale);
141
- const clamped = Math.max(rounded, 1);
142
- return clamped + "px";
143
- }
144
- return unit.value + "%";
145
- };
146
- DCss2.isLengthUnit = (unit) => {
147
- if (!unit) {
148
- return false;
149
- }
150
- const unitKey = "_unit";
151
- const valueKey = "value";
152
- const hasUnitKey = DUtil.hasKey(unit, unitKey);
153
- const hasValueKey = DUtil.hasKey(unit, valueKey);
154
- return hasUnitKey && hasValueKey;
155
- };
156
- })(DCss || (DCss = {}));
157
-
158
- // src/Delement/DStyle.ts
159
- var DStyle;
160
- ((DStyle2) => {
161
- DStyle2.normalize = (el) => {
162
- el.style.padding = "0";
163
- el.style.margin = "0";
164
- el.style.position = "absolute";
165
- el.style.boxSizing = "border-box";
166
- return el;
167
- };
168
- DStyle2.applyStyles = (el, style, scale) => {
169
- const {
170
- x,
171
- y,
172
- backgroundColor,
173
- borderColor,
174
- borderWidth,
175
- borderRadius,
176
- borderStyle,
177
- w,
178
- opacity,
179
- cursor,
180
- fontSize,
181
- fontWeight,
182
- textColor,
183
- textAlign,
184
- translate,
185
- margin,
186
- padding,
187
- letterSpacing,
188
- h,
189
- transform,
190
- visibility
191
- } = style;
192
- if (backgroundColor) {
193
- el.style.backgroundColor = backgroundColor;
194
- }
195
- if (cursor) {
196
- el.style.cursor = cursor;
197
- }
198
- if (transform) {
199
- el.style.transform = transform;
200
- }
201
- if (textColor) {
202
- el.style.color = textColor;
203
- }
204
- if (textAlign) {
205
- el.style.textAlign = textAlign;
206
- }
207
- if (borderColor) {
208
- el.style.borderColor = borderColor;
209
- }
210
- if (borderWidth) {
211
- el.style.borderWidth = DCss.toString(borderWidth, scale);
212
- }
213
- if (fontWeight) {
214
- el.style.fontWeight = fontWeight + "";
215
- }
216
- if (borderStyle) {
217
- el.style.borderStyle = borderStyle;
218
- }
219
- if (fontSize) {
220
- el.style.fontSize = DCss.toString(fontSize, scale);
221
- }
222
- if (DUtil.isNumber(x)) {
223
- el.style.left = x + "%";
224
- }
225
- if (DUtil.isNumber(y)) {
226
- el.style.bottom = y + "%";
227
- }
228
- if (DUtil.isNumber(h)) {
229
- el.style.height = h + "%";
230
- }
231
- if (DUtil.isNumber(w)) {
232
- el.style.width = w + "%";
233
- }
234
- if (DCss.isLengthUnit(borderRadius)) {
235
- el.style.borderRadius = DCss.toString(borderRadius, scale);
236
- }
237
- if (letterSpacing) {
238
- el.style.letterSpacing = DCss.toString(letterSpacing, scale);
239
- }
240
- if (margin) {
241
- el.style.margin = DCss.toString(margin, scale);
242
- }
243
- if (padding) {
244
- el.style.padding = DCss.toString(padding, scale);
245
- }
246
- if (DUtil.isNumber(opacity)) {
247
- el.style.opacity = opacity + "";
248
- }
249
- if (visibility) {
250
- el.style.visibility = visibility;
251
- }
252
- return el;
253
- };
254
- })(DStyle || (DStyle = {}));
255
-
256
- // src/Delement/VideoContainer.ts
257
- var ABORT_PLAY_TO_END = "ABORT_PLAY_TO_END";
258
- var VideoContainer = class {
259
- constructor(el, eventBus, scale) {
260
- this.el = el;
261
- this.eventBus = eventBus;
262
- this.scale = scale;
263
- this.TAG = "[ D_Video ] : ";
264
- this.el.controls = false;
265
- DStyle.normalize(this.el);
266
- DStyle.applyStyles(this.el, this.defaultStyles, this.scale.scale);
267
- this.el.onended = () => {
268
- this.eventBus.emit({
269
- kind: "VIDEO_ENDED_EVENT",
270
- timestamp: DTimestamp.now(),
271
- producer: "DVideo",
272
- producerId: this.id,
273
- data: {}
274
- });
275
- };
276
- this.el.onplay = () => {
277
- };
278
- this.el.onpause = () => {
279
- };
280
- this.el.onerror = () => {
281
- };
282
- this.el.oncanplay = () => {
283
- };
284
- this.el.onloadedmetadata = () => {
285
- const duration = this.el.duration;
286
- const isInfinity = DUtil.isInfinity(duration);
287
- this.eventBus.emit({
288
- kind: "VIDEO_LOADED_METADATA_EVENT",
289
- timestamp: DTimestamp.now(),
290
- producer: "DVideo",
291
- producerId: this.id,
292
- data: { duration, isInfinity }
293
- });
294
- };
295
- this.el.ondurationchange = () => {
296
- const duration = this.el.duration;
297
- const isInfinity = DUtil.isInfinity(duration);
298
- this.eventBus.emit({
299
- kind: "VIDEO_DURATION_CHANGE_EVENT",
300
- producer: "DVideo",
301
- producerId: this.id,
302
- timestamp: DTimestamp.now(),
303
- data: { duration, isInfinity }
304
- });
305
- };
306
- }
307
- TAG;
308
- dto;
309
- defaultStyles = { h: 45, w: 100, visibility: "hidden", y: 55 };
310
- pause() {
311
- this.eventBus.emit({
312
- kind: "VIDEO_PAUSED_EVENT",
313
- data: {},
314
- producer: "DVideo",
315
- producerId: this.id,
316
- timestamp: DTimestamp.now()
317
- });
318
- this.el.pause();
319
- }
320
- play(url) {
321
- if (this.el.src !== url) {
322
- this.el.src = url;
323
- }
324
- const producerId = this.dto?.id ?? "DVideo";
325
- this.eventBus.emit({
326
- kind: "VIDEO_PLAY_EVENT",
327
- data: {},
328
- producer: "DVideo",
329
- producerId,
330
- timestamp: DTimestamp.now()
331
- });
332
- this.el.play().then((res) => {
333
- console.log(res);
334
- }).catch((e) => {
335
- console.log(e);
336
- });
337
- }
338
- async playToEnd() {
339
- this.el.volume = 1;
340
- const url = this.dto?.url;
341
- if (!url) {
342
- return false;
343
- }
344
- try {
345
- const endedOrErrored = new Promise((resolve, reject) => {
346
- this.el.addEventListener(
347
- "ended",
348
- (_) => {
349
- resolve(true);
350
- },
351
- { once: true }
352
- );
353
- this.el.addEventListener(
354
- "error",
355
- (_) => {
356
- resolve(false);
357
- },
358
- { once: true }
359
- );
360
- this.el.addEventListener(
361
- ABORT_PLAY_TO_END,
362
- () => {
363
- console.log("CATCHED ABBORT.");
364
- reject("Aborted");
365
- },
366
- { once: true }
367
- );
368
- });
369
- this.play(url);
370
- await endedOrErrored;
371
- return true;
372
- } catch (e) {
373
- console.log(e);
374
- return false;
375
- } finally {
376
- console.log(this.TAG + " finally block playToEnd() completed videoId: " + this.dto?.id);
377
- }
378
- }
379
- getStats() {
380
- const duration = this.el.duration;
381
- const currentTime = this.el.currentTime;
382
- const volume = this.el.volume;
383
- const isConnected = this.el.isConnected;
384
- const playbackQuality = this.el.getVideoPlaybackQuality();
385
- const defaultPlaybackRate = this.el.defaultPlaybackRate;
386
- const paused = this.el.paused;
387
- const played = this.el.played;
388
- return {
389
- duration,
390
- paused,
391
- played,
392
- currentTime,
393
- volume,
394
- isConnected,
395
- playbackQuality,
396
- defaultPlaybackRate
397
- };
398
- }
399
- setDto(dto) {
400
- this.dto = dto;
401
- this.el.volume = 1;
402
- this.setStyle(dto.style);
403
- this.el.src = dto.url;
404
- this.el.load();
405
- }
406
- getCurrentDto() {
407
- return this.dto ?? false;
408
- }
409
- setStyle(styles) {
410
- DStyle.applyStyles(this.el, styles, this.scale.scale);
411
- }
412
- get id() {
413
- return this.dto?.id ?? "DVideo";
414
- }
415
- destroy() {
416
- }
417
- };
418
-
419
- // src/Delement/AudioContainer.ts
420
- var AudioContainer = class {
421
- constructor(eventBus) {
422
- this.eventBus = eventBus;
423
- this.el = document.createElement("audio");
424
- this.el.style.position = "absolute";
425
- this.el.style.visibility = "hidden";
426
- this.onLoad = this.onLoad.bind(this);
427
- this.el.onload = this.onLoad;
428
- this.onLoadedMetadata = this.onLoadedMetadata.bind(this);
429
- this.el.onloadedmetadata = this.onLoadedMetadata;
430
- this.el.onplay = () => {
431
- };
432
- this.onCanPlayThrough = this.onCanPlayThrough.bind(this);
433
- this.el.oncanplaythrough = this.onCanPlayThrough;
434
- this.el.onended = (_) => {
435
- const url = this.el.src;
436
- this.eventBus.emit({
437
- kind: "AUDIO_ENDED_EVENT",
438
- data: { url },
439
- producer: "DAudio",
440
- timestamp: DTimestamp.now(),
441
- producerId: this.id
442
- });
443
- };
444
- this.el.ondurationchange = (_) => {
445
- const duration = this.el.duration;
446
- const isInfinity = duration === Number.POSITIVE_INFINITY;
447
- this.eventBus.emit({
448
- kind: "AUDIO_DURATION_CHANGE_EVENT",
449
- timestamp: DTimestamp.now(),
450
- producer: "DAudio",
451
- producerId: this.id,
452
- data: { duration: this.el.duration, isInfinity }
453
- });
454
- };
455
- }
456
- TAG = "[ DAudio ]: ";
457
- dto = null;
458
- el;
459
- setAudio(dto) {
460
- this.dto = dto;
461
- this.el.src = dto.url;
462
- this.el.load();
463
- }
464
- destroy() {
465
- try {
466
- this.el.pause();
467
- this.el.src = "";
468
- this.el.load();
469
- } catch (e) {
470
- console.log(e);
471
- }
472
- }
473
- pause() {
474
- try {
475
- this.el.pause();
476
- } catch (e) {
477
- console.log(e);
478
- }
479
- }
480
- play(url) {
481
- if (this.el.src !== url) {
482
- this.el.src = url;
483
- }
484
- this.eventBus.emit({
485
- kind: "AUDIO_PLAY_EVENT",
486
- producerId: this.id,
487
- data: {},
488
- producer: "DAudio",
489
- timestamp: DTimestamp.now()
490
- });
491
- this.el.play().then((res) => {
492
- console.log(res);
493
- }).catch((e) => {
494
- console.log(e);
495
- });
496
- }
497
- onLoadedMetadata(_) {
498
- this.eventBus.emit({
499
- kind: "AUDIO_METADATA_LOADED_EVENT",
500
- timestamp: DTimestamp.now(),
501
- producer: "DAudio",
502
- producerId: this.id,
503
- data: {}
504
- });
505
- }
506
- onLoad(_) {
507
- this.eventBus.emit({
508
- kind: "AUDIO_LOAD_EVENT",
509
- timestamp: DTimestamp.now(),
510
- producer: "DAudio",
511
- producerId: this.id,
512
- data: {}
513
- });
514
- }
515
- get id() {
516
- return this.dto?.id ?? "DAudio";
517
- }
518
- onCanPlayThrough(_) {
519
- this.eventBus.emit({
520
- kind: "AUDIO_CAN_PLAY_THROUGH_EVENT",
521
- data: {},
522
- producer: "DAudio",
523
- timestamp: DTimestamp.now(),
524
- producerId: this.id
525
- });
526
- }
527
- // private onPlay(_: Event) {}
528
- async playToEnd() {
529
- const endedOrErrored = new Promise((resolve) => {
530
- this.el.addEventListener(
531
- "ended",
532
- (_) => {
533
- resolve(true);
534
- },
535
- { once: true }
536
- );
537
- this.el.addEventListener(
538
- "error",
539
- (_) => {
540
- resolve(false);
541
- },
542
- { once: true }
543
- );
544
- });
545
- try {
546
- this.play(this.el.src);
547
- await endedOrErrored;
548
- return true;
549
- } catch (e) {
550
- console.log(e);
551
- this.eventBus.emit({
552
- kind: "AUDIO_ERROR_EVENT",
553
- timestamp: DTimestamp.now(),
554
- producer: "DAudio",
555
- producerId: this.id,
556
- data: { error: e }
557
- });
558
- return false;
559
- } finally {
560
- }
561
- return Promise.resolve(false);
562
- }
563
- };
564
-
565
- // src/services/DMedia-manager.ts
566
- var DMediaManager = class _DMediaManager {
567
- constructor(hostEl, commandBus, eventBus, resourceProvider, scale) {
568
- this.hostEl = hostEl;
569
- this.commandBus = commandBus;
570
- this.eventBus = eventBus;
571
- this.resourceProvider = resourceProvider;
572
- this.scale = scale;
573
- _DMediaManager.INSTANCE_COUNT = _DMediaManager.INSTANCE_COUNT + 1;
574
- this.instanceNumber = _DMediaManager.INSTANCE_COUNT;
575
- const videoEl = document.createElement("video");
576
- this.hostEl.append(videoEl);
577
- this.videoContainer = new VideoContainer(videoEl, eventBus, this.scale);
578
- this.audioContainer = new AudioContainer(this.eventBus);
579
- this.tick = this.tick.bind(this);
580
- this.videoContainer.setStyle({ visibility: "hidden" });
581
- const now = DTimestamp.now();
582
- this.pageEnter = now;
583
- this.sincePageEnter = DTimestamp.diff(now, now);
584
- this.unsubscribeCommands = this.commandBus.subscribe((action) => {
585
- this.commandHandler(action);
586
- }, this.TAG);
587
- this.tickerRef = window.setInterval(() => {
588
- }, 1e3);
589
- }
590
- static INSTANCE_COUNT = 0;
591
- instanceNumber;
592
- TAG = "[ MEDIA_MANAGER ] : ";
593
- videoContainer;
594
- audioContainer;
595
- pageEnter;
596
- sincePageEnter;
597
- currentPage = null;
598
- unsubscribeCommands;
599
- tickerRef;
600
- sequenceManager = false;
601
- /**
602
- * Stop all media that is playing
603
- */
604
- clearAllMedia() {
605
- this.videoContainer.pause();
606
- this.audioContainer.pause();
607
- }
608
- destroy() {
609
- console.log("TODO DESTROY ALL MEDIA");
610
- this.unsubscribeCommands();
611
- window.clearInterval(this.tickerRef);
612
- this.audioContainer.destroy();
613
- this.videoContainer.destroy();
614
- }
615
- setPage(page) {
616
- this.currentPage = page;
617
- this.videoContainer.pause();
618
- this.pageEnter = DTimestamp.now();
619
- const seq = page.autoPlaySequence;
620
- const { mainVideoId, audio } = page;
621
- const audioElements = page.audio;
622
- if (mainVideoId) {
623
- const dto = this.resourceProvider.getVideoById(mainVideoId);
624
- if (dto) {
625
- this.videoContainer.setDto(dto);
626
- this.videoContainer.setStyle({ ...dto.style, visibility: "visible" });
627
- }
628
- } else {
629
- this.videoContainer.setStyle({ visibility: "hidden" });
630
- }
631
- if (audioElements) {
632
- const first = audioElements[0];
633
- if (first) {
634
- this.audioContainer.setAudio(first);
635
- }
636
- }
637
- if (seq) {
638
- this.playSequence(seq);
639
- }
640
- }
641
- commandHandler(command) {
642
- if (command.kind === "VIDEO_PLAY_COMMAND") {
643
- const video = command.targetId;
644
- const dto = this.videoContainer.getCurrentDto();
645
- if (dto && dto.id === command.targetId) {
646
- console.log(video);
647
- this.videoContainer.play(dto.url);
648
- }
649
- }
650
- if (command.kind === "VIDEO_PAUSE_COMMAND") {
651
- this.videoContainer.pause();
652
- }
653
- if (command.kind === "AUDIO_PLAY_COMMAND") {
654
- this.audioContainer.playToEnd().then(() => {
655
- }).catch().finally(() => {
656
- });
657
- }
658
- if (command.kind === "AUDIO_PAUSE_COMMAND") {
659
- }
660
- }
661
- async playSequence(seq) {
662
- const elements = seq.items;
663
- const testClone = [...elements];
664
- const first = testClone.pop();
665
- if (!first) {
666
- return false;
667
- }
668
- const now = DTimestamp.now();
669
- seq.startCommands.forEach((c) => {
670
- console.log(c);
671
- this.commandBus.emit(c);
672
- });
673
- for (let i = 0; i < elements.length; i++) {
674
- const item = elements[i];
675
- if (item.kind === "autoplay-video") {
676
- const dto = this.resourceProvider.getVideoById(item.videoId);
677
- if (dto)
678
- this.videoContainer.setDto(dto);
679
- await this.videoContainer.playToEnd();
680
- }
681
- if (item.kind === "autoplay-audio") {
682
- console.log(item);
683
- const dto = this.resourceProvider.getAudioById(item.audioId);
684
- if (dto)
685
- this.audioContainer.setAudio(dto);
686
- await this.audioContainer.playToEnd();
687
- }
688
- }
689
- seq.endCommands.forEach((c) => {
690
- this.commandBus.emit(c);
691
- });
692
- console.log(this.TAG + "SEQUENCE ENDED");
693
- return true;
694
- }
695
- // setPage()
696
- tick() {
697
- }
698
- };
699
-
700
- // src/commands/DCommandBus.ts
701
- var DCommandBus = class {
702
- TAG = "[ COMMAND_BUS ] ";
703
- logCommands = false;
704
- commandLog = [];
705
- subscribers = /* @__PURE__ */ new Set();
706
- // readonly sub
707
- subscribe(cb, subscriberId) {
708
- const sub = {
709
- subscriberId,
710
- callback: cb
711
- };
712
- this.subscribers.add(sub);
713
- return () => {
714
- this.subscribers.delete(sub);
715
- };
716
- }
717
- emit(command) {
718
- const timestamp = DTimestamp.now();
719
- this.commandLog.push({ ...command, timestamp });
720
- if (this.logCommands) {
721
- this.logCommand(command);
722
- }
723
- this.subscribers.forEach((subscriber) => {
724
- subscriber.callback(command);
725
- });
726
- }
727
- getStats() {
728
- return {
729
- commands: [...this.commandLog],
730
- subscribers: [...this.subscribers],
731
- subscribersCount: this.subscribers.size
732
- };
733
- }
734
- logCommand(command) {
735
- console.groupCollapsed(this.TAG + " " + command.kind);
736
- console.log("TargetID : " + command.targetId);
737
- console.log(command.payload);
738
- console.groupEnd();
739
- }
740
- };
741
-
742
- // src/events/event-bus.ts
743
- var EventBus = class {
744
- TAG = "[ EVENT_BUS ] :";
745
- // private readonly subscribers = new Set<(event: DEvent) => void>();
746
- subscribers = /* @__PURE__ */ new Set();
747
- /**
748
- * Emit on module end.
749
- * @private
750
- */
751
- eventLog = [];
752
- consoleLogEvents = false;
753
- // readonly sub
754
- subscribe(cb, subscriberId) {
755
- const subscriberData = {
756
- subscriberId,
757
- cb
758
- };
759
- this.subscribers.add(subscriberData);
760
- if (this.consoleLogEvents) {
761
- console.log(this.TAG + "subscription added: " + subscriberId);
762
- console.log(this.TAG + "subscription count: " + this.subscribers.size);
763
- }
764
- return () => {
765
- if (this.consoleLogEvents) {
766
- console.log(this.TAG + "subscription removed: " + subscriberId);
767
- console.log(this.TAG + "subscription count : " + this.subscribers.size);
768
- }
769
- this.subscribers.delete(subscriberData);
770
- };
771
- }
772
- getStats() {
773
- return {
774
- subscribersCount: this.subscribers.size,
775
- eventLog: [...this.eventLog],
776
- subscribers: [...this.subscribers]
777
- };
778
- }
779
- emit(event) {
780
- if (this.consoleLogEvents) {
781
- this.logEvent(event);
782
- }
783
- this.eventLog.push(event);
784
- this.subscribers.forEach((data) => {
785
- data.cb(event);
786
- });
787
- }
788
- logEvent(event) {
789
- console.groupCollapsed(this.TAG + " " + event.kind);
790
- console.log("ProducerId: " + event.producerId);
791
- console.log(event.data);
792
- console.groupEnd();
793
- }
794
- logEvents() {
795
- console.group(this.TAG + "LOGG");
796
- console.table(this.eventLog);
797
- console.groupEnd();
798
- }
799
- };
800
-
801
- // src/player/history-que.ts
802
- var AnsweredQuestion;
803
- ((AnsweredQuestion3) => {
804
- AnsweredQuestion3.eq = (a, b) => {
805
- return a.fact === b.fact;
806
- };
807
- })(AnsweredQuestion || (AnsweredQuestion = {}));
808
- var HistoryQue = class {
809
- history = [];
810
- getFacts() {
811
- const answers = this.history.map((h) => h.answeredQuestions).flat(1);
812
- const facts = answers.map((a) => a.fact);
813
- return facts;
814
- }
815
- getAnswers() {
816
- const answers = this.history.map((h) => h.answeredQuestions).flat(1);
817
- return answers;
818
- }
819
- addToHistory(page) {
820
- this.history.push(page);
821
- }
822
- };
823
-
824
- // src/rules/condition.ts
825
- var Condition;
826
- ((Condition2) => {
827
- Condition2.evaluate = (condition, facts) => {
828
- let result = false;
829
- switch (condition.kind) {
830
- case "string-condition":
831
- result = evaluateSimple(condition, facts);
832
- break;
833
- case "numeric-condition":
834
- result = evaluateSimple(condition, facts);
835
- break;
836
- case "complex-condition":
837
- result = evaluateComplex(condition, facts);
838
- break;
839
- default:
840
- const check = condition;
841
- }
842
- return result;
843
- };
844
- const evaluateComplex = (condition, facts) => {
845
- if (condition.some.length === 0 && condition.all.length === 0) {
846
- return false;
847
- }
848
- const allSolved = condition.all.map((condition2) => {
849
- return evaluateSimple(condition2, facts);
850
- });
851
- const someEvaluated = condition.some.map((condition2) => {
852
- return evaluateSimple(condition2, facts);
853
- });
854
- const allResult = allSolved.every(DUtil.isTrue);
855
- const someResult = someEvaluated.length === 0 || someEvaluated.some(DUtil.isTrue);
856
- return someResult && allResult;
857
- };
858
- const evaluateSimple = (condition, facts) => {
859
- const fact = facts.find((f) => f.referenceId === condition.referenceId);
860
- if (!fact) {
861
- return false;
862
- }
863
- let res = false;
864
- switch (condition.kind) {
865
- case "numeric-condition":
866
- if (fact.kind === "numeric-fact") {
867
- res = evaluateNumeric(condition, fact.value);
868
- }
869
- break;
870
- case "string-condition":
871
- if (fact.kind === "string-fact") {
872
- res = evaluateString(condition, fact.value);
873
- }
874
- break;
875
- default:
876
- const check = condition;
877
- }
878
- return res;
879
- };
880
- Condition2.isEmpty = (complex) => {
881
- return complex.all.length === 0 && complex.some.length === 0;
882
- };
883
- const evaluateString = (condition, value) => {
884
- const operator = condition.operator;
885
- let result = false;
886
- switch (operator) {
887
- case "eq":
888
- result = condition.value === value;
889
- break;
890
- case "not-eq":
891
- result = condition.value !== value;
892
- break;
893
- case "shorter-then":
894
- result = condition.value !== value;
895
- break;
896
- case "longer-then":
897
- result = condition.value !== value;
898
- break;
899
- default:
900
- const check = operator;
901
- }
902
- return result;
903
- };
904
- const evaluateNumeric = (condition, value) => {
905
- const op = condition.operator;
906
- const conditionValue = condition.value;
907
- let result = false;
908
- switch (op) {
909
- case "eq":
910
- result = value === conditionValue;
911
- break;
912
- case "not-eq":
913
- result = value !== conditionValue;
914
- break;
915
- case "greater-then":
916
- result = value > conditionValue;
917
- break;
918
- case "greater-then-inclusive":
919
- result = value >= conditionValue;
920
- break;
921
- case "less-then":
922
- result = value < conditionValue;
923
- break;
924
- case "less-then-inclusive":
925
- result = value <= conditionValue;
926
- break;
927
- default:
928
- const check = op;
929
- }
930
- return result;
931
- };
932
- const _getAllSimple = (condition) => {
933
- const simple = [];
934
- switch (condition.kind) {
935
- case "complex-condition":
936
- simple.push(...condition.all);
937
- simple.push(...condition.some);
938
- break;
939
- case "numeric-condition":
940
- simple.push(condition);
941
- break;
942
- case "string-condition":
943
- simple.push(condition);
944
- break;
945
- default:
946
- DUtil.neverCheck(condition);
947
- }
948
- return simple;
949
- };
950
- Condition2.getAllSimpleConditions = (condition) => {
951
- const simple = [];
952
- if (Array.isArray(condition)) {
953
- condition.forEach((c) => {
954
- simple.push(..._getAllSimple(c));
955
- });
956
- } else {
957
- simple.push(..._getAllSimple(condition));
958
- }
959
- return simple;
960
- };
961
- })(Condition || (Condition = {}));
962
-
963
- // src/rules/rule.ts
964
- var Rule;
965
- ((Rule2) => {
966
- Rule2.isEmpty = (rule) => {
967
- const emptyConditions = rule.all.length === 0 && rule.some.length === 0;
968
- const emptyActions = rule.onSuccess.length === 0 && rule.onFailure.length === 0;
969
- return emptyConditions || emptyActions;
970
- };
971
- Rule2.solve = (rule, facts) => {
972
- if (rule.some.length === 0 && rule.all.length === 0) {
973
- return false;
974
- }
975
- const someSolved = rule.some.map((condition) => Condition.evaluate(condition, facts));
976
- const someResult = someSolved.length === 0 || someSolved.some(DUtil.isTrue);
977
- const allSolved = rule.all.map((condition) => Condition.evaluate(condition, facts)).every(DUtil.isTrue);
978
- return allSolved && someResult;
979
- };
980
- })(Rule || (Rule = {}));
981
-
982
- // src/rules/rule-engine.ts
983
- var RuleEngine = class {
984
- constructor() {
985
- }
986
- solveAll(rules, facts) {
987
- const errors = [];
988
- const matching = [];
989
- rules.forEach((rule) => {
990
- if (Rule.isEmpty(rule)) {
991
- errors.push({ message: "Empty rule: " + rule.id });
992
- } else if (Rule.solve(rule, facts)) {
993
- const match = {
994
- ruleDescription: rule.description,
995
- matchingRuleId: rule.id ?? "no-id-given",
996
- actionList: [...rule.onSuccess]
997
- };
998
- matching.push(match);
999
- }
1000
- });
1001
- return { matching, errors };
1002
- }
1003
- solve(rule, facts) {
1004
- return Rule.solve(rule, facts);
1005
- }
1006
- };
1007
-
1008
- // src/player/next-que.ts
1009
- var NextQue = class {
1010
- originalOrder = [];
1011
- allPages = [];
1012
- excludedTags = /* @__PURE__ */ new Set();
1013
- excludedByPageId = /* @__PURE__ */ new Set();
1014
- remaining = [];
1015
- constructor(pages = []) {
1016
- this.resetQue(pages);
1017
- }
1018
- /**
1019
- * Will reset que with the new pages.
1020
- * @param pages
1021
- */
1022
- resetQue(pages) {
1023
- this.allPages = [...pages];
1024
- this.remaining = [...pages];
1025
- this.excludedTags = /* @__PURE__ */ new Set();
1026
- this.excludedByPageId = /* @__PURE__ */ new Set();
1027
- this.originalOrder = this.allPages.map((p) => p.id);
1028
- }
1029
- pop() {
1030
- const next = this.remaining.shift();
1031
- return next ?? false;
1032
- }
1033
- peek() {
1034
- const next = this.remaining[0];
1035
- return next ?? false;
1036
- }
1037
- jumpToPageById(pageId) {
1038
- const index = this.remaining.findIndex((p) => p.id === pageId);
1039
- if (index < 0) {
1040
- return false;
1041
- }
1042
- this.remaining = this.remaining.slice(index);
1043
- return true;
1044
- }
1045
- removeByTag(tag) {
1046
- if (Array.isArray(tag)) {
1047
- tag.forEach((tag2) => {
1048
- this.excludedTags.add(tag2);
1049
- });
1050
- } else {
1051
- this.excludedTags.add(tag);
1052
- }
1053
- this.filterRemaining();
1054
- }
1055
- /**
1056
- * Will not be included
1057
- * @param pages
1058
- */
1059
- insertAsNextByForce(pages) {
1060
- this.remaining.unshift(...pages);
1061
- }
1062
- removeByPageId(pageId) {
1063
- if (Array.isArray(pageId)) {
1064
- pageId.forEach((id) => {
1065
- this.excludedByPageId.add(id);
1066
- });
1067
- } else {
1068
- this.excludedByPageId.add(pageId);
1069
- }
1070
- this.filterRemaining();
1071
- }
1072
- filterRemaining() {
1073
- this.remaining = this.remaining.filter((p) => {
1074
- const tags = p.tags ?? [];
1075
- const isIncluededByTag = !tags.some((tag) => this.excludedTags.has(tag));
1076
- const isIncludedByPageId = !this.excludedByPageId.has(p.id);
1077
- return isIncludedByPageId && isIncluededByTag;
1078
- });
1079
- }
1080
- get isEmpty() {
1081
- return this.remaining.length === 0;
1082
- }
1083
- get size() {
1084
- return this.remaining.length;
1085
- }
1086
- get pageCount() {
1087
- return this.originalOrder.length;
1088
- }
1089
- };
1090
-
1091
- // src/player/dplayer.ts
1092
- var DPlayer = class {
1093
- history = new HistoryQue();
1094
- ruleEngine = new RuleEngine();
1095
- nextQue = new NextQue();
1096
- data;
1097
- constructor(data) {
1098
- this.data = data;
1099
- this.nextQue.resetQue(data.pages);
1100
- }
1101
- saveHistory(pageHistory) {
1102
- console.log("SAVE HISTORY", pageHistory);
1103
- this.history.addToHistory(pageHistory);
1104
- const facts = this.history.getFacts();
1105
- const result = this.ruleEngine.solveAll(this.data.rules, facts);
1106
- const matchingRules = result.matching;
1107
- const actions = matchingRules.map((r) => r.actionList).flat(1);
1108
- actions.forEach((a) => {
1109
- console.log(a.payload);
1110
- switch (a.kind) {
1111
- case "PAGE_QUE_JUMP_TO_PAGE_COMMAND":
1112
- this.nextQue.jumpToPageById(a.payload.pageId);
1113
- break;
1114
- case "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND":
1115
- this.nextQue.removeByPageId(a.payload.pageIds);
1116
- break;
1117
- case "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND":
1118
- this.nextQue.removeByTag(a.payload.tagIds);
1119
- break;
1120
- default:
1121
- console.log("UNKNOWN ACTION", a);
1122
- const check = a;
1123
- }
1124
- });
1125
- console.log(actions);
1126
- }
1127
- getResults() {
1128
- return this.history.getAnswers();
1129
- }
1130
- goToPageById(pageId) {
1131
- this.nextQue.jumpToPageById(pageId);
1132
- }
1133
- handleNavigationCommand(command) {
1134
- switch (command.kind) {
1135
- case "PAGE_QUE_NEXT_PAGE_COMMAND":
1136
- break;
1137
- case "PAGE_QUE_GO_TO_PAGE_COMMAND":
1138
- this.goToPageById(command.payload.pageId);
1139
- break;
1140
- case "PAGE_QUE_GO_TO_SEQUENCE_COMMAND":
1141
- this.insertSequenceById(command.payload.sequenceId);
1142
- break;
1143
- default:
1144
- DUtil.neverCheck(command);
1145
- }
1146
- }
1147
- getNextPage() {
1148
- return this.nextQue.pop();
1149
- }
1150
- insertSequenceById(id) {
1151
- const seq = this.data.pageSequences?.find((s) => s.id === id);
1152
- if (seq) {
1153
- this.nextQue.insertAsNextByForce([...seq.pages]);
1154
- } else {
1155
- }
1156
- }
1157
- /**
1158
- * Total number of pages.
1159
- */
1160
- get pageCount() {
1161
- return this.nextQue.pageCount;
1162
- }
1163
- };
1164
-
1165
- // src/event-handlers/DEventHandler.ts
1166
- var DEventHandler;
1167
- ((DEventHandler2) => {
1168
- DEventHandler2.createLookUp = (handlers) => {
1169
- const map = /* @__PURE__ */ new Map();
1170
- handlers?.forEach((h) => {
1171
- const kind = h.onEvent;
1172
- const current = map.get(kind);
1173
- const actions = current ? [...current, h] : [h];
1174
- map.set(kind, actions);
1175
- });
1176
- return map;
1177
- };
1178
- })(DEventHandler || (DEventHandler = {}));
1179
-
1180
- // src/Delement/DElement.ts
1181
- var DElement = class {
1182
- el;
1183
- clickHandlerIsEnabled = true;
1184
- id;
1185
- isAnimatingSelf = false;
1186
- currStyle = {
1187
- fontSize: { _unit: "px", value: 100 },
1188
- fontWeight: 500,
1189
- textColor: "black",
1190
- opacity: 1
1191
- };
1192
- // private readonly onQueryChangedHandlers =
1193
- eventHandlers;
1194
- commandBus;
1195
- eventBus;
1196
- scale;
1197
- baseDto;
1198
- subscriptions = /* @__PURE__ */ new Set();
1199
- constructor(el, eventBus, commandBus, dto, scale) {
1200
- this.el = el;
1201
- this.id = dto.id;
1202
- this.baseDto = dto;
1203
- this.commandBus = commandBus;
1204
- this.eventBus = eventBus;
1205
- this.eventHandlers = DEventHandler.createLookUp(dto.eventHandlers);
1206
- this.scale = scale;
1207
- this.onClickHandler = this.onClickHandler.bind(this);
1208
- this.el.onclick = this.onClickHandler;
1209
- this.onMouseOver = this.onMouseOver.bind(this);
1210
- this.el.onmouseover = this.onMouseOver;
1211
- if (dto) {
1212
- this.updateStyles(dto?.style);
1213
- }
1214
- const commandSubscription = this.commandBus.subscribe((c) => {
1215
- if (c.kind === "ELEMENT_STYLE_COMMAND" && c.targetId === this.id) {
1216
- this.setStyle(c.payload.changes);
1217
- }
1218
- if (c.kind === "ELEMENT_DISABLE_CLICK_COMMAND" && c.targetId === this.id) {
1219
- this.clickHandlerIsEnabled = false;
1220
- }
1221
- if (c.kind === "ELEMENT_ENABLE_CLICK_COMMAND" && c.targetId === this.id) {
1222
- this.clickHandlerIsEnabled = true;
1223
- }
1224
- if (c.kind === "ELEMENT_ANIMATE_COMMAND" && c.targetId === this.id) {
1225
- console.log("TODO IMPLEMENT ANIMATION_HANDLER IN DElement.");
1226
- }
1227
- }, this.id);
1228
- const eventSubscription = this.eventBus.subscribe((event) => {
1229
- const handlers = this.eventHandlers.get(event.kind) ?? [];
1230
- const commands = handlers.map((h) => h.thenExecute).flat(1);
1231
- commands.forEach((command) => {
1232
- this.commandBus.emit(command);
1233
- });
1234
- if (event.kind === "HOST_SCALE_CHANGED_EVENT") {
1235
- console.log("HANDLE THIS SCALE CHANGE!!");
1236
- this.updateStyles({});
1237
- }
1238
- if (event.kind === "STATE_QUERY_RESULT_CHANGED_EVENT") {
1239
- this.queryChangedHandler(event.data);
1240
- }
1241
- }, "ELEMENT: ");
1242
- this.normalize();
1243
- this.subscriptions.add(commandSubscription);
1244
- this.subscriptions.add(eventSubscription);
1245
- }
1246
- // abstract setScale(scale: number): void;
1247
- // /**
1248
- // * The purpose of this function is to re-emit commands from event-handlers?
1249
- // * @param command
1250
- // * @private
1251
- // */
1252
- // private handleCommandsEmittedByPrivateEventHandlers(command: DCommand) {
1253
- // console.log(command);
1254
- // switch (command.kind) {
1255
- // case "ELEMENT_STYLE_COMMAND":
1256
- // if (command.targetId === this.id) {
1257
- // this.updateStyles(command.payload.changes);
1258
- // }
1259
- // break;
1260
- // case "ELEMENT_ANIMATE_COMMAND":
1261
- // // TODO CHECK FOR TARGET ID
1262
- // this.handleAnimateSelfAction(command.payload);
1263
- // break;
1264
- // case "ELEMENT_ENABLE_CLICK_COMMAND":
1265
- // this.clickHandlerIsEnabled = true;
1266
- // // this.updateStyles(command.payload.changes);
1267
- // break;
1268
- // case "ELEMENT_DISABLE_CLICK_COMMAND":
1269
- // this.clickHandlerIsEnabled = false;
1270
- // // this.handleAnimateSelfAction(command.payload);
1271
- // break;
1272
- // case "VIDEO_PLAY_COMMAND":
1273
- // this.commandBus.emit(command);
1274
- // break;
1275
- // case "VIDEO_PAUSE_COMMAND":
1276
- // this.commandBus.emit(command);
1277
- // break;
1278
- // case "ENGINE_LEAVE_PAGE_COMMAND":
1279
- // this.commandBus.emit(command);
1280
- // break;
1281
- // case "VIDEO_JUMP_TO_COMMAND":
1282
- // this.commandBus.emit(command);
1283
- // break;
1284
- // case "VIDEO_SET_VOLUME_COMMAND":
1285
- // this.commandBus.emit(command);
1286
- // break;
1287
- // case "AUDIO_PLAY_COMMAND":
1288
- // this.commandBus.emit(command);
1289
- // break;
1290
- // case "AUDIO_PAUSE_COMMAND":
1291
- // this.commandBus.emit(command);
1292
- // break;
1293
- // case "AUDIO_SET_VOLUME_COMMAND":
1294
- // this.commandBus.emit(command);
1295
- // break;
1296
- // case "PAGE_QUE_NEXT_PAGE_COMMAND":
1297
- // this.commandBus.emit(command);
1298
- // break;
1299
- // case "PAGE_QUE_GO_TO_SEQUENCE_COMMAND":
1300
- // this.commandBus.emit(command);
1301
- // break;
1302
- // case "PAGE_QUE_GO_TO_PAGE_COMMAND":
1303
- // this.commandBus.emit(command);
1304
- // break;
1305
- // case "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND":
1306
- // this.commandBus.emit(command);
1307
- // break;
1308
- // case "PAGE_QUE_JUMP_TO_PAGE_COMMAND":
1309
- // this.commandBus.emit(command);
1310
- // break;
1311
- // case "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND":
1312
- // this.commandBus.emit(command);
1313
- // break;
1314
- // case "STATE_MUTATE_COMMAND":
1315
- // this.commandBus.emit(command);
1316
- // break;
1317
- // default:
1318
- // DUtil.neverCheck(command);
1319
- // }
1320
- // }
1321
- queryChangedHandler(result) {
1322
- const maybeHandlers = this.baseDto.onStateChange;
1323
- if (!maybeHandlers) {
1324
- return;
1325
- }
1326
- const queryHandlers = maybeHandlers.filter((h) => h.queryName === result.queryName);
1327
- queryHandlers.forEach((h) => {
1328
- if (result.curr) {
1329
- h.whenTrue.forEach((command) => {
1330
- this.commandBus.emit(command);
1331
- });
1332
- } else {
1333
- h.whenFalse.forEach((command) => {
1334
- this.commandBus.emit(command);
1335
- });
1336
- }
1337
- });
1338
- }
1339
- onClickHandler(_) {
1340
- if (!this.clickHandlerIsEnabled) {
1341
- console.log(this.id + "Click disabled");
1342
- return;
1343
- }
1344
- const clickAction = this.baseDto.onClick;
1345
- if (clickAction && clickAction.length > 0) {
1346
- this.eventBus.emit({
1347
- kind: "USER_CLICKED_EVENT",
1348
- producer: "DUser",
1349
- producerId: this.id,
1350
- data: { elementId: this.id },
1351
- timestamp: DTimestamp.now()
1352
- });
1353
- clickAction.forEach((command) => {
1354
- this.commandBus.emit(command);
1355
- });
1356
- }
1357
- }
1358
- onMouseOver(_) {
1359
- }
1360
- setStyle(style) {
1361
- this.updateStyles(style);
1362
- }
1363
- appendYourself(parent) {
1364
- parent.append(this.el);
1365
- }
1366
- handleAnimateSelfAction(dto) {
1367
- this.isAnimatingSelf = true;
1368
- const { keyframes, options } = dto;
1369
- const animation = this.el.animate(keyframes, options.duration);
1370
- animation.onfinish = (e) => {
1371
- console.log(e.type);
1372
- this.isAnimatingSelf = false;
1373
- };
1374
- animation.onremove = () => {
1375
- console.warn("ANIMATION REMOVED: " + animation.id);
1376
- this.isAnimatingSelf = false;
1377
- };
1378
- animation.oncancel = () => {
1379
- console.warn("ANIMATION CANCELED: " + animation.id);
1380
- this.isAnimatingSelf = false;
1381
- };
1382
- }
1383
- normalize() {
1384
- DStyle.normalize(this.el);
1385
- }
1386
- updateStyles(style) {
1387
- this.currStyle = Object.assign(this.currStyle, style);
1388
- DStyle.applyStyles(this.el, this.currStyle, this.scale.scale);
1389
- window.getComputedStyle(this.el);
1390
- }
1391
- };
1392
-
1393
- // src/Delement/Ddiv.ts
1394
- var DDiv = class extends DElement {
1395
- TAG = "[ DDiv ]: ";
1396
- defaultStyle = { x: 22, y: 4 };
1397
- children = [];
1398
- constructor(dto, eventBus, actionService, scale, children) {
1399
- const d = document.createElement("div");
1400
- super(d, eventBus, actionService, dto, scale);
1401
- this.children = children;
1402
- this.children.forEach((child) => {
1403
- child.appendYourself(this.el);
1404
- });
1405
- }
1406
- destroy() {
1407
- this.subscriptions.forEach((unsubscribe) => {
1408
- unsubscribe();
1409
- });
1410
- this.children.forEach((child) => {
1411
- child.destroy();
1412
- });
1413
- }
1414
- };
1415
-
1416
- // src/Delement/DImg.ts
1417
- var DImg = class _DImg extends DElement {
1418
- constructor(dto, actionSubject, eventBus, scaleService) {
1419
- super(document.createElement("img"), eventBus, actionSubject, dto, scaleService);
1420
- this.dto = dto;
1421
- this.actionSubject = actionSubject;
1422
- this.eventBus = eventBus;
1423
- this.scaleService = scaleService;
1424
- _DImg.IMAGE_COUNT += 1;
1425
- this.imageCount = _DImg.IMAGE_COUNT;
1426
- this.TAG = "[D_IMG " + _DImg.IMAGE_COUNT + " ]: ";
1427
- this.TIMING_TAG = "load-time (" + _DImg.IMAGE_COUNT + ") ";
1428
- this.el.loading = "eager";
1429
- this.el.style.position = "absolute";
1430
- this.setStyle(dto.style);
1431
- this.loadStart = DTimestamp.now();
1432
- this.onError = this.onError.bind(this);
1433
- this.onLoad = this.onLoad.bind(this);
1434
- this.el.onload = this.onLoad;
1435
- this.el.onerror = this.onError;
1436
- this.el.src = dto.url;
1437
- console.time(this.TIMING_TAG);
1438
- }
1439
- static IMAGE_COUNT = 0;
1440
- imageCount;
1441
- TAG;
1442
- TIMING_TAG;
1443
- loadStart;
1444
- log() {
1445
- }
1446
- setScale(scale) {
1447
- console.log(scale);
1448
- this.setStyle(this.currStyle);
1449
- }
1450
- destroy() {
1451
- this.subscriptions.forEach((unsubscribe) => {
1452
- unsubscribe();
1453
- });
1454
- }
1455
- onError(ev) {
1456
- if (ev instanceof Event) {
1457
- console.log(this.TAG + " " + ev.type);
1458
- } else {
1459
- console.log(this.TAG + ev);
1460
- }
1461
- }
1462
- onLoad(_) {
1463
- const loadTime = DTimestamp.diffNow(this.loadStart);
1464
- this.eventBus.emit({
1465
- kind: "IMAGE_LOADED_EVENT",
1466
- producer: "DImage",
1467
- producerId: this.id,
1468
- timestamp: DTimestamp.now(),
1469
- data: {
1470
- loadTime,
1471
- naturalHeight: this.el.naturalHeight,
1472
- naturalWidth: this.el.naturalWidth,
1473
- height: this.el.height,
1474
- width: this.el.width
1475
- }
1476
- });
1477
- }
1478
- };
1479
-
1480
- // src/Delement/DText.ts
1481
- var DText = class extends DElement {
1482
- TAG = "[ DParagraph ]: ";
1483
- defaultStyle = {};
1484
- constructor(dto, eventBus, actionService, scale) {
1485
- super(document.createElement("p"), eventBus, actionService, dto, scale);
1486
- this.el.style.position = "absolute";
1487
- this.el.innerText = "" + dto.text;
1488
- this.setStyle(dto.style);
1489
- }
1490
- setScale(scale) {
1491
- this.setStyle(this.currStyle);
1492
- const fontSize = this.el.style.fontSize;
1493
- console.log(this.TAG + "scale: " + scale + " Fontsize: " + fontSize);
1494
- }
1495
- destroy() {
1496
- this.subscriptions.forEach((unsubscribe) => {
1497
- unsubscribe();
1498
- });
1499
- }
1500
- };
1501
-
1502
- // src/engine/element-factory.ts
1503
- var createDElement = (dto, actionBus, eventBus, scale) => {
1504
- switch (dto._tag) {
1505
- case "div":
1506
- const childEls = createChildrenForDiv(dto, actionBus, eventBus, scale);
1507
- const newDiv = new DDiv(dto, eventBus, actionBus, scale, childEls);
1508
- return newDiv;
1509
- case "img":
1510
- return new DImg(dto, actionBus, eventBus, scale);
1511
- case "p":
1512
- return new DText(dto, eventBus, actionBus, scale);
1513
- default:
1514
- const check = dto;
1515
- throw new Error("Unknown dto given to the createDElement function.");
1516
- }
1517
- };
1518
- var createChildrenForDiv = (dto, actionSubject, eventBus, scale) => {
1519
- const childDto = dto.children;
1520
- const childEls = [];
1521
- childDto.forEach((dto2) => {
1522
- if (dto2._tag === "p") {
1523
- const newText = new DText(dto2, eventBus, actionSubject, scale);
1524
- childEls.push(newText);
1525
- }
1526
- if (dto2._tag === "img") {
1527
- const newImage = new DImg(dto2, actionSubject, eventBus, scale);
1528
- childEls.push(newImage);
1529
- }
1530
- });
1531
- return childEls;
1532
- };
1533
-
1534
- // src/engine/DPage.ts
1535
- var DPage = class {
1536
- // Todo GLOBAL EVENT_BUSS AND PAGE EVENTS:
1537
- constructor(dto, eventBus, commandBus, scale) {
1538
- this.dto = dto;
1539
- this.eventBus = eventBus;
1540
- this.commandBus = commandBus;
1541
- this.scale = scale;
1542
- this.elements = dto.elements.map((dto2) => createDElement(dto2, this.commandBus, this.eventBus, this.scale));
1543
- }
1544
- TAG = "[ DPage ]: ";
1545
- elements = [];
1546
- eventBus;
1547
- commandBus;
1548
- scale;
1549
- appendYourself(parent) {
1550
- this.elements.forEach((el) => {
1551
- el.appendYourself(parent);
1552
- });
1553
- this.eventBus.emit({
1554
- kind: "PAGE_ENTER_EVENT",
1555
- timestamp: DTimestamp.now(),
1556
- producer: "DPage",
1557
- producerId: this.id,
1558
- data: { pageId: this.id }
1559
- });
1560
- }
1561
- destroy() {
1562
- this.elements.forEach((el) => {
1563
- el.destroy();
1564
- });
1565
- }
1566
- log() {
1567
- }
1568
- get id() {
1569
- return this.dto.id;
1570
- }
1571
- };
1572
-
1573
- // src/engine/scale.ts
1574
- var ScaleService = class {
1575
- baseHeight;
1576
- baseWidth;
1577
- containerHeight = 1300;
1578
- containerWidth = 1300;
1579
- get scale() {
1580
- return this._scale;
1581
- }
1582
- get pageHeight() {
1583
- return this.baseHeight * this.scale;
1584
- }
1585
- get pageWidth() {
1586
- return this.baseWidth * this._scale;
1587
- }
1588
- _scale = 1;
1589
- subscribers = /* @__PURE__ */ new Set();
1590
- constructor(config) {
1591
- this.baseHeight = config.baseHeight;
1592
- this.baseWidth = config.baseWidth;
1593
- this.containerHeight = config.containerHeight;
1594
- this.containerWidth = config.containerWidth;
1595
- this.updateScale();
1596
- }
1597
- setContainerBounds(bounds) {
1598
- this.containerWidth = bounds.width;
1599
- this.containerHeight = bounds.height;
1600
- this.updateScale();
1601
- }
1602
- updateScale() {
1603
- const scaleFn = Scale.calc(this.baseHeight, this.baseWidth);
1604
- const scale = scaleFn({ height: this.containerHeight, width: this.containerWidth });
1605
- const hasChanged = this.scale !== scale;
1606
- this._scale = scale;
1607
- if (hasChanged) {
1608
- this.subscribers.forEach((fn) => {
1609
- fn(this._scale);
1610
- });
1611
- }
1612
- }
1613
- onChange(scaleChangeHandler, subscriberId) {
1614
- this.subscribers.add(scaleChangeHandler);
1615
- scaleChangeHandler(this._scale);
1616
- return () => {
1617
- this.subscribers.delete(scaleChangeHandler);
1618
- };
1619
- }
1620
- };
1621
- var Scale;
1622
- ((Scale2) => {
1623
- Scale2.calc = (baseHeight, baseWidth) => {
1624
- return (container) => {
1625
- const heightRatio = container.height / baseHeight;
1626
- const widthRatio = container.width / baseWidth;
1627
- return Math.min(heightRatio, widthRatio);
1628
- };
1629
- };
1630
- Scale2.scaleFunctionCreator = (scale) => {
1631
- return (value) => value * scale;
1632
- };
1633
- })(Scale || (Scale = {}));
1634
-
1635
- // src/services/resource-provider.ts
1636
- var ResourceProvider = class {
1637
- TAG = "[ RESOURCE_PROVIDER ]: ";
1638
- videoMap = /* @__PURE__ */ new Map();
1639
- audioMap = /* @__PURE__ */ new Map();
1640
- constructor(data) {
1641
- data.videos.forEach((video) => {
1642
- this.videoMap.set(video.id, video);
1643
- });
1644
- data.audio.forEach((audio) => {
1645
- this.audioMap.set(audio.id, audio);
1646
- });
1647
- }
1648
- getAudioById(id) {
1649
- const maybeAudio = this.audioMap.get(id);
1650
- if (!maybeAudio) {
1651
- console.error(this.TAG + "Audio by id " + id + " dont exist");
1652
- }
1653
- return maybeAudio ?? false;
1654
- }
1655
- getVideoById(id) {
1656
- const maybeVideo = this.videoMap.get(id);
1657
- if (!maybeVideo) {
1658
- console.error(this.TAG + "Video by id " + id + " dont exist");
1659
- }
1660
- return maybeVideo ?? false;
1661
- }
1662
- };
1663
-
1664
- // src/common/result.ts
1665
- var Ok = class _Ok {
1666
- constructor(value) {
1667
- this.value = value;
1668
- }
1669
- isOk() {
1670
- return true;
1671
- }
1672
- isFailure() {
1673
- return false;
1674
- }
1675
- map(f) {
1676
- const value = f(this.value);
1677
- return new _Ok(value);
1678
- }
1679
- };
1680
- var Failure = class _Failure {
1681
- constructor(message) {
1682
- this.message = message;
1683
- }
1684
- isFailure() {
1685
- return true;
1686
- }
1687
- isOk() {
1688
- return false;
1689
- }
1690
- map(_f) {
1691
- return new _Failure(this.message);
1692
- }
1693
- };
1694
- var Result;
1695
- ((Result2) => {
1696
- Result2.ok = (value) => new Ok(value);
1697
- Result2.failure = (message) => new Failure(message);
1698
- })(Result || (Result = {}));
1699
-
1700
- // src/state/Dstate.ts
1701
- var DState;
1702
- ((DState2) => {
1703
- DState2.isNumberMutation = (mutations) => {
1704
- if (!mutations) {
1705
- return false;
1706
- }
1707
- return mutations.kind === "set-number" || mutations.kind === "decrement-number" || mutations.kind === "increment-number";
1708
- };
1709
- DState2.isStringMutation = (mutation) => {
1710
- return mutation && mutation.kind === "set-string";
1711
- };
1712
- DState2.numericPropToFact = (prop, value) => {
1713
- const fact = {
1714
- kind: "numeric-fact",
1715
- referenceId: prop.propName,
1716
- referenceLabel: prop.propDescription ?? " [STATE_PROPERTY] : " + prop.propName,
1717
- value,
1718
- label: " [VALUE] : " + value
1719
- };
1720
- return fact;
1721
- };
1722
- DState2.stringPropToFact = (prop, value) => {
1723
- const fact = {
1724
- kind: "string-fact",
1725
- referenceId: prop.propName,
1726
- referenceLabel: " [STATE_PROPERTY] : " + prop.propName,
1727
- value,
1728
- label: " [VALUE] : " + value
1729
- };
1730
- return fact;
1731
- };
1732
- })(DState || (DState = {}));
1733
-
1734
- // src/state/state-service.ts
1735
- var StateService = class {
1736
- constructor(eventBus, commandBus, props, queryList = []) {
1737
- this.eventBus = eventBus;
1738
- this.commandBus = commandBus;
1739
- this.props = props;
1740
- this.queryList = queryList;
1741
- props.forEach((prop) => {
1742
- this.registerProperty(prop);
1743
- });
1744
- const facts = this.getAllFacts();
1745
- queryList.forEach((definition) => {
1746
- this.registerQuery(definition, facts);
1747
- });
1748
- this.evaluateQueries();
1749
- this.unsubscribeCommands = this.commandBus.subscribe((command) => {
1750
- if (command.kind === "STATE_MUTATE_COMMAND") {
1751
- this.mutation(command.payload.mutation);
1752
- }
1753
- }, this.TAG);
1754
- }
1755
- TAG = " [ STATE_SERVICE ] :";
1756
- factsString = /* @__PURE__ */ new Map();
1757
- factsNumeric = /* @__PURE__ */ new Map();
1758
- propDefinitions = /* @__PURE__ */ new Map();
1759
- queries = /* @__PURE__ */ new Map();
1760
- unsubscribeCommands;
1761
- destroy() {
1762
- this.unsubscribeCommands();
1763
- }
1764
- registerQuery(query, currentFacts) {
1765
- const result = Condition.evaluate(query.condition, currentFacts);
1766
- this.queries.set(query.name, { query, lastResult: result });
1767
- this.emitQueryChangedEvent({ queryName: query.name, prev: result, curr: result });
1768
- }
1769
- registerProperty(prop) {
1770
- if (this.propDefinitions.has(prop.propName)) {
1771
- console.warn("Prop excists already.", prop.propName);
1772
- }
1773
- this.propDefinitions.set(prop.propName, prop);
1774
- if (prop.initialValue === void 0) {
1775
- return;
1776
- }
1777
- if (prop._type === "string") {
1778
- const fact = DState.stringPropToFact(prop, prop.initialValue);
1779
- this.factsString.set(fact.referenceId, fact);
1780
- }
1781
- if (prop._type === "number") {
1782
- const fact = DState.numericPropToFact(prop, prop.initialValue);
1783
- this.factsNumeric.set(fact.referenceId, fact);
1784
- }
1785
- }
1786
- mutateString(prop, value) {
1787
- const curr = this.factsString.get(prop.propName);
1788
- if (curr) {
1789
- const updated = { ...curr, value };
1790
- this.setFact(updated);
1791
- } else {
1792
- const created = {
1793
- kind: "string-fact",
1794
- referenceId: prop.propName,
1795
- referenceLabel: "label for: " + prop.propName,
1796
- value,
1797
- label: "Value: " + value
1798
- };
1799
- this.setFact(created);
1800
- }
1801
- }
1802
- mutateNumber(prop, mutation) {
1803
- const curr = this.factsNumeric.get(prop.propName);
1804
- if (!curr) {
1805
- switch (mutation.kind) {
1806
- case "set-number":
1807
- this.setFact(DState.numericPropToFact(prop, mutation.value));
1808
- break;
1809
- case "decrement-number":
1810
- this.setFact(DState.numericPropToFact(prop, mutation.ifNotExistThenSetTo));
1811
- break;
1812
- case "increment-number":
1813
- this.setFact(DState.numericPropToFact(prop, mutation.ifNotExistThenSetTo));
1814
- break;
1815
- default:
1816
- const check = mutation;
1817
- }
1818
- }
1819
- if (curr) {
1820
- switch (mutation.kind) {
1821
- case "set-number":
1822
- this.setFact({ ...curr, value: mutation.value });
1823
- break;
1824
- case "decrement-number":
1825
- this.setFact({ ...curr, value: curr.value - mutation.stepSize });
1826
- break;
1827
- case "increment-number":
1828
- this.setFact({ ...curr, value: curr.value + mutation.stepSize });
1829
- break;
1830
- default:
1831
- const check = mutation;
1832
- }
1833
- }
1834
- }
1835
- evaluateQueries() {
1836
- const facts = this.getAllFacts();
1837
- const all = [];
1838
- this.queries.forEach((q) => {
1839
- const prev = q.lastResult;
1840
- const curr = Condition.evaluate(q.query.condition, facts);
1841
- const didChange = prev !== curr;
1842
- q.lastResult = curr;
1843
- all.push({ queryName: q.query.name, prev, curr, didChange });
1844
- });
1845
- return all;
1846
- }
1847
- mutation(mutation) {
1848
- const propDef = this.propDefinitions.get(mutation.propName);
1849
- if (!propDef) {
1850
- return { success: false };
1851
- }
1852
- if (propDef._type === "string" && DState.isStringMutation(mutation)) {
1853
- this.mutateString(propDef, mutation.value);
1854
- }
1855
- if (propDef._type === "number" && DState.isNumberMutation(mutation)) {
1856
- this.mutateNumber(propDef, mutation);
1857
- }
1858
- const queryResults = this.evaluateQueries();
1859
- const changedResult = queryResults.filter((r) => r.didChange);
1860
- changedResult.forEach((res) => {
1861
- this.emitQueryChangedEvent({ queryName: res.queryName, prev: res.prev, curr: res.curr });
1862
- });
1863
- return { success: true };
1864
- }
1865
- emitQueryChangedEvent(data) {
1866
- const queryChangedEvent = {
1867
- kind: "STATE_QUERY_RESULT_CHANGED_EVENT",
1868
- producer: "STATE-SERVICE",
1869
- producerId: "STATE-SERVICE",
1870
- timestamp: DTimestamp.now(),
1871
- data
1872
- };
1873
- const { queryName, curr, prev } = queryChangedEvent.data;
1874
- this.eventBus.emit(queryChangedEvent);
1875
- }
1876
- getPropAsFact(propName) {
1877
- const propDef = this.propDefinitions.get(propName);
1878
- if (!propDef) {
1879
- return Result.failure(
1880
- "No definition form property ny name " + propName + " is registered. (Pass in constructor.)"
1881
- );
1882
- }
1883
- const value = this.factsString.get(propName) ?? this.factsNumeric.get(propName);
1884
- return value ? Result.ok(value) : Result.failure("Property " + propName + " has no value.");
1885
- }
1886
- setFact(fact) {
1887
- switch (fact.kind) {
1888
- case "numeric-fact":
1889
- this.factsNumeric.set(fact.referenceId, fact);
1890
- break;
1891
- case "string-fact":
1892
- this.factsString.set(fact.referenceId, fact);
1893
- break;
1894
- default:
1895
- const check = fact;
1896
- }
1897
- }
1898
- getState() {
1899
- const props = {};
1900
- this.propDefinitions.forEach((def) => {
1901
- let value = null;
1902
- const maybeFact = this.getAnyFact(def.propName);
1903
- if (maybeFact) {
1904
- value = maybeFact.value;
1905
- }
1906
- props[def.propName] = value;
1907
- });
1908
- this.queries.forEach((query) => {
1909
- props[query.query.name] = query.lastResult;
1910
- });
1911
- const propNames = Object.keys(props);
1912
- const propCount = propNames.length;
1913
- const propArray = [...this.propDefinitions.values()];
1914
- return { propCount, propNames, propArray, state: props };
1915
- }
1916
- getAnyFact(propName) {
1917
- return this.factsString.get(propName) ?? this.factsNumeric.get(propName) ?? false;
1918
- }
1919
- getAllFacts() {
1920
- return [...this.factsNumeric.values(), ...this.factsString.values()];
1921
- }
1922
- /**
1923
- * Will check that all referenceIds used in Condition is registered as a valid property in state.
1924
- * @param condition
1925
- */
1926
- canBeMatched(condition) {
1927
- const simpleConditions = Condition.getAllSimpleConditions(condition);
1928
- let hasAll = true;
1929
- const allIds = simpleConditions.map((c) => c.referenceId);
1930
- const missingIds = [];
1931
- allIds.forEach((id) => {
1932
- if (!this.propDefinitions.has(id)) {
1933
- hasAll = false;
1934
- missingIds.push(id);
1935
- }
1936
- });
1937
- console.log(this.TAG, missingIds);
1938
- return hasAll;
1939
- }
1940
- isMatched(condition) {
1941
- return Condition.evaluate(condition, this.getAllFacts());
1942
- }
1943
- };
1944
-
1945
- // src/engine/SchemaEngine.ts
1946
- var SchemaEngine = class {
1947
- constructor(hostEl, height, width, schema) {
1948
- this.height = height;
1949
- this.width = width;
1950
- this.schema = schema;
1951
- this.hostElement = hostEl;
1952
- this.hostElement.appendChild(this.uiContainer);
1953
- this.hostElement.appendChild(this.mediaContainer);
1954
- const stateProps = this.schema.stateProps ?? [];
1955
- const stateQueries = this.schema.stateQueries ?? [];
1956
- this.stateService = new StateService(this.eventBus, this.commandBus, stateProps, stateQueries);
1957
- this.scale = new ScaleService({
1958
- baseHeight: schema.baseHeight,
1959
- baseWidth: schema.baseWidth,
1960
- containerWidth: width,
1961
- containerHeight: height
1962
- });
1963
- const globalEventHandlers = schema.stateFromEvent ?? [];
1964
- globalEventHandlers.forEach((h) => {
1965
- this.globalEventToStateHandlers.set(h.onEvent, h.thenExecute);
1966
- });
1967
- const resources = SchemaDto.getResources(this.schema);
1968
- this.resourceProvider = new ResourceProvider({ videos: resources.videoList, audio: resources.audioList });
1969
- this.mediaManager = new DMediaManager(
1970
- this.mediaContainer,
1971
- this.commandBus,
1972
- this.eventBus,
1973
- this.resourceProvider,
1974
- this.scale
1975
- );
1976
- this.player = new DPlayer(this.schema);
1977
- this.styleSelf();
1978
- this.nextPage();
1979
- this.hookUpListeners();
1980
- }
1981
- TAG = "[ SCHEMA_ENGINE ] :";
1982
- commandBus = new DCommandBus();
1983
- eventBus = new EventBus();
1984
- mediaManager;
1985
- scale;
1986
- hostElement;
1987
- uiContainer = document.createElement("div");
1988
- mediaContainer = document.createElement("div");
1989
- resourceProvider;
1990
- stateService;
1991
- globalEventToStateHandlers = /* @__PURE__ */ new Map();
1992
- player;
1993
- currentPage = false;
1994
- subs = [];
1995
- hookUpListeners() {
1996
- const eventSubscription = this.eventBus.subscribe((ev) => {
1997
- this.onCommandOrEvent(ev);
1998
- const globalHandlers = this.globalEventToStateHandlers.get(ev.kind) ?? [];
1999
- globalHandlers.forEach((stateCommand) => {
2000
- this.commandBus.emit(stateCommand);
2001
- });
2002
- }, this.TAG + "HOOK_UP_LISTENERS");
2003
- const commandSubscription = this.commandBus.subscribe((command) => {
2004
- this.onCommandOrEvent(command);
2005
- if (command.kind === "PAGE_QUE_NEXT_PAGE_COMMAND") {
2006
- this.nextPage();
2007
- }
2008
- if (command.kind === "ENGINE_LEAVE_PAGE_COMMAND") {
2009
- console.log(this.TAG + "SEQUENCE STARTED -- TODO EVENT FOR THIS??");
2010
- console.log(command);
2011
- const pageId = command.payload.pageId;
2012
- const facts = command.payload.factsCollected;
2013
- const timestamp = DTimestamp.now();
2014
- const ans = facts.map((f) => ({
2015
- timestamp,
2016
- fact: f
2017
- }));
2018
- this.player.saveHistory({
2019
- answeredQuestions: ans,
2020
- pageId
2021
- });
2022
- this.nextPage();
2023
- }
2024
- }, this.TAG);
2025
- this.subs.push(commandSubscription);
2026
- this.subs.push(eventSubscription);
2027
- }
2028
- styleSelf() {
2029
- this.hostElement.style.height = this.scale.pageHeight + "px";
2030
- this.hostElement.style.width = this.scale.pageWidth + "px";
2031
- this.hostElement.style.backgroundColor = this.schema.backgroundColor ?? "white";
2032
- this.hostElement.style.position = "relative";
2033
- const makeStatic = (div) => {
2034
- div.style.height = "0px";
2035
- div.style.width = "0px";
2036
- div.style.position = "static";
2037
- };
2038
- makeStatic(this.uiContainer);
2039
- makeStatic(this.mediaContainer);
2040
- }
2041
- nextPage() {
2042
- this.mediaManager.clearAllMedia();
2043
- const nextPage = this.player.getNextPage();
2044
- if (this.currentPage) {
2045
- this.currentPage.destroy();
2046
- this.uiContainer.innerHTML = "";
2047
- }
2048
- if (!nextPage) {
2049
- this.player = new DPlayer(this.schema);
2050
- if (this.schema.pages.length > 0) {
2051
- this.nextPage();
2052
- }
2053
- return false;
2054
- }
2055
- const newPage = new DPage(nextPage, this.eventBus, this.commandBus, this.scale);
2056
- this.currentPage = newPage;
2057
- newPage.appendYourself(this.uiContainer);
2058
- this.mediaManager.setPage(nextPage);
2059
- const s1 = this.stateService.getState();
2060
- return true;
2061
- }
2062
- destroy() {
2063
- if (this.currentPage) {
2064
- this.currentPage.destroy();
2065
- this.uiContainer.innerHTML = "";
2066
- }
2067
- this.mediaManager.destroy();
2068
- this.stateService.destroy();
2069
- this.subs.forEach((sub) => {
2070
- sub();
2071
- });
2072
- const evStats = this.eventBus.getStats();
2073
- const cmdStats = this.commandBus.getStats();
2074
- console.assert(evStats.subscribersCount === 0, this.TAG + " Eventbus should have no subscribers ", evStats);
2075
- console.assert(cmdStats.subscribersCount === 0, this.TAG + "Commandbus should have no subscribers", cmdStats);
2076
- }
2077
- onComplete(handler) {
2078
- console.log(handler);
2079
- }
2080
- onFatalError(handler) {
2081
- console.log(handler);
2082
- }
2083
- onCommandOrEvent(_event_or_command) {
2084
- }
2085
- setSchema(schema) {
2086
- console.log(schema);
2087
- }
2088
- };
2089
-
2090
- // src/state/boolean-property.ts
2091
- var BooleanStateProperty = class _BooleanStateProperty {
2092
- constructor(propName, initialValue, description) {
2093
- this.initialValue = initialValue;
2094
- this.propName = propName;
2095
- const initial = initialValue ? 1 : 0;
2096
- const propDescription = description ? description : "No description given";
2097
- this.propDefinition = {
2098
- propDescription,
2099
- propName,
2100
- initialValue: initial,
2101
- options: [
2102
- { value: _BooleanStateProperty.FALSE.value, valueLabel: _BooleanStateProperty.FALSE.label },
2103
- { value: _BooleanStateProperty.TRUE.value, valueLabel: _BooleanStateProperty.TRUE.label }
2104
- ],
2105
- _type: "number"
2106
- };
2107
- }
2108
- propName;
2109
- static TRUE = { value: 1, label: "TRUE" };
2110
- static FALSE = { value: 0, label: "FALSE" };
2111
- propDefinition;
2112
- getIsTrueCondition() {
2113
- return {
2114
- kind: "numeric-condition",
2115
- referenceId: this.propName,
2116
- referenceLabel: this.propName + "[ BOOLEAN ]",
2117
- valueLabel: _BooleanStateProperty.TRUE.label,
2118
- value: _BooleanStateProperty.TRUE.value,
2119
- operator: "eq"
2120
- };
2121
- }
2122
- getIsFalseCondition() {
2123
- return {
2124
- kind: "numeric-condition",
2125
- referenceId: this.propName,
2126
- referenceLabel: this.propName + "[ BOOLEAN ]",
2127
- valueLabel: _BooleanStateProperty.FALSE.label,
2128
- value: _BooleanStateProperty.FALSE.value,
2129
- operator: "eq"
2130
- };
2131
- }
2132
- getSetTrueCommand() {
2133
- return {
2134
- kind: "STATE_MUTATE_COMMAND",
2135
- target: "STATE",
2136
- targetId: "STATE",
2137
- payload: {
2138
- mutation: { propName: this.propName, kind: "set-number", value: 1 }
2139
- }
2140
- };
2141
- }
2142
- getSetFalseCommand() {
2143
- return {
2144
- kind: "STATE_MUTATE_COMMAND",
2145
- target: "STATE",
2146
- targetId: "STATE",
2147
- payload: {
2148
- mutation: { propName: this.propName, kind: "set-number", value: 0 }
2149
- }
2150
- };
2151
- }
2152
- };
2153
-
2154
- // src/utils/ID.ts
2155
- var ID_LENGTH = 32;
2156
- var MIN_LENGTH = 10;
2157
- var isID = (idName, id) => {
2158
- if (typeof id !== "string")
2159
- return false;
2160
- return id.length >= MIN_LENGTH;
2161
- };
2162
- var createIDByName = (idName) => {
2163
- const letters = "abcdefghijklmnopqrstuvyz";
2164
- const all = letters + letters.toUpperCase();
2165
- let result = "";
2166
- for (let i = 0; i < ID_LENGTH; i++) {
2167
- const char = all.charAt(Math.floor(Math.random() * all.length));
2168
- result += char;
2169
- }
2170
- return result;
2171
- };
2172
- var createTypedIdSingleton = (idName) => {
2173
- const create = () => createIDByName(idName);
2174
- const is = (id) => isID(idName, id);
2175
- const validateOrThrow = (id) => {
2176
- if (!is(id)) {
2177
- throw new Error(`Invalid id: ${id}`);
2178
- }
2179
- return id;
2180
- };
2181
- const name = idName;
2182
- const ensure = (id) => {
2183
- return is(id) ? id : create();
2184
- };
2185
- return Object.freeze({ create, is, ensure, validateOrThrow, name });
2186
- };
2187
- var SchemaID = createTypedIdSingleton("SCHEMA");
2188
- var PageID = createTypedIdSingleton("PAGE");
2189
- export {
2190
- BooleanStateProperty,
2191
- Condition,
2192
- DCss,
2193
- DEventHandler,
2194
- DState,
2195
- DStyle,
2196
- DUtil,
2197
- PageID,
2198
- Rule,
2199
- RuleEngine,
2200
- SchemaDto,
2201
- SchemaEngine,
2202
- SchemaID,
2203
- createTypedIdSingleton
2204
- };
2205
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2R0by9TY2hlbWFEdG8udHMiLCAiLi4vc3JjL2NvbW1vbi9EVGltZXN0YW1wLnRzIiwgIi4uL3NyYy91dGlscy9EVXRpbC50cyIsICIuLi9zcmMvRGVsZW1lbnQvY3NzLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EU3R5bGUudHMiLCAiLi4vc3JjL0RlbGVtZW50L1ZpZGVvQ29udGFpbmVyLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9BdWRpb0NvbnRhaW5lci50cyIsICIuLi9zcmMvc2VydmljZXMvRE1lZGlhLW1hbmFnZXIudHMiLCAiLi4vc3JjL2NvbW1hbmRzL0RDb21tYW5kQnVzLnRzIiwgIi4uL3NyYy9ldmVudHMvZXZlbnQtYnVzLnRzIiwgIi4uL3NyYy9wbGF5ZXIvaGlzdG9yeS1xdWUudHMiLCAiLi4vc3JjL3J1bGVzL2NvbmRpdGlvbi50cyIsICIuLi9zcmMvcnVsZXMvcnVsZS50cyIsICIuLi9zcmMvcnVsZXMvcnVsZS1lbmdpbmUudHMiLCAiLi4vc3JjL3BsYXllci9uZXh0LXF1ZS50cyIsICIuLi9zcmMvcGxheWVyL2RwbGF5ZXIudHMiLCAiLi4vc3JjL2V2ZW50LWhhbmRsZXJzL0RFdmVudEhhbmRsZXIudHMiLCAiLi4vc3JjL0RlbGVtZW50L0RFbGVtZW50LnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EZGl2LnRzIiwgIi4uL3NyYy9EZWxlbWVudC9ESW1nLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EVGV4dC50cyIsICIuLi9zcmMvZW5naW5lL2VsZW1lbnQtZmFjdG9yeS50cyIsICIuLi9zcmMvZW5naW5lL0RQYWdlLnRzIiwgIi4uL3NyYy9lbmdpbmUvc2NhbGUudHMiLCAiLi4vc3JjL3NlcnZpY2VzL3Jlc291cmNlLXByb3ZpZGVyLnRzIiwgIi4uL3NyYy9jb21tb24vcmVzdWx0LnRzIiwgIi4uL3NyYy9zdGF0ZS9Ec3RhdGUudHMiLCAiLi4vc3JjL3N0YXRlL3N0YXRlLXNlcnZpY2UudHMiLCAiLi4vc3JjL2VuZ2luZS9TY2hlbWFFbmdpbmUudHMiLCAiLi4vc3JjL3N0YXRlL2Jvb2xlYW4tcHJvcGVydHkudHMiLCAiLi4vc3JjL3V0aWxzL0lELnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBEQXV0b1BsYXlTZXF1ZW5jZSB9IGZyb20gXCIuLi9EZWxlbWVudC9EQXV0by1wbGF5XCI7XG5pbXBvcnQgeyBEQXVkaW9EdG8sIERFbGVtZW50RHRvLCBESW1nRHRvLCBEVmlkZW9EdG8gfSBmcm9tIFwiLi9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IFJ1bGUgfSBmcm9tIFwiLi4vcnVsZXMvcnVsZVwiO1xuaW1wb3J0IHsgRmFjdCB9IGZyb20gXCIuLi9ydWxlcy9mYWN0XCI7XG5pbXBvcnQgeyBQYWdlUXVlQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgRFN0YXRlIH0gZnJvbSBcIi4uL3N0YXRlL0RzdGF0ZVwiO1xuaW1wb3J0IHsgUGFnZUlELCBTY2hlbWFJRCB9IGZyb20gXCIuLi91dGlscy9JRFwiO1xuXG5leHBvcnQgdHlwZSBQYWdlUXVlUnVsZXMgPSBSdWxlPFBhZ2VRdWVDb21tYW5kLCBuZXZlcj47XG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VEdG8ge1xuICByZWFkb25seSBpZDogUGFnZUlEO1xuICByZWFkb25seSBlbGVtZW50czogQXJyYXk8REVsZW1lbnREdG8+O1xuICByZWFkb25seSB0YWdzPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IG1haW5WaWRlb0lkPzogc3RyaW5nO1xuICByZWFkb25seSBiYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZpZGVvPzogQXJyYXk8RFZpZGVvRHRvPjtcbiAgcmVhZG9ubHkgYXVkaW8/OiBBcnJheTxEQXVkaW9EdG8+O1xuICByZWFkb25seSBhdXRvUGxheVNlcXVlbmNlPzogREF1dG9QbGF5U2VxdWVuY2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZVNlcXVlbmNlRHRvIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgcnVsZXM6IEFycmF5PFBhZ2VRdWVSdWxlcz47XG4gIHJlYWRvbmx5IHBhZ2VzOiBBcnJheTxQYWdlRHRvPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY2hlbWFEdG8ge1xuICByZWFkb25seSBpZDogU2NoZW1hSUQ7XG4gIHJlYWRvbmx5IGJhc2VIZWlnaHQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgYmFzZVdpZHRoOiBudW1iZXI7XG4gIHJlYWRvbmx5IGJhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICByZWFkb25seSBwYWdlczogUGFnZUR0b1tdO1xuICByZWFkb25seSBydWxlczogQXJyYXk8UGFnZVF1ZVJ1bGVzPjtcbiAgcmVhZG9ubHkgc3RhdGVQcm9wcz86IFJlYWRvbmx5QXJyYXk8RFN0YXRlLlByb3A+O1xuICByZWFkb25seSBzdGF0ZVF1ZXJpZXM/OiBSZWFkb25seUFycmF5PERTdGF0ZS5TdGF0ZVF1ZXJ5PjtcbiAgcmVhZG9ubHkgc3RhdGVGcm9tRXZlbnQ6IFJlYWRvbmx5QXJyYXk8RFN0YXRlLmZyb21FdmVudEhhbmRsZXI+O1xuICByZWFkb25seSBwYWdlU2VxdWVuY2VzPzogQXJyYXk8UGFnZVNlcXVlbmNlRHRvPjtcbiAgcmVhZG9ubHkgcHJlZGVmaW5lZEZhY3RzPzogUmVhZG9ubHlBcnJheTxGYWN0Pjtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBTY2hlbWFEdG8ge1xuICBleHBvcnQgY29uc3QgZ2V0UmVzb3VyY2VzID0gKFxuICAgIHNjaGVtYTogU2NoZW1hRHRvLFxuICApOiB7XG4gICAgdmlkZW9MaXN0OiBSZWFkb25seUFycmF5PERWaWRlb0R0bz47XG4gICAgYXVkaW9MaXN0OiBSZWFkb25seUFycmF5PERBdWRpb0R0bz47XG4gICAgaW1hZ2VMaXN0OiBSZWFkb25seUFycmF5PERJbWdEdG8+O1xuICB9ID0+IHtcbiAgICBjb25zdCB7IHBhZ2VzIH0gPSBzY2hlbWE7XG4gICAgY29uc3QgdmlkZW9MaXN0ID0gcGFnZXMucmVkdWNlPEFycmF5PERWaWRlb0R0bz4+KChhY2MsIGN1cnIpID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGN1cnIudmlkZW8pKSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLmN1cnIudmlkZW8pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG4gICAgY29uc3QgYXVkaW9MaXN0OiBBcnJheTxEQXVkaW9EdG8+ID0gcGFnZXMucmVkdWNlPEFycmF5PERBdWRpb0R0bz4+KChhY2MsIGN1cnIpID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGN1cnIuYXVkaW8pKSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLmN1cnIuYXVkaW8pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICByZXR1cm4geyB2aWRlb0xpc3QsIGF1ZGlvTGlzdCwgaW1hZ2VMaXN0OiBbXSB9O1xuICB9O1xufVxuIiwgImV4cG9ydCB0eXBlIERUaW1lc3RhbXAgPSBudW1iZXIgJiB7IF9fdGltZXN0YW1wX186IHRydWUgfTtcbmV4cG9ydCBuYW1lc3BhY2UgRFRpbWVzdGFtcCB7XG4gICAgZXhwb3J0IGNvbnN0IG5vdyA9ICgpID0+IERhdGUubm93KCkgYXMgRFRpbWVzdGFtcDtcbiAgICBleHBvcnQgdHlwZSBEaWZmID0gbnVtYmVyICYgeyBfX2RpZmZfXzogdHJ1ZSB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGFkZE1pbGxzID0gKHQ6IERUaW1lc3RhbXAsIG1zOiBudW1iZXIpOiBEVGltZXN0YW1wID0+IHtcbiAgICAgICAgY29uc3QgcmVzID0gdCArIE1hdGguYWJzKG1zKTtcbiAgICAgICAgcmV0dXJuIHJlcyBhcyBEVGltZXN0YW1wO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgZGlmZiA9ICh0MTogRFRpbWVzdGFtcCwgdDI6IERUaW1lc3RhbXApOiBEaWZmID0+IHtcbiAgICAgICAgY29uc3QgdDFBYnMgPSBNYXRoLmFicyh0MSk7XG4gICAgICAgIGNvbnN0IHQyQWJzID0gTWF0aC5hYnModDIpO1xuICAgICAgICByZXR1cm4gTWF0aC5hYnModDFBYnMgLSB0MkFicykgYXMgRGlmZjtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGRpZmZOb3cgPSAodDogRFRpbWVzdGFtcCk6IERpZmYgPT4ge1xuICAgICAgICByZXR1cm4gZGlmZih0LCBub3coKSk7XG4gICAgfTtcbn1cbiIsICJleHBvcnQgdHlwZSBSYW5kb21PYmplY3RJZCA9IHN0cmluZyAmIHsgcmFuZG9tT2JqZWN0SWQ6IHRydWUgfTtcbmV4cG9ydCBuYW1lc3BhY2UgRFV0aWwge1xuICAgIGV4cG9ydCBjb25zdCByYW5kb21TdHJpbmcgPSAobGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgICBjb25zdCBsZXR0ZXJzID0gXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2eHl6XCI7XG4gICAgICAgIGNvbnN0IHVwcGVyY2FzZSA9IGxldHRlcnMudG9VcHBlckNhc2UoKTtcbiAgICAgICAgY29uc3QgYWxsID0gbGV0dGVycyArIHVwcGVyY2FzZTtcbiAgICAgICAgY29uc3QgYWJzID0gTWF0aC5hYnMobGVuZ3RoKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhYnM7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY2hhciA9IGFsbC5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYWxsLmxlbmd0aCkpO1xuICAgICAgICAgICAgcmVzdWx0ICs9IGNoYXI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IHJhbmRvbU9iamVjdElkID0gKCkgPT4gcmFuZG9tU3RyaW5nKDMyKSBhcyBSYW5kb21PYmplY3RJZDtcblxuICAgIGV4cG9ydCBjb25zdCBkZWxldGVQcm9wID0gPE9iaiwgS2V5IGV4dGVuZHMga2V5b2YgT2JqPihvYmo6IE9iaiwga2V5OiBLZXkpOiBPbWl0PE9iaiwgS2V5PiA9PiB7XG4gICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzSW5SYW5nZSA9IChtaW46IG51bWJlciwgbWF4OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuICh2YWx1ZTogbnVtYmVyKSA9PiB2YWx1ZSA+PSBtaW4gJiYgdmFsdWUgPD0gbWF4O1xuICAgIH07XG4gICAgZXhwb3J0IGNvbnN0IGlzSW5maW5pdHkgPSAobnVtYmVyOiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuIG51bWJlciA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIHx8IG51bWJlciA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZIHx8IG51bWJlciA9PT0gSW5maW5pdHk7XG4gICAgfTtcbiAgICBleHBvcnQgdHlwZSBOb25FbXB0eUFycmF5PFQ+ID0gW1QsIC4uLlRbXV07XG4gICAgZXhwb3J0IGNvbnN0IGlzTm9uRW1wdHlBcnJheSA9IDxUPihhcnJheTogQXJyYXk8VD4pOiBhcnJheSBpcyBOb25FbXB0eUFycmF5PFQ+ID0+IHtcbiAgICAgICAgcmV0dXJuIGFycmF5Lmxlbmd0aCA+IDA7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBuZXZlckNoZWNrID0gKGFyZ3M6IG5ldmVyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiT09QUzogVGhpcyB2YWx1ZSBzbGlwcGVkIHRocm91Z2ggdGhlIG5ldmVyLWNoZWNrXCIsIGFyZ3MpO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaXNTdHJpbmcgPSAoc3RyOiB1bmtub3duKTogc3RyIGlzIHN0cmluZyA9PiB0eXBlb2Ygc3RyID09PSBcInN0cmluZ1wiO1xuXG4gICAgZXhwb3J0IGNvbnN0IGhhc0tleSA9IDxUIGV4dGVuZHMgc3RyaW5nPihvYmo6IHVua25vd24sIGtleTogVCk6IG9iaiBpcyBSZWNvcmQ8dHlwZW9mIGtleSwgdW5rbm93bj4gPT4ge1xuICAgICAgICBpZiAoIWlzUmVjb3JkKG9iaikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzUmVjb3JkID0gKG9iajogdW5rbm93bik6IG9iaiBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PiB7XG4gICAgICAgIGlmICghb2JqKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaXNCb29sID0gKG9iajogYm9vbGVhbik6IG9iaiBpcyBib29sZWFuID0+IHR5cGVvZiBvYmogPT09IFwiYm9vbGVhblwiO1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzVHJ1ZSA9IChib29sOiBib29sZWFuKTogYm9vbCBpcyB0cnVlID0+IGJvb2wgPT09IHRydWU7XG5cbiAgICBleHBvcnQgY29uc3QgaXNGYWxzZSA9IChib29sOiBib29sZWFuKTogYm9vbCBpcyBmYWxzZSA9PiBib29sID09PSBmYWxzZTtcblxuICAgIGV4cG9ydCBjb25zdCBpc0RlZmluZWQgPSAob2JqOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGNvbnN0IG5vdE51bGwgPSBvYmogIT09IG51bGw7XG4gICAgICAgIGNvbnN0IG5vdFVuZGVmaW5lZCA9IG9iaiAhPT0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbm90TnVsbCAmJiBub3RVbmRlZmluZWQ7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBoYXNLaW5kID0gKG9iajogdW5rbm93bik6IG9iaiBpcyB7IHJlYWRvbmx5IGtpbmQ6IHN0cmluZyB9ID0+IHtcbiAgICAgICAgaWYgKCFoYXNLZXkob2JqLCBcImtpbmRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9iai5raW5kICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iai5raW5kLmxlbmd0aCA+IDA7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBoYXNWYWx1ZSA9IChvYmo6IHVua25vd24pOiBvYmogaXMgeyB2YWx1ZTogdW5rbm93biB9ID0+IHtcbiAgICAgICAgcmV0dXJuIGhhc0tleShvYmosIFwidmFsdWVcIik7XG4gICAgfTtcbiAgICBleHBvcnQgY29uc3QgaXNOdW1iZXIgPSAodmFsdWU/OiBudW1iZXIpOiB2YWx1ZSBpcyBudW1iZXIgPT4ge1xuICAgICAgICBjb25zdCBpc051bWJlciA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIjtcbiAgICAgICAgY29uc3Qgbm90TmFOID0gIU51bWJlci5pc05hTih2YWx1ZSk7XG4gICAgICAgIHJldHVybiBpc051bWJlciAmJiBub3ROYU47XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBtYXhGbiA9ICh1cHBlckxpbWl0OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuICh2YWx1ZTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5taW4odmFsdWUsIHVwcGVyTGltaXQpO1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgbWluRm4gPSAobG93ZXJMaW1pdDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiAodmFsdWU6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKHZhbHVlLCBsb3dlckxpbWl0KTtcbiAgICAgICAgfTtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IERVdGlsIH0gZnJvbSBcIi4uL3V0aWxzL0RVdGlsXCI7XG5cbmV4cG9ydCBuYW1lc3BhY2UgRENzcyB7XG4gICAgZXhwb3J0IGludGVyZmFjZSBQeCB7XG4gICAgICAgIHJlYWRvbmx5IF91bml0OiBcInB4XCI7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG4gICAgfVxuXG4gICAgZXhwb3J0IHR5cGUgTGVuZ3RoU3RyaW5nID0gYCR7bnVtYmVyfXB4YCB8IGAke251bWJlcn0lYDtcbiAgICBleHBvcnQgaW50ZXJmYWNlIFBlcmNlbnQge1xuICAgICAgICByZWFkb25seSBfdW5pdDogXCJwZXJjZW50XCI7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG4gICAgfVxuXG4gICAgZXhwb3J0IHR5cGUgTGVuZ3RoVW5pdCA9IFB4IHwgUGVyY2VudDtcblxuICAgIC8qKlxuICAgICAqIFdpbGwgc2NhbGUgdG8gMyUgb2YgYmFzZVNjYWxlXG4gICAgICogQHBhcmFtIHVuaXRcbiAgICAgKiBAcGFyYW0gc2NhbGVcbiAgICAgKi9cbiAgICBleHBvcnQgY29uc3QgdG9TdHJpbmcgPSAodW5pdDogUmVhZG9ubHk8TGVuZ3RoVW5pdD4sIHNjYWxlOiBudW1iZXIpOiBMZW5ndGhTdHJpbmcgPT4ge1xuICAgICAgICBjb25zdCBjbGFtcGVkU2NhbGUgPSBNYXRoLm1heChzY2FsZSwgMC4wMyk7XG4gICAgICAgIGlmICh1bml0Ll91bml0ID09PSBcInB4XCIpIHtcbiAgICAgICAgICAgIGlmICh1bml0LnZhbHVlIDwgMC4xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiMHB4XCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJvdW5kZWQgPSBNYXRoLnJvdW5kKHVuaXQudmFsdWUgKiBjbGFtcGVkU2NhbGUpO1xuICAgICAgICAgICAgY29uc3QgY2xhbXBlZCA9IE1hdGgubWF4KHJvdW5kZWQsIDEpO1xuICAgICAgICAgICAgcmV0dXJuIChjbGFtcGVkICsgXCJweFwiKSBhcyBMZW5ndGhTdHJpbmc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICh1bml0LnZhbHVlICsgXCIlXCIpIGFzIExlbmd0aFN0cmluZztcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzTGVuZ3RoVW5pdCA9ICh1bml0PzogTGVuZ3RoVW5pdCk6IHVuaXQgaXMgTGVuZ3RoVW5pdCA9PiB7XG4gICAgICAgIGlmICghdW5pdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVuaXRLZXk6IGtleW9mIExlbmd0aFVuaXQgPSBcIl91bml0XCI7XG4gICAgICAgIGNvbnN0IHZhbHVlS2V5OiBrZXlvZiBMZW5ndGhVbml0ID0gXCJ2YWx1ZVwiO1xuICAgICAgICBjb25zdCBoYXNVbml0S2V5ID0gRFV0aWwuaGFzS2V5KHVuaXQsIHVuaXRLZXkpO1xuICAgICAgICBjb25zdCBoYXNWYWx1ZUtleSA9IERVdGlsLmhhc0tleSh1bml0LCB2YWx1ZUtleSk7XG4gICAgICAgIHJldHVybiBoYXNVbml0S2V5ICYmIGhhc1ZhbHVlS2V5O1xuICAgIH07XG59XG4iLCAiaW1wb3J0IHsgRENzcyB9IGZyb20gXCIuL2Nzc1wiO1xuaW1wb3J0IHsgRWxlbWVudEtleU5hbWVzIH0gZnJvbSBcIi4vRFN0eWxlLXV0aWxzXCI7XG5pbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuXG50eXBlIERTdHlsZTIgPSBDU1NTdHlsZURlY2xhcmF0aW9uO1xuZXhwb3J0IGludGVyZmFjZSBEU3R5bGUge1xuICAgIG9wYWNpdHk6IG51bWJlcjtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgICB2aXNpYmlsaXR5OiBcInZpc2libGVcIiB8IFwiaGlkZGVuXCI7XG4gICAgY3Vyc29yOlxuICAgICAgICB8IFwicG9pbnRlclwiXG4gICAgICAgIHwgXCJoZWxwXCJcbiAgICAgICAgfCBcImNvcHlcIlxuICAgICAgICB8IFwid2FpdFwiXG4gICAgICAgIHwgXCJub3QtYWxsb3dlZFwiXG4gICAgICAgIHwgXCJjb250ZXh0LW1lbnVcIlxuICAgICAgICB8IFwibW92ZVwiXG4gICAgICAgIHwgXCJncmFiYmluZ1wiXG4gICAgICAgIHwgXCJncmFiXCJcbiAgICAgICAgfCBcInpvb20taW5cIlxuICAgICAgICB8IFwiem9vbS1vdXRcIlxuICAgICAgICB8IFwibm9uZVwiXG4gICAgICAgIHwgXCJhdXRvXCJcbiAgICAgICAgfCBcImRlZmF1bHRcIjtcblxuICAgIC8vIFBPU0lUSU9OXG4gICAgaDogbnVtYmVyO1xuICAgIHc6IG51bWJlcjtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xuXG4gICAgLy8gQk9SREVSU1xuICAgIGJvcmRlclN0eWxlOiBcInNvbGlkXCIgfCBcIm5vbmVcIiB8IFwiZG90dGVkXCIgfCBcImRhc2hlZFwiO1xuICAgIGJvcmRlclJhZGl1czogRENzcy5QeCB8IERDc3MuUGVyY2VudDtcbiAgICBib3JkZXJXaWR0aDogRENzcy5QeDtcbiAgICBib3JkZXJDb2xvcjogc3RyaW5nO1xuXG4gICAgbWFyZ2luOiBEQ3NzLlB4IHwgRENzcy5QZXJjZW50O1xuICAgIHBhZGRpbmc6IERDc3MuUHggfCBEQ3NzLlBlcmNlbnQ7XG5cbiAgICAvLyBUcmFuc2xhdGVcbiAgICB0cmFuc2Zvcm06IHN0cmluZztcbiAgICB0cmFuc2xhdGU6IHN0cmluZztcblxuICAgIC8vIFRFWFRcbiAgICBmb250U2l6ZTogRENzcy5QeDtcbiAgICB0ZXh0Q29sb3I6IHN0cmluZztcbiAgICBmb250V2VpZ2h0OiAxMDAgfCAyMDAgfCAzMDAgfCA0MDAgfCA1MDAgfCA2MDAgfCA3MDAgfCA4MDAgfCA5MDA7XG4gICAgdGV4dEFsaWduOiBcInJpZ2h0XCIgfCBcImxlZnRcIiB8IFwiY2VudGVyXCI7XG4gICAgbGV0dGVyU3BhY2luZzogRENzcy5QeDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBEU3R5bGUge1xuICAgIGV4cG9ydCBjb25zdCBub3JtYWxpemUgPSA8VCBleHRlbmRzIEhUTUxFbGVtZW50PihlbDogVCk6IFQgPT4ge1xuICAgICAgICBlbC5zdHlsZS5wYWRkaW5nID0gXCIwXCI7XG4gICAgICAgIGVsLnN0eWxlLm1hcmdpbiA9IFwiMFwiO1xuICAgICAgICBlbC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgZWwuc3R5bGUuYm94U2l6aW5nID0gXCJib3JkZXItYm94XCI7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGFwcGx5U3R5bGVzID0gPFQgZXh0ZW5kcyBIVE1MRWxlbWVudD4oZWw6IFQsIHN0eWxlOiBQYXJ0aWFsPERTdHlsZT4sIHNjYWxlOiBudW1iZXIpOiBUID0+IHtcbiAgICAgICAgLy8gY29uc3Qgc2NhbGVQeCA9IERDc3MudG9TdHJpbmdDcmUodGhpcy5zY2FsZSk7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIHgsXG4gICAgICAgICAgICB5LFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgYm9yZGVyQ29sb3IsXG4gICAgICAgICAgICBib3JkZXJXaWR0aCxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1cyxcbiAgICAgICAgICAgIGJvcmRlclN0eWxlLFxuICAgICAgICAgICAgdyxcbiAgICAgICAgICAgIG9wYWNpdHksXG4gICAgICAgICAgICBjdXJzb3IsXG4gICAgICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgICAgIGZvbnRXZWlnaHQsXG4gICAgICAgICAgICB0ZXh0Q29sb3IsXG4gICAgICAgICAgICB0ZXh0QWxpZ24sXG4gICAgICAgICAgICB0cmFuc2xhdGUsXG4gICAgICAgICAgICBtYXJnaW4sXG4gICAgICAgICAgICBwYWRkaW5nLFxuICAgICAgICAgICAgbGV0dGVyU3BhY2luZyxcbiAgICAgICAgICAgIGgsXG4gICAgICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgICAgICB2aXNpYmlsaXR5LFxuICAgICAgICB9ID0gc3R5bGU7XG5cbiAgICAgICAgLy8gdGhpcy5lbC5zdHlsZS5mb250V2VpZ2h0ID0gJzkwMCc7XG4gICAgICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJzb3IpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmN1cnNvciA9IGN1cnNvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0cmFuc2Zvcm0pIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0Q29sb3IpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmNvbG9yID0gdGV4dENvbG9yO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0ZXh0QWxpZ24pIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLnRleHRBbGlnbiA9IHRleHRBbGlnbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChib3JkZXJDb2xvcikge1xuICAgICAgICAgICAgZWwuc3R5bGUuYm9yZGVyQ29sb3IgPSBib3JkZXJDb2xvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChib3JkZXJXaWR0aCkge1xuICAgICAgICAgICAgZWwuc3R5bGUuYm9yZGVyV2lkdGggPSBEQ3NzLnRvU3RyaW5nKGJvcmRlcldpZHRoLCBzY2FsZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvbnRXZWlnaHQpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmZvbnRXZWlnaHQgPSBmb250V2VpZ2h0ICsgXCJcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYm9yZGVyU3R5bGUpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJvcmRlclN0eWxlID0gYm9yZGVyU3R5bGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvbnRTaXplKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5mb250U2l6ZSA9IERDc3MudG9TdHJpbmcoZm9udFNpemUsIHNjYWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChEVXRpbC5pc051bWJlcih4KSkge1xuICAgICAgICAgICAgZWwuc3R5bGUubGVmdCA9IHggKyBcIiVcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoRFV0aWwuaXNOdW1iZXIoeSkpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJvdHRvbSA9IHkgKyBcIiVcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChEVXRpbC5pc051bWJlcihoKSkge1xuICAgICAgICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gaCArIFwiJVwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChEVXRpbC5pc051bWJlcih3KSkge1xuICAgICAgICAgICAgZWwuc3R5bGUud2lkdGggPSB3ICsgXCIlXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoRENzcy5pc0xlbmd0aFVuaXQoYm9yZGVyUmFkaXVzKSkge1xuICAgICAgICAgICAgZWwuc3R5bGUuYm9yZGVyUmFkaXVzID0gRENzcy50b1N0cmluZyhib3JkZXJSYWRpdXMsIHNjYWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsZXR0ZXJTcGFjaW5nKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5sZXR0ZXJTcGFjaW5nID0gRENzcy50b1N0cmluZyhsZXR0ZXJTcGFjaW5nLCBzY2FsZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hcmdpbikge1xuICAgICAgICAgICAgZWwuc3R5bGUubWFyZ2luID0gRENzcy50b1N0cmluZyhtYXJnaW4sIHNjYWxlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFkZGluZykge1xuICAgICAgICAgICAgZWwuc3R5bGUucGFkZGluZyA9IERDc3MudG9TdHJpbmcocGFkZGluZywgc2NhbGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKERVdGlsLmlzTnVtYmVyKG9wYWNpdHkpKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5vcGFjaXR5ID0gb3BhY2l0eSArIFwiXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmlzaWJpbGl0eSkge1xuICAgICAgICAgICAgZWwuc3R5bGUudmlzaWJpbGl0eSA9IHZpc2liaWxpdHk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZWw7XG4gICAgfTtcbiAgICAvLyBjb25zdCBwcm9wTmFtZXMgPSBuZXcgU2V0KC4uLkVsZW1lbnRLZXlOYW1lcyk7XG4gICAgLy8gZXhwb3J0IGNvbnN0IHZhbGlkS2V5ID0gKGtleU5hbWU6IHN0cmluZykgPT4gcHJvcE5hbWVzLmhhcyhrZXlOYW1lKTtcbn1cbiIsICJpbXBvcnQgeyBEVmlkZW9EdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgREV2ZW50RGlzcGF0Y2hlciB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5pbXBvcnQgeyBEU3R5bGUgfSBmcm9tIFwiLi9EU3R5bGVcIjtcbmltcG9ydCB7IERVdGlsIH0gZnJvbSBcIi4uL3V0aWxzL0RVdGlsXCI7XG5cbmNvbnN0IEFCT1JUX1BMQVlfVE9fRU5EID0gXCJBQk9SVF9QTEFZX1RPX0VORFwiO1xuZXhwb3J0IGludGVyZmFjZSBDYW5QbGF5VG9FbmQge1xuICAgIHBsYXlUb0VuZCgpOiBQcm9taXNlPGJvb2xlYW4+O1xufVxuXG5leHBvcnQgY2xhc3MgVmlkZW9Db250YWluZXIgaW1wbGVtZW50cyBDYW5QbGF5VG9FbmQge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgVEFHOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBkdG8/OiBEVmlkZW9EdG87XG4gICAgcHJpdmF0ZSBkZWZhdWx0U3R5bGVzOiBQYXJ0aWFsPERTdHlsZT4gPSB7IGg6IDQ1LCB3OiAxMDAsIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsIHk6IDU1IH07XG5cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgIGtpbmQ6IFwiVklERU9fUEFVU0VEX0VWRU5UXCIsXG4gICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRWaWRlb1wiLFxuICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZWwucGF1c2UoKTtcbiAgICB9XG5cbiAgICBwbGF5KHVybDogc3RyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmVsLnNyYyAhPT0gdXJsKSB7XG4gICAgICAgICAgICB0aGlzLmVsLnNyYyA9IHVybDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9kdWNlcklkID0gdGhpcy5kdG8/LmlkID8/IFwiRFZpZGVvXCI7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIlZJREVPX1BMQVlfRVZFTlRcIixcbiAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgcHJvZHVjZXI6IFwiRFZpZGVvXCIsXG4gICAgICAgICAgICBwcm9kdWNlcklkLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbFxuICAgICAgICAgICAgLnBsYXkoKVxuICAgICAgICAgICAgLnRoZW4oKHJlcykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlcyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgLy8gaWYodGhpcy5lbC5zcmMgIT09IHVybCkge1xuICAgICAgICAvLyAgICAgdGhpcy5cbiAgICAgICAgLy8gfVxuICAgIH1cblxuICAgIGFzeW5jIHBsYXlUb0VuZCgpIHtcbiAgICAgICAgdGhpcy5lbC52b2x1bWUgPSAxO1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmR0bz8udXJsO1xuICAgICAgICBpZiAoIXVybCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGVuZGVkT3JFcnJvcmVkID0gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgXCJlbmRlZFwiLFxuICAgICAgICAgICAgICAgICAgICAoXykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgeyBvbmNlOiB0cnVlIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgXCJlcnJvclwiLFxuICAgICAgICAgICAgICAgICAgICAoXykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgIEFCT1JUX1BMQVlfVE9fRU5ELFxuICAgICAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkNBVENIRUQgQUJCT1JULlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChcIkFib3J0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJQTEFZXCIpO1xuICAgICAgICAgICAgdGhpcy5wbGF5KHVybCk7XG4gICAgICAgICAgICBhd2FpdCBlbmRlZE9yRXJyb3JlZDtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCIgZmluYWxseSBibG9jayBwbGF5VG9FbmQoKSBjb21wbGV0ZWQgdmlkZW9JZDogXCIgKyB0aGlzLmR0bz8uaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZWw6IEhUTUxWaWRlb0VsZW1lbnQsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXM6IERFdmVudERpc3BhdGNoZXIsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgc2NhbGU6IFNjYWxlU2VydmljZSAvLyBkdG8/OiBEVmlkZW9EdG9cbiAgICApIHtcbiAgICAgICAgdGhpcy5UQUcgPSBcIlsgRF9WaWRlbyBdIDogXCI7XG4gICAgICAgIHRoaXMuZWwuY29udHJvbHMgPSBmYWxzZTtcbiAgICAgICAgRFN0eWxlLm5vcm1hbGl6ZSh0aGlzLmVsKTtcbiAgICAgICAgRFN0eWxlLmFwcGx5U3R5bGVzKHRoaXMuZWwsIHRoaXMuZGVmYXVsdFN0eWxlcywgdGhpcy5zY2FsZS5zY2FsZSk7XG5cbiAgICAgICAgdGhpcy5lbC5vbmVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIlZJREVPX0VOREVEX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRWaWRlb1wiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5lbC5vbnBsYXkgPSAoKSA9PiB7XG4gICAgICAgICAgICAvLyBUT0RPIExPR0cgSU5URVJOQUwgU1RBVEVfQ0hBTkdFUy5cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmVsLm9ucGF1c2UgPSAoKSA9PiB7fTtcbiAgICAgICAgdGhpcy5lbC5vbmVycm9yID0gKCkgPT4ge307XG4gICAgICAgIHRoaXMuZWwub25jYW5wbGF5ID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gY29uc29sZS5ncm91cENvbGxhcHNlZCh0aGlzLlRBRyArIFwiUkVBRFkgVE8gUExBWVwiKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiRHVyYXRpb246IFwiICsgdGhpcy5lbC5kdXJhdGlvbik7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIklkOiBcIiArIHRoaXMuaWQpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJDdXJyZW50IFRpbWU6IFwiICsgdGhpcy5lbC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIkF1ZG9QbGF5OiBcIiArIHRoaXMuZWwuYXV0b3BsYXkpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5ncm91cEVuZCgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVsLm9ubG9hZGVkbWV0YWRhdGEgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMuZWwuZHVyYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc0luZmluaXR5ID0gRFV0aWwuaXNJbmZpbml0eShkdXJhdGlvbik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwiVklERU9fTE9BREVEX01FVEFEQVRBX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRWaWRlb1wiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgZGF0YTogeyBkdXJhdGlvbiwgaXNJbmZpbml0eSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIFRPRE8gVVNFIFRISVMgU1lOVEFYP1xuICAgICAgICB0aGlzLmVsLm9uZHVyYXRpb25jaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMuZWwuZHVyYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc0luZmluaXR5ID0gRFV0aWwuaXNJbmZpbml0eShkdXJhdGlvbik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwiVklERU9fRFVSQVRJT05fQ0hBTkdFX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgcHJvZHVjZXI6IFwiRFZpZGVvXCIsXG4gICAgICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICAgICAgICAgICAgZGF0YTogeyBkdXJhdGlvbiwgaXNJbmZpbml0eSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2V0U3RhdHMoKSB7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gdGhpcy5lbC5kdXJhdGlvbjtcbiAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSB0aGlzLmVsLmN1cnJlbnRUaW1lO1xuICAgICAgICBjb25zdCB2b2x1bWUgPSB0aGlzLmVsLnZvbHVtZTtcbiAgICAgICAgY29uc3QgaXNDb25uZWN0ZWQgPSB0aGlzLmVsLmlzQ29ubmVjdGVkO1xuICAgICAgICBjb25zdCBwbGF5YmFja1F1YWxpdHkgPSB0aGlzLmVsLmdldFZpZGVvUGxheWJhY2tRdWFsaXR5KCk7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRQbGF5YmFja1JhdGUgPSB0aGlzLmVsLmRlZmF1bHRQbGF5YmFja1JhdGU7XG4gICAgICAgIGNvbnN0IHBhdXNlZCA9IHRoaXMuZWwucGF1c2VkO1xuICAgICAgICBjb25zdCBwbGF5ZWQgPSB0aGlzLmVsLnBsYXllZDtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZHVyYXRpb24sXG4gICAgICAgICAgICBwYXVzZWQsXG4gICAgICAgICAgICBwbGF5ZWQsXG4gICAgICAgICAgICBjdXJyZW50VGltZSxcbiAgICAgICAgICAgIHZvbHVtZSxcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkLFxuICAgICAgICAgICAgcGxheWJhY2tRdWFsaXR5LFxuICAgICAgICAgICAgZGVmYXVsdFBsYXliYWNrUmF0ZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBzZXREdG8oZHRvOiBEVmlkZW9EdG8pIHtcbiAgICAgICAgdGhpcy5kdG8gPSBkdG87XG4gICAgICAgIHRoaXMuZWwudm9sdW1lID0gMTtcbiAgICAgICAgdGhpcy5zZXRTdHlsZShkdG8uc3R5bGUpO1xuICAgICAgICB0aGlzLmVsLnNyYyA9IGR0by51cmw7XG4gICAgICAgIHRoaXMuZWwubG9hZCgpO1xuICAgIH1cblxuICAgIGdldEN1cnJlbnREdG8oKTogRFZpZGVvRHRvIHwgZmFsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5kdG8gPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgc2V0U3R5bGUoc3R5bGVzOiBQYXJ0aWFsPERTdHlsZT4pIHtcbiAgICAgICAgRFN0eWxlLmFwcGx5U3R5bGVzKHRoaXMuZWwsIHN0eWxlcywgdGhpcy5zY2FsZS5zY2FsZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmR0bz8uaWQgPz8gXCJEVmlkZW9cIjtcbiAgICB9XG5cbiAgICBkZXN0cm95KCkge31cbn1cbiIsICJpbXBvcnQgeyBDYW5QbGF5VG9FbmQgfSBmcm9tIFwiLi9WaWRlb0NvbnRhaW5lclwiO1xuaW1wb3J0IHsgREF1ZGlvRHRvIH0gZnJvbSBcIi4uL2R0by9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IERFdmVudERpc3BhdGNoZXIgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuXG5leHBvcnQgY2xhc3MgQXVkaW9Db250YWluZXIgaW1wbGVtZW50cyBDYW5QbGF5VG9FbmQge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgVEFHID0gXCJbIERBdWRpbyBdOiBcIjtcbiAgICBwcm90ZWN0ZWQgZHRvOiBEQXVkaW9EdG8gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGVsOiBIVE1MQXVkaW9FbGVtZW50O1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXM6IERFdmVudERpc3BhdGNoZXIpIHtcbiAgICAgICAgdGhpcy5lbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhdWRpb1wiKTtcbiAgICAgICAgdGhpcy5lbC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgdGhpcy5lbC5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICAgICAgLy8gdGhpcy5lbC5vblxuICAgICAgICB0aGlzLm9uTG9hZCA9IHRoaXMub25Mb2FkLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZWwub25sb2FkID0gdGhpcy5vbkxvYWQ7XG4gICAgICAgIHRoaXMub25Mb2FkZWRNZXRhZGF0YSA9IHRoaXMub25Mb2FkZWRNZXRhZGF0YS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmVsLm9ubG9hZGVkbWV0YWRhdGEgPSB0aGlzLm9uTG9hZGVkTWV0YWRhdGE7XG4gICAgICAgIHRoaXMuZWwub25wbGF5ID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9uQ2FuUGxheVRocm91Z2ggPSB0aGlzLm9uQ2FuUGxheVRocm91Z2guYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5lbC5vbmNhbnBsYXl0aHJvdWdoID0gdGhpcy5vbkNhblBsYXlUaHJvdWdoO1xuICAgICAgICB0aGlzLmVsLm9uZW5kZWQgPSAoXykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpcy5lbC5zcmM7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwiQVVESU9fRU5ERURfRVZFTlRcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7IHVybCB9LFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZWwub25kdXJhdGlvbmNoYW5nZSA9IChfOiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLmVsLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgaXNJbmZpbml0eSA9IGR1cmF0aW9uID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwiQVVESU9fRFVSQVRJT05fQ0hBTkdFX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgZGF0YTogeyBkdXJhdGlvbjogdGhpcy5lbC5kdXJhdGlvbiwgaXNJbmZpbml0eSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc2V0QXVkaW8oZHRvOiBEQXVkaW9EdG8pIHtcbiAgICAgICAgdGhpcy5kdG8gPSBkdG87XG4gICAgICAgIHRoaXMuZWwuc3JjID0gZHRvLnVybDtcbiAgICAgICAgdGhpcy5lbC5sb2FkKCk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuZWwucGF1c2UoKTtcbiAgICAgICAgICAgIHRoaXMuZWwuc3JjID0gXCJcIjtcbiAgICAgICAgICAgIHRoaXMuZWwubG9hZCgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHBhdXNlKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5lbC5wYXVzZSgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBUT0RPIEVNSVQgRVJST1IgRVZFTlQuXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHBsYXkodXJsOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHRoaXMuZWwuc3JjICE9PSB1cmwpIHtcbiAgICAgICAgICAgIHRoaXMuZWwuc3JjID0gdXJsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIkFVRElPX1BMQVlfRVZFTlRcIixcbiAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbFxuICAgICAgICAgICAgLnBsYXkoKVxuICAgICAgICAgICAgLnRoZW4oKHJlcykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlcyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkxvYWRlZE1ldGFkYXRhKF86IEV2ZW50KSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIkFVRElPX01FVEFEQVRBX0xPQURFRF9FVkVOVFwiLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgcHJvZHVjZXI6IFwiREF1ZGlvXCIsXG4gICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uTG9hZChfOiBFdmVudCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJBVURJT19MT0FEX0VWRU5UXCIsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICAgICAgICBwcm9kdWNlcjogXCJEQXVkaW9cIixcbiAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgZXZlbnQudHlwZSk7XG4gICAgfVxuXG4gICAgZ2V0IGlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kdG8/LmlkID8/IFwiREF1ZGlvXCI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkNhblBsYXlUaHJvdWdoKF86IEV2ZW50KSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIkFVRElPX0NBTl9QTEFZX1RIUk9VR0hfRVZFTlRcIixcbiAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgcHJvZHVjZXI6IFwiREF1ZGlvXCIsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBwcml2YXRlIG9uUGxheShfOiBFdmVudCkge31cblxuICAgIGFzeW5jIHBsYXlUb0VuZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgY29uc3QgZW5kZWRPckVycm9yZWQgPSBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgIFwiZW5kZWRcIixcbiAgICAgICAgICAgICAgICAoXykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgIFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICAoXykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnBsYXkodGhpcy5lbC5zcmMpO1xuICAgICAgICAgICAgYXdhaXQgZW5kZWRPckVycm9yZWQ7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gVE9ETyBMRVQgUEFSRU5UIERFQUwgV0lUSCBFUlJPUlM/IFRIRSBNQU5BR0VSPz8gTUFOQUdFUlMgQ0FMTCBBQk9SVC5cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIkFVRElPX0VSUk9SX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgZGF0YTogeyBlcnJvcjogZSB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUGFnZUR0byB9IGZyb20gXCIuLi9kdG8vU2NoZW1hRHRvXCI7XG5pbXBvcnQgeyBWaWRlb0NvbnRhaW5lciB9IGZyb20gXCIuLi9EZWxlbWVudC9WaWRlb0NvbnRhaW5lclwiO1xuaW1wb3J0IHsgQXVkaW9Db250YWluZXIgfSBmcm9tIFwiLi4vRGVsZW1lbnQvQXVkaW9Db250YWluZXJcIjtcbmltcG9ydCB7IEF1dG9QbGF5RWxlbWVudCwgREF1dG9QbGF5U2VxdWVuY2UgfSBmcm9tIFwiLi4vRGVsZW1lbnQvREF1dG8tcGxheVwiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IERDb21tYW5kIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kXCI7XG5pbXBvcnQgeyBEVGltZXN0YW1wIH0gZnJvbSBcIi4uL2NvbW1vbi9EVGltZXN0YW1wXCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5pbXBvcnQgeyBSZXNvdXJjZVByb3ZpZGVyIH0gZnJvbSBcIi4vcmVzb3VyY2UtcHJvdmlkZXJcIjtcbmltcG9ydCB7IEF1dG9wbGF5VGFzaywgU2VxdWVuY2VNYW5hZ2VyIH0gZnJvbSBcIi4vc2VxdWVuY2UtbWFuYWdlclwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIElNZWRpYU1hbmFnZXIge1xuICBzZXRQYWdlKHBhZ2U6IFBhZ2VEdG8pOiB2b2lkO1xuICBkZXN0cm95KCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBETWVkaWFNYW5hZ2VyIGltcGxlbWVudHMgSU1lZGlhTWFuYWdlciB7XG4gIHByaXZhdGUgc3RhdGljIElOU1RBTkNFX0NPVU5UID0gMDtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZU51bWJlcjogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBNRURJQV9NQU5BR0VSIF0gOiBcIjtcbiAgcHJpdmF0ZSByZWFkb25seSB2aWRlb0NvbnRhaW5lcjogVmlkZW9Db250YWluZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXVkaW9Db250YWluZXI6IEF1ZGlvQ29udGFpbmVyO1xuICBwcml2YXRlIHBhZ2VFbnRlcjogRFRpbWVzdGFtcDtcbiAgcHJpdmF0ZSBzaW5jZVBhZ2VFbnRlcjogRFRpbWVzdGFtcC5EaWZmO1xuICBwcml2YXRlIGN1cnJlbnRQYWdlOiBQYWdlRHRvIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgdW5zdWJzY3JpYmVDb21tYW5kczogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSB0aWNrZXJSZWY6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzZXF1ZW5jZU1hbmFnZXI6IFNlcXVlbmNlTWFuYWdlciB8IGZhbHNlID0gZmFsc2U7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaG9zdEVsOiBIVE1MRGl2RWxlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRCdXM6IERDb21tYW5kQnVzLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXM6IEV2ZW50QnVzLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VQcm92aWRlcjogUmVzb3VyY2VQcm92aWRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjYWxlOiBTY2FsZVNlcnZpY2UsXG4gICkge1xuICAgIERNZWRpYU1hbmFnZXIuSU5TVEFOQ0VfQ09VTlQgPSBETWVkaWFNYW5hZ2VyLklOU1RBTkNFX0NPVU5UICsgMTtcbiAgICB0aGlzLmluc3RhbmNlTnVtYmVyID0gRE1lZGlhTWFuYWdlci5JTlNUQU5DRV9DT1VOVDtcbiAgICBjb25zdCB2aWRlb0VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInZpZGVvXCIpO1xuICAgIHRoaXMuaG9zdEVsLmFwcGVuZCh2aWRlb0VsKTtcbiAgICB0aGlzLnZpZGVvQ29udGFpbmVyID0gbmV3IFZpZGVvQ29udGFpbmVyKHZpZGVvRWwsIGV2ZW50QnVzLCB0aGlzLnNjYWxlKTtcbiAgICB0aGlzLmF1ZGlvQ29udGFpbmVyID0gbmV3IEF1ZGlvQ29udGFpbmVyKHRoaXMuZXZlbnRCdXMpO1xuICAgIHRoaXMudGljayA9IHRoaXMudGljay5iaW5kKHRoaXMpO1xuICAgIHRoaXMudmlkZW9Db250YWluZXIuc2V0U3R5bGUoeyB2aXNpYmlsaXR5OiBcImhpZGRlblwiIH0pO1xuICAgIGNvbnN0IG5vdyA9IERUaW1lc3RhbXAubm93KCk7XG4gICAgdGhpcy5wYWdlRW50ZXIgPSBub3c7XG4gICAgdGhpcy5zaW5jZVBhZ2VFbnRlciA9IERUaW1lc3RhbXAuZGlmZihub3csIG5vdyk7XG4gICAgdGhpcy51bnN1YnNjcmliZUNvbW1hbmRzID0gdGhpcy5jb21tYW5kQnVzLnN1YnNjcmliZSgoYWN0aW9uKSA9PiB7XG4gICAgICB0aGlzLmNvbW1hbmRIYW5kbGVyKGFjdGlvbik7XG4gICAgfSwgdGhpcy5UQUcpO1xuXG4gICAgdGhpcy50aWNrZXJSZWYgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoKCkgPT4ge30sIDEwMDApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3AgYWxsIG1lZGlhIHRoYXQgaXMgcGxheWluZ1xuICAgKi9cbiAgY2xlYXJBbGxNZWRpYSgpIHtcbiAgICB0aGlzLnZpZGVvQ29udGFpbmVyLnBhdXNlKCk7XG4gICAgdGhpcy5hdWRpb0NvbnRhaW5lci5wYXVzZSgpO1xuICB9XG4gIGRlc3Ryb3koKSB7XG4gICAgY29uc29sZS5sb2coXCJUT0RPIERFU1RST1kgQUxMIE1FRElBXCIpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVDb21tYW5kcygpO1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMudGlja2VyUmVmKTtcbiAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLnRpY2tlclJlZik7XG4gICAgdGhpcy5hdWRpb0NvbnRhaW5lci5kZXN0cm95KCk7XG4gICAgdGhpcy52aWRlb0NvbnRhaW5lci5kZXN0cm95KCk7XG4gIH1cblxuICBzZXRQYWdlKHBhZ2U6IFBhZ2VEdG8pIHtcbiAgICAvLyBUT0RPIFNUT1AgVklERU8vQVVESU8gVEhBVCBNSUdIVCBCRSBQTEFZSU5HIElOIFRIRSBET00/P1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBwYWdlO1xuICAgIHRoaXMudmlkZW9Db250YWluZXIucGF1c2UoKTtcbiAgICB0aGlzLnBhZ2VFbnRlciA9IERUaW1lc3RhbXAubm93KCk7XG4gICAgLy8gVE9ETyBUSGlzIG1pZ2h0IGJlIGEgYnVnIGlmIHNvbWVvbmVcblxuICAgIGNvbnN0IHNlcSA9IHBhZ2UuYXV0b1BsYXlTZXF1ZW5jZTtcbiAgICAvLyB0aGlzLnNlcXVlbmNlID0gc2VxID8gWy4uLnNlcS5pdGVtc10gOiBbXTtcbiAgICBjb25zdCB7IG1haW5WaWRlb0lkLCBhdWRpbyB9ID0gcGFnZTtcbiAgICBjb25zdCBhdWRpb0VsZW1lbnRzID0gcGFnZS5hdWRpbztcblxuICAgIGlmIChtYWluVmlkZW9JZCkge1xuICAgICAgY29uc3QgZHRvID0gdGhpcy5yZXNvdXJjZVByb3ZpZGVyLmdldFZpZGVvQnlJZChtYWluVmlkZW9JZCk7XG4gICAgICBpZiAoZHRvKSB7XG4gICAgICAgIHRoaXMudmlkZW9Db250YWluZXIuc2V0RHRvKGR0byk7XG4gICAgICAgIHRoaXMudmlkZW9Db250YWluZXIuc2V0U3R5bGUoeyAuLi5kdG8uc3R5bGUsIHZpc2liaWxpdHk6IFwidmlzaWJsZVwiIH0pO1xuICAgICAgfVxuICAgICAgLy8gdGhpcy52aWRlb0NvbnRhaW5lci5wbGF5VG9FbmQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWRlb0NvbnRhaW5lci5zZXRTdHlsZSh7IHZpc2liaWxpdHk6IFwiaGlkZGVuXCIgfSk7XG4gICAgICAvLyBISURFP1xuICAgIH1cbiAgICBpZiAoYXVkaW9FbGVtZW50cykge1xuICAgICAgY29uc3QgZmlyc3QgPSBhdWRpb0VsZW1lbnRzWzBdO1xuICAgICAgaWYgKGZpcnN0KSB7XG4gICAgICAgIHRoaXMuYXVkaW9Db250YWluZXIuc2V0QXVkaW8oZmlyc3QpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2VxKSB7XG4gICAgICB0aGlzLnBsYXlTZXF1ZW5jZShzZXEpO1xuICAgIH1cbiAgICAvLyBjb25zdCBoYXNWaWRlbyA9XG4gIH1cblxuICBwcml2YXRlIGNvbW1hbmRIYW5kbGVyKGNvbW1hbmQ6IERDb21tYW5kKSB7XG4gICAgaWYgKGNvbW1hbmQua2luZCA9PT0gXCJWSURFT19QTEFZX0NPTU1BTkRcIikge1xuICAgICAgY29uc3QgdmlkZW8gPSBjb21tYW5kLnRhcmdldElkO1xuICAgICAgY29uc3QgZHRvID0gdGhpcy52aWRlb0NvbnRhaW5lci5nZXRDdXJyZW50RHRvKCk7XG5cbiAgICAgIGlmIChkdG8gJiYgZHRvLmlkID09PSBjb21tYW5kLnRhcmdldElkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHZpZGVvKTtcbiAgICAgICAgdGhpcy52aWRlb0NvbnRhaW5lci5wbGF5KGR0by51cmwpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIlZJREVPX1BBVVNFX0NPTU1BTkRcIikge1xuICAgICAgdGhpcy52aWRlb0NvbnRhaW5lci5wYXVzZSgpO1xuICAgIH1cbiAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIkFVRElPX1BMQVlfQ09NTUFORFwiKSB7XG4gICAgICB0aGlzLmF1ZGlvQ29udGFpbmVyXG4gICAgICAgIC5wbGF5VG9FbmQoKVxuICAgICAgICAudGhlbigoKSA9PiB7fSlcbiAgICAgICAgLmNhdGNoKClcbiAgICAgICAgLmZpbmFsbHkoKCkgPT4ge30pO1xuICAgIH1cblxuICAgIGlmIChjb21tYW5kLmtpbmQgPT09IFwiQVVESU9fUEFVU0VfQ09NTUFORFwiKSB7XG4gICAgICAvLyB0aGlzLmF1ZGlvQ29udGFpbmVyLlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGxheVNlcXVlbmNlKHNlcTogREF1dG9QbGF5U2VxdWVuY2UpIHtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwiU0VRVUVOQ0UgU1RBUlRFRCAtLSBUT0RPIEVWRU5UIEZPUiBUSElTPz9cIik7XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHNlcS5pdGVtcztcbiAgICBjb25zdCB0ZXN0Q2xvbmUgPSBbLi4uZWxlbWVudHNdO1xuICAgIGNvbnN0IGZpcnN0ID0gdGVzdENsb25lLnBvcCgpO1xuXG4gICAgaWYgKCFmaXJzdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBub3cgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgIHNlcS5zdGFydENvbW1hbmRzLmZvckVhY2goKGMpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGMpO1xuICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoYyk7XG4gICAgfSk7XG4gICAgLy8gdGhpcy5jb21tYW5kQnVzLmVtaXQoRFN0YXRlUHJvcHMubWVkaWFCbG9ja2VkQnlTZXF1ZW5jZS5zZXRUcnVlQ29tbWFuZCk7XG4gICAgLy8gaWYgKHNlcS5ibG9ja1VzZXJJbnB1dCkge1xuICAgIC8vICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChEU3RhdGVQcm9wcy5pbnB1dEJsb2NraW5nQnlTZXF1ZW5jZS5nZXRTZXRUcnVlQ29tbWFuZCgpKTtcbiAgICAvLyB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaXRlbSA9IGVsZW1lbnRzW2ldO1xuICAgICAgaWYgKGl0ZW0ua2luZCA9PT0gXCJhdXRvcGxheS12aWRlb1wiKSB7XG4gICAgICAgIGNvbnN0IGR0byA9IHRoaXMucmVzb3VyY2VQcm92aWRlci5nZXRWaWRlb0J5SWQoaXRlbS52aWRlb0lkKTtcbiAgICAgICAgaWYgKGR0bykgdGhpcy52aWRlb0NvbnRhaW5lci5zZXREdG8oZHRvKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aWRlb0NvbnRhaW5lci5wbGF5VG9FbmQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtLmtpbmQgPT09IFwiYXV0b3BsYXktYXVkaW9cIikge1xuICAgICAgICBjb25zb2xlLmxvZyhpdGVtKTtcbiAgICAgICAgY29uc3QgZHRvID0gdGhpcy5yZXNvdXJjZVByb3ZpZGVyLmdldEF1ZGlvQnlJZChpdGVtLmF1ZGlvSWQpO1xuICAgICAgICBpZiAoZHRvKSB0aGlzLmF1ZGlvQ29udGFpbmVyLnNldEF1ZGlvKGR0byk7XG4gICAgICAgIGF3YWl0IHRoaXMuYXVkaW9Db250YWluZXIucGxheVRvRW5kKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHNlcS5lbmRDb21tYW5kcy5mb3JFYWNoKChjKSA9PiB7XG4gICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjKTtcbiAgICB9KTtcbiAgICAvLyB0aGlzLmFjdGlvblNlcnZpY2UuZW1pdChEU3RhdGVQcm9wcy5tZWRpYUJsb2NrZWRCeVNlcXVlbmNlLnNldEZhbHNlQ29tbWFuZCk7XG4gICAgLy8gdGhpcy5hY3Rpb25TZXJ2aWNlLmVtaXQoRFN0YXRlUHJvcHMuaW5wdXRCbG9ja2luZ0J5U2VxdWVuY2Uuc2V0RmFsc2VDb21tYW5kKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwiU0VRVUVOQ0UgRU5ERURcIik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBzZXRQYWdlKClcblxuICBwcml2YXRlIHRpY2soKSB7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy52aWRlbzEuZ2V0U3RhdHMoKSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBEQ29tbWFuZCB9IGZyb20gXCIuL0RDb21tYW5kXCI7XG5pbXBvcnQgeyBEVGltZXN0YW1wIH0gZnJvbSBcIi4uL2NvbW1vbi9EVGltZXN0YW1wXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRENvbW1hbmRTdG9yZSB7XG4gIHN1YnNjcmliZShjYWxsYmFjazogKCkgPT4gdm9pZCwgc3Vic2NyaWJlcklkOiBzdHJpbmcpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERDb21tYW5kRGlzcGF0Y2hlciB7XG4gIGVtaXQoY29tbWFuZDogRENvbW1hbmQpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgQ29tbWFuZFN1YnNjcmliZXJEYXRhIHtcbiAgcmVhZG9ubHkgc3Vic2NyaWJlcklkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNhbGxiYWNrOiAoY29tbWFuZDogRENvbW1hbmQpID0+IHZvaWQ7XG59XG5leHBvcnQgY2xhc3MgRENvbW1hbmRCdXMgaW1wbGVtZW50cyBEQ29tbWFuZFN0b3JlLCBEQ29tbWFuZERpc3BhdGNoZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBDT01NQU5EX0JVUyBdIFwiO1xuICBsb2dDb21tYW5kcyA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRMb2c6IEFycmF5PERDb21tYW5kICYgeyB0aW1lc3RhbXA6IERUaW1lc3RhbXAgfT4gPSBbXTtcbiAgcmVhZG9ubHkgc3Vic2NyaWJlcnMgPSBuZXcgU2V0PENvbW1hbmRTdWJzY3JpYmVyRGF0YT4oKTtcbiAgLy8gcmVhZG9ubHkgc3ViXG5cbiAgc3Vic2NyaWJlKGNiOiAoY29tbWFuZDogRENvbW1hbmQpID0+IHZvaWQsIHN1YnNjcmliZXJJZDogc3RyaW5nKSB7XG4gICAgY29uc3Qgc3ViOiBDb21tYW5kU3Vic2NyaWJlckRhdGEgPSB7XG4gICAgICBzdWJzY3JpYmVySWQsXG4gICAgICBjYWxsYmFjazogY2IsXG4gICAgfTtcblxuICAgIHRoaXMuc3Vic2NyaWJlcnMuYWRkKHN1Yik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXMuc3Vic2NyaWJlcnMuZGVsZXRlKHN1Yik7XG4gICAgfTtcbiAgfVxuXG4gIGVtaXQoY29tbWFuZDogRENvbW1hbmQpIHtcbiAgICBjb25zdCB0aW1lc3RhbXAgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgIHRoaXMuY29tbWFuZExvZy5wdXNoKHsgLi4uY29tbWFuZCwgdGltZXN0YW1wIH0pO1xuICAgIGlmICh0aGlzLmxvZ0NvbW1hbmRzKSB7XG4gICAgICB0aGlzLmxvZ0NvbW1hbmQoY29tbWFuZCk7XG4gICAgfVxuICAgIHRoaXMuc3Vic2NyaWJlcnMuZm9yRWFjaCgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgc3Vic2NyaWJlci5jYWxsYmFjayhjb21tYW5kKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN0YXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb21tYW5kczogWy4uLnRoaXMuY29tbWFuZExvZ10sXG4gICAgICBzdWJzY3JpYmVyczogWy4uLnRoaXMuc3Vic2NyaWJlcnNdLFxuICAgICAgc3Vic2NyaWJlcnNDb3VudDogdGhpcy5zdWJzY3JpYmVycy5zaXplLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGxvZ0NvbW1hbmQoY29tbWFuZDogRENvbW1hbmQpIHtcbiAgICBjb25zb2xlLmdyb3VwQ29sbGFwc2VkKHRoaXMuVEFHICsgXCIgXCIgKyBjb21tYW5kLmtpbmQpO1xuICAgIGNvbnNvbGUubG9nKFwiVGFyZ2V0SUQgOiBcIiArIGNvbW1hbmQudGFyZ2V0SWQpO1xuICAgIGNvbnNvbGUubG9nKGNvbW1hbmQucGF5bG9hZCk7XG4gICAgY29uc29sZS5ncm91cEVuZCgpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgREV2ZW50IH0gZnJvbSBcIi4vREV2ZW50c1wiO1xuXG5pbnRlcmZhY2UgU3Vic2NyaWJlckRhdGEge1xuICAgIHJlYWRvbmx5IHN1YnNjcmliZXJJZDogc3RyaW5nO1xuICAgIHJlYWRvbmx5IGNiOiAoZXZlbnQ6IERFdmVudCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBERXZlbnRTdG9yZSB7XG4gICAgc3Vic2NyaWJlKGNiOiAoZXZlbnQ6IERFdmVudCkgPT4gdm9pZCwgc3Vic2NyaWJlcklkOiBzdHJpbmcpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERFdmVudERpc3BhdGNoZXIge1xuICAgIGVtaXQoZXZlbnQ6IERFdmVudCk6IHZvaWQ7XG59XG5leHBvcnQgY2xhc3MgRXZlbnRCdXMgaW1wbGVtZW50cyBERXZlbnRTdG9yZSwgREV2ZW50RGlzcGF0Y2hlciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgIEVWRU5UX0JVUyAgXSA6XCI7XG4gICAgLy8gcHJpdmF0ZSByZWFkb25seSBzdWJzY3JpYmVycyA9IG5ldyBTZXQ8KGV2ZW50OiBERXZlbnQpID0+IHZvaWQ+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdWJzY3JpYmVycyA9IG5ldyBTZXQ8U3Vic2NyaWJlckRhdGE+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0IG9uIG1vZHVsZSBlbmQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50TG9nOiBERXZlbnRbXSA9IFtdO1xuICAgIGNvbnNvbGVMb2dFdmVudHMgPSBmYWxzZTtcbiAgICAvLyByZWFkb25seSBzdWJcblxuICAgIHN1YnNjcmliZShjYjogKGV2ZW50OiBERXZlbnQpID0+IHZvaWQsIHN1YnNjcmliZXJJZDogc3RyaW5nKSB7XG4gICAgICAgIC8vIHRoaXMuc3Vic2NyaWJlcnMuYWRkKGNiKTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlckRhdGE6IFN1YnNjcmliZXJEYXRhID0ge1xuICAgICAgICAgICAgc3Vic2NyaWJlcklkLFxuICAgICAgICAgICAgY2IsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuYWRkKHN1YnNjcmliZXJEYXRhKTtcbiAgICAgICAgaWYgKHRoaXMuY29uc29sZUxvZ0V2ZW50cykge1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5UQUcgKyBcInN1YnNjcmlwdGlvbiBhZGRlZDogXCIgKyBzdWJzY3JpYmVySWQpO1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5UQUcgKyBcInN1YnNjcmlwdGlvbiBjb3VudDogXCIgKyB0aGlzLnN1YnNjcmliZXJzLnNpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25zb2xlTG9nRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5UQUcgKyBcInN1YnNjcmlwdGlvbiByZW1vdmVkOiBcIiArIHN1YnNjcmliZXJJZCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5UQUcgKyBcInN1YnNjcmlwdGlvbiBjb3VudCAgOiBcIiArIHRoaXMuc3Vic2NyaWJlcnMuc2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB0aGlzLnN1YnNjcmliZXJzLmRlbGV0ZShjYik7XG4gICAgICAgICAgICB0aGlzLnN1YnNjcmliZXJzLmRlbGV0ZShzdWJzY3JpYmVyRGF0YSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2V0U3RhdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyc0NvdW50OiB0aGlzLnN1YnNjcmliZXJzLnNpemUsXG4gICAgICAgICAgICBldmVudExvZzogWy4uLnRoaXMuZXZlbnRMb2ddLFxuICAgICAgICAgICAgc3Vic2NyaWJlcnM6IFsuLi50aGlzLnN1YnNjcmliZXJzXSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBlbWl0KGV2ZW50OiBERXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc29sZUxvZ0V2ZW50cykge1xuICAgICAgICAgICAgdGhpcy5sb2dFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudExvZy5wdXNoKGV2ZW50KTtcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVycy5mb3JFYWNoKChkYXRhKSA9PiB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnQ0FMTElORyBFTUlUJyk7XG4gICAgICAgICAgICBkYXRhLmNiKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHRoaXMubG9nRXZlbnRzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2dFdmVudChldmVudDogREV2ZW50KSB7XG4gICAgICAgIGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQodGhpcy5UQUcgKyBcIiBcIiArIGV2ZW50LmtpbmQpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIlByb2R1Y2VySWQ6IFwiICsgZXZlbnQucHJvZHVjZXJJZCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGV2ZW50LmRhdGEpO1xuICAgICAgICBjb25zb2xlLmdyb3VwRW5kKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2dFdmVudHMoKSB7XG4gICAgICAgIGNvbnNvbGUuZ3JvdXAodGhpcy5UQUcgKyBcIkxPR0dcIik7XG4gICAgICAgIGNvbnNvbGUudGFibGUodGhpcy5ldmVudExvZyk7XG4gICAgICAgIGNvbnNvbGUuZ3JvdXBFbmQoKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgRmFjdCB9IGZyb20gXCIuLi9ydWxlcy9mYWN0XCI7XG5pbXBvcnQgeyBEVGltZXN0YW1wIH0gZnJvbSBcIi4uL2NvbW1vbi9EVGltZXN0YW1wXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQW5zd2VyZWRRdWVzdGlvbiB7XG4gICAgcmVhZG9ubHkgdGltZXN0YW1wOiBEVGltZXN0YW1wO1xuICAgIHJlYWRvbmx5IGZhY3Q6IEZhY3Q7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQW5zd2VyZWRRdWVzdGlvbiB7XG4gICAgZXhwb3J0IGNvbnN0IGVxID0gKGE6IEFuc3dlcmVkUXVlc3Rpb24sIGI6IEFuc3dlcmVkUXVlc3Rpb24pOiBib29sZWFuID0+IHtcbiAgICAgICAgcmV0dXJuIGEuZmFjdCA9PT0gYi5mYWN0O1xuICAgIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZUhpc3Rvcnkge1xuICAgIHJlYWRvbmx5IHBhZ2VJZDogc3RyaW5nO1xuICAgIHJlYWRvbmx5IGFuc3dlcmVkUXVlc3Rpb25zOiBBbnN3ZXJlZFF1ZXN0aW9uW107XG59XG5cbmV4cG9ydCBjbGFzcyBIaXN0b3J5UXVlIHtcbiAgICBwcml2YXRlIGhpc3Rvcnk6IFBhZ2VIaXN0b3J5W10gPSBbXTtcblxuICAgIGdldEZhY3RzKCk6IEFycmF5PEZhY3Q+IHtcbiAgICAgICAgY29uc3QgYW5zd2VycyA9IHRoaXMuaGlzdG9yeS5tYXAoKGgpID0+IGguYW5zd2VyZWRRdWVzdGlvbnMpLmZsYXQoMSk7XG4gICAgICAgIGNvbnN0IGZhY3RzID0gYW5zd2Vycy5tYXAoKGEpID0+IGEuZmFjdCk7XG4gICAgICAgIC8vIFRPRE8gRklORCBMQVRFU1QgRkFDVCAoYW5zd2VyKSBpZiBoYXZlIG11bHRpcGxlLlxuICAgICAgICByZXR1cm4gZmFjdHM7XG4gICAgfVxuXG4gICAgZ2V0QW5zd2VycygpOiBBcnJheTxBbnN3ZXJlZFF1ZXN0aW9uPiB7XG4gICAgICAgIGNvbnN0IGFuc3dlcnMgPSB0aGlzLmhpc3RvcnkubWFwKChoKSA9PiBoLmFuc3dlcmVkUXVlc3Rpb25zKS5mbGF0KDEpO1xuICAgICAgICByZXR1cm4gYW5zd2VycztcbiAgICB9XG5cbiAgICBhZGRUb0hpc3RvcnkocGFnZTogUGFnZUhpc3RvcnkpIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnB1c2gocGFnZSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEZhY3QgfSBmcm9tIFwiLi9mYWN0XCI7XG5pbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuZXhwb3J0IHR5cGUgQ29uZGl0aW9uID0gQ29uZGl0aW9uLlN0cmluZyB8IENvbmRpdGlvbi5OdW1lcmljIHwgQ29uZGl0aW9uLkNvbXBsZXg7XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ29uZGl0aW9uIHtcbiAgICBleHBvcnQgdHlwZSBTdHJpbmdPcGVyYXRvciA9IFwiZXFcIiB8IFwibm90LWVxXCIgfCBcImxvbmdlci10aGVuXCIgfCBcInNob3J0ZXItdGhlblwiO1xuXG4gICAgZXhwb3J0IHR5cGUgTnVtZXJpY09wZXJhdG9yID1cbiAgICAgICAgfCBcImVxXCJcbiAgICAgICAgfCBcIm5vdC1lcVwiXG4gICAgICAgIHwgXCJncmVhdGVyLXRoZW5cIlxuICAgICAgICB8IFwibGVzcy10aGVuXCJcbiAgICAgICAgfCBcImdyZWF0ZXItdGhlbi1pbmNsdXNpdmVcIlxuICAgICAgICB8IFwibGVzcy10aGVuLWluY2x1c2l2ZVwiO1xuXG4gICAgZXhwb3J0IGludGVyZmFjZSBOdW1lcmljIHtcbiAgICAgICAgcmVhZG9ubHkgcmVmZXJlbmNlSWQ6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgcmVmZXJlbmNlTGFiZWw6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgdmFsdWVMYWJlbDogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBraW5kOiBcIm51bWVyaWMtY29uZGl0aW9uXCI7XG4gICAgICAgIHJlYWRvbmx5IG9wZXJhdG9yOiBOdW1lcmljT3BlcmF0b3I7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG4gICAgfVxuICAgIGV4cG9ydCBpbnRlcmZhY2UgU3RyaW5nIHtcbiAgICAgICAgcmVhZG9ubHkgcmVmZXJlbmNlSWQ6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgcmVmZXJlbmNlTGFiZWw6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgdmFsdWVMYWJlbDogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBraW5kOiBcInN0cmluZy1jb25kaXRpb25cIjtcbiAgICAgICAgcmVhZG9ubHkgb3BlcmF0b3I6IFN0cmluZ09wZXJhdG9yO1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgQ29tcGxleCB7XG4gICAgICAgIHJlYWRvbmx5IGtpbmQ6IFwiY29tcGxleC1jb25kaXRpb25cIjtcbiAgICAgICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBhbGw6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uLlNpbXBsZT47XG4gICAgICAgIHJlYWRvbmx5IHNvbWU6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uLlNpbXBsZT47XG4gICAgfVxuXG4gICAgZXhwb3J0IHR5cGUgU2ltcGxlID0gQ29uZGl0aW9uLlN0cmluZyB8IENvbmRpdGlvbi5OdW1lcmljO1xuXG4gICAgLyoqXG4gICAgICogQW4gZW1wdHkgY29uZGl0aW9uIHdpbGwgZXZhbHVhdGUgdG8gZmFsc2UsXG4gICAgICogQHBhcmFtIGNvbmRpdGlvbjogQ29uZGl0aW9uLkFueVxuICAgICAqIEBwYXJhbSBmYWN0c1xuICAgICAqL1xuICAgIGV4cG9ydCBjb25zdCBldmFsdWF0ZSA9IChjb25kaXRpb246IENvbmRpdGlvbiwgZmFjdHM6IFJlYWRvbmx5QXJyYXk8RmFjdD4pID0+IHtcbiAgICAgICAgbGV0IHJlc3VsdDogYm9vbGVhbiA9IGZhbHNlO1xuICAgICAgICBzd2l0Y2ggKGNvbmRpdGlvbi5raW5kKSB7XG4gICAgICAgICAgICBjYXNlIFwic3RyaW5nLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGV2YWx1YXRlU2ltcGxlKGNvbmRpdGlvbiwgZmFjdHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm51bWVyaWMtY29uZGl0aW9uXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZXZhbHVhdGVTaW1wbGUoY29uZGl0aW9uLCBmYWN0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiY29tcGxleC1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBldmFsdWF0ZUNvbXBsZXgoY29uZGl0aW9uLCBmYWN0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IGNvbmRpdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBjb25zdCBldmFsdWF0ZUNvbXBsZXggPSAoY29uZGl0aW9uOiBDb25kaXRpb24uQ29tcGxleCwgZmFjdHM6IFJlYWRvbmx5QXJyYXk8RmFjdD4pOiBib29sZWFuID0+IHtcbiAgICAgICAgaWYgKGNvbmRpdGlvbi5zb21lLmxlbmd0aCA9PT0gMCAmJiBjb25kaXRpb24uYWxsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFsbFNvbHZlZCA9IGNvbmRpdGlvbi5hbGwubWFwKChjb25kaXRpb24pID0+IHtcbiAgICAgICAgICAgIHJldHVybiBldmFsdWF0ZVNpbXBsZShjb25kaXRpb24sIGZhY3RzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc29tZUV2YWx1YXRlZCA9IGNvbmRpdGlvbi5zb21lLm1hcCgoY29uZGl0aW9uKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXZhbHVhdGVTaW1wbGUoY29uZGl0aW9uLCBmYWN0cyk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBhbGxSZXN1bHQgPSBhbGxTb2x2ZWQuZXZlcnkoRFV0aWwuaXNUcnVlKTtcbiAgICAgICAgY29uc3Qgc29tZVJlc3VsdCA9IHNvbWVFdmFsdWF0ZWQubGVuZ3RoID09PSAwIHx8IHNvbWVFdmFsdWF0ZWQuc29tZShEVXRpbC5pc1RydWUpO1xuICAgICAgICByZXR1cm4gc29tZVJlc3VsdCAmJiBhbGxSZXN1bHQ7XG4gICAgfTtcblxuICAgIGNvbnN0IGV2YWx1YXRlU2ltcGxlID0gKGNvbmRpdGlvbjogQ29uZGl0aW9uLlNpbXBsZSwgZmFjdHM6IFJlYWRvbmx5QXJyYXk8RmFjdD4pOiBib29sZWFuID0+IHtcbiAgICAgICAgY29uc3QgZmFjdCA9IGZhY3RzLmZpbmQoKGYpID0+IGYucmVmZXJlbmNlSWQgPT09IGNvbmRpdGlvbi5yZWZlcmVuY2VJZCk7XG4gICAgICAgIGlmICghZmFjdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXMgPSBmYWxzZTtcbiAgICAgICAgc3dpdGNoIChjb25kaXRpb24ua2luZCkge1xuICAgICAgICAgICAgY2FzZSBcIm51bWVyaWMtY29uZGl0aW9uXCI6XG4gICAgICAgICAgICAgICAgaWYgKGZhY3Qua2luZCA9PT0gXCJudW1lcmljLWZhY3RcIikge1xuICAgICAgICAgICAgICAgICAgICByZXMgPSBldmFsdWF0ZU51bWVyaWMoY29uZGl0aW9uLCBmYWN0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwic3RyaW5nLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIGlmIChmYWN0LmtpbmQgPT09IFwic3RyaW5nLWZhY3RcIikge1xuICAgICAgICAgICAgICAgICAgICByZXMgPSBldmFsdWF0ZVN0cmluZyhjb25kaXRpb24sIGZhY3QudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gY29uZGl0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBpc0VtcHR5ID0gKGNvbXBsZXg6IENvbXBsZXgpID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbXBsZXguYWxsLmxlbmd0aCA9PT0gMCAmJiBjb21wbGV4LnNvbWUubGVuZ3RoID09PSAwO1xuICAgIH07XG5cbiAgICBjb25zdCBldmFsdWF0ZVN0cmluZyA9IChjb25kaXRpb246IFJlYWRvbmx5PENvbmRpdGlvbi5TdHJpbmc+LCB2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGNvbnN0IG9wZXJhdG9yID0gY29uZGl0aW9uLm9wZXJhdG9yO1xuICAgICAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgICAgIGNhc2UgXCJlcVwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbmRpdGlvbi52YWx1ZSA9PT0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwibm90LWVxXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gY29uZGl0aW9uLnZhbHVlICE9PSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzaG9ydGVyLXRoZW5cIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjb25kaXRpb24udmFsdWUgIT09IHZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImxvbmdlci10aGVuXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gY29uZGl0aW9uLnZhbHVlICE9PSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gb3BlcmF0b3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgY29uc3QgZXZhbHVhdGVOdW1lcmljID0gKGNvbmRpdGlvbjogTnVtZXJpYywgdmFsdWU6IG51bWJlcik6IGJvb2xlYW4gPT4ge1xuICAgICAgICBjb25zdCBvcCA9IGNvbmRpdGlvbi5vcGVyYXRvcjtcbiAgICAgICAgY29uc3QgY29uZGl0aW9uVmFsdWUgPSBjb25kaXRpb24udmFsdWU7XG4gICAgICAgIGxldCByZXN1bHQgPSBmYWxzZTtcbiAgICAgICAgc3dpdGNoIChvcCkge1xuICAgICAgICAgICAgY2FzZSBcImVxXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWUgPT09IGNvbmRpdGlvblZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm5vdC1lcVwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlICE9PSBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJncmVhdGVyLXRoZW5cIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZSA+IGNvbmRpdGlvblZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImdyZWF0ZXItdGhlbi1pbmNsdXNpdmVcIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZSA+PSBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJsZXNzLXRoZW5cIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZSA8IGNvbmRpdGlvblZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImxlc3MtdGhlbi1pbmNsdXNpdmVcIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZSA8PSBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gb3A7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgY29uc3QgX2dldEFsbFNpbXBsZSA9IChjb25kaXRpb246IENvbmRpdGlvbik6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uLlNpbXBsZT4gPT4ge1xuICAgICAgICBjb25zdCBzaW1wbGU6IEFycmF5PENvbmRpdGlvbi5TaW1wbGU+ID0gW107XG4gICAgICAgIHN3aXRjaCAoY29uZGl0aW9uLmtpbmQpIHtcbiAgICAgICAgICAgIGNhc2UgXCJjb21wbGV4LWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIHNpbXBsZS5wdXNoKC4uLmNvbmRpdGlvbi5hbGwpO1xuICAgICAgICAgICAgICAgIHNpbXBsZS5wdXNoKC4uLmNvbmRpdGlvbi5zb21lKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJudW1lcmljLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIHNpbXBsZS5wdXNoKGNvbmRpdGlvbik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwic3RyaW5nLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIHNpbXBsZS5wdXNoKGNvbmRpdGlvbik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIERVdGlsLm5ldmVyQ2hlY2soY29uZGl0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2ltcGxlO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgZ2V0QWxsU2ltcGxlQ29uZGl0aW9ucyA9IChcbiAgICAgICAgY29uZGl0aW9uOiBDb25kaXRpb24gfCBBcnJheTxDb25kaXRpb24+XG4gICAgKTogUmVhZG9ubHlBcnJheTxDb25kaXRpb24uU2ltcGxlPiA9PiB7XG4gICAgICAgIGNvbnN0IHNpbXBsZTogQXJyYXk8Q29uZGl0aW9uLlNpbXBsZT4gPSBbXTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29uZGl0aW9uKSkge1xuICAgICAgICAgICAgY29uZGl0aW9uLmZvckVhY2goKGMpID0+IHtcbiAgICAgICAgICAgICAgICBzaW1wbGUucHVzaCguLi5fZ2V0QWxsU2ltcGxlKGMpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2ltcGxlLnB1c2goLi4uX2dldEFsbFNpbXBsZShjb25kaXRpb24pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2ltcGxlO1xuICAgIH07XG59XG4iLCAiaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4vY29uZGl0aW9uXCI7XG5pbXBvcnQgeyBGYWN0IH0gZnJvbSBcIi4vZmFjdFwiO1xuaW1wb3J0IHsgRFV0aWwgfSBmcm9tIFwiLi4vdXRpbHMvRFV0aWxcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSdWxlPE9uU3VjY2Vzc0FjdGlvbiwgT25GYWlsdXJlQWN0aW9uPiB7XG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuICByZWFkb25seSBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICByZWFkb25seSBhbGw6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uPjtcbiAgcmVhZG9ubHkgc29tZTogUmVhZG9ubHlBcnJheTxDb25kaXRpb24+O1xuICByZWFkb25seSBvblN1Y2Nlc3M6IFJlYWRvbmx5QXJyYXk8T25TdWNjZXNzQWN0aW9uPjtcbiAgcmVhZG9ubHkgb25GYWlsdXJlOiBSZWFkb25seUFycmF5PE9uRmFpbHVyZUFjdGlvbj47XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgUnVsZSB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhhdCB0aGUgcnVsZSBpcyB2YWxpZC5cbiAgICogQHBhcmFtIHJ1bGVcbiAgICovXG5cbiAgZXhwb3J0IGNvbnN0IGlzRW1wdHkgPSAocnVsZTogUnVsZTxhbnksIGFueT4pOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBlbXB0eUNvbmRpdGlvbnMgPSBydWxlLmFsbC5sZW5ndGggPT09IDAgJiYgcnVsZS5zb21lLmxlbmd0aCA9PT0gMDtcbiAgICBjb25zdCBlbXB0eUFjdGlvbnMgPSBydWxlLm9uU3VjY2Vzcy5sZW5ndGggPT09IDAgJiYgcnVsZS5vbkZhaWx1cmUubGVuZ3RoID09PSAwO1xuICAgIHJldHVybiBlbXB0eUNvbmRpdGlvbnMgfHwgZW1wdHlBY3Rpb25zO1xuICB9O1xuXG4gIGV4cG9ydCBjb25zdCBzb2x2ZSA9IChydWxlOiBSdWxlPGFueSwgYW55PiwgZmFjdHM6IFJlYWRvbmx5QXJyYXk8RmFjdD4pOiBib29sZWFuID0+IHtcbiAgICBpZiAocnVsZS5zb21lLmxlbmd0aCA9PT0gMCAmJiBydWxlLmFsbC5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIFRPRE8gUkVUVVJOIFdBUk5JTkc/IE9SIExPR0dJTkcgP1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHNvbWVTb2x2ZWQgPSBydWxlLnNvbWUubWFwKChjb25kaXRpb24pID0+IENvbmRpdGlvbi5ldmFsdWF0ZShjb25kaXRpb24sIGZhY3RzKSk7XG5cbiAgICBjb25zdCBzb21lUmVzdWx0ID0gc29tZVNvbHZlZC5sZW5ndGggPT09IDAgfHwgc29tZVNvbHZlZC5zb21lKERVdGlsLmlzVHJ1ZSk7XG5cbiAgICBjb25zdCBhbGxTb2x2ZWQgPSBydWxlLmFsbC5tYXAoKGNvbmRpdGlvbikgPT4gQ29uZGl0aW9uLmV2YWx1YXRlKGNvbmRpdGlvbiwgZmFjdHMpKS5ldmVyeShEVXRpbC5pc1RydWUpO1xuXG4gICAgcmV0dXJuIGFsbFNvbHZlZCAmJiBzb21lUmVzdWx0O1xuICB9O1xufVxuIiwgImltcG9ydCB7IEZhY3QgfSBmcm9tIFwiLi9mYWN0XCI7XG5pbXBvcnQgeyBSdWxlIH0gZnJvbSBcIi4vcnVsZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvbHZlUmVzdWx0PFMsIEY+IHtcbiAgbWF0Y2hpbmc6IFJlYWRvbmx5QXJyYXk8TWF0Y2g8UywgRj4+O1xuICBlcnJvcnM6IFJlYWRvbmx5QXJyYXk8UnVsZUVuZ2luZUVycm9yPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNYXRjaDxTLCBGPiB7XG4gIHJlYWRvbmx5IG1hdGNoaW5nUnVsZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJ1bGVEZXNjcmlwdGlvbjogc3RyaW5nO1xuICByZWFkb25seSBhY3Rpb25MaXN0OiBSZWFkb25seUFycmF5PFM+IHwgUmVhZG9ubHlBcnJheTxGPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdWxlRW5naW5lRXJyb3Ige1xuICByZWFkb25seSBraW5kPzogc3RyaW5nO1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBSdWxlRW5naW5lPFMsIEY+IHtcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIHNvbHZlQWxsKHJ1bGVzOiBSdWxlPFMsIEY+W10sIGZhY3RzOiBGYWN0W10pOiBTb2x2ZVJlc3VsdDxTLCBGPiB7XG4gICAgY29uc3QgZXJyb3JzOiBSdWxlRW5naW5lRXJyb3JbXSA9IFtdO1xuICAgIGNvbnN0IG1hdGNoaW5nOiBNYXRjaDxTLCBGPltdID0gW107XG4gICAgcnVsZXMuZm9yRWFjaCgocnVsZSkgPT4ge1xuICAgICAgaWYgKFJ1bGUuaXNFbXB0eShydWxlKSkge1xuICAgICAgICBlcnJvcnMucHVzaCh7IG1lc3NhZ2U6IFwiRW1wdHkgcnVsZTogXCIgKyBydWxlLmlkIH0pO1xuICAgICAgfSBlbHNlIGlmIChSdWxlLnNvbHZlKHJ1bGUsIGZhY3RzKSkge1xuICAgICAgICBjb25zdCBtYXRjaDogTWF0Y2g8UywgRj4gPSB7XG4gICAgICAgICAgcnVsZURlc2NyaXB0aW9uOiBydWxlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIG1hdGNoaW5nUnVsZUlkOiBydWxlLmlkID8/IFwibm8taWQtZ2l2ZW5cIixcbiAgICAgICAgICBhY3Rpb25MaXN0OiBbLi4ucnVsZS5vblN1Y2Nlc3NdLFxuICAgICAgICB9O1xuICAgICAgICBtYXRjaGluZy5wdXNoKG1hdGNoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4geyBtYXRjaGluZywgZXJyb3JzIH07XG4gIH1cblxuICBzb2x2ZShydWxlOiBSdWxlPFMsIEY+LCBmYWN0czogRmFjdFtdKTogYm9vbGVhbiB7XG4gICAgLy8gVE9ETyBWYWxpZGF0ZSwgYW5kIFJldHVybiByZXN1bHRcbiAgICByZXR1cm4gUnVsZS5zb2x2ZShydWxlLCBmYWN0cyk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBQYWdlRHRvIH0gZnJvbSBcIi4uL2R0by9TY2hlbWFEdG9cIjtcblxuZXhwb3J0IGNsYXNzIE5leHRRdWUge1xuICAgIHByaXZhdGUgb3JpZ2luYWxPcmRlcjogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0gW107XG4gICAgcHJpdmF0ZSBhbGxQYWdlczogUGFnZUR0b1tdID0gW107XG4gICAgcHJpdmF0ZSBleGNsdWRlZFRhZ3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIGV4Y2x1ZGVkQnlQYWdlSWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIHJlbWFpbmluZzogUGFnZUR0b1tdID0gW107XG4gICAgY29uc3RydWN0b3IocGFnZXM6IFBhZ2VEdG9bXSA9IFtdKSB7XG4gICAgICAgIHRoaXMucmVzZXRRdWUocGFnZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdpbGwgcmVzZXQgcXVlIHdpdGggdGhlIG5ldyBwYWdlcy5cbiAgICAgKiBAcGFyYW0gcGFnZXNcbiAgICAgKi9cbiAgICByZXNldFF1ZShwYWdlczogUGFnZUR0b1tdKSB7XG4gICAgICAgIHRoaXMuYWxsUGFnZXMgPSBbLi4ucGFnZXNdO1xuICAgICAgICB0aGlzLnJlbWFpbmluZyA9IFsuLi5wYWdlc107XG4gICAgICAgIHRoaXMuZXhjbHVkZWRUYWdzID0gbmV3IFNldCgpO1xuICAgICAgICB0aGlzLmV4Y2x1ZGVkQnlQYWdlSWQgPSBuZXcgU2V0KCk7XG4gICAgICAgIHRoaXMub3JpZ2luYWxPcmRlciA9IHRoaXMuYWxsUGFnZXMubWFwKChwKSA9PiBwLmlkKTtcbiAgICB9XG5cbiAgICBwb3AoKTogUGFnZUR0byB8IGZhbHNlIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IHRoaXMucmVtYWluaW5nLnNoaWZ0KCk7XG4gICAgICAgIC8vIFRPRE8gQ0xPTkU/P1xuICAgICAgICByZXR1cm4gbmV4dCA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBwZWVrKCk6IFBhZ2VEdG8gfCBmYWxzZSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLnJlbWFpbmluZ1swXTtcbiAgICAgICAgcmV0dXJuIG5leHQgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAganVtcFRvUGFnZUJ5SWQocGFnZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnJlbWFpbmluZy5maW5kSW5kZXgoKHApID0+IHAuaWQgPT09IHBhZ2VJZCk7XG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbWFpbmluZyA9IHRoaXMucmVtYWluaW5nLnNsaWNlKGluZGV4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmVtb3ZlQnlUYWcodGFnOiBzdHJpbmcgfCBzdHJpbmdbXSkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0YWcpKSB7XG4gICAgICAgICAgICB0YWcuZm9yRWFjaCgodGFnKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5leGNsdWRlZFRhZ3MuYWRkKHRhZyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZXhjbHVkZWRUYWdzLmFkZCh0YWcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsdGVyUmVtYWluaW5nKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2lsbCBub3QgYmUgaW5jbHVkZWRcbiAgICAgKiBAcGFyYW0gcGFnZXNcbiAgICAgKi9cbiAgICBpbnNlcnRBc05leHRCeUZvcmNlKHBhZ2VzOiBQYWdlRHRvW10pIHtcbiAgICAgICAgdGhpcy5yZW1haW5pbmcudW5zaGlmdCguLi5wYWdlcyk7XG4gICAgfVxuXG4gICAgcmVtb3ZlQnlQYWdlSWQocGFnZUlkOiBzdHJpbmcgfCBzdHJpbmdbXSkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYWdlSWQpKSB7XG4gICAgICAgICAgICBwYWdlSWQuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4Y2x1ZGVkQnlQYWdlSWQuYWRkKGlkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5leGNsdWRlZEJ5UGFnZUlkLmFkZChwYWdlSWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsdGVyUmVtYWluaW5nKCk7XG4gICAgICAgIC8vIHRoaXMuZXhjbHVkZWRCeVBhZ2VJZC5hZGQocGFnZUlkKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZpbHRlclJlbWFpbmluZygpIHtcbiAgICAgICAgdGhpcy5yZW1haW5pbmcgPSB0aGlzLnJlbWFpbmluZy5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhZ3MgPSBwLnRhZ3MgPz8gW107XG4gICAgICAgICAgICBjb25zdCBpc0luY2x1ZWRlZEJ5VGFnID0gIXRhZ3Muc29tZSgodGFnKSA9PiB0aGlzLmV4Y2x1ZGVkVGFncy5oYXModGFnKSk7XG4gICAgICAgICAgICBjb25zdCBpc0luY2x1ZGVkQnlQYWdlSWQgPSAhdGhpcy5leGNsdWRlZEJ5UGFnZUlkLmhhcyhwLmlkKTtcbiAgICAgICAgICAgIHJldHVybiBpc0luY2x1ZGVkQnlQYWdlSWQgJiYgaXNJbmNsdWVkZWRCeVRhZztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW1haW5pbmcubGVuZ3RoID09PSAwO1xuICAgIH1cbiAgICBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW1haW5pbmcubGVuZ3RoO1xuICAgIH1cbiAgICBnZXQgcGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm9yaWdpbmFsT3JkZXIubGVuZ3RoO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBBbnN3ZXJlZFF1ZXN0aW9uLCBIaXN0b3J5UXVlLCBQYWdlSGlzdG9yeSB9IGZyb20gXCIuL2hpc3RvcnktcXVlXCI7XG5pbXBvcnQgeyBSdWxlRW5naW5lIH0gZnJvbSBcIi4uL3J1bGVzL3J1bGUtZW5naW5lXCI7XG5pbXBvcnQgeyBOZXh0UXVlIH0gZnJvbSBcIi4vbmV4dC1xdWVcIjtcbmltcG9ydCB7IFBhZ2VEdG8sIFNjaGVtYUR0byB9IGZyb20gXCIuLi9kdG8vU2NoZW1hRHRvXCI7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uQ29tbWFuZCwgUGFnZVF1ZUNvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRcIjtcbmltcG9ydCB7IERVdGlsIH0gZnJvbSBcIi4uL3V0aWxzL0RVdGlsXCI7XG5cbmV4cG9ydCB0eXBlIERQbGF5ZXJEYXRhID0gUGljazxTY2hlbWFEdG8sIFwicGFnZXNcIiB8IFwicGFnZVNlcXVlbmNlc1wiIHwgXCJydWxlc1wiPjtcbmV4cG9ydCBjbGFzcyBEUGxheWVyIHtcbiAgcHJpdmF0ZSBoaXN0b3J5ID0gbmV3IEhpc3RvcnlRdWUoKTtcbiAgcHJpdmF0ZSBydWxlRW5naW5lID0gbmV3IFJ1bGVFbmdpbmU8UGFnZVF1ZUNvbW1hbmQsIFBhZ2VRdWVDb21tYW5kPigpO1xuICBwcml2YXRlIG5leHRRdWUgPSBuZXcgTmV4dFF1ZSgpO1xuICBwcml2YXRlIGRhdGE6IERQbGF5ZXJEYXRhO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IERQbGF5ZXJEYXRhKSB7XG4gICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB0aGlzLm5leHRRdWUucmVzZXRRdWUoZGF0YS5wYWdlcyk7XG4gIH1cblxuICBzYXZlSGlzdG9yeShwYWdlSGlzdG9yeTogUGFnZUhpc3RvcnkpIHtcbiAgICBjb25zb2xlLmxvZyhcIlNBVkUgSElTVE9SWVwiLCBwYWdlSGlzdG9yeSk7XG4gICAgdGhpcy5oaXN0b3J5LmFkZFRvSGlzdG9yeShwYWdlSGlzdG9yeSk7XG4gICAgY29uc3QgZmFjdHMgPSB0aGlzLmhpc3RvcnkuZ2V0RmFjdHMoKTtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnJ1bGVFbmdpbmUuc29sdmVBbGwodGhpcy5kYXRhLnJ1bGVzLCBmYWN0cyk7XG4gICAgY29uc3QgbWF0Y2hpbmdSdWxlcyA9IHJlc3VsdC5tYXRjaGluZztcbiAgICBjb25zdCBhY3Rpb25zID0gbWF0Y2hpbmdSdWxlcy5tYXAoKHIpID0+IHIuYWN0aW9uTGlzdCkuZmxhdCgxKTtcbiAgICBhY3Rpb25zLmZvckVhY2goKGEpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGEucGF5bG9hZCk7XG4gICAgICBzd2l0Y2ggKGEua2luZCkge1xuICAgICAgICBjYXNlIFwiUEFHRV9RVUVfSlVNUF9UT19QQUdFX0NPTU1BTkRcIjpcbiAgICAgICAgICB0aGlzLm5leHRRdWUuanVtcFRvUGFnZUJ5SWQoYS5wYXlsb2FkLnBhZ2VJZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJQQUdFX1FVRV9FWENMVURFX0JZX1BBR0VfSURfQ09NTUFORFwiOlxuICAgICAgICAgIHRoaXMubmV4dFF1ZS5yZW1vdmVCeVBhZ2VJZChhLnBheWxvYWQucGFnZUlkcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJQQUdFX1FVRV9FWENMVURFX0JZX1RBR19DT01NQU5EXCI6XG4gICAgICAgICAgdGhpcy5uZXh0UXVlLnJlbW92ZUJ5VGFnKGEucGF5bG9hZC50YWdJZHMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiVU5LTk9XTiBBQ1RJT05cIiwgYSk7XG4gICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gYTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyhhY3Rpb25zKTtcbiAgfVxuXG4gIGdldFJlc3VsdHMoKTogQW5zd2VyZWRRdWVzdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5LmdldEFuc3dlcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ29Ub1BhZ2VCeUlkKHBhZ2VJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5uZXh0UXVlLmp1bXBUb1BhZ2VCeUlkKHBhZ2VJZCk7XG4gIH1cblxuICBoYW5kbGVOYXZpZ2F0aW9uQ29tbWFuZChjb21tYW5kOiBOYXZpZ2F0aW9uQ29tbWFuZCkge1xuICAgIHN3aXRjaCAoY29tbWFuZC5raW5kKSB7XG4gICAgICBjYXNlIFwiUEFHRV9RVUVfTkVYVF9QQUdFX0NPTU1BTkRcIjpcbiAgICAgICAgLy8gTk8gTkVFRCBUTyBETyBBTllUSElOR1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJQQUdFX1FVRV9HT19UT19QQUdFX0NPTU1BTkRcIjpcbiAgICAgICAgdGhpcy5nb1RvUGFnZUJ5SWQoY29tbWFuZC5wYXlsb2FkLnBhZ2VJZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcIlBBR0VfUVVFX0dPX1RPX1NFUVVFTkNFX0NPTU1BTkRcIjpcbiAgICAgICAgdGhpcy5pbnNlcnRTZXF1ZW5jZUJ5SWQoY29tbWFuZC5wYXlsb2FkLnNlcXVlbmNlSWQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgRFV0aWwubmV2ZXJDaGVjayhjb21tYW5kKTtcbiAgICB9XG4gIH1cblxuICBnZXROZXh0UGFnZSgpOiBQYWdlRHRvIHwgZmFsc2Uge1xuICAgIC8vIFRPRE8gSEFORExFIFJVTEVTISFcbiAgICByZXR1cm4gdGhpcy5uZXh0UXVlLnBvcCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRTZXF1ZW5jZUJ5SWQoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHNlcSA9IHRoaXMuZGF0YS5wYWdlU2VxdWVuY2VzPy5maW5kKChzKSA9PiBzLmlkID09PSBpZCk7XG4gICAgaWYgKHNlcSkge1xuICAgICAgdGhpcy5uZXh0UXVlLmluc2VydEFzTmV4dEJ5Rm9yY2UoWy4uLnNlcS5wYWdlc10pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBIT1cgVE8gSEFORExFIElOVkFMSUQgSURfUkVGUz8/IExPR0dFUj8/XG4gICAgICAvLyBMT0cgSU5WQUxJRCBDT01NQU5ELlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUb3RhbCBudW1iZXIgb2YgcGFnZXMuXG4gICAqL1xuICBnZXQgcGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubmV4dFF1ZS5wYWdlQ291bnQ7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBEQ29tbWFuZCwgRWxlbWVudENvbW1hbmQsIFN0YXRlQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgREV2ZW50IH0gZnJvbSBcIi4uL2V2ZW50cy9ERXZlbnRzXCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcnVsZXMvY29uZGl0aW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgREV2ZW50SGFuZGxlcjxFIGV4dGVuZHMgREV2ZW50ID0gREV2ZW50PiB7XG4gICAgcmVhZG9ubHkgb25FdmVudDogRVtcImtpbmRcIl07XG4gICAgcmVhZG9ubHkgd2hlbj86IHsgcHJvZHVjZXJJZD86IHN0cmluZzsgY29uZGl0aW9uPzogQ29uZGl0aW9uIH07XG4gICAgcmVhZG9ubHkgdGhlbkV4ZWN1dGU6IFJlYWRvbmx5QXJyYXk8RENvbW1hbmQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFF1ZXJ5Q2hhbmdlZEhhbmRsZXIge1xuICAgIHJlYWRvbmx5IHF1ZXJ5TmFtZTogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHdoZW5UcnVlOiBSZWFkb25seUFycmF5PEVsZW1lbnRDb21tYW5kPjtcbiAgICByZWFkb25seSB3aGVuRmFsc2U6IFJlYWRvbmx5QXJyYXk8RWxlbWVudENvbW1hbmQ+O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIERFdmVudEhhbmRsZXIge1xuICAgIGV4cG9ydCB0eXBlIExvb2tVcCA9IE1hcDxERXZlbnRIYW5kbGVyW1wib25FdmVudFwiXSwgQXJyYXk8REV2ZW50SGFuZGxlcj4+O1xuICAgIGV4cG9ydCBjb25zdCBjcmVhdGVMb29rVXAgPSAoaGFuZGxlcnM/OiBSZWFkb25seUFycmF5PERFdmVudEhhbmRsZXI+KTogTG9va1VwID0+IHtcbiAgICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxERXZlbnRIYW5kbGVyW1wib25FdmVudFwiXSwgQXJyYXk8REV2ZW50SGFuZGxlcj4+KCk7XG4gICAgICAgIGhhbmRsZXJzPy5mb3JFYWNoKChoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBraW5kID0gaC5vbkV2ZW50O1xuICAgICAgICAgICAgY29uc3QgY3VycmVudCA9IG1hcC5nZXQoa2luZCk7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25zID0gY3VycmVudCA/IFsuLi5jdXJyZW50LCBoXSA6IFtoXTtcbiAgICAgICAgICAgIG1hcC5zZXQoa2luZCwgYWN0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbWFwO1xuICAgIH07XG59XG4iLCAiaW1wb3J0IHsgRFN0eWxlIH0gZnJvbSBcIi4vRFN0eWxlXCI7XG5pbXBvcnQgeyBERWxlbWVudEJhc2VEdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuaW1wb3J0IHsgRENvbW1hbmQsIEVsZW1lbnRDb21tYW5kIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuaW1wb3J0IHsgREV2ZW50SGFuZGxlciB9IGZyb20gXCIuLi9ldmVudC1oYW5kbGVycy9ERXZlbnRIYW5kbGVyXCI7XG5pbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgQW5pbWF0aW9uRHRvIH0gZnJvbSBcIi4uL2R0by9BbmltYXRpb25EdG9cIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuLi9lbmdpbmUvc2NhbGVcIjtcbmltcG9ydCB7IERTdGF0ZSB9IGZyb20gXCIuLi9zdGF0ZS9Ec3RhdGVcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIERFbGVtZW50PFQgZXh0ZW5kcyBIVE1MRWxlbWVudD4ge1xuICAgIHByb3RlY3RlZCByZWFkb25seSBlbDogVDtcbiAgICBwcml2YXRlIGNsaWNrSGFuZGxlcklzRW5hYmxlZCA9IHRydWU7XG4gICAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgICBwcml2YXRlIGlzQW5pbWF0aW5nU2VsZiA9IGZhbHNlO1xuICAgIHByb3RlY3RlZCBjdXJyU3R5bGU6IFBhcnRpYWw8RFN0eWxlPiA9IHtcbiAgICAgICAgZm9udFNpemU6IHsgX3VuaXQ6IFwicHhcIiwgdmFsdWU6IDEwMCB9LFxuICAgICAgICBmb250V2VpZ2h0OiA1MDAsXG4gICAgICAgIHRleHRDb2xvcjogXCJibGFja1wiLFxuICAgICAgICBvcGFjaXR5OiAxLFxuICAgIH07XG5cbiAgICAvLyBwcml2YXRlIHJlYWRvbmx5IG9uUXVlcnlDaGFuZ2VkSGFuZGxlcnMgPVxuICAgIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRIYW5kbGVyczogREV2ZW50SGFuZGxlci5Mb29rVXA7XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbW1hbmRCdXM6IERDb21tYW5kQnVzO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBldmVudEJ1czogRXZlbnRCdXM7XG4gICAgcHJvdGVjdGVkIHNjYWxlOiBTY2FsZVNlcnZpY2U7XG4gICAgcHJpdmF0ZSByZWFkb25seSBiYXNlRHRvOiBERWxlbWVudEJhc2VEdG87XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnMgPSBuZXcgU2V0PCgpID0+IHZvaWQ+KCk7XG5cbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgICAgIGVsOiBULFxuICAgICAgICBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgICAgIGNvbW1hbmRCdXM6IERDb21tYW5kQnVzLFxuICAgICAgICBkdG86IERFbGVtZW50QmFzZUR0byxcbiAgICAgICAgc2NhbGU6IFNjYWxlU2VydmljZVxuICAgICkge1xuICAgICAgICB0aGlzLmVsID0gZWw7XG4gICAgICAgIHRoaXMuaWQgPSBkdG8uaWQ7XG4gICAgICAgIHRoaXMuYmFzZUR0byA9IGR0bztcbiAgICAgICAgLy8gdGhpcy5lbC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgdGhpcy5jb21tYW5kQnVzID0gY29tbWFuZEJ1cztcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBERXZlbnRIYW5kbGVyLmNyZWF0ZUxvb2tVcChkdG8uZXZlbnRIYW5kbGVycyk7XG4gICAgICAgIHRoaXMuc2NhbGUgPSBzY2FsZTtcbiAgICAgICAgLy8gQ0xJQ0tcbiAgICAgICAgdGhpcy5vbkNsaWNrSGFuZGxlciA9IHRoaXMub25DbGlja0hhbmRsZXIuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5lbC5vbmNsaWNrID0gdGhpcy5vbkNsaWNrSGFuZGxlcjtcblxuICAgICAgICAvLyBIT1ZFUlxuICAgICAgICB0aGlzLm9uTW91c2VPdmVyID0gdGhpcy5vbk1vdXNlT3Zlci5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmVsLm9ubW91c2VvdmVyID0gdGhpcy5vbk1vdXNlT3ZlcjtcblxuICAgICAgICBpZiAoZHRvKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVN0eWxlcyhkdG8/LnN0eWxlKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21tYW5kU3Vic2NyaXB0aW9uID0gdGhpcy5jb21tYW5kQnVzLnN1YnNjcmliZSgoYykgPT4ge1xuICAgICAgICAgICAgaWYgKGMua2luZCA9PT0gXCJFTEVNRU5UX1NUWUxFX0NPTU1BTkRcIiAmJiBjLnRhcmdldElkID09PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdHlsZShjLnBheWxvYWQuY2hhbmdlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYy5raW5kID09PSBcIkVMRU1FTlRfRElTQUJMRV9DTElDS19DT01NQU5EXCIgJiYgYy50YXJnZXRJZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xpY2tIYW5kbGVySXNFbmFibGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYy5raW5kID09PSBcIkVMRU1FTlRfRU5BQkxFX0NMSUNLX0NPTU1BTkRcIiAmJiBjLnRhcmdldElkID09PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGlja0hhbmRsZXJJc0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGMua2luZCA9PT0gXCJFTEVNRU5UX0FOSU1BVEVfQ09NTUFORFwiICYmIGMudGFyZ2V0SWQgPT09IHRoaXMuaWQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIlRPRE8gSU1QTEVNRU5UIEFOSU1BVElPTl9IQU5ETEVSIElOIERFbGVtZW50LlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcy5pZCk7XG4gICAgICAgIC8vIFRPRE8gTUVNT1JZIExFQUtcbiAgICAgICAgY29uc3QgZXZlbnRTdWJzY3JpcHRpb24gPSB0aGlzLmV2ZW50QnVzLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJzID0gdGhpcy5ldmVudEhhbmRsZXJzLmdldChldmVudC5raW5kKSA/PyBbXTtcbiAgICAgICAgICAgIC8vIFRPRE8gQXBwbHkgQ29uZGl0aW9ucyBpbiBXSEVOLlxuICAgICAgICAgICAgY29uc3QgY29tbWFuZHMgPSBoYW5kbGVycy5tYXAoKGgpID0+IGgudGhlbkV4ZWN1dGUpLmZsYXQoMSk7XG4gICAgICAgICAgICBjb21tYW5kcy5mb3JFYWNoKChjb21tYW5kKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgICAgICAgICAgICAgLy8gdGhpcy5kb0FjdGlvbihjb21tYW5kKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoZXZlbnQua2luZCA9PT0gXCJIT1NUX1NDQUxFX0NIQU5HRURfRVZFTlRcIikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiSEFORExFIFRISVMgU0NBTEUgQ0hBTkdFISFcIik7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTdHlsZXMoe30pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXZlbnQua2luZCA9PT0gXCJTVEFURV9RVUVSWV9SRVNVTFRfQ0hBTkdFRF9FVkVOVFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWVyeUNoYW5nZWRIYW5kbGVyKGV2ZW50LmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBcIkVMRU1FTlQ6IFwiKTtcbiAgICAgICAgdGhpcy5ub3JtYWxpemUoKTtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChjb21tYW5kU3Vic2NyaXB0aW9uKTtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChldmVudFN1YnNjcmlwdGlvbik7XG4gICAgfVxuXG4gICAgYWJzdHJhY3QgZGVzdHJveSgpOiB2b2lkO1xuXG4gICAgLy8gYWJzdHJhY3Qgc2V0U2NhbGUoc2NhbGU6IG51bWJlcik6IHZvaWQ7XG5cbiAgICAvLyAvKipcbiAgICAvLyAgKiBUaGUgcHVycG9zZSBvZiB0aGlzIGZ1bmN0aW9uIGlzIHRvIHJlLWVtaXQgY29tbWFuZHMgZnJvbSBldmVudC1oYW5kbGVycz9cbiAgICAvLyAgKiBAcGFyYW0gY29tbWFuZFxuICAgIC8vICAqIEBwcml2YXRlXG4gICAgLy8gICovXG4gICAgLy8gcHJpdmF0ZSBoYW5kbGVDb21tYW5kc0VtaXR0ZWRCeVByaXZhdGVFdmVudEhhbmRsZXJzKGNvbW1hbmQ6IERDb21tYW5kKSB7XG4gICAgLy8gICAgIGNvbnNvbGUubG9nKGNvbW1hbmQpO1xuICAgIC8vICAgICBzd2l0Y2ggKGNvbW1hbmQua2luZCkge1xuICAgIC8vICAgICAgICAgY2FzZSBcIkVMRU1FTlRfU1RZTEVfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIGlmIChjb21tYW5kLnRhcmdldElkID09PSB0aGlzLmlkKSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU3R5bGVzKGNvbW1hbmQucGF5bG9hZC5jaGFuZ2VzKTtcbiAgICAvLyAgICAgICAgICAgICB9XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiRUxFTUVOVF9BTklNQVRFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICAvLyBUT0RPIENIRUNLIEZPUiBUQVJHRVQgSURcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmhhbmRsZUFuaW1hdGVTZWxmQWN0aW9uKGNvbW1hbmQucGF5bG9hZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiRUxFTUVOVF9FTkFCTEVfQ0xJQ0tfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY2xpY2tIYW5kbGVySXNFbmFibGVkID0gdHJ1ZTtcbiAgICAvLyAgICAgICAgICAgICAvLyB0aGlzLnVwZGF0ZVN0eWxlcyhjb21tYW5kLnBheWxvYWQuY2hhbmdlcyk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiRUxFTUVOVF9ESVNBQkxFX0NMSUNLX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNsaWNrSGFuZGxlcklzRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8vICAgICAgICAgICAgIC8vIHRoaXMuaGFuZGxlQW5pbWF0ZVNlbGZBY3Rpb24oY29tbWFuZC5wYXlsb2FkKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJWSURFT19QTEFZX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJWSURFT19QQVVTRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiRU5HSU5FX0xFQVZFX1BBR0VfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlZJREVPX0pVTVBfVE9fQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlZJREVPX1NFVF9WT0xVTUVfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkFVRElPX1BMQVlfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkFVRElPX1BBVVNFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJBVURJT19TRVRfVk9MVU1FX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJQQUdFX1FVRV9ORVhUX1BBR0VfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlBBR0VfUVVFX0dPX1RPX1NFUVVFTkNFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJQQUdFX1FVRV9HT19UT19QQUdFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJQQUdFX1FVRV9FWENMVURFX0JZX1BBR0VfSURfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlBBR0VfUVVFX0pVTVBfVE9fUEFHRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiUEFHRV9RVUVfRVhDTFVERV9CWV9UQUdfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlNUQVRFX01VVEFURV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBkZWZhdWx0OlxuICAgIC8vICAgICAgICAgICAgIERVdGlsLm5ldmVyQ2hlY2soY29tbWFuZCk7XG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG5cbiAgICBwcml2YXRlIHF1ZXJ5Q2hhbmdlZEhhbmRsZXIocmVzdWx0OiBEU3RhdGUuU3RhdGVRdWVyeVJlc3VsdCkge1xuICAgICAgICBjb25zdCBtYXliZUhhbmRsZXJzID0gdGhpcy5iYXNlRHRvLm9uU3RhdGVDaGFuZ2U7XG4gICAgICAgIGlmICghbWF5YmVIYW5kbGVycykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHF1ZXJ5SGFuZGxlcnMgPSBtYXliZUhhbmRsZXJzLmZpbHRlcigoaCkgPT4gaC5xdWVyeU5hbWUgPT09IHJlc3VsdC5xdWVyeU5hbWUpO1xuICAgICAgICBxdWVyeUhhbmRsZXJzLmZvckVhY2goKGgpID0+IHtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuY3Vycikge1xuICAgICAgICAgICAgICAgIGgud2hlblRydWUuZm9yRWFjaCgoY29tbWFuZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLmRvQWN0aW9uKGNvbW1hbmQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaC53aGVuRmFsc2UuZm9yRWFjaCgoY29tbWFuZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLmRvQWN0aW9uKGNvbW1hbmQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGZpbmRCeVF1ZXJ5LCB2YWx1ZSk7XG4gICAgICAgIC8vIGNvbnN0IGFsbCA9IHRoaXMuYmFzZUR0by5zdGF0ZVF1ZXJ5Q2hhbmdlID8/IFtdO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25DbGlja0hhbmRsZXIoXzogTW91c2VFdmVudCkge1xuICAgICAgICAvLyBjb25zb2xlLmxvZygpO1xuICAgICAgICBpZiAoIXRoaXMuY2xpY2tIYW5kbGVySXNFbmFibGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmlkICsgXCJDbGljayBkaXNhYmxlZFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGlja0FjdGlvbiA9IHRoaXMuYmFzZUR0by5vbkNsaWNrO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIk5BVElWRSBDTElDSyBFTEVNRU5UOiBIYW5kbGVycyBcIiArIGNsaWNrQWN0aW9uPy5sZW5ndGgpO1xuICAgICAgICBpZiAoY2xpY2tBY3Rpb24gJiYgY2xpY2tBY3Rpb24ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJUQVJHRVRJRDogXCIgKyBjbGlja0FjdGlvblswXS50YXJnZXRJZCArIFwiIFwiICsgdGhpcy5pZCk7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwiVVNFUl9DTElDS0VEX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgcHJvZHVjZXI6IFwiRFVzZXJcIixcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgZWxlbWVudElkOiB0aGlzLmlkIH0sXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjbGlja0FjdGlvbi5mb3JFYWNoKChjb21tYW5kKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25Nb3VzZU92ZXIoXzogTW91c2VFdmVudCkge1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhldik7XG4gICAgfVxuXG4gICAgc2V0U3R5bGUoc3R5bGU6IFBhcnRpYWw8RFN0eWxlPikge1xuICAgICAgICB0aGlzLnVwZGF0ZVN0eWxlcyhzdHlsZSk7XG4gICAgfVxuXG4gICAgYXBwZW5kWW91cnNlbGYocGFyZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgICBwYXJlbnQuYXBwZW5kKHRoaXMuZWwpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhwYXJlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlQW5pbWF0ZVNlbGZBY3Rpb24oZHRvOiBBbmltYXRpb25EdG8pIHtcbiAgICAgICAgdGhpcy5pc0FuaW1hdGluZ1NlbGYgPSB0cnVlO1xuICAgICAgICBjb25zdCB7IGtleWZyYW1lcywgb3B0aW9ucyB9ID0gZHRvO1xuXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbiA9IHRoaXMuZWwuYW5pbWF0ZShrZXlmcmFtZXMsIG9wdGlvbnMuZHVyYXRpb24pO1xuICAgICAgICBhbmltYXRpb24ub25maW5pc2ggPSAoZTogQW5pbWF0aW9uUGxheWJhY2tFdmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZS50eXBlKTtcbiAgICAgICAgICAgIHRoaXMuaXNBbmltYXRpbmdTZWxmID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIGFuaW1hdGlvbi5vbnJlbW92ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkFOSU1BVElPTiBSRU1PVkVEOiBcIiArIGFuaW1hdGlvbi5pZCk7XG4gICAgICAgICAgICB0aGlzLmlzQW5pbWF0aW5nU2VsZiA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBhbmltYXRpb24ub25jYW5jZWwgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJBTklNQVRJT04gQ0FOQ0VMRUQ6IFwiICsgYW5pbWF0aW9uLmlkKTtcbiAgICAgICAgICAgIHRoaXMuaXNBbmltYXRpbmdTZWxmID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBub3JtYWxpemUoKSB7XG4gICAgICAgIERTdHlsZS5ub3JtYWxpemUodGhpcy5lbCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHVwZGF0ZVN0eWxlcyhzdHlsZTogUGFydGlhbDxEU3R5bGU+KSB7XG4gICAgICAgIHRoaXMuY3VyclN0eWxlID0gT2JqZWN0LmFzc2lnbih0aGlzLmN1cnJTdHlsZSwgc3R5bGUpO1xuICAgICAgICBEU3R5bGUuYXBwbHlTdHlsZXModGhpcy5lbCwgdGhpcy5jdXJyU3R5bGUsIHRoaXMuc2NhbGUuc2NhbGUpO1xuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgREVsZW1lbnQgfSBmcm9tIFwiLi9ERWxlbWVudFwiO1xuaW1wb3J0IHsgRERpdkR0byB9IGZyb20gXCIuLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5pbXBvcnQgeyBEVGV4dCB9IGZyb20gXCIuL0RUZXh0XCI7XG5pbXBvcnQgeyBESW1nIH0gZnJvbSBcIi4vREltZ1wiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuLi9lbmdpbmUvc2NhbGVcIjtcblxuZXhwb3J0IGNsYXNzIEREaXYgZXh0ZW5kcyBERWxlbWVudDxIVE1MRGl2RWxlbWVudD4ge1xuICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBERGl2IF06IFwiO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGVmYXVsdFN0eWxlID0geyB4OiAyMiwgeTogNCB9O1xuICBwcml2YXRlIGNoaWxkcmVuOiBBcnJheTxEVGV4dCB8IERJbWc+ID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZHRvOiBERGl2RHRvLFxuICAgIGV2ZW50QnVzOiBFdmVudEJ1cyxcbiAgICBhY3Rpb25TZXJ2aWNlOiBEQ29tbWFuZEJ1cyxcbiAgICBzY2FsZTogU2NhbGVTZXJ2aWNlLFxuICAgIGNoaWxkcmVuOiBBcnJheTxEVGV4dCB8IERJbWc+LFxuICApIHtcbiAgICBjb25zdCBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBzdXBlcihkLCBldmVudEJ1cywgYWN0aW9uU2VydmljZSwgZHRvLCBzY2FsZSk7XG4gICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgY2hpbGQuYXBwZW5kWW91cnNlbGYodGhpcy5lbCk7XG4gICAgfSk7XG4gIH1cblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKCh1bnN1YnNjcmliZSkgPT4ge1xuICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcbiAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICBjaGlsZC5kZXN0cm95KCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBERWxlbWVudCB9IGZyb20gXCIuL0RFbGVtZW50XCI7XG5pbXBvcnQgeyBESW1nRHRvIH0gZnJvbSBcIi4uL2R0by9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5pbXBvcnQgeyBEVGltZXN0YW1wIH0gZnJvbSBcIi4uL2NvbW1vbi9EVGltZXN0YW1wXCI7XG5cbmV4cG9ydCBjbGFzcyBESW1nIGV4dGVuZHMgREVsZW1lbnQ8SFRNTEltYWdlRWxlbWVudD4ge1xuICAgIHByaXZhdGUgc3RhdGljIElNQUdFX0NPVU5UID0gMDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGltYWdlQ291bnQ6IG51bWJlcjtcbiAgICByZWFkb25seSBUQUc6IHN0cmluZztcbiAgICByZWFkb25seSBUSU1JTkdfVEFHOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSByZWFkb25seSBsb2FkU3RhcnQ6IERUaW1lc3RhbXA7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkdG86IERJbWdEdG8sXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgYWN0aW9uU3ViamVjdDogRENvbW1hbmRCdXMsXG4gICAgICAgIHJlYWRvbmx5IGV2ZW50QnVzOiBFdmVudEJ1cyxcbiAgICAgICAgcmVhZG9ubHkgc2NhbGVTZXJ2aWNlOiBTY2FsZVNlcnZpY2VcbiAgICApIHtcbiAgICAgICAgc3VwZXIoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKSwgZXZlbnRCdXMsIGFjdGlvblN1YmplY3QsIGR0bywgc2NhbGVTZXJ2aWNlKTtcbiAgICAgICAgREltZy5JTUFHRV9DT1VOVCArPSAxO1xuICAgICAgICB0aGlzLmltYWdlQ291bnQgPSBESW1nLklNQUdFX0NPVU5UO1xuICAgICAgICB0aGlzLlRBRyA9IFwiW0RfSU1HIFwiICsgREltZy5JTUFHRV9DT1VOVCArIFwiIF06IFwiO1xuICAgICAgICB0aGlzLlRJTUlOR19UQUcgPSBcImxvYWQtdGltZSAoXCIgKyBESW1nLklNQUdFX0NPVU5UICsgXCIpIFwiO1xuICAgICAgICB0aGlzLmVsLmxvYWRpbmcgPSBcImVhZ2VyXCI7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUoZHRvLnN0eWxlKTtcbiAgICAgICAgdGhpcy5sb2FkU3RhcnQgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgICAgICAvLyBCaW5kIEhhbmRsZXJzXG4gICAgICAgIHRoaXMub25FcnJvciA9IHRoaXMub25FcnJvci5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLm9uTG9hZCA9IHRoaXMub25Mb2FkLmJpbmQodGhpcyk7XG4gICAgICAgIC8vIHRoaXMub25DbGljayA9IHRoaXMub25DbGljay5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmVsLm9ubG9hZCA9IHRoaXMub25Mb2FkO1xuICAgICAgICB0aGlzLmVsLm9uZXJyb3IgPSB0aGlzLm9uRXJyb3I7XG4gICAgICAgIC8vIHRoaXMuZWwub25jbGljayA9IHRoaXMub25DbGljaztcbiAgICAgICAgdGhpcy5lbC5zcmMgPSBkdG8udXJsO1xuICAgICAgICBjb25zb2xlLnRpbWUodGhpcy5USU1JTkdfVEFHKTtcbiAgICB9XG5cbiAgICBsb2coKTogdm9pZCB7fVxuXG4gICAgc2V0U2NhbGUoc2NhbGU6IG51bWJlcikge1xuICAgICAgICBjb25zb2xlLmxvZyhzY2FsZSk7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUodGhpcy5jdXJyU3R5bGUpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgodW5zdWJzY3JpYmUpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25FcnJvcihldjogRXZlbnQgfCBzdHJpbmcpIHtcbiAgICAgICAgaWYgKGV2IGluc3RhbmNlb2YgRXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCIgXCIgKyBldi50eXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgZXYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkxvYWQoXzogRXZlbnQpIHtcbiAgICAgICAgY29uc3QgbG9hZFRpbWUgPSBEVGltZXN0YW1wLmRpZmZOb3codGhpcy5sb2FkU3RhcnQpO1xuXG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIklNQUdFX0xPQURFRF9FVkVOVFwiLFxuICAgICAgICAgICAgcHJvZHVjZXI6IFwiREltYWdlXCIsXG4gICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGxvYWRUaW1lLFxuICAgICAgICAgICAgICAgIG5hdHVyYWxIZWlnaHQ6IHRoaXMuZWwubmF0dXJhbEhlaWdodCxcbiAgICAgICAgICAgICAgICBuYXR1cmFsV2lkdGg6IHRoaXMuZWwubmF0dXJhbFdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5lbC5oZWlnaHQsXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMuZWwud2lkdGgsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgREVsZW1lbnQgfSBmcm9tIFwiLi9ERWxlbWVudFwiO1xuaW1wb3J0IHsgRFRleHREdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuLi9lbmdpbmUvc2NhbGVcIjtcblxuZXhwb3J0IGNsYXNzIERUZXh0IGV4dGVuZHMgREVsZW1lbnQ8SFRNTFBhcmFncmFwaEVsZW1lbnQ+IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBEUGFyYWdyYXBoIF06IFwiO1xuICAgIHByb3RlY3RlZCBkZWZhdWx0U3R5bGUgPSB7fTtcblxuICAgIGNvbnN0cnVjdG9yKGR0bzogRFRleHREdG8sIGV2ZW50QnVzOiBFdmVudEJ1cywgYWN0aW9uU2VydmljZTogRENvbW1hbmRCdXMsIHNjYWxlOiBTY2FsZVNlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInBcIiksIGV2ZW50QnVzLCBhY3Rpb25TZXJ2aWNlLCBkdG8sIHNjYWxlKTtcbiAgICAgICAgdGhpcy5lbC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgICAgdGhpcy5lbC5pbm5lclRleHQgPSBcIlwiICsgZHRvLnRleHQ7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUoZHRvLnN0eWxlKTtcbiAgICB9XG5cbiAgICBzZXRTY2FsZShzY2FsZTogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUodGhpcy5jdXJyU3R5bGUpO1xuICAgICAgICBjb25zdCBmb250U2l6ZSA9IHRoaXMuZWwuc3R5bGUuZm9udFNpemU7XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJzY2FsZTogXCIgKyBzY2FsZSArIFwiIEZvbnRzaXplOiBcIiArIGZvbnRTaXplKTtcbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgodW5zdWJzY3JpYmUpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBERWxlbWVudCB9IGZyb20gXCIuLi9EZWxlbWVudC9ERWxlbWVudFwiO1xuaW1wb3J0IHsgRERpdiB9IGZyb20gXCIuLi9EZWxlbWVudC9EZGl2XCI7XG5pbXBvcnQgeyBESW1nIH0gZnJvbSBcIi4uL0RlbGVtZW50L0RJbWdcIjtcbmltcG9ydCB7IERUZXh0IH0gZnJvbSBcIi4uL0RlbGVtZW50L0RUZXh0XCI7XG5pbXBvcnQgeyBERGl2RHRvLCBERWxlbWVudER0byB9IGZyb20gXCIuLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4vc2NhbGVcIjtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURFbGVtZW50ID0gKFxuICAgIGR0bzogREVsZW1lbnREdG8sXG4gICAgYWN0aW9uQnVzOiBEQ29tbWFuZEJ1cyxcbiAgICBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgc2NhbGU6IFNjYWxlU2VydmljZVxuKTogREVsZW1lbnQ8YW55PiA9PiB7XG4gICAgc3dpdGNoIChkdG8uX3RhZykge1xuICAgICAgICBjYXNlIFwiZGl2XCI6XG4gICAgICAgICAgICBjb25zdCBjaGlsZEVscyA9IGNyZWF0ZUNoaWxkcmVuRm9yRGl2KGR0bywgYWN0aW9uQnVzLCBldmVudEJ1cywgc2NhbGUpO1xuICAgICAgICAgICAgY29uc3QgbmV3RGl2ID0gbmV3IEREaXYoZHRvLCBldmVudEJ1cywgYWN0aW9uQnVzLCBzY2FsZSwgY2hpbGRFbHMpO1xuICAgICAgICAgICAgcmV0dXJuIG5ld0RpdjtcbiAgICAgICAgY2FzZSBcImltZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBESW1nKGR0bywgYWN0aW9uQnVzLCBldmVudEJ1cywgc2NhbGUpO1xuICAgICAgICBjYXNlIFwicFwiOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBEVGV4dChkdG8sIGV2ZW50QnVzLCBhY3Rpb25CdXMsIHNjYWxlKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IGR0bztcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gZHRvIGdpdmVuIHRvIHRoZSBjcmVhdGVERWxlbWVudCBmdW5jdGlvbi5cIik7XG4gICAgICAgIC8vIFRPRE8gTE9HR0lORyBvciBjcmVhdGUgYW55IEhUTUwtRUxFTUVOVD8/XG4gICAgfVxufTtcblxuY29uc3QgY3JlYXRlQ2hpbGRyZW5Gb3JEaXYgPSAoXG4gICAgZHRvOiBERGl2RHRvLFxuICAgIGFjdGlvblN1YmplY3Q6IERDb21tYW5kQnVzLFxuICAgIGV2ZW50QnVzOiBFdmVudEJ1cyxcbiAgICBzY2FsZTogU2NhbGVTZXJ2aWNlXG4pOiBERGl2W1wiY2hpbGRyZW5cIl0gPT4ge1xuICAgIGNvbnN0IGNoaWxkRHRvID0gZHRvLmNoaWxkcmVuO1xuICAgIGNvbnN0IGNoaWxkRWxzOiBBcnJheTxESW1nIHwgRFRleHQ+ID0gW107XG4gICAgLy8gY29uc29sZS5sb2coY2hpbGRFbGVtZW50cyk7XG4gICAgY2hpbGREdG8uZm9yRWFjaCgoZHRvKSA9PiB7XG4gICAgICAgIGlmIChkdG8uX3RhZyA9PT0gXCJwXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1RleHQgPSBuZXcgRFRleHQoZHRvLCBldmVudEJ1cywgYWN0aW9uU3ViamVjdCwgc2NhbGUpO1xuICAgICAgICAgICAgY2hpbGRFbHMucHVzaChuZXdUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZHRvLl90YWcgPT09IFwiaW1nXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0ltYWdlID0gbmV3IERJbWcoZHRvLCBhY3Rpb25TdWJqZWN0LCBldmVudEJ1cywgc2NhbGUpO1xuICAgICAgICAgICAgY2hpbGRFbHMucHVzaChuZXdJbWFnZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY2hpbGRFbHM7XG59O1xuIiwgImltcG9ydCB7IERFbGVtZW50IH0gZnJvbSBcIi4uL0RlbGVtZW50L0RFbGVtZW50XCI7XG5pbXBvcnQgeyBQYWdlRHRvIH0gZnJvbSBcIi4uL2R0by9TY2hlbWFEdG9cIjtcbmltcG9ydCB7IGNyZWF0ZURFbGVtZW50IH0gZnJvbSBcIi4vZWxlbWVudC1mYWN0b3J5XCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4vc2NhbGVcIjtcblxuZXhwb3J0IGNsYXNzIERQYWdlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgRFBhZ2UgXTogXCI7XG4gIHByaXZhdGUgZWxlbWVudHM6IERFbGVtZW50PEhUTUxFbGVtZW50PltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXM7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZEJ1cztcbiAgcHJpdmF0ZSByZWFkb25seSBzY2FsZTogU2NhbGVTZXJ2aWNlO1xuICAvLyBUb2RvIEdMT0JBTCBFVkVOVF9CVVNTIEFORCBQQUdFIEVWRU5UUzpcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGR0bzogUGFnZUR0byxcbiAgICBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgY29tbWFuZEJ1czogRENvbW1hbmRCdXMsXG4gICAgc2NhbGU6IFNjYWxlU2VydmljZSxcbiAgKSB7XG4gICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgIHRoaXMuY29tbWFuZEJ1cyA9IGNvbW1hbmRCdXM7XG4gICAgdGhpcy5zY2FsZSA9IHNjYWxlO1xuICAgIHRoaXMuZWxlbWVudHMgPSBkdG8uZWxlbWVudHMubWFwKChkdG8pID0+IGNyZWF0ZURFbGVtZW50KGR0bywgdGhpcy5jb21tYW5kQnVzLCB0aGlzLmV2ZW50QnVzLCB0aGlzLnNjYWxlKSk7XG4gIH1cblxuICBhcHBlbmRZb3Vyc2VsZihwYXJlbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyBcIiBBUFBFTkRJTkcgVE8gUEFSRU5UXCIpO1xuICAgIHRoaXMuZWxlbWVudHMuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgIGVsLmFwcGVuZFlvdXJzZWxmKHBhcmVudCk7XG4gICAgICAvLyBwYXJlbnQuYXBwZW5kQ2hpbGQoZWwuZWwpO1xuICAgIH0pO1xuXG4gICAgLy8gaWYgKCFwcmVsb2FkTW9kZSkge1xuICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICBraW5kOiBcIlBBR0VfRU5URVJfRVZFTlRcIixcbiAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgIHByb2R1Y2VyOiBcIkRQYWdlXCIsXG4gICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgZGF0YTogeyBwYWdlSWQ6IHRoaXMuaWQgfSxcbiAgICB9KTtcbiAgICAvLyB9XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuZWxlbWVudHMuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgIGVsLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxvZygpOiB2b2lkIHtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLlRBRyArICdzY2FsZSAtICcgKyB0aGlzLnNjYWxlKTtcbiAgfVxuXG4gIGdldCBpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5kdG8uaWQ7XG4gIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgU2NhbGVTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlSGVpZ2h0O1xuICBwcml2YXRlIHJlYWRvbmx5IGJhc2VXaWR0aDtcbiAgcHJpdmF0ZSBjb250YWluZXJIZWlnaHQgPSAxMzAwO1xuICBwcml2YXRlIGNvbnRhaW5lcldpZHRoID0gMTMwMDtcblxuICBnZXQgc2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NjYWxlO1xuICB9XG5cbiAgZ2V0IHBhZ2VIZWlnaHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZUhlaWdodCAqIHRoaXMuc2NhbGU7XG4gIH1cbiAgZ2V0IHBhZ2VXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlV2lkdGggKiB0aGlzLl9zY2FsZTtcbiAgfVxuXG4gIHByaXZhdGUgX3NjYWxlID0gMTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmliZXJzID0gbmV3IFNldDwoc2NhbGU6IG51bWJlcikgPT4gdm9pZD4oKTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IHsgYmFzZUhlaWdodDogbnVtYmVyOyBiYXNlV2lkdGg6IG51bWJlcjsgY29udGFpbmVySGVpZ2h0OiBudW1iZXI7IGNvbnRhaW5lcldpZHRoOiBudW1iZXIgfSkge1xuICAgIHRoaXMuYmFzZUhlaWdodCA9IGNvbmZpZy5iYXNlSGVpZ2h0O1xuICAgIHRoaXMuYmFzZVdpZHRoID0gY29uZmlnLmJhc2VXaWR0aDtcbiAgICB0aGlzLmNvbnRhaW5lckhlaWdodCA9IGNvbmZpZy5jb250YWluZXJIZWlnaHQ7XG4gICAgdGhpcy5jb250YWluZXJXaWR0aCA9IGNvbmZpZy5jb250YWluZXJXaWR0aDtcbiAgICB0aGlzLnVwZGF0ZVNjYWxlKCk7XG4gIH1cblxuICBzZXRDb250YWluZXJCb3VuZHMoYm91bmRzOiB7IGhlaWdodDogbnVtYmVyOyB3aWR0aDogbnVtYmVyIH0pIHtcbiAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gYm91bmRzLndpZHRoO1xuICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gYm91bmRzLmhlaWdodDtcbiAgICB0aGlzLnVwZGF0ZVNjYWxlKCk7XG4gIH1cbiAgcHJpdmF0ZSB1cGRhdGVTY2FsZSgpIHtcbiAgICBjb25zdCBzY2FsZUZuID0gU2NhbGUuY2FsYyh0aGlzLmJhc2VIZWlnaHQsIHRoaXMuYmFzZVdpZHRoKTtcbiAgICBjb25zdCBzY2FsZSA9IHNjYWxlRm4oeyBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0LCB3aWR0aDogdGhpcy5jb250YWluZXJXaWR0aCB9KTtcbiAgICBjb25zdCBoYXNDaGFuZ2VkID0gdGhpcy5zY2FsZSAhPT0gc2NhbGU7XG4gICAgdGhpcy5fc2NhbGUgPSBzY2FsZTtcbiAgICBpZiAoaGFzQ2hhbmdlZCkge1xuICAgICAgdGhpcy5zdWJzY3JpYmVycy5mb3JFYWNoKChmbikgPT4ge1xuICAgICAgICBmbih0aGlzLl9zY2FsZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvbkNoYW5nZShzY2FsZUNoYW5nZUhhbmRsZXI6IChzY2FsZTogbnVtYmVyKSA9PiB2b2lkLCBzdWJzY3JpYmVySWQ6IHN0cmluZykge1xuICAgIC8vIGNvbnNvbGUubG9nKHN1YnNjcmliZXJJZCk7XG4gICAgdGhpcy5zdWJzY3JpYmVycy5hZGQoc2NhbGVDaGFuZ2VIYW5kbGVyKTtcbiAgICBzY2FsZUNoYW5nZUhhbmRsZXIodGhpcy5fc2NhbGUpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0aGlzLnN1YnNjcmliZXJzLmRlbGV0ZShzY2FsZUNoYW5nZUhhbmRsZXIpO1xuICAgIH07XG4gIH1cbn1cbmV4cG9ydCBuYW1lc3BhY2UgU2NhbGUge1xuICBleHBvcnQgY29uc3QgY2FsYyA9IChiYXNlSGVpZ2h0OiBudW1iZXIsIGJhc2VXaWR0aDogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIChjb250YWluZXI6IHsgaGVpZ2h0OiBudW1iZXI7IHdpZHRoOiBudW1iZXIgfSkgPT4ge1xuICAgICAgY29uc3QgaGVpZ2h0UmF0aW8gPSBjb250YWluZXIuaGVpZ2h0IC8gYmFzZUhlaWdodDtcbiAgICAgIGNvbnN0IHdpZHRoUmF0aW8gPSBjb250YWluZXIud2lkdGggLyBiYXNlV2lkdGg7XG4gICAgICByZXR1cm4gTWF0aC5taW4oaGVpZ2h0UmF0aW8sIHdpZHRoUmF0aW8pO1xuICAgIH07XG4gIH07XG5cbiAgdHlwZSBTY2FsZVBvc0lucHV0ID0geyB4OiBudW1iZXI7IHk6IG51bWJlcjsgaDogbnVtYmVyOyB3OiBudW1iZXIgfTtcblxuICBleHBvcnQgY29uc3Qgc2NhbGVGdW5jdGlvbkNyZWF0b3IgPSAoc2NhbGU6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiAodmFsdWU6IG51bWJlcikgPT4gdmFsdWUgKiBzY2FsZTtcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBEQXVkaW9EdG8sIERJbWdEdG8sIERWaWRlb0R0byB9IGZyb20gXCIuLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVByb3ZpZGVyIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBSRVNPVVJDRV9QUk9WSURFUiBdOiBcIjtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHZpZGVvTWFwID0gbmV3IE1hcDxzdHJpbmcsIERWaWRlb0R0bz4oKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGF1ZGlvTWFwID0gbmV3IE1hcDxzdHJpbmcsIERBdWRpb0R0bz4oKTtcbiAgICBjb25zdHJ1Y3RvcihkYXRhOiB7IHZpZGVvczogUmVhZG9ubHlBcnJheTxEVmlkZW9EdG8+OyBhdWRpbzogUmVhZG9ubHlBcnJheTxEQXVkaW9EdG8+IH0pIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyBcIlZJREVPX0NPVU5UIFwiICsgZGF0YS52aWRlb3MubGVuZ3RoKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyBcIkFVRElPX0NPVU5UIFwiICsgZGF0YS5hdWRpby5sZW5ndGgpO1xuICAgICAgICBkYXRhLnZpZGVvcy5mb3JFYWNoKCh2aWRlbykgPT4ge1xuICAgICAgICAgICAgdGhpcy52aWRlb01hcC5zZXQodmlkZW8uaWQsIHZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEuYXVkaW8uZm9yRWFjaCgoYXVkaW8pID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXVkaW9NYXAuc2V0KGF1ZGlvLmlkLCBhdWRpbyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldEF1ZGlvQnlJZChpZDogc3RyaW5nKTogREF1ZGlvRHRvIHwgZmFsc2Uge1xuICAgICAgICBjb25zdCBtYXliZUF1ZGlvID0gdGhpcy5hdWRpb01hcC5nZXQoaWQpO1xuICAgICAgICBpZiAoIW1heWJlQXVkaW8pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IodGhpcy5UQUcgKyBcIkF1ZGlvIGJ5IGlkIFwiICsgaWQgKyBcIiBkb250IGV4aXN0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXliZUF1ZGlvID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldFZpZGVvQnlJZChpZDogc3RyaW5nKTogRFZpZGVvRHRvIHwgZmFsc2Uge1xuICAgICAgICBjb25zdCBtYXliZVZpZGVvID0gdGhpcy52aWRlb01hcC5nZXQoaWQpO1xuICAgICAgICBpZiAoIW1heWJlVmlkZW8pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IodGhpcy5UQUcgKyBcIlZpZGVvIGJ5IGlkIFwiICsgaWQgKyBcIiBkb250IGV4aXN0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXliZVZpZGVvID8/IGZhbHNlO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgT2s8VD4gaW1wbGVtZW50cyBJUmVzdWx0PFQ+IHtcbiAgICBjb25zdHJ1Y3RvcihyZWFkb25seSB2YWx1ZTogVCkge31cbiAgICBpc09rKCk6IHRoaXMgaXMgT2s8VD4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaXNGYWlsdXJlKCk6IHRoaXMgaXMgRmFpbHVyZTxUPiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBtYXA8QT4oZjogKHQ6IFQpID0+IEEpOiBJUmVzdWx0PEE+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBmKHRoaXMudmFsdWUpO1xuICAgICAgICByZXR1cm4gbmV3IE9rPEE+KHZhbHVlKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGYWlsdXJlPFQ+IGltcGxlbWVudHMgSVJlc3VsdDxUPiB7XG4gICAgY29uc3RydWN0b3IocmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nKSB7fVxuICAgIGlzRmFpbHVyZSgpOiB0aGlzIGlzIEZhaWx1cmU8VD4ge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpc09rKCk6IHRoaXMgaXMgT2s8VD4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbWFwPEE+KF9mOiAodDogVCkgPT4gQSk6IElSZXN1bHQ8QT4ge1xuICAgICAgICByZXR1cm4gbmV3IEZhaWx1cmU8QT4odGhpcy5tZXNzYWdlKTtcbiAgICB9XG59XG5cbmludGVyZmFjZSBJUmVzdWx0PFQ+IHtcbiAgICBpc09rKCk6IHRoaXMgaXMgT2s8VD47XG4gICAgaXNGYWlsdXJlKCk6IHRoaXMgaXMgRmFpbHVyZTxUPjtcbiAgICBtYXA8QT4oZjogKHQ6IFQpID0+IEEpOiBJUmVzdWx0PEE+O1xufVxuXG5leHBvcnQgdHlwZSBSZXN1bHQ8VD4gPSBGYWlsdXJlPFQ+IHwgT2s8VD47XG5leHBvcnQgbmFtZXNwYWNlIFJlc3VsdCB7XG4gICAgZXhwb3J0IGNvbnN0IG9rID0gPFQ+KHZhbHVlOiBUKSA9PiBuZXcgT2s8VD4odmFsdWUpO1xuICAgIGV4cG9ydCBjb25zdCBmYWlsdXJlID0gPFQ+KG1lc3NhZ2U6IHN0cmluZykgPT4gbmV3IEZhaWx1cmU8VD4obWVzc2FnZSk7XG59XG4iLCAiaW1wb3J0IHsgRmFjdCB9IGZyb20gXCIuLi9ydWxlcy9mYWN0XCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcnVsZXMvY29uZGl0aW9uXCI7XG5pbXBvcnQgeyBERXZlbnQgfSBmcm9tIFwiLi4vZXZlbnRzL0RFdmVudHNcIjtcbmltcG9ydCB7IFN0YXRlQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuXG5leHBvcnQgbmFtZXNwYWNlIERTdGF0ZSB7XG4gICAgaW50ZXJmYWNlIFByb3BEZWZpbml0aW9uPFR5cGVOYW1lLCBUeXBlIGV4dGVuZHMgc3RyaW5nIHwgbnVtYmVyPiB7XG4gICAgICAgIHJlYWRvbmx5IF90eXBlOiBUeXBlTmFtZTtcbiAgICAgICAgcmVhZG9ubHkgcHJvcE5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgcHJvcERlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IGluaXRpYWxWYWx1ZT86IFR5cGU7XG4gICAgICAgIHJlYWRvbmx5IG9wdGlvbnM/OiBSZWFkb25seUFycmF5PFByb3BWYWx1ZTxUeXBlPj47XG4gICAgfVxuXG4gICAgZXhwb3J0IHR5cGUgTnVtZXJpY1Byb3AgPSBQcm9wRGVmaW5pdGlvbjxcIm51bWJlclwiLCBudW1iZXI+O1xuICAgIGV4cG9ydCB0eXBlIFN0cmluZ1Byb3AgPSBQcm9wRGVmaW5pdGlvbjxcInN0cmluZ1wiLCBzdHJpbmc+O1xuXG4gICAgZXhwb3J0IGludGVyZmFjZSBmcm9tRXZlbnRIYW5kbGVyIHtcbiAgICAgICAgcmVhZG9ubHkgb25FdmVudDogREV2ZW50W1wia2luZFwiXTtcbiAgICAgICAgcmVhZG9ubHkgdGhlbkV4ZWN1dGU6IFJlYWRvbmx5QXJyYXk8U3RhdGVDb21tYW5kPjtcbiAgICB9XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIFByb3BWYWx1ZTxUPiB7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBUO1xuICAgICAgICByZWFkb25seSB2YWx1ZUxhYmVsOiBzdHJpbmc7XG4gICAgfVxuICAgIGV4cG9ydCB0eXBlIFByb3AgPSBOdW1lcmljUHJvcCB8IFN0cmluZ1Byb3A7XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIFNldFN0cmluZ011dGF0aW9uIHtcbiAgICAgICAgcmVhZG9ubHkga2luZDogXCJzZXQtc3RyaW5nXCI7XG4gICAgICAgIHJlYWRvbmx5IHByb3BOYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgZXhwb3J0IGludGVyZmFjZSBJbmNyZW1lbnROdW1iZXJNdXRhdGlvbiB7XG4gICAgICAgIHJlYWRvbmx5IGtpbmQ6IFwiaW5jcmVtZW50LW51bWJlclwiO1xuICAgICAgICByZWFkb25seSBwcm9wTmFtZTogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBzdGVwU2l6ZTogbnVtYmVyO1xuICAgICAgICByZWFkb25seSBpZk5vdEV4aXN0VGhlblNldFRvOiBudW1iZXI7XG4gICAgfVxuICAgIGV4cG9ydCBpbnRlcmZhY2UgRGVjcmVtZW50TnVtYmVyTXV0YXRpb24ge1xuICAgICAgICByZWFkb25seSBraW5kOiBcImRlY3JlbWVudC1udW1iZXJcIjtcbiAgICAgICAgcmVhZG9ubHkgcHJvcE5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgc3RlcFNpemU6IG51bWJlcjtcbiAgICAgICAgcmVhZG9ubHkgaWZOb3RFeGlzdFRoZW5TZXRUbzogbnVtYmVyO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2V0TnVtYmVyTXV0YXRpb24ge1xuICAgICAgICByZWFkb25seSBraW5kOiBcInNldC1udW1iZXJcIjtcbiAgICAgICAgcmVhZG9ubHkgcHJvcE5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgdmFsdWU6IG51bWJlcjtcbiAgICB9XG4gICAgZXhwb3J0IHR5cGUgTnVtYmVyTXV0YXRpb25zID0gSW5jcmVtZW50TnVtYmVyTXV0YXRpb24gfCBEZWNyZW1lbnROdW1iZXJNdXRhdGlvbiB8IFNldE51bWJlck11dGF0aW9uO1xuXG4gICAgZXhwb3J0IHR5cGUgU3RhdGVNdXRhdGlvbiA9IFNldFN0cmluZ011dGF0aW9uIHwgTnVtYmVyTXV0YXRpb25zO1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzTnVtYmVyTXV0YXRpb24gPSAobXV0YXRpb25zOiBTdGF0ZU11dGF0aW9uKTogbXV0YXRpb25zIGlzIE51bWJlck11dGF0aW9ucyA9PiB7XG4gICAgICAgIGlmICghbXV0YXRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgbXV0YXRpb25zLmtpbmQgPT09IFwic2V0LW51bWJlclwiIHx8XG4gICAgICAgICAgICBtdXRhdGlvbnMua2luZCA9PT0gXCJkZWNyZW1lbnQtbnVtYmVyXCIgfHxcbiAgICAgICAgICAgIG11dGF0aW9ucy5raW5kID09PSBcImluY3JlbWVudC1udW1iZXJcIlxuICAgICAgICApO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaXNTdHJpbmdNdXRhdGlvbiA9IChtdXRhdGlvbjogU3RhdGVNdXRhdGlvbik6IG11dGF0aW9uIGlzIFNldFN0cmluZ011dGF0aW9uID0+IHtcbiAgICAgICAgcmV0dXJuIG11dGF0aW9uICYmIG11dGF0aW9uLmtpbmQgPT09IFwic2V0LXN0cmluZ1wiO1xuICAgIH07XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIFN0YXRlUXVlcnkge1xuICAgICAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IGNvbmRpdGlvbjogQ29uZGl0aW9uO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgU3RhdGVRdWVyeVJlc3VsdCB7XG4gICAgICAgIHJlYWRvbmx5IHF1ZXJ5TmFtZTogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBwcmV2OiBib29sZWFuO1xuICAgICAgICByZWFkb25seSBjdXJyOiBib29sZWFuO1xuICAgIH1cblxuICAgIGV4cG9ydCBjb25zdCBudW1lcmljUHJvcFRvRmFjdCA9IChwcm9wOiBOdW1lcmljUHJvcCwgdmFsdWU6IG51bWJlcikgPT4ge1xuICAgICAgICBjb25zdCBmYWN0OiBGYWN0Lk51bWVyaWMgPSB7XG4gICAgICAgICAgICBraW5kOiBcIm51bWVyaWMtZmFjdFwiLFxuICAgICAgICAgICAgcmVmZXJlbmNlSWQ6IHByb3AucHJvcE5hbWUsXG4gICAgICAgICAgICByZWZlcmVuY2VMYWJlbDogcHJvcC5wcm9wRGVzY3JpcHRpb24gPz8gXCIgW1NUQVRFX1BST1BFUlRZXSA6IFwiICsgcHJvcC5wcm9wTmFtZSxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgbGFiZWw6IFwiIFtWQUxVRV0gOiBcIiArIHZhbHVlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gZmFjdDtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IHN0cmluZ1Byb3BUb0ZhY3QgPSAocHJvcDogU3RyaW5nUHJvcCwgdmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBmYWN0OiBGYWN0LlN0cmluZyA9IHtcbiAgICAgICAgICAgIGtpbmQ6IFwic3RyaW5nLWZhY3RcIixcbiAgICAgICAgICAgIHJlZmVyZW5jZUlkOiBwcm9wLnByb3BOYW1lLFxuICAgICAgICAgICAgcmVmZXJlbmNlTGFiZWw6IFwiIFtTVEFURV9QUk9QRVJUWV0gOiBcIiArIHByb3AucHJvcE5hbWUsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGxhYmVsOiBcIiBbVkFMVUVdIDogXCIgKyB2YWx1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZhY3Q7XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgeyBGYWN0IH0gZnJvbSBcIi4uL3J1bGVzL2ZhY3RcIjtcbmltcG9ydCB7IFJlc3VsdCB9IGZyb20gXCIuLi9jb21tb24vcmVzdWx0XCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcnVsZXMvY29uZGl0aW9uXCI7XG5pbXBvcnQgeyBEU3RhdGUgfSBmcm9tIFwiLi9Ec3RhdGVcIjtcbmltcG9ydCB7IERFdmVudERpc3BhdGNoZXIgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgUXVlcnlDaGFuZ2VkRXZlbnQgfSBmcm9tIFwiLi4vZXZlbnRzL0RFdmVudHNcIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5cbmV4cG9ydCBjbGFzcyBTdGF0ZVNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiIFsgU1RBVEVfU0VSVklDRSBdIDpcIjtcbiAgcHJpdmF0ZSByZWFkb25seSBmYWN0c1N0cmluZyA9IG5ldyBNYXA8c3RyaW5nLCBGYWN0LlN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBmYWN0c051bWVyaWMgPSBuZXcgTWFwPHN0cmluZywgRmFjdC5OdW1lcmljPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb3BEZWZpbml0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBEU3RhdGUuUHJvcD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBxdWVyaWVzID0gbmV3IE1hcDxzdHJpbmcsIHsgcXVlcnk6IERTdGF0ZS5TdGF0ZVF1ZXJ5OyBsYXN0UmVzdWx0OiBib29sZWFuIH0+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdW5zdWJzY3JpYmVDb21tYW5kczogKCkgPT4gdm9pZDtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBldmVudEJ1czogREV2ZW50RGlzcGF0Y2hlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRCdXM6IERDb21tYW5kQnVzLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IFJlYWRvbmx5QXJyYXk8RFN0YXRlLlByb3A+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcXVlcnlMaXN0OiBSZWFkb25seUFycmF5PERTdGF0ZS5TdGF0ZVF1ZXJ5PiA9IFtdLFxuICApIHtcbiAgICBwcm9wcy5mb3JFYWNoKChwcm9wKSA9PiB7XG4gICAgICB0aGlzLnJlZ2lzdGVyUHJvcGVydHkocHJvcCk7XG4gICAgfSk7XG4gICAgY29uc3QgZmFjdHMgPSB0aGlzLmdldEFsbEZhY3RzKCk7XG4gICAgcXVlcnlMaXN0LmZvckVhY2goKGRlZmluaXRpb24pID0+IHtcbiAgICAgIHRoaXMucmVnaXN0ZXJRdWVyeShkZWZpbml0aW9uLCBmYWN0cyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmV2YWx1YXRlUXVlcmllcygpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVDb21tYW5kcyA9IHRoaXMuY29tbWFuZEJ1cy5zdWJzY3JpYmUoKGNvbW1hbmQpID0+IHtcbiAgICAgIGlmIChjb21tYW5kLmtpbmQgPT09IFwiU1RBVEVfTVVUQVRFX0NPTU1BTkRcIikge1xuICAgICAgICB0aGlzLm11dGF0aW9uKGNvbW1hbmQucGF5bG9hZC5tdXRhdGlvbik7XG4gICAgICB9XG4gICAgfSwgdGhpcy5UQUcpO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLnVuc3Vic2NyaWJlQ29tbWFuZHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJRdWVyeShxdWVyeTogRFN0YXRlLlN0YXRlUXVlcnksIGN1cnJlbnRGYWN0czogUmVhZG9ubHlBcnJheTxGYWN0Pikge1xuICAgIGNvbnN0IHJlc3VsdCA9IENvbmRpdGlvbi5ldmFsdWF0ZShxdWVyeS5jb25kaXRpb24sIGN1cnJlbnRGYWN0cyk7XG4gICAgdGhpcy5xdWVyaWVzLnNldChxdWVyeS5uYW1lLCB7IHF1ZXJ5OiBxdWVyeSwgbGFzdFJlc3VsdDogcmVzdWx0IH0pO1xuICAgIHRoaXMuZW1pdFF1ZXJ5Q2hhbmdlZEV2ZW50KHsgcXVlcnlOYW1lOiBxdWVyeS5uYW1lLCBwcmV2OiByZXN1bHQsIGN1cnI6IHJlc3VsdCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJQcm9wZXJ0eShwcm9wOiBEU3RhdGUuUHJvcCkge1xuICAgIGlmICh0aGlzLnByb3BEZWZpbml0aW9ucy5oYXMocHJvcC5wcm9wTmFtZSkpIHtcbiAgICAgIC8vIExPR0dJTkdcbiAgICAgIGNvbnNvbGUud2FybihcIlByb3AgZXhjaXN0cyBhbHJlYWR5LlwiLCBwcm9wLnByb3BOYW1lKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb3BEZWZpbml0aW9ucy5zZXQocHJvcC5wcm9wTmFtZSwgcHJvcCk7XG5cbiAgICBpZiAocHJvcC5pbml0aWFsVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwcm9wLl90eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCBmYWN0ID0gRFN0YXRlLnN0cmluZ1Byb3BUb0ZhY3QocHJvcCwgcHJvcC5pbml0aWFsVmFsdWUpO1xuICAgICAgdGhpcy5mYWN0c1N0cmluZy5zZXQoZmFjdC5yZWZlcmVuY2VJZCwgZmFjdCk7XG4gICAgfVxuICAgIGlmIChwcm9wLl90eXBlID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjb25zdCBmYWN0ID0gRFN0YXRlLm51bWVyaWNQcm9wVG9GYWN0KHByb3AsIHByb3AuaW5pdGlhbFZhbHVlKTtcbiAgICAgIHRoaXMuZmFjdHNOdW1lcmljLnNldChmYWN0LnJlZmVyZW5jZUlkLCBmYWN0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG11dGF0ZVN0cmluZyhwcm9wOiBEU3RhdGUuU3RyaW5nUHJvcCwgdmFsdWU6IHN0cmluZykge1xuICAgIGNvbnN0IGN1cnIgPSB0aGlzLmZhY3RzU3RyaW5nLmdldChwcm9wLnByb3BOYW1lKTtcbiAgICBpZiAoY3Vycikge1xuICAgICAgY29uc3QgdXBkYXRlZDogRmFjdC5TdHJpbmcgPSB7IC4uLmN1cnIsIHZhbHVlIH07XG4gICAgICB0aGlzLnNldEZhY3QodXBkYXRlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNyZWF0ZWQ6IEZhY3QuU3RyaW5nID0ge1xuICAgICAgICBraW5kOiBcInN0cmluZy1mYWN0XCIsXG4gICAgICAgIHJlZmVyZW5jZUlkOiBwcm9wLnByb3BOYW1lLFxuICAgICAgICByZWZlcmVuY2VMYWJlbDogXCJsYWJlbCBmb3I6IFwiICsgcHJvcC5wcm9wTmFtZSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGxhYmVsOiBcIlZhbHVlOiBcIiArIHZhbHVlLFxuICAgICAgfTtcbiAgICAgIHRoaXMuc2V0RmFjdChjcmVhdGVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG11dGF0ZU51bWJlcihwcm9wOiBEU3RhdGUuTnVtZXJpY1Byb3AsIG11dGF0aW9uOiBEU3RhdGUuTnVtYmVyTXV0YXRpb25zKSB7XG4gICAgY29uc3QgY3VyciA9IHRoaXMuZmFjdHNOdW1lcmljLmdldChwcm9wLnByb3BOYW1lKTtcbiAgICBpZiAoIWN1cnIpIHtcbiAgICAgIHN3aXRjaCAobXV0YXRpb24ua2luZCkge1xuICAgICAgICBjYXNlIFwic2V0LW51bWJlclwiOlxuICAgICAgICAgIHRoaXMuc2V0RmFjdChEU3RhdGUubnVtZXJpY1Byb3BUb0ZhY3QocHJvcCwgbXV0YXRpb24udmFsdWUpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRlY3JlbWVudC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoRFN0YXRlLm51bWVyaWNQcm9wVG9GYWN0KHByb3AsIG11dGF0aW9uLmlmTm90RXhpc3RUaGVuU2V0VG8pKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImluY3JlbWVudC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoRFN0YXRlLm51bWVyaWNQcm9wVG9GYWN0KHByb3AsIG11dGF0aW9uLmlmTm90RXhpc3RUaGVuU2V0VG8pKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBjb25zdCBjaGVjazogbmV2ZXIgPSBtdXRhdGlvbjtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGN1cnIpIHtcbiAgICAgIHN3aXRjaCAobXV0YXRpb24ua2luZCkge1xuICAgICAgICBjYXNlIFwic2V0LW51bWJlclwiOlxuICAgICAgICAgIHRoaXMuc2V0RmFjdCh7IC4uLmN1cnIsIHZhbHVlOiBtdXRhdGlvbi52YWx1ZSB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRlY3JlbWVudC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoeyAuLi5jdXJyLCB2YWx1ZTogY3Vyci52YWx1ZSAtIG11dGF0aW9uLnN0ZXBTaXplIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiaW5jcmVtZW50LW51bWJlclwiOlxuICAgICAgICAgIHRoaXMuc2V0RmFjdCh7IC4uLmN1cnIsIHZhbHVlOiBjdXJyLnZhbHVlICsgbXV0YXRpb24uc3RlcFNpemUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gbXV0YXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZVF1ZXJpZXMoKTogUmVhZG9ubHlBcnJheTx7IHF1ZXJ5TmFtZTogc3RyaW5nOyBwcmV2OiBib29sZWFuOyBjdXJyOiBib29sZWFuOyBkaWRDaGFuZ2U6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IGZhY3RzID0gdGhpcy5nZXRBbGxGYWN0cygpO1xuICAgIGNvbnN0IGFsbDogQXJyYXk8eyBxdWVyeU5hbWU6IHN0cmluZzsgcHJldjogYm9vbGVhbjsgY3VycjogYm9vbGVhbjsgZGlkQ2hhbmdlOiBib29sZWFuIH0+ID0gW107XG4gICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKHEpID0+IHtcbiAgICAgIGNvbnN0IHByZXYgPSBxLmxhc3RSZXN1bHQ7XG5cbiAgICAgIGNvbnN0IGN1cnIgPSBDb25kaXRpb24uZXZhbHVhdGUocS5xdWVyeS5jb25kaXRpb24sIGZhY3RzKTtcbiAgICAgIGNvbnN0IGRpZENoYW5nZSA9IHByZXYgIT09IGN1cnI7XG4gICAgICBxLmxhc3RSZXN1bHQgPSBjdXJyO1xuICAgICAgYWxsLnB1c2goeyBxdWVyeU5hbWU6IHEucXVlcnkubmFtZSwgcHJldiwgY3VyciwgZGlkQ2hhbmdlIH0pO1xuICAgICAgLy8gZGVmLnZhbHVlID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFsbDtcbiAgfVxuXG4gIHByaXZhdGUgbXV0YXRpb24obXV0YXRpb246IERTdGF0ZS5TdGF0ZU11dGF0aW9uKTogeyBzdWNjZXNzOiBib29sZWFuIH0ge1xuICAgIGNvbnN0IHByb3BEZWYgPSB0aGlzLnByb3BEZWZpbml0aW9ucy5nZXQobXV0YXRpb24ucHJvcE5hbWUpO1xuICAgIGlmICghcHJvcERlZikge1xuICAgICAgLy8gVE9ETyBMT0dHSU5HXG4gICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIGlmIChwcm9wRGVmLl90eXBlID09PSBcInN0cmluZ1wiICYmIERTdGF0ZS5pc1N0cmluZ011dGF0aW9uKG11dGF0aW9uKSkge1xuICAgICAgdGhpcy5tdXRhdGVTdHJpbmcocHJvcERlZiwgbXV0YXRpb24udmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChwcm9wRGVmLl90eXBlID09PSBcIm51bWJlclwiICYmIERTdGF0ZS5pc051bWJlck11dGF0aW9uKG11dGF0aW9uKSkge1xuICAgICAgdGhpcy5tdXRhdGVOdW1iZXIocHJvcERlZiwgbXV0YXRpb24pO1xuICAgIH1cbiAgICBjb25zdCBxdWVyeVJlc3VsdHMgPSB0aGlzLmV2YWx1YXRlUXVlcmllcygpO1xuICAgIGNvbnN0IGNoYW5nZWRSZXN1bHQgPSBxdWVyeVJlc3VsdHMuZmlsdGVyKChyKSA9PiByLmRpZENoYW5nZSk7XG4gICAgY2hhbmdlZFJlc3VsdC5mb3JFYWNoKChyZXMpID0+IHtcbiAgICAgIHRoaXMuZW1pdFF1ZXJ5Q2hhbmdlZEV2ZW50KHsgcXVlcnlOYW1lOiByZXMucXVlcnlOYW1lLCBwcmV2OiByZXMucHJldiwgY3VycjogcmVzLmN1cnIgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gIH1cblxuICBwcml2YXRlIGVtaXRRdWVyeUNoYW5nZWRFdmVudChkYXRhOiB7IHF1ZXJ5TmFtZTogc3RyaW5nOyBwcmV2OiBib29sZWFuOyBjdXJyOiBib29sZWFuIH0pIHtcbiAgICBjb25zdCBxdWVyeUNoYW5nZWRFdmVudDogUXVlcnlDaGFuZ2VkRXZlbnQgPSB7XG4gICAgICBraW5kOiBcIlNUQVRFX1FVRVJZX1JFU1VMVF9DSEFOR0VEX0VWRU5UXCIsXG4gICAgICBwcm9kdWNlcjogXCJTVEFURS1TRVJWSUNFXCIsXG4gICAgICBwcm9kdWNlcklkOiBcIlNUQVRFLVNFUlZJQ0VcIixcbiAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgIGRhdGEsXG4gICAgfTtcbiAgICBjb25zdCB7IHF1ZXJ5TmFtZSwgY3VyciwgcHJldiB9ID0gcXVlcnlDaGFuZ2VkRXZlbnQuZGF0YTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIlsgUVVFUllfQ0hBTkdFRCBcIiArIHF1ZXJ5TmFtZSArIFwiXSA6IFwiICsgcHJldiArIFwiIC0+IFwiICsgY3Vycik7XG4gICAgdGhpcy5ldmVudEJ1cy5lbWl0KHF1ZXJ5Q2hhbmdlZEV2ZW50KTtcbiAgfVxuXG4gIGdldFByb3BBc0ZhY3QocHJvcE5hbWU6IHN0cmluZyk6IFJlc3VsdDxGYWN0PiB7XG4gICAgY29uc3QgcHJvcERlZiA9IHRoaXMucHJvcERlZmluaXRpb25zLmdldChwcm9wTmFtZSk7XG4gICAgaWYgKCFwcm9wRGVmKSB7XG4gICAgICByZXR1cm4gUmVzdWx0LmZhaWx1cmUoXG4gICAgICAgIFwiTm8gZGVmaW5pdGlvbiBmb3JtIHByb3BlcnR5IG55IG5hbWUgXCIgKyBwcm9wTmFtZSArIFwiIGlzIHJlZ2lzdGVyZWQuIChQYXNzIGluIGNvbnN0cnVjdG9yLilcIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5mYWN0c1N0cmluZy5nZXQocHJvcE5hbWUpID8/IHRoaXMuZmFjdHNOdW1lcmljLmdldChwcm9wTmFtZSk7XG5cbiAgICByZXR1cm4gdmFsdWUgPyBSZXN1bHQub2sodmFsdWUpIDogUmVzdWx0LmZhaWx1cmUoXCJQcm9wZXJ0eSBcIiArIHByb3BOYW1lICsgXCIgaGFzIG5vIHZhbHVlLlwiKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0RmFjdChmYWN0OiBGYWN0KSB7XG4gICAgc3dpdGNoIChmYWN0LmtpbmQpIHtcbiAgICAgIGNhc2UgXCJudW1lcmljLWZhY3RcIjpcbiAgICAgICAgdGhpcy5mYWN0c051bWVyaWMuc2V0KGZhY3QucmVmZXJlbmNlSWQsIGZhY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzdHJpbmctZmFjdFwiOlxuICAgICAgICB0aGlzLmZhY3RzU3RyaW5nLnNldChmYWN0LnJlZmVyZW5jZUlkLCBmYWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb25zdCBjaGVjazogbmV2ZXIgPSBmYWN0O1xuICAgIH1cbiAgfVxuXG4gIGdldFN0YXRlKCkge1xuICAgIGNvbnN0IHByb3BzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBudWxsIHwgYm9vbGVhbj4gPSB7fTtcbiAgICB0aGlzLnByb3BEZWZpbml0aW9ucy5mb3JFYWNoKChkZWYpID0+IHtcbiAgICAgIGxldCB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgICBjb25zdCBtYXliZUZhY3QgPSB0aGlzLmdldEFueUZhY3QoZGVmLnByb3BOYW1lKTtcbiAgICAgIGlmIChtYXliZUZhY3QpIHtcbiAgICAgICAgdmFsdWUgPSBtYXliZUZhY3QudmFsdWU7XG4gICAgICB9XG4gICAgICBwcm9wc1tkZWYucHJvcE5hbWVdID0gdmFsdWU7XG4gICAgfSk7XG4gICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKHF1ZXJ5KSA9PiB7XG4gICAgICBwcm9wc1txdWVyeS5xdWVyeS5uYW1lXSA9IHF1ZXJ5Lmxhc3RSZXN1bHQ7XG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9wTmFtZXMgPSBPYmplY3Qua2V5cyhwcm9wcyk7XG4gICAgY29uc3QgcHJvcENvdW50ID0gcHJvcE5hbWVzLmxlbmd0aDtcbiAgICBjb25zdCBwcm9wQXJyYXkgPSBbLi4udGhpcy5wcm9wRGVmaW5pdGlvbnMudmFsdWVzKCldO1xuXG4gICAgcmV0dXJuIHsgcHJvcENvdW50LCBwcm9wTmFtZXMsIHByb3BBcnJheSwgc3RhdGU6IHByb3BzIH07XG4gIH1cblxuICBwcml2YXRlIGdldEFueUZhY3QocHJvcE5hbWU6IHN0cmluZyk6IEZhY3QgfCBmYWxzZSB7XG4gICAgcmV0dXJuIHRoaXMuZmFjdHNTdHJpbmcuZ2V0KHByb3BOYW1lKSA/PyB0aGlzLmZhY3RzTnVtZXJpYy5nZXQocHJvcE5hbWUpID8/IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBbGxGYWN0cygpOiBSZWFkb25seUFycmF5PEZhY3Q+IHtcbiAgICByZXR1cm4gWy4uLnRoaXMuZmFjdHNOdW1lcmljLnZhbHVlcygpLCAuLi50aGlzLmZhY3RzU3RyaW5nLnZhbHVlcygpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaWxsIGNoZWNrIHRoYXQgYWxsIHJlZmVyZW5jZUlkcyB1c2VkIGluIENvbmRpdGlvbiBpcyByZWdpc3RlcmVkIGFzIGEgdmFsaWQgcHJvcGVydHkgaW4gc3RhdGUuXG4gICAqIEBwYXJhbSBjb25kaXRpb25cbiAgICovXG4gIGNhbkJlTWF0Y2hlZChjb25kaXRpb246IENvbmRpdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNpbXBsZUNvbmRpdGlvbnMgPSBDb25kaXRpb24uZ2V0QWxsU2ltcGxlQ29uZGl0aW9ucyhjb25kaXRpb24pO1xuICAgIGxldCBoYXNBbGwgPSB0cnVlO1xuXG4gICAgY29uc3QgYWxsSWRzID0gc2ltcGxlQ29uZGl0aW9ucy5tYXAoKGMpID0+IGMucmVmZXJlbmNlSWQpO1xuXG4gICAgY29uc3QgbWlzc2luZ0lkczogc3RyaW5nW10gPSBbXTtcbiAgICBhbGxJZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgIGlmICghdGhpcy5wcm9wRGVmaW5pdGlvbnMuaGFzKGlkKSkge1xuICAgICAgICBoYXNBbGwgPSBmYWxzZTtcbiAgICAgICAgbWlzc2luZ0lkcy5wdXNoKGlkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLlRBRywgbWlzc2luZ0lkcyk7XG5cbiAgICByZXR1cm4gaGFzQWxsO1xuICB9XG4gIGlzTWF0Y2hlZChjb25kaXRpb246IENvbmRpdGlvbikge1xuICAgIHJldHVybiBDb25kaXRpb24uZXZhbHVhdGUoY29uZGl0aW9uLCB0aGlzLmdldEFsbEZhY3RzKCkpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgU2NoZW1hRHRvIH0gZnJvbSBcIi4uL2R0by9TY2hlbWFEdG9cIjtcbmltcG9ydCB7IERNZWRpYU1hbmFnZXIgfSBmcm9tIFwiLi4vc2VydmljZXMvRE1lZGlhLW1hbmFnZXJcIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBEUGxheWVyIH0gZnJvbSBcIi4uL3BsYXllci9kcGxheWVyXCI7XG5pbXBvcnQgeyBBbnN3ZXJlZFF1ZXN0aW9uIH0gZnJvbSBcIi4uL3BsYXllci9oaXN0b3J5LXF1ZVwiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgRFBhZ2UgfSBmcm9tIFwiLi9EUGFnZVwiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4vc2NhbGVcIjtcbmltcG9ydCB7IFJlc291cmNlUHJvdmlkZXIgfSBmcm9tIFwiLi4vc2VydmljZXMvcmVzb3VyY2UtcHJvdmlkZXJcIjtcbmltcG9ydCB7IFN0YXRlU2VydmljZSB9IGZyb20gXCIuLi9zdGF0ZS9zdGF0ZS1zZXJ2aWNlXCI7XG5pbXBvcnQgeyBEQ29tbWFuZCwgU3RhdGVDb21tYW5kIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kXCI7XG5pbXBvcnQgeyBERXZlbnQgfSBmcm9tIFwiLi4vZXZlbnRzL0RFdmVudHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBFbmdpbmVMb2dnZXIge1xuICBlcnJvcihtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQ7XG4gIGFwcEV2ZW50KGV2ZW50OiBERXZlbnQpOiB2b2lkO1xuICBhcHBDb21tYW5kKGNvbW1hbmQ6IERDb21tYW5kKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY2hlbWFSZXN1bHQge1xuICByZWFkb25seSBldmVudExvZzogUmVhZG9ubHlBcnJheTxERXZlbnQ+O1xuICByZWFkb25seSBjb21tYW5kTG9nOiBSZWFkb25seUFycmF5PERDb21tYW5kPjtcbiAgcmVhZG9ubHkgYW5zd2VyczogUmVhZG9ubHlBcnJheTxhbnk+O1xufVxuZXhwb3J0IGludGVyZmFjZSBJU2NoZW1hRW5naW5lIHtcbiAgb25Db21wbGV0ZShoYW5kbGVyOiAocmVzdWx0OiBTY2hlbWFSZXN1bHQpID0+IHZvaWQpOiB2b2lkO1xuICBvbkNvbW1hbmRPckV2ZW50KGl0ZW06IERFdmVudCB8IERDb21tYW5kKTogdm9pZDtcbiAgc2V0U2NoZW1hKHNjaGVtYTogU2NoZW1hRHRvKTogdm9pZDtcbiAgb25GYXRhbEVycm9yKGhhbmRsZXI6IChlcnJvcjogeyBtZXNzYWdlOiBzdHJpbmcgfSkgPT4gdm9pZCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBTY2hlbWFFbmdpbmUgaW1wbGVtZW50cyBJU2NoZW1hRW5naW5lIHtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgU0NIRU1BX0VOR0lORSBdIDpcIjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kQnVzID0gbmV3IERDb21tYW5kQnVzKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXMgPSBuZXcgRXZlbnRCdXMoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZWRpYU1hbmFnZXI6IERNZWRpYU1hbmFnZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2NhbGU6IFNjYWxlU2VydmljZTtcbiAgcHJpdmF0ZSByZWFkb25seSBob3N0RWxlbWVudDogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgdWlDb250YWluZXI6IEhUTUxEaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZWRpYUNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlUHJvdmlkZXI6IFJlc291cmNlUHJvdmlkZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RhdGVTZXJ2aWNlOiBTdGF0ZVNlcnZpY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2xvYmFsRXZlbnRUb1N0YXRlSGFuZGxlcnMgPSBuZXcgTWFwPHN0cmluZywgUmVhZG9ubHlBcnJheTxTdGF0ZUNvbW1hbmQ+PigpO1xuICBwcml2YXRlIHBsYXllcjogRFBsYXllcjtcbiAgcHJpdmF0ZSBjdXJyZW50UGFnZTogRFBhZ2UgfCBmYWxzZSA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnM6IEFycmF5PCgpID0+IHZvaWQ+ID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaG9zdEVsOiBIVE1MRGl2RWxlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhlaWdodDogbnVtYmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgd2lkdGg6IG51bWJlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjaGVtYTogU2NoZW1hRHRvLFxuICApIHtcbiAgICB0aGlzLmhvc3RFbGVtZW50ID0gaG9zdEVsO1xuICAgIHRoaXMuaG9zdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy51aUNvbnRhaW5lcik7XG4gICAgdGhpcy5ob3N0RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLm1lZGlhQ29udGFpbmVyKTtcbiAgICBjb25zdCBzdGF0ZVByb3BzID0gdGhpcy5zY2hlbWEuc3RhdGVQcm9wcyA/PyBbXTtcbiAgICBjb25zdCBzdGF0ZVF1ZXJpZXMgPSB0aGlzLnNjaGVtYS5zdGF0ZVF1ZXJpZXMgPz8gW107XG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UgPSBuZXcgU3RhdGVTZXJ2aWNlKHRoaXMuZXZlbnRCdXMsIHRoaXMuY29tbWFuZEJ1cywgc3RhdGVQcm9wcywgc3RhdGVRdWVyaWVzKTtcbiAgICB0aGlzLnNjYWxlID0gbmV3IFNjYWxlU2VydmljZSh7XG4gICAgICBiYXNlSGVpZ2h0OiBzY2hlbWEuYmFzZUhlaWdodCxcbiAgICAgIGJhc2VXaWR0aDogc2NoZW1hLmJhc2VXaWR0aCxcbiAgICAgIGNvbnRhaW5lcldpZHRoOiB3aWR0aCxcbiAgICAgIGNvbnRhaW5lckhlaWdodDogaGVpZ2h0LFxuICAgIH0pO1xuICAgIC8vIHRoaXMuY29tbWFuZEJ1cy5sb2dDb21tYW5kcyA9IHRydWU7XG4gICAgY29uc3QgZ2xvYmFsRXZlbnRIYW5kbGVycyA9IHNjaGVtYS5zdGF0ZUZyb21FdmVudCA/PyBbXTtcblxuICAgIGdsb2JhbEV2ZW50SGFuZGxlcnMuZm9yRWFjaCgoaCkgPT4ge1xuICAgICAgdGhpcy5nbG9iYWxFdmVudFRvU3RhdGVIYW5kbGVycy5zZXQoaC5vbkV2ZW50LCBoLnRoZW5FeGVjdXRlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc291cmNlcyA9IFNjaGVtYUR0by5nZXRSZXNvdXJjZXModGhpcy5zY2hlbWEpO1xuICAgIHRoaXMucmVzb3VyY2VQcm92aWRlciA9IG5ldyBSZXNvdXJjZVByb3ZpZGVyKHsgdmlkZW9zOiByZXNvdXJjZXMudmlkZW9MaXN0LCBhdWRpbzogcmVzb3VyY2VzLmF1ZGlvTGlzdCB9KTtcbiAgICB0aGlzLm1lZGlhTWFuYWdlciA9IG5ldyBETWVkaWFNYW5hZ2VyKFxuICAgICAgdGhpcy5tZWRpYUNvbnRhaW5lcixcbiAgICAgIHRoaXMuY29tbWFuZEJ1cyxcbiAgICAgIHRoaXMuZXZlbnRCdXMsXG4gICAgICB0aGlzLnJlc291cmNlUHJvdmlkZXIsXG4gICAgICB0aGlzLnNjYWxlLFxuICAgICk7XG4gICAgdGhpcy5wbGF5ZXIgPSBuZXcgRFBsYXllcih0aGlzLnNjaGVtYSk7XG4gICAgdGhpcy5zdHlsZVNlbGYoKTtcbiAgICB0aGlzLm5leHRQYWdlKCk7XG4gICAgdGhpcy5ob29rVXBMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgaG9va1VwTGlzdGVuZXJzKCkge1xuICAgIGNvbnN0IGV2ZW50U3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudEJ1cy5zdWJzY3JpYmUoKGV2KSA9PiB7XG4gICAgICB0aGlzLm9uQ29tbWFuZE9yRXZlbnQoZXYpO1xuICAgICAgY29uc3QgZ2xvYmFsSGFuZGxlcnMgPSB0aGlzLmdsb2JhbEV2ZW50VG9TdGF0ZUhhbmRsZXJzLmdldChldi5raW5kKSA/PyBbXTtcbiAgICAgIGdsb2JhbEhhbmRsZXJzLmZvckVhY2goKHN0YXRlQ29tbWFuZCkgPT4ge1xuICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChzdGF0ZUNvbW1hbmQpO1xuICAgICAgfSk7XG4gICAgfSwgdGhpcy5UQUcgKyBcIkhPT0tfVVBfTElTVEVORVJTXCIpO1xuICAgIGNvbnN0IGNvbW1hbmRTdWJzY3JpcHRpb24gPSB0aGlzLmNvbW1hbmRCdXMuc3Vic2NyaWJlKChjb21tYW5kKSA9PiB7XG4gICAgICAvLyBzd2l0Y2ggKGNvbW1hbmQua2luZCkge1xuICAgICAgLy9cbiAgICAgIC8vIH1cbiAgICAgIHRoaXMub25Db21tYW5kT3JFdmVudChjb21tYW5kKTtcbiAgICAgIGlmIChjb21tYW5kLmtpbmQgPT09IFwiUEFHRV9RVUVfTkVYVF9QQUdFX0NPTU1BTkRcIikge1xuICAgICAgICB0aGlzLm5leHRQYWdlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb21tYW5kLmtpbmQgPT09IFwiRU5HSU5FX0xFQVZFX1BBR0VfQ09NTUFORFwiKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJTRVFVRU5DRSBTVEFSVEVEIC0tIFRPRE8gRVZFTlQgRk9SIFRISVM/P1wiKTtcbiAgICAgICAgY29uc29sZS5sb2coY29tbWFuZCk7XG4gICAgICAgIGNvbnN0IHBhZ2VJZCA9IGNvbW1hbmQucGF5bG9hZC5wYWdlSWQ7XG4gICAgICAgIGNvbnN0IGZhY3RzID0gY29tbWFuZC5wYXlsb2FkLmZhY3RzQ29sbGVjdGVkO1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgICAgICBjb25zdCBhbnM6IEFuc3dlcmVkUXVlc3Rpb25bXSA9IGZhY3RzLm1hcCgoZikgPT4gKHtcbiAgICAgICAgICB0aW1lc3RhbXAsXG4gICAgICAgICAgZmFjdDogZixcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLnBsYXllci5zYXZlSGlzdG9yeSh7XG4gICAgICAgICAgYW5zd2VyZWRRdWVzdGlvbnM6IGFucyxcbiAgICAgICAgICBwYWdlSWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubmV4dFBhZ2UoKTtcbiAgICAgICAgLy8gY29uc3QgaGlzdG9yeTogUGFnZUhpc3RvcnkgPSB7IHBhZ2U6IHt9LCBhbnN3ZXJlZFF1ZXN0aW9uczogW10gfTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLlRBRyk7XG5cbiAgICB0aGlzLnN1YnMucHVzaChjb21tYW5kU3Vic2NyaXB0aW9uKTtcbiAgICB0aGlzLnN1YnMucHVzaChldmVudFN1YnNjcmlwdGlvbik7XG4gIH1cblxuICBwcml2YXRlIHN0eWxlU2VsZigpIHtcbiAgICB0aGlzLmhvc3RFbGVtZW50LnN0eWxlLmhlaWdodCA9IHRoaXMuc2NhbGUucGFnZUhlaWdodCArIFwicHhcIjtcbiAgICB0aGlzLmhvc3RFbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy5zY2FsZS5wYWdlV2lkdGggKyBcInB4XCI7XG4gICAgdGhpcy5ob3N0RWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnNjaGVtYS5iYWNrZ3JvdW5kQ29sb3IgPz8gXCJ3aGl0ZVwiO1xuICAgIHRoaXMuaG9zdEVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG4gICAgLy8gdGhpcy5ob3N0RWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG4gICAgY29uc3QgbWFrZVN0YXRpYyA9IChkaXY6IEhUTUxEaXZFbGVtZW50KSA9PiB7XG4gICAgICBkaXYuc3R5bGUuaGVpZ2h0ID0gXCIwcHhcIjtcbiAgICAgIGRpdi5zdHlsZS53aWR0aCA9IFwiMHB4XCI7XG4gICAgICBkaXYuc3R5bGUucG9zaXRpb24gPSBcInN0YXRpY1wiO1xuICAgIH07XG5cbiAgICBtYWtlU3RhdGljKHRoaXMudWlDb250YWluZXIpO1xuICAgIG1ha2VTdGF0aWModGhpcy5tZWRpYUNvbnRhaW5lcik7XG4gIH1cblxuICBwcml2YXRlIG5leHRQYWdlKCkge1xuICAgIC8vIFRPRE8gU0hPVUxEIFRISVMgQkUgUEFSVCBPRiBUSEUgU0NIRU1BPz8gVEhJUyBJUyBDTEVBTlVQIExPR0lDXG4gICAgLy8gdGhpcy5jb21tYW5kQnVzLmVtaXQoeyBraW5kOiBcIlZJREVPX1BBVVNFX0NPTU1BTkRcIiwgdGFyZ2V0OiBcIlZJREVPXCIsIHRhcmdldElkOiBcIlZJREVPXCIsIHBheWxvYWQ6IHt9IH0pO1xuICAgIC8vIHRoaXMuY29tbWFuZEJ1cy5lbWl0KHsga2luZDogXCJBVURJT19QQVVTRV9DT01NQU5EXCIsIHRhcmdldDogXCJBVURJT1wiLCB0YXJnZXRJZDogXCJBVURJT1wiLCBwYXlsb2FkOiB7fSB9KTtcbiAgICAvLyBjb25zdCBjdXJyUGFnZUlkID0gdGhpcy5jdXJyZW50UGFnZSA/IHRoaXMuY3VycmVudFBhZ2UuaWQgOiBcIk5PX1BBR0VcIjtcbiAgICAvLyBjb25zb2xlLmdyb3VwQ29sbGFwc2VkKFwiTkVYVF9QQUdFIEZST006IFwiICsgY3VyclBhZ2VJZCk7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyBcIiBORVhUX1BBR0UgU1RBUlRFRCBBVDogXCIgKyBjdXJyUGFnZUlkKTtcbiAgICB0aGlzLm1lZGlhTWFuYWdlci5jbGVhckFsbE1lZGlhKCk7XG4gICAgY29uc3QgbmV4dFBhZ2UgPSB0aGlzLnBsYXllci5nZXROZXh0UGFnZSgpO1xuICAgIC8vIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZVNlcnZpY2UuZ2V0U3RhdGUoKTtcbiAgICAvLyBjb25zb2xlLmxvZyhzdGF0ZSk7XG4gICAgLy8gVE9ETyBDTEVBTiBVUCBQQUdFIENPTVBPTkVOVFMgdGhpcy5wYWdlLkNsZWFuVXAoKVxuICAgIGlmICh0aGlzLmN1cnJlbnRQYWdlKSB7XG4gICAgICB0aGlzLmN1cnJlbnRQYWdlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudWlDb250YWluZXIuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9XG4gICAgaWYgKCFuZXh0UGFnZSkge1xuICAgICAgLy8gVE9ETyBGSUdVUkUgT1VUIFdIQVFUIFRPIERPIEFUIEVORCBPRiBURVNUISEgU3RhcnQgb3Zlcj8/XG4gICAgICB0aGlzLnBsYXllciA9IG5ldyBEUGxheWVyKHRoaXMuc2NoZW1hKTtcbiAgICAgIGlmICh0aGlzLnNjaGVtYS5wYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMubmV4dFBhZ2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgbmV3UGFnZSA9IG5ldyBEUGFnZShuZXh0UGFnZSwgdGhpcy5ldmVudEJ1cywgdGhpcy5jb21tYW5kQnVzLCB0aGlzLnNjYWxlKTtcblxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBuZXdQYWdlO1xuICAgIG5ld1BhZ2UuYXBwZW5kWW91cnNlbGYodGhpcy51aUNvbnRhaW5lcik7XG5cbiAgICB0aGlzLm1lZGlhTWFuYWdlci5zZXRQYWdlKG5leHRQYWdlKTtcbiAgICBjb25zdCBzMSA9IHRoaXMuc3RhdGVTZXJ2aWNlLmdldFN0YXRlKCk7XG4gICAgLy8gY29uc29sZS5sb2coczEpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwiTmV4dC1wYWdlOiBcIiArIG5ld1BhZ2UuaWQpO1xuICAgIC8vIGNvbnNvbGUuZ3JvdXBFbmQoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudFBhZ2UpIHtcbiAgICAgIHRoaXMuY3VycmVudFBhZ2UuZGVzdHJveSgpO1xuICAgICAgdGhpcy51aUNvbnRhaW5lci5pbm5lckhUTUwgPSBcIlwiO1xuICAgIH1cbiAgICB0aGlzLm1lZGlhTWFuYWdlci5kZXN0cm95KCk7XG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UuZGVzdHJveSgpO1xuICAgIHRoaXMuc3Vicy5mb3JFYWNoKChzdWIpID0+IHtcbiAgICAgIHN1YigpO1xuICAgIH0pO1xuICAgIGNvbnN0IGV2U3RhdHMgPSB0aGlzLmV2ZW50QnVzLmdldFN0YXRzKCk7XG4gICAgY29uc3QgY21kU3RhdHMgPSB0aGlzLmNvbW1hbmRCdXMuZ2V0U3RhdHMoKTtcbiAgICBjb25zb2xlLmFzc2VydChldlN0YXRzLnN1YnNjcmliZXJzQ291bnQgPT09IDAsIHRoaXMuVEFHICsgXCIgRXZlbnRidXMgc2hvdWxkIGhhdmUgbm8gc3Vic2NyaWJlcnMgXCIsIGV2U3RhdHMpO1xuICAgIGNvbnNvbGUuYXNzZXJ0KGNtZFN0YXRzLnN1YnNjcmliZXJzQ291bnQgPT09IDAsIHRoaXMuVEFHICsgXCJDb21tYW5kYnVzIHNob3VsZCBoYXZlIG5vIHN1YnNjcmliZXJzXCIsIGNtZFN0YXRzKTtcbiAgfVxuICBvbkNvbXBsZXRlKGhhbmRsZXI6IChyZXN1bHQ6IFNjaGVtYVJlc3VsdCkgPT4gdm9pZCkge1xuICAgIGNvbnNvbGUubG9nKGhhbmRsZXIpO1xuICB9XG5cbiAgb25GYXRhbEVycm9yKGhhbmRsZXI6IChlcnJvcjogeyBtZXNzYWdlOiBzdHJpbmcgfSkgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKGhhbmRsZXIpO1xuICB9XG5cbiAgb25Db21tYW5kT3JFdmVudChfZXZlbnRfb3JfY29tbWFuZDogREV2ZW50IHwgRENvbW1hbmQpIHt9XG5cbiAgc2V0U2NoZW1hKHNjaGVtYTogU2NoZW1hRHRvKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coc2NoZW1hKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IERTdGF0ZSB9IGZyb20gXCIuL0RzdGF0ZVwiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL3J1bGVzL2NvbmRpdGlvblwiO1xuaW1wb3J0IHsgU3RhdGVDb21tYW5kIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kXCI7XG5cbmV4cG9ydCBjbGFzcyBCb29sZWFuU3RhdGVQcm9wZXJ0eTxQcm9wTmFtZSBleHRlbmRzIHN0cmluZz4ge1xuICAgIHJlYWRvbmx5IHByb3BOYW1lOiBQcm9wTmFtZTtcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBUUlVFID0geyB2YWx1ZTogMSwgbGFiZWw6IFwiVFJVRVwiIH07XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgRkFMU0UgPSB7IHZhbHVlOiAwLCBsYWJlbDogXCJGQUxTRVwiIH07XG4gICAgcmVhZG9ubHkgcHJvcERlZmluaXRpb246IERTdGF0ZS5OdW1lcmljUHJvcDtcblxuICAgIGdldElzVHJ1ZUNvbmRpdGlvbigpOiBDb25kaXRpb24uTnVtZXJpYyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBraW5kOiBcIm51bWVyaWMtY29uZGl0aW9uXCIsXG4gICAgICAgICAgICByZWZlcmVuY2VJZDogdGhpcy5wcm9wTmFtZSxcbiAgICAgICAgICAgIHJlZmVyZW5jZUxhYmVsOiB0aGlzLnByb3BOYW1lICsgXCJbIEJPT0xFQU4gXVwiLFxuICAgICAgICAgICAgdmFsdWVMYWJlbDogQm9vbGVhblN0YXRlUHJvcGVydHkuVFJVRS5sYWJlbCxcbiAgICAgICAgICAgIHZhbHVlOiBCb29sZWFuU3RhdGVQcm9wZXJ0eS5UUlVFLnZhbHVlLFxuICAgICAgICAgICAgb3BlcmF0b3I6IFwiZXFcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZ2V0SXNGYWxzZUNvbmRpdGlvbigpOiBDb25kaXRpb24uTnVtZXJpYyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBraW5kOiBcIm51bWVyaWMtY29uZGl0aW9uXCIsXG4gICAgICAgICAgICByZWZlcmVuY2VJZDogdGhpcy5wcm9wTmFtZSxcbiAgICAgICAgICAgIHJlZmVyZW5jZUxhYmVsOiB0aGlzLnByb3BOYW1lICsgXCJbIEJPT0xFQU4gXVwiLFxuICAgICAgICAgICAgdmFsdWVMYWJlbDogQm9vbGVhblN0YXRlUHJvcGVydHkuRkFMU0UubGFiZWwsXG4gICAgICAgICAgICB2YWx1ZTogQm9vbGVhblN0YXRlUHJvcGVydHkuRkFMU0UudmFsdWUsXG4gICAgICAgICAgICBvcGVyYXRvcjogXCJlcVwiLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdldFNldFRydWVDb21tYW5kKCk6IFN0YXRlQ29tbWFuZCB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBraW5kOiBcIlNUQVRFX01VVEFURV9DT01NQU5EXCIsXG4gICAgICAgICAgICB0YXJnZXQ6IFwiU1RBVEVcIixcbiAgICAgICAgICAgIHRhcmdldElkOiBcIlNUQVRFXCIsXG4gICAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICAgICAgbXV0YXRpb246IHsgcHJvcE5hbWU6IHRoaXMucHJvcE5hbWUsIGtpbmQ6IFwic2V0LW51bWJlclwiLCB2YWx1ZTogMSB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXRTZXRGYWxzZUNvbW1hbmQoKTogU3RhdGVDb21tYW5kIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGtpbmQ6IFwiU1RBVEVfTVVUQVRFX0NPTU1BTkRcIixcbiAgICAgICAgICAgIHRhcmdldDogXCJTVEFURVwiLFxuICAgICAgICAgICAgdGFyZ2V0SWQ6IFwiU1RBVEVcIixcbiAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgICBtdXRhdGlvbjogeyBwcm9wTmFtZTogdGhpcy5wcm9wTmFtZSwga2luZDogXCJzZXQtbnVtYmVyXCIsIHZhbHVlOiAwIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByb3BOYW1lOiBQcm9wTmFtZSwgcHJpdmF0ZSByZWFkb25seSBpbml0aWFsVmFsdWU6IGJvb2xlYW4sIGRlc2NyaXB0aW9uOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wcm9wTmFtZSA9IHByb3BOYW1lO1xuICAgICAgICBjb25zdCBpbml0aWFsID0gaW5pdGlhbFZhbHVlID8gMSA6IDA7XG4gICAgICAgIGNvbnN0IHByb3BEZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uID8gZGVzY3JpcHRpb24gOiBcIk5vIGRlc2NyaXB0aW9uIGdpdmVuXCI7XG4gICAgICAgIHRoaXMucHJvcERlZmluaXRpb24gPSB7XG4gICAgICAgICAgICBwcm9wRGVzY3JpcHRpb24sXG4gICAgICAgICAgICBwcm9wTmFtZTogcHJvcE5hbWUsXG4gICAgICAgICAgICBpbml0aWFsVmFsdWU6IGluaXRpYWwsXG4gICAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICAgICAgeyB2YWx1ZTogQm9vbGVhblN0YXRlUHJvcGVydHkuRkFMU0UudmFsdWUsIHZhbHVlTGFiZWw6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LkZBTFNFLmxhYmVsIH0sXG4gICAgICAgICAgICAgICAgeyB2YWx1ZTogQm9vbGVhblN0YXRlUHJvcGVydHkuVFJVRS52YWx1ZSwgdmFsdWVMYWJlbDogQm9vbGVhblN0YXRlUHJvcGVydHkuVFJVRS5sYWJlbCB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF90eXBlOiBcIm51bWJlclwiLFxuICAgICAgICB9O1xuICAgIH1cbn1cbiIsICIvLyBUaGUgZGVmYXVsdCBsZW5ndGggb2YgYW4gSURcbmNvbnN0IElEX0xFTkdUSCA9IDMyO1xuXG4vLyBUaGUgbWluaW11bSBsZW5ndGggb2YgYW4gSURcbmNvbnN0IE1JTl9MRU5HVEggPSAxMDtcblxuZXhwb3J0IHR5cGUgSUQ8QiBleHRlbmRzIHN0cmluZz4gPSBzdHJpbmcgJiB7IF9fSURfXzogQiB9O1xuXG5jb25zdCBpc0lEID0gPGNvbnN0IEIgZXh0ZW5kcyBzdHJpbmc+KGlkTmFtZTogQiwgaWQ/OiBzdHJpbmcpOiBpZCBpcyBJRDxCPiA9PiB7XG4gIGlmICh0eXBlb2YgaWQgIT09IFwic3RyaW5nXCIpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGlkLmxlbmd0aCA+PSBNSU5fTEVOR1RIO1xufTtcblxuY29uc3QgY3JlYXRlSURCeU5hbWUgPSA8Y29uc3QgQiBleHRlbmRzIHN0cmluZz4oaWROYW1lOiBCKTogSUQ8Qj4gPT4ge1xuICBjb25zdCBsZXR0ZXJzID0gXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2eXpcIjtcbiAgY29uc3QgYWxsID0gbGV0dGVycyArIGxldHRlcnMudG9VcHBlckNhc2UoKTtcbiAgbGV0IHJlc3VsdCA9IFwiXCI7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSURfTEVOR1RIOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gYWxsLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhbGwubGVuZ3RoKSk7XG4gICAgcmVzdWx0ICs9IGNoYXI7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCBhcyBJRDxCPjtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG9iamVjdCB3aXRoIGhlbHBlciBmdW5jdGlvbnMgZm9yIGEgc3BlY2lmaWMgSUQgdHlwZVxuICogQHBhcmFtIGlkTmFtZVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlVHlwZWRJZFNpbmdsZXRvbiA9IDxjb25zdCBCIGV4dGVuZHMgc3RyaW5nPihpZE5hbWU6IEIpID0+IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgSUQgb2YgdGhlIGNvcnJlY3QgdHlwZVxuICAgKi9cbiAgY29uc3QgY3JlYXRlID0gKCk6IElEPEI+ID0+IGNyZWF0ZUlEQnlOYW1lKGlkTmFtZSk7XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgaWQgaXMgb2YgdGhlIGNvcnJlY3QgdHlwZVxuICAgKiBAcGFyYW0gaWRcbiAgICovXG4gIGNvbnN0IGlzID0gKGlkOiBzdHJpbmcpOiBpZCBpcyBJRDxCPiA9PiBpc0lEKGlkTmFtZSwgaWQpO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGlkIGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUsIGlmIG5vdCBpdCB0aHJvd3MgYW4gZXJyb3JcbiAgICogQHBhcmFtIGlkXG4gICAqL1xuICBjb25zdCB2YWxpZGF0ZU9yVGhyb3cgPSAoaWQ6IHN0cmluZyk6IElEPEI+ID0+IHtcbiAgICBpZiAoIWlzKGlkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGlkOiAke2lkfWApO1xuICAgIH1cbiAgICByZXR1cm4gaWQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIFRoZSBsb3dlcmNhc2UgbmFtZSBvZiB0aGUgaWQgKFNDSEVNQSwgUEFHRSwgZXRjKVxuICAgKi9cbiAgY29uc3QgbmFtZTogQiA9IGlkTmFtZTtcblxuICAvKipcbiAgICogRW5zdXJlcyB0aGF0IHRoZSBpZCBpcyBvZiB0aGUgY29ycmVjdCB0eXBlLCBpZiBub3QgaXQgY3JlYXRlcyBhIG5ldyBvbmVcbiAgICogQHBhcmFtIGlkXG4gICAqL1xuICBjb25zdCBlbnN1cmUgPSAoaWQ6IHN0cmluZyk6IElEPEI+ID0+IHtcbiAgICByZXR1cm4gaXMoaWQpID8gaWQgOiBjcmVhdGUoKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7IGNyZWF0ZSwgaXMsIGVuc3VyZSwgdmFsaWRhdGVPclRocm93LCBuYW1lIH0pO1xufTtcblxuZXhwb3J0IHR5cGUgU2NoZW1hSUQgPSBJRDxcIlNDSEVNQVwiPjtcbmV4cG9ydCBjb25zdCBTY2hlbWFJRCA9IGNyZWF0ZVR5cGVkSWRTaW5nbGV0b24oXCJTQ0hFTUFcIik7XG5leHBvcnQgdHlwZSBQYWdlSUQgPSBJRDxcIlBBR0VcIj47XG5leHBvcnQgY29uc3QgUGFnZUlEID0gY3JlYXRlVHlwZWRJZFNpbmdsZXRvbihcIlBBR0VcIik7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBd0NPLElBQVU7QUFBQSxDQUFWLENBQVVBLGVBQVY7QUFDRSxFQUFNQSxXQUFBLGVBQWUsQ0FDMUIsV0FLRztBQUNILFVBQU0sRUFBRSxNQUFNLElBQUk7QUFDbEIsVUFBTSxZQUFZLE1BQU0sT0FBeUIsQ0FBQyxLQUFLLFNBQVM7QUFDOUQsVUFBSSxNQUFNLFFBQVEsS0FBSyxLQUFLLEdBQUc7QUFDN0IsWUFBSSxLQUFLLEdBQUcsS0FBSyxLQUFLO0FBQUEsTUFDeEI7QUFDQSxhQUFPO0FBQUEsSUFDVCxHQUFHLENBQUMsQ0FBQztBQUNMLFVBQU0sWUFBOEIsTUFBTSxPQUF5QixDQUFDLEtBQUssU0FBUztBQUNoRixVQUFJLE1BQU0sUUFBUSxLQUFLLEtBQUssR0FBRztBQUM3QixZQUFJLEtBQUssR0FBRyxLQUFLLEtBQUs7QUFBQSxNQUN4QjtBQUNBLGFBQU87QUFBQSxJQUNULEdBQUcsQ0FBQyxDQUFDO0FBRUwsV0FBTyxFQUFFLFdBQVcsV0FBVyxXQUFXLENBQUMsRUFBRTtBQUFBLEVBQy9DO0FBQUEsR0F2QmU7OztBQ3ZDVixJ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O0FBQUEsTUFDTixRQUFRO0FBQUEsTUFDUixVQUFVO0FBQUEsTUFDVixTQUFTO0FBQUEsUUFDTCxVQUFVLEVBQUUsVUFBVSxLQUFLLFVBQVUsTUFBTSxjQUFjLE9BQU8sRUFBRTtBQUFBLE1BQ3RFO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFBQSxFQUVBLHFCQUFtQztBQUMvQixXQUFPO0FBQUEsTUFDSCxNQUFNO0FBQUEsTUFDTixRQUFRO0FBQUEsTUFDUixVQUFVO0FBQUEsTUFDVixTQUFTO0FBQUEsUUFDTCxVQUFVLEVBQUUsVUFBVSxLQUFLLFVBQVUsTUFBTSxjQUFjLE9BQU8sRUFBRTtBQUFBLE1BQ3RFO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFpQko7OztBQ25FQSxJQUFNLFlBQVk7QUFHbEIsSUFBTSxhQUFhO0FBSW5CLElBQU0sT0FBTyxDQUF5QixRQUFXLE9BQTZCO0FBQzVFLE1BQUksT0FBTyxPQUFPO0FBQVUsV0FBTztBQUNuQyxTQUFPLEdBQUcsVUFBVTtBQUN0QjtBQUVBLElBQU0saUJBQWlCLENBQXlCLFdBQXFCO0FBQ25FLFFBQU0sVUFBVTtBQUNoQixRQUFNLE1BQU0sVUFBVSxRQUFRLFlBQVk7QUFDMUMsTUFBSSxTQUFTO0FBQ2IsV0FBUyxJQUFJLEdBQUcsSUFBSSxXQUFXLEtBQUs7QUFDbEMsVUFBTSxPQUFPLElBQUksT0FBTyxLQUFLLE1BQU0sS0FBSyxPQUFPLElBQUksSUFBSSxNQUFNLENBQUM7QUFDOUQsY0FBVTtBQUFBLEVBQ1o7QUFDQSxTQUFPO0FBQ1Q7QUFNTyxJQUFNLHlCQUF5QixDQUF5QixXQUFjO0FBSTNFLFFBQU0sU0FBUyxNQUFhLGVBQWUsTUFBTTtBQU1qRCxRQUFNLEtBQUssQ0FBQyxPQUE0QixLQUFLLFFBQVEsRUFBRTtBQU12RCxRQUFNLGtCQUFrQixDQUFDLE9BQXNCO0FBQzdDLFFBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRztBQUNYLFlBQU0sSUFBSSxNQUFNLGVBQWUsRUFBRSxFQUFFO0FBQUEsSUFDckM7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUtBLFFBQU0sT0FBVTtBQU1oQixRQUFNLFNBQVMsQ0FBQyxPQUFzQjtBQUNwQyxXQUFPLEdBQUcsRUFBRSxJQUFJLEtBQUssT0FBTztBQUFBLEVBQzlCO0FBRUEsU0FBTyxPQUFPLE9BQU8sRUFBRSxRQUFRLElBQUksUUFBUSxpQkFBaUIsS0FBSyxDQUFDO0FBQ3BFO0FBR08sSUFBTSxXQUFXLHVCQUF1QixRQUFRO0FBRWhELElBQU0sU0FBUyx1QkFBdUIsTUFBTTsiLAogICJuYW1lcyI6IFsiU2NoZW1hRHRvIiwgIkRUaW1lc3RhbXAiLCAiRFV0aWwiLCAiaXNOdW1iZXIiLCAiRENzcyIsICJEU3R5bGUiLCAiQW5zd2VyZWRRdWVzdGlvbiIsICJDb25kaXRpb24iLCAiY29uZGl0aW9uIiwgIlJ1bGUiLCAidGFnIiwgIkRFdmVudEhhbmRsZXIiLCAiZHRvIiwgImR0byIsICJTY2FsZSIsICJSZXN1bHQiLCAiRFN0YXRlIl0KfQo=